il.c 19 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. #include "all.h"
  2. #include "mem.h"
  3. #include "../ip/ip.h"
  4. #define DEBUG if(cons.flags&ilflag)print
  5. #define msec (MACHP(0)->ticks * (1000/HZ))
  6. enum
  7. {
  8. Ilsync = 0, /* Packet types */
  9. Ildata,
  10. Ildataquery,
  11. Ilack,
  12. Ilquery,
  13. Ilstate,
  14. Ilclose,
  15. Ilclosed = 0, /* Connection state */
  16. Ilsyncer,
  17. Ilsyncee,
  18. Ilestablished,
  19. Illistening,
  20. Ilclosing,
  21. Ilopening,
  22. Seconds = 1000,
  23. Iltickms = 50, /* time base */
  24. AckDelay = (Timet)(2*Iltickms), /* max time twixt message rcvd & ack sent */
  25. MaxTimeout = (Timet)(4*Seconds), /* max time between rexmit */
  26. QueryTime = (Timet)(10*Seconds), /* time between subsequent queries */
  27. DeathTime = (Timet)(30*QueryTime),
  28. MaxRexmit = 16, /* max retransmissions before hangup */
  29. DefWin = 20,
  30. LogAGain = 3,
  31. AGain = 1<<LogAGain,
  32. LogDGain = 2,
  33. DGain = 1<<LogDGain,
  34. DefByteRate = 100, /* assume a megabit link */
  35. DefRtt = 50, /* cross country on a great day */
  36. };
  37. static
  38. struct
  39. {
  40. Lock;
  41. Queue* reply;
  42. Chan* chan;
  43. } il;
  44. static void ilout(void);
  45. static void ilprocess(Chan*, Msgbuf*);
  46. static Chan* getchan(Ifc*, Ilpkt*, Msgbuf*);
  47. static void ilhangup(Chan*, char*, int);
  48. static void ilsendctl(Chan*, Ilpkt*, int, ulong, ulong, int);
  49. static void ilpullup(Chan*);
  50. static void ilackto(Chan*, ulong, Msgbuf*);
  51. static void ilrexmit(Ilp*);
  52. static void iloutoforder(Chan*, Ilpkt*, Msgbuf*);
  53. static void ilfreeq(Chan*);
  54. static void ilackq(Chan*, Msgbuf*);
  55. static void ilbackoff(Ilp*);
  56. static void ilsettimeout(Ilp*);
  57. static int ilnextqt(Ilp*);
  58. static void iltimer(void);
  59. static void ilgoaway(Msgbuf*, Ifc*);
  60. static
  61. char* ilstate[] =
  62. {
  63. "Closed",
  64. "Syncer",
  65. "Syncee",
  66. "Established",
  67. "Listening",
  68. "Closing",
  69. "Opening",
  70. };
  71. static
  72. char* iltype[] =
  73. {
  74. "sync",
  75. "data",
  76. "dataquery",
  77. "ack",
  78. "query",
  79. "state",
  80. "close",
  81. };
  82. static Rendez ild;
  83. static int ilflag;
  84. static void
  85. ilwhoprint(Chan* cp)
  86. {
  87. Ilp *ilp;
  88. Timet t;
  89. if(cp->type != Devil)
  90. return;
  91. ilp = cp->pdata;
  92. t = MACHP(0)->ticks * (1000/HZ);
  93. print(" (%d,%d)", ilp->alloc, ilp->state);
  94. print(" (%ld,%ld,%ld)",
  95. ilp->timeout-t, ilp->querytime-t,
  96. ilp->lastrecv-t);
  97. print(" (%ld,%ld,%ld,%ld)", ilp->rate, ilp->delay,
  98. ilp->mdev, ilp->unackedbytes);
  99. }
  100. static
  101. void
  102. ilpinit(Ilp *ilp)
  103. {
  104. ilp->start = (toytime() * 80021) & 0x3fffffffUL;
  105. ilp->next = ilp->start + 1;
  106. ilp->rstart = 0;
  107. ilp->recvd = 0;
  108. ilp->window = DefWin;
  109. ilp->unackedbytes = 0;
  110. ilp->unacked = nil;
  111. ilp->unackedtail = nil;
  112. ilp->outoforder = nil;
  113. ilp->rexmit = 0;
  114. /* timers */
  115. ilp->delay = DefRtt<<LogAGain;
  116. ilp->mdev = DefRtt<<LogDGain;
  117. ilp->rate = DefByteRate<<LogAGain;
  118. ilp->querytime = msec + QueryTime;
  119. ilp->lastrecv = msec; /* to avoid immediate timeout */
  120. ilsettimeout(ilp);
  121. }
  122. static
  123. Chan*
  124. getchan(Ifc *ifc, Ilpkt *p, Msgbuf *mb)
  125. {
  126. Ilp *ilp;
  127. Chan *cp, *xcp;
  128. int srcp, dstp;
  129. srcp = nhgets(p->ilsrc);
  130. dstp = nhgets(p->ildst);
  131. lock(&il);
  132. xcp = 0;
  133. for(cp = il.chan; cp; cp = ilp->chan) {
  134. ilp = cp->pdata;
  135. if(ilp->alloc == 0) {
  136. xcp = cp;
  137. continue;
  138. }
  139. if(srcp == ilp->srcp)
  140. if(dstp == ilp->dstp)
  141. if(memcmp(p->src, ilp->iphis, Pasize) == 0)
  142. if(memcmp(p->dst, ifc->ipa, Pasize) == 0){
  143. unlock(&il);
  144. return cp;
  145. }
  146. }
  147. if(il.reply == 0) {
  148. il.reply = newqueue(Nqueue);
  149. userinit(ilout, &il, "ilo");
  150. userinit(iltimer, &il, "ilt");
  151. ilflag = flag_install("il", "-- on errors");
  152. }
  153. if(dstp != Ilfsport) {
  154. ilgoaway(mb, ifc);
  155. unlock(&il);
  156. DEBUG("open not fsport %I.%d -> %I.%d\n", p->src, srcp, p->dst, dstp);
  157. return nil;
  158. }
  159. if(p->iltype != Ilsync) {
  160. ilgoaway(mb, ifc);
  161. unlock(&il);
  162. DEBUG("open not sync %I.%d -> %I.%d\n", p->src, srcp, p->dst, dstp);
  163. return nil;
  164. }
  165. cp = xcp;
  166. if(cp == 0) {
  167. cp = chaninit(Devil, 1, sizeof(Ilp));
  168. ilp = cp->pdata;
  169. ilp->chan = il.chan;
  170. il.chan = cp;
  171. }
  172. cp->ifc = ifc;
  173. ilp = cp->pdata;
  174. memmove(ilp->iphis, p->src, Pasize);
  175. memmove(ifc->ipa, p->dst, Pasize);
  176. ilp->srcp = srcp;
  177. ilp->dstp = dstp;
  178. ilp->state = Ilopening;
  179. ilpinit(ilp);
  180. memmove(ilp->ipgate, ilp->iphis, Pasize);
  181. if((nhgetl(ifc->ipa)&ifc->mask) != (nhgetl(p->src)&ifc->mask))
  182. iproute(ilp->ipgate, p->src, ifc->netgate);
  183. cp->send = serveq;
  184. cp->reply = il.reply;
  185. ilp->reply = ifc->reply;
  186. cp->protocol = nil;
  187. cp->msize = 0;
  188. cp->whotime = 0;
  189. sprint(cp->whochan, "il!%I!%d", p->src, srcp);
  190. cp->whoprint = ilwhoprint;
  191. ilp->alloc = 1;
  192. unlock(&il);
  193. return cp;
  194. }
  195. void
  196. ilrecv(Msgbuf *mb, Ifc *ifc)
  197. {
  198. Ilpkt *ih;
  199. Chan *cp;
  200. Ilp *ilp;
  201. int illen, plen;
  202. ih = (Ilpkt*)mb->data;
  203. plen = mb->count;
  204. if(plen < Ensize+Ipsize+Ilsize)
  205. goto drop;
  206. illen = nhgets(ih->illen);
  207. if(illen+Ilsize > plen)
  208. goto drop;
  209. if(ptclcsum((uchar*)ih+(Ensize+Ipsize), illen) != 0) {
  210. print("il: cksum error %E %I\n", ih->s, ih->src);
  211. ifc->sumerr++;
  212. goto drop;
  213. }
  214. cp = getchan(ifc, ih, mb);
  215. if(cp == nil)
  216. goto drop;
  217. mb->chan = cp;
  218. ilp = cp->pdata;
  219. if(ilp->state == Ilopening) {
  220. ilp->state = Ilsyncee;
  221. ilpinit(ilp);
  222. ilp->rstart = nhgetl(ih->ilid);
  223. print("il: allocating %s\n", cp->whochan);
  224. }
  225. ilprocess(cp, mb);
  226. return;
  227. drop:
  228. mbfree(mb);
  229. }
  230. /*
  231. * process to convert p9 to il/ip
  232. */
  233. static
  234. void
  235. ilout(void)
  236. {
  237. Ifc *ifc;
  238. Msgbuf *mb;
  239. Ilp *ilp;
  240. Ilpkt *ih;
  241. Chan *cp;
  242. int dlen;
  243. ulong id, ack;
  244. for (;;) {
  245. while ((mb = recv(il.reply, 0)) == nil)
  246. continue;
  247. cp = mb->chan;
  248. ilp = cp->pdata;
  249. switch(ilp->state) {
  250. case Ilclosed:
  251. case Illistening:
  252. case Ilclosing:
  253. print("ilout: error\n");
  254. mbfree(mb);
  255. continue;
  256. }
  257. dlen = mb->count;
  258. mb->data -= Ensize+Ipsize+Ilsize; /* make room for header */
  259. mb->count += Ensize+Ipsize+Ilsize;
  260. if(mb->data < mb->xdata)
  261. panic("ilout: no room for header");
  262. ih = (Ilpkt*)mb->data;
  263. /*
  264. * Ip fields
  265. */
  266. ifc = cp->ifc;
  267. memmove(ih->src, ifc->ipa, Pasize);
  268. memmove(ih->dst, ilp->iphis, Pasize);
  269. ih->proto = Ilproto;
  270. /*
  271. * Il fields
  272. */
  273. hnputs(ih->illen, Ilsize+dlen);
  274. hnputs(ih->ilsrc, ilp->dstp);
  275. hnputs(ih->ildst, ilp->srcp);
  276. id = ilp->next++;
  277. hnputl(ih->ilid, id);
  278. ack = ilp->recvd;
  279. hnputl(ih->ilack, ack);
  280. ilp->acksent = ack;
  281. ilp->acktime = msec + AckDelay;
  282. ih->iltype = Ildata;
  283. ih->ilspec = 0;
  284. ih->ilsum[0] = 0;
  285. ih->ilsum[1] = 0;
  286. /*
  287. * checksum
  288. */
  289. hnputs(ih->ilsum, ptclcsum((uchar*)ih+(Ensize+Ipsize),
  290. dlen+Ilsize));
  291. ilackq(cp, mb);
  292. /*
  293. * Start the round trip timer for this packet if the timer
  294. * is free.
  295. */
  296. if(ilp->rttack == 0) {
  297. ilp->rttack = id;
  298. ilp->rttstart = msec;
  299. ilp->rttlen = dlen+Ipsize+Ilsize;
  300. }
  301. if(ilp->timeout <= msec)
  302. ilsettimeout(ilp);
  303. ipsend(mb);
  304. }
  305. }
  306. static
  307. void
  308. ilackq(Chan *cp, Msgbuf *mb)
  309. {
  310. Msgbuf *nmb;
  311. Ilp *ilp;
  312. /*
  313. * Enqueue a copy on the unacked queue in case this one gets lost
  314. */
  315. /* botch -- a reference count will save this copy */
  316. nmb = mballoc(mb->count, cp, Mbil2);
  317. memmove(nmb->data, mb->data, mb->count);
  318. nmb->next = 0;
  319. ilp = cp->pdata;
  320. lock(ilp);
  321. if(ilp->unacked)
  322. ilp->unackedtail->next = nmb;
  323. else
  324. ilp->unacked = nmb;
  325. ilp->unackedtail = nmb;
  326. ilp->unackedbytes += nmb->count;
  327. unlock(ilp);
  328. }
  329. static
  330. void
  331. ilprocess(Chan *cp, Msgbuf *mb)
  332. {
  333. ulong id, ack;
  334. Ilp* ilp;
  335. Ilpkt *h;
  336. ilp = cp->pdata;
  337. h = (Ilpkt*)mb->data;
  338. id = nhgetl(h->ilid);
  339. ack = nhgetl(h->ilack);
  340. ilp->lastrecv = msec;
  341. switch(ilp->state) {
  342. default:
  343. print("il unknown state\n");
  344. case Ilclosed:
  345. mbfree(mb);
  346. break;
  347. case Ilsyncer:
  348. switch(h->iltype) {
  349. default:
  350. break;
  351. case Ilsync:
  352. if(ack != ilp->start) {
  353. ilp->state = Ilclosed;
  354. ilhangup(cp, "connection rejected", 1);
  355. } else {
  356. ilp->recvd = id;
  357. ilp->rstart = id;
  358. ilsendctl(cp, 0, Ilack, ilp->next, ilp->recvd, 0);
  359. ilp->state = Ilestablished;
  360. wakeup(&ilp->syn);
  361. ilpullup(cp);
  362. }
  363. break;
  364. case Ilclose:
  365. if(ack == ilp->start) {
  366. ilp->state = Ilclosed;
  367. ilhangup(cp, "remote close-1", 1);
  368. }
  369. break;
  370. }
  371. mbfree(mb);
  372. break;
  373. case Ilsyncee:
  374. switch(h->iltype) {
  375. default:
  376. break;
  377. case Ilsync:
  378. if(id != ilp->rstart || ack != 0)
  379. ilp->state = Ilclosed;
  380. else {
  381. ilp->recvd = id;
  382. ilsendctl(cp, 0, Ilsync, ilp->start, ilp->recvd, 0);
  383. }
  384. break;
  385. case Ilack:
  386. if(ack == ilp->start) {
  387. ilp->state = Ilestablished;
  388. ilpullup(cp);
  389. }
  390. break;
  391. case Ildata:
  392. if(ack == ilp->start) {
  393. ilp->state = Ilestablished;
  394. goto established;
  395. }
  396. break;
  397. case Ilclose:
  398. if(id == ilp->next) {
  399. ilp->state = Ilclosed;
  400. ilhangup(cp, "remote close-2", 1);
  401. }
  402. break;
  403. }
  404. mbfree(mb);
  405. break;
  406. case Ilestablished:
  407. established:
  408. switch(h->iltype) {
  409. default:
  410. mbfree(mb);
  411. break;
  412. case Ilsync:
  413. if(id != ilp->rstart) {
  414. ilp->state = Ilclosed;
  415. ilhangup(cp, "remote close-3", 1);
  416. } else
  417. ilsendctl(cp, 0, Ilack, ilp->next, ilp->rstart, 0);
  418. mbfree(mb);
  419. break;
  420. case Ildata:
  421. ilackto(cp, ack, mb);
  422. iloutoforder(cp, h, mb);
  423. ilpullup(cp);
  424. break;
  425. case Ildataquery:
  426. ilackto(cp, ack, mb);
  427. iloutoforder(cp, h, mb);
  428. ilpullup(cp);
  429. ilsendctl(cp, 0, Ilstate, ilp->next, ilp->recvd, h->ilspec);
  430. break;
  431. case Ilack:
  432. ilackto(cp, ack, mb);
  433. mbfree(mb);
  434. break;
  435. case Ilquery:
  436. ilackto(cp, ack, mb);
  437. ilsendctl(cp, 0, Ilstate, ilp->next, ilp->recvd, h->ilspec);
  438. mbfree(mb);
  439. break;
  440. case Ilstate:
  441. if(ack >= ilp->rttack)
  442. ilp->rttack = 0;
  443. ilackto(cp, ack, mb);
  444. if(h->ilspec > Nqt)
  445. h->ilspec = 0;
  446. if(ilp->qt[h->ilspec] > ack){
  447. ilrexmit(ilp);
  448. ilsettimeout(ilp);
  449. }
  450. mbfree(mb);
  451. break;
  452. case Ilclose:
  453. mbfree(mb);
  454. if(ack < ilp->start || ack > ilp->next)
  455. break;
  456. ilp->recvd = id;
  457. ilsendctl(cp, 0, Ilclose, ilp->next, ilp->recvd, 0);
  458. ilp->state = Ilclosing;
  459. ilfreeq(cp);
  460. break;
  461. }
  462. break;
  463. case Illistening:
  464. mbfree(mb);
  465. break;
  466. case Ilclosing:
  467. switch(h->iltype) {
  468. case Ilclose:
  469. ilp->recvd = id;
  470. ilsendctl(cp, 0, Ilclose, ilp->next, ilp->recvd, 0);
  471. if(ack == ilp->next) {
  472. ilp->state = Ilclosed;
  473. ilhangup(cp, "closed", 1);
  474. }
  475. break;
  476. }
  477. mbfree(mb);
  478. break;
  479. }
  480. }
  481. static
  482. void
  483. ilsendctl(Chan *cp, Ilpkt *inih, int type, ulong id, ulong ack, int ilspec)
  484. {
  485. Ifc *ifc;
  486. Ilpkt *ih;
  487. Msgbuf *mb;
  488. Ilp *ilp;
  489. ilp = cp->pdata;
  490. mb = mballoc(Ensize+Ipsize+Ilsize, cp, Mbil3);
  491. ih = (Ilpkt*)mb->data;
  492. ih->proto = Ilproto;
  493. ifc = cp->ifc;
  494. memmove(ih->src, ifc->ipa, Pasize);
  495. hnputs(ih->illen, Ilsize);
  496. if(inih) {
  497. memmove(ih->dst, inih->src, Pasize);
  498. memmove(ih->ilsrc, inih->ildst, sizeof(ih->ilsrc));
  499. memmove(ih->ildst, inih->ilsrc, sizeof(ih->ildst));
  500. memmove(ih->ilid, inih->ilack, sizeof(ih->ilid));
  501. memmove(ih->ilack, inih->ilid, sizeof(ih->ilack));
  502. } else {
  503. memmove(ih->dst, ilp->iphis, Pasize);
  504. hnputs(ih->ilsrc, ilp->dstp);
  505. hnputs(ih->ildst, ilp->srcp);
  506. hnputl(ih->ilid, id);
  507. hnputl(ih->ilack, ack);
  508. ilp->acksent = ack;
  509. ilp->acktime = msec;
  510. }
  511. ih->iltype = type;
  512. ih->ilspec = ilspec;
  513. ih->ilsum[0] = 0;
  514. ih->ilsum[1] = 0;
  515. hnputs(ih->ilsum, ptclcsum((uchar*)mb->data+(Ensize+Ipsize), Ilsize));
  516. ipsend(mb);
  517. }
  518. static
  519. void
  520. ilhangup(Chan *cp, char *msg, int dolock)
  521. {
  522. Ilp *ilp;
  523. int s;
  524. ilp = cp->pdata;
  525. s = ilp->state;
  526. ilp->state = Ilclosed;
  527. if(s == Ilsyncer)
  528. wakeup(&ilp->syn);
  529. if(msg != nil)
  530. print("hangup! %s %d/%I.%d\n", msg, ilp->srcp,
  531. ilp->iphis, ilp->dstp);
  532. ilfreeq(cp);
  533. fileinit(cp);
  534. cp->whotime = 0;
  535. strcpy(cp->whoname, "<none>");
  536. if(dolock)
  537. lock(&il);
  538. ilp->alloc = 0;
  539. ilp->srcp = 0;
  540. ilp->dstp = 0;
  541. memset(ilp->iphis, 0, sizeof(ilp->iphis));
  542. if(dolock)
  543. unlock(&il);
  544. }
  545. static
  546. void
  547. ilpullup(Chan *cp)
  548. {
  549. Ilpkt *oh;
  550. Msgbuf *mb;
  551. Ilp *ilp;
  552. ulong oid, dlen;
  553. ilp = cp->pdata;
  554. lock(ilp);
  555. while(ilp->outoforder) {
  556. mb = ilp->outoforder;
  557. oh = (Ilpkt*)mb->data;
  558. oid = nhgetl(oh->ilid);
  559. if(oid <= ilp->recvd) {
  560. ilp->outoforder = mb->next;
  561. mbfree(mb);
  562. continue;
  563. }
  564. if(oid != ilp->recvd+1)
  565. break;
  566. ilp->recvd = oid;
  567. ilp->outoforder = mb->next;
  568. /*
  569. * strip off the header
  570. */
  571. dlen = nhgets(oh->illen)-Ilsize;
  572. mb->data += Ensize+Ipsize+Ilsize;
  573. mb->count = dlen;
  574. send(cp->send, mb);
  575. }
  576. unlock(ilp);
  577. }
  578. static
  579. void
  580. iloutoforder(Chan *cp, Ilpkt *h, Msgbuf *mb)
  581. {
  582. Msgbuf **l, *f;
  583. Ilp *ilp;
  584. ulong id, ilid;
  585. uchar *lid;
  586. ilp = cp->pdata;
  587. id = nhgetl(h->ilid);
  588. /*
  589. * Window checks
  590. */
  591. if(id <= ilp->recvd || id > ilp->recvd+ilp->window) {
  592. mbfree(mb);
  593. return;
  594. }
  595. /*
  596. * Packet is acceptable so
  597. * sort onto receive queue for pullup
  598. */
  599. mb->next = 0;
  600. lock(ilp);
  601. if(ilp->outoforder == 0) {
  602. ilp->outoforder = mb;
  603. } else {
  604. l = &ilp->outoforder;
  605. for(f = *l; f; f = f->next) {
  606. lid = ((Ilpkt*)(f->data))->ilid;
  607. ilid = nhgetl(lid);
  608. if(id <= ilid) {
  609. if(id == ilid) {
  610. mbfree(mb);
  611. unlock(ilp);
  612. return;
  613. }
  614. mb->next = f;
  615. break;
  616. }
  617. l = &f->next;
  618. }
  619. *l = mb;
  620. }
  621. unlock(ilp);
  622. }
  623. static
  624. void
  625. ilrttcalc(Ilp *ilp, Msgbuf *mb)
  626. {
  627. int rtt, tt, pt, delay, rate;
  628. rtt = msec - ilp->rttstart + TK2MS(1) - 1;
  629. delay = ilp->delay;
  630. rate = ilp->rate;
  631. /* Guard against zero wrap */
  632. if(rtt > 120000 || rtt < 0)
  633. return;
  634. /* this block had to be transmitted after the one acked so count its size */
  635. ilp->rttlen += mb->count+Ipsize+Ilsize;
  636. if(ilp->rttlen < 256){
  637. /* guess fixed delay as rtt of small packets */
  638. delay += rtt - (delay>>LogAGain);
  639. if(delay < AGain)
  640. delay = AGain;
  641. ilp->delay = delay;
  642. } else {
  643. /* if packet took longer than avg rtt delay, recalc rate */
  644. tt = rtt - (delay>>LogAGain);
  645. if(tt > 0){
  646. rate += ilp->rttlen/tt - (rate>>LogAGain);
  647. if(rate < AGain)
  648. rate = AGain;
  649. ilp->rate = rate;
  650. }
  651. }
  652. /* mdev */
  653. pt = ilp->rttlen/(rate>>LogAGain) + (delay>>LogAGain);
  654. ilp->mdev += abs(rtt-pt) - (ilp->mdev>>LogDGain);
  655. if(rtt > ilp->maxrtt)
  656. ilp->maxrtt = rtt;
  657. }
  658. static
  659. void
  660. ilackto(Chan *cp, ulong ackto, Msgbuf *mb)
  661. {
  662. Ilpkt *h;
  663. Ilp *ilp;
  664. ulong id;
  665. ilp = cp->pdata;
  666. if(ilp->rttack == ackto)
  667. ilrttcalc(ilp, mb);
  668. /* Cancel if we lost the packet we were interested in */
  669. if(ilp->rttack <= ackto)
  670. ilp->rttack = 0;
  671. lock(ilp);
  672. while(ilp->unacked) {
  673. h = (Ilpkt*)ilp->unacked->data;
  674. id = nhgetl(h->ilid);
  675. if(ackto < id)
  676. break;
  677. mb = ilp->unacked;
  678. ilp->unacked = mb->next;
  679. mb->next = 0;
  680. ilp->unackedbytes -= mb->count;
  681. mbfree(mb);
  682. ilp->rexmit = 0;
  683. ilsettimeout(ilp);
  684. }
  685. unlock(ilp);
  686. }
  687. static
  688. void
  689. ilrexmit(Ilp *ilp)
  690. {
  691. Msgbuf *omb, *mb;
  692. Ilpkt *h;
  693. lock(ilp);
  694. omb = ilp->unacked;
  695. if(omb == 0) {
  696. unlock(ilp);
  697. return;
  698. }
  699. /* botch -- a reference count will save this copy */
  700. mb = mballoc(omb->count, omb->chan, Mbil4);
  701. memmove(mb->data, omb->data, omb->count);
  702. unlock(ilp);
  703. h = (Ilpkt*)mb->data;
  704. h->iltype = Ildataquery;
  705. hnputl(h->ilack, ilp->recvd);
  706. h->ilspec = ilnextqt(ilp);
  707. h->ilsum[0] = 0;
  708. h->ilsum[1] = 0;
  709. hnputs(h->ilsum, ptclcsum((uchar*)mb->data+(Ensize+Ipsize), nhgets(h->illen)));
  710. ilbackoff(ilp);
  711. ipsend(mb);
  712. }
  713. static
  714. void
  715. ilfreeq(Chan *cp)
  716. {
  717. Ilp *ilp;
  718. Msgbuf *mb, *next;
  719. ilp = cp->pdata;
  720. lock(ilp);
  721. for(mb = ilp->unacked; mb; mb = next) {
  722. next = mb->next;
  723. mbfree(mb);
  724. }
  725. ilp->unacked = 0;
  726. for(mb = ilp->outoforder; mb; mb = next) {
  727. next = mb->next;
  728. mbfree(mb);
  729. }
  730. ilp->outoforder = 0;
  731. unlock(ilp);
  732. }
  733. static
  734. void
  735. ilsettimeout(Ilp *ilp)
  736. {
  737. Timet pt;
  738. pt = (ilp->delay>>LogAGain)
  739. + ilp->unackedbytes/(ilp->rate>>LogAGain)
  740. + (ilp->mdev>>(LogDGain-1))
  741. + AckDelay;
  742. if(pt > MaxTimeout)
  743. pt = MaxTimeout;
  744. ilp->timeout = msec + pt;
  745. }
  746. static
  747. void
  748. ilbackoff(Ilp *ilp)
  749. {
  750. Timet pt;
  751. int i;
  752. pt = (ilp->delay>>LogAGain)
  753. + ilp->unackedbytes/(ilp->rate>>LogAGain)
  754. + (ilp->mdev>>(LogDGain-1))
  755. + AckDelay;
  756. for(i = 0; i < ilp->rexmit; i++)
  757. pt = pt + (pt>>1);
  758. if(pt > MaxTimeout)
  759. pt = MaxTimeout;
  760. ilp->timeout = msec + pt;
  761. ilp->rexmit++;
  762. }
  763. /*
  764. * il timer
  765. * every 100ms
  766. */
  767. static Rendez ilt;
  768. static
  769. void
  770. callil(Alarm *a, void *)
  771. {
  772. cancel(a);
  773. wakeup(&ilt);
  774. }
  775. // complain if two numbers not within an hour of each other
  776. #define Tfuture (1000*60*60)
  777. int
  778. later(Timet t1, Timet t2, char *x)
  779. {
  780. Timet dt;
  781. dt = t1 - t2;
  782. if(dt > 0) {
  783. if(dt > Tfuture)
  784. print("%s: way future %ld\n", x, dt);
  785. return 1;
  786. }
  787. if(dt < -Tfuture) {
  788. print("%s: way past %ld\n", x, -dt);
  789. return 1;
  790. }
  791. return 0;
  792. }
  793. static
  794. void
  795. iltimer(void)
  796. {
  797. Chan *cp;
  798. Ilp *ilp;
  799. loop:
  800. lock(&il);
  801. for(cp = il.chan; cp; cp = ilp->chan) {
  802. ilp = cp->pdata;
  803. if(ilp->alloc == 0)
  804. continue;
  805. switch(ilp->state) {
  806. case Ilclosed:
  807. case Illistening:
  808. break;
  809. case Ilclosing:
  810. if(later(msec, ilp->timeout, "timeout")){
  811. if(ilp->rexmit > MaxRexmit){
  812. ilp->state = Ilclosed;
  813. ilhangup(cp, "connection timed out-0", 0);
  814. break;
  815. }
  816. ilsendctl(cp, 0, Ilclose, ilp->next, ilp->recvd, 0);
  817. ilbackoff(ilp);
  818. }
  819. break;
  820. case Ilsyncee:
  821. case Ilsyncer:
  822. if(later(msec, ilp->timeout, "timeout")){
  823. if(ilp->rexmit > MaxRexmit){
  824. ilp->state = Ilclosed;
  825. ilhangup(cp, "connection timed out-1", 0);
  826. break;
  827. }
  828. ilsendctl(cp, 0, Ilsync, ilp->start, ilp->recvd, 0);
  829. ilbackoff(ilp);
  830. }
  831. break;
  832. case Ilestablished:
  833. if(ilp->recvd != ilp->acksent)
  834. if(later(msec, ilp->acktime, "acktime"))
  835. ilsendctl(cp, 0, Ilack, ilp->next, ilp->recvd, 0);
  836. if(later(msec, ilp->querytime, "querytime")){
  837. if(later(msec, ilp->lastrecv+DeathTime, "deathtime")){
  838. ilhangup(cp, "connection timed out-2", 0);
  839. break;
  840. }
  841. ilsendctl(cp, 0, Ilquery, ilp->next, ilp->recvd, ilnextqt(ilp));
  842. ilp->querytime = msec + QueryTime;
  843. }
  844. if(ilp->unacked != nil)
  845. if(later(msec, ilp->timeout, "timeout")) {
  846. if(ilp->rexmit > MaxRexmit) {
  847. ilp->state = Ilclosed;
  848. ilhangup(cp, "connection timed out-3", 0);
  849. break;
  850. }
  851. ilsendctl(cp, 0, Ilquery, ilp->next, ilp->recvd, ilnextqt(ilp));
  852. ilbackoff(ilp);
  853. }
  854. break;
  855. }
  856. }
  857. unlock(&il);
  858. alarm(Iltickms, callil, 0);
  859. sleep(&ilt, no, 0);
  860. goto loop;
  861. }
  862. static
  863. int
  864. notsyncer(void *ic)
  865. {
  866. return ((Ilp*)ic)->state != Ilsyncer;
  867. }
  868. static
  869. void
  870. callildial(Alarm *a, void*)
  871. {
  872. cancel(a);
  873. wakeup(&ild);
  874. }
  875. static
  876. int
  877. ilnextqt(Ilp *ilp)
  878. {
  879. int x;
  880. lock(ilp);
  881. x = ilp->qtx;
  882. if(++x > Nqt)
  883. x = 1;
  884. ilp->qtx = x;
  885. ilp->qt[x] = ilp->next-1; /* highest xmitted packet */
  886. ilp->qt[0] = ilp->qt[x]; /* compatibility with old implementations */
  887. unlock(ilp);
  888. return x;
  889. }
  890. #define HOWMANY(x, y) (((x)+((y)-1))/(y))
  891. #define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))
  892. static void
  893. ilgoaway(Msgbuf *inmb, Ifc *ifc)
  894. {
  895. Chan *cp;
  896. int size;
  897. Ilpkt *ih, *inih;
  898. Msgbuf *mb;
  899. Ilp *ilp;
  900. uchar *p;
  901. inih = (Ilpkt*)inmb->data;
  902. /* allocate a temporary message, channel, and Ilp structure */
  903. size = ROUNDUP(Ensize+Ipsize+Ilsize, BY2WD)+sizeof(Chan)+sizeof(Ilp);
  904. mb = mballoc(size, nil, Mbil3);
  905. p = mb->data;
  906. p += ROUNDUP(Ensize+Ipsize+Ilsize, BY2WD);
  907. cp = (Chan*)p;
  908. p += sizeof(Chan);
  909. ilp = (Ilp*)p;
  910. /* link them together */
  911. cp->ifc = ifc;
  912. mb->chan = cp;
  913. cp->pdata = ilp;
  914. /* figure out next hop */
  915. memmove(ilp->ipgate, inih->src, Pasize);
  916. if((nhgetl(ifc->ipa)&ifc->mask) != (nhgetl(inih->src)&ifc->mask))
  917. iproute(ilp->ipgate, inih->src, ifc->netgate);
  918. /* create a close message */
  919. ih = (Ilpkt*)mb->data;
  920. ih->proto = Ilproto;
  921. hnputs(ih->illen, Ilsize);
  922. memmove(ih->src, ifc->ipa, Pasize);
  923. memmove(ih->dst, inih->src, Pasize);
  924. memmove(ih->ilsrc, inih->ildst, sizeof(ih->ilsrc));
  925. memmove(ih->ildst, inih->ilsrc, sizeof(ih->ildst));
  926. memmove(ih->ilid, inih->ilack, sizeof(ih->ilid));
  927. memmove(ih->ilack, inih->ilid, sizeof(ih->ilack));
  928. ih->iltype = Ilclose;
  929. ih->ilspec = 0;
  930. ih->ilsum[0] = 0;
  931. ih->ilsum[1] = 0;
  932. hnputs(ih->ilsum, ptclcsum((uchar*)mb->data+(Ensize+Ipsize), Ilsize));
  933. ipsend(mb);
  934. }