il.c 26 KB

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