<commit_before>/*
 * Copyright(C) 2015 <NAME>
 * 
 * This Source Code Form is subject to the terms of the
 * Mozilla Public License, v. 2.0. If a copy of the MPL
 * was not distributed with this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 */
#include <ppe/tcp_control.h>

/*
 * A bitmask for those flags, relevant to TCP connection control.
 */
static const int TCP_CC_RELEVANT = TCPF_FIN|TCPF_SYN|TCPF_RST|TCPF_ACK;

static const int TCP_CC_FINACK = TCPF_FIN|TCPF_ACK;

#define QUEUE_INSERT(queue,element,fnext)   \
	do{                                     \
		element->fnext = 0;                 \
		if( queue.tail ) {                  \
			queue.tail->fnext = element;    \
		}else{                              \
			queue.head = element;           \
			queue.tail = element;           \
		}                                   \
			queue.tail = element;           \
	}while(0)


int ppe_tcpPcb_isAccept(TCP_SegmentInfo *input, TCP_PacketMeta *meta){
	if( ((input->flags)&TCP_CC_RELEVANT) == TCPF_SYN){
		meta->flags = input->flags;
		meta->seq   = input->seq;
		meta->ack   = input->ack;
	}
	return 0;
}

int ppe_tcpPcb_accept(
	TCP_ProtocolControlBlock* pcb,
	TCP_SegmentInfo *output,
	TCP_PacketMeta *meta,
	uint32_t random){
	pcb->phase = TCP_PHASE_ACCEPTING;
	output->flags = TCPF_SYN|TCPF_ACK;
	pcb->rcvSeq = output->ack = meta->seq+1;
	pcb->sndSeq = output->seq = random;
	return 0;
}

int ppe_tcpPcb_connect(
	TCP_ProtocolControlBlock* pcb,
	TCP_SegmentInfo *output,
	uint32_t random){
	pcb->phase = TCP_PHASE_CONNECTING;
	output->flags = TCPF_SYN;
	pcb->sndSeq = output->seq = random;
	return 0;
}


int ppe_tcpPcb_input(TCP_ProtocolControlBlock* pcb,TCP_Segment *input){
	TCP_Segment *output;
	TCP_SegmentInfo *inputHead = &(input->header);
	uintptr_t length = ((input->buffer.limit)-(input->buffer.position));
	int result = 0;
	#define ADDRESULT(x) result|=x
	#define REMRESULT(x) result&=~x
	if(  (inputHead->flags)&TCPF_RST  ){
		pcb->phase = TCP_PHASE_DEAD;
		ADDRESULT(TCPPCB_DEAD);
		QUEUE_INSERT(pcb->free,input,next);
		return result;
	}
	switch(pcb->phase){
	case TCP_PHASE_ESTABLISHED:
		switch( (inputHead->flags) & TCP_CC_RELEVANT ) {
		case TCPF_FIN:
			pcb->phase                = TCP_PHASE_PASSIVE_CLOSE;
			output                    = pcb->alloc(pcb->allocData);
			output->header.localPort  = pcb->localPort;
			output->header.remotePort = pcb->remotePort;
			output->header.flags      = TCPF_ACK;
			output->header.ack        = inputHead->seq+1;
			output->header.seq        = inputHead->ack+1;
			output->header.windowSize = pcb->rcvWnd;
			QUEUE_INSERT(pcb->output,output,next);
			output                    = pcb->alloc(pcb->allocData);
			output->header.localPort  = pcb->localPort;
			output->header.remotePort = pcb->remotePort;
			output->header.flags      = TCPF_FIN;
			output->header.ack        = inputHead->seq+1;
			output->header.seq        = inputHead->ack+1;
			output->header.windowSize = pcb->rcvWnd;
			QUEUE_INSERT(pcb->output,output,next);
			QUEUE_INSERT(pcb->free,input,next);<commit_msg>various fixes<commit_after>/*
 * Copyright(C) 2015 <NAME>
 * 
 * This Source Code Form is subject to the terms of the
 * Mozilla Public License, v. 2.0. If a copy of the MPL
 * was not distributed with this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 */
#include <ppe/tcp_control.h>

/*
 * A bitmask for those flags, relevant to TCP connection control.
 */
static const int TCP_CC_RELEVANT = TCPF_FIN|TCPF_SYN|TCPF_RST|TCPF_ACK;

static const int TCP_CC_FINACK = TCPF_FIN|TCPF_ACK;

#define QUEUE_INSERT(queue,element,fnext)   \
	do{                                     \
		element->fnext = 0;                 \
		if( queue.tail ) {                  \
			queue.tail->fnext = element;    \
		}else{                              \
			queue.head = element;           \
			queue.tail = element;           \
		}                                   \
			queue.tail = element;           \
	}while(0)


int ppe_tcpPcb_isAccept(TCP_SegmentInfo *input, TCP_PacketMeta *meta){
	if( ((input->flags)&TCP_CC_RELEVANT) == TCPF_SYN){
		meta->flags = input->flags;
		meta->seq   = input->seq;
		meta->ack   = input->ack;
	}
	return 0;
}

int ppe_tcpPcb_accept(
	TCP_ProtocolControlBlock* pcb,
	TCP_SegmentInfo *output,
	TCP_PacketMeta *meta,
	uint32_t random){
	pcb->phase = TCP_PHASE_ACCEPTING;
	output->flags = TCPF_SYN|TCPF_ACK;
	pcb->rcvSeq = output->ack = meta->seq+1;
	pcb->sndSeq = output->seq = random;
	return 0;
}

int ppe_tcpPcb_connect(
	TCP_ProtocolControlBlock* pcb,
	TCP_SegmentInfo *output,
	uint32_t random){
	pcb->phase = TCP_PHASE_CONNECTING;
	output->flags = TCPF_SYN;
	pcb->sndSeq = output->seq = random;
	return 0;
}


int ppe_tcpPcb_input(TCP_ProtocolControlBlock* pcb,TCP_Segment *input){
	TCP_Segment *output;
	TCP_SegmentInfo *inputHead = &(input->header);
	uintptr_t length = ((input->packet.limit)-(input->packet.position));
	int result = 0;
	#define ADDRESULT(x) result|=x
	#define REMRESULT(x) result&=~x
	if(  (inputHead->flags)&TCPF_RST  ){
		pcb->phase = TCP_PHASE_DEAD;
		ADDRESULT(TCPPCB_DEAD);
		QUEUE_INSERT(pcb->free,input,next);
		return result;
	}
	switch(pcb->phase){
	case TCP_PHASE_ESTABLISHED:
		switch( (inputHead->flags) & TCP_CC_RELEVANT ) {
		case TCPF_FIN:
			pcb->phase                = TCP_PHASE_PASSIVE_CLOSE;
			output                    = pcb->alloc(pcb->allocData);
			output->header.localPort  = pcb->localPort;
			output->header.remotePort = pcb->remotePort;
			output->header.flags      = TCPF_ACK;
			output->header.ack        = inputHead->seq+1;
			output->header.seq        = inputHead->ack+1;
			output->header.windowSize = pcb->rcvWnd;
			QUEUE_INSERT(pcb->output,output,next);
			output                    = pcb->alloc(pcb->allocData);
			output->header.localPort  = pcb->localPort;
			output->header.remotePort = pcb->remotePort;
			output->header.flags      = TCPF_FIN;
			output->header.ack        = inputHead->seq+1;
			output->header.seq        = inputHead->ack+1;
			output->header.windowSize = pcb->rcvWnd;
			QUEUE_INSERT(pcb->output,output,next);
			QUEUE_INSERT(pcb->free,input,next);
{'fraction_non_alphanumeric': 0.1318717277486911, 'fraction_numerical': 0.007526178010471204, 'mean_word_length': 2.878807106598985, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 123, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7111393', 'n_tokens_mistral': 2366, 'n_tokens_neox': 2198, 'n_words': 404}