Skip to content

Commit

Permalink
implemented mssfix
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyu- committed Nov 21, 2017
1 parent 359b989 commit ae735de
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 4 deletions.
2 changes: 1 addition & 1 deletion UDPspeeder
8 changes: 7 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ static void print_help()
// printf(" --disable-xor <number> disable xor\n");

printf("developer options:\n");
printf(" --tun-mtu <number > mtu of the tun interface,most time you shouldnt change this\n");
printf(" --disable-mssfix <number > disable mssfix for tcp connection\n");
printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n");
printf(" --fifo <string> use a fifo(named pipe) for sending commands to the running program, so that you\n");
printf(" can change fec encode parameters dynamically, check readme.md in repository for\n");
printf(" supported commands.\n");
Expand Down Expand Up @@ -114,7 +117,10 @@ int main(int argc, char *argv[])
sprintf(tun_dev,"tun%u",get_true_random_number()%1000);
}
mylog(log_info,"using interface %s\n",tun_dev);

/*if(tun_mtu==0)
{
tun_mtu=g_fec_mtu;
}*/
if(client_or_server==client_mode)
{
tun_dev_client_event_loop();
Expand Down
175 changes: 173 additions & 2 deletions tun_dev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
#include "log.h"
#include "misc.h"

#include <netinet/tcp.h> //Provides declarations for tcp header
#include <netinet/udp.h>
#include <netinet/ip.h> //Provides declarations for ip header
#include <netinet/if_ether.h>


my_time_t last_keep_alive_time=0;

int keep_alive_interval=1000;//1000ms
Expand Down Expand Up @@ -148,6 +154,167 @@ int from_fec_to_normal2(conn_info_t & conn_info,dest_t &dest,char * data,int len

return 0;
}
int do_mssfix(char * s,int len)
{
if(mssfix==0)
{
return 0;
}
if(len<20)
{
mylog(log_debug,"packet from tun len=%d <20\n",len);
return -1;
}
iphdr * iph;
iph = (struct iphdr *) s;
if(iph->protocol!=IPPROTO_TCP)
{
//mylog(log_trace,"not tcp");
return 0;
}

if (!(iph->ihl > 0 && iph->ihl <=60)) {
mylog(log_debug,"iph ihl error ihl= %u\n",(u32_t)iph->ihl);
return -1;
}
int ip_len=ntohs(iph->tot_len);
int ip_hdr_len=iph->ihl*4;
if(len<ip_hdr_len)
{
mylog(log_debug,"len<ip_hdr_len,%d %d\n",len,ip_hdr_len);
return -1;
}
if(len<ip_len)
{
mylog(log_debug,"len<ip_len,%d %d\n",len,ip_len);
return -1;
}
if(ip_hdr_len>ip_len)
{
mylog(log_debug,"ip_hdr_len<ip_len,%d %d\n",ip_hdr_len,ip_len);
return -1;
}

if( ( ntohs(iph->frag_off) &(short)(0x1FFF) ) !=0 )
{
//not first segment

//printf("line=%d %x %x \n",__LINE__,(u32_t)ntohs(iph->frag_off),u32_t( ntohs(iph->frag_off) &0xFFF8));
return 0;
}
if( ( ntohs(iph->frag_off) &(short)(0x80FF) ) !=0 )
{
//not whole segment
//printf("line=%d \n",__LINE__);
return 0;
}

char * tcp_begin=s+ip_hdr_len;
int tcp_len=ip_len-ip_hdr_len;

if(tcp_len<20)
{
mylog(log_debug,"tcp_len<20,%d\n",tcp_len);
return -1;
}

tcphdr * tcph=(struct tcphdr*)tcp_begin;

if(int(tcph->syn)==0) //fast fail
{
mylog(log_trace,"tcph->syn==0\n");
return 0;
}

int tcp_hdr_len = tcph->doff*4;

if(tcp_len<tcp_hdr_len)
{
mylog(log_debug,"tcp_len <tcp_hdr_len, %d %d\n",tcp_len,tcp_hdr_len);
return -1;
}

/*
if(tcp_hdr_len==20)
{
//printf("line=%d\n",__LINE__);
mylog(log_trace,"no tcp option\n");
return 0;
}*/

char *ptr=tcp_begin+20;
char *option_end=tcp_begin+tcp_hdr_len;
while(ptr<option_end)
{
if(*ptr==0)
{
return 0;
}
else if(*ptr==1)
{
ptr++;
}
else if(*ptr==2)
{
if(ptr+1>=option_end)
{
mylog(log_debug,"invaild option ptr+1==option_end,for mss\n");
return -1;
}
if(*(ptr+1)!=4)
{
mylog(log_debug,"invaild mss len\n");
return -1;
}
if(ptr+3>=option_end)
{
mylog(log_debug,"ptr+4>option_end for mss\n");
return -1;
}
int mss= read_u16(ptr+2);//uint8_t(ptr[2])*256+uint8_t(ptr[3]);
int new_mss=mss;
if(new_mss>g_fec_mtu-40)
{
new_mss=g_fec_mtu-40;
}
write_u16(ptr+2,(unsigned short)new_mss);

pseudo_header psh;

psh.source_address =iph->saddr;
psh.dest_address = iph->daddr;
psh.placeholder = 0;
psh.protocol = iph->protocol;
psh.tcp_length = htons(tcp_len);


tcph->check=0;
tcph->check=tcp_csum(psh,(unsigned short *)tcph,tcp_len);

mylog(log_trace,"mss=%d syn=%d ack=%d, changed mss to %d \n",mss,(int)tcph->syn,(int)tcph->ack,new_mss);

//printf("test=%x\n",u32_t(1));
//printf("frag=%x\n",u32_t( ntohs(iph->frag_off) ));

return 0;
}
else
{
if(ptr+1>=option_end)
{
mylog(log_debug,"invaild option ptr+1==option_end\n");
return -1;
}
else
{
//omit check
ptr+=*(ptr+1);
}
}
}

return 0;
}
int do_keep_alive(dest_t & dest)
{
if(get_current_time()-last_keep_alive_time>u64_t(keep_alive_interval))
Expand Down Expand Up @@ -180,7 +347,7 @@ int tun_dev_client_event_loop()
assert(new_connected_socket(remote_fd,remote_ip_uint32,remote_port)==0);
remote_fd64=fd_manager.create(remote_fd);

assert(set_if(tun_dev,htonl((ntohl(sub_net_uint32)&0xFFFFFF00)|2),htonl((ntohl(sub_net_uint32)&0xFFFFFF00 )|1),1500)==0);
assert(set_if(tun_dev,htonl((ntohl(sub_net_uint32)&0xFFFFFF00)|2),htonl((ntohl(sub_net_uint32)&0xFFFFFF00 )|1),tun_mtu)==0);

epoll_fd = epoll_create1(0);
assert(epoll_fd>0);
Expand Down Expand Up @@ -335,6 +502,8 @@ int tun_dev_client_event_loop()
continue;
}

do_mssfix(data,len);

mylog(log_trace,"Received packet from tun,len: %d\n",len);

char header=(got_feed_back==0?header_new_connect:header_normal);
Expand Down Expand Up @@ -449,7 +618,7 @@ int tun_dev_server_event_loop()
assert(tun_fd>0);

assert(new_listen_socket(local_listen_fd,local_ip_uint32,local_port)==0);
assert(set_if(tun_dev,htonl((ntohl(sub_net_uint32)&0xFFFFFF00)|1),htonl((ntohl(sub_net_uint32)&0xFFFFFF00 )|2),1500)==0);
assert(set_if(tun_dev,htonl((ntohl(sub_net_uint32)&0xFFFFFF00)|1),htonl((ntohl(sub_net_uint32)&0xFFFFFF00 )|2),tun_mtu)==0);

epoll_fd = epoll_create1(0);
assert(epoll_fd>0);
Expand Down Expand Up @@ -694,6 +863,8 @@ int tun_dev_server_event_loop()
continue;
}

do_mssfix(data,len);

mylog(log_trace,"Received packet from tun,len: %d\n",len);

if(udp_dest.inner.fd64_ip_port.ip_port.to_u64()==0)
Expand Down

0 comments on commit ae735de

Please sign in to comment.