diff --git a/README.md b/README.md index 8d9f0e8..24b8de6 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,17 @@ or [简体中文](/doc/README.zh-cn.md)(内容更丰富) ###### Note -You can use udp2raw with UDPspeeder together to bypass UDP firewalls. -udp2raw:https://github.com/wangyu-/udp2raw-tunnel +You can use udp2raw with UDPspeeder together to get better speed on some ISP with UDP QoS(UDP throttling). + +udp2raw's repo: + +https://github.com/wangyu-/udp2raw-tunnel + +You can also try tinyFecVPN, a lightweight high-performance VPN with build-in FEC support: + +tinyFecVPN's repo: + +https://github.com/wangyu-/tinyFecVPN # Efficacy @@ -73,7 +82,7 @@ Now connecting to UDP port 3333 at the client side is equivalent to connecting t `-f20:10` means sending 10 redundant packets for every 20 original packets. -`-k` enables simple XOR encryption to confuse DPI(Deep Packet Inspection) +`-k` enables simple XOR encryption To run stably, pay attention to MTU. diff --git a/common.cpp b/common.cpp index eccd4d8..2af6699 100644 --- a/common.cpp +++ b/common.cpp @@ -260,6 +260,39 @@ unsigned short csum(const unsigned short *ptr,int nbytes) { return(answer); } + + +unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes) {//works both for big and little endian + + register long sum; + unsigned short oddbyte; + register short answer; + + sum=0; + unsigned short * tmp= (unsigned short *)&ph; + for(int i=0;i<6;i++) + { + sum+=*tmp++; + } + + + while(nbytes>1) { + sum+=*ptr++; + nbytes-=2; + } + if(nbytes==1) { + oddbyte=0; + *((u_char*)&oddbyte)=*(u_char*)ptr; + sum+=oddbyte; + } + + sum = (sum>>16)+(sum & 0xffff); + sum = sum + (sum>>16); + answer=(short)~sum; + + return(answer); +} + int set_buf_size(int fd,int socket_buf_size,int force_socket_buf) { if(force_socket_buf) diff --git a/common.h b/common.h index ee4267e..403b0e4 100644 --- a/common.h +++ b/common.h @@ -176,6 +176,13 @@ struct fd_info_t ip_port_t ip_port; }; +struct pseudo_header { + u_int32_t source_address; + u_int32_t dest_address; + u_int8_t placeholder; + u_int8_t protocol; + u_int16_t tcp_length; +}; u64_t get_current_time(); u64_t get_current_time_us(); @@ -209,6 +216,7 @@ void setnonblocking(int sock); int set_buf_size(int fd,int socket_buf_size,int force_socket_buf=0); unsigned short csum(const unsigned short *ptr,int nbytes); +unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes); void signal_handler(int sig); int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len); diff --git a/doc/README.zh-cn.md b/doc/README.zh-cn.md index 8d0afd1..f0f3ce1 100644 --- a/doc/README.zh-cn.md +++ b/doc/README.zh-cn.md @@ -11,9 +11,21 @@ ![image0](/images/Capture2.PNG) -另外,可以和udp2raw串联使用,在加速的同时把UDP伪装成TCP,防止UDP被运营商QOS或屏蔽。udp2raw: https://github.com/wangyu-/udp2raw-tunnel +对于某些运营商,UDPspeeder跟udp2raw配合可以达到更好的速度,udp2raw负责把UDP伪装成TCP,来绕过运营商的UDP限速。 + +udp2raw的repo: + +https://github.com/wangyu-/udp2raw-tunnel + +如果你嫌UDPspeeder+OpenVPN麻烦,你可以尝试tinyFecVPN,一个集成了UDPspeeder功能的VPN: + +tinyFecVPN的repo: + +https://github.com/wangyu-/tinyFecVPN + + #### 效果 -![image0](/images/Capture8.PNG) +![image0](/images/cn/ping_compare_cn.PNG) ![image0](/images/cn/scp_compare.PNG) #### 原理简介 @@ -67,7 +79,7 @@ https://github.com/wangyu-/UDPspeeder/releases `-f20:10` 表示对每20个原始数据发送10个冗余包。`-f20:10` 和`-f 20:10`都是可以的,空格可以省略,对于所有的单字节option都是如此。对于双字节option,例如后面的`--mode 0`和`--mtu 1200`,空格不可以省略。 -`-k` 指定一个字符串,server/client间所有收发的包都会被异或,改变协议特征,防止UDPspeeder的协议被运营商针对。 +`-k` 指定一个字符串,开启简单的异或加密 ###### 注意 @@ -165,8 +177,6 @@ mode 0模式允许你发送的数据包大小超过物理接口的MTU而几乎 ##### `--disable-obscure` UDPspeeder默认情况下会对每个发出的数据包随机填充和异或一些字节(4~32字节),这样通过抓包难以发现你发了冗余数据,防止VPS被封。这个功能只是为了小心谨慎,即使你关掉这个功能,基本上也没问题,关掉可以省一些带宽和CPU。 -##### `-q,--queue-len` -编码器在做FEC前最多积攒多少个数据包,只对mode 0有效。除非是使用下文`V2版如何多倍发包`里面提到的用法,不建议改动。 #### `--fifo` option 用fifo(命名管道)向运行中的程序发送command。例如`--fifo fifo.file`,可用的command有: ``` @@ -190,16 +200,16 @@ echo mode 0 > fifo.file ### V2版如何多倍发包 -只要在设置-f参数时把x设置为1,fec算法就退化为多倍发包了。例如-f1:1,表示2倍发包,-f1:2表示3倍发包,以此类推。另外可以加上`--mode 0 -q1`参数,防止fec编码器试图积攒和合并数据,获得最低的延迟。 +只要在设置-f参数时把x设置为1,fec算法就退化为多倍发包了。例如-f1:1,表示2倍发包,-f1:2表示3倍发包,以此类推。另外建议加上"--mode 1"参数,防止fec编码器试图积攒和合并数据,获得最低的延迟。 2倍发包的完整参数: ``` -./speederv2 -s -l0.0.0.0:4096 -r127.0.0.1:7777 -f1:1 -k "passwd" --mode 0 -q1 -./speederv2 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -f1:1 -k "passwd" --mode 0 -q1 +./speederv2 -s -l0.0.0.0:4096 -r127.0.0.1:7777 -f1:1 -k "passwd" --mode 1 +./speederv2 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -f1:1 -k "passwd" --mode 1 ``` -使用了`--mode 0 -q1`以后,`--timeout`选项不起作用,所以不用调。 +使用了`--mode 1`以后,`--timeout`选项不起作用,所以不用调。 如果你只需要多倍发包,可以直接用回V1版,V1版配置更简单,占用内存更小,而且经过了几个月的考验,很稳定。 @@ -227,9 +237,9 @@ FEC算法很吃CPU,初次使用建议关注UDPspeeder的CPU占用。如果CPU ### 为什么使用之后效果反而变差了? -有可能是你用了mode 0参数,而又没调好参数。 +有可能是你用了`--mode 0`参数,而又没调好参数。 -如果你没有使用mode 0,而确实效果变差了,那很可能是因为你的运营商对UDP有限制。一般看视频和下载都是TCP流量,而用UDPspeeder中转后流量变成了UDP流量,如果运营商对UDP做了限制,就可能导致效果比不用还差。用udp2raw可以解决,udp2raw: https://github.com/wangyu-/udp2raw-tunnel +如果你没有使用`--mode 0`,而确实效果变差了,那很可能是因为你的运营商对UDP有限制。一般看视频和下载都是TCP流量,而用UDPspeeder中转后流量变成了UDP流量,如果运营商对UDP做了限制,就可能导致效果比不用还差。用udp2raw可以解决,udp2raw: https://github.com/wangyu-/udp2raw-tunnel ### UDPspeeder和BBR/锐速配合 @@ -255,12 +265,18 @@ UDPspeeder和Kcptun配合,UDPspeeder和Kcptun可以并联也可以串联。 #### UDPspeeder + OpenVPN加速任何流量,也适用于其他VPN ![image0](/images/Capture2.PNG) -具体配置见,[UDPspeeder + openvpn config guide](/doc/udpspeeder_openvpn.md). - 可以和BBR/锐速叠加,不过BBR/锐速部署在VPS上只对从本地到VPS的流量有效,对从本地到第三方服务器的流量无效。 需要在服务端开启ipforward和NAT。在客户端改路由表(可以手动修改,也可以由OpenVPN的redirect-gateway选项自动加好)。 +Linux具体配置: [UDPspeeder + openvpn config guide](/doc/udpspeeder_openvpn.md). + +Windows具体配置: [win10系统UDPspeeder+OpenVPN的完整设置](https://github.com/wangyu-/UDPspeeder/wiki/win10系统UDPspeeder-OpenVPN的完整设置) + +如果UDPspeeder + OpenVPN对你来说显得太麻烦了,你可以尝试一下tinyFecVPN,一个集成了UDPspeeder功能的VPN: + +https://github.com/wangyu-/tinyFecVPN/ + #### UDPspeeder + kcptun/finalspeed + $*** 同时加速tcp和udp流量 如果你需要用加速的tcp看视频和下载文件,这样效果可能比没有BBR的UDPspeeder+vpn方案更好。另外,如果你需要玩游戏,但是嫌配VPN麻烦,也可以用这种方案。 ![image0](/images/cn/speeder_kcptun.PNG) @@ -281,9 +297,9 @@ run at client side: 这就是全部的命令了。issue里有很多人困惑于怎么把tcp和udp流量"分开",其实很简单就可以做到。 -如果只需要加速UDP,不需要加速TCP,可以把kcptun换成其他的任意端口转发方式,比如ncat/socat/ssh tunnel/iptables。 +如果只需要加速UDP,不需要加速TCP,可以把kcptun换成其他的任意端口转发方式,比如ncat/socat/ssh tunnel/iptables/[tinyPortMapper](https://github.com/wangyu-/tinyPortMapper/releases)。 -另外,如果没有kcptun只有BBR/锐速的话,也可以把kcptun换成ncat/socat/ssh tunnel/iptables。这样,TCP流量由锐速/BBR加速,UDP由UDPspeeder加速。 +另外,如果没有kcptun只有BBR/锐速的话,也可以把kcptun换成ncat/socat/ssh tunnel/iptables/[tinyPortMapper](https://github.com/wangyu-/tinyPortMapper/releases)。这样,TCP流量由锐速/BBR加速,UDP由UDPspeeder加速。 #### UDPspeeder + openvpn + $*** 混合方案,也适用于其他VPN 也是我正在用的方案。优点是可以随时在vpn和$\*\*\*方案间快速切换。 @@ -295,6 +311,20 @@ run at client side: 可以和BBR/锐速叠加,BBR/锐速只要部署在VPS上就有效。 +也可以用[tinyFecVPN](https://github.com/wangyu-/tinyFecVPN/) + $\*\*\* ,配置起来更简单。 + +# 应用实例 + +#### win10系统UDPspeeder+OpenVPN的完整设置 + +https://github.com/wangyu-/UDPspeeder/wiki/win10系统UDPspeeder-OpenVPN的完整设置 + + +#### 用树莓派做路由器,搭建透明代理,加速游戏主机的网络 + +https://github.com/wangyu-/UDPspeeder/wiki/用树莓派做路由器,搭建透明代理,加速游戏主机的网络 + + # 编译教程 暂时先参考udp2raw的这篇教程,几乎一样的过程。 diff --git a/doc/udpspeeder_openvpn.md b/doc/udpspeeder_openvpn.md index e27ac8e..3b4a436 100644 --- a/doc/udpspeeder_openvpn.md +++ b/doc/udpspeeder_openvpn.md @@ -100,3 +100,8 @@ or ip route add 44.55.66.77 dev XXX ``` (run at client side) + +##### Other Info +You can also use tinyFecVPN,a lightweight VPN with build-in FEC support: + +https://github.com/wangyu-/tinyFecVPN diff --git a/fec_manager.cpp b/fec_manager.cpp index 693cf8a..46747f6 100644 --- a/fec_manager.cpp +++ b/fec_manager.cpp @@ -218,10 +218,14 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/) //int counter_back=counter; assert(fec_mode==0||fec_mode==1); - if(fec_mode==0&& s!=0 &&counter==0&&blob_encode.get_shard_len(fec_data_num,len)>fec_mtu) + if(fec_mode==0&& s!=0 &&counter==0) { - mylog(log_warn,"message too long len=%d,ignored\n",len); - return -1; + int out_len=blob_encode.get_shard_len(fec_data_num,len); + if(out_len>fec_mtu) + { + mylog(log_warn,"message too long ori_len=%d out_len=%d fec_mtu=%d,ignored\n",len,out_len,fec_mtu); + return -1; + } } if(fec_mode==1&&s!=0&&len>fec_mtu) { diff --git a/images/cn/ping_compare_cn.PNG b/images/cn/ping_compare_cn.PNG new file mode 100644 index 0000000..976bb4c Binary files /dev/null and b/images/cn/ping_compare_cn.PNG differ diff --git a/main.cpp b/main.cpp index 76f6c0a..ec1f622 100644 --- a/main.cpp +++ b/main.cpp @@ -10,9 +10,69 @@ #include "misc.h" #include "tunnel.h" //#include "tun_dev.h" +#include "git_version.h" using namespace std; +static void print_help() +{ + char git_version_buf[100]={0}; + strncpy(git_version_buf,gitversion,10); + + printf("UDPspeeder V2\n"); + printf("git version: %s ",git_version_buf); + printf("build date: %s %s\n",__DATE__,__TIME__); + printf("repository: https://github.com/wangyu-/UDPspeeder\n"); + printf("\n"); + printf("usage:\n"); + printf(" run as client: ./this_program -c -l local_listen_ip:local_port -r server_ip:server_port [options]\n"); + printf(" run as server: ./this_program -s -l server_listen_ip:server_port -r remote_ip:remote_port [options]\n"); + printf("\n"); + printf("common options, must be same on both sides:\n"); + printf(" -k,--key key for simple xor encryption. if not set, xor is disabled\n"); + + printf("main options:\n"); + printf(" -f,--fec x:y forward error correction, send y redundant packets for every x packets\n"); + printf(" --timeout how long could a packet be held in queue before doing fec, unit: ms, default: 8ms\n"); + printf(" --mode fec-mode,available values: 0, 1; 0 cost less bandwidth, 1 cost less latency(default)\n"); + printf(" --report turn on send/recv report, and set a period for reporting, unit: s\n"); + + printf("advanced options:\n"); + printf(" --mtu mtu. for mode 0, the program will split packet to segment smaller than mtu_value.\n"); + printf(" for mode 1, no packet will be split, the program just check if the mtu is exceed.\n"); + printf(" default value: 1250\n"); + printf(" -j,--jitter simulated jitter. randomly delay first packet for 0~ ms, default value: 0.\n"); + printf(" do not use if you dont know what it means.\n"); + printf(" -i,--interval scatter each fec group to a interval of ms, to protect burst packet loss.\n"); + printf(" default value: 0. do not use if you dont know what it means.\n"); + printf(" --random-drop simulate packet loss, unit: 0.01%%. default value: 0\n"); + printf(" --disable-obscure disable obscure, to save a bit bandwidth and cpu\n"); +// printf(" --disable-xor disable xor\n"); + + printf("developer options:\n"); + printf(" --fifo 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"); + printf(" -j ,--jitter jmin:jmax similiar to -j above, but create jitter randomly between jmin and jmax\n"); + printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n"); + printf(" -q,--queue-len max fec queue len, only for mode 0\n"); + printf(" --decode-buf size of buffer of fec decoder,u nit: packet, default: 2000\n"); + printf(" --fix-latency try to stabilize latency, only for mode 0\n"); + printf(" --delay-capacity max number of delayed packets\n"); + printf(" --disable-fec completely disable fec, turn the program into a normal udp tunnel\n"); + printf(" --sock-buf buf size for socket, >=10 and <=10240, unit: kbyte, default: 1024\n"); + printf("log and help options:\n"); + printf(" --log-level 0: never 1: fatal 2: error 3: warn \n"); + printf(" 4: info (default) 5: debug 6: trace\n"); + printf(" --log-position enable file name, function name, line number in log\n"); + printf(" --disable-color disable log color\n"); + printf(" -h,--help print this help message\n"); + + //printf("common options,these options must be same on both side\n"); +} + + + int main(int argc, char *argv[]) { //working_mode=tunnel_mode; @@ -25,6 +85,22 @@ int main(int argc, char *argv[]) assert(sizeof(i16_t)==2); dup2(1, 2); //redirect stderr to stdout int i, j, k; + + if (argc == 1) + { + print_help(); + myexit( -1); + } + for (i = 0; i < argc; i++) + { + if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0) + { + print_help(); + myexit(0); + } + } + + process_arg(argc,argv); delay_manager.set_capacity(delay_capacity); diff --git a/misc.cpp b/misc.cpp index 0a1a6b2..c387599 100644 --- a/misc.cpp +++ b/misc.cpp @@ -40,12 +40,18 @@ int time_mono_test=0; int delay_capacity=0; -char sub_net[100]="10.0.0.0"; +char sub_net[100]="10.22.22.0"; u32_t sub_net_uint32=0; char tun_dev[100]=""; +int keep_reconnect=0; + +int tun_mtu=1500; + +int mssfix=1; + int from_normal_to_fec(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay) { @@ -566,15 +572,14 @@ void process_arg(int argc, char *argv[]) {"jitter", required_argument, 0,'j'}, {"fifo", required_argument, 0, 1}, {"sub-net", required_argument, 0, 1}, - {"tun-dev", optional_argument, 0, 1}, + {"tun-dev", required_argument, 0, 1}, + {"tun-mtu", required_argument, 0, 1}, + {"disable-mssfix", no_argument, 0, 1}, + {"keep-reconnect", no_argument, 0, 1}, {NULL, 0, 0, 0} }; int option_index = 0; - if (argc == 1) - { - print_help(); - myexit( -1); - } + for (i = 0; i < argc; i++) { if(strcmp(argv[i],"--unit-test")==0) @@ -583,14 +588,7 @@ void process_arg(int argc, char *argv[]) myexit(0); } } - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0) - { - print_help(); - myexit(0); - } - } + for (i = 0; i < argc; i++) { if(strcmp(argv[i],"--log-level")==0) @@ -621,11 +619,6 @@ void process_arg(int argc, char *argv[]) } log_bare(log_info, "\n"); - if (argc == 1) - { - print_help(); - myexit(-1); - } int no_l = 1, no_r = 1; while ((opt = getopt_long(argc, argv, "l:r:hcsk:j:f:p:n:i:q:",long_options,&option_index)) != -1) @@ -884,6 +877,11 @@ void process_arg(int argc, char *argv[]) mylog(log_info,"fifo_file =%s \n",fifo_file); } + else if(strcmp(long_options[option_index].name,"keep-reconnect")==0) + { + keep_reconnect=1; + mylog(log_info,"keep_reconnect enabled\n"); + } else if(strcmp(long_options[option_index].name,"sub-net")==0) { sscanf(optarg,"%s",sub_net); @@ -892,14 +890,22 @@ void process_arg(int argc, char *argv[]) } else if(strcmp(long_options[option_index].name,"tun-dev")==0) { - if(optarg!=0) - { - sscanf(optarg,"%s",tun_dev); - mylog(log_info,"tun_dev =%s \n",tun_dev); - } + sscanf(optarg,"%s",tun_dev); + mylog(log_info,"tun_dev=%s\n",tun_dev); + mylog(log_info,"running at tun-dev mode\n"); working_mode=tun_dev_mode; } + else if(strcmp(long_options[option_index].name,"tun-mtu")==0) + { + sscanf(optarg,"%d",&tun_mtu); + mylog(log_warn,"changed tun_mtu,tun_mtu=%d\n",tun_mtu); + } + else if(strcmp(long_options[option_index].name,"disable-mssfix")==0) + { + mssfix=0; + mylog(log_warn,"mssfix disabled\n"); + } else { mylog(log_fatal,"unknown option\n"); @@ -959,60 +965,3 @@ void process_arg(int argc, char *argv[]) } -void print_help() -{ - char git_version_buf[100]={0}; - strncpy(git_version_buf,gitversion,10); - - printf("UDPspeeder V2\n"); - printf("git version: %s ",git_version_buf); - printf("build date: %s %s\n",__DATE__,__TIME__); - printf("repository: https://github.com/wangyu-/UDPspeeder\n"); - printf("\n"); - printf("usage:\n"); - printf(" run as client: ./this_program -c -l local_listen_ip:local_port -r server_ip:server_port [options]\n"); - printf(" run as server: ./this_program -s -l server_listen_ip:server_port -r remote_ip:remote_port [options]\n"); - printf("\n"); - printf("common options, must be same on both sides:\n"); - printf(" -k,--key key for simple xor encryption. if not set, xor is disabled\n"); - - printf("main options:\n"); - printf(" -f,--fec x:y forward error correction, send y redundant packets for every x packets\n"); - printf(" --timeout how long could a packet be held in queue before doing fec, unit: ms, default: 8ms\n"); - printf(" --mode fec-mode,available values: 0, 1; 0 cost less bandwidth, 1 cost less latency(default)\n"); - printf(" --report turn on send/recv report, and set a period for reporting, unit: s\n"); - - printf("advanced options:\n"); - printf(" --mtu mtu. for mode 0, the program will split packet to segment smaller than mtu_value.\n"); - printf(" for mode 1, no packet will be split, the program just check if the mtu is exceed.\n"); - printf(" default value: 1250\n"); - printf(" -j,--jitter simulated jitter. randomly delay first packet for 0~ ms, default value: 0.\n"); - printf(" do not use if you dont know what it means.\n"); - printf(" -i,--interval scatter each fec group to a interval of ms, to protect burst packet loss.\n"); - printf(" default value: 0. do not use if you dont know what it means.\n"); - printf(" --random-drop simulate packet loss, unit: 0.01%%. default value: 0\n"); - printf(" --disable-obscure disable obscure, to save a bit bandwidth and cpu\n"); -// printf(" --disable-xor disable xor\n"); - - printf("developer options:\n"); - printf(" --fifo 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"); - printf(" -j ,--jitter jmin:jmax similiar to -j above, but create jitter randomly between jmin and jmax\n"); - printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n"); - printf(" -q,--queue-len max fec queue len, only for mode 0\n"); - printf(" --decode-buf size of buffer of fec decoder,u nit: packet, default: 2000\n"); - printf(" --fix-latency try to stabilize latency, only for mode 0\n"); - printf(" --delay-capacity max number of delayed packets\n"); - printf(" --disable-fec completely disable fec, turn the program into a normal udp tunnel\n"); - printf(" --sock-buf buf size for socket, >=10 and <=10240, unit: kbyte, default: 1024\n"); - printf("log and help options:\n"); - printf(" --log-level 0: never 1: fatal 2: error 3: warn \n"); - printf(" 4: info (default) 5: debug 6: trace\n"); - printf(" --log-position enable file name, function name, line number in log\n"); - printf(" --disable-color disable log color\n"); - printf(" -h,--help print this help message\n"); - - //printf("common options,these options must be same on both side\n"); -} - diff --git a/misc.h b/misc.h index 0c9ee24..91322fa 100644 --- a/misc.h +++ b/misc.h @@ -13,7 +13,7 @@ #include "fd_manager.h" #include "delay_manager.h" #include "fec_manager.h" -#include "git_version.h" + extern char fifo_file[1000]; @@ -46,6 +46,12 @@ extern int time_mono_test; extern int delay_capacity; +extern int keep_reconnect; + +extern int tun_mtu; + +extern int mssfix; + int from_normal_to_fec(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay); int from_fec_to_normal(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay); @@ -56,7 +62,7 @@ int handle_command(char *s); int unit_test(); -void print_help(); +//void print_help(); void process_arg(int argc, char *argv[]);