tcpin.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:26k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "timer.h"
  8. #include "mbuf.h"
  9. #include "netuser.h"
  10. #include "internet.h"
  11. #include "tcp.h"
  12. #include "icmp.h"
  13. #include "iface.h"
  14. #include "ip.h"
  15. static void update(struct tcb *tcb,struct tcp *seg,uint16 length);
  16. static void proc_syn(struct tcb *tcb,uint8 tos,struct tcp *seg);
  17. static void add_reseq(struct tcb *tcb,uint8 tos,struct tcp *seg,
  18. struct mbuf **bp,uint16 length);
  19. static void get_reseq(struct tcb *tcb,uint8 *tos,struct tcp *seq,
  20. struct mbuf **bp,uint16 *length);
  21. static int trim(struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  22. uint16 *length);
  23. static int in_window(struct tcb *tcb,int32 seq);
  24. /* This function is called from IP with the IP header in machine byte order,
  25.  * along with a mbuf chain pointing to the TCP header.
  26.  */
  27. void
  28. tcp_input(
  29. struct iface *iface, /* Incoming interface (ignored) */
  30. struct ip *ip, /* IP header */
  31. struct mbuf **bpp, /* Data field, if any */
  32. int rxbroadcast, /* Incoming broadcast - discard if true */
  33. int32 said /* Authenticated packet */
  34. ){
  35. struct tcb *ntcb;
  36. register struct tcb *tcb; /* TCP Protocol control block */
  37. struct tcp seg; /* Local copy of segment header */
  38. struct connection conn; /* Local copy of addresses */
  39. struct pseudo_header ph; /* Pseudo-header for checksumming */
  40. int hdrlen; /* Length of TCP header */
  41. uint16 length;
  42. int32 t;
  43. if(bpp == NULL || *bpp == NULL)
  44. return;
  45. tcpInSegs++;
  46. if(rxbroadcast){
  47. /* Any TCP packet arriving as a broadcast is
  48.  * to be completely IGNORED!!
  49.  */
  50. free_p(bpp);
  51. return;
  52. }
  53. length = ip->length - IPLEN - ip->optlen;
  54. ph.source = ip->source;
  55. ph.dest = ip->dest;
  56. ph.protocol = ip->protocol;
  57. ph.length = length;
  58. if(cksum(&ph,*bpp,length) != 0){
  59. /* Checksum failed, ignore segment completely */
  60. tcpInErrs++;
  61. free_p(bpp);
  62. return;
  63. }
  64. /* Form local copy of TCP header in host byte order */
  65. if((hdrlen = ntohtcp(&seg,bpp)) < 0){
  66. /* TCP header is too small */
  67. free_p(bpp);
  68. return;
  69. }
  70. length -= hdrlen;
  71. /* Fill in connection structure and find TCB */
  72. conn.local.address = ip->dest;
  73. conn.local.port = seg.dest;
  74. conn.remote.address = ip->source;
  75. conn.remote.port = seg.source;
  76. if((tcb = lookup_tcb(&conn)) == NULL){
  77. /* If this segment doesn't carry a SYN, reject it */
  78. if(!seg.flags.syn){
  79. free_p(bpp);
  80. reset(ip,&seg);
  81. return;
  82. }
  83. /* See if there's a TCP_LISTEN on this socket with
  84.  * unspecified remote address and port
  85.  */
  86. conn.remote.address = 0;
  87. conn.remote.port = 0;
  88. if((tcb = lookup_tcb(&conn)) == NULL){
  89. /* Nope, try unspecified local address too */
  90. conn.local.address = 0;
  91. if((tcb = lookup_tcb(&conn)) == NULL){
  92. /* No LISTENs, so reject */
  93. free_p(bpp);
  94. reset(ip,&seg);
  95. return;
  96. }
  97. }
  98. /* We've found an server listen socket, so clone the TCB */
  99. if(tcb->flags.clone){
  100. ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  101. ASSIGN(*ntcb,*tcb);
  102. tcb = ntcb;
  103. tcb->timer.arg = tcb;
  104. /* Put on list */
  105. tcb->next = Tcbs;
  106. Tcbs = tcb;
  107. }
  108. /* Put all the socket info into the TCB */
  109. tcb->conn.local.address = ip->dest;
  110. tcb->conn.remote.address = ip->source;
  111. tcb->conn.remote.port = seg.source;
  112. }
  113. tcb->flags.congest = ip->flags.congest;
  114. /* Do unsynchronized-state processing (p. 65-68) */
  115. switch(tcb->state){
  116. case TCP_CLOSED:
  117. free_p(bpp);
  118. reset(ip,&seg);
  119. return;
  120. case TCP_LISTEN:
  121. if(seg.flags.rst){
  122. free_p(bpp);
  123. return;
  124. }
  125. if(seg.flags.ack){
  126. free_p(bpp);
  127. reset(ip,&seg);
  128. return;
  129. }
  130. if(seg.flags.syn){
  131. /* (Security check is bypassed) */
  132. /* page 66 */
  133. proc_syn(tcb,ip->tos,&seg);
  134. send_syn(tcb);
  135. settcpstate(tcb,TCP_SYN_RECEIVED);
  136. if(length != 0 || seg.flags.fin) {
  137. /* Continue processing if there's more */
  138. break;
  139. }
  140. tcp_output(tcb);
  141. }
  142. free_p(bpp); /* Unlikely to get here directly */
  143. return;
  144. case TCP_SYN_SENT:
  145. if(seg.flags.ack){
  146. if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  147. free_p(bpp);
  148. reset(ip,&seg);
  149. return;
  150. }
  151. }
  152. if(seg.flags.rst){ /* p 67 */
  153. if(seg.flags.ack){
  154. /* The ack must be acceptable since we just checked it.
  155.  * This is how the remote side refuses connect requests.
  156.  */
  157. close_self(tcb,RESET);
  158. }
  159. free_p(bpp);
  160. return;
  161. }
  162. /* (Security check skipped here) */
  163. #ifdef PREC_CHECK /* Turned off for compatibility with BSD */
  164. /* Check incoming precedence; it must match if there's an ACK */
  165. if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  166. free_p(bpp);
  167. reset(ip,&seg);
  168. return;
  169. }
  170. #endif
  171. if(seg.flags.syn){
  172. proc_syn(tcb,ip->tos,&seg);
  173. if(seg.flags.ack){
  174. /* Our SYN has been acked, otherwise the ACK
  175.  * wouldn't have been valid.
  176.  */
  177. update(tcb,&seg,length);
  178. settcpstate(tcb,TCP_ESTABLISHED);
  179. } else {
  180. settcpstate(tcb,TCP_SYN_RECEIVED);
  181. }
  182. if(length != 0 || seg.flags.fin) {
  183. break; /* Continue processing if there's more */
  184. }
  185. tcp_output(tcb);
  186. } else {
  187. free_p(bpp); /* Ignore if neither SYN or RST is set */
  188. }
  189. return;
  190. }
  191. /* We reach this point directly in any synchronized state. Note that
  192.  * if we fell through from LISTEN or SYN_SENT processing because of a
  193.  * data-bearing SYN, window trimming and sequence testing "cannot fail".
  194.  *
  195.  * Begin by trimming segment to fit receive window.
  196.  */
  197. if(trim(tcb,&seg,bpp,&length) == -1){
  198. /* Segment is unacceptable */
  199. if(!seg.flags.rst){ /* NEVER answer RSTs */
  200. /* In SYN_RECEIVED state, answer a retransmitted SYN 
  201.  * with a retransmitted SYN/ACK.
  202.  */
  203. if(tcb->state == TCP_SYN_RECEIVED)
  204. tcb->snd.ptr = tcb->snd.una;
  205. tcb->flags.force = 1;
  206. tcp_output(tcb);
  207. }
  208. return;
  209. }
  210. /* If segment isn't the next one expected, and there's data
  211.  * or flags associated with it, put it on the resequencing
  212.  * queue and remind ourselves to ACK it. Then strip off
  213.  * the SYN/data/FIN and continue to process the ACK (or RST)
  214.  */
  215. if(seg.seq != tcb->rcv.nxt
  216.  && (length != 0 || seg.flags.syn || seg.flags.fin)){
  217. add_reseq(tcb,ip->tos,&seg,bpp,length);
  218. if(seg.flags.ack && !seg.flags.rst)
  219. tcb->flags.force = 1;
  220. seg.flags.syn = seg.flags.fin = 0;
  221. length = 0;
  222. }
  223. /* This loop first processes the current segment, and then
  224.  * repeats if it can process the resequencing queue.
  225.  */
  226. for(;;){
  227. /* We reach this point with an acceptable segment; data and flags
  228.  * (if any) are in the window, and if there's data, syn or fin, 
  229.  * the starting sequence number equals rcv.nxt
  230.  * (p. 70)
  231.  */
  232. if(seg.flags.rst){
  233. if(tcb->state == TCP_SYN_RECEIVED
  234.  && !tcb->flags.clone && !tcb->flags.active){
  235. /* Go back to listen state only if this was
  236.  * not a cloned or active server TCB
  237.  */
  238. settcpstate(tcb,TCP_LISTEN);
  239. } else {
  240. close_self(tcb,RESET);
  241. }
  242. free_p(bpp);
  243. return;
  244. }
  245. /* (Security check skipped here) p. 71 */
  246. #ifdef PREC_CHECK
  247. /* Check for precedence mismatch */
  248. if(PREC(ip->tos) != PREC(tcb->tos)){
  249. free_p(bpp);
  250. reset(ip,&seg);
  251. return;
  252. }
  253. #endif
  254. /* Check for erroneous extra SYN */
  255. if(seg.flags.syn){
  256. free_p(bpp);
  257. reset(ip,&seg);
  258. return;
  259. }
  260. /* Update timestamp field */
  261. if(seg.flags.tstamp
  262.  && seq_within(tcb->last_ack_sent,seg.seq,seg.seq+length))
  263. tcb->ts_recent = seg.tsval;
  264. /* Check ack field p. 72 */
  265. if(!seg.flags.ack){
  266. free_p(bpp); /* All segments after synchronization must have ACK */
  267. return;
  268. }
  269. /* Process ACK */
  270. switch(tcb->state){
  271. case TCP_SYN_RECEIVED:
  272. if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  273. update(tcb,&seg,length);
  274. settcpstate(tcb,TCP_ESTABLISHED);
  275. } else {
  276. free_p(bpp);
  277. reset(ip,&seg);
  278. return;
  279. }
  280. break;
  281. case TCP_ESTABLISHED:
  282. case TCP_CLOSE_WAIT:
  283. case TCP_FINWAIT2:
  284. update(tcb,&seg,length);
  285. break;
  286. case TCP_FINWAIT1: /* p. 73 */
  287. update(tcb,&seg,length);
  288. if(tcb->sndcnt == 0){
  289. /* Our FIN is acknowledged */
  290. settcpstate(tcb,TCP_FINWAIT2);
  291. }
  292. break;
  293. case TCP_CLOSING:
  294. update(tcb,&seg,length);
  295. if(tcb->sndcnt == 0){
  296. /* Our FIN is acknowledged */
  297. settcpstate(tcb,TCP_TIME_WAIT);
  298. set_timer(&tcb->timer,MSL2*1000L);
  299. start_timer(&tcb->timer);
  300. }
  301. break;
  302. case TCP_LAST_ACK:
  303. update(tcb,&seg,length);
  304. if(tcb->sndcnt == 0){
  305. /* Our FIN is acknowledged, close connection */
  306. close_self(tcb,NORMAL);
  307. return;
  308. }
  309. break;
  310. case TCP_TIME_WAIT:
  311. start_timer(&tcb->timer);
  312. break;
  313. }
  314. /* (URGent bit processing skipped here) */
  315. /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  316. if(length != 0){
  317. switch(tcb->state){
  318. case TCP_SYN_RECEIVED:
  319. case TCP_ESTABLISHED:
  320. case TCP_FINWAIT1:
  321. case TCP_FINWAIT2:
  322. /* Place on receive queue */
  323. t = msclock();
  324. if(t > tcb->lastrx){
  325. tcb->rxbw = 1000L*length / (t - tcb->lastrx);
  326. tcb->lastrx = t;
  327. }
  328. append(&tcb->rcvq,bpp);
  329. tcb->rcvcnt += length;
  330. tcb->rcv.nxt += length;
  331. tcb->rcv.wnd -= length;
  332. tcb->flags.force = 1;
  333. /* Notify user */
  334. if(tcb->r_upcall)
  335. (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  336. break;
  337. default:
  338. /* Ignore segment text */
  339. free_p(bpp);
  340. break;
  341. }
  342. }
  343. /* process FIN bit (p 75) */
  344. if(seg.flags.fin){
  345. tcb->flags.force = 1; /* Always respond with an ACK */
  346. switch(tcb->state){
  347. case TCP_SYN_RECEIVED:
  348. case TCP_ESTABLISHED:
  349. tcb->rcv.nxt++;
  350. settcpstate(tcb,TCP_CLOSE_WAIT);
  351. break;
  352. case TCP_FINWAIT1:
  353. tcb->rcv.nxt++;
  354. if(tcb->sndcnt == 0){
  355. /* Our FIN has been acked; bypass TCP_CLOSING state */
  356. settcpstate(tcb,TCP_TIME_WAIT);
  357. set_timer(&tcb->timer,MSL2*1000L);
  358. start_timer(&tcb->timer);
  359. } else {
  360. settcpstate(tcb,TCP_CLOSING);
  361. }
  362. break;
  363. case TCP_FINWAIT2:
  364. tcb->rcv.nxt++;
  365. settcpstate(tcb,TCP_TIME_WAIT);
  366. set_timer(&tcb->timer,MSL2*1000L);
  367. start_timer(&tcb->timer);
  368. break;
  369. case TCP_CLOSE_WAIT:
  370. case TCP_CLOSING:
  371. case TCP_LAST_ACK:
  372. break; /* Ignore */
  373. case TCP_TIME_WAIT: /* p 76 */
  374. start_timer(&tcb->timer);
  375. break;
  376. }
  377. /* Call the client again so he can see EOF */
  378. if(tcb->r_upcall)
  379. (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  380. }
  381. /* Scan the resequencing queue, looking for a segment we can handle,
  382.  * and freeing all those that are now obsolete.
  383.  */
  384. while(tcb->reseq != NULL && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  385. get_reseq(tcb,&ip->tos,&seg,bpp,&length);
  386. if(trim(tcb,&seg,bpp,&length) == 0)
  387. goto gotone;
  388. /* Segment is an old one; trim has freed it */
  389. }
  390. break;
  391. gotone: ;
  392. }
  393. tcp_output(tcb); /* Send any necessary ack */
  394. }
  395. /* Process an incoming ICMP response */
  396. void
  397. tcp_icmp(
  398. int32 icsource, /* Sender of ICMP message (not used) */
  399. int32 source, /* Original IP datagram source (i.e. us) */
  400. int32 dest, /* Original IP datagram dest (i.e., them) */
  401. uint8 type, /* ICMP error codes */
  402. uint8 code,
  403. struct mbuf **bpp /* First 8 bytes of TCP header */
  404. ){
  405. struct tcp seg;
  406. struct connection conn;
  407. register struct tcb *tcb;
  408. /* Extract the socket info from the returned TCP header fragment
  409.  * Note that since this is a datagram we sent, the source fields
  410.  * refer to the local side.
  411.  */
  412. ntohtcp(&seg,bpp);
  413. conn.local.port = seg.source;
  414. conn.remote.port = seg.dest;
  415. conn.local.address = source;
  416. conn.remote.address = dest;
  417. if((tcb = lookup_tcb(&conn)) == NULL)
  418. return; /* Unknown connection, ignore */
  419. /* Verify that the sequence number in the returned segment corresponds
  420.  * to something currently unacknowledged. If not, it can safely
  421.  * be ignored.
  422.  */
  423. if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  424. return;
  425. /* Destination Unreachable and Time Exceeded messages never kill a
  426.  * connection; the info is merely saved for future reference.
  427.  */
  428. switch(type){
  429. case ICMP_DEST_UNREACH:
  430. case ICMP_TIME_EXCEED:
  431. tcb->type = type;
  432. tcb->code = code;
  433. tcb->unreach++;
  434. break;
  435. case ICMP_QUENCH:
  436. /* Source quench; reduce slowstart threshold to half
  437.  * current window and restart slowstart
  438.  */
  439. tcb->ssthresh = tcb->cwind / 2;
  440. tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  441. /* Shrink congestion window to 1 packet */
  442. tcb->cwind = tcb->mss;
  443. tcb->quench++;
  444. break;
  445. }
  446. }
  447. /* Send an acceptable reset (RST) response for this segment
  448.  * The RST reply is composed in place on the input segment
  449.  */
  450. void
  451. reset(ip,seg)
  452. struct ip *ip; /* Offending IP header */
  453. register struct tcp *seg; /* Offending TCP header */
  454. {
  455. struct mbuf *hbp;
  456. uint16 tmp;
  457. if(seg->flags.rst)
  458. return; /* Never send an RST in response to an RST */
  459. /* Swap port numbers */
  460. tmp = seg->source;
  461. seg->source = seg->dest;
  462. seg->dest = tmp;
  463. if(seg->flags.ack){
  464. /* This reset is being sent to clear a half-open connection.
  465.  * Set the sequence number of the RST to the incoming ACK
  466.  * so it will be acceptable.
  467.  */
  468. seg->flags.ack = 0;
  469. seg->seq = seg->ack;
  470. seg->ack = 0;
  471. } else {
  472. /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  473.  * so we have to "acknowledge" their SYN.
  474.  */
  475. seg->flags.ack = 1;
  476. seg->ack = seg->seq;
  477. seg->seq = 0;
  478. if(seg->flags.syn)
  479. seg->ack++;
  480. }
  481. /* Set remaining parts of packet */
  482. seg->flags.urg = 0;
  483. seg->flags.psh = 0;
  484. seg->flags.rst = 1;
  485. seg->flags.syn = 0;
  486. seg->flags.fin = 0;
  487. seg->flags.mss = 0;
  488. seg->flags.wscale = 0;
  489. seg->flags.tstamp = 0;
  490. seg->wnd = 0;
  491. seg->up = 0;
  492. seg->checksum = 0; /* force recomputation */
  493. hbp = ambufw(TCP_HDR_PAD); /* Prealloc room for headers */
  494. hbp->data += TCP_HDR_PAD;
  495. htontcp(seg,&hbp,ip->dest,ip->source);
  496. /* Ship it out (note swap of addresses) */
  497. ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,&hbp,len_p(hbp),0,0);
  498. tcpOutRsts++;
  499. }
  500. /* Process an incoming acknowledgement and window indication.
  501.  * From page 72.
  502.  */
  503. static void
  504. update(tcb,seg,length)
  505. register struct tcb *tcb;
  506. register struct tcp *seg;
  507. uint16 length;
  508. {
  509. int32 acked;
  510. int winupd = 0;
  511. int32 swind; /* Incoming window, scaled (non-SYN only) */
  512. long rtt; /* measured round trip time */
  513. int32 abserr; /* abs(rtt - srtt) */
  514. acked = 0;
  515. if(seq_gt(seg->ack,tcb->snd.nxt)){
  516. tcb->flags.force = 1; /* Acks something not yet sent */
  517. return;
  518. }
  519. /* Decide if we need to do a window update.
  520.  * This is always checked whenever a legal ACK is received,
  521.  * even if it doesn't actually acknowledge anything,
  522.  * because it might be a spontaneous window reopening.
  523.  */
  524. if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  525.  && seq_ge(seg->ack,tcb->snd.wl2))){
  526. if(seg->flags.syn || !tcb->flags.ws_ok)
  527. swind = seg->wnd;
  528. else
  529. swind = seg->wnd << tcb->snd.wind_scale;
  530. if(swind > tcb->snd.wnd){
  531. winupd = 1; /* Don't count as duplicate ack */
  532. /* If the window had been closed, crank back the send
  533.  * pointer so we'll immediately resume transmission.
  534.  * Otherwise we'd have to wait until the next probe.
  535.  */
  536. if(tcb->snd.wnd == 0)
  537. tcb->snd.ptr = tcb->snd.una;
  538. }
  539. /* Remember for next time */
  540. tcb->snd.wnd = swind;
  541. tcb->snd.wl1 = seg->seq;
  542. tcb->snd.wl2 = seg->ack;
  543. }
  544. /* See if anything new is being acknowledged */
  545. if(seq_lt(seg->ack,tcb->snd.una))
  546. return; /* Old ack, ignore */
  547. if(seg->ack == tcb->snd.una){
  548. /* Ack current, but doesn't ack anything */
  549. if(tcb->sndcnt == 0 || winupd || length != 0 || seg->flags.syn || seg->flags.fin){
  550. /* Either we have nothing in the pipe, this segment
  551.  * was sent to update the window, or it carries
  552.  * data/syn/fin. In any of these cases we
  553.  * wouldn't necessarily expect an ACK.
  554.  */
  555. return;
  556. }
  557. /* Van Jacobson "fast recovery" code */
  558. if(++tcb->dupacks == TCPDUPACKS){
  559. /* We've had a burst of do-nothing acks, so
  560.  * we almost certainly lost a packet.
  561.  * Resend it now to avoid a timeout. (This is
  562.  * Van Jacobson's 'quick recovery' algorithm.)
  563.  */
  564. int32 ptrsave;
  565. /* Knock the threshold down just as though
  566.  * this were a timeout, since we've had
  567.  * network congestion.
  568.  */
  569. tcb->ssthresh = tcb->cwind/2;
  570. tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  571. /* Manipulate the machinery in tcp_output() to
  572.  * retransmit just the missing packet
  573.  */
  574. ptrsave = tcb->snd.ptr;
  575. tcb->snd.ptr = tcb->snd.una;
  576. tcb->cwind = tcb->mss;
  577. tcp_output(tcb);
  578. tcb->snd.ptr = ptrsave;
  579. /* "Inflate" the congestion window, pretending as
  580.  * though the duplicate acks were normally acking
  581.  * the packets beyond the one that was lost.
  582.  */
  583. tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  584. } else if(tcb->dupacks > TCPDUPACKS){
  585. /* Continue to inflate the congestion window
  586.  * until the acks finally get "unstuck".
  587.  */
  588. tcb->cwind += tcb->mss;
  589. }
  590. /* Clamp the congestion window at the amount currently
  591.  * on the send queue, with a minimum of one packet.
  592.  * This keeps us from increasing the cwind beyond what
  593.  * we're actually putting in the pipe; otherwise a big
  594.  * burst of data could overwhelm the net.
  595.  */
  596. tcb->cwind = min(tcb->cwind,tcb->sndcnt);
  597. tcb->cwind = max(tcb->cwind,tcb->mss);
  598. return;
  599. }
  600. /* We're here, so the ACK must have actually acked something */
  601. if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  602. /* The acks have finally gotten "unstuck". So now we
  603.  * can "deflate" the congestion window, i.e. take it
  604.  * back down to where it would be after slow start
  605.  * finishes.
  606.  */
  607. tcb->cwind = tcb->ssthresh;
  608. }
  609. tcb->dupacks = 0;
  610. acked = seg->ack - tcb->snd.una;
  611. /* Expand congestion window if not already at limit and if
  612.  * this packet wasn't retransmitted
  613.  */
  614. if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  615. if(tcb->cwind < tcb->ssthresh){
  616. /* Still doing slow start/CUTE, expand by amount acked */
  617. tcb->cwind += min(acked,tcb->mss);
  618. } else {
  619. /* Steady-state test of extra path capacity */
  620. tcb->cwind += ((long)tcb->mss * tcb->mss) / tcb->cwind;
  621. }
  622. /* Don't expand beyond the offered window */
  623. if(tcb->cwind > tcb->snd.wnd)
  624. tcb->cwind = tcb->snd.wnd;
  625. }
  626. tcb->cwind = min(tcb->cwind,tcb->sndcnt); /* Clamp */
  627. tcb->cwind = max(tcb->cwind,tcb->mss);
  628. /* Round trip time estimation */
  629. rtt = -1; /* Init to invalid value */
  630. if(tcb->flags.ts_ok && seg->flags.tstamp){
  631. /* Determine RTT from timestamp echo */
  632. rtt = msclock() - seg->tsecr;
  633. } else if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  634. /* use standard round trip timing */
  635. /* A timed sequence number has been acked */
  636. tcb->flags.rtt_run = 0;
  637. if(!(tcb->flags.retran)){
  638. /* This packet was sent only once and now
  639.  * it's been acked, so process the round trip time
  640.  */
  641. rtt = msclock() - tcb->rtt_time;
  642. }
  643. }
  644. if(rtt >= 0){
  645. tcb->rtt = rtt; /* Save for display */
  646. abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  647. /* Run SRTT and MDEV integrators, with rounding */
  648. tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  649. tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  650. rtt_add(tcb->conn.remote.address,rtt);
  651. /* Reset the backoff level */
  652. tcb->backoff = 0;
  653. /* Update our tx throughput estimate */
  654. if(rtt != 0) /* Avoid division by zero */
  655. tcb->txbw = 1000*(seg->ack - tcb->rttack)/rtt;
  656. }
  657. tcb->sndcnt -= acked; /* Update virtual byte count on snd queue */
  658. tcb->snd.una = seg->ack;
  659. /* If we're waiting for an ack of our SYN, note it and adjust count */
  660. if(!(tcb->flags.synack)){
  661. tcb->flags.synack = 1;
  662. acked--; /* One less byte to pull from real snd queue */
  663. }
  664. /* Remove acknowledged bytes from the send queue and update the
  665.  * unacknowledged pointer. If a FIN is being acked,
  666.  * pullup won't be able to remove it from the queue, but that
  667.  * causes no harm.
  668.  */
  669. pullup(&tcb->sndq,NULL,(uint16)acked);
  670. /* Stop retransmission timer, but restart it if there is still
  671.  * unacknowledged data.
  672.  */
  673. stop_timer(&tcb->timer);
  674. if(tcb->snd.una != tcb->snd.nxt)
  675. start_timer(&tcb->timer);
  676. /* If retransmissions have been occurring, make sure the
  677.  * send pointer doesn't repeat ancient history
  678.  */
  679. if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  680. tcb->snd.ptr = tcb->snd.una;
  681. /* Clear the retransmission flag since the oldest
  682.  * unacknowledged segment (the only one that is ever retransmitted)
  683.  * has now been acked.
  684.  */
  685. tcb->flags.retran = 0;
  686. /* If outgoing data was acked, notify the user so he can send more
  687.  * unless we've already sent a FIN.
  688.  */
  689. if(acked != 0 && tcb->t_upcall
  690.  && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  691. (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  692. }
  693. }
  694. /* Determine if the given sequence number is in our receiver window.
  695.  * NB: must not be used when window is closed!
  696.  */
  697. static
  698. int
  699. in_window(tcb,seq)
  700. struct tcb *tcb;
  701. int32 seq;
  702. {
  703. return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  704. }
  705. /* Process an incoming SYN */
  706. static void
  707. proc_syn(tcb,tos,seg)
  708. register struct tcb *tcb;
  709. uint8 tos;
  710. struct tcp *seg;
  711. {
  712. uint16 mtu;
  713. struct tcp_rtt *tp;
  714. tcb->flags.force = 1; /* Always send a response */
  715. /* Note: It's not specified in RFC 793, but SND.WL1 and
  716.  * SND.WND are initialized here since it's possible for the
  717.  * window update routine in update() to fail depending on the
  718.  * IRS if they are left unitialized.
  719.  */
  720. /* Check incoming precedence and increase if higher */
  721. if(PREC(tos) > PREC(tcb->tos))
  722. tcb->tos = tos;
  723. tcb->rcv.nxt = seg->seq + 1; /* p 68 */
  724. tcb->snd.wl1 = tcb->irs = seg->seq;
  725. tcb->snd.wnd = seg->wnd; /* Never scaled in a SYN */
  726. if(seg->flags.mss)
  727. tcb->mss = seg->mss;
  728. if(seg->flags.wscale){
  729. tcb->snd.wind_scale = seg->wsopt;
  730. tcb->rcv.wind_scale = DEF_WSCALE;
  731. tcb->flags.ws_ok = 1;
  732. }
  733. if(seg->flags.tstamp && Tcp_tstamps){
  734. tcb->flags.ts_ok = 1;
  735. tcb->ts_recent = seg->tsval;
  736. }
  737. /* Check the MTU of the interface we'll use to reach this guy
  738.  * and lower the MSS so that unnecessary fragmentation won't occur
  739.  */
  740. if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  741. /* Allow space for the TCP and IP headers */
  742. if(tcb->flags.ts_ok)
  743. mtu -= (TSTAMP_LENGTH + TCPLEN + IPLEN + 3) & ~3;
  744. else
  745. mtu -= TCPLEN + IPLEN;
  746. tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  747. }
  748. /* See if there's round-trip time experience */
  749. if((tp = rtt_get(tcb->conn.remote.address)) != NULL){
  750. tcb->srtt = tp->srtt;
  751. tcb->mdev = tp->mdev;
  752. }
  753. }
  754. /* Generate an initial sequence number and put a SYN on the send queue */
  755. void
  756. send_syn(tcb)
  757. register struct tcb *tcb;
  758. {
  759. tcb->iss = geniss();
  760. tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  761. tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  762. tcb->sndcnt++;
  763. tcb->flags.force = 1;
  764. }
  765. /* Add an entry to the resequencing queue in the proper place */
  766. static void
  767. add_reseq(
  768. struct tcb *tcb,
  769. uint8 tos,
  770. struct tcp *seg,
  771. struct mbuf **bpp,
  772. uint16 length
  773. ){
  774. register struct reseq *rp,*rp1;
  775. /* Allocate reassembly descriptor */
  776. if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULL){
  777. /* No space, toss on floor */
  778. free_p(bpp);
  779. return;
  780. }
  781. ASSIGN(rp->seg,*seg);
  782. rp->tos = tos;
  783. rp->bp = (*bpp);
  784. *bpp = NULL;
  785. rp->length = length;
  786. /* Place on reassembly list sorting by starting seq number */
  787. rp1 = tcb->reseq;
  788. if(rp1 == NULL || seq_lt(seg->seq,rp1->seg.seq)){
  789. /* Either the list is empty, or we're less than all other
  790.  * entries; insert at beginning.
  791.  */
  792. rp->next = rp1;
  793. tcb->reseq = rp;
  794. } else {
  795. /* Find the last entry less than us */
  796. for(;;){
  797. if(rp1->next == NULL || seq_lt(seg->seq,rp1->next->seg.seq)){
  798. /* We belong just after this one */
  799. rp->next = rp1->next;
  800. rp1->next = rp;
  801. break;
  802. }
  803. rp1 = rp1->next;
  804. }
  805. }
  806. }
  807. /* Fetch the first entry off the resequencing queue */
  808. static void
  809. get_reseq(
  810. register struct tcb *tcb,
  811. uint8 *tos,
  812. struct tcp *seg,
  813. struct mbuf **bp,
  814. uint16 *length
  815. ){
  816. register struct reseq *rp;
  817. if((rp = tcb->reseq) == NULL)
  818. return;
  819. tcb->reseq = rp->next;
  820. *tos = rp->tos;
  821. ASSIGN(*seg,rp->seg);
  822. *bp = rp->bp;
  823. *length = rp->length;
  824. free(rp);
  825. }
  826. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  827.  * unacceptable.
  828.  */
  829. static int
  830. trim(
  831. register struct tcb *tcb,
  832. register struct tcp *seg,
  833. struct mbuf **bpp,
  834. uint16 *length
  835. ){
  836. long dupcnt,excess;
  837. uint16 len; /* Segment length including flags */
  838. char accept = 0;
  839. len = *length;
  840. if(seg->flags.syn)
  841. len++;
  842. if(seg->flags.fin)
  843. len++;
  844. /* Segment acceptability tests */
  845. if(tcb->rcv.wnd == 0){
  846. /* If our window is closed, then the other end is
  847.  * probably probing us. If so, they might send us acks
  848.  * with seg.seq > rcv.nxt. Be sure to accept these
  849.  */
  850. if(len == 0 && seq_within(seg->seq,tcb->rcv.nxt,tcb->rcv.nxt+tcb->window))
  851. return 0;
  852. return -1; /* reject all others */
  853. }
  854. if(tcb->rcv.wnd > 0){
  855. /* Some part of the segment must be in the window */
  856. if(in_window(tcb,seg->seq)){
  857. accept++; /* Beginning is */
  858. } else if(len != 0){
  859. if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  860.  seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  861. accept++;
  862. }
  863. }
  864. }
  865. if(!accept){
  866. tcb->rerecv += len;
  867. free_p(bpp);
  868. return -1;
  869. }
  870. if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  871. tcb->rerecv += dupcnt;
  872. /* Trim off SYN if present */
  873. if(seg->flags.syn){
  874. /* SYN is before first data byte */
  875. seg->flags.syn = 0;
  876. seg->seq++;
  877. dupcnt--;
  878. }
  879. if(dupcnt > 0){
  880. pullup(bpp,NULL,(uint16)dupcnt);
  881. seg->seq += dupcnt;
  882. *length -= dupcnt;
  883. }
  884. }
  885. if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  886. tcb->rerecv += excess;
  887. /* Trim right edge */
  888. *length -= excess;
  889. trim_mbuf(bpp,*length);
  890. seg->flags.fin = 0; /* FIN follows last data byte */
  891. }
  892. return 0;
  893. }