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 #include "nip_init.h"
00032 #include "dispatcher.h"
00033 #include "inet.h"
00034 #include "os_core.h"
00035 #include "nip_error.h"
00036 #include "net/net_if.h"
00037 #include "net/tcp.h"
00038 #include "net/numbers.h"
00039
00040 #if NIP_TCP_ENABLE == 1
00041
00042
00043 #if NIP_TCP_MAX_SOCKETS == 1
00044 #define sockid 0
00045 struct nip_tcp_sock nip_tcp_sock = 0;
00046 #define NIP_TCP_SOCKATTR(sockid, attr) nip_tcp_sock.attr
00047 #else
00048 struct nip_tcp_sock nip_tcp_sockets[ NIP_TCP_MAX_SOCKETS ];
00049 #define NIP_TCP_SOCKATTR(sockid, attr) nip_tcp_sockets[sockid].attr
00050 #endif
00051
00052 nip_tcp_sock_cnt_t nip_tcp_unaccepted_cnt;
00053 nip_tcp_sock_id_t nip_tcp_unaccepted[ NIP_TCP_MAX_UNACCEPTED ];
00054 nip_tcp_sock_cnt_t nip_tcp_conn_cnt;
00055 nip_mem_handle_t nip_tcp_conns = NIP_MEM_NULL;
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 nip_tcp_sock_id_t nip_tcp_socket( struct nip_tcp_sock_addr *addr, uint8_t flags )
00071 {
00072 #if NIP_TCP_MAX_SOCKETS > 1
00073
00074
00075 nip_tcp_sock_id_t sockid = 0;
00076 do
00077 {
00078 #endif
00079
00080 if ( (NIP_TCP_SOCKATTR(sockid,flags) & NIP_TCP_SOCK_FLG_USED) == 0 )
00081 {
00082
00083 NIP_TCP_SOCKATTR(sockid,flags) = flags | NIP_TCP_SOCK_FLG_USED;
00084 nip_memcpy( &NIP_TCP_SOCKATTR(sockid,addr), addr, 4 );
00085 return sockid;
00086 }
00087 #if NIP_TCP_MAX_SOCKETS > 1
00088 } while ( ++sockid < NIP_TCP_MAX_SOCKETS );
00089 #endif
00090
00091
00092 nip_error = NIP_E_OUT_OF_RESSOURCES;
00093 return NIP_TCP_NO_SOCKET;
00094 }
00095
00096
00097
00098
00099 void nip_tcp_del_conn( nip_tcp_sock_id_t connid )
00100 {
00101 struct nip_tcb *tcb;
00102 nip_tcp_sock_cnt_t cnt = 0;
00103 nip_tcp_sock_id_t sockid = NIP_TCP_NO_SOCKET;
00104 uint8_t moveup;
00105 uint8_t children;
00106
00107 if ( connid < NIP_TCP_MAX_SOCKETS )
00108 sockid = connid;
00109
00110 do
00111 {
00112 moveup = 0;
00113 children = 0;
00114 if ( nip_tcp_conn_cnt > 0 )
00115 {
00116
00117 tcb = nip_mem_obtain_ptr( nip_tcp_conns );
00118 if ( tcb != NULL )
00119 {
00120 do
00121 {
00122 if ( tcb->connid == connid )
00123 {
00124
00125 nip_mem_free( tcb->snd_buf );
00126 nip_mem_free( tcb->rcv_buf );
00127
00128 moveup++;
00129 sockid = tcb->sockid;
00130 }
00131 else
00132 {
00133 if ( tcb->sockid == sockid )
00134 children++;
00135
00136 nip_memcpy( tcb - moveup, tcb, sizeof( struct nip_tcb ) );
00137 }
00138 tcb++;
00139 } while ( ++cnt < nip_tcp_conn_cnt );
00140
00141
00142 nip_tcp_conn_cnt -= moveup;
00143
00144
00145 nip_mem_release_block( nip_tcp_conns );
00146 nip_mem_set_used( nip_tcp_conns, nip_tcp_conn_cnt * sizeof( struct nip_tcb ) );
00147 }
00148 }
00149 }
00150
00151 while ( moveup > 0 );
00152
00153
00154
00155 if ( sockid != NIP_TCP_NO_SOCKET
00156 && NIP_TCP_SOCKATTR(sockid,flags) & NIP_TCP_SOCK_FLG_AUTOCLOSE )
00157 {
00158
00159
00160 if ( children > 0 )
00161 {
00162 NIP_TCP_SOCKATTR(sockid,flags) &= ~NIP_TCP_SOCK_FLG_LISTENING;
00163 }
00164 else
00165 NIP_TCP_SOCKATTR(sockid,flags) = 0;
00166 }
00167
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 struct nip_tcb *
00182 nip_tcp_find_conn( nip_tcp_sock_id_t sockid, uint8_t *rem_ip, uint16_t rem_port)
00183 {
00184 struct nip_tcb *tcb;
00185 nip_tcp_sock_cnt_t cnt = 0;
00186 if ( nip_tcp_conn_cnt > 0 )
00187 {
00188
00189 tcb = nip_mem_obtain_ptr( nip_tcp_conns );
00190 if ( tcb != NULL )
00191 {
00192 do
00193 {
00194
00195 if(( tcb->sockid == sockid
00196 && rem_ip != NULL
00197 && tcb->rem_addr.port == rem_port
00198 && nip_memcmp( tcb->rem_addr.ip, rem_ip, 4 ) == 0
00199 && tcb->status != NIP_TCP_STAT_CLOSED )
00200 || ( tcb->connid == sockid
00201 && rem_ip == NULL )
00202 )
00203 {
00204 return tcb;
00205 }
00206 tcb++;
00207 } while ( ++cnt < nip_tcp_conn_cnt );
00208
00209
00210 nip_mem_release_block( nip_tcp_conns );
00211 nip_error = NIP_E_INVALID_SOCK;
00212 }
00213 else
00214 {
00215 nip_error = NIP_E_AGAIN;
00216 }
00217 }
00218
00219 return NULL;
00220 }
00221
00222
00223
00224
00225
00226
00227 struct nip_tcb *
00228 nip_tcp_create_conn( nip_tcp_sock_id_t sockid, uint8_t *rem_ip, uint16_t rem_port,
00229 nip_tcp_stat_t init_status )
00230 {
00231 struct nip_tcb *tcb = NULL;
00232 nip_tcp_sock_cnt_t cnt;
00233 nip_tcp_sock_id_t connid;
00234 if ( nip_tcp_conns == NIP_MEM_NULL )
00235 {
00236 nip_tcp_conn_cnt = 0;
00237 nip_tcp_conns = nip_mem_alloc( sizeof( struct nip_tcb ), 0, 0, NULL );
00238 }
00239
00240
00241 if ( nip_mem_write( nip_tcp_conns, NULL, sizeof( struct nip_tcb ) )
00242 == NIP_E_OK )
00243 {
00244
00245 tcb = nip_mem_obtain_ptr( nip_tcp_conns );
00246 if ( tcb != NULL )
00247 {
00248
00249
00250
00251 if ( init_status == NIP_TCP_STAT_LISTEN )
00252 connid = NIP_TCP_MAX_SOCKETS;
00253 else
00254 connid = sockid;
00255
00256
00257 unique_check:
00258 cnt = 0;
00259 while ( cnt < nip_tcp_conn_cnt )
00260 {
00261
00262 if ( tcb->connid == connid )
00263 {
00264
00265 connid++;
00266 tcb -= cnt;
00267 goto unique_check;
00268 }
00269 tcb++;
00270 cnt++;
00271 };
00272
00273 nip_memset( tcb, 0, sizeof( struct nip_tcb ) );
00274
00275 tcb->snd_buf = nip_mem_alloc( 0, 0, 0, NULL );
00276 tcb->rcv_buf = nip_mem_alloc( 0, 0, 0, NULL );
00277
00278
00279 if ( tcb->snd_buf != NIP_MEM_NULL && tcb->rcv_buf != NIP_MEM_NULL )
00280 {
00281
00282 nip_tcp_conn_cnt++ ;
00283
00284
00285 tcb->sockid = sockid;
00286 tcb->connid = connid;
00287 tcb->status = init_status;
00288 nip_memcpy( tcb->rem_addr.ip, rem_ip, 4 );
00289 tcb->rem_addr.port = rem_port;
00290
00291
00292
00293
00294 tcb->iss = nip_tickcount();
00295 tcb->rcv_wnd = NIP_TCP_DEFAULT_RCV_WND;
00296
00297 tcb->snd_nxt = tcb->iss + 1;
00298 tcb->snd_una = tcb->iss;
00299
00300 return tcb;
00301 }
00302
00303
00304 nip_mem_free( tcb->snd_buf );
00305 nip_mem_free( tcb->rcv_buf );
00306 nip_mem_release_block( nip_tcp_conns );
00307
00308 }
00309
00310
00311
00312
00313 nip_mem_set_used( nip_tcp_conns, nip_tcp_conn_cnt * sizeof( struct nip_tcb ) );
00314 }
00315
00316
00317 return NULL;
00318 }
00319
00320
00321
00322 void nip_tcp_close( nip_tcp_sock_id_t connid )
00323 {
00324 struct nip_tcb *tcb;
00325
00326
00327
00328
00329
00330 tcb = nip_tcp_find_conn( connid, NULL, 0 );
00331
00332
00333
00334
00335 if (tcb == NULL && nip_error == NIP_E_INVALID_SOCK)
00336 {
00337
00338
00339
00340 nip_tcp_del_conn( connid );
00341 }
00342 else if ( tcb != NULL )
00343 {
00344
00345
00346 if ( tcb->status == NIP_TCP_STAT_SYN_SENT
00347 || tcb->status == NIP_TCP_STAT_LISTEN )
00348 {
00349 tcb->status = NIP_TCP_STAT_CLOSED;
00350 }
00351
00352 if ( tcb->status == NIP_TCP_STAT_SYN_RECEIVED
00353 || tcb->status == NIP_TCP_STAT_ESTABLISHED )
00354 {
00355 tcb->status = NIP_TCP_STAT_FIN_WAIT1;
00356 }
00357 else
00358 if ( tcb->status == NIP_TCP_STAT_CLOSE_WAIT )
00359 {
00360 tcb->status = NIP_TCP_STAT_LAST_ACK;
00361 }
00362 else
00363 goto release;
00364
00365
00366 if ( nip_mem_buf_used( tcb->snd_buf ) == 0 )
00367 {
00368 tcb->snd_nxt ++;
00369 tcb->flags &= ~NIP_TCP_SOCK_FLG_SEND;
00370 }
00371 }
00372
00373 if ( tcb != NULL )
00374 {
00375 release:
00376 tcb->flags |= NIP_TCP_SHUT_WR;
00377 nip_mem_release_block( nip_tcp_conns );
00378
00379
00380 nip_disp_notify( NIP_DISP_CHECK_TCP );
00381
00382
00383 nip_dispatcher();
00384 }
00385
00386
00387 }
00388
00389
00390
00391
00392 nip_tcp_sock_id_t nip_tcp_accept( nip_tcp_sock_id_t sockid )
00393 {
00394 nip_tcp_sock_cnt_t i;
00395 nip_tcp_sock_id_t res = NIP_TCP_NO_SOCKET;
00396 struct nip_tcb *tcb;
00397
00398
00399
00400
00401 for ( i = 0; i < nip_tcp_unaccepted_cnt; i++ )
00402 {
00403 tcb = nip_tcp_find_conn( nip_tcp_unaccepted[i], NULL, 0 );
00404 if ( tcb == NULL || (tcb->flags&NIP_TCP_SOCK_FLG_ACCEPTED) )
00405 {
00406
00407 }
00408 else if ( tcb->sockid == sockid )
00409 {
00410
00411 res = tcb->connid;
00412 tcb->flags |= NIP_TCP_SOCK_FLG_ACCEPTED;
00413 }
00414 else
00415 goto next;
00416
00417
00418 nip_tcp_unaccepted_cnt--;
00419 nip_memmove( &nip_tcp_unaccepted[i],&nip_tcp_unaccepted[i+1],nip_tcp_unaccepted_cnt-i);
00420
00421 next:
00422 if ( tcb != NULL )
00423 nip_mem_release_block( nip_tcp_conns );
00424
00425 if ( res != NIP_TCP_NO_SOCKET )
00426 break;
00427 }
00428
00429
00430
00431 return res;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441 nip_mem_size_t nip_tcp_write( nip_tcp_sock_id_t connid, uint8_t *buf, nip_mem_size_t size )
00442 {
00443 struct nip_tcb *tcb;
00444 nip_mem_handle_t snd_buf;
00445
00446
00447
00448
00449
00450
00451 tcb = nip_tcp_find_conn( connid, NULL, 0 );
00452 if ( tcb == NULL )
00453 {
00454
00455 size = 0;
00456 }
00457
00458 else
00459 {
00460
00461 if ( tcb->status == NIP_TCP_STAT_FIN_WAIT1
00462 || tcb->status == NIP_TCP_STAT_FIN_WAIT2
00463 || tcb->status == NIP_TCP_STAT_CLOSING
00464 || tcb->status == NIP_TCP_STAT_TIMEWAIT
00465 || tcb->status == NIP_TCP_STAT_LAST_ACK
00466 )
00467 {
00468 nip_error = NIP_E_EOF;
00469 size = 0;
00470 }
00471 snd_buf = tcb->snd_buf;
00472 nip_mem_release_block( nip_tcp_conns );
00473
00474 if ( size > 0 && NIP_E_OK != nip_mem_write( snd_buf, buf, size ) )
00475 {
00476 nip_error = NIP_E_AGAIN;
00477 size = 0;
00478 }
00479 }
00480
00481
00482
00483 if ( size > 0 )
00484 {
00485
00486 nip_disp_notify( NIP_DISP_CHECK_TCP );
00487 nip_dispatcher();
00488 }
00489
00490 return size;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500 nip_mem_size_t nip_tcp_read( nip_tcp_sock_id_t connid, uint8_t *buf, nip_mem_size_t size )
00501 {
00502 struct nip_tcb *tcb;
00503
00504
00505
00506
00507
00508 tcb = nip_tcp_find_conn( connid, NULL, 0 );
00509 if ( tcb == NULL )
00510 {
00511
00512 size = 0;
00513 }
00514 else
00515 {
00516
00517 size = nip_mem_read( tcb->rcv_buf, buf, size );
00518
00519
00520 if ( size == 0 && nip_error == NIP_E_EOF )
00521 {
00522
00523 if ( tcb->status < NIP_TCP_STAT_ESTABLISHED || (tcb->flags & NIP_TCP_SOCK_FLG_RECV) )
00524 {
00525 nip_error = NIP_E_AGAIN;
00526 }
00527
00528
00529 else
00530 {
00531
00532 tcb->flags |= NIP_TCP_SHUT_RD;
00533 }
00534 }
00535 nip_mem_release_block( nip_tcp_conns );
00536 }
00537
00538
00539
00540 return size;
00541 }
00542
00543
00544
00545
00546
00547 uint16_t nip_tcp_checksum( nip_net_if_trans_t *trans )
00548 {
00549 uint16_t sum = 0;
00550
00551 uint16_t tcplen = trans->header_size + trans->payload_size;
00552 uint16_t word;
00553 uint16_t *word_ptr;
00554 struct nip_tcp_header *head = nip_mem_obtain_ptr( trans->header );
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 uint8_t checkpos = 0;
00566
00567 do
00568 {
00569 if ( checkpos == 0 )
00570 word_ptr = (uint16_t*)trans->params.ip.src_nw_addr;
00571 else if ( checkpos == 2 )
00572 word_ptr = (uint16_t*)trans->params.ip.dst_nw_addr;
00573
00574
00575 else if ( checkpos == 6 + trans->header_size )
00576 word_ptr = nip_mem_obtain_ptr( trans->payload );
00577 else if ( checkpos == 6 )
00578 word_ptr = (uint16_t*)head;
00579
00580 if ( word_ptr == NULL )
00581 break;
00582
00583 if ( checkpos == 4 )
00584 word = NIP_IP_PROTO_TCP;
00585 else if ( checkpos == 5 )
00586 word = tcplen;
00587 else if ( checkpos == 6 + tcplen -1 )
00588
00589 word = ((uint8_t*)word_ptr)[0] << 8;
00590 else
00591 word = ntohs(*word_ptr);
00592 sum += word;
00593 if ( sum < word )
00594 sum++;
00595
00596 word_ptr++;
00597 if ( checkpos >= 6 )
00598 checkpos++;
00599 checkpos++;
00600
00601 } while ( checkpos < tcplen + 6 );
00602
00603 sum = htons(~sum);
00604
00605 if ( head != NULL )
00606 head->checksum = sum;
00607
00608 nip_mem_release_block( trans->payload );
00609 nip_mem_release_block( trans->header );
00610
00611 return sum;
00612 }
00613
00614
00615
00616
00617
00618
00619
00620 void nip_tcp_disp_send( void )
00621 {
00622 struct nip_tcb *tcb;
00623 nip_net_if_trans_t *trans;
00624 struct nip_tcp_header *head;
00625 uint8_t rto;
00626 uint8_t optlen = 0;
00627 uint16_t new_data_size = 0;
00628 uint32_t seq;
00629 nip_mem_size_t snd_buf_size;
00630
00631
00632 tcb = nip_tcp_find_conn( nip_disp.next.tcp.sockid, NULL, 0 );
00633
00634 if ( tcb == NULL )
00635 goto quit;
00636
00637 snd_buf_size = nip_mem_buf_used( tcb->snd_buf );
00638
00639
00640 trans = nip_ip_route( tcb->rem_addr.ip, NIP_NET_NO_IF, NULL );
00641 if ( trans == NULL )
00642 {
00643
00644
00645 goto release_connection;
00646 }
00647
00648
00649
00650
00651 trans->flags.reset_status = 1;
00652
00653
00654 trans->header = nip_mem_alloc(
00655 NIP_TCP_MIN_HEADER_SIZE,
00656 NIP_TCP_MIN_HEADER_SIZE,
00657 0,
00658 NULL
00659 );
00660
00661 if ( trans->header == NIP_MEM_NULL
00662 || nip_mem_write( trans->header, NULL, NIP_TCP_MIN_HEADER_SIZE ) != NIP_E_OK )
00663 goto reset_transmission;
00664
00665 head = nip_mem_obtain_ptr( trans->header );
00666 if ( head == NULL )
00667 goto reset_transmission;
00668
00669 trans->header_size = NIP_TCP_MIN_HEADER_SIZE + optlen;
00670 trans->flags.free_payload = 0;
00671
00672
00673 head->flags = nip_disp.next.tcp.flags;
00674
00675 if ( tcb->status != NIP_TCP_STAT_SYN_SENT )
00676 {
00677 head->flags |= NIP_TCP_ACK_FLAG;
00678 }
00679
00680
00681 if ( tcb->status == NIP_TCP_STAT_SYN_RECEIVED
00682 || tcb->status == NIP_TCP_STAT_SYN_SENT
00683 )
00684 {
00685 head->flags |= NIP_TCP_SYN_FLAG;
00686 }
00687 else
00688
00689 if ( snd_buf_size == 0
00690 && ( tcb->status == NIP_TCP_STAT_FIN_WAIT1
00691 || tcb->status == NIP_TCP_STAT_LAST_ACK
00692 || tcb->status == NIP_TCP_STAT_CLOSING
00693 || tcb->status == NIP_TCP_STAT_LAST_ACK )
00694 )
00695 {
00696 head->flags |= NIP_TCP_FIN_FLAG;
00697 }
00698 else
00699 {
00700
00701
00702
00703 new_data_size = snd_buf_size - tcb->snd_nxt + tcb->snd_una;
00704 }
00705
00706
00707
00708 seq = tcb->snd_nxt;
00709
00710
00711 if ( (tcb->flags & NIP_TCP_SOCK_FLG_SEND) == 0 )
00712 {
00713 trans->payload_size = 0;
00714 trans->payload = NIP_MEM_NULL;
00715 }
00716 else
00717 {
00718 if ( head->flags & NIP_TCP_PSH_FLAG )
00719 tcb->push_ptr = tcb->snd_nxt;
00720
00721 trans->payload = tcb->snd_buf;
00722
00723
00724
00725 trans->payload_off = snd_buf_size - new_data_size;
00726 trans->payload_size = new_data_size;
00727
00728
00729 if ( tcb->rto <= nip_tickcount() )
00730 {
00731 trans->payload_off = 0;
00732 trans->payload_size = snd_buf_size;
00733 seq = tcb->snd_una;
00734 if ( tcb->snd_una < tcb->push_ptr )
00735 head->flags = nip_disp.next.tcp.flags | NIP_TCP_PSH_FLAG;
00736 tcb->rt_count++;
00737
00738 if ( tcb->push_ptr > seq )
00739 head->flags |= NIP_TCP_PSH_FLAG;
00740 }
00741 }
00742
00743
00744 if ( seq == tcb->snd_una )
00745 {
00746 rto = tcb->srtt * NIP_TCP_RTO_BETA;
00747 if ( rto < NIP_TCP_RTO_LBOUND ) rto = NIP_TCP_RTO_LBOUND;
00748 if ( rto > NIP_TCP_RTO_UBOUND ) rto = NIP_TCP_RTO_UBOUND;
00749 tcb->rto = nip_tickcount() + rto;
00750 tcb->rt_una = seq + trans->payload_size;
00751 tcb->rt_count = 0;
00752 }
00753
00754
00755
00756
00757
00758
00759 if ( head->flags & ( NIP_TCP_FIN_FLAG | NIP_TCP_SYN_FLAG ) )
00760 seq = tcb->snd_nxt-1;
00761
00762 head->seq = htonl( seq );
00763 head->srcport = NIP_TCP_SOCKATTR(tcb->sockid,addr.port);
00764 head->dstport = tcb->rem_addr.port;
00765 head->ack = htonl( tcb->rcv_nxt );
00766 head->dataoffset = (trans->header_size / 4 ) << 4;
00767
00768 head->window = htons( tcb->rcv_wnd );
00769
00770
00771
00772 head->checksum = 0;
00773 nip_mem_release_block( trans->header );
00774
00775 nip_tcp_checksum( trans );
00776
00777
00778 tcb->snd_nxt += new_data_size;
00779
00780
00781 trans->params.ip.protocol = NIP_IP_PROTO_TCP;
00782 trans->status = NIP_NET_IF_RESOLV_ADDR;
00783 nip_disp.next.common.trans = trans;
00784 NIP_CURR_CMD = & nip_ip_disp_send;
00785
00786 goto release_connection;
00787
00788 reset_transmission:
00789 trans->payload = NIP_MEM_NULL;
00790 nip_mem_release_block( trans->header );
00791 nip_reset_trans( trans );
00792
00793 release_connection:
00794 nip_mem_release_block( nip_tcp_conns );
00795
00796 quit:
00797 return;
00798 }
00799
00800
00801
00802
00803
00804 void nip_tcp_disp_receive( void )
00805 {
00806 nip_net_if_trans_t *trans = nip_disp.next.common.trans;
00807
00808 uint8_t flags;
00809 uint16_t wnd;
00810 uint32_t seq;
00811 uint32_t ack;
00812 uint32_t nxt;
00813 uint32_t eownd;
00814 nip_mem_size_t seglen;
00815 nip_mem_size_t hlen;
00816 nip_mem_size_t payoff;
00817 nip_mem_size_t rcvbuf_size;
00818 nip_mem_handle_t rcvbuf;
00819 struct nip_tcp_header *head;
00820 struct nip_tcb *tcb = NULL;
00821 uint8_t tmp;
00822 nip_mem_handle_t hbuf;
00823 #if NIP_TCP_MAX_SOCKETS > 1
00824 nip_tcp_sock_id_t sockid;
00825 #endif
00826
00827
00828 if ( trans->payload_size < NIP_TCP_MIN_HEADER_SIZE )
00829 goto discard;
00830
00831 if ( trans->header != NIP_MEM_NULL )
00832 hbuf = trans->header;
00833 else
00834 hbuf = trans->payload;
00835 head = nip_mem_obtain_ptr( hbuf );
00836
00837 if ( head == NULL )
00838 goto discard;
00839
00840
00841 hlen = (head->dataoffset>>4) * 4;
00842 seglen = trans->payload_size;
00843 if ( hbuf == trans->payload )
00844 {
00845 if ( hlen > trans->payload_size )
00846 {
00847 nip_mem_release_block( hbuf );
00848 goto discard;
00849 }
00850 seglen -= hlen;
00851 }
00852
00853
00854
00855 trans->params.tcp.src_port = head->srcport;
00856 trans->params.tcp.dst_port = head->dstport;
00857 flags = head->flags;
00858 wnd = ntohs( head->window );
00859 seq = ntohl( head->seq );
00860 ack = ntohl( head->ack );
00861 nxt = seq + seglen;
00862
00863
00864
00865
00866 nip_mem_release_block( hbuf );
00867 payoff = 0;
00868 if ( hbuf != trans->payload || trans->flags.free_payload == 1 )
00869 {
00870 nip_mem_read( hbuf, NULL, hlen );
00871 }
00872 else if ( hbuf == trans->payload )
00873 {
00874 payoff = hlen;
00875 }
00876 trans->payload_size = payoff + seglen;
00877
00878
00879
00880 #if NIP_TCP_MAX_SOCKETS > 1
00881 sockid = 0;
00882 do
00883 {
00884 #endif
00885 if ( NIP_TCP_SOCKATTR(sockid,addr).port == trans->params.tcp.dst_port
00886 && ( nip_memcmp( NIP_TCP_SOCKATTR(sockid,addr).ip, trans->params.ip.dst_nw_addr, 4 ) == 0
00887 || nip_memcmp( NIP_TCP_SOCKATTR(sockid,addr).ip, nip_ip_null, 4 ) == 0 )
00888 )
00889 goto socketfound;
00890 #if NIP_TCP_MAX_SOCKETS > 1
00891 } while ( ++sockid < NIP_TCP_MAX_SOCKETS );
00892 #endif
00893
00894 if ( flags & NIP_TCP_SYN_FLAG )
00895 goto discard;
00896 else
00897 goto reset;
00898
00899 socketfound:
00900
00901
00902
00903
00904 tcb = nip_tcp_find_conn( sockid, trans->params.ip.src_nw_addr, trans->params.tcp.src_port );
00905
00906
00907
00908
00909 nip_disp.next.tcp.flags = 0;
00910 nip_disp.next.tcp.sockid = NIP_TCP_NO_SOCKET;
00911
00912 if ( tcb != NULL )
00913 {
00914 eownd = tcb->rcv_nxt + tcb->rcv_wnd;
00915
00916
00917 if ( flags & NIP_TCP_RST_FLAG && tcb->status != NIP_TCP_STAT_LISTEN )
00918 {
00919
00920 if ( tcb->status == NIP_TCP_STAT_SYN_SENT )
00921 {
00922 if ( tcb->snd_nxt != ack )
00923 goto release_conns;
00924 }
00925 else if ( seq < tcb->rcv_nxt || seq > eownd )
00926 goto release_conns;
00927
00928
00929 tcb->status = NIP_TCP_STAT_CLOSED;
00930 nip_mem_release_block( nip_tcp_conns );
00931 goto release_conns;
00932 }
00933 }
00934
00935
00936 if ( flags & NIP_TCP_ACK_FLAG )
00937 {
00938
00939
00940 if ( tcb == NULL || tcb->status == NIP_TCP_STAT_LISTEN )
00941 goto reset;
00942
00943
00944 if ( tcb->snd_una < ack && ack <= tcb->snd_nxt )
00945 {
00946
00947 if ( tcb->flags & NIP_TCP_SOCK_FLG_SEND )
00948 {
00949 nip_mem_read( tcb->snd_buf, NULL, ack - tcb->snd_una );
00950
00951
00952 if ( nip_mem_buf_used( tcb->snd_buf ) == 0
00953 && tcb->snd_una != tcb->snd_nxt
00954 && ( tcb->status == NIP_TCP_STAT_FIN_WAIT1
00955 || tcb->status == NIP_TCP_STAT_LAST_ACK )
00956 )
00957 {
00958
00959 tcb->flags &= ~NIP_TCP_SOCK_FLG_SEND;
00960 tcb->snd_nxt++;
00961 NIP_CURR_CMD = &nip_tcp_disp_send;
00962 }
00963 }
00964
00965 tcb->snd_una = ack;
00966
00967
00968 if ( ack >= tcb->rt_una )
00969 {
00970
00971
00972
00973
00974
00975
00976
00977
00978 tcb->rt_una = tcb->snd_nxt;
00979 tcb->rto = nip_tickcount() + NIP_TCP_RTO_LBOUND;
00980
00981
00982 }
00983
00984 }
00985
00986
00987 if ( seglen > 0 )
00988 NIP_CURR_CMD = &nip_tcp_disp_send;
00989
00990
00991 if ( (tcb->rcv_wnd == 0 && seglen == 0 && tcb->rcv_nxt == seq)
00992 || ( tcb->rcv_wnd > 0
00993 && ( (seq <= tcb->rcv_nxt )
00994 && (tcb->rcv_nxt <= nxt && nxt <= eownd )
00995 )
00996 )
00997 )
00998 {
00999
01000 if ( tcb->flags & NIP_TCP_SOCK_FLG_RECV )
01001 {
01002
01003
01004
01005
01006 rcvbuf = tcb->rcv_buf;
01007 rcvbuf_size = nip_mem_buf_used( tcb->rcv_buf );
01008
01009 payoff += tcb->rcv_nxt - seq;
01010
01011 if ( (tcb->flags & NIP_TCP_SOCK_FLG_SHUT_RD) == 0)
01012 {
01013 nip_mem_release_block( nip_tcp_conns );
01014
01015 if ( trans->flags.free_payload == 1 )
01016 {
01017
01018
01019 nip_mem_read( trans->payload, NULL, payoff );
01020 seglen = nip_mem_move( rcvbuf, trans->payload, seglen - payoff );
01021 }
01022 else
01023 {
01024
01025 seglen = trans->payload_size - payoff;
01026
01027
01028 do
01029 {
01030 if ( 1 != nip_mem_read_at_pos( trans->payload, &tmp, 1, payoff++ )
01031 || NIP_E_OK != nip_mem_write( rcvbuf, &tmp, 1 ) )
01032 {
01033 break;
01034 }
01035 } while ( payoff < trans->payload_size );
01036
01037
01038 seglen -= (trans->payload_size - payoff);
01039 }
01040
01041 tcb = nip_tcp_find_conn( sockid, trans->params.ip.src_nw_addr, trans->params.tcp.src_port );
01042
01043
01044
01045 if ( tcb == NULL )
01046 {
01047
01048
01049 nip_mem_set_used( rcvbuf, rcvbuf_size );
01050 goto discard;
01051 }
01052 }
01053
01054 tcb->rcv_nxt += seglen;
01055
01056
01057
01058 }
01059 }
01060 }
01061
01062
01063 if ( flags & NIP_TCP_SYN_FLAG )
01064 {
01065
01066 if ( tcb == NULL
01067 && (NIP_TCP_SOCKATTR(sockid,flags) & NIP_TCP_SOCK_FLG_LISTENING)
01068 && nip_tcp_unaccepted_cnt < NIP_TCP_MAX_UNACCEPTED )
01069 {
01070 tcb = nip_tcp_create_conn(
01071 sockid,
01072 trans->params.ip.src_nw_addr,
01073 trans->params.tcp.src_port,
01074 NIP_TCP_STAT_LISTEN
01075 );
01076 tcb->flags = NIP_TCP_SOCKATTR(sockid,flags);
01077 nip_tcp_unaccepted[nip_tcp_unaccepted_cnt] = tcb->connid;
01078 nip_tcp_unaccepted_cnt++;
01079 }
01080
01081
01082 if ( tcb == NULL )
01083 goto discard;
01084
01085
01086 if ( tcb->status == NIP_TCP_STAT_LISTEN
01087 || tcb->status == NIP_TCP_STAT_SYN_SENT )
01088 {
01089 tcb->irs = seq;
01090 tcb->rcv_nxt = tcb->irs + 1;
01091
01092
01093 tcb->snd_wl1 = seq;
01094 tcb->snd_wl2 = ack;
01095 tcb->snd_wnd = wnd;
01096
01097 tcb->status = NIP_TCP_STAT_SYN_RECEIVED;
01098
01099
01100 }
01101
01102
01103
01104 NIP_CURR_CMD = &nip_tcp_disp_send;
01105 }
01106
01107
01108 if ( flags & NIP_TCP_FIN_FLAG )
01109 {
01110 if ( tcb == NULL )
01111 goto reset;
01112
01113
01114 if ( tcb->rcv_nxt == seq )
01115 {
01116
01117
01118 tcb->flags &= ~NIP_TCP_SOCK_FLG_RECV;
01119
01120 if ( tcb->status == NIP_TCP_STAT_ESTABLISHED )
01121 tcb->status = NIP_TCP_STAT_CLOSE_WAIT;
01122
01123 if ( tcb->status == NIP_TCP_STAT_FIN_WAIT1 )
01124 tcb->status = NIP_TCP_STAT_CLOSING;
01125
01126 if ( tcb->status == NIP_TCP_STAT_FIN_WAIT2 )
01127 {
01128 tcb->timeout = nip_tickcount() + NIP_TCP_MSL;
01129 tcb->status = NIP_TCP_STAT_TIMEWAIT;
01130 }
01131
01132 tcb->rcv_nxt++;
01133 }
01134
01135
01136 NIP_CURR_CMD = &nip_tcp_disp_send;
01137 }
01138
01139
01140
01141 if ( tcb->snd_una == tcb->snd_nxt )
01142 {
01143 if ( tcb->status == NIP_TCP_STAT_SYN_RECEIVED )
01144 {
01145 tcb->status = NIP_TCP_STAT_ESTABLISHED;
01146 tcb->flags |= NIP_TCP_SOCK_FLG_SEND | NIP_TCP_SOCK_FLG_RECV;
01147 }
01148
01149 if ( tcb->status == NIP_TCP_STAT_CLOSING )
01150 {
01151 tcb->timeout = nip_tickcount() + NIP_TCP_MSL;
01152 tcb->status = NIP_TCP_STAT_TIMEWAIT;
01153 }
01154
01155 if ( tcb->status == NIP_TCP_STAT_FIN_WAIT1 )
01156 tcb->status = NIP_TCP_STAT_FIN_WAIT2;
01157
01158 if ( tcb->status == NIP_TCP_STAT_LAST_ACK )
01159 tcb->status = NIP_TCP_STAT_CLOSED;
01160 }
01161
01162 if ( tcb != NULL )
01163 nip_disp.next.tcp.sockid = tcb->connid;
01164
01165
01166 release_conns:
01167 nip_mem_release_block( nip_tcp_conns );
01168
01169
01170
01171 discard:
01172 trans->status = NIP_NET_IF_DONE;
01173 nip_reset_trans( trans );
01174 return;
01175
01176
01177
01178 reset:
01179
01180 if ( tcb != NULL )
01181 nip_mem_release_block( nip_tcp_conns );
01182
01183
01184
01185 trans->payload_size = 0;
01186
01187
01188 if ( trans->header == NIP_MEM_NULL )
01189 {
01190
01191 trans->header = nip_mem_alloc(
01192 NIP_TCP_MIN_HEADER_SIZE,
01193 NIP_TCP_MIN_HEADER_SIZE,
01194 0,
01195 NULL
01196 );
01197
01198 }
01199 else
01200 {
01201
01202 nip_mem_set_used( trans->header, 0 );
01203 }
01204
01205
01206 if ( trans->header == NIP_MEM_NULL
01207 || nip_mem_write( trans->header, NULL, NIP_TCP_MIN_HEADER_SIZE ) != NIP_E_OK )
01208 {
01209 goto discard;
01210 }
01211
01212 head = nip_mem_obtain_ptr( trans->header );
01213 if ( head == NULL )
01214 {
01215 goto discard;
01216 }
01217
01218 trans->header_size = NIP_TCP_MIN_HEADER_SIZE;
01219
01220
01221
01222 nip_memcpy( trans->params.tcp.dst_nw_addr, trans->params.tcp.src_nw_addr, 4 );
01223 head->srcport = trans->params.tcp.dst_port;
01224 head->dstport = trans->params.tcp.src_port;
01225 head->dataoffset = NIP_TCP_MIN_DATA_OFFSET;
01226 head->flags = NIP_TCP_RST_FLAG;
01227 head->ack = NIP_TCP_RESET_ACK;
01228 if ( flags & NIP_TCP_ACK_FLAG )
01229 head->seq = htonl(ack);
01230
01231 nip_mem_release_block( trans->header );
01232
01233 trans = nip_ip_route( trans->params.tcp.dst_nw_addr, NIP_NET_NO_IF, trans );
01234 if ( trans == NULL )
01235 {
01236
01237 goto discard;
01238 }
01239 nip_tcp_checksum( trans );
01240
01241
01242 trans->params.ip.protocol = NIP_IP_PROTO_TCP;
01243 trans->status = NIP_NET_IF_RESOLV_ADDR;
01244 NIP_CURR_CMD = & nip_ip_disp_send;
01245
01246 return;
01247 }
01248
01249
01250
01251 void nip_tcp_disp_close( void )
01252 {
01253 nip_tcp_del_conn( nip_disp.next.tcp.sockid );
01254 }
01255
01256
01257
01258
01259
01260 void nip_tcp_disp_check( void )
01261 {
01262 struct nip_tcb *tcb;
01263 nip_tcp_sock_cnt_t cnt = 0;
01264 nip_mem_size_t used;
01265
01266 if ( nip_tcp_conn_cnt > 0 )
01267 {
01268
01269 tcb = nip_mem_obtain_ptr( nip_tcp_conns );
01270 if ( tcb != NULL )
01271 {
01272
01273 do
01274 {
01275
01276
01277 if ( NIP_CURR_CMD != NULL )
01278 {
01279 nip_disp_notify( NIP_DISP_CHECK_TCP );
01280 break;
01281 }
01282
01283 nip_disp.next.tcp.flags = 0;
01284 nip_disp.next.tcp.sockid = tcb->connid;
01285
01286 used = nip_mem_buf_used( tcb->snd_buf );
01287
01288
01289 if ( tcb->timeout >= nip_tickcount()
01290 && tcb->status == NIP_TCP_STAT_TIMEWAIT )
01291 {
01292 tcb->status = NIP_TCP_STAT_CLOSED;
01293 }
01294
01295 if ( tcb->status == NIP_TCP_STAT_CLOSED
01296 && tcb->flags & NIP_TCP_SOCK_FLG_AUTOCLOSE )
01297 {
01298 NIP_CURR_CMD = &nip_tcp_disp_close;
01299 }
01300 else
01301
01302 if ( (used > 0 && used > tcb->snd_nxt - tcb->snd_una)
01303 || (used == 0
01304 && ( tcb->status == NIP_TCP_STAT_FIN_WAIT1
01305 || tcb->status == NIP_TCP_STAT_LAST_ACK )
01306 )
01307 || ( tcb->snd_nxt > tcb->snd_una && tcb->rto <= nip_tickcount() )
01308 )
01309
01310 {
01311 NIP_CURR_CMD = &nip_tcp_disp_send;
01312 }
01313 tcb++;
01314 } while ( ++cnt < nip_tcp_conn_cnt );
01315
01316
01317 nip_mem_release_block( nip_tcp_conns );
01318 }
01319 }
01320
01321 }
01322
01323 #endif