NetBurner 3.1
tcp.h
Go to the documentation of this file.
1 /*NB_REVISION*/
2 
3 /*NB_COPYRIGHT*/
4 
14 #ifndef _NB_TCP_H
15 #define _NB_TCP_H
16 
17 #include <ip.h>
18 #include <nettypes.h>
19 
20 /* TCP socket states RFC 793 (Do not change) */
25 #define TCP_STATE_CLOSED (0)
26 #define TCP_STATE_LISTEN (1)
27 #define TCP_STATE_SYN_SENT (2)
28 #define TCP_STATE_SYN_RCVD (3)
29 #define TCP_STATE_WAIT_FOR_ACCEPT (4)
30 #define TCP_STATE_ESTABLISHED (5)
31 #define TCP_STATE_CLOSE_WAIT (6)
32 #define TCP_STATE_LAST_ACK (7)
33 #define TCP_STATE_FIN_WAIT_1 (8)
34 #define TCP_STATE_FIN_WAIT_2 (9)
35 #define TCP_STATE_CLOSING (10)
36 #define TCP_STATE_TIME_WAIT (11)
37 
39 /*********************************************************************/
40 /* The Users interface to TCP. */
41 /*********************************************************************/
42 /* TCP socket status */
47 #define TCP_ERR_NORMAL (0)
48 #define TCP_ERR_TIMEOUT (-1)
49 #define TCP_ERR_NOCON (-2)
50 #define TCP_ERR_CLOSING (-3)
51 #define TCP_ERR_NOSUCH_SOCKET (-4)
52 #define TCP_ERR_NONE_AVAIL (-5)
53 #define TCP_ERR_CON_RESET (-6)
54 #define TCP_ERR_CON_ABORT (-7)
55 
57 /* Any address */
58 #define INADDR_ANY4 IPADDR4::NullIP()
59 
60 #ifdef IPV6
61 #define INADDR_ANY IPADDR6::NullIP()
62 #else
63 #define INADDR_ANY INADDR_ANY4
64 #endif
65 
90 int listen4(IPADDR4 addr, uint16_t port, uint8_t maxpend = 5);
91 
124 int accept4(int listening_socket, IPADDR4 *address, uint16_t *port, uint16_t timeout);
125 
126 // int listenvia(IPADDR addr, uint16_t port, uint8_t maxpend, IPADDR interfaceIpAddress );
127 
128 #ifdef IPV6
129 
153 int listen6(const IPADDR6 &addr, uint16_t port, uint8_t maxpend = 5);
154 
155 inline int listen(const IPADDR6 &addr, uint16_t port, uint8_t maxpend = 5)
156 {
157  return listen6(addr, port, maxpend);
158 };
159 
192 int accept6(int listening_socket, IPADDR6 *address, uint16_t *port, uint16_t timeout);
193 
194 inline int accept(int listening_socket, IPADDR6 *address, uint16_t *port, uint16_t timeout)
195 {
196  return accept6(listening_socket, address, port, timeout);
197 };
198 
199 #else
200 inline int listen(IPADDR4 addr, uint16_t port, uint8_t maxpend = 5)
201 {
202  return listen4(addr, port, maxpend);
203 };
204 inline int accept(int listening_socket, IPADDR4 *address, uint16_t *port, uint16_t timeout)
205 {
206  return accept4(listening_socket, address, port, timeout);
207 };
208 #endif
209 /*
210  ******************************************************************************
211  *
212  * Establishes socket with local port and remote IP address and port.
213  * It by default uses the first network interface but can be optionally
214  * directed to use a specific network interface.
215  *
216  * Parameters:
217  * ipAddress - Remote IP address
218  * localPort - Port for local side of socket
219  * If zero (0) a randomly selected port > 0x8000
220  * will be used.
221  * remotePort - Remote port of socket
222  * timeout - Timeout in ticks
223  * interfaceIpAddress- Network interface IP address to use
224  * If zero (0) it will attempt to use the first
225  * interface associated with the remote IP address
226  * Return:
227  * > 0 is a socket file descriptor (fd).
228  * < 0 error described in NetBurner Runtime Libraries Reference
229  *
230  * ******************************************************************************
231  */
232 
233 int connect4wlocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout);
234 int connect4wlocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout, IPADDR4 interfaceIpAddress);
235 inline int connect4(IPADDR4 ipAddress, uint16_t remotePort, uint32_t timeout)
236 {
237  return connect4wlocal(ipAddress, 0, remotePort, timeout);
238 };
239 
240 inline int connect4wlocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, const TickTimeout &timeout)
241 {
242  return connect4wlocal(ipAddress, localPort, remotePort, timeout.val());
243 };
244 inline int connect4(IPADDR4 ipAddress, uint16_t remotePort, const TickTimeout &timeout)
245 {
246  return connect4wlocal(ipAddress, 0, remotePort, timeout.val());
247 };
248 
249 
250 
273 inline int connect4(IPADDR4 ipAddress, uint16_t remotePort, uint32_t timeout, IPADDR4 interfaceIpAddress)
274 {
275  return connect4wlocal(ipAddress, 0, remotePort, timeout, interfaceIpAddress);
276 };
277 
278 #ifdef IPV6
279 int connect6wlocal(const IPADDR6 &ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout);
280 int connect6wlocal(const IPADDR6 &ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout, const IPADDR6 &interfaceIpAddress);
281 inline int connect6(const IPADDR6 &ipAddress, uint16_t remotePort, uint32_t timeout)
282 {
283  return connect6wlocal(ipAddress, 0, remotePort, timeout);
284 };
285 
308 inline int connect6(const IPADDR6 &ipAddress, uint16_t remotePort, uint32_t timeout, const IPADDR6 &interfaceIpAddress)
309 {
310  return connect6wlocal(ipAddress, 0, remotePort, timeout, interfaceIpAddress);
311 };
312 
313 inline int connectwlocal(const IPADDR6 &ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout)
314 {
315  return connect6wlocal(ipAddress, localPort, remotePort, timeout);
316 };
317 inline int connectwlocal(const IPADDR6 &ipAddress,
318  uint16_t localPort,
319  uint16_t remotePort,
320  uint32_t timeout,
321  const IPADDR6 &interfaceIpAddress)
322 {
323  return connect6wlocal(ipAddress, localPort, remotePort, timeout, interfaceIpAddress);
324 };
325 inline int connect(const IPADDR6 &ipAddress, uint16_t remotePort, uint32_t timeout)
326 {
327  return connect6(ipAddress, remotePort, timeout);
328 };
329 inline int connect(const IPADDR6 &ipAddress, uint16_t remotePort, uint32_t timeout, const IPADDR6 &interfaceIpAddress)
330 {
331  return connect6(ipAddress, remotePort, timeout, interfaceIpAddress);
332 };
333 #else
334 inline int connect(IPADDR4 ipAddress, uint16_t remotePort, uint32_t timeout)
335 {
336  return connect4(ipAddress, remotePort, timeout);
337 };
338 inline int connect(IPADDR4 ipAddress, uint16_t remotePort, uint32_t timeout, IPADDR4 interfaceIpAddress)
339 {
340  return connect4(ipAddress, remotePort, timeout, interfaceIpAddress);
341 };
342 inline int connectwlocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout)
343 {
344  return connect4wlocal(ipAddress, localPort, remotePort, timeout);
345 };
346 inline int connectwlocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, uint32_t timeout, IPADDR4 interfaceIpAddress)
347 {
348  return connect4wlocal(ipAddress, localPort, remotePort, timeout, interfaceIpAddress);
349 };
350 #endif
351 
352 /* Creates the FD and returns immediatly...
353 It returns a TCP socket....
354 To determine if the connection worked you will need to periodically check:
355 
356 TcpGetSocketState(fd)
357 
358 If it is ==TCP_STATE_ESTABLISHED then the socket is ready to use...
359 If it is ==TCP_STATE_SYN_SENT then the socket is still trying to connect...
360 
361 If it is ==TCP_STATE_CLOSING Then either it completly timed out or the other side reset the conenction....
362 
363 IN ALL CASES even if it returns state closing you MUST call close to free the returned fd....
364 */
365 int NoBlockConnect4wLocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, IPADDR4 interfaceIpAddress = IPADDR4::NullIP());
366 
387 inline int NoBlockConnect4(IPADDR4 ipAddress, uint16_t remotePort, IPADDR4 interfaceIpAddress = IPADDR4::NullIP())
388 {
389  return NoBlockConnect4wLocal(ipAddress, 0, remotePort, interfaceIpAddress);
390 };
391 #ifdef IPV6
392 int NoBlockConnect6wLocal(const IPADDR6 &ipAddress, uint16_t localPort, uint16_t remotePort, const IPADDR6 &interfaceIpAddress);
393 
414 inline int NoBlockConnect6(const IPADDR6 &ipAddress, uint16_t remotePort, const IPADDR6 &interfaceIpAddress)
415 {
416  return NoBlockConnect6wLocal(ipAddress, 0, remotePort, interfaceIpAddress);
417 };
418 
419 inline int NoBlockConnect(const IPADDR6 &ipAddress, uint16_t remotePort, const IPADDR6 &interfaceIpAddress = IPADDR6::NullIP())
420 {
421  return NoBlockConnect6wLocal(ipAddress, 0, remotePort, interfaceIpAddress);
422 };
423 #else
424 inline int NoBlockConnectwLocal(IPADDR4 ipAddress, uint16_t localPort, uint16_t remotePort, IPADDR4 interfaceIpAddress = IPADDR4::NullIP())
425 {
426  return NoBlockConnect4wLocal(ipAddress, 0, remotePort, interfaceIpAddress);
427 };
428 inline int NoBlockConnect(IPADDR4 ipAddress, uint16_t remotePort, IPADDR4 interfaceIpAddress = IPADDR4::NullIP())
429 {
430  return NoBlockConnect4wLocal(ipAddress, 0, remotePort, interfaceIpAddress);
431 };
432 #endif
433 
434 int getsocketerror(int fd);
435 
436 /* Socket status functions */
437 
450 IPADDR4 GetSocketRemoteAddr4(int fd);
451 
464 IPADDR4 GetSocketLocalAddr4(int fd);
465 
466 #ifdef IPV6
467 bool bRemoteAddrIsIpV6();
468 bool bLocalAddrIsIpV6();
469 
483 
497 
498 inline IPADDR6 GetSocketRemoteAddr(int fd)
499 {
500  return GetSocketRemoteAddr6(fd);
501 };
502 inline IPADDR6 GetSocketLocalAddr(int fd)
503 {
504  return GetSocketLocalAddr6(fd);
505 };
506 #else
507 inline IPADDR4 GetSocketRemoteAddr(int fd)
508 {
509  return GetSocketRemoteAddr4(fd);
510 };
511 inline IPADDR4 GetSocketLocalAddr(int fd)
512 {
513  return GetSocketLocalAddr4(fd);
514 };
515 #endif
516 
517 
518 
519 
520 
531 uint16_t GetSocketRemotePort(int fd);
532 
543 uint16_t GetSocketLocalPort(int fd);
544 
545 /*----- Keepalive functions -----*/
546 
568 uint32_t TcpGetLastRxTime(int fd);
569 
582 void TcpSendKeepAlive(int fd);
583 
584 /*
585  *****************************************************************************-
586  *
587  * Interval in ticks since last received packet
588  *
589  * Parameters:
590  * socket
591  *
592  * Return:
593  * Interval is ticks from now until the last received packet
594  *
595  * Notes:
596  * Will handle one rollover approx. 6 years but not more than one which
597  * given the timeliness of the use of this function should not matter.
598  *
599  *****************************************************************************-
600  */
612 uint32_t TcpGetLastRxInterval(int fd);
613 
622 int GetTcpRtxCount(int fd); /* return the number of retransmit counts*/
623 
624 // Enable keeping out of order buffers
625 uint8_t SetOutOfOrderbuffers(int fd, uint8_t max);
626 
627 #if defined MULTIHOME || defined AUTOIP
628 
629 int connectvia4(IPADDR4 addr, uint16_t localport, uint16_t remoteport, uint32_t timeout, IPADDR4 ipa);
630 int NoBlockconnectvia4(IPADDR4 addr, uint16_t localport, uint16_t remoteport, IPADDR4 ipa);
631 
632 #ifdef IPV6
633 int connectvia6(const IPADDR6 &addr, uint16_t localport, uint16_t remoteport, uint32_t timeout, const IPADDR6 &ipa);
634 inline int connectvia(const IPADDR6 &addr, uint16_t localport, uint16_t remoteport, uint32_t timeout, const IPADDR6 &ipa)
635 {
636  return connectvia6(addr, localport, remoteport, timeout, ipa);
637 };
638 
639 int NoBlockconnectvia6(IPADDR4 addr, uint16_t localport, uint16_t remoteport, IPADDR4 ipa);
640 inline int NoBlockconnectvia(IPADDR4 addr, uint16_t localport, uint16_t remoteport, IPADDR4 ipa)
641 {
642  return NoBlockconnectvia6(addr, localport, remoteport, ipa);
643 };
644 
645 #else
646 inline int connectvia(IPADDR4 addr, uint16_t localport, uint16_t remoteport, uint32_t timeout, IPADDR4 ipa)
647 {
648  return connectvia4(addr, localport, remoteport, timeout, ipa);
649 };
650 inline int NoBlockconnectvia(IPADDR4 addr, uint16_t localport, uint16_t remoteport, IPADDR4 ipa)
651 {
652  return NoBlockconnectvia4(addr, localport, remoteport, ipa);
653 };
654 #endif
655 #endif
656 
657 /* Get and set the socket options */
658 
663 #define SO_DEBUG 1
664 #define SO_NONAGLE 2
665 #define SO_NOPUSH 4
666 
668 
678 int setsockoption(int fd, int option);
679 
690 int clrsockoption(int fd, int option);
691 
701 int getsockoption(int fd);
702 
703 int setsocketackbuffers(int fd, uint8_t val);
704 int SetSocketRxBuffers(int fd, int n);
705 int SetSocketTxBuffers(int fd, int n);
706 
707 int abortsocket(int fd);
708 int SockReadWithTimeout(int fd, char *buf, int nbytes, uint32_t timeout);
709 
710 
711 
720 char SocketPeek(int fd);
721 
722 
723 void DumpTcpDebug();
724 void EnableTcpDebug(uint16_t dbFlags);
725 
726 /**********************************************************************/
727 /* Internal TCP Definitions */
728 /**********************************************************************/
729 typedef struct
730 {
731  beuint16_t srcPort;
732  beuint16_t dstPort;
733  beuint32_t SeqNumber;
734  beuint32_t AckNumber;
735  uint8_t header_len;
736  uint8_t flags;
737  beuint16_t window;
738  uint16_t csum; // Do not make big endian. csum is calculated as if native
739  beuint16_t urgent;
740  uint8_t DATA[]; // The data field is actually as long as the packet....
741 } TCPPKT;
742 
743 typedef TCPPKT *PTCPPKT;
744 
745 /**********************************************************************/
746 /* Warning WARNING WARNING If you use these functions on an */
747 /* uninitialized buffer you will get bogus values for the pointer */
748 /* As the header length field in the IP packet is not yet set up! */
749 /* Use the GetInitxxx functions instead */
750 /**********************************************************************/
751 
752 inline PTCPPKT GetTcpPkt(PIPPKT pIp)
753 {
754  if (pIp == NULL) { return NULL; }
755  if (pIp->bVerHdrLen == 0x45) { return (PTCPPKT)pIp->DATA; }
756  return (PTCPPKT)(pIp->DATA + (((pIp->bVerHdrLen & 0XF) * 4) - 20));
757 }
758 
759 inline PTCPPKT GetTcpPkt(PoolPtr p)
760 {
761  return GetTcpPkt(GetIpPkt(p));
762 };
763 inline PTCPPKT GetTcpPkt(PEFRAME pFrame)
764 {
765  return GetTcpPkt(GetIpPkt(pFrame));
766 };
767 
768 inline PTCPPKT GetInitTcpPkt4(PIPPKT pIp)
769 {
770  pIp->bVerHdrLen = 0x45;
771  return (PTCPPKT)pIp->DATA;
772 }
773 
774 inline PTCPPKT GetInitTcpPkt4(PoolPtr p)
775 {
776  return GetInitTcpPkt4(GetIpPkt(p));
777 };
778 
779 #ifdef SPEED_TCP
780 typedef void(tcp_data_handler)(int fd, puint8_t data, uint16_t len);
781 void RegisterDataProcessor(int fd, tcp_data_handler *pdh);
782 #endif
783 
784 void InitTCP();
785 
786 // Used by the IP.cpp process packet function
787 void process_tcp4(PoolPtr pp, PIPPKT pIP, uint16_t csum);
788 
789 void DumpTcpDebug();
790 void EnableTcpDebug(uint16_t);
791 void DumpTcpPacket(PIPPKT pIP);
792 
801 int TcpGetSocketInterface(int fd);
802 
811 uint8_t TcpGetSocketState(int fd);
812 
813 /*******************************************************************************
814  *
815  * Get the remaining space in the socket's RX buffer
816  *
817  * Parameters:
818  * socket
819  *
820  * Return:
821  * Bytes of space left in socket's receive buffer
822  *
823  * Notes:
824  * none
825  *
826  *******************************************************************************/
827 uint16_t TcpGetRxBufferSpaceUsed(int fd);
828 
829 /*******************************************************************************
830  *
831  * Get the remaining space in the socket's TX buffer
832  *
833  * Parameters:
834  * socket
835  *
836  * Return:
837  * Bytes of space left in socket's transmit buffer
838  *
839  * Notes:
840  * none
841  *
842  *******************************************************************************/
843 uint16_t TcpGetTxBufferAvailSpace(int fd);
844 
845 /******************************************************************************-
846  *
847  * Check state of socket
848  *
849  * Parameters:
850  * socket
851  *
852  * Return:
853  * True if all sent data has been acknowledged by the other end
854  * of the tcp connection.
855  *
856  * False otherwise.
857  *
858  * Notes:
859  * none
860  *
861  ******************************************************************************/
862 BOOL TcpAllDataAcked(int socket);
863 
864 /******************************************************************************-
865  * Check state of socket
866  *
867  * Parameters:
868  * socket
869  * ticks the number of time ticks to wait. 0==wait for ever
870  *
871  * Return:
872  * True if all sent data has been acknowledged.
873  * False if it timed out.
874  *
875  * False otherwise.
876  *
877  * Notes:
878  * none
879  *
880  ******************************************************************************/
881 BOOL WaitForSocketFlush(int fd, uint32_t ticks);
882 
883 /****************************************************************************
884 
885  Expanded file descriptor callback
886 
887  Parameters:
888  tcpFd - Actual connection file descriptor
889  notifyHandler - Notification callback
890 
891  Return:
892  None
893 
894  Notes:
895  Data arrival or an connection error state calls this routine.
896 
897 ***************************************************************************/
898 typedef void(tcp_notify_handler)(int tcpFd);
899 void RegisterTCPReadNotify(int tcpFd, tcp_notify_handler *notifyHandler);
900 void RegisterTCPWriteNotify(int tcpFd, tcp_notify_handler *notifyHandler);
901 
902 /* associate a void * with tcp */
903 void TCPAssociateExtraData(int tcpFd, void *pData);
904 void *TCPGetExtraData(int tcpFd);
905 
906 #ifndef IPV6
907 #ifndef IPV4ONLY
908 #error Got to pick an IP version
909 #endif
910 #endif
911 
912 #endif /* #ifndef _NB_TCP_H */
uint16_t GetSocketRemotePort(int fd)
Returns the port number of the remote host associated with the connection.
Definition: tcp.cpp:2017
static IPADDR6 NullIP()
Return a null IPADDR6 object.
Definition: ipv6_addr.cpp:334
int getsockoption(int fd)
Returns the options for the specified TCP socket.
Definition: tcp.cpp:3008
int connect6(const IPADDR6 &ipAddress, uint16_t remotePort, uint32_t timeout, const IPADDR6 &interfaceIpAddress)
Connect to a remote IPv6 host.
Definition: tcp.h:308
int GetTcpRtxCount(int fd)
Returns the number of re-transmits that have occured on the specified connection. ...
Definition: tcp.cpp:4231
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition: ipv6_addr.h:28
uint8_t TcpGetSocketState(int fd)
Return the current state of a TCP socket.
Definition: tcp.cpp:4436
uint16_t GetSocketLocalPort(int fd)
Returns the local port number associated with the connection.
Definition: tcp.cpp:2025
TickTimeouts are used to facilitate sequential function calls with timeout parameters that need to in...
Definition: nbrtos.h:112
int connect4(IPADDR4 ipAddress, uint16_t remotePort, uint32_t timeout, IPADDR4 interfaceIpAddress)
Connect to a remote IPv4 host.
Definition: tcp.h:273
int setsockoption(int fd, int option)
Set TCP socket options.
Definition: tcp.cpp:2999
int clrsockoption(int fd, int option)
Clear TCP socket options.
Definition: tcp.cpp:3016
char SocketPeek(int fd)
Returns the next char that would be read, 0 if no data.
Definition: tcp.cpp:3065
IPADDR6 GetSocketRemoteAddr6(int fd)
Returns the IPv6 address of the remote host associated with the specified file descriptor.
Definition: tcp.cpp:1997
int NoBlockConnect6(const IPADDR6 &ipAddress, uint16_t remotePort, const IPADDR6 &interfaceIpAddress)
Create a file descriptior and return immediately, does not wait for connection to complete...
Definition: tcp.h:414
int listen4(IPADDR4 addr, uint16_t port, uint8_t maxpend=5)
Listen for incoming IPv4 connections.
Definition: tcp.cpp:1000
int listen6(const IPADDR6 &addr, uint16_t port, uint8_t maxpend=5)
Listen for incoming IPv6 connections.
Definition: tcp.cpp:1034
uint32_t TcpGetLastRxInterval(int fd)
Returns the number of system Time Ticks since the last packet was received. This is the difference be...
Definition: tcp.cpp:4466
uint32_t val() const
Get the timeout duration to be passed to a function utilizing timeout ticks.
Definition: nbrtos.h:153
int accept4(int listening_socket, IPADDR4 *address, uint16_t *port, uint16_t timeout)
Accept an incoming IPv4 connection from a listening socket.
Definition: tcp.cpp:1151
IPADDR4 GetSocketRemoteAddr4(int fd)
Returns the IPv4 address of the remote host associated with the specified file descriptor.
Definition: tcp.cpp:1984
#define NULL
Definition: nm_bsp.h:76
int TcpGetSocketInterface(int fd)
Return the network interface asociated with a TCP socket.
Definition: tcp.cpp:4942
uint32_t TcpGetLastRxTime(int fd)
Returns the value of system Time Ticks when the last packet was received. Used for the TCP Keep Alive...
Definition: tcp.cpp:4268
void TcpSendKeepAlive(int fd)
Send a TCP keep alive packet to a remote host.
Definition: tcp.cpp:4276
IPADDR4 GetSocketLocalAddr4(int fd)
Returns the IPv4 address of the local interface associated with the connection.
Definition: tcp.cpp:1948
int accept6(int listening_socket, IPADDR6 *address, uint16_t *port, uint16_t timeout)
Accept an incoming IPv6 connection from a listening socket.
Definition: tcp.cpp:1070
IPADDR6 GetSocketLocalAddr6(int fd)
Returns the IPv6 address of the local interface associated with the connection.
Definition: tcp.cpp:2006
int NoBlockConnect4(IPADDR4 ipAddress, uint16_t remotePort, IPADDR4 interfaceIpAddress=IPADDR4::NullIP())
Create a file descriptior and return immediately, does not wait for connection to complete...
Definition: tcp.h:387