-PcktSieve special return functionality added -ARP multicast learning bug fixed -include guards have been refactored -Doxygen style tweaked
70 lines
2.2 KiB
C
70 lines
2.2 KiB
C
//
|
|
// Created by epagris on 2023.01.16..
|
|
//
|
|
|
|
#include <memory.h>
|
|
#include <stdbool.h>
|
|
#include "tcp_window.h"
|
|
#include "../../../dynmem.h"
|
|
|
|
TcpWindow *tcpw_create(uint32_t size) {
|
|
uint32_t allocSize = sizeof(TcpWindow) + size; // calculate full allocation size
|
|
TcpWindow * tcpw = (TcpWindow *) dynmem_alloc(allocSize); // allocate data block at the end
|
|
tcpw->mp = mp_init(tcpw->data, size); // initialize memory pool
|
|
|
|
return tcpw;
|
|
}
|
|
|
|
#define TCP_WINDOW_MAX_WINSIZE_PADDING (16) // keep-out zone, this way allocated blocks will not block registry table growth TODO: not the best solution
|
|
|
|
uint32_t tcpw_get_max_window_size(TcpWindow * tcpw) {
|
|
return mp_largest_free_block_size(tcpw->mp) - sizeof(TcpWindowSegment) - TCP_WINDOW_MAX_WINSIZE_PADDING;
|
|
}
|
|
|
|
TcpWindowSegment * tcpw_store_segment(TcpWindow * tcpw, const uint8_t * data, uint32_t size, uint32_t seqNum) {
|
|
TcpWindowSegment * seg = (TcpWindowSegment *) mp_alloc(tcpw->mp, sizeof(TcpWindowSegment) + size);
|
|
if (seg == NULL) { // could not store...
|
|
return NULL;
|
|
}
|
|
|
|
// store segment descriptor
|
|
seg->size = size;
|
|
seg->seqNum = seqNum;
|
|
|
|
// store segment
|
|
memcpy(seg->data, data, size);
|
|
|
|
// chain-in into linked list of segments
|
|
if (tcpw->firstSeg == NULL) {
|
|
tcpw->firstSeg = tcpw->lastSeg = seg;
|
|
} else {
|
|
tcpw->lastSeg->next = seg;
|
|
}
|
|
|
|
//mp_report(tcpw->mp);
|
|
|
|
return seg;
|
|
}
|
|
|
|
bool tcpw_acknowledge(TcpWindow * tcpw, uint32_t ackNum) {
|
|
if (tcpw->firstSeg == NULL) { // cannot acknowledge if there's nothing to acknowledge
|
|
return false;
|
|
}
|
|
uint32_t segAckNum = tcpw->firstSeg->seqNum + tcpw->firstSeg->size;
|
|
if (segAckNum == ackNum) { // if the acknowledgement number is correct
|
|
TcpWindowSegment * oldFirst = tcpw->firstSeg; // replace first
|
|
TcpWindowSegment * newFirst = oldFirst->next;
|
|
tcpw->firstSeg = newFirst;
|
|
if (newFirst == NULL) { // if the list is empty, also clear pointer to last segment
|
|
tcpw->lastSeg = NULL;
|
|
}
|
|
mp_free(tcpw->mp, (uint8_t *) oldFirst); // release old first segment
|
|
|
|
//mp_report(tcpw->mp);
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|