PageRenderTime 67ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/platform/FNET/fnet_stack/stack/fnet_tcp.c

https://gitlab.com/fuggles/ucos
C | 4121 lines | 2565 code | 678 blank | 878 comment | 471 complexity | bc5ed71aa75ec5379df171b086c22f30 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /**************************************************************************
  2. *
  3. * Copyright 2011-2015 by Andrey Butok. FNET Community.
  4. * Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
  5. * Copyright 2003 by Alexey Shervashidze, Andrey Butok. Motorola SPS.
  6. *
  7. ***************************************************************************
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License Version 3
  10. * or later (the "LGPL").
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * and the GNU Lesser General Public License along with this program.
  18. * If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. **********************************************************************/ /*!
  21. *
  22. * @file fnet_tcp.c
  23. *
  24. * @author Olexandr Servasidze, Andrey Butok.
  25. *
  26. * @brief TCP protocol implementation.
  27. *
  28. ***************************************************************************/
  29. #include "fnet.h"
  30. #if FNET_CFG_TCP
  31. #include "fnet_socket_prv.h"
  32. #include "fnet_timer_prv.h"
  33. #include "fnet_tcp.h"
  34. #include "fnet_checksum.h"
  35. #include "fnet_prot.h"
  36. /************************************************************************
  37. * Definitions
  38. *************************************************************************/
  39. struct fnet_tcp_segment
  40. {
  41. fnet_socket_option_t *sockoption;
  42. struct sockaddr src_addr;
  43. struct sockaddr dest_addr;
  44. unsigned long seq;
  45. unsigned long ack;
  46. unsigned char flags;
  47. unsigned short wnd;
  48. unsigned short urgpointer;
  49. void *options;
  50. char optlen;
  51. fnet_netbuf_t *data;
  52. };
  53. /************************************************************************
  54. * Function Prototypes
  55. *************************************************************************/
  56. static void fnet_tcp_slowtimo( void *cookie );
  57. static void fnet_tcp_fasttimo( void *cookie );
  58. static void fnet_tcp_slowtimosk( fnet_socket_t *sk );
  59. static void fnet_tcp_fasttimosk( fnet_socket_t *sk );
  60. static int fnet_tcp_inputsk( fnet_socket_t *sk, fnet_netbuf_t *insegment, struct sockaddr *src_addr, struct sockaddr *dest_addr);
  61. static void fnet_tcp_initconnection( fnet_socket_t *sk );
  62. static int fnet_tcp_dataprocess( fnet_socket_t *sk, fnet_netbuf_t *insegment, int *ackparam );
  63. static int fnet_tcp_sendheadseg( fnet_socket_t *sk, unsigned char flags, void *options, char optlen );
  64. static int fnet_tcp_senddataseg( fnet_socket_t *sk, void *options, char optlen, unsigned long datasize );
  65. static unsigned long fnet_tcp_getrcvwnd( fnet_socket_t *sk );
  66. static int fnet_tcp_sendseg( struct fnet_tcp_segment *segment);
  67. static void fnet_tcp_sendrst( fnet_socket_option_t *sockoption, fnet_netbuf_t *insegment, struct sockaddr *src_addr, struct sockaddr *dest_addr);
  68. static void fnet_tcp_sendrstsk( fnet_socket_t *sk );
  69. static void fnet_tcp_sendack( fnet_socket_t *sk );
  70. static void fnet_tcp_abortsk( fnet_socket_t *sk );
  71. static void fnet_tcp_setsynopt( fnet_socket_t *sk, char *options, char *optionlen );
  72. static void fnet_tcp_getsynopt( fnet_socket_t *sk );
  73. static int fnet_tcp_addopt( fnet_netbuf_t *segment, unsigned char len, void *data );
  74. static void fnet_tcp_getopt( fnet_socket_t *sk, fnet_netbuf_t *segment );
  75. static unsigned long fnet_tcp_getsize( unsigned long pos1, unsigned long pos2 );
  76. static void fnet_tcp_rtimeo( fnet_socket_t *sk );
  77. static void fnet_tcp_ktimeo( fnet_socket_t *sk );
  78. static void fnet_tcp_ptimeo( fnet_socket_t *sk );
  79. static int fnet_tcp_hit( unsigned long startpos, unsigned long endpos, unsigned long pos );
  80. static int fnet_tcp_addinpbuf( fnet_socket_t *sk, fnet_netbuf_t *insegment, int *ackparam );
  81. static fnet_socket_t *fnet_tcp_findsk( struct sockaddr *src_addr, struct sockaddr *dest_addr );
  82. static void fnet_tcp_addpartialsk( fnet_socket_t *mainsk, fnet_socket_t *partialsk );
  83. static void fnet_tcp_movesk2incominglist( fnet_socket_t *sk );
  84. static void fnet_tcp_closesk( fnet_socket_t *sk );
  85. static void fnet_tcp_delpartialsk( fnet_socket_t *sk );
  86. static void fnet_tcp_delincomingsk( fnet_socket_t *sk );
  87. static void fnet_tcp_delcb( fnet_tcp_control_t *cb );
  88. #if !FNET_CFG_TCP_DISCARD_OUT_OF_ORDER
  89. static void fnet_tcp_deletetmpbuf( fnet_tcp_control_t *cb );
  90. #endif
  91. static void fnet_tcp_delsk( fnet_socket_t ** head, fnet_socket_t *sk );
  92. static int fnet_tcp_sendanydata( fnet_socket_t *sk, int oneexec );
  93. #if FNET_CFG_TCP_URGENT
  94. static void fnet_tcp_urgprocessing( fnet_socket_t *sk, fnet_netbuf_t ** segment, unsigned long repdatasize, int *ackparam );
  95. #endif
  96. static void fnet_tcp_finprocessing( fnet_socket_t *sk, unsigned long ack );
  97. static int fnet_tcp_init( void );
  98. static void fnet_tcp_release( void );
  99. static void fnet_tcp_input(fnet_netif_t *netif, struct sockaddr *src_addr, struct sockaddr *dest_addr, fnet_netbuf_t *nb, fnet_netbuf_t *ip_nb);
  100. static void fnet_tcp_control_input(fnet_prot_notify_t command, struct sockaddr *src_addr, struct sockaddr *dest_addr, fnet_netbuf_t *nb);
  101. static int fnet_tcp_attach( fnet_socket_t *sk );
  102. static int fnet_tcp_close( fnet_socket_t *sk );
  103. static int fnet_tcp_connect( fnet_socket_t *sk, struct sockaddr *foreign_addr);
  104. static fnet_socket_t *fnet_tcp_accept( fnet_socket_t *listensk );
  105. static int fnet_tcp_rcv( fnet_socket_t *sk, char *buf, int len, int flags, struct sockaddr *foreign_addr);
  106. static int fnet_tcp_snd( fnet_socket_t *sk, char *buf, int len, int flags, const struct sockaddr *foreign_addr);
  107. static int fnet_tcp_shutdown( fnet_socket_t *sk, int how );
  108. static int fnet_tcp_setsockopt( fnet_socket_t *sk, int level, int optname, char *optval, unsigned int optlen );
  109. static int fnet_tcp_getsockopt( fnet_socket_t *sk, int level, int optname, char *optval, unsigned int *optlen );
  110. static int fnet_tcp_listen( fnet_socket_t *sk, int backlog );
  111. static void fnet_tcp_drain( void );
  112. #if FNET_CFG_DEBUG_TRACE_TCP
  113. void fnet_tcp_trace(char *str, fnet_tcp_header_t *tcp_hdr);
  114. #else
  115. #define fnet_tcp_trace(str, tcp_hdr)
  116. #endif
  117. #if 0 /* For Debug needs.*/
  118. int FNET_DEBUG_check_send_buffer(fnet_socket_t *sk);
  119. #endif
  120. /************************************************************************
  121. * Global Variables
  122. *************************************************************************/
  123. /* Initial Sequence Number
  124. * tcpcb_isntime is changed by STEPISN every 0.5 sec.
  125. * Additionaly, each time a connection is established,
  126. * tcpcb_isntime is also incremented by FNET_TCP_STEPISN */
  127. static unsigned long fnet_tcp_isntime = 1;
  128. /* Timers.*/
  129. static fnet_timer_desc_t fnet_tcp_fasttimer;
  130. static fnet_timer_desc_t fnet_tcp_slowtimer;
  131. /*****************************************************************************
  132. * Protocol API structure.
  133. ******************************************************************************/
  134. static const fnet_socket_prot_if_t fnet_tcp_socket_api =
  135. {
  136. 1, /* TRUE = connection required by protocol.*/
  137. fnet_tcp_attach, /* A new socket has been created.*/
  138. fnet_tcp_close,
  139. fnet_tcp_connect,
  140. fnet_tcp_accept,
  141. fnet_tcp_rcv,
  142. fnet_tcp_snd,
  143. fnet_tcp_shutdown,
  144. fnet_tcp_setsockopt,
  145. fnet_tcp_getsockopt,
  146. fnet_tcp_listen
  147. };
  148. /* Protocol structure.*/
  149. fnet_prot_if_t fnet_tcp_prot_if =
  150. {
  151. 0,
  152. AF_SUPPORTED, /* Protocol domain.*/
  153. SOCK_STREAM, /* Socket type.*/
  154. FNET_IP_PROTOCOL_TCP, /* Protocol number.*/
  155. fnet_tcp_init,
  156. fnet_tcp_release,
  157. fnet_tcp_input,
  158. fnet_tcp_control_input, /* Control input (from below).*/
  159. fnet_tcp_drain,
  160. &fnet_tcp_socket_api /* Socket API */
  161. };
  162. /************************************************************************
  163. * NAME: fnet_tcp_init
  164. *
  165. * DESCRIPTION: This function performs a protocol initialization.
  166. *
  167. * RETURNS: If no error occurs, this function returns ERR_OK. Otherwise
  168. * it returns FNET_ERR.
  169. *************************************************************************/
  170. static int fnet_tcp_init( void )
  171. {
  172. /* Create the slow timer.*/
  173. fnet_tcp_fasttimer = fnet_timer_new(FNET_TCP_FASTTIMO / FNET_TIMER_PERIOD_MS, fnet_tcp_fasttimo, 0);
  174. if(!fnet_tcp_fasttimer)
  175. return FNET_ERR;
  176. /* Create the fast timer.*/
  177. fnet_tcp_slowtimer = fnet_timer_new(FNET_TCP_SLOWTIMO / FNET_TIMER_PERIOD_MS, fnet_tcp_slowtimo, 0);
  178. if(!fnet_tcp_slowtimer)
  179. {
  180. fnet_timer_free(fnet_tcp_fasttimer);
  181. fnet_tcp_fasttimer = 0;
  182. return FNET_ERR;
  183. }
  184. return FNET_OK;
  185. }
  186. /************************************************************************
  187. * NAME: fnet_tcp_release
  188. *
  189. * DESCRIPTION: This function resets and deletes sockets and releases timers.
  190. *
  191. * RETURNS: None.
  192. *************************************************************************/
  193. static void fnet_tcp_release( void )
  194. {
  195. fnet_tcp_control_t *cb;
  196. fnet_isr_lock();
  197. /* Release sockets.*/
  198. while(fnet_tcp_prot_if.head)
  199. {
  200. cb = (fnet_tcp_control_t *)fnet_tcp_prot_if.head->protocol_control;
  201. cb->tcpcb_flags |= FNET_TCP_CBF_CLOSE;
  202. fnet_tcp_abortsk(fnet_tcp_prot_if.head);
  203. }
  204. /* Free timers.*/
  205. fnet_timer_free(fnet_tcp_fasttimer);
  206. fnet_timer_free(fnet_tcp_slowtimer);
  207. fnet_tcp_fasttimer = 0;
  208. fnet_tcp_slowtimer = 0;
  209. fnet_isr_unlock();
  210. }
  211. /************************************************************************
  212. * NAME: fnet_tcp_input
  213. *
  214. * DESCRIPTION: This function receives, checks and routes input segments.
  215. *
  216. * RETURNS: FNET_OK.
  217. *************************************************************************/
  218. static void fnet_tcp_input(fnet_netif_t *netif, struct sockaddr *src_addr, struct sockaddr *dest_addr, fnet_netbuf_t *nb, fnet_netbuf_t *ip_nb)
  219. {
  220. fnet_socket_t *sk;
  221. fnet_netbuf_t *buf;
  222. unsigned short checksum;
  223. unsigned long tcp_length;
  224. tcp_length = (unsigned long)FNET_TCP_LENGTH(nb);
  225. fnet_netbuf_free_chain(ip_nb);
  226. /* The header must reside in contiguous area of the memory.*/
  227. buf = fnet_netbuf_pullup(nb, (int)tcp_length);
  228. if(!buf)
  229. {
  230. goto DROP;
  231. }
  232. nb = buf;
  233. /*Checksum.*/
  234. #if FNET_CFG_CPU_ETH_HW_RX_PROTOCOL_CHECKSUM || FNET_CFG_CPU_ETH_HW_TX_PROTOCOL_CHECKSUM
  235. if(nb->flags & FNET_NETBUF_FLAG_HW_PROTOCOL_CHECKSUM)
  236. {
  237. checksum = 0;
  238. }
  239. else
  240. #endif
  241. {
  242. checksum = fnet_checksum_pseudo_start( nb, FNET_HTONS((unsigned short)FNET_IP_PROTOCOL_TCP), (unsigned short)nb->total_length );
  243. checksum = fnet_checksum_pseudo_end( checksum, (char *)src_addr->sa_data, (char *)dest_addr->sa_data,
  244. (dest_addr->sa_family == AF_INET) ? sizeof(fnet_ip4_addr_t) : sizeof(fnet_ip6_addr_t) );
  245. }
  246. if(checksum
  247. || (fnet_socket_addr_is_broadcast(src_addr, netif)
  248. || fnet_socket_addr_is_multicast(src_addr))
  249. || (nb->total_length < tcp_length) /* Check the length.*/)
  250. {
  251. goto DROP;
  252. }
  253. /* Set port numbers.*/
  254. src_addr->sa_port = FNET_TCP_SPORT(nb);
  255. dest_addr->sa_port = FNET_TCP_DPORT(nb);
  256. if(fnet_socket_addr_is_broadcast(dest_addr, netif) || fnet_socket_addr_is_multicast(dest_addr))
  257. {
  258. /* Send RST.*/
  259. fnet_tcp_sendrst(0, nb, dest_addr, src_addr);
  260. goto DROP;
  261. }
  262. fnet_tcp_trace("RX", buf->data_ptr); /* TCP trace.*/
  263. sk = fnet_tcp_findsk(src_addr, dest_addr);
  264. if(sk)
  265. {
  266. if(sk->state == SS_LISTENING)
  267. {
  268. sk->foreign_addr = *src_addr;
  269. }
  270. nb->next_chain = 0;
  271. /* Process the segment.*/
  272. if(fnet_tcp_inputsk(sk, nb, src_addr, dest_addr) == FNET_TRUE)
  273. goto DROP;
  274. }
  275. else
  276. {
  277. if(!(FNET_TCP_FLAGS(nb) & FNET_TCP_SGT_RST))
  278. fnet_tcp_sendrst(0, nb, dest_addr, src_addr);
  279. goto DROP;
  280. }
  281. /* Wake-up user application.*/
  282. fnet_os_event_raise();
  283. return;
  284. DROP:
  285. /* Wake-up user application.*/
  286. fnet_os_event_raise();
  287. /* Delete the segment.*/
  288. fnet_netbuf_free_chain(nb);
  289. }
  290. /************************************************************************
  291. * NAME: fnet_tcp_control_input
  292. *
  293. * DESCRIPTION: This function process ICMP errors.
  294. *
  295. * RETURNS: None.
  296. *************************************************************************/
  297. static void fnet_tcp_control_input(fnet_prot_notify_t command, struct sockaddr *src_addr, struct sockaddr *dest_addr, fnet_netbuf_t *nb)
  298. {
  299. fnet_tcp_header_t *tcp_header; /* Pointer to the TCP header.*/
  300. fnet_socket_t *sk; /* Pointer to the socket.*/
  301. fnet_tcp_control_t *cb;
  302. if(src_addr && dest_addr && nb)
  303. {
  304. tcp_header = nb->data_ptr;
  305. /* Find the corresponding socket.*/
  306. dest_addr->sa_port = tcp_header->destination_port;
  307. src_addr->sa_port = tcp_header->source_port;
  308. sk = fnet_tcp_findsk(dest_addr, src_addr);
  309. if(sk)
  310. {
  311. /* Initialize the pointer of the control block.*/
  312. cb = sk->protocol_control;
  313. switch(command)
  314. {
  315. case FNET_PROT_NOTIFY_QUENCH: /* Someone said to slow down.*/
  316. /* Begin the Slow Start algorithm.*/
  317. cb->tcpcb_cwnd = cb->tcpcb_sndmss;
  318. break;
  319. case FNET_PROT_NOTIFY_MSGSIZE: /* Message size forced drop.*/
  320. sk->options.local_error = FNET_ERR_MSGSIZE;
  321. break;
  322. case FNET_PROT_NOTIFY_UNREACH_HOST: /* No route to host.*/
  323. case FNET_PROT_NOTIFY_UNREACH_NET: /* No route to network.*/
  324. case FNET_PROT_NOTIFY_UNREACH_SRCFAIL: /* Source route failed.*/
  325. sk->options.local_error = FNET_ERR_HOSTUNREACH;
  326. break;
  327. case FNET_PROT_NOTIFY_PARAMPROB: /* Header incorrect.*/
  328. sk->options.local_error = FNET_ERR_NOPROTOOPT; /* Bad protocol option.*/
  329. break;
  330. case FNET_PROT_NOTIFY_UNREACH_PORT: /* bad port #.*/
  331. case FNET_PROT_NOTIFY_UNREACH_PROTOCOL:
  332. if(sk->state != SS_LISTENING) /* Avoid listening sockets.*/
  333. {
  334. sk->options.local_error = FNET_ERR_CONNRESET;
  335. fnet_tcp_closesk(sk);
  336. }
  337. break;
  338. default:
  339. break;
  340. }
  341. }
  342. }
  343. }
  344. /************************************************************************
  345. * NAME: fnet_tcp_attach
  346. *
  347. * DESCRIPTION: This function performs the initialization of the
  348. * socket's options and creates the structure of the control blok.
  349. *
  350. * RETURNS: If no error occurs, this function returns FNET_OK. Otherwise
  351. * it returns FNET_ERR.
  352. *************************************************************************/
  353. static int fnet_tcp_attach( fnet_socket_t *sk )
  354. {
  355. struct tcpcb *cb;
  356. /* Create the control block.*/
  357. cb = (struct tcpcb *)fnet_malloc_zero(sizeof(fnet_tcp_control_t));
  358. /* Check the memory allocation.*/
  359. if(!cb)
  360. {
  361. fnet_socket_set_error(sk, FNET_ERR_NOMEM);
  362. return FNET_ERR;
  363. }
  364. sk->protocol_control = (void *)cb;
  365. /* Set the maximal segment size option.*/
  366. sk->options.tcp_opt.mss = FNET_CFG_SOCKET_TCP_MSS;
  367. /* Default setting of the flags.*/
  368. sk->options.tcp_opt.flags =
  369. #if FNET_CFG_TCP_URGENT
  370. TCP_BSD |
  371. #endif
  372. TCP_NODELAY;
  373. sk->options.tcp_opt.keep_idle = FNET_TCP_KEEPIDLE_DEFAULT; /* TCP_KEEPIDLE option. */
  374. sk->options.tcp_opt.keep_intvl = FNET_TCP_KEEPINTVL_DEFAULT; /* TCP_KEEPINTVL option. */
  375. sk->options.tcp_opt.keep_cnt = FNET_TCP_KEEPCNT_DEFAULT; /* TCP_KEEPCNT option. */
  376. sk->options.flags = SO_KEEPALIVE;
  377. /* Set the IP options.*/
  378. #if FNET_CFG_IP4
  379. sk->options.ip_opt.ttl = FNET_TCP_TTL_DEFAULT;
  380. sk->options.ip_opt.tos = 0;
  381. #endif
  382. #if FNET_CFG_IP6
  383. sk->options.ip6_opt.hops_unicast = 0; /* Defined by ND.*/
  384. #endif
  385. /* Set the buffer sizes.*/
  386. sk->send_buffer.count_max = FNET_TCP_TX_BUF_MAX;
  387. sk->receive_buffer.count_max = FNET_TCP_RX_BUF_MAX;
  388. return FNET_OK;
  389. }
  390. /************************************************************************
  391. * NAME: fnet_tcp_close
  392. *
  393. * DESCRIPTION: This function performs the connection termination.
  394. *
  395. * RETURNS: If no error occurs, this function returns FNET_OK. Otherwise
  396. * it returns FNET_ERR.
  397. *************************************************************************/
  398. static int fnet_tcp_close( fnet_socket_t *sk )
  399. {
  400. fnet_tcp_control_t *cb = (fnet_tcp_control_t *)sk->protocol_control;
  401. /* If the connection is closed, free the memory.*/
  402. if(sk->state == SS_UNCONNECTED)
  403. {
  404. cb->tcpcb_flags |= FNET_TCP_CBF_CLOSE;
  405. fnet_tcp_closesk(sk);
  406. return FNET_OK;
  407. }
  408. /* If SO_LINGER option is present.*/
  409. if(sk->options.flags & SO_LINGER)
  410. {
  411. if(sk->options.linger_ticks == 0)
  412. /* Linger is 0 so close the socket immediately. */
  413. {
  414. /* Hard reset.*/
  415. fnet_isr_lock();
  416. cb->tcpcb_flags |= FNET_TCP_CBF_CLOSE;
  417. fnet_tcp_abortsk(sk);
  418. fnet_isr_unlock();
  419. return FNET_OK;
  420. }
  421. }
  422. fnet_isr_lock();
  423. if(sk->state != SS_CONNECTED)
  424. {
  425. cb->tcpcb_flags |= FNET_TCP_CBF_CLOSE;
  426. fnet_tcp_abortsk(sk);
  427. /* Unlock interrupts.*/
  428. fnet_isr_unlock();
  429. return FNET_OK;
  430. }
  431. /* If the socket is not unlocked, try to send the data.*/
  432. if(!sk->send_buffer.is_shutdown)
  433. {
  434. sk->send_buffer.is_shutdown = 1;
  435. fnet_tcp_sendanydata(sk, 1);
  436. }
  437. fnet_isr_unlock();
  438. fnet_isr_lock();
  439. /* After this moment the unconnecetd socket must be deleted.*/
  440. cb->tcpcb_flags |= FNET_TCP_CBF_CLOSE;
  441. /* If the socket is already unconnected, close the socket.*/
  442. if(sk->state == SS_UNCONNECTED)
  443. {
  444. fnet_tcp_closesk(sk);
  445. }
  446. else
  447. {
  448. if(cb->tcpcb_connection_state != FNET_TCP_CS_TIME_WAIT)
  449. {
  450. if((sk->options.flags & SO_LINGER) && sk->options.linger_ticks)
  451. cb->tcpcb_timers.connection = ((sk->options.linger_ticks * FNET_TIMER_PERIOD_MS)
  452. / FNET_TCP_SLOWTIMO);
  453. else
  454. cb->tcpcb_timers.connection = FNET_TCP_ABORT_INTERVAL;
  455. sk->receive_buffer.is_shutdown = 1;
  456. }
  457. if(sk->receive_buffer.count)
  458. fnet_socket_buffer_release(&sk->receive_buffer);
  459. }
  460. fnet_isr_unlock();
  461. return FNET_OK;
  462. }
  463. /************************************************************************
  464. * NAME: fnet_tcp_connect
  465. *
  466. * DESCRIPTION: This function performs the connection establishment.
  467. *
  468. * RETURNS: If no error occurs, this function returns FNET_OK. Otherwise
  469. * it returns FNET_ERR.
  470. *************************************************************************/
  471. static int fnet_tcp_connect( fnet_socket_t *sk, struct sockaddr *foreign_addr)
  472. {
  473. fnet_tcp_control_t *cb;
  474. char options[FNET_TCP_MAX_OPT_SIZE];
  475. char optionlen;
  476. int error;
  477. fnet_netif_t *netif;
  478. if((netif = fnet_socket_addr_route(foreign_addr)) == FNET_NULL)
  479. {
  480. error = FNET_ERR_NETUNREACH;
  481. goto ERROR;
  482. }
  483. /* TCP doesn't support broadcasting and multicasting.*/
  484. if(fnet_socket_addr_is_broadcast(foreign_addr, netif) || fnet_socket_addr_is_multicast(foreign_addr))
  485. {
  486. error = FNET_ERR_ADDRNOTAVAIL;
  487. goto ERROR;
  488. }
  489. /* Initialize the pointer to the control block.*/
  490. cb = (fnet_tcp_control_t *)sk->protocol_control;
  491. /* Initialize the control block.*/
  492. fnet_tcp_initconnection(sk);
  493. /* Set synchronized options.*/
  494. fnet_tcp_setsynopt(sk, options, &optionlen);
  495. /* Initialize sequnece number parameters.*/
  496. cb->tcpcb_sndseq = fnet_tcp_isntime;
  497. cb->tcpcb_maxrcvack = fnet_tcp_isntime + 1;
  498. #if FNET_CFG_TCP_URGENT
  499. cb->tcpcb_sndurgseq = cb->tcpcb_sndseq - 1;
  500. #endif /* FNET_CFG_TCP_URGENT */
  501. /* Set the foreign address.*/
  502. sk->foreign_addr = *foreign_addr;
  503. fnet_isr_lock();
  504. /* Send SYN segment.*/
  505. error = fnet_tcp_sendheadseg(sk, FNET_TCP_SGT_SYN, options, optionlen);
  506. /* Check the result.*/
  507. if(error)
  508. {
  509. fnet_isr_unlock();
  510. goto ERROR;
  511. }
  512. /* Change the states.*/
  513. cb->tcpcb_connection_state = FNET_TCP_CS_SYN_SENT;
  514. sk->state = SS_CONNECTING;
  515. /* Increase Initial Sequence Number.*/
  516. fnet_tcp_isntime += FNET_TCP_STEPISN;
  517. /* Initialize Abort Timer.*/
  518. cb->tcpcb_timers.retransmission = cb->tcpcb_rto;
  519. cb->tcpcb_timers.connection = FNET_TCP_ABORT_INTERVAL_CON;
  520. fnet_isr_unlock();
  521. return FNET_OK;
  522. ERROR:
  523. fnet_socket_set_error(sk, error);
  524. return FNET_ERR;
  525. }
  526. /************************************************************************
  527. * NAME: fnet_tcp_accept
  528. *
  529. * DESCRIPTION: This function removes the created socket
  530. * from the incoming queue of the listening socket,
  531. * and adds this socket to the main list.
  532. *
  533. * RETURNS: If the incoming socket is present, this function returns
  534. * the first created incoming socket. Otherwise, it returns 0.
  535. *************************************************************************/
  536. static fnet_socket_t *fnet_tcp_accept( fnet_socket_t *listensk )
  537. {
  538. fnet_socket_t *sk= FNET_NULL;
  539. /* If the incoming socket is not present, return.*/
  540. if(listensk->incoming_con)
  541. {
  542. fnet_isr_lock();
  543. /* Find the first incoming socket.*/
  544. sk = listensk->incoming_con;
  545. while(sk->next)
  546. sk = sk->next;
  547. /* Delete the incoming socket from the list.*/
  548. sk->head_con->incoming_con_len--;
  549. fnet_socket_list_del(&sk->head_con->incoming_con, sk);
  550. fnet_isr_unlock();
  551. sk->head_con = 0;
  552. }
  553. return sk;
  554. }
  555. /************************************************************************
  556. * NAME: fnet_tcp_rcv
  557. *
  558. * DESCRIPTION: This function receives the data and sends the acknowledgment
  559. * (This acknowledgment segment informs about the new free size
  560. * in the input buffer).
  561. *
  562. * RETURNS: If no error occurs, this function returns the length
  563. * of the received data. Otherwise, it returns FNET_ERR.
  564. *************************************************************************/
  565. static int fnet_tcp_rcv( fnet_socket_t *sk, char *buf, int len, int flags, struct sockaddr *foreign_addr)
  566. {
  567. fnet_tcp_control_t *cb = (fnet_tcp_control_t *)sk->protocol_control;
  568. int remove; /* Remove flag. 1 means that the data must be deleted
  569. * from the input buffer after the reading.*/
  570. int error_code;
  571. /* Receive the flags.*/
  572. remove = !(flags & MSG_PEEK);
  573. #if FNET_CFG_TCP_URGENT
  574. /* Reading of the OOB data.*/
  575. if(flags & MSG_OOB)
  576. {
  577. /* If the OOB data can't be read, return.*/
  578. if(sk->options.flags & SO_OOBINLINE)
  579. {
  580. error_code = FNET_ERR_INVAL;
  581. goto ERROR;
  582. }
  583. /* If the OOB data is present, read */
  584. if(cb->tcpcb_flags & FNET_TCP_CBF_RCVURGENT)
  585. {
  586. fnet_isr_lock();
  587. if(remove)
  588. {
  589. cb->tcpcb_rcvurgmark = FNET_TCP_NOT_USED;
  590. cb->tcpcb_flags &= ~FNET_TCP_CBF_RCVURGENT;
  591. }
  592. *buf = cb->tcpcb_iobc;
  593. fnet_isr_unlock();
  594. return FNET_TCP_URGENT_DATA_SIZE;
  595. }
  596. else
  597. {
  598. /* If the socket is not connected , return with the error. */
  599. if(sk->state != SS_CONNECTED)
  600. {
  601. error_code = FNET_ERR_NOTCONN;
  602. goto ERROR;
  603. }
  604. return 0;
  605. }
  606. }
  607. #endif /* FNET_CFG_TCP_URGENT */
  608. fnet_isr_lock();
  609. #if FNET_CFG_TCP_URGENT
  610. /* Calculate the length of the data that can be received.*/
  611. if(cb->tcpcb_rcvurgmark > 0 && len >= cb->tcpcb_rcvurgmark)
  612. {
  613. len = cb->tcpcb_rcvurgmark;
  614. if(remove)
  615. cb->tcpcb_rcvurgmark = FNET_TCP_NOT_USED;
  616. }
  617. else
  618. #endif /* FNET_CFG_TCP_URGENT */
  619. if(sk->receive_buffer.count < len)
  620. {
  621. len = (int)sk->receive_buffer.count;
  622. }
  623. /* Copy the data to the buffer.*/
  624. len = fnet_socket_buffer_read_record(&sk->receive_buffer, buf, len, remove);
  625. /* Remove the data from input buffer.*/
  626. if(remove)
  627. {
  628. /* Recalculate the new free size in the input buffer.*/
  629. cb->tcpcb_newfreercvsize += len;
  630. /* If the window is opened, send acknowledgment.*/
  631. if((cb->tcpcb_newfreercvsize >= (cb->tcpcb_rcvmss << 1)
  632. || cb->tcpcb_newfreercvsize >= (cb->tcpcb_rcvcountmax >> 1) /* More than half of RX buffer.*/
  633. || (!cb->tcpcb_rcvwnd && cb->tcpcb_newfreercvsize)) && (sk->state == SS_CONNECTED))
  634. fnet_tcp_sendack(sk);
  635. }
  636. /* If the socket is not connected and the data are not received, return with error.*/
  637. if(len == 0 && sk->state != SS_CONNECTED)
  638. {
  639. error_code = FNET_ERR_NOTCONN;
  640. goto ERROR_UNLOCK;
  641. }
  642. else
  643. {
  644. /* Set the foreign address and port.*/
  645. if(foreign_addr)
  646. *foreign_addr = sk->foreign_addr;
  647. /* If the socket is closed by peer and no data.*/
  648. if((len == 0) && (cb->tcpcb_flags & FNET_TCP_CBF_FIN_RCVD))
  649. {
  650. error_code = FNET_ERR_CONNCLOSED;
  651. goto ERROR_UNLOCK;
  652. }
  653. }
  654. fnet_isr_unlock();
  655. return len;
  656. ERROR_UNLOCK:
  657. fnet_isr_unlock();
  658. #if FNET_CFG_TCP_URGENT
  659. ERROR:
  660. #endif
  661. fnet_socket_set_error(sk, error_code);
  662. return FNET_ERR;
  663. }
  664. /************************************************************************
  665. * NAME: fnet_tcp_snd
  666. *
  667. * DESCRIPTION: This function adds the data to the output buffer and
  668. * sends the data that can be sent.
  669. *
  670. * RETURNS: If no error occurs, this function returns the length
  671. * of the data that is added to the output buffer.
  672. * Otherwise, it returns FNET_ERR.
  673. *************************************************************************/
  674. static int fnet_tcp_snd( fnet_socket_t *sk, char *buf, int len, int flags, const struct sockaddr *foreign_addr)
  675. {
  676. fnet_tcp_control_t *cb = (fnet_tcp_control_t *)sk->protocol_control;
  677. fnet_netbuf_t *netbuf;
  678. long sendlength = len; /* Size of the data that must be sent.*/
  679. long sentlength = 0; /* Length of the sent data.*/
  680. long freespace; /* Free space in the output buffer.*/
  681. long currentlen; /* Current length.*/
  682. int dontroute = 0; /* Routing flag.*/
  683. unsigned long malloc_max;
  684. int error_code;
  685. FNET_COMP_UNUSED_ARG(foreign_addr);
  686. /* If the size of the data greater than the maximal size of the output buffer, return*/
  687. if(sendlength > FNET_TCP_MAX_BUFFER)
  688. {
  689. error_code = FNET_ERR_INVAL;
  690. goto ERROR;
  691. }
  692. /* If the socket is not connected, return*/
  693. if(sk->state != SS_CONNECTED)
  694. {
  695. error_code = FNET_ERR_NOTCONN;
  696. goto ERROR;
  697. }
  698. if(sendlength)
  699. {
  700. fnet_isr_lock();
  701. /* Caclulate a free space in the output buffer.*/
  702. freespace = (long)(sk->send_buffer.count_max - sk->send_buffer.count);
  703. /* Check maximum allocated memory chunck */
  704. malloc_max = fnet_malloc_max_netbuf();
  705. if(malloc_max < (long)(FNET_CFG_CPU_ETH0_MTU*1.5)) /* TBD I do not like it ????*/
  706. {
  707. freespace = 0;
  708. }
  709. else if(freespace > malloc_max)
  710. {
  711. freespace = (long)malloc_max;
  712. }
  713. /* If the function is nonblocking and the data length greater than the freespace, recalculate the size of the data*/
  714. if(freespace < sendlength)
  715. {
  716. /* If the data can't be added to the output buffer, return*/
  717. if(freespace <= 0)
  718. {
  719. fnet_isr_unlock();
  720. return 0;
  721. }
  722. else
  723. {
  724. /* Recalculate the data size.*/
  725. sendlength = freespace;
  726. #if FNET_CFG_TCP_URGENT
  727. flags &= ~MSG_OOB;
  728. #endif /* FNET_CFG_TCP_URGENT */
  729. }
  730. }
  731. #if FNET_CFG_TCP_URGENT
  732. /* Process the OOB data.*/
  733. if(flags & MSG_OOB)
  734. {
  735. /* If the urgent data are already present, the urgent byte will not be added.*/
  736. if(FNET_TCP_COMP_GE(cb->tcpcb_sndurgseq, cb->tcpcb_rcvack))
  737. {
  738. sendlength -= 1;
  739. /* If the data size is 0, return.*/
  740. if(!sendlength)
  741. {
  742. fnet_isr_unlock();
  743. return 0;
  744. }
  745. }
  746. else
  747. {
  748. /* Calculate the new sequence number of the urgent data.*/
  749. cb->tcpcb_sndurgseq = cb->tcpcb_rcvack + sk->send_buffer.count + sendlength - 1;
  750. }
  751. }
  752. #endif /* FNET_CFG_TCP_URGENT */
  753. /* If the routing tables should be bypassed for this message only, set dontroute flag.*/
  754. if((flags & MSG_DONTROUTE) && !(sk->options.flags & SO_DONTROUTE))
  755. {
  756. dontroute = 1;
  757. sk->options.flags |= SO_DONTROUTE;
  758. }
  759. /* Receive the freespace value.*/
  760. /* TBD*/
  761. #if 0
  762. freespace = (long)(sk->send_buffer.count_max - sk->send_buffer.count);
  763. #endif
  764. /* Try to add the data.*/
  765. if(freespace > 0)
  766. {
  767. cb->tcpcb_flags |= FNET_TCP_CBF_INSND;
  768. /* Calculate the data size that can be added.*/
  769. if(sendlength > freespace)
  770. currentlen = freespace;
  771. else
  772. currentlen = sendlength;
  773. netbuf = fnet_netbuf_from_buf(&buf[sentlength], currentlen, FNET_TRUE);
  774. /* Check the memory allocation.*/
  775. if(netbuf)
  776. {
  777. sentlength += currentlen;
  778. if(fnet_socket_buffer_append_record(&sk->send_buffer, netbuf) == FNET_OK)
  779. {
  780. /* If the window of another side is closed, set the persist timer.*/
  781. if(!cb->tcpcb_sndwnd)
  782. {
  783. if(cb->tcpcb_timers.persist == FNET_TCP_TIMER_OFF)
  784. {
  785. cb->tcpcb_cprto = cb->tcpcb_rto;
  786. cb->tcpcb_timers.persist = cb->tcpcb_cprto;
  787. }
  788. }
  789. else
  790. {
  791. /* Try to send the data.*/
  792. while(1)
  793. {
  794. /* If the connection is not established, delete the data. Otherwise try to send the data*/
  795. if(sk->state == SS_CONNECTED)
  796. {
  797. if(!fnet_tcp_sendanydata(sk, 1))
  798. {
  799. cb->tcpcb_flags &= ~FNET_TCP_CBF_INSND;
  800. break;
  801. }
  802. }
  803. else
  804. {
  805. /* If socket is not connected, delete the output buffer.*/
  806. fnet_socket_buffer_release(&sk->send_buffer);
  807. cb->tcpcb_flags &= ~FNET_TCP_CBF_INSND;
  808. break;
  809. }
  810. }
  811. }
  812. }
  813. else /* Not able to add to the socket send buffer.*/
  814. {
  815. fnet_netbuf_free( netbuf );
  816. fnet_isr_unlock();
  817. return 0;
  818. }
  819. }
  820. }
  821. /* Receive the freespace value.*/
  822. freespace = (long)(sk->send_buffer.count_max - sk->send_buffer.count);
  823. #if FNET_CFG_TCP_URGENT
  824. if(FNET_TCP_COMP_GE(cb->tcpcb_sndurgseq, cb->tcpcb_rcvack + sk->send_buffer.count))
  825. cb->tcpcb_sndurgseq = cb->tcpcb_rcvack - 1;
  826. #endif /* FNET_CFG_TCP_URGENT */
  827. /* Remove the dontroute flag.*/
  828. if(dontroute)
  829. sk->options.flags &= ~SO_DONTROUTE;
  830. fnet_isr_unlock();
  831. }
  832. return sentlength;
  833. ERROR:
  834. fnet_socket_set_error(sk, error_code);
  835. return FNET_ERR;
  836. }
  837. /************************************************************************
  838. * NAME: fnet_tcp_shutdown
  839. *
  840. * DESCRIPTION: This function closes a write-half, read-half, or
  841. * both halves of the connection.
  842. *
  843. * RETURNS: If no error occurs, this function returns FNET_OK. Otherwise
  844. * it returns FNET_ERR.
  845. *************************************************************************/
  846. static int fnet_tcp_shutdown( fnet_socket_t *sk, int how )
  847. {
  848. /* If the socket is not connected, return.*/
  849. if(sk->state != SS_CONNECTED)
  850. {
  851. fnet_socket_set_error(sk, FNET_ERR_NOTCONN);
  852. return FNET_ERR;
  853. }
  854. else
  855. {
  856. fnet_isr_lock();
  857. /* Shutdown the writing.*/
  858. if(how & SD_WRITE && !sk->send_buffer.is_shutdown)
  859. {
  860. /* Set the flag of the buffer.*/
  861. sk->send_buffer.is_shutdown = 1;
  862. /* Send the data that is in the output buffer.*/
  863. fnet_tcp_sendanydata(sk, 1);
  864. }
  865. /* Shutdown the reading.*/
  866. if(how & SD_READ && !sk->receive_buffer.is_shutdown)
  867. {
  868. fnet_socket_buffer_release(&sk->receive_buffer);
  869. /* Set the flag of the buffer (Data can't be read).*/
  870. sk->receive_buffer.is_shutdown = 1;
  871. }
  872. fnet_isr_unlock();
  873. return FNET_OK;
  874. }
  875. }
  876. /************************************************************************
  877. * NAME: fnet_tcp_setsockopt
  878. *
  879. * DESCRIPTION: This function sets a TCP option.
  880. *
  881. * RETURNS: If no error occurs, this function returns FNET_OK. Otherwise
  882. * it returns FNET_ERR.
  883. *************************************************************************/
  884. static int fnet_tcp_setsockopt( fnet_socket_t *sk, int level, int optname, char *optval, unsigned int optlen )
  885. {
  886. int error_code;
  887. /* If the level is not IPPROTO_TCP, go to IP processing.*/
  888. if(level == IPPROTO_TCP)
  889. {
  890. /* Check the option size.*/
  891. switch(optname)
  892. {
  893. case TCP_MSS:
  894. if(optlen != sizeof(unsigned short))
  895. {
  896. error_code = FNET_ERR_INVAL;
  897. goto ERROR;
  898. }
  899. break;
  900. case TCP_KEEPCNT:
  901. case TCP_KEEPINTVL:
  902. case TCP_KEEPIDLE:
  903. case TCP_NODELAY:
  904. #if FNET_CFG_TCP_URGENT
  905. case TCP_BSD:
  906. #endif
  907. if(optlen != sizeof(int))
  908. {
  909. error_code = FNET_ERR_INVAL;
  910. goto ERROR;
  911. }
  912. break;
  913. default:
  914. /* The option is not supported.*/
  915. error_code = FNET_ERR_NOPROTOOPT;
  916. goto ERROR;
  917. }
  918. /* Process the option.*/
  919. switch(optname)
  920. {
  921. /* Maximal segment size option.*/
  922. case TCP_MSS:
  923. if(!(*((unsigned short *)(optval))))
  924. {
  925. error_code = FNET_ERR_INVAL;
  926. goto ERROR;
  927. }
  928. sk->options.tcp_opt.mss = *((unsigned short *)(optval));
  929. break;
  930. /* Keepalive probe retransmit limit.*/
  931. case TCP_KEEPCNT:
  932. if(!(*((unsigned int *)(optval))))
  933. {
  934. error_code = FNET_ERR_INVAL;
  935. goto ERROR;
  936. }
  937. sk->options.tcp_opt.keep_cnt = *((int *)(optval));
  938. break;
  939. /* Keepalive retransmit interval.*/
  940. case TCP_KEEPINTVL:
  941. if(!(*((unsigned int *)(optval))))
  942. {
  943. error_code = FNET_ERR_INVAL;
  944. goto ERROR;
  945. }
  946. sk->options.tcp_opt.keep_intvl = *((int *)(optval))*(1000/FNET_TCP_SLOWTIMO);
  947. break;
  948. /* Time between keepalive probes.*/
  949. case TCP_KEEPIDLE:
  950. if(!(*((unsigned int *)(optval))))
  951. {
  952. error_code = FNET_ERR_INVAL;
  953. goto ERROR;
  954. }
  955. sk->options.tcp_opt.keep_idle = *((int *)(optval))*(1000/FNET_TCP_SLOWTIMO);
  956. break;
  957. #if FNET_CFG_TCP_URGENT
  958. /* BSD interpretation of the urgent pointer.*/
  959. case TCP_BSD:
  960. #endif
  961. /* TCP_NO_DELAY option.*/
  962. case TCP_NODELAY:
  963. if(*((int *)(optval)))
  964. sk->options.tcp_opt.flags |= optname;
  965. else
  966. sk->options.tcp_opt.flags &= ~optname;
  967. break;
  968. }
  969. return FNET_OK;
  970. }
  971. else
  972. {
  973. /* IP level option processing.*/
  974. return fnet_ip_setsockopt(sk, level, optname, optval, optlen);
  975. }
  976. ERROR:
  977. fnet_socket_set_error(sk, error_code);
  978. return FNET_ERR;
  979. }
  980. /************************************************************************
  981. * NAME: fnet_tcp_getsockopt
  982. *
  983. * DESCRIPTION: This function receives a TCP option.
  984. *
  985. * RETURNS: If no error occurs, this function returns FNET_OK. Otherwise
  986. * it returns FNET_ERR.
  987. *************************************************************************/
  988. static int fnet_tcp_getsockopt( fnet_socket_t *sk, int level, int optname, char *optval, unsigned int *optlen )
  989. {
  990. fnet_tcp_control_t *cb = (fnet_tcp_control_t *)sk->protocol_control;
  991. if(level == IPPROTO_TCP)
  992. {
  993. switch(optname)
  994. {
  995. case TCP_KEEPCNT:
  996. *((int *)(optval)) = sk->options.tcp_opt.keep_cnt;
  997. break;
  998. case TCP_KEEPINTVL:
  999. *((int *)(optval)) = sk->options.tcp_opt.keep_intvl/(1000/FNET_TCP_SLOWTIMO);
  1000. break;
  1001. case TCP_KEEPIDLE:
  1002. *((int *)(optval)) = sk->options.tcp_opt.keep_idle/(1000/FNET_TCP_SLOWTIMO);
  1003. break;
  1004. #if FNET_CFG_TCP_URGENT
  1005. case TCP_BSD:
  1006. #endif
  1007. case TCP_NODELAY:
  1008. if(sk->options.tcp_opt.flags & optname)
  1009. *((int *)(optval)) = 1;
  1010. else
  1011. *((int *)(optval)) = 0;
  1012. break;
  1013. case TCP_FINRCVD:
  1014. if(cb->tcpcb_flags & FNET_TCP_CBF_FIN_RCVD)
  1015. *((int *)(optval)) = 1;
  1016. else
  1017. *((int *)(optval)) = 0;
  1018. break;
  1019. #if FNET_CFG_TCP_URGENT
  1020. case TCP_URGRCVD:
  1021. if(cb->tcpcb_flags & FNET_TCP_CBF_RCVURGENT)
  1022. *((int *)(optval)) = 1;
  1023. else
  1024. *((int *)(optval)) = 0;
  1025. break;
  1026. #endif
  1027. case TCP_MSS:
  1028. *((unsigned short *)(optval)) = sk->options.tcp_opt.mss;
  1029. *optlen = sizeof(unsigned short);
  1030. return FNET_OK;
  1031. default:
  1032. fnet_socket_set_error(sk, FNET_ERR_NOPROTOOPT);
  1033. return FNET_ERR;
  1034. }
  1035. *optlen = sizeof(int);
  1036. return FNET_OK;
  1037. }
  1038. else
  1039. {
  1040. /* IP level option processing.*/
  1041. return fnet_ip_getsockopt(sk, level, optname, optval, optlen);
  1042. }
  1043. }
  1044. /************************************************************************
  1045. * NAME: fnet_tcp_listen
  1046. *
  1047. * DESCRIPTION: This function changes
  1048. * the state of the socket to the listening state.
  1049. *
  1050. * RETURNS: FNET_OK.
  1051. *************************************************************************/
  1052. static int fnet_tcp_listen( fnet_socket_t *sk, int backlog )
  1053. {
  1054. /* Initializen the pointer to the control block.*/
  1055. fnet_tcp_control_t *cb = (fnet_tcp_control_t *)sk->protocol_control;
  1056. if(sk->state == SS_LISTENING)
  1057. {
  1058. /* If the socket number of the listening socket is greater than the new backlog,
  1059. * delete the sockets.*/
  1060. fnet_isr_lock();
  1061. while(backlog < sk->partial_con_len + sk->incoming_con_len && sk->partial_con_len)
  1062. fnet_tcp_abortsk(sk->partial_con);
  1063. while(backlog < sk->incoming_con_len)
  1064. fnet_tcp_abortsk(sk->incoming_con);
  1065. sk->con_limit = backlog;
  1066. fnet_isr_unlock();
  1067. }
  1068. else
  1069. {
  1070. fnet_tcp_initconnection(sk);
  1071. /* Foreign address must be any.*/
  1072. ((struct sockaddr_in *)(&sk->foreign_addr))->sin_addr.s_addr = INADDR_ANY;
  1073. sk->foreign_addr.sa_port = 0;
  1074. sk->foreign_addr.sa_family = AF_INET;
  1075. sk->con_limit = backlog;
  1076. /* Change the state.*/
  1077. cb->tcpcb_connection_state = FNET_TCP_CS_LISTENING;
  1078. sk->state = SS_LISTENING;
  1079. }
  1080. return FNET_OK;
  1081. }
  1082. /************************************************************************
  1083. * NAME: fnet_tcp_drain
  1084. *
  1085. * DESCRIPTION: fnet_tcp_drain removes the temporary data.
  1086. *
  1087. * RETURNS: None.
  1088. *************************************************************************/
  1089. static void fnet_tcp_drain( void )
  1090. {
  1091. fnet_socket_t *sk;
  1092. fnet_socket_t *delsk;
  1093. fnet_tcp_control_t *cb;
  1094. fnet_isr_lock();
  1095. /* Receive the pointer to the first socket.*/
  1096. sk = fnet_tcp_prot_if.head;
  1097. while(sk)
  1098. {
  1099. cb = (fnet_tcp_control_t *)sk->protocol_control;
  1100. delsk = sk;
  1101. sk = sk->next;
  1102. /* if((cb->tcpcb_connection_state == FNET_TCP_CS_TIME_WAIT) && (cb->tcpcb_flags & FNET_TCP_CBF_CLOSE))*/
  1103. if((cb->tcpcb_flags & FNET_TCP_CBF_CLOSE))
  1104. {
  1105. /* Remove the socket that to be closed. */
  1106. fnet_tcp_closesk(delsk);
  1107. }
  1108. /* Delete all partial and incoming connections */
  1109. else if(delsk->state == SS_LISTENING)
  1110. {
  1111. while(delsk->partial_con)
  1112. fnet_tcp_abortsk(delsk->partial_con);
  1113. #if 0
  1114. while (delsk->incoming_con)
  1115. fnet_tcp_abortsk(delsk->incoming_con);
  1116. #endif
  1117. }
  1118. #if !FNET_CFG_TCP_DISCARD_OUT_OF_ORDER
  1119. else
  1120. /* Remove the temporary data.*/
  1121. fnet_tcp_deletetmpbuf(cb);
  1122. #endif
  1123. }
  1124. fnet_isr_unlock();
  1125. }
  1126. /************************************************************************
  1127. * NAME: fnet_tcp_initconnection
  1128. *
  1129. * DESCRIPTION: This function creates and initializes the control block,
  1130. * and initializes the socket.
  1131. *
  1132. * RETURNS: None.
  1133. *************************************************************************/
  1134. static void fnet_tcp_initconnection( fnet_socket_t *sk )
  1135. {
  1136. fnet_tcp_control_t *cb;
  1137. cb = sk->protocol_control;
  1138. fnet_memset_zero(cb, sizeof(fnet_tcp_control_t));
  1139. /* Set the default maximal segment size value.*/
  1140. cb->tcpcb_sndmss = FNET_TCP_DEFAULT_MSS;
  1141. cb->tcpcb_rcvmss = sk->options.tcp_opt.mss;
  1142. /* Set the length of the socket buffers.*/
  1143. cb->tcpcb_rcvcountmax = sk->receive_buffer.count_max;
  1144. /* The input buffer can't be greater than the FNET_TCP_MAX_BUFFER value.*/
  1145. if(cb->tcpcb_rcvcountmax > FNET_TCP_MAX_BUFFER)
  1146. cb->tcpcb_rcvcountmax = FNET_TCP_MAX_BUFFER;
  1147. /* If a segment size greater than the buffer length, recalculate the segment size.*/
  1148. if(cb->tcpcb_rcvcountmax < cb->tcpcb_rcvmss)
  1149. cb->tcpcb_rcvmss = (unsigned short)cb->tcpcb_rcvcountmax;
  1150. /* Receive a scale of the input window.*/
  1151. while(FNET_TCP_MAXWIN << cb->tcpcb_recvscale < cb->tcpcb_rcvcountmax)
  1152. cb->tcpcb_recvscale++;
  1153. /* Stop all timers.*/
  1154. cb->tcpcb_timers.retransmission = FNET_TCP_TIMER_OFF;
  1155. cb->tcpcb_timers.connection = FNET_TCP_TIMER_OFF;
  1156. cb->tcpcb_timers.abort = FNET_TCP_TIMER_OFF;
  1157. cb->tcpcb_timers.round_trip = FNET_TCP_TIMER_OFF;
  1158. cb->tcpcb_timers.persist = FNET_TCP_TIMER_OFF;
  1159. cb->tcpcb_timers.keepalive = FNET_TCP_TIMER_OFF;
  1160. cb->tcpcb_timers.delayed_ack = FNET_TCP_TIMER_OFF;
  1161. /* Initialize the retransmission timeout.*/
  1162. cb->tcpcb_rto = cb->tcpcb_crto = FNET_TCP_TIMERS_INIT;
  1163. #if FNET_CFG_TCP_URGENT
  1164. /* Initialize the receive urgent mark.*/
  1165. cb->tcpcb_rcvurgmark = FNET_TCP_NOT_USED;
  1166. #endif /* FNET_CFG_TCP_URGENT */
  1167. /* Initialize Slow Start Threshold.*/
  1168. cb->tcpcb_ssthresh = FNET_TCP_MAX_BUFFER;
  1169. /* Clear the input buffer.*/
  1170. if(sk->receive_buffer.count)
  1171. fnet_socket_buffer_release(&sk->receive_buffer);
  1172. }
  1173. /************************************************************************
  1174. * NAME: fnet_tcp_inputsk
  1175. *
  1176. * DESCRIPTION: This function processes the input segments of
  1177. * the corresponding socket.
  1178. *
  1179. * RETURNS: TRUE if the input segment must be deleted. Otherwise
  1180. * this function returns FALSE.
  1181. *************************************************************************/
  1182. static int fnet_tcp_inputsk( fnet_socket_t *sk, fnet_netbuf_t *insegment, struct sockaddr *src_addr, struct sockaddr *dest_addr)
  1183. {
  1184. fnet_tcp_control_t *cb = (fnet_tcp_control_t *)sk->protocol_control;
  1185. fnet_tcp_control_t *pcb; /* Pointer to the partial control block.*/
  1186. unsigned char sgmtype; /* Flags of the segment.*/
  1187. fnet_socket_t *psk; /* Pointer to the partial socket.*/
  1188. int result = FNET_TRUE;
  1189. char options[FNET_TCP_MAX_OPT_SIZE];
  1190. char optionlen;
  1191. unsigned long repsize; /* Size of repeated data.*/
  1192. int ackparam = 0; /* Acknowledgment parameter.*/
  1193. unsigned long tcp_seq = fnet_ntohl(FNET_TCP_SEQ(insegment));
  1194. unsigned long tcp_length = (unsigned long)FNET_TCP_LENGTH(insegment);
  1195. unsigned long tcp_ack = fnet_ntohl(FNET_TCP_ACK(insegment));
  1196. /* Get the flags.*/
  1197. sgmtype = (unsigned char)(FNET_TCP_FLAGS(insegment));
  1198. /* Check the sequence number.*/
  1199. switch(cb->tcpcb_connection_state)
  1200. {
  1201. case FNET_TCP_CS_SYN_SENT:
  1202. case FNET_TCP_CS_LISTENING:
  1203. break;
  1204. case FNET_TCP_CS_SYN_RCVD:
  1205. if(cb->tcpcb_prev_connection_state == FNET_TCP_CS_SYN_SENT && (sgmtype & FNET_TCP_SGT_SYN))
  1206. {
  1207. /* Check the sequence number for simultaneouos open.*/
  1208. if(tcp_seq == cb->tcpcb_sndack - 1)
  1209. break;
  1210. }
  1211. default:
  1212. if(FNET_TCP_COMP_G(cb->tcpcb_sndack, tcp_seq))
  1213. {
  1214. if(FNET_TCP_COMP_G(tcp_seq + insegment->total_length - tcp_length, cb->tcpcb_sndack))
  1215. {
  1216. /* Delete the left repeated part.*/
  1217. repsize = fnet_tcp_getsize(tcp_seq, cb->tcpcb_sndack);
  1218. fnet_netbuf_cut_center(&insegment, (int)tcp_length, (int)repsize);
  1219. /* If urgent flag is present, recalculate of the urgent pointer.*/
  1220. if(sgmtype & FNET_TCP_SGT_URG)
  1221. {
  1222. if((int)fnet_ntohs(FNET_TCP_URG(insegment)) - (int)repsize >= 0)
  1223. {
  1224. FNET_TCP_URG(insegment) = fnet_htons((

Large files files are truncated, but you can click here to view the full file