il.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. #include "ip.h"
  8. enum /* Connection state */
  9. {
  10. Ilclosed,
  11. Ilsyncer,
  12. Ilsyncee,
  13. Ilestablished,
  14. Illistening,
  15. Ilclosing,
  16. Ilopening, /* only for file server */
  17. };
  18. char *ilstates[] =
  19. {
  20. "Closed",
  21. "Syncer",
  22. "Syncee",
  23. "Established",
  24. "Listen",
  25. "Closing",
  26. "Opening", /* only for file server */
  27. };
  28. enum /* Packet types */
  29. {
  30. Ilsync,
  31. Ildata,
  32. Ildataquery,
  33. Ilack,
  34. Ilquery,
  35. Ilstate,
  36. Ilclose,
  37. };
  38. char *iltype[] =
  39. {
  40. "sync",
  41. "data",
  42. "dataquery",
  43. "ack",
  44. "query",
  45. "state",
  46. "close"
  47. };
  48. enum
  49. {
  50. Seconds = 1000,
  51. Iltickms = 50, /* time base */
  52. AckDelay = 2*Iltickms, /* max time twixt message rcvd & ack sent */
  53. MaxTimeout = 30*Seconds, /* max time between rexmit */
  54. QueryTime = 10*Seconds, /* time between subsequent queries */
  55. DeathTime = 30*QueryTime,
  56. MaxRexmit = 16, /* max retransmissions before hangup */
  57. Defaultwin = 20,
  58. LogAGain = 3,
  59. AGain = 1<<LogAGain,
  60. LogDGain = 2,
  61. DGain = 1<<LogDGain,
  62. DefByteRate = 100, /* assume a megabit link */
  63. DefRtt = 50, /* cross country on a great day */
  64. };
  65. enum
  66. {
  67. Nqt= 8,
  68. };
  69. typedef struct Ilcb Ilcb;
  70. struct Ilcb /* Control block */
  71. {
  72. int state; /* Connection state */
  73. Conv *conv;
  74. QLock ackq; /* Unacknowledged queue */
  75. Block *unacked;
  76. Block *unackedtail;
  77. ulong unackedbytes;
  78. QLock outo; /* Out of order packet queue */
  79. Block *outoforder;
  80. ulong next; /* Id of next to send */
  81. ulong recvd; /* Last packet received */
  82. ulong acksent; /* Last packet acked */
  83. ulong start; /* Local start id */
  84. ulong rstart; /* Remote start id */
  85. int window; /* Maximum receive window */
  86. int rxquery; /* number of queries on this connection */
  87. int rxtot; /* number of retransmits on this connection */
  88. int rexmit; /* number of retransmits of *unacked */
  89. ulong qt[Nqt+1]; /* state table for query messages */
  90. int qtx; /* ... index into qt */
  91. /* if set, fasttimeout causes a connection request to terminate after 4*Iltickms */
  92. int fasttimeout;
  93. /* timers */
  94. ulong lastxmit; /* time of last xmit */
  95. ulong lastrecv; /* time of last recv */
  96. ulong timeout; /* retransmission time for *unacked */
  97. ulong acktime; /* time to send next ack */
  98. ulong querytime; /* time to send next query */
  99. /* adaptive measurements */
  100. int delay; /* Average of the fixed rtt delay */
  101. int rate; /* Average uchar rate */
  102. int mdev; /* Mean deviation of rtt */
  103. int maxrtt; /* largest rtt seen */
  104. ulong rttack; /* The ack we are waiting for */
  105. int rttlen; /* Length of rttack packet */
  106. uvlong rttstart; /* Time we issued rttack packet */
  107. };
  108. enum
  109. {
  110. IL_IPSIZE = 20,
  111. IL_HDRSIZE = 18,
  112. IL_LISTEN = 0,
  113. IL_CONNECT = 1,
  114. IP_ILPROTO = 40,
  115. };
  116. typedef struct Ilhdr Ilhdr;
  117. struct Ilhdr
  118. {
  119. uchar vihl; /* Version and header length */
  120. uchar tos; /* Type of service */
  121. uchar length[2]; /* packet length */
  122. uchar id[2]; /* Identification */
  123. uchar frag[2]; /* Fragment information */
  124. uchar ttl; /* Time to live */
  125. uchar proto; /* Protocol */
  126. uchar cksum[2]; /* Header checksum */
  127. uchar src[4]; /* Ip source */
  128. uchar dst[4]; /* Ip destination */
  129. uchar ilsum[2]; /* Checksum including header */
  130. uchar illen[2]; /* Packet length */
  131. uchar iltype; /* Packet type */
  132. uchar ilspec; /* Special */
  133. uchar ilsrc[2]; /* Src port */
  134. uchar ildst[2]; /* Dst port */
  135. uchar ilid[4]; /* Sequence id */
  136. uchar ilack[4]; /* Acked sequence */
  137. };
  138. enum
  139. {
  140. InMsgs,
  141. OutMsgs,
  142. CsumErrs, /* checksum errors */
  143. HlenErrs, /* header length error */
  144. LenErrs, /* short packet */
  145. OutOfOrder, /* out of order */
  146. Retrans, /* retransmissions */
  147. DupMsg,
  148. DupBytes,
  149. Nstats,
  150. };
  151. static char *statnames[] =
  152. {
  153. [InMsgs] "InMsgs",
  154. [OutMsgs] "OutMsgs",
  155. [CsumErrs] "CsumErrs",
  156. [HlenErrs] "HlenErr",
  157. [LenErrs] "LenErrs",
  158. [OutOfOrder] "OutOfOrder",
  159. [Retrans] "Retrans",
  160. [DupMsg] "DupMsg",
  161. [DupBytes] "DupBytes",
  162. };
  163. typedef struct Ilpriv Ilpriv;
  164. struct Ilpriv
  165. {
  166. Ipht ht;
  167. ulong stats[Nstats];
  168. ulong csumerr; /* checksum errors */
  169. ulong hlenerr; /* header length error */
  170. ulong lenerr; /* short packet */
  171. ulong order; /* out of order */
  172. ulong rexmit; /* retransmissions */
  173. ulong dup;
  174. ulong dupb;
  175. /* keeping track of the ack kproc */
  176. int ackprocstarted;
  177. QLock apl;
  178. };
  179. /* state for query/dataquery messages */
  180. void ilrcvmsg(Conv*, Block*);
  181. void ilsendctl(Conv*, Ilhdr*, int, ulong, ulong, int);
  182. void ilackq(Ilcb*, Block*);
  183. void ilprocess(Conv*, Ilhdr*, Block*);
  184. void ilpullup(Conv*);
  185. void ilhangup(Conv*, char*);
  186. void ilfreeq(Ilcb*);
  187. void ilrexmit(Ilcb*);
  188. void ilbackoff(Ilcb*);
  189. void ilsettimeout(Ilcb*);
  190. char* ilstart(Conv*, int, int);
  191. void ilackproc(void*);
  192. void iloutoforder(Conv*, Ilhdr*, Block*);
  193. void iliput(Proto*, Ipifc*, Block*);
  194. void iladvise(Proto*, Block*, char*);
  195. int ilnextqt(Ilcb*);
  196. void ilcbinit(Ilcb*);
  197. int later(ulong, ulong, char*);
  198. void ilreject(Fs*, Ilhdr*);
  199. void illocalclose(Conv *c);
  200. int ilcksum = 1;
  201. static int initseq = 25001;
  202. static ulong scalediv, scalemul;
  203. static char *etime = "connection timed out";
  204. static char*
  205. ilconnect(Conv *c, char **argv, int argc)
  206. {
  207. char *e, *p;
  208. int fast;
  209. /* huge hack to quickly try an il connection */
  210. fast = 0;
  211. if(argc > 1){
  212. p = strstr(argv[1], "!fasttimeout");
  213. if(p != nil){
  214. *p = 0;
  215. fast = 1;
  216. }
  217. }
  218. e = Fsstdconnect(c, argv, argc);
  219. if(e != nil)
  220. return e;
  221. return ilstart(c, IL_CONNECT, fast);
  222. }
  223. static int
  224. ilstate(Conv *c, char *state, int n)
  225. {
  226. Ilcb *ic;
  227. ic = (Ilcb*)(c->ptcl);
  228. return snprint(state, n, "%s qin %d qout %d del %5.5d Br %5.5d md %5.5d una %5.5lud rex %5.5d rxq %5.5d max %5.5d",
  229. ilstates[ic->state],
  230. c->rq ? qlen(c->rq) : 0,
  231. c->wq ? qlen(c->wq) : 0,
  232. ic->delay>>LogAGain, ic->rate>>LogAGain, ic->mdev>>LogDGain,
  233. ic->unackedbytes, ic->rxtot, ic->rxquery, ic->maxrtt);
  234. }
  235. static int
  236. ilinuse(Conv *c)
  237. {
  238. Ilcb *ic;
  239. ic = (Ilcb*)(c->ptcl);
  240. return ic->state != Ilclosed;
  241. }
  242. /* called with c locked */
  243. static char*
  244. ilannounce(Conv *c, char **argv, int argc)
  245. {
  246. char *e;
  247. e = Fsstdannounce(c, argv, argc);
  248. if(e != nil)
  249. return e;
  250. e = ilstart(c, IL_LISTEN, 0);
  251. if(e != nil)
  252. return e;
  253. Fsconnected(c, nil);
  254. return nil;
  255. }
  256. void
  257. illocalclose(Conv *c)
  258. {
  259. Ilcb *ic;
  260. Ilpriv *ipriv;
  261. ipriv = c->p->priv;
  262. ic = (Ilcb*)c->ptcl;
  263. ic->state = Ilclosed;
  264. iphtrem(&ipriv->ht, c);
  265. ipmove(c->laddr, IPnoaddr);
  266. c->lport = 0;
  267. }
  268. static void
  269. ilclose(Conv *c)
  270. {
  271. Ilcb *ic;
  272. ic = (Ilcb*)c->ptcl;
  273. qclose(c->rq);
  274. qclose(c->wq);
  275. qclose(c->eq);
  276. switch(ic->state) {
  277. case Ilclosing:
  278. case Ilclosed:
  279. break;
  280. case Ilsyncer:
  281. case Ilsyncee:
  282. case Ilestablished:
  283. ic->state = Ilclosing;
  284. ilsettimeout(ic);
  285. ilsendctl(c, nil, Ilclose, ic->next, ic->recvd, 0);
  286. break;
  287. case Illistening:
  288. illocalclose(c);
  289. break;
  290. }
  291. ilfreeq(ic);
  292. }
  293. void
  294. ilkick(void *x, Block *bp)
  295. {
  296. Conv *c = x;
  297. Ilhdr *ih;
  298. Ilcb *ic;
  299. int dlen;
  300. ulong id, ack;
  301. Fs *f;
  302. Ilpriv *priv;
  303. f = c->p->f;
  304. priv = c->p->priv;
  305. ic = (Ilcb*)c->ptcl;
  306. if(bp == nil)
  307. return;
  308. switch(ic->state) {
  309. case Ilclosed:
  310. case Illistening:
  311. case Ilclosing:
  312. freeblist(bp);
  313. qhangup(c->rq, nil);
  314. return;
  315. }
  316. dlen = blocklen(bp);
  317. /* Make space to fit il & ip */
  318. bp = padblock(bp, IL_IPSIZE+IL_HDRSIZE);
  319. ih = (Ilhdr *)(bp->rp);
  320. ih->vihl = IP_VER4;
  321. /* Ip fields */
  322. ih->frag[0] = 0;
  323. ih->frag[1] = 0;
  324. v6tov4(ih->dst, c->raddr);
  325. v6tov4(ih->src, c->laddr);
  326. ih->proto = IP_ILPROTO;
  327. /* Il fields */
  328. hnputs(ih->illen, dlen+IL_HDRSIZE);
  329. hnputs(ih->ilsrc, c->lport);
  330. hnputs(ih->ildst, c->rport);
  331. qlock(&ic->ackq);
  332. id = ic->next++;
  333. hnputl(ih->ilid, id);
  334. ack = ic->recvd;
  335. hnputl(ih->ilack, ack);
  336. ic->acksent = ack;
  337. ic->acktime = NOW + AckDelay;
  338. ih->iltype = Ildata;
  339. ih->ilspec = 0;
  340. ih->ilsum[0] = 0;
  341. ih->ilsum[1] = 0;
  342. /* Checksum of ilheader plus data (not ip & no pseudo header) */
  343. if(ilcksum)
  344. hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, dlen+IL_HDRSIZE));
  345. ilackq(ic, bp);
  346. qunlock(&ic->ackq);
  347. /* Start the round trip timer for this packet if the timer is free */
  348. if(ic->rttack == 0) {
  349. ic->rttack = id;
  350. ic->rttstart = fastticks(nil);
  351. ic->rttlen = dlen + IL_IPSIZE + IL_HDRSIZE;
  352. }
  353. if(later(NOW, ic->timeout, nil))
  354. ilsettimeout(ic);
  355. ipoput4(f, bp, 0, c->ttl, c->tos, c);
  356. priv->stats[OutMsgs]++;
  357. }
  358. static void
  359. ilcreate(Conv *c)
  360. {
  361. c->rq = qopen(64*1024, 0, 0, c);
  362. c->wq = qbypass(ilkick, c);
  363. }
  364. int
  365. ilxstats(Proto *il, char *buf, int len)
  366. {
  367. Ilpriv *priv;
  368. char *p, *e;
  369. int i;
  370. priv = il->priv;
  371. p = buf;
  372. e = p+len;
  373. for(i = 0; i < Nstats; i++)
  374. p = seprint(p, e, "%s: %lud\n", statnames[i], priv->stats[i]);
  375. return p - buf;
  376. }
  377. void
  378. ilackq(Ilcb *ic, Block *bp)
  379. {
  380. Block *np;
  381. int n;
  382. n = blocklen(bp);
  383. /* Enqueue a copy on the unacked queue in case this one gets lost */
  384. np = copyblock(bp, n);
  385. if(ic->unacked)
  386. ic->unackedtail->list = np;
  387. else
  388. ic->unacked = np;
  389. ic->unackedtail = np;
  390. np->list = nil;
  391. ic->unackedbytes += n;
  392. }
  393. static
  394. void
  395. ilrttcalc(Ilcb *ic, Block *bp)
  396. {
  397. int rtt, tt, pt, delay, rate;
  398. rtt = fastticks(nil) - ic->rttstart;
  399. rtt = (rtt*scalemul)/scalediv;
  400. delay = ic->delay;
  401. rate = ic->rate;
  402. /* Guard against zero wrap */
  403. if(rtt > 120000 || rtt < 0)
  404. return;
  405. /* this block had to be transmitted after the one acked so count its size */
  406. ic->rttlen += blocklen(bp) + IL_IPSIZE + IL_HDRSIZE;
  407. if(ic->rttlen < 256){
  408. /* guess fixed delay as rtt of small packets */
  409. delay += rtt - (delay>>LogAGain);
  410. if(delay < AGain)
  411. delay = AGain;
  412. ic->delay = delay;
  413. } else {
  414. /* if packet took longer than avg rtt delay, recalc rate */
  415. tt = rtt - (delay>>LogAGain);
  416. if(tt > 0){
  417. rate += ic->rttlen/tt - (rate>>LogAGain);
  418. if(rate < AGain)
  419. rate = AGain;
  420. ic->rate = rate;
  421. }
  422. }
  423. /* mdev */
  424. pt = ic->rttlen/(rate>>LogAGain) + (delay>>LogAGain);
  425. ic->mdev += abs(rtt-pt) - (ic->mdev>>LogDGain);
  426. if(rtt > ic->maxrtt)
  427. ic->maxrtt = rtt;
  428. }
  429. void
  430. ilackto(Ilcb *ic, ulong ackto, Block *bp)
  431. {
  432. Ilhdr *h;
  433. ulong id;
  434. if(ic->rttack == ackto)
  435. ilrttcalc(ic, bp);
  436. /* Cancel if we've passed the packet we were interested in */
  437. if(ic->rttack <= ackto)
  438. ic->rttack = 0;
  439. qlock(&ic->ackq);
  440. while(ic->unacked) {
  441. h = (Ilhdr *)ic->unacked->rp;
  442. id = nhgetl(h->ilid);
  443. if(ackto < id)
  444. break;
  445. bp = ic->unacked;
  446. ic->unacked = bp->list;
  447. bp->list = nil;
  448. ic->unackedbytes -= blocklen(bp);
  449. freeblist(bp);
  450. ic->rexmit = 0;
  451. ilsettimeout(ic);
  452. }
  453. qunlock(&ic->ackq);
  454. }
  455. void
  456. iliput(Proto *il, Ipifc*, Block *bp)
  457. {
  458. char *st;
  459. Ilcb *ic;
  460. Ilhdr *ih;
  461. uchar raddr[IPaddrlen];
  462. uchar laddr[IPaddrlen];
  463. ushort sp, dp, csum;
  464. int plen, illen;
  465. Conv *new, *s;
  466. Ilpriv *ipriv;
  467. ipriv = il->priv;
  468. ih = (Ilhdr *)bp->rp;
  469. plen = blocklen(bp);
  470. if(plen < IL_IPSIZE+IL_HDRSIZE){
  471. netlog(il->f, Logil, "il: hlenerr\n");
  472. ipriv->stats[HlenErrs]++;
  473. goto raise;
  474. }
  475. illen = nhgets(ih->illen);
  476. if(illen+IL_IPSIZE > plen){
  477. netlog(il->f, Logil, "il: lenerr\n");
  478. ipriv->stats[LenErrs]++;
  479. goto raise;
  480. }
  481. sp = nhgets(ih->ildst);
  482. dp = nhgets(ih->ilsrc);
  483. v4tov6(raddr, ih->src);
  484. v4tov6(laddr, ih->dst);
  485. if((csum = ptclcsum(bp, IL_IPSIZE, illen)) != 0) {
  486. if(ih->iltype > Ilclose)
  487. st = "?";
  488. else
  489. st = iltype[ih->iltype];
  490. ipriv->stats[CsumErrs]++;
  491. netlog(il->f, Logil, "il: cksum %ux %ux, pkt(%s id %lud ack %lud %I/%d->%d)\n",
  492. csum, st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
  493. goto raise;
  494. }
  495. qlock(il);
  496. s = iphtlook(&ipriv->ht, raddr, dp, laddr, sp);
  497. if(s == nil){
  498. if(ih->iltype == Ilsync)
  499. ilreject(il->f, ih); /* no listener */
  500. qunlock(il);
  501. goto raise;
  502. }
  503. ic = (Ilcb*)s->ptcl;
  504. if(ic->state == Illistening){
  505. if(ih->iltype != Ilsync){
  506. qunlock(il);
  507. if(ih->iltype > Ilclose)
  508. st = "?";
  509. else
  510. st = iltype[ih->iltype];
  511. ilreject(il->f, ih); /* no channel and not sync */
  512. netlog(il->f, Logil, "il: no channel, pkt(%s id %lud ack %lud %I/%ud->%ud)\n",
  513. st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
  514. goto raise;
  515. }
  516. new = Fsnewcall(s, raddr, dp, laddr, sp, V4);
  517. if(new == nil){
  518. qunlock(il);
  519. netlog(il->f, Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp);
  520. ilsendctl(s, ih, Ilclose, 0, nhgetl(ih->ilid), 0);
  521. goto raise;
  522. }
  523. s = new;
  524. ic = (Ilcb*)s->ptcl;
  525. ic->conv = s;
  526. ic->state = Ilsyncee;
  527. ilcbinit(ic);
  528. ic->rstart = nhgetl(ih->ilid);
  529. iphtadd(&ipriv->ht, s);
  530. }
  531. qlock(s);
  532. qunlock(il);
  533. if(waserror()){
  534. qunlock(s);
  535. nexterror();
  536. }
  537. ilprocess(s, ih, bp);
  538. qunlock(s);
  539. poperror();
  540. return;
  541. raise:
  542. freeblist(bp);
  543. }
  544. void
  545. _ilprocess(Conv *s, Ilhdr *h, Block *bp)
  546. {
  547. Ilcb *ic;
  548. ulong id, ack;
  549. Ilpriv *priv;
  550. id = nhgetl(h->ilid);
  551. ack = nhgetl(h->ilack);
  552. ic = (Ilcb*)s->ptcl;
  553. ic->lastrecv = NOW;
  554. ic->querytime = NOW + QueryTime;
  555. priv = s->p->priv;
  556. priv->stats[InMsgs]++;
  557. switch(ic->state) {
  558. default:
  559. netlog(s->p->f, Logil, "il: unknown state %d\n", ic->state);
  560. case Ilclosed:
  561. freeblist(bp);
  562. break;
  563. case Ilsyncer:
  564. switch(h->iltype) {
  565. default:
  566. break;
  567. case Ilsync:
  568. if(ack != ic->start)
  569. ilhangup(s, "connection rejected");
  570. else {
  571. ic->recvd = id;
  572. ic->rstart = id;
  573. ilsendctl(s, nil, Ilack, ic->next, ic->recvd, 0);
  574. ic->state = Ilestablished;
  575. ic->fasttimeout = 0;
  576. ic->rexmit = 0;
  577. Fsconnected(s, nil);
  578. ilpullup(s);
  579. }
  580. break;
  581. case Ilclose:
  582. if(ack == ic->start)
  583. ilhangup(s, "connection rejected");
  584. break;
  585. }
  586. freeblist(bp);
  587. break;
  588. case Ilsyncee:
  589. switch(h->iltype) {
  590. default:
  591. break;
  592. case Ilsync:
  593. if(id != ic->rstart || ack != 0){
  594. illocalclose(s);
  595. } else {
  596. ic->recvd = id;
  597. ilsendctl(s, nil, Ilsync, ic->start, ic->recvd, 0);
  598. }
  599. break;
  600. case Ilack:
  601. if(ack == ic->start) {
  602. ic->state = Ilestablished;
  603. ic->fasttimeout = 0;
  604. ic->rexmit = 0;
  605. ilpullup(s);
  606. }
  607. break;
  608. case Ildata:
  609. if(ack == ic->start) {
  610. ic->state = Ilestablished;
  611. ic->fasttimeout = 0;
  612. ic->rexmit = 0;
  613. goto established;
  614. }
  615. break;
  616. case Ilclose:
  617. if(ack == ic->start)
  618. ilhangup(s, "remote close");
  619. break;
  620. }
  621. freeblist(bp);
  622. break;
  623. case Ilestablished:
  624. established:
  625. switch(h->iltype) {
  626. case Ilsync:
  627. if(id != ic->rstart)
  628. ilhangup(s, "remote close");
  629. else
  630. ilsendctl(s, nil, Ilack, ic->next, ic->rstart, 0);
  631. freeblist(bp);
  632. break;
  633. case Ildata:
  634. ilackto(ic, ack, bp);
  635. iloutoforder(s, h, bp);
  636. ilpullup(s);
  637. break;
  638. case Ildataquery:
  639. ilackto(ic, ack, bp);
  640. iloutoforder(s, h, bp);
  641. ilpullup(s);
  642. ilsendctl(s, nil, Ilstate, ic->next, ic->recvd, h->ilspec);
  643. break;
  644. case Ilack:
  645. ilackto(ic, ack, bp);
  646. freeblist(bp);
  647. break;
  648. case Ilquery:
  649. ilackto(ic, ack, bp);
  650. ilsendctl(s, nil, Ilstate, ic->next, ic->recvd, h->ilspec);
  651. freeblist(bp);
  652. break;
  653. case Ilstate:
  654. if(ack >= ic->rttack)
  655. ic->rttack = 0;
  656. ilackto(ic, ack, bp);
  657. if(h->ilspec > Nqt)
  658. h->ilspec = 0;
  659. if(ic->qt[h->ilspec] > ack){
  660. ilrexmit(ic);
  661. ilsettimeout(ic);
  662. }
  663. freeblist(bp);
  664. break;
  665. case Ilclose:
  666. freeblist(bp);
  667. if(ack < ic->start || ack > ic->next)
  668. break;
  669. ic->recvd = id;
  670. ilsendctl(s, nil, Ilclose, ic->next, ic->recvd, 0);
  671. ic->state = Ilclosing;
  672. ilsettimeout(ic);
  673. ilfreeq(ic);
  674. break;
  675. }
  676. break;
  677. case Illistening:
  678. freeblist(bp);
  679. break;
  680. case Ilclosing:
  681. switch(h->iltype) {
  682. case Ilclose:
  683. ic->recvd = id;
  684. ilsendctl(s, nil, Ilclose, ic->next, ic->recvd, 0);
  685. if(ack == ic->next)
  686. ilhangup(s, nil);
  687. break;
  688. default:
  689. break;
  690. }
  691. freeblist(bp);
  692. break;
  693. }
  694. }
  695. void
  696. ilrexmit(Ilcb *ic)
  697. {
  698. Ilhdr *h;
  699. Block *nb;
  700. Conv *c;
  701. ulong id;
  702. Ilpriv *priv;
  703. nb = nil;
  704. qlock(&ic->ackq);
  705. if(ic->unacked)
  706. nb = copyblock(ic->unacked, blocklen(ic->unacked));
  707. qunlock(&ic->ackq);
  708. if(nb == nil)
  709. return;
  710. h = (Ilhdr*)nb->rp;
  711. h->vihl = IP_VER4;
  712. h->iltype = Ildataquery;
  713. hnputl(h->ilack, ic->recvd);
  714. h->ilspec = ilnextqt(ic);
  715. h->ilsum[0] = 0;
  716. h->ilsum[1] = 0;
  717. hnputs(h->ilsum, ptclcsum(nb, IL_IPSIZE, nhgets(h->illen)));
  718. c = ic->conv;
  719. id = nhgetl(h->ilid);
  720. netlog(c->p->f, Logil, "il: rexmit %d %ud: %d %d: %i %d/%d\n", id, ic->recvd,
  721. ic->rexmit, ic->timeout,
  722. c->raddr, c->lport, c->rport);
  723. ilbackoff(ic);
  724. ipoput4(c->p->f, nb, 0, c->ttl, c->tos, c);
  725. /* statistics */
  726. ic->rxtot++;
  727. priv = c->p->priv;
  728. priv->rexmit++;
  729. }
  730. /* DEBUG */
  731. void
  732. ilprocess(Conv *s, Ilhdr *h, Block *bp)
  733. {
  734. Ilcb *ic;
  735. ic = (Ilcb*)s->ptcl;
  736. USED(ic);
  737. netlog(s->p->f, Logilmsg, "%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
  738. ilstates[ic->state], ic->rstart, ic->recvd, ic->start,
  739. ic->next, iltype[h->iltype], nhgetl(h->ilid),
  740. nhgetl(h->ilack), nhgets(h->ilsrc), nhgets(h->ildst));
  741. _ilprocess(s, h, bp);
  742. netlog(s->p->f, Logilmsg, "%11s rcv %d snt %d\n", ilstates[ic->state], ic->recvd, ic->next);
  743. }
  744. void
  745. ilhangup(Conv *s, char *msg)
  746. {
  747. Ilcb *ic;
  748. int callout;
  749. netlog(s->p->f, Logil, "il: hangup! %I %d/%d: %s\n", s->raddr,
  750. s->lport, s->rport, msg?msg:"no reason");
  751. ic = (Ilcb*)s->ptcl;
  752. callout = ic->state == Ilsyncer;
  753. illocalclose(s);
  754. qhangup(s->rq, msg);
  755. qhangup(s->wq, msg);
  756. if(callout)
  757. Fsconnected(s, msg);
  758. }
  759. void
  760. ilpullup(Conv *s)
  761. {
  762. Ilcb *ic;
  763. Ilhdr *oh;
  764. Block *bp;
  765. ulong oid, dlen;
  766. Ilpriv *ipriv;
  767. ic = (Ilcb*)s->ptcl;
  768. if(ic->state != Ilestablished)
  769. return;
  770. qlock(&ic->outo);
  771. while(ic->outoforder) {
  772. bp = ic->outoforder;
  773. oh = (Ilhdr*)bp->rp;
  774. oid = nhgetl(oh->ilid);
  775. if(oid <= ic->recvd) {
  776. ic->outoforder = bp->list;
  777. freeblist(bp);
  778. continue;
  779. }
  780. if(oid != ic->recvd+1){
  781. ipriv = s->p->priv;
  782. ipriv->stats[OutOfOrder]++;
  783. break;
  784. }
  785. ic->recvd = oid;
  786. ic->outoforder = bp->list;
  787. bp->list = nil;
  788. dlen = nhgets(oh->illen)-IL_HDRSIZE;
  789. bp = trimblock(bp, IL_IPSIZE+IL_HDRSIZE, dlen);
  790. /*
  791. * Upper levels don't know about multiple-block
  792. * messages so copy all into one (yick).
  793. */
  794. bp = concatblock(bp);
  795. if(bp == 0)
  796. panic("ilpullup");
  797. bp = packblock(bp);
  798. if(bp == 0)
  799. panic("ilpullup2");
  800. qpassnolim(s->rq, bp);
  801. }
  802. qunlock(&ic->outo);
  803. }
  804. void
  805. iloutoforder(Conv *s, Ilhdr *h, Block *bp)
  806. {
  807. Ilcb *ic;
  808. uchar *lid;
  809. Block *f, **l;
  810. ulong id, newid;
  811. Ilpriv *ipriv;
  812. ipriv = s->p->priv;
  813. ic = (Ilcb*)s->ptcl;
  814. bp->list = nil;
  815. id = nhgetl(h->ilid);
  816. /* Window checks */
  817. if(id <= ic->recvd || id > ic->recvd+ic->window) {
  818. netlog(s->p->f, Logil, "il: message outside window %ud <%ud-%ud>: %i %d/%d\n",
  819. id, ic->recvd, ic->recvd+ic->window, s->raddr, s->lport, s->rport);
  820. freeblist(bp);
  821. return;
  822. }
  823. /* Packet is acceptable so sort onto receive queue for pullup */
  824. qlock(&ic->outo);
  825. if(ic->outoforder == nil)
  826. ic->outoforder = bp;
  827. else {
  828. l = &ic->outoforder;
  829. for(f = *l; f; f = f->list) {
  830. lid = ((Ilhdr*)(f->rp))->ilid;
  831. newid = nhgetl(lid);
  832. if(id <= newid) {
  833. if(id == newid) {
  834. ipriv->stats[DupMsg]++;
  835. ipriv->stats[DupBytes] += blocklen(bp);
  836. qunlock(&ic->outo);
  837. freeblist(bp);
  838. return;
  839. }
  840. bp->list = f;
  841. *l = bp;
  842. qunlock(&ic->outo);
  843. return;
  844. }
  845. l = &f->list;
  846. }
  847. *l = bp;
  848. }
  849. qunlock(&ic->outo);
  850. }
  851. void
  852. ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
  853. {
  854. Ilhdr *ih;
  855. Ilcb *ic;
  856. Block *bp;
  857. int ttl, tos;
  858. bp = allocb(IL_IPSIZE+IL_HDRSIZE);
  859. bp->wp += IL_IPSIZE+IL_HDRSIZE;
  860. ih = (Ilhdr *)(bp->rp);
  861. ih->vihl = IP_VER4;
  862. /* Ip fields */
  863. ih->proto = IP_ILPROTO;
  864. hnputs(ih->illen, IL_HDRSIZE);
  865. ih->frag[0] = 0;
  866. ih->frag[1] = 0;
  867. if(inih) {
  868. hnputl(ih->dst, nhgetl(inih->src));
  869. hnputl(ih->src, nhgetl(inih->dst));
  870. hnputs(ih->ilsrc, nhgets(inih->ildst));
  871. hnputs(ih->ildst, nhgets(inih->ilsrc));
  872. hnputl(ih->ilid, nhgetl(inih->ilack));
  873. hnputl(ih->ilack, nhgetl(inih->ilid));
  874. ttl = MAXTTL;
  875. tos = DFLTTOS;
  876. }
  877. else {
  878. v6tov4(ih->dst, ipc->raddr);
  879. v6tov4(ih->src, ipc->laddr);
  880. hnputs(ih->ilsrc, ipc->lport);
  881. hnputs(ih->ildst, ipc->rport);
  882. hnputl(ih->ilid, id);
  883. hnputl(ih->ilack, ack);
  884. ic = (Ilcb*)ipc->ptcl;
  885. ic->acksent = ack;
  886. ic->acktime = NOW;
  887. ttl = ipc->ttl;
  888. tos = ipc->tos;
  889. }
  890. ih->iltype = type;
  891. ih->ilspec = ilspec;
  892. ih->ilsum[0] = 0;
  893. ih->ilsum[1] = 0;
  894. if(ilcksum)
  895. hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, IL_HDRSIZE));
  896. if(ipc==nil)
  897. panic("ipc is nil caller is %.8lux", getcallerpc(&ipc));
  898. if(ipc->p==nil)
  899. panic("ipc->p is nil");
  900. netlog(ipc->p->f, Logilmsg, "ctl(%s id %d ack %d %d->%d)\n",
  901. iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
  902. nhgets(ih->ilsrc), nhgets(ih->ildst));
  903. ipoput4(ipc->p->f, bp, 0, ttl, tos, ipc);
  904. }
  905. void
  906. ilreject(Fs *f, Ilhdr *inih)
  907. {
  908. Ilhdr *ih;
  909. Block *bp;
  910. bp = allocb(IL_IPSIZE+IL_HDRSIZE);
  911. bp->wp += IL_IPSIZE+IL_HDRSIZE;
  912. ih = (Ilhdr *)(bp->rp);
  913. ih->vihl = IP_VER4;
  914. /* Ip fields */
  915. ih->proto = IP_ILPROTO;
  916. hnputs(ih->illen, IL_HDRSIZE);
  917. ih->frag[0] = 0;
  918. ih->frag[1] = 0;
  919. hnputl(ih->dst, nhgetl(inih->src));
  920. hnputl(ih->src, nhgetl(inih->dst));
  921. hnputs(ih->ilsrc, nhgets(inih->ildst));
  922. hnputs(ih->ildst, nhgets(inih->ilsrc));
  923. hnputl(ih->ilid, nhgetl(inih->ilack));
  924. hnputl(ih->ilack, nhgetl(inih->ilid));
  925. ih->iltype = Ilclose;
  926. ih->ilspec = 0;
  927. ih->ilsum[0] = 0;
  928. ih->ilsum[1] = 0;
  929. if(ilcksum)
  930. hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, IL_HDRSIZE));
  931. ipoput4(f, bp, 0, MAXTTL, DFLTTOS, nil);
  932. }
  933. void
  934. ilsettimeout(Ilcb *ic)
  935. {
  936. ulong pt;
  937. pt = (ic->delay>>LogAGain)
  938. + ic->unackedbytes/(ic->rate>>LogAGain)
  939. + (ic->mdev>>(LogDGain-1))
  940. + AckDelay;
  941. if(pt > MaxTimeout)
  942. pt = MaxTimeout;
  943. ic->timeout = NOW + pt;
  944. }
  945. void
  946. ilbackoff(Ilcb *ic)
  947. {
  948. ulong pt;
  949. int i;
  950. pt = (ic->delay>>LogAGain)
  951. + ic->unackedbytes/(ic->rate>>LogAGain)
  952. + (ic->mdev>>(LogDGain-1))
  953. + AckDelay;
  954. for(i = 0; i < ic->rexmit; i++)
  955. pt = pt + (pt>>1);
  956. if(pt > MaxTimeout)
  957. pt = MaxTimeout;
  958. ic->timeout = NOW + pt;
  959. if(ic->fasttimeout)
  960. ic->timeout = NOW+Iltickms;
  961. ic->rexmit++;
  962. }
  963. // complain if two numbers not within an hour of each other
  964. #define Tfuture (1000*60*60)
  965. int
  966. later(ulong t1, ulong t2, char *x)
  967. {
  968. int dt;
  969. dt = t1 - t2;
  970. if(dt > 0) {
  971. if(x != nil && dt > Tfuture)
  972. print("%s: way future %d\n", x, dt);
  973. return 1;
  974. }
  975. if(dt < -Tfuture) {
  976. if(x != nil)
  977. print("%s: way past %d\n", x, -dt);
  978. return 1;
  979. }
  980. return 0;
  981. }
  982. void
  983. ilackproc(void *x)
  984. {
  985. Ilcb *ic;
  986. Conv **s, *p;
  987. Proto *il;
  988. il = x;
  989. loop:
  990. tsleep(&up->sleep, return0, 0, Iltickms);
  991. for(s = il->conv; s && *s; s++) {
  992. p = *s;
  993. ic = (Ilcb*)p->ptcl;
  994. switch(ic->state) {
  995. case Ilclosed:
  996. case Illistening:
  997. break;
  998. case Ilclosing:
  999. if(later(NOW, ic->timeout, "timeout0")) {
  1000. if(ic->rexmit > MaxRexmit){
  1001. ilhangup(p, nil);
  1002. break;
  1003. }
  1004. ilsendctl(p, nil, Ilclose, ic->next, ic->recvd, 0);
  1005. ilbackoff(ic);
  1006. }
  1007. break;
  1008. case Ilsyncee:
  1009. case Ilsyncer:
  1010. if(later(NOW, ic->timeout, "timeout1")) {
  1011. if(ic->rexmit > MaxRexmit){
  1012. ilhangup(p, etime);
  1013. break;
  1014. }
  1015. ilsendctl(p, nil, Ilsync, ic->start, ic->recvd, 0);
  1016. ilbackoff(ic);
  1017. }
  1018. break;
  1019. case Ilestablished:
  1020. if(ic->recvd != ic->acksent)
  1021. if(later(NOW, ic->acktime, "acktime"))
  1022. ilsendctl(p, nil, Ilack, ic->next, ic->recvd, 0);
  1023. if(later(NOW, ic->querytime, "querytime")){
  1024. if(later(NOW, ic->lastrecv+DeathTime, "deathtime")){
  1025. netlog(il->f, Logil, "il: hangup: deathtime\n");
  1026. ilhangup(p, etime);
  1027. break;
  1028. }
  1029. ilsendctl(p, nil, Ilquery, ic->next, ic->recvd, ilnextqt(ic));
  1030. ic->querytime = NOW + QueryTime;
  1031. }
  1032. if(ic->unacked != nil)
  1033. if(later(NOW, ic->timeout, "timeout2")) {
  1034. if(ic->rexmit > MaxRexmit){
  1035. netlog(il->f, Logil, "il: hangup: too many rexmits\n");
  1036. ilhangup(p, etime);
  1037. break;
  1038. }
  1039. ilsendctl(p, nil, Ilquery, ic->next, ic->recvd, ilnextqt(ic));
  1040. ic->rxquery++;
  1041. ilbackoff(ic);
  1042. }
  1043. break;
  1044. }
  1045. }
  1046. goto loop;
  1047. }
  1048. void
  1049. ilcbinit(Ilcb *ic)
  1050. {
  1051. ic->start = nrand(0x1000000);
  1052. ic->next = ic->start+1;
  1053. ic->recvd = 0;
  1054. ic->window = Defaultwin;
  1055. ic->unackedbytes = 0;
  1056. ic->unacked = nil;
  1057. ic->outoforder = nil;
  1058. ic->rexmit = 0;
  1059. ic->rxtot = 0;
  1060. ic->rxquery = 0;
  1061. ic->qtx = 1;
  1062. ic->fasttimeout = 0;
  1063. /* timers */
  1064. ic->delay = DefRtt<<LogAGain;
  1065. ic->mdev = DefRtt<<LogDGain;
  1066. ic->rate = DefByteRate<<LogAGain;
  1067. ic->querytime = NOW + QueryTime;
  1068. ic->lastrecv = NOW; /* or we'll timeout right away */
  1069. ilsettimeout(ic);
  1070. }
  1071. char*
  1072. ilstart(Conv *c, int type, int fasttimeout)
  1073. {
  1074. Ilcb *ic;
  1075. Ilpriv *ipriv;
  1076. char kpname[KNAMELEN];
  1077. ipriv = c->p->priv;
  1078. if(ipriv->ackprocstarted == 0){
  1079. qlock(&ipriv->apl);
  1080. if(ipriv->ackprocstarted == 0){
  1081. sprint(kpname, "#I%dilack", c->p->f->dev);
  1082. kproc(kpname, ilackproc, c->p);
  1083. ipriv->ackprocstarted = 1;
  1084. }
  1085. qunlock(&ipriv->apl);
  1086. }
  1087. ic = (Ilcb*)c->ptcl;
  1088. ic->conv = c;
  1089. if(ic->state != Ilclosed)
  1090. return nil;
  1091. ilcbinit(ic);
  1092. if(fasttimeout){
  1093. /* timeout if we can't connect quickly */
  1094. ic->fasttimeout = 1;
  1095. ic->timeout = NOW+Iltickms;
  1096. ic->rexmit = MaxRexmit - 4;
  1097. };
  1098. switch(type) {
  1099. default:
  1100. netlog(c->p->f, Logil, "il: start: type %d\n", type);
  1101. break;
  1102. case IL_LISTEN:
  1103. ic->state = Illistening;
  1104. iphtadd(&ipriv->ht, c);
  1105. break;
  1106. case IL_CONNECT:
  1107. ic->state = Ilsyncer;
  1108. iphtadd(&ipriv->ht, c);
  1109. ilsendctl(c, nil, Ilsync, ic->start, ic->recvd, 0);
  1110. break;
  1111. }
  1112. return nil;
  1113. }
  1114. void
  1115. ilfreeq(Ilcb *ic)
  1116. {
  1117. Block *bp, *next;
  1118. qlock(&ic->ackq);
  1119. for(bp = ic->unacked; bp; bp = next) {
  1120. next = bp->list;
  1121. freeblist(bp);
  1122. }
  1123. ic->unacked = nil;
  1124. qunlock(&ic->ackq);
  1125. qlock(&ic->outo);
  1126. for(bp = ic->outoforder; bp; bp = next) {
  1127. next = bp->list;
  1128. freeblist(bp);
  1129. }
  1130. ic->outoforder = nil;
  1131. qunlock(&ic->outo);
  1132. }
  1133. void
  1134. iladvise(Proto *il, Block *bp, char *msg)
  1135. {
  1136. Ilhdr *h;
  1137. Ilcb *ic;
  1138. uchar source[IPaddrlen], dest[IPaddrlen];
  1139. ushort psource;
  1140. Conv *s, **p;
  1141. h = (Ilhdr*)(bp->rp);
  1142. v4tov6(dest, h->dst);
  1143. v4tov6(source, h->src);
  1144. psource = nhgets(h->ilsrc);
  1145. /* Look for a connection, unfortunately the destination port is missing */
  1146. qlock(il);
  1147. for(p = il->conv; *p; p++) {
  1148. s = *p;
  1149. if(s->lport == psource)
  1150. if(ipcmp(s->laddr, source) == 0)
  1151. if(ipcmp(s->raddr, dest) == 0){
  1152. qunlock(il);
  1153. ic = (Ilcb*)s->ptcl;
  1154. switch(ic->state){
  1155. case Ilsyncer:
  1156. ilhangup(s, msg);
  1157. break;
  1158. }
  1159. freeblist(bp);
  1160. return;
  1161. }
  1162. }
  1163. qunlock(il);
  1164. freeblist(bp);
  1165. }
  1166. int
  1167. ilnextqt(Ilcb *ic)
  1168. {
  1169. int x;
  1170. qlock(&ic->ackq);
  1171. x = ic->qtx;
  1172. if(++x > Nqt)
  1173. x = 1;
  1174. ic->qtx = x;
  1175. ic->qt[x] = ic->next-1; /* highest xmitted packet */
  1176. ic->qt[0] = ic->qt[x]; /* compatibility with old implementations */
  1177. qunlock(&ic->ackq);
  1178. return x;
  1179. }
  1180. /* calculate scale constants that converts fast ticks to ms (more or less) */
  1181. static void
  1182. inittimescale(void)
  1183. {
  1184. uvlong hz;
  1185. fastticks(&hz);
  1186. if(hz > 1000){
  1187. scalediv = hz/1000;
  1188. scalemul = 1;
  1189. } else {
  1190. scalediv = 1;
  1191. scalemul = 1000/hz;
  1192. }
  1193. }
  1194. void
  1195. ilinit(Fs *f)
  1196. {
  1197. Proto *il;
  1198. inittimescale();
  1199. il = smalloc(sizeof(Proto));
  1200. il->priv = smalloc(sizeof(Ilpriv));
  1201. il->name = "il";
  1202. il->connect = ilconnect;
  1203. il->announce = ilannounce;
  1204. il->state = ilstate;
  1205. il->create = ilcreate;
  1206. il->close = ilclose;
  1207. il->rcv = iliput;
  1208. il->ctl = nil;
  1209. il->advise = iladvise;
  1210. il->stats = ilxstats;
  1211. il->inuse = ilinuse;
  1212. il->gc = nil;
  1213. il->ipproto = IP_ILPROTO;
  1214. il->nc = scalednconv();
  1215. il->ptclsize = sizeof(Ilcb);
  1216. Fsproto(f, il);
  1217. }