From d6ede21626f4ad5e298aaa5f63a28bf54b97b40f Mon Sep 17 00:00:00 2001 From: Samuel Jero Date: Tue, 5 Feb 2013 21:05:54 -0500 Subject: [PATCH] Improve connection support by adding DEAD and IGNORE states --- connections.c | 36 +++++++++++++++++++++++++++++------- dccp2tcp.c | 43 +++++++++++++++++++++++++++++++++---------- dccp2tcp.h | 4 +++- 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/connections.c b/connections.c index 4d04d46..732399e 100644 --- a/connections.c +++ b/connections.c @@ -22,9 +22,11 @@ Date: 02/2013 ******************************************************************************/ #include "dccp2tcp.h" +int isClosed(struct hcon *A, struct hcon *B, int pkt_type); + /*Lookup a connection. If it doesn't exist, add a new connection and return it.*/ int get_host(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port, - struct hcon **fwd, struct hcon **rev){ + int pkt_type, struct hcon **fwd, struct hcon **rev){ struct connection *ptr; /*Empty list*/ @@ -41,13 +43,13 @@ int get_host(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest ptr=chead; while(ptr!=NULL){ if(memcmp(ptr->A.id,src_id,id_len)==0 && ptr->A.port==src_port && - !(ptr->A.state==CLOSE && ptr->B.state==CLOSE)){ + !isClosed(&ptr->A, &ptr->B, pkt_type)){ *fwd=&ptr->A; *rev=&ptr->B; return 0; } if(memcmp(ptr->B.id,src_id,id_len)==0 && ptr->B.port==src_port && - !(ptr->B.state==CLOSE && ptr->A.state==CLOSE)){ + !isClosed(&ptr->A, &ptr->B, pkt_type)){ *fwd=&ptr->B; *rev=&ptr->A; return 0; @@ -65,6 +67,25 @@ int get_host(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest return 0; } +/*Returns true if the connection is closed and any packets should go to + * a new connection with the same four-tuple*/ +int isClosed(struct hcon *A, struct hcon *B, int pkt_type){ + if(pkt_type==DCCP_PKT_REQUEST || pkt_type==DCCP_PKT_RESPONSE){ + if(A->state==CLOSE && B->state==CLOSE){ + /*We're opening a new connection on hosts/ports we've used before, mark + * old connection as dead*/ + A->state=DEAD; + B->state=DEAD; + return TRUE; + } + }else{ + if(A->state==DEAD || B->state==DEAD){ + return TRUE; + } + } + return FALSE; +} + /*Add a connection. Return it. On failure, return NULL*/ struct connection *add_connection(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port){ struct connection *ptr; @@ -177,7 +198,7 @@ u_int32_t add_new_seq(struct hcon *hcn, __be32 num, int size, enum dccp_pkt_type while(hcn->table[hcn->cur].old +1 < num && hcn->table[hcn->cur].old +1 > 0){ prev=hcn->cur; if(num - hcn->table[hcn->cur].old +1 <100){ - dbgprintf(1,"Missing Packet: %X\n",hcn->table[prev].new+1); + dbgprintf(1,"Missing Packet %i\n",hcn->table[prev].new+1); } hcn->cur=(hcn->cur+1)%(hcn->size);/*find next available table slot*/ hcn->table[hcn->cur].old=hcn->table[prev].old+1; @@ -228,8 +249,9 @@ u_int32_t convert_ack(struct hcon *hcn, __be32 num, struct hcon *o_hcn) } } - dbgprintf(1, "Error: Address Not Found! looking for: %X. Using highest ACK, %i, instead\n", num, o_hcn->high_ack); -return 0; + dbgprintf(1, "Error: Sequence Number Not Found! looking for %i. Using highest ACK, %i, instead.\n", + num, o_hcn->high_ack); +return o_hcn->high_ack; } /* Get size of packet being acked*/ @@ -252,7 +274,7 @@ int acked_packet_size(struct hcon *hcn, __be32 num) } } - dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num); + dbgprintf(1, "Error: Sequence Number Not Found! looking for %i\n", num); return 0; } diff --git a/dccp2tcp.c b/dccp2tcp.c index db9ca53..488b6f3 100644 --- a/dccp2tcp.c +++ b/dccp2tcp.c @@ -248,8 +248,8 @@ int convert_packet(struct packet *new, const struct const_packet* old) } /*Get Hosts*/ - if(get_host(new->src_id, new->dest_id, new->id_len, - dccph->dccph_sport, dccph->dccph_dport, &h1, &h2)){ + if(get_host(new->src_id, new->dest_id, new->id_len, dccph->dccph_sport, + dccph->dccph_dport, dccph->dccph_type,&h1, &h2)){ dbgprintf(0,"Error: Can't Get Hosts!\n"); return 0; } @@ -257,6 +257,11 @@ int convert_packet(struct packet *new, const struct const_packet* old) dbgprintf(0, "Error: Can't Get Hosts!\n"); return 0; } + if(h1->state==IGNORE || h2->state==IGNORE){ + dbgprintf(2, "Ignoring packet between %i and %i\n", + ntohs(dccph->dccph_sport), ntohs(dccph->dccph_dport)); + return 0; + } /*set TCP standard features*/ tcph->source=dccph->dccph_sport; @@ -954,12 +959,20 @@ int parse_options(const u_char* opt_start, int len, struct hcon* A, struct hcon* /*Ack Vector Option*/ if(*opt==38 || *opt==39){ - + if(B->type==UNKNOWN){ + B->type=CCID2; + dbgprintf(1,"Half-connection from port %i to %i probably using CCID 2\n", + ntohs(B->port),ntohs(A->port)); + } } /*NDP Count Option*/ if(*opt==37){ - + if(B->type==UNKNOWN){ + B->type=CCID3; + dbgprintf(1,"Half-connection from port %i to %i probably using CCID 3\n", + ntohs(B->port),ntohs(A->port)); + } } /*Feature negotation*/ @@ -1005,7 +1018,7 @@ int process_feature(const u_char* feat, int len, int confirm, int L, struct hcon switch(*feat){ case 1: /*CCID*/ - if(confirm==FALSE){ + if(confirm==TRUE){ switch(*val){ case 2: ccid=CCID2; @@ -1019,16 +1032,24 @@ int process_feature(const u_char* feat, int len, int confirm, int L, struct hcon } if(L==TRUE){ B->type=ccid; + dbgprintf(1,"Half-connection from port %i to %i using CCID %i\n", + ntohs(B->port),ntohs(A->port), *val); }else{ A->type=ccid; + dbgprintf(1,"Half-connection from port %i to %i using CCID %i\n", + ntohs(A->port),ntohs(B->port), *val); } } break; case 2: /*Short sequence nums*/ - if(confirm==FALSE && *val==1){ - dbgprintf(0,"Error! DCCP is trying to turn on short sequence numbers! We do not support this!!\n"); - exit(1); + if(confirm==TRUE && *val==1){ + B->type=IGNORE; + A->type=IGNORE; + dbgprintf(0,"Error: DCCP is trying to turn on short sequence numbers\n" + " for the connection between %i and %i. We do not support this.\n" + " This connection will be ignored.",ntohs(A->port),ntohs(B->port)); + return 0; } break; } @@ -1157,9 +1178,11 @@ return; void version() { - dbgprintf(0, "dccp2tcp version %.1f\nCopyright (C) %i Samuel Jero \n", DCCP2TCP_VERSION,COPYRIGHT_YEAR); + dbgprintf(0, "dccp2tcp version %.1f\n",DCCP2TCP_VERSION); + dbgprintf(0, "Copyright (C) %i Samuel Jero \n",COPYRIGHT_YEAR); dbgprintf(0, "This program comes with ABSOLUTELY NO WARRANTY.\n"); - dbgprintf(0, "This is free software, and you are welcome to\nredistribute it under certain conditions.\n"); + dbgprintf(0, "This is free software, and you are welcome to\n"); + dbgprintf(0, "redistribute it under certain conditions.\n"); exit(0); } diff --git a/dccp2tcp.h b/dccp2tcp.h index dafaeac..3a071a6 100644 --- a/dccp2tcp.h +++ b/dccp2tcp.h @@ -84,6 +84,8 @@ enum con_state{ INIT, OPEN, CLOSE, + DEAD, + IGNORE, }; /*Connection Types (i.e. CCID)*/ @@ -142,7 +144,7 @@ int do_encap(int link, struct packet *new, const struct const_packet *old); /*Connection functions*/ int get_host(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port, - struct hcon **fwd, struct hcon **rev); + int pkt_type, struct hcon **fwd, struct hcon **rev); struct connection *add_connection(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port); int update_state(struct hcon* hst, enum con_state st); -- 2.39.2