- TCP: set_accept_cb() added; semaphore release bugs fixed
This commit is contained in:
parent
cea600b3a4
commit
ca97d1718a
@ -3,16 +3,16 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../packet_parsers/packet_parsers.h"
|
|
||||||
#include "../../utils.h"
|
|
||||||
#include "../../dynmem.h"
|
#include "../../dynmem.h"
|
||||||
#include "../../pckt_assembler.h"
|
|
||||||
#include "../../eth_interface.h"
|
#include "../../eth_interface.h"
|
||||||
#include "ipv4_connblock.h"
|
|
||||||
#include "../../gen_queue.h"
|
#include "../../gen_queue.h"
|
||||||
#include "etherlib_options.h"
|
|
||||||
#include "../../prefab/conn_blocks/tcp/tcp_window.h"
|
|
||||||
#include "../../global_state.h"
|
#include "../../global_state.h"
|
||||||
|
#include "../../pckt_assembler.h"
|
||||||
|
#include "../../prefab/conn_blocks/tcp/tcp_window.h"
|
||||||
|
#include "../../utils.h"
|
||||||
|
#include "../packet_parsers/packet_parsers.h"
|
||||||
|
#include "etherlib_options.h"
|
||||||
|
#include "ipv4_connblock.h"
|
||||||
|
|
||||||
// TODO: - retransmission hiányzik
|
// TODO: - retransmission hiányzik
|
||||||
// TODO: - állapotváltás esetleg a küldés előtt? (külcsönös kizárás és társai...)
|
// TODO: - állapotváltás esetleg a küldés előtt? (külcsönös kizárás és társai...)
|
||||||
@ -30,14 +30,13 @@ static inline cbd tcp_new_connblock_filtcond(EthInterface *intf, ip4_addr ipAddr
|
|||||||
|
|
||||||
static char *TCP_STATE_NAMES[] = {
|
static char *TCP_STATE_NAMES[] = {
|
||||||
"CLOSED", "LISTEN", "SYN_RCVD", "SYN_SENT", "ESTAB", "FIN_WAIT_1",
|
"CLOSED", "LISTEN", "SYN_RCVD", "SYN_SENT", "ESTAB", "FIN_WAIT_1",
|
||||||
"FIN_WAIT_2", "CLOSE_WAIT", "CLOSING", "LAST_ACK", "TIME_WAIT"
|
"FIN_WAIT_2", "CLOSE_WAIT", "CLOSING", "LAST_ACK", "TIME_WAIT"};
|
||||||
};
|
|
||||||
|
|
||||||
int tcp_send_segment(const struct ConnBlock_ *connBlock, TcpFlag flags, TcpOption *opts, const uint8_t *data, uint32_t size);
|
int tcp_send_segment(const struct ConnBlock_ *connBlock, TcpFlag flags, TcpOption *opts, const uint8_t *data, uint32_t size);
|
||||||
|
|
||||||
static bool filtTcp(const PcktSieveFilterCondition *filtCond, const PcktProps *contProps, const PcktProps *ownProps, EthInterface *intf) {
|
static bool filtTcp(const PcktSieveFilterCondition *filtCond, const PcktProps *contProps, const PcktProps *ownProps, EthInterface *intf) {
|
||||||
IPv4Props *ipProps = (IPv4Props *) contProps;
|
IPv4Props *ipProps = (IPv4Props *)contProps;
|
||||||
TcpProps *tcpProps = (TcpProps *) ownProps;
|
TcpProps *tcpProps = (TcpProps *)ownProps;
|
||||||
|
|
||||||
TCP_EXTRACT_FILTCOND(filtCond);
|
TCP_EXTRACT_FILTCOND(filtCond);
|
||||||
|
|
||||||
@ -56,7 +55,9 @@ static inline TcpState *tcps_create() {
|
|||||||
uint32_t winSize = MAX(ETHLIB_DEF_TCP_WINDOW_SIZE, MAX_TCP_WINDOW_SIZE);
|
uint32_t winSize = MAX(ETHLIB_DEF_TCP_WINDOW_SIZE, MAX_TCP_WINDOW_SIZE);
|
||||||
tcps->txWin = tcpw_create(winSize); // create transmit window
|
tcps->txWin = tcpw_create(winSize); // create transmit window
|
||||||
tcps->txBufNotFull = ETHLIB_OS_SEM_CREATE(1); // create transmit buffer not full semaphore
|
tcps->txBufNotFull = ETHLIB_OS_SEM_CREATE(1); // create transmit buffer not full semaphore
|
||||||
|
ETHLIB_OS_SEM_POST(tcps->txBufNotFull); // post the tx buffer semaphore
|
||||||
tcps->txInProgress = ETHLIB_OS_SEM_CREATE(1); // create transmission in progress semaphore
|
tcps->txInProgress = ETHLIB_OS_SEM_CREATE(1); // create transmission in progress semaphore
|
||||||
|
ETHLIB_OS_SEM_POST(tcps->txInProgress);
|
||||||
|
|
||||||
return tcps;
|
return tcps;
|
||||||
}
|
}
|
||||||
@ -92,7 +93,7 @@ void tcps_init(TcpState *tcps, uint16_t localPort) {
|
|||||||
tcps->remotePort = 0;
|
tcps->remotePort = 0;
|
||||||
tcps->remoteAddr = 0;
|
tcps->remoteAddr = 0;
|
||||||
|
|
||||||
tcps->txSeqNum = (uint32_t) rand();
|
tcps->txSeqNum = (uint32_t)rand();
|
||||||
tcps->rxAckNum = 0;
|
tcps->rxAckNum = 0;
|
||||||
tcps->lastTxSeqNumAcked = tcps->txSeqNum;
|
tcps->lastTxSeqNumAcked = tcps->txSeqNum;
|
||||||
|
|
||||||
@ -114,8 +115,8 @@ void tcps_init(TcpState *tcps, uint16_t localPort) {
|
|||||||
void tcp_init_connection(ConnBlock *connBlock);
|
void tcp_init_connection(ConnBlock *connBlock);
|
||||||
|
|
||||||
static void retry_to_connect_cb(Timer *timer, AlarmUserData user) {
|
static void retry_to_connect_cb(Timer *timer, AlarmUserData user) {
|
||||||
ConnBlock *connBlock = (ConnBlock *) user.ptr;
|
ConnBlock *connBlock = (ConnBlock *)user.ptr;
|
||||||
//tcp_init_connection(connBlock); TODO
|
// tcp_init_connection(connBlock); TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline cbd tcps_create_based_on_listening(const TcpState *source, uint16_t remotePort, ip4_addr remoteAddr, ConnBlock *connBlock) {
|
static inline cbd tcps_create_based_on_listening(const TcpState *source, uint16_t remotePort, ip4_addr remoteAddr, ConnBlock *connBlock) {
|
||||||
@ -147,7 +148,7 @@ static inline cbd tcps_create_based_on_listening(const TcpState *source, uint16_
|
|||||||
}
|
}
|
||||||
|
|
||||||
int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
||||||
TcpState *tcps = (TcpState *) tag.p; // pointer to state is stored in sieve layer tag
|
TcpState *tcps = (TcpState *)tag.p; // pointer to state is stored in sieve layer tag
|
||||||
TcpProps *tcpProps = HEADER_FETCH_PROPS(TcpProps, pckt->header); // fetch header
|
TcpProps *tcpProps = HEADER_FETCH_PROPS(TcpProps, pckt->header); // fetch header
|
||||||
|
|
||||||
TcpConnectionState beginState = tcps->connState;
|
TcpConnectionState beginState = tcps->connState;
|
||||||
@ -205,7 +206,6 @@ int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
|||||||
// step into next state
|
// step into next state
|
||||||
tcps->connState = TCP_STATE_ESTAB;
|
tcps->connState = TCP_STATE_ESTAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -245,7 +245,6 @@ int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
|||||||
tcps->acceptCb(client_d);
|
tcps->acceptCb(client_d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -297,8 +296,8 @@ int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
|||||||
case TCP_STATE_LAST_ACK: /* last ACK received */
|
case TCP_STATE_LAST_ACK: /* last ACK received */
|
||||||
if (tcpProps->Flags & TCP_FLAG_ACK) {
|
if (tcpProps->Flags & TCP_FLAG_ACK) {
|
||||||
tcps->connState = TCP_STATE_CLOSED;
|
tcps->connState = TCP_STATE_CLOSED;
|
||||||
ETHLIB_OS_SEM_POST(tcps->txBufNotFull);
|
//ETHLIB_OS_SEM_POST(tcps->txBufNotFull); FIXME!
|
||||||
ETHLIB_OS_SEM_WAIT(tcps->txInProgress);
|
//ETHLIB_OS_SEM_WAIT(tcps->txInProgress);
|
||||||
ret = SIEVE_LAYER_REMOVE_THIS; // if peer closed the connection, remove sieve layer
|
ret = SIEVE_LAYER_REMOVE_THIS; // if peer closed the connection, remove sieve layer
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -377,6 +376,17 @@ void tcp_listen(cbd d) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcp_set_accept_callback(cbd d, TcpAcceptCbFn acb) {
|
||||||
|
ConnBlock connBlock;
|
||||||
|
if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) {
|
||||||
|
ERROR("Invalid CBD descriptor: '%d'!\n", d);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpState *tcps = TCP_FETCH_STATE_FROM_CONNBLOCK(&connBlock);
|
||||||
|
tcps->acceptCb = acb;
|
||||||
|
}
|
||||||
|
|
||||||
void tcp_debug(cbd d, bool debug) {
|
void tcp_debug(cbd d, bool debug) {
|
||||||
ConnBlock connBlock;
|
ConnBlock connBlock;
|
||||||
if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) {
|
if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) {
|
||||||
@ -447,7 +457,7 @@ int tcp_send_segment(const struct ConnBlock_ *connBlock, TcpFlag flags, TcpOptio
|
|||||||
|
|
||||||
// get TCP state
|
// get TCP state
|
||||||
PcktSieveLayer *layer = connBlock->sieveLayer; // TCP layer
|
PcktSieveLayer *layer = connBlock->sieveLayer; // TCP layer
|
||||||
TcpState *tcpState = (TcpState *) layer->tag.p;
|
TcpState *tcpState = (TcpState *)layer->tag.p;
|
||||||
|
|
||||||
// fetch sieve layers and fill transmit headers
|
// fetch sieve layers and fill transmit headers
|
||||||
tcpProps->SourcePort = tcpState->localPort;
|
tcpProps->SourcePort = tcpState->localPort;
|
||||||
@ -509,8 +519,8 @@ int tcp_send_segment(const struct ConnBlock_ *connBlock, TcpFlag flags, TcpOptio
|
|||||||
// advance TCP sequence number
|
// advance TCP sequence number
|
||||||
tcpState->txSeqNum += size;
|
tcpState->txSeqNum += size;
|
||||||
|
|
||||||
// free headers
|
// free headers
|
||||||
release_resources:
|
release_resources:
|
||||||
dynmem_free(tcpHeader);
|
dynmem_free(tcpHeader);
|
||||||
dynmem_free(ipHeader);
|
dynmem_free(ipHeader);
|
||||||
dynmem_free(ethHeader);
|
dynmem_free(ethHeader);
|
||||||
|
@ -103,7 +103,7 @@ typedef struct {
|
|||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
BlockingFifo * rxFifo; ///< Receive FIFO
|
EthBlockingFifo * rxFifo; ///< Receive FIFO
|
||||||
|
|
||||||
} TcpState;
|
} TcpState;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user