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