00001
00002
00003
00004
00005
00006 #include <stdio.h>
00007 #include <string.h>
00008 #include <netinet/in.h>
00009 #include <linux/ip.h>
00010 #include <linux/tcp.h>
00011 #include <sys/socket.h>
00012 #include <netinet/in.h>
00013 #include <arpa/inet.h>
00014 #include <pthread.h>
00015 #include <assert.h>
00016
00017 #include "misc.h"
00018 #include "tcpproxy.h"
00019 #include "scheduler.h"
00020 #include "tcptimer.h"
00021 #include "tcp.h"
00022
00023
00024
00025
00026 static unsigned win_clamp_size = TCP_WIN_CLAMP_SIZE;
00027 static Ttcp_cb tcp_tab[TCP_MAX_CONN];
00028 static pthread_mutex_t tcp_tab_mut;
00029
00030
00031
00032
00033
00034 void init_tcp()
00035 {
00036 int i;
00037
00038
00039 memset(tcp_tab, 0, sizeof(Ttcp_cb)*TCP_MAX_CONN);
00040 pthread_mutex_init(&tcp_tab_mut, NULL);
00041 for(i=0; i<TCP_MAX_CONN; i++) {
00042 tcp_tab[i].state = TCPS_FREE;
00043 tcp_tab[i].out_queue = -1;
00044 pthread_mutex_init(&tcp_tab[i].mut, NULL);
00045 }
00046 }
00047
00048
00049
00050
00051
00052 void cleanup_tcp()
00053 {
00054
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 inline int seq_cmp(unsigned a, unsigned b)
00067 {
00068 return (int)(a - b);
00069 }
00070
00071
00072
00073
00074
00075
00076 inline int allow_conn(Tpacket_data *pd)
00077 {
00078 if(ntohs(pd->trans.tcp->dest) == 5009)
00079 return 0;
00080 return 1;
00081 }
00082
00083
00084
00085
00086
00087
00088 unsigned get_queue_weight(Ttcp_cid *cid)
00089 {
00090 if(ntohs(cid->sport) == 5005)
00091 return QUEUE_WEIGHT_HIGH;
00092 else
00093 return QUEUE_WEIGHT_NORMAL;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103 Ttcp_cb *alloc_tcp_cb(Tpacket_data *pd, Ttcp_cid *cid)
00104 {
00105 Ttcp_cb *cb;
00106 int queue_num;
00107 unsigned weight;
00108 int i;
00109
00110 for(i=0; i<TCP_MAX_CONN; i++)
00111 if(tcp_tab[i].state == TCPS_FREE)
00112 break;
00113
00114 if(i < TCP_MAX_CONN) {
00115 weight = get_queue_weight(cid);
00116 queue_num = alloc_tcp_queue(weight);
00117 if(queue_num >= 0) {
00118 cb = &tcp_tab[i];
00119 memcpy(&(cb->cid), cid, sizeof(Ttcp_cid));
00120 cb->state = TCPS_NEW;
00121 cb->init = 0;
00122 cb->out_queue = queue_num;
00123 DPRINT("tcb_cb_alloc: allocated new connection block.\n");
00124 } else {
00125 cb = NULL;
00126 DPRINT("alloc_tcp_cb: no free tcp output queues.\n");
00127 }
00128 } else {
00129 cb = NULL;
00130 DPRINT("alloc_tcp_cb: no free control blocks.\n");
00131 }
00132
00133 return cb;
00134 }
00135
00136
00137
00138
00139
00140
00141 int dealloc_tcp_cb(Ttcp_cb *cb)
00142 {
00143 DPRINT("dealloc_tcp_cb: entered.\n");
00144 close_tcp_queue(cb->out_queue);
00145 cb->state = TCPS_FREE;
00146 return 0;
00147 }
00148
00149 inline int valid_ack(Ttcp_cb *cb, Tpacket_data *pd)
00150 {
00151 if(pd->dir == PACKET_DIR_IN) {
00152 return (ntohl(pd->trans.tcp->ack_seq) == cb->mh_seq);
00153 } else {
00154 return (ntohl(pd->trans.tcp->ack_seq) == cb->fh_seq);
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163 unsigned short tcp_chksum(struct iphdr *ip)
00164 {
00165 unsigned short *ptr;
00166 unsigned short len, words;
00167 unsigned long chksum = 0;
00168 int i;
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 ptr = (unsigned short*) &(ip->saddr);
00183 for(i=0; i<4; i++)
00184 chksum += *ptr++;
00185
00186 ptr = ((unsigned short*)ip) + ip->ihl*2;
00187 len = ntohs(ip->tot_len) - ip->ihl*4;
00188 chksum += htons(TCP_PROTO) + htons(len);
00189
00190 words = len >> 1;
00191
00192 for(i=0; i<words; i++)
00193 chksum += *ptr++;
00194
00195 if(len % 2)
00196 chksum += htons((unsigned short) (*((char *)ptr) << 8));
00197
00198 chksum = (chksum >> 16) + (chksum & 0xffff);
00199 chksum += (chksum >> 16);
00200 chksum = ~chksum & 0xffff;
00201
00202 return (short) chksum;
00203 }
00204
00205
00206
00207
00208
00209
00210 int send_tcp_rst (Tpacket_data *pd)
00211 {
00212 struct iphdr *ip_out, *ip_in = pd->ip;
00213 struct tcphdr *tcp_out, *tcp_in = pd->trans.tcp;
00214 int pkt_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
00215 int data_len;
00216
00217 DPRINT("send_tcp_rst: entered.\n");
00218
00219 if(tcp_in->rst) {
00220 DPRINT("send_tcp_rst: not sending RST in response to RST.\n");
00221 return 0;
00222 }
00223 ip_out = (struct iphdr *) xmalloc(pkt_len);
00224 tcp_out = (struct tcphdr*) (ip_out + 1);
00225
00226
00227 ip_out->version = IP_VERSION;
00228 ip_out->ihl = sizeof(struct iphdr)/4;
00229 ip_out->tos = 0;
00230 ip_out->tot_len = htons(pkt_len);
00231 ip_out->id = 0;
00232 ip_out->frag_off = htons(0x40<<8);
00233 ip_out->ttl = IP_START_TTL;
00234 ip_out->protocol = TCP_PROTO;
00235 ip_out->saddr = ip_in->daddr;
00236 ip_out->daddr = ip_in->saddr;
00237
00238
00239 tcp_out->source = tcp_in->dest;
00240 tcp_out->dest = tcp_in->source;
00241 if(tcp_in->ack) {
00242 tcp_out->seq = tcp_in->ack_seq;
00243 tcp_flag_word(tcp_out) = TCP_FLAG_RST;
00244 } else {
00245 tcp_out->seq = 0;
00246 tcp_flag_word(tcp_out) = TCP_FLAG_RST | TCP_FLAG_ACK;
00247 }
00248 data_len = ntohs(ip_in->tot_len) - ip_in->ihl*4 - tcp_in->doff*4;
00249 if(tcp_in->syn)
00250 data_len++;
00251 if(tcp_in->fin)
00252 data_len++;
00253 tcp_out->ack_seq = htonl(ntohl(tcp_in->seq) + data_len);
00254 tcp_out->doff = sizeof(struct tcphdr)/4;
00255 tcp_out->res1 = 0;
00256 tcp_out->window = tcp_out->urg_ptr = tcp_out->check = 0;
00257 tcp_out->check = tcp_chksum(ip_out);
00258
00259
00260 xfree(pd->payload);
00261 pd->payload = (char *)ip_out;
00262 pd->ip = ip_out;
00263 pd->trans.tcp = tcp_out;
00264
00265
00266 pd->ipq_pm.data_len = pkt_len;
00267
00268
00269 if(pd->dir == PACKET_DIR_IN)
00270 pd->dir = PACKET_DIR_OUT;
00271 else
00272 pd->dir = PACKET_DIR_IN;
00273
00274
00275 return queue_hipri(pd);
00276 }
00277
00278
00279
00280
00281
00282
00283 int clamp_tcp_win (Tpacket_data *pd)
00284 {
00285 struct tcphdr *tcp = pd->trans.tcp;
00286 unsigned window = ntohs(tcp->window);
00287 if(window > win_clamp_size)
00288 {
00289 tcp->window = htons(win_clamp_size);
00290 tcp->check = 0;
00291 tcp->check = tcp_chksum(pd->ip);
00292
00293 return 1;
00294 } else {
00295
00296 return 0;
00297 }
00298 }
00299
00300
00301
00302
00303
00304
00305 inline int tcp_data_size(Tpacket_data *pd)
00306 {
00307 struct tcphdr *tcp = pd->trans.tcp;
00308 int size = 0;
00309
00310 size += tcp->syn ? 1 : 0;
00311 size += tcp->fin ? 1 : 0;
00312 size += pd->ipq_pm.data_len - pd->ip->ihl*4 - tcp->doff*4;
00313
00314 return size;
00315 }
00316
00317
00318
00319
00320
00321 int tcps_err (Ttcp_cb *cb, Tpacket_data *pd)
00322 {
00323 EPRINT("tcps_err: entered.\n");
00324 assert(UNREACHABLE);
00325 }
00326
00327
00328
00329
00330
00331 int tcps_new (Ttcp_cb *cb, Tpacket_data *pd)
00332 {
00333 if(pd->dir == PACKET_DIR_IN) {
00334 cb->state = TCPS_SYN_RECV;
00335 DPRINT("tcps_new: state new->syn_recv.\n");
00336
00337 } else {
00338 cb->state = TCPS_SYN_SENT;
00339 add_timer(TCP_TWO_MSL, tcp_timeout, cb);
00340 DPRINT("tcps_new: state new->syn_sent.\n");
00341 }
00342 return 0;
00343 }
00344
00345
00346
00347
00348
00349 int tcps_syn_sent (Ttcp_cb *cb, Tpacket_data *pd)
00350 {
00351 struct tcphdr *tcp = pd->trans.tcp;
00352
00353 if(pd->dir == PACKET_DIR_IN) {
00354 if(tcp->syn) {
00355 clear_timer(tcp_timeout, cb);
00356 if(tcp->ack) {
00357 if(valid_ack(cb, pd)) {
00358 cb->state = TCPS_ESTABLISHED;
00359 DPRINT("tcps_syn_sent: syn-ack, state syn_sent->established.\n");
00360 } else {
00361 DPRINT("tcps_syn_sent: bad ack number.\n");
00362 }
00363 } else {
00364 cb->state = TCPS_SYN_RECV;
00365 DPRINT("tcps_syn_sent: syn, state syn_sent->syn_recv.\n");
00366 }
00367 } else {
00368 DPRINT("tcps_syn_sent: no syn bit, invalid packet.\n");
00369 }
00370
00371 } else {
00372 DPRINT("tcps_syn_sent: state syn_sent.\n");
00373 }
00374 return 0;
00375 }
00376
00377
00378
00379
00380
00381 int tcps_syn_recv (Ttcp_cb *cb, Tpacket_data *pd)
00382 {
00383 struct tcphdr *tcp = pd->trans.tcp;
00384
00385 if(pd->dir == PACKET_DIR_IN) {
00386 if(tcp->ack) {
00387 if(valid_ack(cb, pd)) {
00388 cb->state = TCPS_ESTABLISHED;
00389 DPRINT("tcps_syn_recv: ack, state syn_recv->established.\n");
00390 } else {
00391 DPRINT("tcps_syn_recv: bad ack number.\n");
00392 }
00393 } else {
00394 DPRINT("tcps_syn_recv: state syn_recv.\n");
00395 }
00396
00397 } else {
00398 if(tcp->fin) {
00399 cb->state = TCPS_FIN_WAIT1;
00400 DPRINT("tcps_syn_recv: fin, state syn_recv->fin_wait1.\n");
00401 } else {
00402 DPRINT("tcps_syn_recv: state syn_recv.\n");
00403 }
00404 }
00405 return 0;
00406 }
00407
00408
00409
00410
00411
00412 int tcps_established (Ttcp_cb *cb, Tpacket_data *pd)
00413 {
00414 struct tcphdr *tcp = pd->trans.tcp;
00415
00416 if(pd->dir == PACKET_DIR_IN) {
00417 if(tcp->fin) {
00418 cb->state = TCPS_CLOSE_WAIT;
00419 DPRINT("tcps_established: fin, state established->close_wait.\n");
00420 } else {
00421 DPRINT("tcps_established: normal traffic.\n");
00422 }
00423 } else {
00424 if(tcp->fin) {
00425 cb->state = TCPS_FIN_WAIT1;
00426 DPRINT("tcps_established: fin, state established->fin_wait1.\n");
00427 } else {
00428 DPRINT("tcps_established: normal traffic.\n");
00429 }
00430 }
00431 return 0;
00432 }
00433
00434
00435
00436
00437
00438 int tcps_fin_wait1 (Ttcp_cb *cb, Tpacket_data *pd)
00439 {
00440 struct tcphdr *tcp = pd->trans.tcp;
00441
00442 if(pd->dir == PACKET_DIR_IN) {
00443 if(tcp->fin) {
00444 if(tcp->ack) {
00445 if(valid_ack(cb, pd)) {
00446 cb->state = TCPS_TIME_WAIT;
00447 add_timer(TCP_TWO_MSL, tcp_timeout, cb);
00448 DPRINT("tcps_fin_wait1: fin-ack, state fin_wait1->time_wait.\n");
00449 } else {
00450 cb->state = TCPS_CLOSING;
00451 DPRINT("tcps_fin_wait1: fin, state fin_wait1->closing.\n");
00452 }
00453 } else {
00454 DPRINT("tcps_fin_wait1: fin without ack bit set, invalid packet.\n");
00455 }
00456 } else if(tcp->ack) {
00457 if(valid_ack(cb, pd))
00458 {
00459 cb->state = TCPS_FIN_WAIT2;
00460 DPRINT("tcps_fin_wait1: ack, state fin_wait1->fin_wait2.\n");
00461 } else {
00462 DPRINT("tcps_fin_wait1: state fin_wait1.\n");
00463 }
00464 } else {
00465 DPRINT("tcps_fin_wait1: no ack bit set, bad packet.\n");
00466 }
00467
00468 } else {
00469 DPRINT("tcps_fin_wait1: state fin_wait1.\n");
00470 }
00471 return 0;
00472 }
00473
00474
00475
00476
00477
00478 int tcps_fin_wait2 (Ttcp_cb *cb, Tpacket_data *pd)
00479 {
00480 struct tcphdr *tcp = pd->trans.tcp;
00481
00482 if(pd->dir == PACKET_DIR_IN) {
00483 if(tcp->fin) {
00484 cb->state = TCPS_TIME_WAIT;
00485 add_timer(TCP_TWO_MSL, tcp_timeout, cb);
00486 DPRINT("tcps_fin_wait2: fin, state fin_wait2->time_wait.\n");
00487 } else {
00488 DPRINT("tcps_fin_wait2: state fin_wait2.\n");
00489 }
00490
00491 } else {
00492 DPRINT("tcps_fin_wait2: state fin_wait2.\n");
00493 }
00494 return 0;
00495 }
00496
00497
00498
00499
00500
00501 int tcps_time_wait (Ttcp_cb *cb, Tpacket_data *pd)
00502 {
00503 if(pd->dir == PACKET_DIR_IN) {
00504 DPRINT("tcps_time_wait: state time_wait.\n");
00505
00506 } else {
00507 DPRINT("tcps_time_wait: state time_wait.\n");
00508 }
00509 return 0;
00510 }
00511
00512
00513
00514
00515
00516 int tcps_closed (Ttcp_cb *cb, Tpacket_data *pd)
00517 {
00518 if(pd->dir == PACKET_DIR_IN) {
00519 EPRINT("tcps_closed: shouldn't ever get here.\n");
00520 assert(UNREACHABLE);
00521 } else {
00522 EPRINT("tcps_closed: shouldn't ever get here.\n");
00523 assert(UNREACHABLE);
00524 }
00525 return 0;
00526 }
00527
00528
00529
00530
00531
00532 int tcps_close_wait (Ttcp_cb *cb, Tpacket_data *pd)
00533 {
00534 struct tcphdr *tcp = pd->trans.tcp;
00535
00536 if(pd->dir == PACKET_DIR_IN) {
00537 DPRINT("tcps_close_wait: state close_wait.\n");
00538
00539 } else {
00540 if(tcp->fin) {
00541 if(tcp->ack) {
00542 if(valid_ack(cb, pd)) {
00543 cb->state = TCPS_LAST_ACK;
00544 add_timer(TCP_TWO_MSL, tcp_timeout, cb);
00545 DPRINT("tcp_close_wait: fin, state close_wait->last_ack.\n");
00546 } else {
00547 cb->state = TCPS_CLOSING;
00548 DPRINT("tcp_close_wait: fin, state close_wait->closing "
00549 "(wasn't actually in close_wait).\n");
00550 }
00551 } else {
00552 DPRINT("tcps_close_wait: fin without ack bit set, invalid packet.\n");
00553 }
00554 } else {
00555 DPRINT("tcps_close_wait: state close_wait.\n");
00556 }
00557 }
00558 return 0;
00559 }
00560
00561
00562
00563
00564
00565 int tcps_last_ack (Ttcp_cb *cb, Tpacket_data *pd)
00566 {
00567 struct tcphdr *tcp = pd->trans.tcp;
00568
00569 if(pd->dir == PACKET_DIR_IN) {
00570 if(tcp->ack) {
00571 if(valid_ack(cb, pd)) {
00572 cb->state = TCPS_CLOSED;
00573 DPRINT("tcps_last_ack: ack, state last_ack->closed.\n");
00574 } else {
00575 DPRINT("tcps_last_ack: bad ack number.\n");
00576 }
00577 } else {
00578 DPRINT("tcps_last_ack: no ack bit set, bad packet.\n");
00579 }
00580
00581 } else {
00582 DPRINT("tcps_last_ack: state last_ack.\n");
00583 }
00584 return 0;
00585 }
00586
00587
00588
00589
00590
00591 int tcps_closing (Ttcp_cb *cb, Tpacket_data *pd)
00592 {
00593 struct tcphdr *tcp = pd->trans.tcp;
00594
00595 if(pd->dir == PACKET_DIR_IN) {
00596 if(tcp->ack) {
00597 if(valid_ack(cb, pd)) {
00598 cb->state = TCPS_TIME_WAIT;
00599 add_timer(TCP_TWO_MSL, tcp_timeout, cb);
00600 DPRINT("tcps_closing: ack, state closing->time_wait.\n");
00601 } else {
00602 DPRINT("tcps_closing: bad ack number.\n");
00603 }
00604 } else {
00605 DPRINT("tcps_closing: state closing.\n");
00606 }
00607
00608 } else {
00609 DPRINT("tcps_closing: state closing.\n");
00610 }
00611 return 0;
00612 }
00613
00614
00615 int (*tcp_switch[TCPS_MAX_STATES])() = {
00616 tcps_err,
00617 tcps_new,
00618 tcps_syn_sent,
00619 tcps_syn_recv,
00620 tcps_established,
00621 tcps_fin_wait1,
00622 tcps_fin_wait2,
00623 tcps_time_wait,
00624 tcps_closed,
00625 tcps_close_wait,
00626 tcps_last_ack,
00627 tcps_closing
00628 };
00629
00630
00631
00632
00633
00634 void tcp_timeout(void *ptr)
00635 {
00636 Ttcp_cb *cb = (Ttcp_cb *)ptr;
00637
00638 assert(cb != NULL);
00639
00640 mutex_lock("tcp_timeout", &cb->mut);
00641 switch(cb->state)
00642 {
00643 case TCPS_SYN_SENT:
00644 DPRINT("tcp_timeout: state syn_sent.\n");
00645 break;
00646 case TCPS_LAST_ACK:
00647 DPRINT("tcp_timeout: state last_ack.\n");
00648 break;
00649 case TCPS_TIME_WAIT:
00650 DPRINT("tcp_timeout: state time_wait.\n");
00651 break;
00652 default:
00653 EPRINT("tcp_timeout: called with tcp in a state which does not have a timeout: %d\n",
00654 cb->state);
00655 mutex_unlock("tcp_timeout", &cb->mut);
00656 return;
00657 break;
00658 }
00659 cb->state = TCPS_CLOSED;
00660 dealloc_tcp_cb(cb);
00661 mutex_unlock("tcp_timeout", &cb->mut);
00662 }
00663
00664
00665
00666
00667
00668 int handle_tcp(Tpacket_data *pd)
00669 {
00670 struct iphdr *ip = pd->ip;
00671 struct tcphdr *tcp;
00672 Ttcp_cid cid;
00673 Ttcp_cid rcid;
00674 Ttcp_cb *cb;
00675 int i;
00676
00677 assert(pd != NULL);
00678
00679
00680 if((ip->ihl * 4 + 20) > pd->ipq_pm.data_len) {
00681 DPRINT("handle_tcp: malformed TCP packet: not enough data.\n");
00682 dealloc_packet_data(pd);
00683 return 1;
00684 }
00685
00686 tcp = pd->trans.tcp;
00687
00688 if(tcp_chksum(pd->ip)) {
00689 DPRINT("handle_tcp: bad TCP checksum: %u\n", ntohs(tcp->check));
00690 dealloc_packet_data(pd);
00691 return 1;
00692 }
00693
00694 DPRINT("tcp sport: %u, dport: %u, seq: %u, ack: %u, hlen: %u, flags: %c%c%c%c%c%c\n",
00695 ntohs(tcp->source), ntohs(tcp->dest), ntohl(tcp->seq), ntohl(tcp->ack_seq),
00696 tcp->doff,
00697 (tcp->urg ?'U':'.'), (tcp->ack ?'A':'.'), (tcp->psh ?'P':'.'),
00698 (tcp->rst ?'R':'.'), (tcp->syn ?'S':'.'), (tcp->fin ?'F':'.'));
00699
00700 cid.saddr = ip->saddr;
00701 cid.daddr = ip->daddr;
00702 cid.sport = tcp->source;
00703 cid.dport = tcp->dest;
00704 rcid.saddr = ip->daddr;
00705 rcid.daddr = ip->saddr;
00706 rcid.sport = tcp->dest;
00707 rcid.dport = tcp->source;
00708
00709 mutex_lock("handle_tcp", &tcp_tab_mut);
00710
00711 for(cb=&tcp_tab[0], i=0; i<TCP_MAX_CONN; i++, cb++) {
00712 if(cb->state != TCPS_FREE) {
00713 if(memcmp(&(cb->cid), &cid, sizeof(Ttcp_cid)) == 0 ||
00714 memcmp(&(cb->cid), &rcid, sizeof(Ttcp_cid)) == 0)
00715 break;
00716 }
00717 }
00718
00719 if(i >= TCP_MAX_CONN) {
00720 if(tcp->syn & !tcp->ack) {
00721 if(allow_conn(pd)) {
00722 Ttcp_cid *ncid;
00723
00724
00725
00726
00727 if(pd->dir == PACKET_DIR_IN)
00728 ncid = &rcid;
00729 else
00730 ncid = &cid;
00731
00732 cb = alloc_tcp_cb(pd, ncid);
00733
00734 if(cb == NULL) {
00735 dealloc_packet_data(pd);
00736 mutex_unlock("handle_tcp", &tcp_tab_mut);
00737 return -1;
00738 }
00739 } else {
00740 mutex_unlock("handle_tcp", &tcp_tab_mut);
00741 DPRINT("handle_tcp: connection denied: %s:%u > ",
00742 inet_ntoa(*(struct in_addr*)&(cid.saddr)), ntohs(cid.sport));
00743 DPRINT("%s:%u\n",
00744 inet_ntoa(*(struct in_addr*)&(cid.daddr)), ntohs(cid.dport));
00745 send_tcp_rst(pd);
00746 return 1;
00747 }
00748 } else {
00749 DPRINT("handle_tcp: new connection mid-stream.\n");
00750 mutex_unlock("handle_tcp", &tcp_tab_mut);
00751 send_tcp_rst(pd);
00752 return 1;
00753 }
00754 }
00755 assert(cb != NULL);
00756
00757 mutex_lock("handle_tcp", &cb->mut);
00758 mutex_unlock("handle_tcp", &tcp_tab_mut);
00759
00760
00761 if(tcp->rst) {
00762 cb->state = TCPS_CLOSED;
00763 DPRINT("handle_tcp: rst, state ->closed.\n");
00764 reset_tcp_queue(cb->out_queue);
00765 queue_hipri(pd);
00766
00767 } else if((tcp_switch[cb->state])(cb, pd) == 0) {
00768
00769 unsigned ack_seq = ntohl(tcp->ack_seq);
00770 unsigned seq = ntohl(tcp->seq) + tcp_data_size(pd);
00771
00772 if(pd->dir == PACKET_DIR_IN)
00773 {
00774 if(tcp->ack) {
00775 if((cb->init & TCP_INIT_MH_ACK) == 0) {
00776 cb->mh_ack = ack_seq;
00777 cb->init |= TCP_INIT_MH_ACK;
00778 DPRINT("handle_tcp: init mh_ack=%u\n", ack_seq);
00779 } else if(seq_cmp(ack_seq, cb->mh_ack) > 0) {
00780 cb->mh_ack = ack_seq;
00781 }
00782 }
00783 if((cb->init & TCP_INIT_FH_SEQ) == 0) {
00784 cb->fh_seq = seq;
00785 cb->init |= TCP_INIT_FH_SEQ;
00786 DPRINT("handle_tcp: init fh_seq=%u\n", seq);
00787 } else if(seq_cmp(seq, cb->fh_seq) > 0) {
00788 cb->fh_seq = seq;
00789 }
00790 } else {
00791 if(tcp->ack) {
00792 if((cb->init & TCP_INIT_FH_ACK) == 0) {
00793 cb->fh_ack = ack_seq;
00794 cb->init |= TCP_INIT_FH_ACK;
00795 DPRINT("handle_tcp: init fh_ack=%d\n", ack_seq);
00796 } else if(seq_cmp(ack_seq, cb->fh_ack) > 0) {
00797 cb->fh_ack = ack_seq;
00798
00799
00800 mh_ack_rcvd(ack_seq, cb->out_queue);
00801 }
00802 }
00803 if((cb->init & TCP_INIT_MH_SEQ) == 0) {
00804 cb->mh_seq = seq;
00805 cb->init |= TCP_INIT_MH_SEQ;
00806 DPRINT("handle_tcp: init mh_seq=%u\n", seq);
00807 } else if(seq_cmp(seq, cb->mh_seq) > 0) {
00808 cb->mh_seq = seq;
00809 }
00810 }
00811 clamp_tcp_win(pd);
00812 queue_tcp(pd, cb->out_queue);
00813 }
00814
00815 if(cb->state == TCPS_CLOSED)
00816 {
00817 clear_timer(tcp_timeout, cb);
00818 dealloc_tcp_cb(cb);
00819 }
00820
00821 mutex_unlock("handle_tcp", &cb->mut);
00822
00823 return 0;
00824 }