00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 #include <cfg/os.h>
00221 #include <cfg/tcp.h>
00222
00223 #include <sys/thread.h>
00224 #include <sys/heap.h>
00225 #include <sys/event.h>
00226 #include <sys/timer.h>
00227
00228 #include <net/errno.h>
00229 #include <netinet/in.h>
00230 #include <netinet/ip.h>
00231 #include <net/route.h>
00232 #include <sys/socket.h>
00233 #include <netinet/tcputil.h>
00234 #include <netinet/tcp.h>
00235
00236 #ifdef NUTDEBUG
00237 #include <net/netdebug.h>
00238 #endif
00239
00240 #ifndef NUT_THREAD_TCPSMSTACK
00241 #define NUT_THREAD_TCPSMSTACK 512
00242 #endif
00243
00244 extern TCPSOCKET *tcpSocketList;
00245
00250
00251 HANDLE tcp_in_rdy;
00252 NETBUF *volatile tcp_in_nbq;
00253 static u_short tcp_in_cnt;
00254 static HANDLE tcpThread = 0;
00255
00256
00257
00258
00259
00260
00269 static void NutTcpInputOptions(TCPSOCKET * sock, NETBUF * nb)
00270 {
00271 u_char *cp;
00272 u_short s;
00273
00274
00275 if (nb->nb_tp.sz <= sizeof (TCPHDR))
00276 return;
00277
00278
00279 for (cp = ((u_char*) nb->nb_tp.vp) + sizeof(TCPHDR); (*cp != TCPOPT_EOL)
00280 && (cp - (u_char *)nb->nb_tp.vp < (int)nb->nb_tp.sz); )
00281 {
00282 switch (*cp)
00283 {
00284
00285 case TCPOPT_NOP:
00286 cp++;
00287 continue;
00288
00289
00290 case TCPOPT_MAXSEG:
00291 s = ntohs(((u_short)cp[2] << 8) | cp[3]);
00292 if (s < sock->so_mss)
00293 sock->so_mss = s;
00294 cp += TCPOLEN_MAXSEG;
00295 break;
00296
00297 default:
00298 cp += *(u_char*) (cp + 1);
00299 break;
00300 }
00301 }
00302 }
00303
00312 static void NutTcpProcessAppData(TCPSOCKET * sock, NETBUF * nb)
00313 {
00314
00315
00316
00317 if (sock->so_rx_buf) {
00318 NETBUF *nbp = sock->so_rx_buf;
00319
00320 while (nbp->nb_next)
00321 nbp = nbp->nb_next;
00322 nbp->nb_next = nb;
00323 } else
00324 sock->so_rx_buf = nb;
00325
00326
00327
00328
00329
00330 sock->so_rx_cnt += nb->nb_ap.sz;
00331 sock->so_rx_nxt += nb->nb_ap.sz;
00332
00333
00334
00335
00336 if (nb->nb_ap.sz >= sock->so_rx_win)
00337 sock->so_rx_win = 0;
00338 else
00339 sock->so_rx_win -= nb->nb_ap.sz;
00340
00341
00342
00343
00344
00345
00346 sock->so_tx_flags |= SO_ACK;
00347 if (nb->nb_next)
00348 nb->nb_next = 0;
00349 else
00350 sock->so_tx_flags |= SO_FORCE;
00351
00352 NutTcpOutput(sock, 0, 0);
00353 }
00354
00355
00356
00357
00358 static void NutTcpProcessSyn(TCPSOCKET * sock, IPHDR * ih, TCPHDR * th)
00359 {
00360 u_short mss;
00361 NUTDEVICE *dev;
00362 IFNET *nif;
00363
00364 sock->so_local_addr = ih->ip_dst;
00365 sock->so_remote_port = th->th_sport;
00366 sock->so_remote_addr = ih->ip_src;
00367
00368 sock->so_rx_nxt = sock->so_tx_wl1 = sock->so_rx_isn = ntohl(th->th_seq);
00369 sock->so_rx_nxt++;
00370 sock->so_tx_win = ntohs(th->th_win);
00371
00372
00373
00374
00375
00376
00377 if ((dev = NutIpRouteQuery(ih->ip_src, 0)) != 0) {
00378 nif = dev->dev_icb;
00379 mss = nif->if_mtu - sizeof(IPHDR) - sizeof(TCPHDR);
00380 if (sock->so_mss == 0 || sock->so_mss > mss)
00381 sock->so_mss = mss;
00382
00383
00384 if (sock->so_devobsz > sock->so_mss)
00385 sock->so_devobsz = sock->so_mss;
00386 }
00387 }
00388
00396 static int NutTcpProcessAck(TCPSOCKET * sock, TCPHDR * th, u_short length)
00397 {
00398 NETBUF *nb;
00399 u_long h_seq;
00400 u_long h_ack;
00401
00402
00403
00404
00405 h_ack = ntohl(th->th_ack);
00406 if (h_ack > sock->so_tx_nxt) {
00407 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00408 return 0;
00409 }
00410
00411
00412
00413
00414
00415
00416 if (h_ack == sock->so_tx_una) {
00417 h_seq = ntohl(th->th_seq);
00418 if (h_seq > sock->so_tx_wl1 || (h_seq == sock->so_tx_wl1 && h_ack >= sock->so_tx_wl2)) {
00419 sock->so_tx_win = ntohs(th->th_win);
00420 sock->so_tx_wl1 = h_seq;
00421 sock->so_tx_wl2 = h_ack;
00422 }
00423 }
00424
00425
00426
00427
00428
00429 if (h_ack < sock->so_tx_una) {
00430 return 0;
00431 }
00432
00433
00434
00435
00436 if (h_ack == sock->so_tx_una) {
00437
00438
00439
00440
00441 if (sock->so_tx_nbq && length == 0 && (th->th_flags & (TH_SYN | TH_FIN)) == 0) {
00442
00443
00444
00445
00446 if (++sock->so_tx_dup >= 3) {
00447 sock->so_tx_dup = 0;
00448 #ifdef NUTDEBUG
00449 if (__tcp_trf)
00450 NutDumpTcpHeader(__tcp_trs, "RET", sock, sock->so_tx_nbq);
00451 #endif
00452
00453
00454
00455
00456 if (NutTcpStateRetranTimeout(sock))
00457 return -1;
00458 }
00459 }
00460 return 0;
00461 }
00462
00463
00464
00465
00466 sock->so_tx_dup = 0;
00467 sock->so_tx_una = h_ack;
00468
00469
00470
00471
00472
00473
00474 sock->so_tx_win = ntohs(th->th_win);
00475
00476
00477
00478
00479 if (sock->so_rtt_seq && sock->so_rtt_seq < h_ack)
00480 NutTcpCalcRtt (sock);
00481 sock->so_rtt_seq = 0;
00482
00483
00484
00485 while ((nb = sock->so_tx_nbq) != 0) {
00486
00487 h_seq = ntohl(((TCPHDR *) (nb->nb_tp.vp))->th_seq) + nb->nb_ap.sz;
00488 if (((TCPHDR *) (nb->nb_tp.vp))->th_flags & (TH_SYN | TH_FIN)) {
00489 h_seq++;
00490 }
00491
00492 if (h_seq > h_ack) {
00493 break;
00494 }
00495 sock->so_tx_nbq = nb->nb_next;
00496 NutNetBufFree(nb);
00497 }
00498
00499
00500
00501
00502 if (sock->so_tx_nbq) {
00503 sock->so_retran_time = (u_short) NutGetMillis() | 1;
00504 } else {
00505 sock->so_retran_time = 0;
00506 }
00507 sock->so_retransmits = 0;
00508
00509 return 0;
00510 }
00511
00512
00513
00514
00515
00516
00517
00526 static int NutTcpStateChange(TCPSOCKET * sock, u_char state)
00527 {
00528 int rc = 0;
00529 ureg_t txf = 0;
00530
00531 switch (sock->so_state) {
00532
00533 case TCPS_ESTABLISHED:
00534 switch (state) {
00535 case TCPS_FIN_WAIT_1:
00536
00537
00538
00539 sock->so_tx_flags |= SO_FIN | SO_ACK;
00540 txf = 1;
00541
00542 #ifdef RTLCONNECTHACK
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 NutDelay(5);
00553 #endif
00554 break;
00555 case TCPS_CLOSE_WAIT:
00556
00557
00558
00559 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00560 txf = 1;
00561 break;
00562 default:
00563 rc = -1;
00564 break;
00565 }
00566 break;
00567
00568 case TCPS_LISTEN:
00569
00570
00571
00572 if (state == TCPS_SYN_RECEIVED) {
00573 sock->so_tx_flags |= SO_SYN | SO_ACK;
00574 txf = 1;
00575 #ifdef RTLCONNECTHACK
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 NutDelay(5);
00586 #endif
00587 } else
00588 rc = -1;
00589 break;
00590
00591 case TCPS_SYN_SENT:
00592 switch (state) {
00593 case TCPS_LISTEN:
00594
00595
00596
00597 break;
00598 case TCPS_SYN_RECEIVED:
00599
00600
00601
00602 sock->so_tx_flags |= SO_SYN | SO_ACK;
00603 txf = 1;
00604 break;
00605 case TCPS_ESTABLISHED:
00606
00607
00608
00609 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00610 txf = 1;
00611 break;
00612 default:
00613 rc = -1;
00614 break;
00615 }
00616 break;
00617
00618 case TCPS_SYN_RECEIVED:
00619 switch (state) {
00620 case TCPS_LISTEN:
00621
00622
00623
00624 break;
00625 case TCPS_ESTABLISHED:
00626
00627
00628
00629 break;
00630 case TCPS_FIN_WAIT_1:
00631
00632
00633
00634 sock->so_tx_flags |= SO_FIN;
00635 txf = 1;
00636 break;
00637 case TCPS_CLOSE_WAIT:
00638
00639
00640
00641 sock->so_tx_flags |= SO_FIN | SO_ACK;
00642 txf = 1;
00643 break;
00644 default:
00645 rc = -1;
00646 break;
00647 }
00648 break;
00649
00650 case TCPS_FIN_WAIT_1:
00651 switch (state) {
00652 case TCPS_FIN_WAIT_1:
00653 case TCPS_FIN_WAIT_2:
00654
00655
00656
00657 break;
00658 case TCPS_CLOSING:
00659
00660
00661
00662 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00663 txf = 1;
00664 break;
00665 case TCPS_TIME_WAIT:
00666
00667
00668
00669 break;
00670 default:
00671 rc = -1;
00672 break;
00673 }
00674 break;
00675
00676 case TCPS_FIN_WAIT_2:
00677
00678
00679
00680 if (state != TCPS_TIME_WAIT)
00681 rc = -1;
00682 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00683 txf = 1;
00684 break;
00685
00686 case TCPS_CLOSE_WAIT:
00687
00688
00689
00690 if (state == TCPS_LAST_ACK) {
00691 sock->so_tx_flags |= SO_FIN | SO_ACK;
00692 txf = 1;
00693 } else
00694 rc = -1;
00695 break;
00696
00697 case TCPS_CLOSING:
00698
00699
00700
00701 if (state != TCPS_TIME_WAIT)
00702 rc = -1;
00703 break;
00704
00705 case TCPS_LAST_ACK:
00706 rc = -1;
00707 break;
00708
00709 case TCPS_TIME_WAIT:
00710 rc = -1;
00711 break;
00712
00713 case TCPS_CLOSED:
00714 switch (state) {
00715 case TCPS_LISTEN:
00716
00717
00718
00719 break;
00720 case TCPS_SYN_SENT:
00721
00722
00723
00724 sock->so_tx_flags |= SO_SYN;
00725 txf = 1;
00726 break;
00727 default:
00728 rc = -1;
00729 break;
00730 }
00731 break;
00732 }
00733 #ifdef NUTDEBUG
00734 if (__tcp_trf) {
00735 fprintf(__tcp_trs, " %04x-", (u_int) sock);
00736 if (rc)
00737 NutDumpSockState(__tcp_trs, sock->so_state, "**ERR ", "**>");
00738 NutDumpSockState(__tcp_trs, state, "[>", "]");
00739 }
00740 #endif
00741
00742 if (rc == 0) {
00743 sock->so_state = state;
00744 if (txf && NutTcpOutput(sock, 0, 0)) {
00745 if (state == TCPS_SYN_SENT) {
00746 rc = -1;
00747 sock->so_last_error = EHOSTDOWN;
00748 NutEventPostAsync(&sock->so_ac_tq);
00749 }
00750 }
00751 if (state == TCPS_CLOSE_WAIT) {
00752
00753
00754
00755 NutEventBroadcast(&sock->so_rx_tq);
00756 NutEventBroadcast(&sock->so_pc_tq);
00757 NutEventBroadcast(&sock->so_ac_tq);
00758 }
00759 }
00760 return rc;
00761 }
00762
00763
00764
00765
00766
00775 int NutTcpStatePassiveOpenEvent(TCPSOCKET * sock)
00776 {
00777 if (sock->so_state != TCPS_CLOSED)
00778 return (sock->so_last_error = EISCONN);
00779
00780 NutTcpStateChange(sock, TCPS_LISTEN);
00781
00782
00783
00784
00785 NutEventWait(&sock->so_pc_tq, 0);
00786
00787 return 0;
00788 }
00789
00800 int NutTcpStateActiveOpenEvent(TCPSOCKET * sock)
00801 {
00802
00803
00804
00805
00806 NutTcpStateChange(sock, TCPS_SYN_SENT);
00807
00808
00809
00810
00811 if(sock->so_state == TCPS_SYN_SENT)
00812 NutEventWait(&sock->so_ac_tq, 0);
00813
00814 if (sock->so_state != TCPS_ESTABLISHED)
00815 return -1;
00816
00817 return 0;
00818 }
00819
00832 int NutTcpStateCloseEvent(TCPSOCKET * sock)
00833 {
00834 if (sock == 0)
00835 return -1;
00836
00837 NutThreadYield();
00838
00839 switch (sock->so_state) {
00840 case TCPS_LISTEN:
00841 case TCPS_SYN_SENT:
00842 case TCPS_CLOSED:
00843
00844
00845
00846 NutTcpDestroySocket(sock);
00847 break;
00848
00849 case TCPS_SYN_RECEIVED:
00850 case TCPS_ESTABLISHED:
00851
00852
00853
00854
00855 NutTcpStateChange(sock, TCPS_FIN_WAIT_1);
00856 break;
00857
00858 case TCPS_CLOSE_WAIT:
00859
00860
00861
00862
00863 NutTcpStateChange(sock, TCPS_LAST_ACK);
00864 break;
00865
00866 case TCPS_FIN_WAIT_1:
00867 case TCPS_FIN_WAIT_2:
00868 case TCPS_CLOSING:
00869 case TCPS_LAST_ACK:
00870 case TCPS_TIME_WAIT:
00871 sock->so_last_error = EALREADY;
00872 return -1;
00873
00874 default:
00875 sock->so_last_error = ENOTCONN;
00876 return -1;
00877 }
00878 return 0;
00879 }
00880
00887 int NutTcpStateWindowEvent(TCPSOCKET * sock)
00888 {
00889 if (sock == 0)
00890 return -1;
00891 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00892 NutTcpOutput(sock, 0, 0);
00893
00894 return 0;
00895 }
00896
00897
00898
00899
00900
00912 int NutTcpStateRetranTimeout(TCPSOCKET * sock)
00913 {
00914 NETBUF *so_tx_next;
00915 if (sock->so_retransmits++ > 7)
00916 {
00917
00918 NutTcpAbortSocket(sock, ETIMEDOUT);
00919 return -1;
00920 } else {
00921 #ifdef NUTDEBUG
00922 if (__tcp_trf)
00923 NutDumpTcpHeader(__tcp_trs, "RET", sock, sock->so_tx_nbq);
00924 #endif
00925
00926
00927
00928
00929 so_tx_next = sock->so_tx_nbq->nb_next;
00930 if (NutIpOutput(IPPROTO_TCP, sock->so_remote_addr, sock->so_tx_nbq)) {
00931
00932 sock->so_tx_nbq = so_tx_next;
00933
00934 NutTcpAbortSocket(sock, ENETDOWN);
00935 return -1;
00936 } else {
00937
00938 sock->so_retran_time = (u_short) NutGetMillis() | 1;
00939 return 0;
00940 }
00941 }
00942 }
00943
00944
00945
00946
00947
00948
00958 static void NutTcpStateListen(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
00959 {
00960
00961
00962
00963
00964 if ((flags & (TH_SYN | TH_ACK | TH_RST)) == TH_SYN) {
00965 NutTcpProcessSyn(sock, nb->nb_nw.vp, th);
00966 NutTcpStateChange(sock, TCPS_SYN_RECEIVED);
00967 NutNetBufFree(nb);
00968 } else
00969 NutTcpReject(nb);
00970 }
00971
00972
00981 static void NutTcpStateSynSent(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
00982 {
00983
00984
00985
00986 if (flags & TH_ACK) {
00987 if (!IsInLimits(ntohl(th->th_ack), sock->so_tx_isn + 1, sock->so_tx_nxt)) {
00988 NutTcpReject(nb);
00989 return;
00990 }
00991 }
00992
00993
00994
00995
00996
00997
00998 if (flags & TH_RST) {
00999 if (flags & TH_ACK) {
01000
01001
01002
01003 NutTcpAbortSocket(sock, ECONNREFUSED);
01004 }
01005 NutNetBufFree(nb);
01006 return;
01007 }
01008
01009
01010
01011
01012
01013
01014 if (flags & TH_SYN) {
01015 NutTcpProcessSyn(sock, nb->nb_nw.vp, th);
01016 if (flags & TH_ACK) {
01017 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01018 NutTcpStateChange(sock, TCPS_ESTABLISHED);
01019
01020 NutEventPost(&sock->so_ac_tq);
01021 } else {
01022 NutTcpStateChange(sock, TCPS_SYN_RECEIVED);
01023 }
01024 }
01025 NutNetBufFree(nb);
01026 }
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039 static void NutTcpStateSynReceived(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01040 {
01041
01042
01043
01044
01045 if (flags & TH_RST) {
01046 if (sock->so_pc_tq)
01047 NutTcpStateChange(sock, TCPS_LISTEN);
01048 else
01049 NutTcpAbortSocket(sock, ECONNREFUSED);
01050 NutNetBufFree(nb);
01051 sock->so_retran_time = 0;
01052 NutTcpDiscardBuffers(sock);
01053 return;
01054 }
01055
01056
01057
01058
01059 if (flags & TH_SYN) {
01060 NutTcpReject(nb);
01061 return;
01062 }
01063
01064
01065
01066
01067 if ((flags & TH_ACK) == 0) {
01068 NutNetBufFree(nb);
01069 return;
01070 }
01071
01072
01073
01074
01075 if (!IsInLimits(ntohl(th->th_ack), sock->so_tx_una + 1, sock->so_tx_nxt)) {
01076 NutTcpReject(nb);
01077 return;
01078 }
01079
01080
01081 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01082
01083
01084
01085
01086
01087
01088
01089 if (nb->nb_ap.sz)
01090 NutTcpProcessAppData(sock, nb);
01091 else
01092 NutNetBufFree(nb);
01093
01094
01095
01096
01097 if (flags & TH_FIN) {
01098 sock->so_rx_nxt++;
01099 NutTcpStateChange(sock, TCPS_CLOSE_WAIT);
01100 } else {
01101 NutTcpStateChange(sock, TCPS_ESTABLISHED);
01102 NutEventPost(&sock->so_pc_tq);
01103 NutEventPost(&sock->so_ac_tq);
01104 }
01105 }
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121 static void NutTcpStateEstablished(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01122 {
01123 if (flags & TH_RST) {
01124 NutNetBufFree(nb);
01125 NutTcpAbortSocket(sock, ECONNRESET);
01126 return;
01127 }
01128
01129
01130
01131
01132
01133 if (flags & TH_SYN) {
01134 if (htonl(th->th_seq) != sock->so_rx_isn)
01135 NutTcpReject(nb);
01136 else
01137 NutNetBufFree(nb);
01138 return;
01139 }
01140
01141
01142
01143
01144 if ((flags & TH_ACK) == 0) {
01145 NutNetBufFree(nb);
01146 return;
01147 }
01148
01149 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01150
01151
01152
01153
01154
01155
01156
01157 if (htonl(th->th_seq) > sock->so_rx_nxt) {
01158 NETBUF *nbq;
01159 NETBUF **nbqp;
01160 TCPHDR *thq;
01161 u_long th_seq;
01162 u_long thq_seq;
01163
01164 if (nb->nb_ap.sz) {
01165 nbq = sock->so_rx_nbq;
01166 nbqp = &sock->so_rx_nbq;
01167 while (nbq) {
01168 thq = (TCPHDR *) (nbq->nb_tp.vp);
01169 th_seq = htonl(th->th_seq);
01170 thq_seq = htonl(thq->th_seq);
01171 if (th_seq < thq_seq) {
01172 *nbqp = nb;
01173 nb->nb_next = nbq;
01174 break;
01175 }
01176 if (th_seq == thq_seq) {
01177 NutNetBufFree(nb);
01178 sock->so_tx_flags |= SO_ACK | SO_FORCE;
01179 NutTcpOutput(sock, 0, 0);
01180 return;
01181 }
01182 nbqp = &nbq->nb_next;
01183 nbq = nbq->nb_next;
01184 }
01185 if (nbq == 0) {
01186 *nbqp = nb;
01187 nb->nb_next = 0;
01188 }
01189 } else
01190 NutNetBufFree(nb);
01191
01192 sock->so_tx_flags |= SO_ACK | SO_FORCE;
01193 NutTcpOutput(sock, 0, 0);
01194 return;
01195 }
01196
01197
01198
01199
01200
01201
01202
01203
01204 if (htonl(th->th_seq) != sock->so_rx_nxt) {
01205 sock->so_tx_flags |= SO_ACK | SO_FORCE;
01206
01207 sock->so_oos_drop++;
01208 NutNetBufFree(nb);
01209 NutTcpOutput(sock, 0, 0);
01210 }
01211
01212
01213
01214
01215 else if (nb->nb_ap.sz) {
01216 NutTcpProcessAppData(sock, nb);
01217
01218
01219
01220 while ((nb = sock->so_rx_nbq) != 0) {
01221 th = (TCPHDR *) (nb->nb_tp.vp);
01222 if (htonl(th->th_seq) > sock->so_rx_nxt)
01223 break;
01224 sock->so_rx_nbq = nb->nb_next;
01225 if (htonl(th->th_seq) == sock->so_rx_nxt) {
01226 NutTcpProcessAppData(sock, nb);
01227 flags |= th->th_flags;
01228 } else
01229 NutNetBufFree(nb);
01230 }
01231
01232 NutEventPost(&sock->so_rx_tq);
01233 } else {
01234 NutNetBufFree(nb);
01235
01236
01237 }
01238 if (flags & TH_FIN) {
01239
01240 sock->so_rx_nxt++;
01241 NutTcpStateChange(sock, TCPS_CLOSE_WAIT);
01242 }
01243 }
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 static void NutTcpStateFinWait1(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01261 {
01262
01263 if (flags & TH_RST) {
01264 NutNetBufFree(nb);
01265 NutTcpDestroySocket(sock);
01266 return;
01267 }
01268
01269
01270
01271
01272 if (flags & TH_SYN) {
01273 NutTcpReject(nb);
01274 return;
01275 }
01276
01277
01278
01279
01280 if ((flags & TH_ACK) == 0) {
01281 NutNetBufFree(nb);
01282 return;
01283 }
01284
01285
01286
01287
01288
01289 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01290
01291
01292
01293
01294
01295 if (sock->so_tx_nxt == sock->so_tx_una) {
01296
01297 NutTcpStateChange(sock, TCPS_FIN_WAIT_2);
01298 }
01299
01300
01301
01302
01303
01304 if (nb->nb_ap.sz) {
01305 NutTcpProcessAppData(sock, nb);
01306
01307 NutEventPost(&sock->so_rx_tq);
01308 }
01309 else
01310 NutNetBufFree(nb);
01311
01312 if (flags & TH_FIN) {
01313 sock->so_rx_nxt++;
01314
01315
01316
01317 sock->so_time_wait = 0;
01318
01319 if (sock->so_state == TCPS_FIN_WAIT_2)
01320 NutTcpStateChange(sock, TCPS_TIME_WAIT);
01321 else
01322 NutTcpStateChange(sock, TCPS_CLOSING);
01323 }
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 static void NutTcpStateFinWait2(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01340 {
01341
01342 if (flags & TH_RST) {
01343 NutNetBufFree(nb);
01344 NutTcpDestroySocket(sock);
01345 return;
01346 }
01347
01348
01349
01350
01351 if (flags & TH_SYN) {
01352 NutTcpReject(nb);
01353 return;
01354 }
01355
01356
01357
01358
01359 if ((flags & TH_ACK) == 0) {
01360 NutNetBufFree(nb);
01361 return;
01362 }
01363
01364
01365
01366
01367
01368
01369 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01370
01371
01372
01373 if (nb->nb_ap.sz) {
01374 NutTcpProcessAppData(sock, nb);
01375
01376 NutEventPost(&sock->so_rx_tq);
01377 }
01378 else
01379 NutNetBufFree(nb);
01380
01381 if (flags & TH_FIN) {
01382 sock->so_rx_nxt++;
01383 sock->so_time_wait = 0;
01384
01385 NutTcpStateChange(sock, TCPS_TIME_WAIT);
01386 }
01387 }
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static void NutTcpStateCloseWait(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01400 {
01401
01402 if (flags & TH_RST) {
01403 NutNetBufFree(nb);
01404 NutTcpAbortSocket(sock, ECONNRESET);
01405 return;
01406 }
01407
01408
01409
01410
01411 if (flags & TH_SYN) {
01412 NutTcpReject(nb);
01413 return;
01414 }
01415
01416
01417
01418
01419 if ((flags & TH_ACK) == 0) {
01420 NutNetBufFree(nb);
01421 return;
01422 }
01423
01424 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01425
01426 NutNetBufFree(nb);
01427 }
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441 static void NutTcpStateClosing(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01442 {
01443
01444 if (flags & TH_RST) {
01445 NutNetBufFree(nb);
01446 NutTcpDestroySocket(sock);
01447 return;
01448 }
01449
01450
01451
01452
01453 if (flags & TH_SYN) {
01454 NutTcpReject(nb);
01455 return;
01456 }
01457
01458
01459
01460
01461 if ((flags & TH_ACK) == 0) {
01462 NutNetBufFree(nb);
01463 return;
01464 }
01465
01466 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01467
01468
01469
01470
01471 if (sock->so_tx_nxt == sock->so_tx_una) {
01472 sock->so_time_wait = 0;
01473 NutTcpStateChange(sock, TCPS_TIME_WAIT);
01474
01475 }
01476
01477
01478 NutNetBufFree(nb);
01479 }
01480
01495 static void NutTcpStateLastAck(TCPSOCKET * sock, u_char flags, TCPHDR * th, NETBUF * nb)
01496 {
01497
01498 if (flags & TH_RST) {
01499 NutNetBufFree(nb);
01500 NutTcpDestroySocket(sock);
01501 return;
01502 }
01503
01504
01505
01506
01507 if (flags & TH_SYN) {
01508 NutTcpReject(nb);
01509 return;
01510 }
01511
01512
01513
01514
01515 if ((flags & TH_ACK) == 0) {
01516 NutNetBufFree(nb);
01517 return;
01518 }
01519
01520 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01521 NutNetBufFree(nb);
01522
01523 if (sock->so_tx_nxt == sock->so_tx_una)
01524 NutTcpDestroySocket(sock);
01525
01526 }
01527
01538 static void NutTcpStateProcess(TCPSOCKET * sock, NETBUF * nb)
01539 {
01540 u_long tx_win;
01541 u_long tx_una;
01542 TCPHDR *th = (TCPHDR *) nb->nb_tp.vp;
01543 u_char flags = th->th_flags;
01544
01545 #ifdef NUTDEBUG
01546 if (__tcp_trf) {
01547 fprintf(__tcp_trs, " %04x-", (u_int) sock);
01548 NutDumpSockState(__tcp_trs, sock->so_state, "[", ">]");
01549 }
01550 #endif
01551 switch (sock->so_state) {
01552
01553 case TCPS_ESTABLISHED:
01554 tx_win = sock->so_tx_win;
01555 tx_una = sock->so_tx_una;
01556 NutTcpStateEstablished(sock, flags, th, nb);
01557
01558 if(sock->so_state != TCPS_ESTABLISHED ||
01559 sock->so_tx_win > tx_win ||
01560 sock->so_tx_una > tx_una) {
01561 NutEventBroadcast(&sock->so_tx_tq);
01562 }
01563 break;
01564 case TCPS_LISTEN:
01565 NutTcpStateListen(sock, flags, th, nb);
01566 break;
01567 case TCPS_SYN_SENT:
01568 NutTcpStateSynSent(sock, flags, th, nb);
01569 break;
01570 case TCPS_SYN_RECEIVED:
01571 NutTcpStateSynReceived(sock, flags, th, nb);
01572 break;
01573 case TCPS_FIN_WAIT_1:
01574 NutTcpStateFinWait1(sock, flags, th, nb);
01575 break;
01576 case TCPS_FIN_WAIT_2:
01577 NutTcpStateFinWait2(sock, flags, th, nb);
01578 break;
01579 case TCPS_CLOSE_WAIT:
01580 NutTcpStateCloseWait(sock, flags, th, nb);
01581 break;
01582 case TCPS_CLOSING:
01583 NutTcpStateClosing(sock, flags, th, nb);
01584 break;
01585 case TCPS_LAST_ACK:
01586 NutTcpStateLastAck(sock, flags, th, nb);
01587 break;
01588 case TCPS_TIME_WAIT:
01589
01590
01591
01592 NutNetBufFree(nb);
01593 break;
01594 case TCPS_CLOSED:
01595
01596
01597
01598 NutTcpReject(nb);
01599 break;
01600 default:
01601 NutNetBufFree(nb);
01602 break;
01603 }
01604 }
01605
01612 THREAD(NutTcpSm, arg)
01613 {
01614 NETBUF *nb;
01615 NETBUF *nbx;
01616 TCPHDR *th;
01617 IPHDR *ih;
01618 TCPSOCKET *sock;
01619 u_char tac = 0;
01620
01621
01622
01623
01624
01625 NutThreadSetPriority (32);
01626
01627 for (;;) {
01628 if (++tac > 3 || NutEventWait(&tcp_in_rdy, 200)) {
01629 tac = 0;
01630 for (sock = tcpSocketList; sock; sock = sock->so_next) {
01631
01632
01633
01634
01635 if (sock->so_tx_flags & SO_ACK) {
01636 sock->so_tx_flags |= SO_FORCE;
01637 NutTcpOutput(sock, 0, 0);
01638 }
01639
01640
01641
01642
01643 if (sock->so_tx_nbq && sock->so_retran_time) {
01644 if ((u_short)((u_short)NutGetMillis() - sock->so_retran_time) > sock->so_rtto) {
01645 NutTcpStateRetranTimeout(sock);
01646 }
01647 }
01648
01649
01650
01651
01652 if (sock->so_state == TCPS_TIME_WAIT || sock->so_state == TCPS_FIN_WAIT_2) {
01653 if (sock->so_time_wait++ >= 9) {
01654 NutTcpDestroySocket(sock);
01655 break;
01656 }
01657 }
01658
01659
01660
01661
01662 else if (sock->so_state == TCPS_SYN_RECEIVED) {
01663 if (sock->so_time_wait++ >= 45) {
01664 sock->so_state = TCPS_LISTEN;
01665 sock->so_time_wait = 0;
01666 }
01667 }
01668 }
01669 } else {
01670 nb = tcp_in_nbq;
01671 tcp_in_nbq = 0;
01672 tcp_in_cnt = 0;
01673 while (nb) {
01674 ih = (IPHDR *) nb->nb_nw.vp;
01675 th = (TCPHDR *) nb->nb_tp.vp;
01676 sock = NutTcpFindSocket(th->th_dport, th->th_sport, ih->ip_src);
01677 #ifdef NUTDEBUG
01678 if (__tcp_trf)
01679 NutDumpTcpHeader(__tcp_trs, " IN", sock, nb);
01680 #endif
01681 nbx = nb->nb_next;
01682 if (sock) {
01683 NutTcpInputOptions(sock, nb);
01684 NutTcpStateProcess(sock, nb);
01685 }
01686
01687
01688
01689
01690 else
01691 NutTcpReject(nb);
01692 nb = nbx;
01693 }
01694 }
01695 }
01696 }
01697
01709 void NutTcpStateMachine(NETBUF * nb)
01710 {
01711 NETBUF *nbp;
01712 u_short size;
01713
01714 nb->nb_next = 0;
01715
01716
01717
01718
01719
01720
01721
01722 if (tcpThread == 0) {
01723 NutTcpReject(nb);
01724 return;
01725 }
01726
01727 if ((nbp = tcp_in_nbq) == 0) {
01728 tcp_in_nbq = nb;
01729 NutEventPost(&tcp_in_rdy);
01730 } else {
01731 size = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
01732 if (tcp_in_cnt + size + 2048 < NutHeapAvailable()) {
01733 tcp_in_cnt += size;
01734 while (nbp->nb_next)
01735 nbp = nbp->nb_next;
01736 nbp->nb_next = nb;
01737 NutEventPost(&tcp_in_rdy);
01738 } else
01739 NutNetBufFree(nb);
01740 }
01741 }
01742
01751 int NutTcpInitStateMachine(void)
01752 {
01753 if (tcpThread == 0 && (tcpThread = NutThreadCreate("tcpsm", NutTcpSm, NULL, NUT_THREAD_TCPSMSTACK)) == 0)
01754 return -1;
01755 return 0;
01756 }
01757
01771 int NutTcpAbortSocket(TCPSOCKET * sock, u_short last_error)
01772 {
01773 sock->so_last_error = last_error;
01774 sock->so_retran_time = 0;
01775 sock->so_time_wait = 0;
01776
01777
01778
01779
01780
01781 if (sock->so_state >= TCPS_FIN_WAIT_1)
01782 sock->so_state = TCPS_TIME_WAIT;
01783 else
01784 sock->so_state = TCPS_CLOSED;
01785 NutTcpDiscardBuffers(sock);
01786 NutEventBroadcast(&sock->so_rx_tq);
01787 NutEventBroadcast(&sock->so_tx_tq);
01788 NutEventBroadcast(&sock->so_pc_tq);
01789 NutEventBroadcast(&sock->so_ac_tq);
01790 return 0;
01791 }
01792