il.c 26 KB

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