******************************************************************************/
#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*/
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;
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;
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;
}
}
- 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*/
}
}
- 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;
}
}
/*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;
}
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;
/*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*/
switch(*feat){
case 1:
/*CCID*/
- if(confirm==FALSE){
+ if(confirm==TRUE){
switch(*val){
case 2:
ccid=CCID2;
}
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;
}
void version()
{
- dbgprintf(0, "dccp2tcp version %.1f\nCopyright (C) %i Samuel Jero <sj323707@ohio.edu>\n", DCCP2TCP_VERSION,COPYRIGHT_YEAR);
+ dbgprintf(0, "dccp2tcp version %.1f\n",DCCP2TCP_VERSION);
+ dbgprintf(0, "Copyright (C) %i Samuel Jero <sj323707@ohio.edu>\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);
}
INIT,
OPEN,
CLOSE,
+ DEAD,
+ IGNORE,
};
/*Connection Types (i.e. CCID)*/
/*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);