Wiesner András ac5fc9c529 -IP reassembler added
-PcktSieve special return functionality added
-ARP multicast learning bug fixed
-include guards have been refactored
-Doxygen style tweaked
2023-02-04 11:04:26 +01:00

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;
}
}