EtherLib/prefab/conn_blocks/tcp_connblock.h
Wiesner András 8a5c800fd3 - BlockingFifo implemented
- get_interface_by_address() added
- HTTP server initials added
- code added to strip away padding on processing the IP layer by shrinking overall packet size
- load of TCP fixes and improvements
- TCP stream interface added
- TCP window destroy() added and some bugs fixed
2023-11-22 20:55:50 +01:00

170 lines
5.0 KiB
C

#ifndef ETHERLIB_TCP_CONNBLOCK_H
#define ETHERLIB_TCP_CONNBLOCK_H
#define TCP_EXTRACT_FILTCOND(fc) uint16_t local_port = ((fc)->uw[4]); uint16_t remote_port = ((fc)->uw[5]); ip4_addr remote_addr = ((fc)->u[0])
#define TCP_LOCAL_PORT_TO_FILTCOND(fc, local_port) ((fc)->uw[4]) = (local_port)
#define TCP_REMOTE_PORT_TO_FILTCOND(fc, remote_port) ((fc)->uw[5]) = (remote_port)
#define TCP_REMOTE_ADDR_TO_FILTCOND(fc, remote_addr) ((fc)->u[0] = (remote_addr))
#include <stdint.h>
#include "../packet_parsers/ipv4_types.h"
#include "../../connection_block.h"
#include "../packet_parsers/tcp_segment.h"
#include "../../cbd_table.h"
#include "../conn_blocks/tcp/tcp_window.h"
#include "../../blocking_fifo.h"
#include <etherlib_options.h>
struct EthInterface_;
/**
* TCP segment flags
*/
typedef enum {
TCP_FLAG_FIN = 0x01,
TCP_FLAG_SYN = 0x02,
TCP_FLAG_RESET = 0x04,
TCP_FLAG_PUSH = 0x08,
TCP_FLAG_ACK = 0x10,
TCP_FLAG_URGENT = 0x20,
TCP_FLAG_ECNECHO = 0x40,
TCP_FLAG_CWR = 0x80,
TCP_FLAG_NONCE = 0x100
} TcpFlag;
/**
* TCP connection block states.
*/
typedef enum {
TCP_STATE_CLOSED = 0,
TCP_STATE_LISTEN,
TCP_STATE_SYN_RCVD,
TCP_STATE_SYN_SENT,
TCP_STATE_ESTAB,
TCP_STATE_FIN_WAIT_1,
TCP_STATE_FIN_WAIT_2,
TCP_STATE_CLOSE_WAIT,
TCP_STATE_CLOSING,
TCP_STATE_LAST_ACK,
TCP_STATE_TIME_WAIT
} TcpConnectionState;
typedef int (*StreamCallBackFn)(cbd d);
typedef int (*TcpAcceptCbFn)(cbd d);
/**
* TCP state.
*/
typedef struct {
uint16_t localPort; ///< Local port
uint16_t remotePort; ///< Remote port this CB is bound to
ip4_addr remoteAddr; ///< Remote IP-address this CB is bound to
TcpConnectionState connState; ///< TCP connection state
uint16_t localMSS; ///< Local Maximum Segment Size
uint16_t remoteMSS; ///< Remote Maximum Segment Size
// ---------------
uint32_t txSeqNum; ///< Seq. num of next transmitted octet (TX)
uint32_t rxAckNum; ///< Seq. num of the next EXPECTED octet (RX) (Ack. number sent to the remote side)
uint16_t localWindow; ///< Maximum number of bytes we are willing (able) to accept
uint16_t remoteWindow; ///< Maximum number of bytes the peer is willing (able) to accept
TcpWindow *txWin; ///< Transmit window OBJECT
uint32_t lastTxSeqNumAcked; ///< Last txSeqNum that has received an ACK (used for differentiation between ACK and Keep-Alive segment)
// ---------------
ConnBlock connBlock; ///< Connection block (copy)
cbd d; ///< Connection block descriptor
// ---------------
bool8_t isServer; ///< this connection is a server connection TODO: nem a legjobb elnevezés
// ---------------
uint8_t retryLimit; ///< Maximum number of retransmission reties
uint8_t retries; ///< Current attempts number
uint8_t retryTO; ///< Retry timeout
// ---------------
bool8_t debug; ///< Turns on/off debug mode
// ---------------
StreamCallBackFn streamCb; ///< Callback invoked on stream actions
TcpAcceptCbFn acceptCb; ///< Callback invoked on detecting an incoming connection
// ---------------
ETHLIB_OS_SEM_TYPE txBufNotFull; ///< Semaphore protecting the transmit window
ETHLIB_OS_SEM_TYPE txInProgress; ///< Transmission is in progress, transmit thread is blocked
// ---------------
BlockingFifo * rxFifo; ///< Receive FIFO
} TcpState;
#define TCP_FETCH_STATE_FROM_CONNBLOCK(connBlock) ((TcpState *) (connBlock)->sieveLayer->tag.p)
/**
* Create new TCP connection block
* @param intf associated Ethernet interface
* @param ipAddr local IP-address
* @param port local port
* @param cbFn receive callback function
* @return TCP connection block
*/
cbd tcp_new_connblock(struct EthInterface_ *intf, ip4_addr ipAddr, uint16_t port, StreamCallBackFn cbFn);
/**
* Bind TCP connection to remote socket.
* @param d connection block descriptor
* @param remoteAddr remote socket address
* @param remotePort remote socket port
*/
void tcp_bind(cbd d, ip4_addr remoteAddr, uint16_t remotePort);
/**
* Make the TCP connection listening for incoming connections.
* @param d connection block descriptor
*/
void tcp_listen(cbd d);
/**
* Set callback invoked on detecting an incoming connection on a listening conncetion.
* @param d cbd of the listening connection
* @param acb function pointer of the callback
*/
void tcp_set_accept_callback(cbd d, TcpAcceptCbFn acb);
/**
* Send data over an existing TCP connection.
* @param d pointer to existing connblock
* @param data pointer to data to send
* @param size data size in bytes
* @return number of bytes sent
*/
uint32_t tcp_send(unsigned char d, const uint8_t *data, uint32_t size);
uint32_t tcp_recv(unsigned char d, uint8_t * data, uint32_t size);
/**
* Turn TCP debugging ON/OFF
* @param d
* @param debug
*/
void tcp_debug(cbd d, bool debug);
/**
* Print TCP connblock report.
* @param connBlock TCP connblock
*/
void tcp_print_report(const ConnBlock *connBlock);
//int tcp_send_segment(const struct ConnBlock_ *connBlock, TcpFlag flags, TcpOption * opts, const uint8_t *data, uint32_t size);
#endif //ETHERLIB_TCP_CONNBLOCK_H