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
00221
00222
00223
00224
00225
00226 #include <cfg/os.h>
00227 #include <cfg/tcp.h>
00228
00229 #include <sys/thread.h>
00230 #include <sys/heap.h>
00231 #include <sys/event.h>
00232 #include <sys/timer.h>
00233
00234 #include <net/errno.h>
00235 #include <netinet/in.h>
00236 #include <netinet/ip.h>
00237 #include <net/route.h>
00238 #include <sys/socket.h>
00239 #include <netinet/tcputil.h>
00240 #include <netinet/tcp.h>
00241
00242 #ifdef NUTDEBUG
00243 #include <net/netdebug.h>
00244 #endif
00245
00246 #ifndef NUT_THREAD_TCPSMSTACK
00247 #define NUT_THREAD_TCPSMSTACK 512
00248 #endif
00249
00250 #ifndef TCP_RETRIES_MAX
00251 #define TCP_RETRIES_MAX 7
00252 #endif
00253
00254 extern TCPSOCKET *tcpSocketList;
00255
00260
00261 HANDLE tcp_in_rdy;
00262 NETBUF *volatile tcp_in_nbq;
00263 static uint16_t tcp_in_cnt;
00264 static HANDLE tcpThread = 0;
00265
00266
00267
00268
00269
00270
00279 static void NutTcpInputOptions(TCPSOCKET * sock, NETBUF * nb)
00280 {
00281 uint8_t *cp;
00282 uint16_t s;
00283
00284
00285 if (nb->nb_tp.sz <= sizeof (TCPHDR))
00286 return;
00287
00288
00289 for (cp = ((uint8_t*) nb->nb_tp.vp) + sizeof(TCPHDR); (*cp != TCPOPT_EOL)
00290 && (cp - (uint8_t *)nb->nb_tp.vp < (int)nb->nb_tp.sz); )
00291 {
00292 switch (*cp)
00293 {
00294
00295 case TCPOPT_NOP:
00296 cp++;
00297 continue;
00298
00299
00300 case TCPOPT_MAXSEG:
00301 s = ntohs(((uint16_t)cp[2] << 8) | cp[3]);
00302 if (s < sock->so_mss)
00303 sock->so_mss = s;
00304 cp += TCPOLEN_MAXSEG;
00305 break;
00306
00307 default:
00308 cp += *(uint8_t*) (cp + 1);
00309 break;
00310 }
00311 }
00312 }
00313
00322 static void NutTcpProcessAppData(TCPSOCKET * sock, NETBUF * nb)
00323 {
00324
00325
00326
00327 if (sock->so_rx_buf) {
00328 NETBUF *nbp = sock->so_rx_buf;
00329
00330 while (nbp->nb_next)
00331 nbp = nbp->nb_next;
00332 nbp->nb_next = nb;
00333 } else
00334 sock->so_rx_buf = nb;
00335
00336
00337
00338
00339
00340 sock->so_rx_cnt += nb->nb_ap.sz;
00341 sock->so_rx_nxt += nb->nb_ap.sz;
00342
00343
00344
00345
00346 if (nb->nb_ap.sz >= sock->so_rx_win)
00347 sock->so_rx_win = 0;
00348 else
00349 sock->so_rx_win -= nb->nb_ap.sz;
00350
00351
00352
00353
00354
00355
00356 sock->so_tx_flags |= SO_ACK;
00357 if (nb->nb_next)
00358 nb->nb_next = 0;
00359 else
00360 sock->so_tx_flags |= SO_FORCE;
00361
00362 NutTcpOutput(sock, 0, 0);
00363 }
00364
00365
00366
00367
00368 static void NutTcpProcessSyn(TCPSOCKET * sock, IPHDR * ih, TCPHDR * th)
00369 {
00370 uint16_t mss;
00371 NUTDEVICE *dev;
00372 IFNET *nif;
00373
00374 sock->so_local_addr = ih->ip_dst;
00375 sock->so_remote_port = th->th_sport;
00376 sock->so_remote_addr = ih->ip_src;
00377
00378 sock->so_rx_nxt = sock->so_tx_wl1 = sock->so_rx_isn = ntohl(th->th_seq);
00379 sock->so_rx_nxt++;
00380 sock->so_tx_win = ntohs(th->th_win);
00381
00382
00383
00384
00385
00386
00387 if ((dev = NutIpRouteQuery(ih->ip_src, 0)) != 0) {
00388 nif = dev->dev_icb;
00389 mss = nif->if_mtu - sizeof(IPHDR) - sizeof(TCPHDR);
00390 if (sock->so_mss == 0 || sock->so_mss > mss)
00391 sock->so_mss = mss;
00392
00393
00394 if (sock->so_devobsz > sock->so_mss)
00395 sock->so_devobsz = sock->so_mss;
00396 }
00397 }
00398
00406 static int NutTcpProcessAck(TCPSOCKET * sock, TCPHDR * th, uint16_t length)
00407 {
00408 NETBUF *nb;
00409 uint32_t h_seq;
00410 uint32_t h_ack;
00411
00412
00413
00414
00415 h_ack = ntohl(th->th_ack);
00416 if (h_ack > sock->so_tx_nxt) {
00417 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00418 return 0;
00419 }
00420
00421
00422
00423
00424
00425
00426 if (h_ack == sock->so_tx_una) {
00427 h_seq = ntohl(th->th_seq);
00428 if (h_seq > sock->so_tx_wl1 || (h_seq == sock->so_tx_wl1 && h_ack >= sock->so_tx_wl2)) {
00429 sock->so_tx_win = ntohs(th->th_win);
00430 sock->so_tx_wl1 = h_seq;
00431 sock->so_tx_wl2 = h_ack;
00432 }
00433 }
00434
00435
00436
00437
00438
00439 if (h_ack < sock->so_tx_una) {
00440 return 0;
00441 }
00442
00443
00444
00445
00446 if (h_ack == sock->so_tx_una) {
00447
00448
00449
00450
00451 if (sock->so_tx_nbq && length == 0 && (th->th_flags & (TH_SYN | TH_FIN)) == 0) {
00452
00453
00454
00455
00456 if (++sock->so_tx_dup >= 3) {
00457 sock->so_tx_dup = 0;
00458 #ifdef NUTDEBUG
00459 if (__tcp_trf)
00460 NutDumpTcpHeader(__tcp_trs, "RET", sock, sock->so_tx_nbq);
00461 #endif
00462
00463
00464
00465
00466 if (NutTcpStateRetranTimeout(sock))
00467 return -1;
00468 }
00469 }
00470 return 0;
00471 }
00472
00473
00474
00475
00476 sock->so_tx_dup = 0;
00477 sock->so_tx_una = h_ack;
00478
00479
00480
00481
00482
00483
00484 sock->so_tx_win = ntohs(th->th_win);
00485
00486
00487
00488
00489 if (sock->so_rtt_seq && sock->so_rtt_seq < h_ack)
00490 NutTcpCalcRtt (sock);
00491 sock->so_rtt_seq = 0;
00492
00493
00494
00495 while ((nb = sock->so_tx_nbq) != 0) {
00496
00497 h_seq = ntohl(((TCPHDR *) (nb->nb_tp.vp))->th_seq) + nb->nb_ap.sz;
00498 if (((TCPHDR *) (nb->nb_tp.vp))->th_flags & (TH_SYN | TH_FIN)) {
00499 h_seq++;
00500 }
00501
00502 if (h_seq > h_ack) {
00503 break;
00504 }
00505 sock->so_tx_nbq = nb->nb_next;
00506 NutNetBufFree(nb);
00507 }
00508
00509
00510
00511
00512 if (sock->so_tx_nbq) {
00513 sock->so_retran_time = (uint16_t) NutGetMillis() | 1;
00514 } else {
00515 sock->so_retran_time = 0;
00516 }
00517 sock->so_retransmits = 0;
00518
00519 return 0;
00520 }
00521
00522
00523
00524
00525
00526
00527
00536 static int NutTcpStateChange(TCPSOCKET * sock, uint8_t state)
00537 {
00538 int rc = 0;
00539 ureg_t txf = 0;
00540
00541 switch (sock->so_state) {
00542
00543 case TCPS_ESTABLISHED:
00544 switch (state) {
00545 case TCPS_FIN_WAIT_1:
00546
00547
00548
00549 sock->so_tx_flags |= SO_FIN | SO_ACK;
00550 txf = 1;
00551
00552 #ifdef RTLCONNECTHACK
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 NutDelay(5);
00563 #endif
00564 break;
00565 case TCPS_CLOSE_WAIT:
00566
00567
00568
00569 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00570 txf = 1;
00571 break;
00572 default:
00573 rc = -1;
00574 break;
00575 }
00576 break;
00577
00578 case TCPS_LISTEN:
00579
00580
00581
00582 if (state == TCPS_SYN_RECEIVED) {
00583 sock->so_tx_flags |= SO_SYN | SO_ACK;
00584 txf = 1;
00585 #ifdef RTLCONNECTHACK
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 NutDelay(5);
00596 #endif
00597 } else
00598 rc = -1;
00599 break;
00600
00601 case TCPS_SYN_SENT:
00602 switch (state) {
00603 case TCPS_LISTEN:
00604
00605
00606
00607 break;
00608 case TCPS_SYN_RECEIVED:
00609
00610
00611
00612 sock->so_tx_flags |= SO_SYN | SO_ACK;
00613 txf = 1;
00614 break;
00615 case TCPS_ESTABLISHED:
00616
00617
00618
00619 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00620 txf = 1;
00621 break;
00622 default:
00623 rc = -1;
00624 break;
00625 }
00626 break;
00627
00628 case TCPS_SYN_RECEIVED:
00629 switch (state) {
00630 case TCPS_LISTEN:
00631
00632
00633
00634 break;
00635 case TCPS_ESTABLISHED:
00636
00637
00638
00639 break;
00640 case TCPS_FIN_WAIT_1:
00641
00642
00643
00644 sock->so_tx_flags |= SO_FIN;
00645 txf = 1;
00646 break;
00647 case TCPS_CLOSE_WAIT:
00648
00649
00650
00651 sock->so_tx_flags |= SO_FIN | SO_ACK;
00652 txf = 1;
00653 break;
00654 default:
00655 rc = -1;
00656 break;
00657 }
00658 break;
00659
00660 case TCPS_FIN_WAIT_1:
00661 switch (state) {
00662 case TCPS_FIN_WAIT_1:
00663 case TCPS_FIN_WAIT_2:
00664
00665
00666
00667 break;
00668 case TCPS_CLOSING:
00669
00670
00671
00672 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00673 txf = 1;
00674 break;
00675 case TCPS_TIME_WAIT:
00676
00677
00678
00679 break;
00680 default:
00681 rc = -1;
00682 break;
00683 }
00684 break;
00685
00686 case TCPS_FIN_WAIT_2:
00687
00688
00689
00690 if (state != TCPS_TIME_WAIT)
00691 rc = -1;
00692 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00693 txf = 1;
00694 break;
00695
00696 case TCPS_CLOSE_WAIT:
00697
00698
00699
00700 if (state == TCPS_LAST_ACK) {
00701 sock->so_tx_flags |= SO_FIN | SO_ACK;
00702 txf = 1;
00703 } else
00704 rc = -1;
00705 break;
00706
00707 case TCPS_CLOSING:
00708
00709
00710
00711 if (state != TCPS_TIME_WAIT)
00712 rc = -1;
00713 break;
00714
00715 case TCPS_LAST_ACK:
00716 rc = -1;
00717 break;
00718
00719 case TCPS_TIME_WAIT:
00720 rc = -1;
00721 break;
00722
00723 case TCPS_CLOSED:
00724 switch (state) {
00725 case TCPS_LISTEN:
00726
00727
00728
00729 break;
00730 case TCPS_SYN_SENT:
00731
00732
00733
00734 sock->so_tx_flags |= SO_SYN;
00735 txf = 1;
00736 break;
00737 default:
00738 rc = -1;
00739 break;
00740 }
00741 break;
00742 }
00743 #ifdef NUTDEBUG
00744 if (__tcp_trf) {
00745 fprintf(__tcp_trs, " %04x-", (u_int) sock);
00746 if (rc)
00747 NutDumpSockState(__tcp_trs, sock->so_state, "**ERR ", "**>");
00748 NutDumpSockState(__tcp_trs, state, "[>", "]");
00749 }
00750 #endif
00751
00752 if (rc == 0) {
00753 sock->so_state = state;
00754 if (txf && NutTcpOutput(sock, 0, 0)) {
00755 if (state == TCPS_SYN_SENT) {
00756 rc = -1;
00757 sock->so_last_error = EHOSTDOWN;
00758 NutEventPostAsync(&sock->so_ac_tq);
00759 }
00760 }
00761 if (state == TCPS_CLOSE_WAIT) {
00762
00763
00764
00765 NutEventBroadcast(&sock->so_rx_tq);
00766 NutEventBroadcast(&sock->so_pc_tq);
00767 NutEventBroadcast(&sock->so_ac_tq);
00768 }
00769 }
00770 return rc;
00771 }
00772
00773
00774
00775
00776
00785 int NutTcpStatePassiveOpenEvent(TCPSOCKET * sock)
00786 {
00787 if (sock->so_state != TCPS_CLOSED)
00788 return (sock->so_last_error = EISCONN);
00789
00790 NutTcpStateChange(sock, TCPS_LISTEN);
00791
00792
00793
00794
00795 NutEventWait(&sock->so_pc_tq, 0);
00796
00797 return 0;
00798 }
00799
00810 int NutTcpStateActiveOpenEvent(TCPSOCKET * sock)
00811 {
00812
00813
00814
00815
00816 NutTcpStateChange(sock, TCPS_SYN_SENT);
00817
00818
00819
00820
00821 if(sock->so_state == TCPS_SYN_SENT)
00822 NutEventWait(&sock->so_ac_tq, 0);
00823
00824 if (sock->so_state != TCPS_ESTABLISHED)
00825 return -1;
00826
00827 return 0;
00828 }
00829
00842 int NutTcpStateCloseEvent(TCPSOCKET * sock)
00843 {
00844 if (sock == 0)
00845 return -1;
00846
00847 NutThreadYield();
00848
00849 switch (sock->so_state) {
00850 case TCPS_LISTEN:
00851 case TCPS_SYN_SENT:
00852 case TCPS_CLOSED:
00853
00854
00855
00856 NutTcpDestroySocket(sock);
00857 break;
00858
00859 case TCPS_SYN_RECEIVED:
00860 case TCPS_ESTABLISHED:
00861
00862
00863
00864
00865 NutTcpStateChange(sock, TCPS_FIN_WAIT_1);
00866 break;
00867
00868 case TCPS_CLOSE_WAIT:
00869
00870
00871
00872
00873 NutTcpStateChange(sock, TCPS_LAST_ACK);
00874 break;
00875
00876 case TCPS_FIN_WAIT_1:
00877 case TCPS_FIN_WAIT_2:
00878 case TCPS_CLOSING:
00879 case TCPS_LAST_ACK:
00880 case TCPS_TIME_WAIT:
00881 sock->so_last_error = EALREADY;
00882 return -1;
00883
00884 default:
00885 sock->so_last_error = ENOTCONN;
00886 return -1;
00887 }
00888 return 0;
00889 }
00890
00897 int NutTcpStateWindowEvent(TCPSOCKET * sock)
00898 {
00899 if (sock == 0)
00900 return -1;
00901 sock->so_tx_flags |= SO_ACK | SO_FORCE;
00902 NutTcpOutput(sock, 0, 0);
00903
00904 return 0;
00905 }
00906
00907
00908
00909
00910
00922 int NutTcpStateRetranTimeout(TCPSOCKET * sock)
00923 {
00924 NETBUF *so_tx_next;
00925 if (sock->so_retransmits++ > TCP_RETRIES_MAX)
00926 {
00927
00928 NutTcpAbortSocket(sock, ETIMEDOUT);
00929 return -1;
00930 } else {
00931 #ifdef NUTDEBUG
00932 if (__tcp_trf)
00933 NutDumpTcpHeader(__tcp_trs, "RET", sock, sock->so_tx_nbq);
00934 #endif
00935
00936
00937
00938
00939 so_tx_next = sock->so_tx_nbq->nb_next;
00940 if (NutIpOutput(IPPROTO_TCP, sock->so_remote_addr, sock->so_tx_nbq)) {
00941
00942 sock->so_tx_nbq = so_tx_next;
00943
00944 NutTcpAbortSocket(sock, ENETDOWN);
00945 return -1;
00946 } else {
00947
00948 sock->so_retran_time = (uint16_t) NutGetMillis() | 1;
00949 return 0;
00950 }
00951 }
00952 }
00953
00954
00955
00956
00957
00958
00968 static void NutTcpStateListen(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
00969 {
00970
00971
00972
00973
00974 if ((flags & (TH_SYN | TH_ACK | TH_RST)) == TH_SYN) {
00975 NutTcpProcessSyn(sock, nb->nb_nw.vp, th);
00976 NutTcpStateChange(sock, TCPS_SYN_RECEIVED);
00977 NutNetBufFree(nb);
00978 } else
00979 NutTcpReject(nb);
00980 }
00981
00982
00991 static void NutTcpStateSynSent(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
00992 {
00993
00994
00995
00996 if (flags & TH_ACK) {
00997 if (!IsInLimits(ntohl(th->th_ack), sock->so_tx_isn + 1, sock->so_tx_nxt)) {
00998 NutTcpReject(nb);
00999 return;
01000 }
01001 }
01002
01003
01004
01005
01006
01007
01008 if (flags & TH_RST) {
01009 if (flags & TH_ACK) {
01010
01011
01012
01013 NutTcpAbortSocket(sock, ECONNREFUSED);
01014 }
01015 NutNetBufFree(nb);
01016 return;
01017 }
01018
01019
01020
01021
01022
01023
01024 if (flags & TH_SYN) {
01025 NutTcpProcessSyn(sock, nb->nb_nw.vp, th);
01026 if (flags & TH_ACK) {
01027 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01028 NutTcpStateChange(sock, TCPS_ESTABLISHED);
01029
01030 NutEventPost(&sock->so_ac_tq);
01031 } else {
01032 NutTcpStateChange(sock, TCPS_SYN_RECEIVED);
01033 }
01034 }
01035 NutNetBufFree(nb);
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 static void NutTcpStateSynReceived(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01050 {
01051
01052
01053
01054
01055 if (flags & TH_RST) {
01056 if (sock->so_pc_tq)
01057 NutTcpStateChange(sock, TCPS_LISTEN);
01058 else
01059 NutTcpAbortSocket(sock, ECONNREFUSED);
01060 NutNetBufFree(nb);
01061 sock->so_retran_time = 0;
01062 NutTcpDiscardBuffers(sock);
01063 return;
01064 }
01065
01066
01067
01068
01069 if (flags & TH_SYN) {
01070 NutTcpReject(nb);
01071 return;
01072 }
01073
01074
01075
01076
01077 if ((flags & TH_ACK) == 0) {
01078 NutNetBufFree(nb);
01079 return;
01080 }
01081
01082
01083
01084
01085 if (!IsInLimits(ntohl(th->th_ack), sock->so_tx_una + 1, sock->so_tx_nxt)) {
01086 NutTcpReject(nb);
01087 return;
01088 }
01089
01090
01091 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01092
01093
01094
01095
01096
01097
01098
01099 if (nb->nb_ap.sz)
01100 NutTcpProcessAppData(sock, nb);
01101 else
01102 NutNetBufFree(nb);
01103
01104
01105
01106
01107 if (flags & TH_FIN) {
01108 sock->so_rx_nxt++;
01109 NutTcpStateChange(sock, TCPS_CLOSE_WAIT);
01110 } else {
01111 NutTcpStateChange(sock, TCPS_ESTABLISHED);
01112 NutEventPost(&sock->so_pc_tq);
01113 NutEventPost(&sock->so_ac_tq);
01114 }
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 static void NutTcpStateEstablished(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01132 {
01133 if (flags & TH_RST) {
01134 NutNetBufFree(nb);
01135 NutTcpAbortSocket(sock, ECONNRESET);
01136 return;
01137 }
01138
01139
01140
01141
01142
01143 if (flags & TH_SYN) {
01144 if (htonl(th->th_seq) != sock->so_rx_isn)
01145 NutTcpReject(nb);
01146 else
01147 NutNetBufFree(nb);
01148 return;
01149 }
01150
01151
01152
01153
01154 if ((flags & TH_ACK) == 0) {
01155 NutNetBufFree(nb);
01156 return;
01157 }
01158
01159 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01160
01161
01162
01163
01164
01165
01166
01167 if (htonl(th->th_seq) > sock->so_rx_nxt) {
01168 NETBUF *nbq;
01169 NETBUF **nbqp;
01170 TCPHDR *thq;
01171 uint32_t th_seq;
01172 uint32_t thq_seq;
01173
01174 if (nb->nb_ap.sz) {
01175 nbq = sock->so_rx_nbq;
01176 nbqp = &sock->so_rx_nbq;
01177 while (nbq) {
01178 thq = (TCPHDR *) (nbq->nb_tp.vp);
01179 th_seq = htonl(th->th_seq);
01180 thq_seq = htonl(thq->th_seq);
01181 if (th_seq < thq_seq) {
01182 *nbqp = nb;
01183 nb->nb_next = nbq;
01184 break;
01185 }
01186 if (th_seq == thq_seq) {
01187 NutNetBufFree(nb);
01188 sock->so_tx_flags |= SO_ACK | SO_FORCE;
01189 NutTcpOutput(sock, 0, 0);
01190 return;
01191 }
01192 nbqp = &nbq->nb_next;
01193 nbq = nbq->nb_next;
01194 }
01195 if (nbq == 0) {
01196 *nbqp = nb;
01197 nb->nb_next = 0;
01198 }
01199 } else
01200 NutNetBufFree(nb);
01201
01202 sock->so_tx_flags |= SO_ACK | SO_FORCE;
01203 NutTcpOutput(sock, 0, 0);
01204 return;
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214 if (htonl(th->th_seq) != sock->so_rx_nxt) {
01215 sock->so_tx_flags |= SO_ACK | SO_FORCE;
01216
01217 sock->so_oos_drop++;
01218 NutNetBufFree(nb);
01219 NutTcpOutput(sock, 0, 0);
01220 }
01221
01222
01223
01224
01225 else if (nb->nb_ap.sz) {
01226 NutTcpProcessAppData(sock, nb);
01227
01228
01229
01230 while ((nb = sock->so_rx_nbq) != 0) {
01231 th = (TCPHDR *) (nb->nb_tp.vp);
01232 if (htonl(th->th_seq) > sock->so_rx_nxt)
01233 break;
01234 sock->so_rx_nbq = nb->nb_next;
01235 if (htonl(th->th_seq) == sock->so_rx_nxt) {
01236 NutTcpProcessAppData(sock, nb);
01237 flags |= th->th_flags;
01238 } else
01239 NutNetBufFree(nb);
01240 }
01241
01242 NutEventPost(&sock->so_rx_tq);
01243 } else {
01244 NutNetBufFree(nb);
01245
01246
01247 }
01248 if (flags & TH_FIN) {
01249
01250 sock->so_rx_nxt++;
01251 NutTcpStateChange(sock, TCPS_CLOSE_WAIT);
01252 }
01253 }
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 static void NutTcpStateFinWait1(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01271 {
01272
01273 if (flags & TH_RST) {
01274 NutNetBufFree(nb);
01275 NutTcpDestroySocket(sock);
01276 return;
01277 }
01278
01279
01280
01281
01282 if (flags & TH_SYN) {
01283 NutTcpReject(nb);
01284 return;
01285 }
01286
01287
01288
01289
01290 if ((flags & TH_ACK) == 0) {
01291 NutNetBufFree(nb);
01292 return;
01293 }
01294
01295
01296
01297
01298
01299 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01300
01301
01302
01303
01304
01305 if (sock->so_tx_nxt == sock->so_tx_una) {
01306
01307 NutTcpStateChange(sock, TCPS_FIN_WAIT_2);
01308 }
01309
01310
01311
01312
01313
01314 if (nb->nb_ap.sz) {
01315 NutTcpProcessAppData(sock, nb);
01316
01317 NutEventPost(&sock->so_rx_tq);
01318 }
01319 else
01320 NutNetBufFree(nb);
01321
01322 if (flags & TH_FIN) {
01323 sock->so_rx_nxt++;
01324
01325
01326
01327 sock->so_time_wait = 0;
01328
01329 if (sock->so_state == TCPS_FIN_WAIT_2)
01330 NutTcpStateChange(sock, TCPS_TIME_WAIT);
01331 else
01332 NutTcpStateChange(sock, TCPS_CLOSING);
01333 }
01334 }
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349 static void NutTcpStateFinWait2(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01350 {
01351
01352 if (flags & TH_RST) {
01353 NutNetBufFree(nb);
01354 NutTcpDestroySocket(sock);
01355 return;
01356 }
01357
01358
01359
01360
01361 if (flags & TH_SYN) {
01362 NutTcpReject(nb);
01363 return;
01364 }
01365
01366
01367
01368
01369 if ((flags & TH_ACK) == 0) {
01370 NutNetBufFree(nb);
01371 return;
01372 }
01373
01374
01375
01376
01377
01378
01379 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01380
01381
01382
01383 if (nb->nb_ap.sz) {
01384 NutTcpProcessAppData(sock, nb);
01385
01386 NutEventPost(&sock->so_rx_tq);
01387 }
01388 else
01389 NutNetBufFree(nb);
01390
01391 if (flags & TH_FIN) {
01392 sock->so_rx_nxt++;
01393 sock->so_time_wait = 0;
01394
01395 NutTcpStateChange(sock, TCPS_TIME_WAIT);
01396 }
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 static void NutTcpStateCloseWait(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01410 {
01411
01412 if (flags & TH_RST) {
01413 NutNetBufFree(nb);
01414 NutTcpAbortSocket(sock, ECONNRESET);
01415 return;
01416 }
01417
01418
01419
01420
01421 if (flags & TH_SYN) {
01422 NutTcpReject(nb);
01423 return;
01424 }
01425
01426
01427
01428
01429 if ((flags & TH_ACK) == 0) {
01430 NutNetBufFree(nb);
01431 return;
01432 }
01433
01434 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01435
01436 NutNetBufFree(nb);
01437 }
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451 static void NutTcpStateClosing(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01452 {
01453
01454 if (flags & TH_RST) {
01455 NutNetBufFree(nb);
01456 NutTcpDestroySocket(sock);
01457 return;
01458 }
01459
01460
01461
01462
01463 if (flags & TH_SYN) {
01464 NutTcpReject(nb);
01465 return;
01466 }
01467
01468
01469
01470
01471 if ((flags & TH_ACK) == 0) {
01472 NutNetBufFree(nb);
01473 return;
01474 }
01475
01476 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01477
01478
01479
01480
01481 if (sock->so_tx_nxt == sock->so_tx_una) {
01482 sock->so_time_wait = 0;
01483 NutTcpStateChange(sock, TCPS_TIME_WAIT);
01484
01485 }
01486
01487
01488 NutNetBufFree(nb);
01489 }
01490
01505 static void NutTcpStateLastAck(TCPSOCKET * sock, uint8_t flags, TCPHDR * th, NETBUF * nb)
01506 {
01507
01508 if (flags & TH_RST) {
01509 NutNetBufFree(nb);
01510 NutTcpDestroySocket(sock);
01511 return;
01512 }
01513
01514
01515
01516
01517 if (flags & TH_SYN) {
01518 NutTcpReject(nb);
01519 return;
01520 }
01521
01522
01523
01524
01525 if ((flags & TH_ACK) == 0) {
01526 NutNetBufFree(nb);
01527 return;
01528 }
01529
01530 NutTcpProcessAck(sock, th, nb->nb_ap.sz);
01531 NutNetBufFree(nb);
01532
01533 if (sock->so_tx_nxt == sock->so_tx_una)
01534 NutTcpDestroySocket(sock);
01535
01536 }
01537
01548 static void NutTcpStateProcess(TCPSOCKET * sock, NETBUF * nb)
01549 {
01550 uint32_t tx_win;
01551 uint32_t tx_una;
01552 TCPHDR *th = (TCPHDR *) nb->nb_tp.vp;
01553 uint8_t flags = th->th_flags;
01554
01555 #ifdef NUTDEBUG
01556 if (__tcp_trf) {
01557 fprintf(__tcp_trs, " %04x-", (u_int) sock);
01558 NutDumpSockState(__tcp_trs, sock->so_state, "[", ">]");
01559 }
01560 #endif
01561 switch (sock->so_state) {
01562
01563 case TCPS_ESTABLISHED:
01564 tx_win = sock->so_tx_win;
01565 tx_una = sock->so_tx_una;
01566 NutTcpStateEstablished(sock, flags, th, nb);
01567
01568 if(sock->so_state != TCPS_ESTABLISHED ||
01569 sock->so_tx_win > tx_win ||
01570 sock->so_tx_una > tx_una) {
01571 NutEventBroadcast(&sock->so_tx_tq);
01572 }
01573 break;
01574 case TCPS_LISTEN:
01575 NutTcpStateListen(sock, flags, th, nb);
01576 break;
01577 case TCPS_SYN_SENT:
01578 NutTcpStateSynSent(sock, flags, th, nb);
01579 break;
01580 case TCPS_SYN_RECEIVED:
01581 NutTcpStateSynReceived(sock, flags, th, nb);
01582 break;
01583 case TCPS_FIN_WAIT_1:
01584 NutTcpStateFinWait1(sock, flags, th, nb);
01585 break;
01586 case TCPS_FIN_WAIT_2:
01587 NutTcpStateFinWait2(sock, flags, th, nb);
01588 break;
01589 case TCPS_CLOSE_WAIT:
01590 NutTcpStateCloseWait(sock, flags, th, nb);
01591 break;
01592 case TCPS_CLOSING:
01593 NutTcpStateClosing(sock, flags, th, nb);
01594 break;
01595 case TCPS_LAST_ACK:
01596 NutTcpStateLastAck(sock, flags, th, nb);
01597 break;
01598 case TCPS_TIME_WAIT:
01599
01600
01601
01602 NutNetBufFree(nb);
01603 break;
01604 case TCPS_CLOSED:
01605
01606
01607
01608 NutTcpReject(nb);
01609 break;
01610 default:
01611 NutNetBufFree(nb);
01612 break;
01613 }
01614 }
01615
01622 THREAD(NutTcpSm, arg)
01623 {
01624 NETBUF *nb;
01625 NETBUF *nbx;
01626 TCPHDR *th;
01627 IPHDR *ih;
01628 TCPSOCKET *sock;
01629 uint8_t tac = 0;
01630
01631
01632
01633
01634
01635 NutThreadSetPriority (32);
01636
01637 for (;;) {
01638 if (++tac > 3 || NutEventWait(&tcp_in_rdy, 200)) {
01639 tac = 0;
01640 for (sock = tcpSocketList; sock; sock = sock->so_next) {
01641
01642
01643
01644
01645 if (sock->so_tx_flags & SO_ACK) {
01646 sock->so_tx_flags |= SO_FORCE;
01647 NutTcpOutput(sock, 0, 0);
01648 }
01649
01650
01651
01652
01653 if (sock->so_tx_nbq && sock->so_retran_time) {
01654 if ((uint16_t)((uint16_t)NutGetMillis() - sock->so_retran_time) > sock->so_rtto) {
01655 NutTcpStateRetranTimeout(sock);
01656 }
01657 }
01658
01659
01660
01661
01662 if (sock->so_state == TCPS_TIME_WAIT || sock->so_state == TCPS_FIN_WAIT_2) {
01663 if (sock->so_time_wait++ >= 9) {
01664 NutTcpDestroySocket(sock);
01665 break;
01666 }
01667 }
01668
01669
01670
01671
01672 else if (sock->so_state == TCPS_SYN_RECEIVED) {
01673 if (sock->so_time_wait++ >= 45) {
01674 sock->so_state = TCPS_LISTEN;
01675 sock->so_time_wait = 0;
01676 }
01677 }
01678 }
01679 } else {
01680 nb = tcp_in_nbq;
01681 tcp_in_nbq = 0;
01682 tcp_in_cnt = 0;
01683 while (nb) {
01684 ih = (IPHDR *) nb->nb_nw.vp;
01685 th = (TCPHDR *) nb->nb_tp.vp;
01686 sock = NutTcpFindSocket(th->th_dport, th->th_sport, ih->ip_src);
01687 #ifdef NUTDEBUG
01688 if (__tcp_trf)
01689 NutDumpTcpHeader(__tcp_trs, " IN", sock, nb);
01690 #endif
01691 nbx = nb->nb_next;
01692 if (sock) {
01693 NutTcpInputOptions(sock, nb);
01694 NutTcpStateProcess(sock, nb);
01695 }
01696
01697
01698
01699
01700 else
01701 NutTcpReject(nb);
01702 nb = nbx;
01703 }
01704 }
01705 }
01706 }
01707
01719 void NutTcpStateMachine(NETBUF * nb)
01720 {
01721 NETBUF *nbp;
01722 uint16_t size;
01723
01724 nb->nb_next = 0;
01725
01726
01727
01728
01729
01730
01731
01732 if (tcpThread == 0) {
01733 NutTcpReject(nb);
01734 return;
01735 }
01736
01737 if ((nbp = tcp_in_nbq) == 0) {
01738 tcp_in_nbq = nb;
01739 NutEventPost(&tcp_in_rdy);
01740 } else {
01741 size = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
01742 if (tcp_in_cnt + size + 2048 < NutHeapAvailable()) {
01743 tcp_in_cnt += size;
01744 while (nbp->nb_next)
01745 nbp = nbp->nb_next;
01746 nbp->nb_next = nb;
01747 NutEventPost(&tcp_in_rdy);
01748 } else
01749 NutNetBufFree(nb);
01750 }
01751 }
01752
01761 int NutTcpInitStateMachine(void)
01762 {
01763 if (tcpThread == 0 && (tcpThread = NutThreadCreate("tcpsm", NutTcpSm, NULL, NUT_THREAD_TCPSMSTACK)) == 0)
01764 return -1;
01765 return 0;
01766 }
01767
01781 int NutTcpAbortSocket(TCPSOCKET * sock, uint16_t last_error)
01782 {
01783 sock->so_last_error = last_error;
01784 sock->so_retran_time = 0;
01785 sock->so_time_wait = 0;
01786
01787
01788
01789
01790
01791 if (sock->so_state >= TCPS_FIN_WAIT_1)
01792 sock->so_state = TCPS_TIME_WAIT;
01793 else
01794 sock->so_state = TCPS_CLOSED;
01795 NutTcpDiscardBuffers(sock);
01796 NutEventBroadcast(&sock->so_rx_tq);
01797 NutEventBroadcast(&sock->so_tx_tq);
01798 NutEventBroadcast(&sock->so_pc_tq);
01799 NutEventBroadcast(&sock->so_ac_tq);
01800 return 0;
01801 }
01802