From 41cac842a84fa5052a46041a3ea71bc68591f0cd Mon Sep 17 00:00:00 2001 From: yancey Date: Tue, 7 Feb 2023 05:34:06 -0500 Subject: [PATCH] fix indent problem with clang-format --- common.cpp | 1490 ++++++++++++++++++-------------------- common.h | 669 +++++++++-------- connection.cpp | 209 +++--- connection.h | 557 +++++++-------- delay_manager.cpp | 171 ++--- delay_manager.h | 216 +++--- fd_manager.cpp | 81 +-- fd_manager.h | 39 +- fec_manager.cpp | 1498 ++++++++++++++++++-------------------- fec_manager.h | 733 +++++++++---------- lib/rs.cpp | 102 ++- lib/rs.h | 14 +- log.cpp | 88 ++- log.h | 58 +- main.cpp | 209 +++--- misc.cpp | 1736 ++++++++++++++++++++------------------------- misc.h | 21 +- my_ev.h | 1 - my_ev_common.h | 12 +- packet.cpp | 598 +++++++--------- packet.h | 35 +- tunnel.h | 1 - tunnel_client.cpp | 711 +++++++++---------- tunnel_server.cpp | 783 ++++++++++---------- 24 files changed, 4599 insertions(+), 5433 deletions(-) mode change 100755 => 100644 log.cpp mode change 100755 => 100644 log.h diff --git a/common.cpp b/common.cpp index 02052a9..c36293d 100644 --- a/common.cpp +++ b/common.cpp @@ -11,152 +11,140 @@ #include #include -int about_to_exit=0; +int about_to_exit = 0; -raw_mode_t raw_mode=mode_faketcp; -unordered_map raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}}; +raw_mode_t raw_mode = mode_faketcp; +unordered_map raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}}; +// static int random_number_fd=-1; +char iptables_rule[200] = ""; +// int is_client = 0, is_server = 0; -//static int random_number_fd=-1; -char iptables_rule[200]=""; -//int is_client = 0, is_server = 0; +program_mode_t program_mode = unset_mode; // 0 unset; 1client 2server -program_mode_t program_mode=unset_mode;//0 unset; 1client 2server +working_mode_t working_mode = tunnel_mode; -working_mode_t working_mode=tunnel_mode; +int socket_buf_size = 1024 * 1024; -int socket_buf_size=1024*1024; - -int init_ws() -{ +int init_ws() { #if defined(__MINGW32__) - WORD wVersionRequested; - WSADATA wsaData; - int err; + WORD wVersionRequested; + WSADATA wsaData; + int err; - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ - printf("WSAStartup failed with error: %d\n", err); - exit(-1); - } - - /* Confirm that the WinSock DLL supports 2.2.*/ - /* Note that if the DLL supports versions greater */ - /* than 2.2 in addition to 2.2, it will still return */ - /* 2.2 in wVersion since that is the version we */ - /* requested. */ - - if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { - /* Tell the user that we could not find a usable */ - /* WinSock DLL. */ - printf("Could not find a usable version of Winsock.dll\n"); - WSACleanup(); - exit(-1); - } - else - { - printf("The Winsock 2.2 dll was found okay"); - } - - int tmp[]={0,100,200,300,500,800,1000,2000,3000,4000,-1}; - int succ=0; - for(int i=1;tmp[i]!=-1;i++) - { - if(_setmaxstdio(100)==-1) break; - else succ=i; - } - printf(", _setmaxstdio() was set to %d\n",tmp[succ]); -#endif -return 0; -} - -#if defined(__MINGW32__) -int inet_pton(int af, const char *src, void *dst) -{ - struct sockaddr_storage ss; - int size = sizeof(ss); - char src_copy[INET6_ADDRSTRLEN+1]; - - ZeroMemory(&ss, sizeof(ss)); - /* stupid non-const API */ - strncpy (src_copy, src, INET6_ADDRSTRLEN+1); - src_copy[INET6_ADDRSTRLEN] = 0; - - if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { - switch(af) { - case AF_INET: - *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; - return 1; - case AF_INET6: - *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; - return 1; + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + printf("WSAStartup failed with error: %d\n", err); + exit(-1); } - } - return 0; + + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("Could not find a usable version of Winsock.dll\n"); + WSACleanup(); + exit(-1); + } else { + printf("The Winsock 2.2 dll was found okay"); + } + + int tmp[] = {0, 100, 200, 300, 500, 800, 1000, 2000, 3000, 4000, -1}; + int succ = 0; + for (int i = 1; tmp[i] != -1; i++) { + if (_setmaxstdio(100) == -1) + break; + else + succ = i; + } + printf(", _setmaxstdio() was set to %d\n", tmp[succ]); +#endif + return 0; } -const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) -{ - struct sockaddr_storage ss; - unsigned long s = size; +#if defined(__MINGW32__) +int inet_pton(int af, const char *src, void *dst) { + struct sockaddr_storage ss; + int size = sizeof(ss); + char src_copy[INET6_ADDRSTRLEN + 1]; - ZeroMemory(&ss, sizeof(ss)); - ss.ss_family = af; + ZeroMemory(&ss, sizeof(ss)); + /* stupid non-const API */ + strncpy(src_copy, src, INET6_ADDRSTRLEN + 1); + src_copy[INET6_ADDRSTRLEN] = 0; - switch(af) { - case AF_INET: - ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; - break; - case AF_INET6: - ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; - break; - default: - return NULL; - } - /* cannot direclty use &size because of strict aliasing rules */ - return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)? - dst : NULL; + if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { + switch (af) { + case AF_INET: + *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; + return 1; + case AF_INET6: + *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; + return 1; + } + } + return 0; } -char *get_sock_error() -{ - static char buf[1000]; - int e=WSAGetLastError(); - wchar_t *s = NULL; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, e, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR)&s, 0, NULL); - sprintf(buf, "%d:%S", e,s); - int len=strlen(buf); - if(len>0&&buf[len-1]=='\n') buf[len-1]=0; - LocalFree(s); - return buf; + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { + struct sockaddr_storage ss; + unsigned long s = size; + + ZeroMemory(&ss, sizeof(ss)); + ss.ss_family = af; + + switch (af) { + case AF_INET: + ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; + break; + case AF_INET6: + ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; + break; + default: + return NULL; + } + /* cannot direclty use &size because of strict aliasing rules */ + return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0) ? dst : NULL; } -int get_sock_errno() -{ - return WSAGetLastError(); +char *get_sock_error() { + static char buf[1000]; + int e = WSAGetLastError(); + wchar_t *s = NULL; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, e, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&s, 0, NULL); + sprintf(buf, "%d:%S", e, s); + int len = strlen(buf); + if (len > 0 && buf[len - 1] == '\n') buf[len - 1] = 0; + LocalFree(s); + return buf; +} +int get_sock_errno() { + return WSAGetLastError(); } #else -char *get_sock_error() -{ - static char buf[1000]; - sprintf(buf, "%d:%s", errno,strerror(errno)); - return buf; +char *get_sock_error() { + static char buf[1000]; + sprintf(buf, "%d:%s", errno, strerror(errno)); + return buf; } -int get_sock_errno() -{ - return errno; +int get_sock_errno() { + return errno; } #endif - -struct my_random_t -{ +struct my_random_t { std::random_device rd; std::mt19937 gen; std::uniform_int_distribution dis64; @@ -164,504 +152,429 @@ struct my_random_t std::uniform_int_distribution dis8; - my_random_t() - { - std::mt19937 gen_tmp(rd()); - gen=gen_tmp; - gen.discard(700000); //magic - } - u64_t gen64() - { - return dis64(gen); + my_random_t() { + std::mt19937 gen_tmp(rd()); + gen = gen_tmp; + gen.discard(700000); // magic } - u32_t gen32() - { - return dis32(gen); + u64_t gen64() { + return dis64(gen); + } + u32_t gen32() { + return dis32(gen); } - unsigned char gen8() - { - return dis8(gen); + unsigned char gen8() { + return dis8(gen); } - /*int random_number_fd; - random_fd_t() - { - random_number_fd=open("/dev/urandom",O_RDONLY); + /*int random_number_fd; + random_fd_t() + { + random_number_fd=open("/dev/urandom",O_RDONLY); - if(random_number_fd==-1) - { - mylog(log_fatal,"error open /dev/urandom\n"); - myexit(-1); - } - setnonblocking(random_number_fd); - } - int get_fd() - { - return random_number_fd; - }*/ -}my_random; + if(random_number_fd==-1) + { + mylog(log_fatal,"error open /dev/urandom\n"); + myexit(-1); + } + setnonblocking(random_number_fd); + } + int get_fd() + { + return random_number_fd; + }*/ +} my_random; -int address_t::from_str(char *str) -{ - clear(); +int address_t::from_str(char *str) { + clear(); - char ip_addr_str[100];u32_t port; - mylog(log_info,"parsing address: %s\n",str); - int is_ipv6=0; - if(sscanf(str, "[%[^]]]:%u", ip_addr_str,&port)==2) - { - mylog(log_info,"its an ipv6 adress\n"); - inner.ipv6.sin6_family=AF_INET6; - is_ipv6=1; - } - else if(sscanf(str, "%[^:]:%u", ip_addr_str,&port)==2) - { - mylog(log_info,"its an ipv4 adress\n"); - inner.ipv4.sin_family=AF_INET; - } - else - { - mylog(log_error,"failed to parse\n"); - myexit(-1); - } + char ip_addr_str[100]; + u32_t port; + mylog(log_info, "parsing address: %s\n", str); + int is_ipv6 = 0; + if (sscanf(str, "[%[^]]]:%u", ip_addr_str, &port) == 2) { + mylog(log_info, "its an ipv6 adress\n"); + inner.ipv6.sin6_family = AF_INET6; + is_ipv6 = 1; + } else if (sscanf(str, "%[^:]:%u", ip_addr_str, &port) == 2) { + mylog(log_info, "its an ipv4 adress\n"); + inner.ipv4.sin_family = AF_INET; + } else { + mylog(log_error, "failed to parse\n"); + myexit(-1); + } - mylog(log_info,"ip_address is {%s}, port is {%u}\n",ip_addr_str,port); + mylog(log_info, "ip_address is {%s}, port is {%u}\n", ip_addr_str, port); - if(port>65535) - { - mylog(log_error,"invalid port: %d\n",port); - myexit(-1); - } + if (port > 65535) { + mylog(log_error, "invalid port: %d\n", port); + myexit(-1); + } - int ret=-100; - if(is_ipv6) - { - ret=inet_pton(AF_INET6, ip_addr_str,&(inner.ipv6.sin6_addr)); - inner.ipv6.sin6_port=htons(port); - if(ret==0) // 0 if address type doesnt match - { - mylog(log_error,"ip_addr %s is not an ipv6 address, %d\n",ip_addr_str,ret); - myexit(-1); - } - else if(ret==1) // inet_pton returns 1 on success - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",ip_addr_str,ret); - myexit(-1); - } - } - else - { - ret=inet_pton(AF_INET, ip_addr_str,&(inner.ipv4.sin_addr)); - inner.ipv4.sin_port=htons(port); + int ret = -100; + if (is_ipv6) { + ret = inet_pton(AF_INET6, ip_addr_str, &(inner.ipv6.sin6_addr)); + inner.ipv6.sin6_port = htons(port); + if (ret == 0) // 0 if address type doesnt match + { + mylog(log_error, "ip_addr %s is not an ipv6 address, %d\n", ip_addr_str, ret); + myexit(-1); + } else if (ret == 1) // inet_pton returns 1 on success + { + // okay + } else { + mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret); + myexit(-1); + } + } else { + ret = inet_pton(AF_INET, ip_addr_str, &(inner.ipv4.sin_addr)); + inner.ipv4.sin_port = htons(port); - if(ret==0) - { - mylog(log_error,"ip_addr %s is not an ipv4 address, %d\n",ip_addr_str,ret); - myexit(-1); - } - else if(ret==1) - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",ip_addr_str,ret); - myexit(-1); - } - } + if (ret == 0) { + mylog(log_error, "ip_addr %s is not an ipv4 address, %d\n", ip_addr_str, ret); + myexit(-1); + } else if (ret == 1) { + // okay + } else { + mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret); + myexit(-1); + } + } - return 0; + return 0; } -int address_t::from_str_ip_only(char * str) -{ - clear(); +int address_t::from_str_ip_only(char *str) { + clear(); - u32_t type; + u32_t type; - if(strchr(str,':')==NULL) - type=AF_INET; - else - type=AF_INET6; + if (strchr(str, ':') == NULL) + type = AF_INET; + else + type = AF_INET6; - ((sockaddr*)&inner)->sa_family=type; + ((sockaddr *)&inner)->sa_family = type; - int ret; - if(type==AF_INET) - { - ret=inet_pton(type, str,&inner.ipv4.sin_addr); - } - else - { - ret=inet_pton(type, str,&inner.ipv6.sin6_addr); - } + int ret; + if (type == AF_INET) { + ret = inet_pton(type, str, &inner.ipv4.sin_addr); + } else { + ret = inet_pton(type, str, &inner.ipv6.sin6_addr); + } - if(ret==0) // 0 if address type doesnt match - { - mylog(log_error,"confusion in parsing %s, %d\n",str,ret); - myexit(-1); - } - else if(ret==1) // inet_pton returns 1 on success - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",str,ret); - myexit(-1); - } - return 0; + if (ret == 0) // 0 if address type doesnt match + { + mylog(log_error, "confusion in parsing %s, %d\n", str, ret); + myexit(-1); + } else if (ret == 1) // inet_pton returns 1 on success + { + // okay + } else { + mylog(log_error, "ip_addr %s is invalid, %d\n", str, ret); + myexit(-1); + } + return 0; } -char * address_t::get_str() -{ - static char res[max_addr_len]; - to_str(res); - return res; +char *address_t::get_str() { + static char res[max_addr_len]; + to_str(res); + return res; } -void address_t::to_str(char * s) -{ - //static char res[max_addr_len]; - char ip_addr[max_addr_len]; - u32_t port; - const char * ret=0; - if(get_type()==AF_INET6) - { - ret=inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr,max_addr_len); - port=inner.ipv6.sin6_port; - } - else if(get_type()==AF_INET) - { - ret=inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr,max_addr_len); - port=inner.ipv4.sin_port; - } - else - { - assert(0==1); - } +void address_t::to_str(char *s) { + // static char res[max_addr_len]; + char ip_addr[max_addr_len]; + u32_t port; + const char *ret = 0; + if (get_type() == AF_INET6) { + ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len); + port = inner.ipv6.sin6_port; + } else if (get_type() == AF_INET) { + ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len); + port = inner.ipv4.sin_port; + } else { + assert(0 == 1); + } - if(ret==0) //NULL on failure - { - mylog(log_error,"inet_ntop failed\n"); - myexit(-1); - } + if (ret == 0) // NULL on failure + { + mylog(log_error, "inet_ntop failed\n"); + myexit(-1); + } - port=ntohs(port); + port = ntohs(port); - ip_addr[max_addr_len-1]=0; - if(get_type()==AF_INET6) - { - sprintf(s,"[%s]:%u",ip_addr,(u32_t)port); - }else - { - sprintf(s,"%s:%u",ip_addr,(u32_t)port); - } + ip_addr[max_addr_len - 1] = 0; + if (get_type() == AF_INET6) { + sprintf(s, "[%s]:%u", ip_addr, (u32_t)port); + } else { + sprintf(s, "%s:%u", ip_addr, (u32_t)port); + } - //return res; + // return res; } -char* address_t::get_ip() -{ - char ip_addr[max_addr_len]; - static char s[max_addr_len]; - const char * ret=0; - if(get_type()==AF_INET6) - { - ret=inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr,max_addr_len); - } - else if(get_type()==AF_INET) - { - ret=inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr,max_addr_len); - } - else - { - assert(0==1); - } +char *address_t::get_ip() { + char ip_addr[max_addr_len]; + static char s[max_addr_len]; + const char *ret = 0; + if (get_type() == AF_INET6) { + ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len); + } else if (get_type() == AF_INET) { + ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len); + } else { + assert(0 == 1); + } - if(ret==0) //NULL on failure - { - mylog(log_error,"inet_ntop failed\n"); - myexit(-1); - } + if (ret == 0) // NULL on failure + { + mylog(log_error, "inet_ntop failed\n"); + myexit(-1); + } - ip_addr[max_addr_len-1]=0; - if(get_type()==AF_INET6) - { - sprintf(s,"%s",ip_addr); - }else - { - sprintf(s,"%s",ip_addr); - } + ip_addr[max_addr_len - 1] = 0; + if (get_type() == AF_INET6) { + sprintf(s, "%s", ip_addr); + } else { + sprintf(s, "%s", ip_addr); + } - return s; + return s; } -int address_t::from_sockaddr(sockaddr * addr,socklen_t slen) -{ - clear(); - //memset(&inner,0,sizeof(inner)); - if(addr->sa_family==AF_INET6) - { - assert(slen==sizeof(sockaddr_in6)); - //inner.ipv6= *( (sockaddr_in6*) addr ); - memcpy(&inner,addr,slen); - } - else if(addr->sa_family==AF_INET) - { - assert(slen==sizeof(sockaddr_in)); - //inner.ipv4= *( (sockaddr_in*) addr ); - memcpy(&inner,addr,slen); - } - else - { - assert(0==1); - } - return 0; +int address_t::from_sockaddr(sockaddr *addr, socklen_t slen) { + clear(); + // memset(&inner,0,sizeof(inner)); + if (addr->sa_family == AF_INET6) { + assert(slen == sizeof(sockaddr_in6)); + // inner.ipv6= *( (sockaddr_in6*) addr ); + memcpy(&inner, addr, slen); + } else if (addr->sa_family == AF_INET) { + assert(slen == sizeof(sockaddr_in)); + // inner.ipv4= *( (sockaddr_in*) addr ); + memcpy(&inner, addr, slen); + } else { + assert(0 == 1); + } + return 0; } -int address_t::new_connected_udp_fd() -{ +int address_t::new_connected_udp_fd() { + int new_udp_fd; + new_udp_fd = socket(get_type(), SOCK_DGRAM, IPPROTO_UDP); + if (new_udp_fd < 0) { + mylog(log_warn, "create udp_fd error\n"); + return -1; + } + setnonblocking(new_udp_fd); + set_buf_size(new_udp_fd, socket_buf_size); - int new_udp_fd; - new_udp_fd = socket(get_type(), SOCK_DGRAM, IPPROTO_UDP); - if (new_udp_fd < 0) { - mylog(log_warn, "create udp_fd error\n"); - return -1; - } - setnonblocking(new_udp_fd); - set_buf_size(new_udp_fd,socket_buf_size); + mylog(log_debug, "created new udp_fd %d\n", new_udp_fd); + int ret = connect(new_udp_fd, (struct sockaddr *)&inner, get_len()); + if (ret != 0) { + mylog(log_warn, "udp fd connect fail %d %s\n", ret, strerror(errno)); + // sock_close(new_udp_fd); + close(new_udp_fd); + return -1; + } - mylog(log_debug, "created new udp_fd %d\n", new_udp_fd); - int ret = connect(new_udp_fd, (struct sockaddr *) &inner, get_len()); - if (ret != 0) { - mylog(log_warn, "udp fd connect fail %d %s\n",ret,strerror(errno) ); - //sock_close(new_udp_fd); - close(new_udp_fd); - return -1; - } - - return new_udp_fd; + return new_udp_fd; } -void get_fake_random_chars(char * s,int len) -{ - char *p=s; - int left=len; +void get_fake_random_chars(char *s, int len) { + char *p = s; + int left = len; - while(left>=(int)sizeof(u64_t)) - { - //*((u64_t*)p)=my_random.gen64(); //this may break strict-alias , also p may not point to a multiple of sizeof(u64_t) + while (left >= (int)sizeof(u64_t)) { + //*((u64_t*)p)=my_random.gen64(); //this may break strict-alias , also p may not point to a multiple of sizeof(u64_t) - u64_t tmp=my_random.gen64(); - memcpy(p,&tmp,sizeof(u64_t)); // so,use memcpy instead. + u64_t tmp = my_random.gen64(); + memcpy(p, &tmp, sizeof(u64_t)); // so,use memcpy instead. - p+=sizeof(u64_t); - left-=sizeof(u64_t); - } - if(left) - { - u64_t tmp=my_random.gen64(); - memcpy(p,&tmp,left); - } + p += sizeof(u64_t); + left -= sizeof(u64_t); + } + if (left) { + u64_t tmp = my_random.gen64(); + memcpy(p, &tmp, left); + } } -int random_between(u32_t a,u32_t b) -{ - if(a>b) - { - mylog(log_fatal,"min >max?? %d %d\n",a ,b); - myexit(1); - } - if(a==b)return a; - else return a+get_fake_random_number()%(b+1-a); +int random_between(u32_t a, u32_t b) { + if (a > b) { + mylog(log_fatal, "min >max?? %d %d\n", a, b); + myexit(1); + } + if (a == b) + return a; + else + return a + get_fake_random_number() % (b + 1 - a); } /* u64_t get_current_time()//ms { - timespec tmp_time; - clock_gettime(CLOCK_MONOTONIC, &tmp_time); - return ((u64_t)tmp_time.tv_sec)*1000llu+((u64_t)tmp_time.tv_nsec)/(1000*1000llu); + timespec tmp_time; + clock_gettime(CLOCK_MONOTONIC, &tmp_time); + return ((u64_t)tmp_time.tv_sec)*1000llu+((u64_t)tmp_time.tv_nsec)/(1000*1000llu); } u64_t get_current_time_us() { - timespec tmp_time; - clock_gettime(CLOCK_MONOTONIC, &tmp_time); - return (uint64_t(tmp_time.tv_sec))*1000llu*1000llu+ (uint64_t(tmp_time.tv_nsec))/1000llu; + timespec tmp_time; + clock_gettime(CLOCK_MONOTONIC, &tmp_time); + return (uint64_t(tmp_time.tv_sec))*1000llu*1000llu+ (uint64_t(tmp_time.tv_nsec))/1000llu; }*/ -u64_t get_current_time_us() -{ - static u64_t value_fix=0; - static u64_t largest_value=0; +u64_t get_current_time_us() { + static u64_t value_fix = 0; + static u64_t largest_value = 0; - u64_t raw_value=(u64_t)(ev_time()*1000*1000); + u64_t raw_value = (u64_t)(ev_time() * 1000 * 1000); - u64_t fixed_value=raw_value+value_fix; + u64_t fixed_value = raw_value + value_fix; - if(fixed_value< largest_value) - { - value_fix+= largest_value- fixed_value; - } - else - { - largest_value=fixed_value; - } + if (fixed_value < largest_value) { + value_fix += largest_value - fixed_value; + } else { + largest_value = fixed_value; + } - //printf("<%lld,%lld,%lld>\n",raw_value,value_fix,raw_value + value_fix); - return raw_value + value_fix; //new fixed value + // printf("<%lld,%lld,%lld>\n",raw_value,value_fix,raw_value + value_fix); + return raw_value + value_fix; // new fixed value } -u64_t get_current_time() -{ - return get_current_time_us()/1000lu; +u64_t get_current_time() { + return get_current_time_us() / 1000lu; } -u64_t pack_u64(u32_t a,u32_t b) -{ - u64_t ret=a; - ret<<=32u; - ret+=b; - return ret; +u64_t pack_u64(u32_t a, u32_t b) { + u64_t ret = a; + ret <<= 32u; + ret += b; + return ret; } -u32_t get_u64_h(u64_t a) -{ - return a>>32u; +u32_t get_u64_h(u64_t a) { + return a >> 32u; } -u32_t get_u64_l(u64_t a) -{ - return (a<<32u)>>32u; +u32_t get_u64_l(u64_t a) { + return (a << 32u) >> 32u; } -void write_u16(char * p,u16_t w) -{ - *(unsigned char*)(p + 1) = (w & 0xff); - *(unsigned char*)(p + 0) = (w >> 8); +void write_u16(char *p, u16_t w) { + *(unsigned char *)(p + 1) = (w & 0xff); + *(unsigned char *)(p + 0) = (w >> 8); } -u16_t read_u16(char * p) -{ - u16_t res; - res = *(const unsigned char*)(p + 0); - res = *(const unsigned char*)(p + 1) + (res << 8); - return res; +u16_t read_u16(char *p) { + u16_t res; + res = *(const unsigned char *)(p + 0); + res = *(const unsigned char *)(p + 1) + (res << 8); + return res; } -void write_u32(char * p,u32_t l) -{ - *(unsigned char*)(p + 3) = (unsigned char)((l >> 0) & 0xff); - *(unsigned char*)(p + 2) = (unsigned char)((l >> 8) & 0xff); - *(unsigned char*)(p + 1) = (unsigned char)((l >> 16) & 0xff); - *(unsigned char*)(p + 0) = (unsigned char)((l >> 24) & 0xff); +void write_u32(char *p, u32_t l) { + *(unsigned char *)(p + 3) = (unsigned char)((l >> 0) & 0xff); + *(unsigned char *)(p + 2) = (unsigned char)((l >> 8) & 0xff); + *(unsigned char *)(p + 1) = (unsigned char)((l >> 16) & 0xff); + *(unsigned char *)(p + 0) = (unsigned char)((l >> 24) & 0xff); } -u32_t read_u32(char * p) -{ - u32_t res; - res = *(const unsigned char*)(p + 0); - res = *(const unsigned char*)(p + 1) + (res << 8); - res = *(const unsigned char*)(p + 2) + (res << 8); - res = *(const unsigned char*)(p + 3) + (res << 8); - return res; +u32_t read_u32(char *p) { + u32_t res; + res = *(const unsigned char *)(p + 0); + res = *(const unsigned char *)(p + 1) + (res << 8); + res = *(const unsigned char *)(p + 2) + (res << 8); + res = *(const unsigned char *)(p + 3) + (res << 8); + return res; } -void write_u64(char * s,u64_t a) -{ - assert(0==1); +void write_u64(char *s, u64_t a) { + assert(0 == 1); } -u64_t read_u64(char * s) -{ - assert(0==1); - return 0; +u64_t read_u64(char *s) { + assert(0 == 1); + return 0; } - -char * my_ntoa(u32_t ip) -{ - in_addr a; - a.s_addr=ip; - return inet_ntoa(a); +char *my_ntoa(u32_t ip) { + in_addr a; + a.s_addr = ip; + return inet_ntoa(a); } -u64_t get_fake_random_number_64() -{ - //u64_t ret; - //int size=read(random_fd.get_fd(),&ret,sizeof(ret)); - //if(size!=sizeof(ret)) - //{ - // mylog(log_fatal,"get random number failed %d\n",size); +u64_t get_fake_random_number_64() { + // u64_t ret; + // int size=read(random_fd.get_fd(),&ret,sizeof(ret)); + // if(size!=sizeof(ret)) + //{ + // mylog(log_fatal,"get random number failed %d\n",size); - // myexit(-1); - //} + // myexit(-1); + //} - return my_random.gen64(); + return my_random.gen64(); } -u32_t get_fake_random_number() -{ - //u32_t ret; - //int size=read(random_fd.get_fd(),&ret,sizeof(ret)); - //if(size!=sizeof(ret)) - //{ - // mylog(log_fatal,"get random number failed %d\n",size); - // myexit(-1); - //} - return my_random.gen32(); +u32_t get_fake_random_number() { + // u32_t ret; + // int size=read(random_fd.get_fd(),&ret,sizeof(ret)); + // if(size!=sizeof(ret)) + //{ + // mylog(log_fatal,"get random number failed %d\n",size); + // myexit(-1); + // } + return my_random.gen32(); } -u32_t get_fake_random_number_nz() //nz for non-zero +u32_t get_fake_random_number_nz() // nz for non-zero { - u32_t ret=0; - while(ret==0) - { - ret=get_fake_random_number(); - } - return ret; + u32_t ret = 0; + while (ret == 0) { + ret = get_fake_random_number(); + } + return ret; } /* u64_t ntoh64(u64_t a) { - if(__BYTE_ORDER == __LITTLE_ENDIAN) - { - return __bswap_64( a); - } - else return a; + if(__BYTE_ORDER == __LITTLE_ENDIAN) + { + return __bswap_64( a); + } + else return a; } u64_t hton64(u64_t a) { - if(__BYTE_ORDER == __LITTLE_ENDIAN) - { - return __bswap_64( a); - } - else return a; + if(__BYTE_ORDER == __LITTLE_ENDIAN) + { + return __bswap_64( a); + } + else return a; }*/ void setnonblocking(int sock) { #if !defined(__MINGW32__) - int opts; - opts = fcntl(sock, F_GETFL); + int opts; + opts = fcntl(sock, F_GETFL); - if (opts < 0) { - mylog(log_fatal,"fcntl(sock,GETFL)\n"); - //perror("fcntl(sock,GETFL)"); - myexit(1); - } - opts = opts | O_NONBLOCK; - if (fcntl(sock, F_SETFL, opts) < 0) { - mylog(log_fatal,"fcntl(sock,SETFL,opts)\n"); - //perror("fcntl(sock,SETFL,opts)"); - myexit(1); - } + if (opts < 0) { + mylog(log_fatal, "fcntl(sock,GETFL)\n"); + // perror("fcntl(sock,GETFL)"); + myexit(1); + } + opts = opts | O_NONBLOCK; + if (fcntl(sock, F_SETFL, opts) < 0) { + mylog(log_fatal, "fcntl(sock,SETFL,opts)\n"); + // perror("fcntl(sock,SETFL,opts)"); + myexit(1); + } #else - int iResult; - u_long iMode = 1; - iResult = ioctlsocket(sock, FIONBIO, &iMode); - if (iResult != NO_ERROR) - printf("ioctlsocket failed with error: %d\n", iResult); + int iResult; + u_long iMode = 1; + iResult = ioctlsocket(sock, FIONBIO, &iMode); + if (iResult != NO_ERROR) + printf("ioctlsocket failed with error: %d\n", iResult); #endif } @@ -669,379 +582,352 @@ void setnonblocking(int sock) { /* Generic checksum calculation function */ -unsigned short csum(const unsigned short *ptr,int nbytes) { +unsigned short csum(const unsigned short *ptr, int nbytes) { long sum; unsigned short oddbyte; short answer; - sum=0; - while(nbytes>1) { - sum+=*ptr++; - nbytes-=2; + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; } - if(nbytes==1) { - oddbyte=0; - *((u_char*)&oddbyte)=*(u_char*)ptr; - sum+=oddbyte; + 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; + sum = (sum >> 16) + (sum & 0xffff); + sum = sum + (sum >> 16); + answer = (short)~sum; - return(answer); + return (answer); } - -unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes) {//works both for big and little endian +unsigned short tcp_csum(const pseudo_header &ph, const unsigned short *ptr, int nbytes) { // works both for big and little endian long sum; unsigned short oddbyte; 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 = 0; + unsigned short *tmp = (unsigned short *)&ph; + for (int i = 0; i < 6; i++) { + sum += *tmp++; } - sum = (sum>>16)+(sum & 0xffff); - sum = sum + (sum>>16); - answer=(short)~sum; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + *((u_char *)&oddbyte) = *(u_char *)ptr; + sum += oddbyte; + } - return(answer); + sum = (sum >> 16) + (sum & 0xffff); + sum = sum + (sum >> 16); + answer = (short)~sum; + + return (answer); } -int set_buf_size(int fd,int socket_buf_size) -{ - if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,get_sock_error()); - myexit(1); - } - if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,get_sock_error()); - myexit(1); - } - return 0; +int set_buf_size(int fd, int socket_buf_size) { + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_SNDBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, get_sock_error()); + myexit(1); + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_RCVBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, get_sock_error()); + myexit(1); + } + return 0; } -void myexit(int a) -{ - if(enable_log_color) - printf("%s\n",RESET); - // clear_iptables_rule(); - exit(a); +void myexit(int a) { + if (enable_log_color) + printf("%s\n", RESET); + // clear_iptables_rule(); + exit(a); } -void signal_handler(int sig) -{ - about_to_exit=1; +void signal_handler(int sig) { + about_to_exit = 1; // myexit(0); } /* int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len) { - static char buf[buf_len]; - data=buf; - id_t tmp=htonl(id1); - memcpy(buf,&tmp,sizeof(tmp)); + static char buf[buf_len]; + data=buf; + id_t tmp=htonl(id1); + memcpy(buf,&tmp,sizeof(tmp)); - tmp=htonl(id2); - memcpy(buf+sizeof(tmp),&tmp,sizeof(tmp)); + tmp=htonl(id2); + memcpy(buf+sizeof(tmp),&tmp,sizeof(tmp)); - tmp=htonl(id3); - memcpy(buf+sizeof(tmp)*2,&tmp,sizeof(tmp)); + tmp=htonl(id3); + memcpy(buf+sizeof(tmp)*2,&tmp,sizeof(tmp)); - len=sizeof(id_t)*3; - return 0; + len=sizeof(id_t)*3; + return 0; } int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3) { - if(leninner, bind_addr->get_len()) == -1) { - mylog(log_fatal,"socket bind error=%s\n", get_sock_error()); - //perror("socket bind error"); - myexit(1); - } - -#ifdef __linux__ - if (interface_string && ::setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_string, strlen(interface_string)) < 0) { - mylog(log_fatal,"socket interface bind error=%s\n", get_sock_error()); - //perror("socket bind error"); - myexit(1); - } -#endif - - setnonblocking(fd); - set_buf_size(fd, socket_buf_size); - - mylog(log_debug, "[%s]created new udp_fd %d\n", addr.get_str(), fd); - int ret = connect(fd, (struct sockaddr *) &addr.inner, addr.get_len()); - if (ret != 0) { - mylog(log_warn, "[%s]fd connect fail\n",addr.get_str()); - sock_close(fd); - return -1; - } - return 0; -} - - -u32_t djb2(unsigned char *str,int len) -{ - u32_t hash = 5381; - int c; - int i=0; - while(c = *str++,i++!=len) - { - hash = ((hash << 5) + hash)^c; /* (hash * 33) ^ c */ +int new_connected_socket2(int &fd, address_t &addr, address_t *bind_addr, char *interface_string) { + fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) { + mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str()); + return -1; } - hash=htonl(hash); - return hash; - } + if (bind_addr && ::bind(fd, (struct sockaddr *)&bind_addr->inner, bind_addr->get_len()) == -1) { + mylog(log_fatal, "socket bind error=%s\n", get_sock_error()); + // perror("socket bind error"); + myexit(1); + } -u32_t sdbm(unsigned char *str,int len) -{ - u32_t hash = 0; - int c; - int i=0; - while(c = *str++,i++!=len) - { - hash = c + (hash << 6) + (hash << 16) - hash; - } - //hash=htonl(hash); - return hash; - } +#ifdef __linux__ + if (interface_string && ::setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_string, strlen(interface_string)) < 0) { + mylog(log_fatal, "socket interface bind error=%s\n", get_sock_error()); + // perror("socket bind error"); + myexit(1); + } +#endif -vector string_to_vec(const char * s,const char * sp) { - vector res; - string str=s; - char *p = strtok ((char *)str.c_str(),sp); - while (p != NULL) - { - res.push_back(p); - //printf ("%s\n",p); - p = strtok(NULL, sp); - } + setnonblocking(fd); + set_buf_size(fd, socket_buf_size); - /* for(int i=0;i<(int)res.size();i++) - { - printf("<<%s>>\n",res[i].c_str()); - }*/ - return res; + mylog(log_debug, "[%s]created new udp_fd %d\n", addr.get_str(), fd); + int ret = connect(fd, (struct sockaddr *)&addr.inner, addr.get_len()); + if (ret != 0) { + mylog(log_warn, "[%s]fd connect fail\n", addr.get_str()); + sock_close(fd); + return -1; + } + return 0; } +u32_t djb2(unsigned char *str, int len) { + u32_t hash = 5381; + int c; + int i = 0; + while (c = *str++, i++ != len) { + hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */ + } + + hash = htonl(hash); + return hash; +} + +u32_t sdbm(unsigned char *str, int len) { + u32_t hash = 0; + int c; + int i = 0; + while (c = *str++, i++ != len) { + hash = c + (hash << 6) + (hash << 16) - hash; + } + // hash=htonl(hash); + return hash; +} + +vector string_to_vec(const char *s, const char *sp) { + vector res; + string str = s; + char *p = strtok((char *)str.c_str(), sp); + while (p != NULL) { + res.push_back(p); + // printf ("%s\n",p); + p = strtok(NULL, sp); + } + + /* for(int i=0;i<(int)res.size();i++) + { + printf("<<%s>>\n",res[i].c_str()); + }*/ + return res; +} diff --git a/common.h b/common.h index cb1797a..9f59799 100644 --- a/common.h +++ b/common.h @@ -10,17 +10,17 @@ //#define __STDC_FORMAT_MACROS 1 #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include +#include +#include #include #include -#include //for exit(0); -#include //For errno - the error number +#include //for exit(0); +#include //For errno - the error number //#include //Provides declarations for tcp header //#include //#include //Provides declarations for ip header @@ -44,24 +44,22 @@ #include typedef int socklen_t; #else -#include +#include #include #include #include #include #endif +#include +#include +#include +#include +#include +#include +using namespace std; -#include -#include -#include -#include -#include -#include -using namespace std; - - -typedef unsigned long long u64_t; //this works on most platform,avoid using the PRId64 +typedef unsigned long long u64_t; // this works on most platform,avoid using the PRId64 typedef long long i64_t; typedef unsigned int u32_t; @@ -70,11 +68,10 @@ typedef int i32_t; typedef unsigned short u16_t; typedef short i16_t; - #if defined(__MINGW32__) int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); -#define setsockopt(a,b,c,d,e) setsockopt(a,b,c,(const char *)(d),e) +#define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char *)(d), e) #endif char *get_sock_error(); @@ -83,39 +80,36 @@ int init_ws(); #if defined(__MINGW32__) typedef SOCKET my_fd_t; -inline int sock_close(my_fd_t fd) -{ - return closesocket(fd); +inline int sock_close(my_fd_t fd) { + return closesocket(fd); } #else typedef int my_fd_t; -inline int sock_close(my_fd_t fd) -{ - return close(fd); +inline int sock_close(my_fd_t fd) { + return close(fd); } #endif - struct my_itimerspec { - struct timespec it_interval; /* Timer interval */ - struct timespec it_value; /* Initial expiration */ + struct timespec it_interval; /* Timer interval */ + struct timespec it_value; /* Initial expiration */ }; typedef u64_t my_time_t; -const int max_addr_len=100; -const int max_data_len=3600; -const int buf_len=max_data_len+200; +const int max_addr_len = 100; +const int max_data_len = 3600; +const int buf_len = max_data_len + 200; -const int default_mtu=1250; +const int default_mtu = 1250; -//const u32_t timer_interval=400; +// const u32_t timer_interval=400; ////const u32_t conv_timeout=180000; -//const u32_t conv_timeout=40000;//for test -const u32_t conv_timeout=180000; -const int max_conv_num=10000; -const int max_conn_num=200; +// const u32_t conv_timeout=40000;//for test +const u32_t conv_timeout = 180000; +const int max_conv_num = 10000; +const int max_conn_num = 200; /* const u32_t max_handshake_conn_num=10000; @@ -128,46 +122,50 @@ const u32_t client_retry_interval=1000; const u32_t server_handshake_timeout=10000;// this should be much longer than clients. client retry initially ,server retry passtively*/ -const int conv_clear_ratio=30; //conv grabage collecter check 1/30 of all conv one time -const int conn_clear_ratio=50; -const int conv_clear_min=1; -const int conn_clear_min=1; +const int conv_clear_ratio = 30; // conv grabage collecter check 1/30 of all conv one time +const int conn_clear_ratio = 50; +const int conv_clear_min = 1; +const int conn_clear_min = 1; -const u32_t conv_clear_interval=1000; -const u32_t conn_clear_interval=1000; +const u32_t conv_clear_interval = 1000; +const u32_t conn_clear_interval = 1000; +const i32_t max_fail_time = 0; // disable -const i32_t max_fail_time=0;//disable +const u32_t heartbeat_interval = 1000; -const u32_t heartbeat_interval=1000; +const u32_t timer_interval = 400; // this should be smaller than heartbeat_interval and retry interval; -const u32_t timer_interval=400;//this should be smaller than heartbeat_interval and retry interval; +// const uint32_t conv_timeout=120000; //120 second +// const u32_t conv_timeout=120000; //for test -//const uint32_t conv_timeout=120000; //120 second -//const u32_t conv_timeout=120000; //for test - -const u32_t client_conn_timeout=10000; -const u32_t client_conn_uplink_timeout=client_conn_timeout+2000; - -//const uint32_t server_conn_timeout=conv_timeout+60000;//this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth -const u32_t server_conn_timeout=conv_timeout+20000;//for test +const u32_t client_conn_timeout = 10000; +const u32_t client_conn_uplink_timeout = client_conn_timeout + 2000; +// const uint32_t server_conn_timeout=conv_timeout+60000;//this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth +const u32_t server_conn_timeout = conv_timeout + 20000; // for test extern int about_to_exit; -enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end}; +enum raw_mode_t { mode_faketcp = 0, + mode_udp, + mode_icmp, + mode_end }; extern raw_mode_t raw_mode; -enum program_mode_t {unset_mode=0,client_mode,server_mode}; +enum program_mode_t { unset_mode = 0, + client_mode, + server_mode }; extern program_mode_t program_mode; -extern unordered_map raw_mode_tostring ; +extern unordered_map raw_mode_tostring; -enum working_mode_t {unset_working_mode=0,tunnel_mode,tun_dev_mode}; +enum working_mode_t { unset_working_mode = 0, + tunnel_mode, + tun_dev_mode }; extern working_mode_t working_mode; extern int socket_buf_size; - -//typedef u32_t id_t; +// typedef u32_t id_t; typedef u64_t iv_t; @@ -177,31 +175,35 @@ typedef u64_t anti_replay_seq_t; typedef u64_t fd64_t; -//enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd64_ip_port_conv,type_fd64_conv/*,type_fd*/}; -enum dest_type{none=0,type_fd64_addr,type_fd64,type_fd,type_write_fd,type_fd_addr/*,type_fd*/}; +// enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd64_ip_port_conv,type_fd64_conv/*,type_fd*/}; +enum dest_type { none = 0, + type_fd64_addr, + type_fd64, + type_fd, + type_write_fd, + type_fd_addr /*,type_fd*/ }; /* struct ip_port_t { - u32_t ip; - int port; - void from_u64(u64_t u64); - u64_t to_u64(); - char * to_s(); + u32_t ip; + int port; + void from_u64(u64_t u64); + u64_t to_u64(); + char * to_s(); }; struct fd64_ip_port_t { - fd64_t fd64; - ip_port_t ip_port; + fd64_t fd64; + ip_port_t ip_port; }; struct fd_ip_port_t { - int fd; - ip_port_t ip_port; + int fd; + ip_port_t ip_port; };*/ - struct pseudo_header { u32_t source_address; u32_t dest_address; @@ -210,205 +212,181 @@ struct pseudo_header { unsigned short tcp_length; }; -u32_t djb2(unsigned char *str,int len); -u32_t sdbm(unsigned char *str,int len); +u32_t djb2(unsigned char *str, int len); +u32_t sdbm(unsigned char *str, int len); -struct address_t //TODO scope id +struct address_t // TODO scope id { - struct hash_function - { - u32_t operator()(const address_t &key) const - { - return sdbm((unsigned char*)&key.inner,sizeof(key.inner)); - } - }; + struct hash_function { + u32_t operator()(const address_t &key) const { + return sdbm((unsigned char *)&key.inner, sizeof(key.inner)); + } + }; - union storage_t //sockaddr_storage is too huge, we dont use it. - { - sockaddr_in ipv4; - sockaddr_in6 ipv6; - }; - storage_t inner; - - /*address_t() - { - clear(); - }*/ - void clear() - { - memset(&inner,0,sizeof(inner)); - } - /* - int from_ip_port(u32_t ip, int port) - { - clear(); - inner.ipv4.sin_family=AF_INET; - inner.ipv4.sin_port=htons(port); - inner.ipv4.sin_addr.s_addr=ip; - return 0; - }*/ - - int from_ip_port_new(int type, void * ip, int port) - { - clear(); - if(type==AF_INET) - { - inner.ipv4.sin_family=AF_INET; - inner.ipv4.sin_port=htons(port); - inner.ipv4.sin_addr.s_addr=*((u32_t *)ip); - } - else if(type==AF_INET6) - { - inner.ipv6.sin6_family=AF_INET6; - inner.ipv6.sin6_port=htons(port); - inner.ipv6.sin6_addr=*((in6_addr*)ip); - } - return 0; - } - - int from_str(char * str); - - int from_str_ip_only(char * str); - - int from_sockaddr(sockaddr *,socklen_t); - - char* get_str(); - void to_str(char *); - - inline int is_vaild() - { - u32_t ret=((sockaddr*)&inner)->sa_family; - return (ret==AF_INET||ret==AF_INET6); - } - - inline u32_t get_type() - { - assert(is_vaild()); - u32_t ret=((sockaddr*)&inner)->sa_family; - return ret; - } - - inline u32_t get_len() - { - u32_t type=get_type(); - switch(type) - { - case AF_INET: - return sizeof(sockaddr_in); - case AF_INET6: - return sizeof(sockaddr_in6); - default: - assert(0==1); - } - return -1; - } - - inline u32_t get_port() - { - u32_t type=get_type(); - switch(type) - { - case AF_INET: - return ntohs(inner.ipv4.sin_port); - case AF_INET6: - return ntohs(inner.ipv6.sin6_port); - default: - assert(0==1); - } - return -1; - } - - inline void set_port(int port) - { - u32_t type=get_type(); - switch(type) - { - case AF_INET: - inner.ipv4.sin_port=htons(port); - break; - case AF_INET6: - inner.ipv6.sin6_port=htons(port); - break; - default: - assert(0==1); - } - return ; - } - - bool operator == (const address_t &b) const + union storage_t // sockaddr_storage is too huge, we dont use it. { - //return this->data==b.data; - return memcmp(&this->inner,&b.inner,sizeof(this->inner))==0; + sockaddr_in ipv4; + sockaddr_in6 ipv6; + }; + storage_t inner; + + /*address_t() + { + clear(); + }*/ + void clear() { + memset(&inner, 0, sizeof(inner)); + } + /* + int from_ip_port(u32_t ip, int port) + { + clear(); + inner.ipv4.sin_family=AF_INET; + inner.ipv4.sin_port=htons(port); + inner.ipv4.sin_addr.s_addr=ip; + return 0; + }*/ + + int from_ip_port_new(int type, void *ip, int port) { + clear(); + if (type == AF_INET) { + inner.ipv4.sin_family = AF_INET; + inner.ipv4.sin_port = htons(port); + inner.ipv4.sin_addr.s_addr = *((u32_t *)ip); + } else if (type == AF_INET6) { + inner.ipv6.sin6_family = AF_INET6; + inner.ipv6.sin6_port = htons(port); + inner.ipv6.sin6_addr = *((in6_addr *)ip); + } + return 0; + } + + int from_str(char *str); + + int from_str_ip_only(char *str); + + int from_sockaddr(sockaddr *, socklen_t); + + char *get_str(); + void to_str(char *); + + inline int is_vaild() { + u32_t ret = ((sockaddr *)&inner)->sa_family; + return (ret == AF_INET || ret == AF_INET6); + } + + inline u32_t get_type() { + assert(is_vaild()); + u32_t ret = ((sockaddr *)&inner)->sa_family; + return ret; + } + + inline u32_t get_len() { + u32_t type = get_type(); + switch (type) { + case AF_INET: + return sizeof(sockaddr_in); + case AF_INET6: + return sizeof(sockaddr_in6); + default: + assert(0 == 1); + } + return -1; + } + + inline u32_t get_port() { + u32_t type = get_type(); + switch (type) { + case AF_INET: + return ntohs(inner.ipv4.sin_port); + case AF_INET6: + return ntohs(inner.ipv6.sin6_port); + default: + assert(0 == 1); + } + return -1; + } + + inline void set_port(int port) { + u32_t type = get_type(); + switch (type) { + case AF_INET: + inner.ipv4.sin_port = htons(port); + break; + case AF_INET6: + inner.ipv6.sin6_port = htons(port); + break; + default: + assert(0 == 1); + } + return; + } + + bool operator==(const address_t &b) const { + // return this->data==b.data; + return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0; } int new_connected_udp_fd(); - char* get_ip(); + char *get_ip(); }; namespace std { template <> - struct hash - { - std::size_t operator()(const address_t& key) const - { +struct hash { + std::size_t operator()(const address_t &key) const { + // return address_t::hash_function(k); + return sdbm((unsigned char *)&key.inner, sizeof(key.inner)); + } +}; +} // namespace std - //return address_t::hash_function(k); - return sdbm((unsigned char*)&key.inner,sizeof(key.inner)); - } - }; -} - -struct fd64_addr_t -{ - fd64_t fd64; - address_t addr; +struct fd64_addr_t { + fd64_t fd64; + address_t addr; }; -struct fd_addr_t -{ - int fd; - address_t addr; +struct fd_addr_t { + int fd; + address_t addr; }; -union inner_t -{ - fd64_t fd64; - int fd; - fd64_addr_t fd64_addr; - fd_addr_t fd_addr; +union inner_t { + fd64_t fd64; + int fd; + fd64_addr_t fd64_addr; + fd_addr_t fd_addr; }; -struct dest_t -{ - dest_type type; - inner_t inner; - u32_t conv; - int cook=0; +struct dest_t { + dest_type type; + inner_t inner; + u32_t conv; + int cook = 0; }; -struct fd_info_t -{ - address_t addr; - ev_io io_watcher; +struct fd_info_t { + address_t addr; + ev_io io_watcher; }; u64_t get_current_time(); -//u64_t get_current_time_rough(); +// u64_t get_current_time_rough(); u64_t get_current_time_us(); -u64_t pack_u64(u32_t a,u32_t b); +u64_t pack_u64(u32_t a, u32_t b); u32_t get_u64_h(u64_t a); u32_t get_u64_l(u64_t a); -void write_u16(char *,u16_t a); +void write_u16(char *, u16_t a); u16_t read_u16(char *); -void write_u32(char *,u32_t a); +void write_u32(char *, u32_t a); u32_t read_u32(char *); -void write_u64(char *,u64_t a); +void write_u64(char *, u64_t a); u64_t read_uu64(char *); -char * my_ntoa(u32_t ip); +char *my_ntoa(u32_t ip); void myexit(int a); void init_random_number_fd(); @@ -417,148 +395,135 @@ u32_t get_fake_random_number(); u32_t get_fake_random_number_nz(); u64_t ntoh64(u64_t a); u64_t hton64(u64_t a); -bool larger_than_u16(uint16_t a,uint16_t b); -bool larger_than_u32(u32_t a,u32_t b); +bool larger_than_u16(uint16_t a, uint16_t b); +bool larger_than_u32(u32_t a, u32_t b); void setnonblocking(int sock); -int set_buf_size(int fd,int socket_buf_size); +int set_buf_size(int fd, int socket_buf_size); -unsigned short csum(const unsigned short *ptr,int nbytes); -unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes); +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); -//int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3); +void signal_handler(int sig); +// int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len); +// int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3); void myexit(int a); int add_iptables_rule(char *); int clear_iptables_rule(); -void get_fake_random_chars(char * s,int len); -int random_between(u32_t a,u32_t b); +void get_fake_random_chars(char *s, int len); +int random_between(u32_t a, u32_t b); -int set_timer_ms(int epollfd,int &timer_fd,u32_t timer_interval); +int set_timer_ms(int epollfd, int &timer_fd, u32_t timer_interval); -int round_up_div(int a,int b); +int round_up_div(int a, int b); -int create_fifo(char * file); +int create_fifo(char *file); /* int create_new_udp(int &new_udp_fd,int remote_address_uint32,int remote_port); */ -int new_listen_socket(int &fd,u32_t ip,int port); +int new_listen_socket(int &fd, u32_t ip, int port); -int new_connected_socket(int &fd,u32_t ip,int port); +int new_connected_socket(int &fd, u32_t ip, int port); -int new_listen_socket2(int &fd,address_t &addr); -int new_connected_socket2(int &fd,address_t &addr,address_t *bind_addr,char *out_interface); +int new_listen_socket2(int &fd, address_t &addr); +int new_connected_socket2(int &fd, address_t &addr, address_t *bind_addr, char *out_interface); -struct not_copy_able_t -{ - not_copy_able_t() - { - - } - not_copy_able_t(const not_copy_able_t &other) - { - assert(0==1); - } - const not_copy_able_t & operator=(const not_copy_able_t &other) - { - assert(0==1); - return other; - } +struct not_copy_able_t { + not_copy_able_t() { + } + not_copy_able_t(const not_copy_able_t &other) { + assert(0 == 1); + } + const not_copy_able_t &operator=(const not_copy_able_t &other) { + assert(0 == 1); + return other; + } }; - template -struct lru_collector_t:not_copy_able_t -{ - //typedef void* key_t; -//#define key_t void* - struct lru_pair_t - { - key_t key; - my_time_t ts; - }; +struct lru_collector_t : not_copy_able_t { + // typedef void* key_t; + //#define key_t void* + struct lru_pair_t { + key_t key; + my_time_t ts; + }; - unordered_map::iterator> mp; + unordered_map::iterator> mp; - list q; - int update(key_t key) - { - assert(mp.find(key)!=mp.end()); - auto it=mp[key]; - q.erase(it); + list q; + int update(key_t key) { + assert(mp.find(key) != mp.end()); + auto it = mp[key]; + q.erase(it); - my_time_t value=get_current_time(); - if(!q.empty()) - { - assert(value >=q.front().ts); - } - lru_pair_t tmp; tmp.key=key; tmp.ts=value; - q.push_front( tmp); - mp[key]=q.begin(); + my_time_t value = get_current_time(); + if (!q.empty()) { + assert(value >= q.front().ts); + } + lru_pair_t tmp; + tmp.key = key; + tmp.ts = value; + q.push_front(tmp); + mp[key] = q.begin(); - return 0; - } - int new_key(key_t key) - { - assert(mp.find(key)==mp.end()); + return 0; + } + int new_key(key_t key) { + assert(mp.find(key) == mp.end()); - my_time_t value=get_current_time(); - if(!q.empty()) - { - assert(value >=q.front().ts); - } - lru_pair_t tmp; tmp.key=key; tmp.ts=value; - q.push_front( tmp); - mp[key]=q.begin(); + my_time_t value = get_current_time(); + if (!q.empty()) { + assert(value >= q.front().ts); + } + lru_pair_t tmp; + tmp.key = key; + tmp.ts = value; + q.push_front(tmp); + mp[key] = q.begin(); - return 0; - } - int size() - { - return q.size(); - } - int empty() - { - return q.empty(); - } - void clear() - { - mp.clear(); q.clear(); - } - my_time_t ts_of(key_t key) - { - assert(mp.find(key)!=mp.end()); - return mp[key]->ts; - } + return 0; + } + int size() { + return q.size(); + } + int empty() { + return q.empty(); + } + void clear() { + mp.clear(); + q.clear(); + } + my_time_t ts_of(key_t key) { + assert(mp.find(key) != mp.end()); + return mp[key]->ts; + } - my_time_t peek_back(key_t &key) - { - assert(!q.empty()); - auto it=q.end(); it--; - key=it->key; - return it->ts; - } - void erase(key_t key) - { - assert(mp.find(key)!=mp.end()); - q.erase(mp[key]); - mp.erase(key); - } - /* - void erase_back() - { - assert(!q.empty()); - auto it=q.end(); it--; - key_t key=it->key; - erase(key); - }*/ + my_time_t peek_back(key_t &key) { + assert(!q.empty()); + auto it = q.end(); + it--; + key = it->key; + return it->ts; + } + void erase(key_t key) { + assert(mp.find(key) != mp.end()); + q.erase(mp[key]); + mp.erase(key); + } + /* + void erase_back() + { + assert(!q.empty()); + auto it=q.end(); it--; + key_t key=it->key; + erase(key); + }*/ }; - -vector string_to_vec(const char * s,const char * sp) ; +vector string_to_vec(const char *s, const char *sp); #endif /* COMMON_H_ */ diff --git a/connection.cpp b/connection.cpp index 294cabc..9a0ee89 100644 --- a/connection.cpp +++ b/connection.cpp @@ -7,147 +7,124 @@ #include "connection.h" -//const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short. +// const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short. -const int disable_conn_clear=0;//a raw connection is called conn. +const int disable_conn_clear = 0; // a raw connection is called conn. -int report_interval=0; +int report_interval = 0; -void server_clear_function(u64_t u64)//used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection), -//so we have to close the fd when conv expires +void server_clear_function(u64_t u64) // used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection), +// so we have to close the fd when conv expires { - fd64_t fd64=u64; - assert(fd_manager.exist(fd64)); - ev_io &watcher= fd_manager.get_info(fd64).io_watcher; + fd64_t fd64 = u64; + assert(fd_manager.exist(fd64)); + ev_io &watcher = fd_manager.get_info(fd64).io_watcher; - address_t &addr=fd_manager.get_info(fd64).addr;// - assert(conn_manager.exist(addr));// - struct ev_loop *loop =conn_manager.find_insert(addr).loop; // overkill ? should we just use ev_default_loop(0)? + address_t &addr = fd_manager.get_info(fd64).addr; // + assert(conn_manager.exist(addr)); // + struct ev_loop *loop = conn_manager.find_insert(addr).loop; // overkill ? should we just use ev_default_loop(0)? - ev_io_stop(loop,&watcher); - - fd_manager.fd64_close(fd64); + ev_io_stop(loop, &watcher); + fd_manager.fd64_close(fd64); } - //////////////////////////////////////////////////////////////////// -conn_manager_t::conn_manager_t() -{ - mp.reserve(10007); - last_clear_time=0; +conn_manager_t::conn_manager_t() { + mp.reserve(10007); + last_clear_time = 0; } -int conn_manager_t::exist(address_t addr) -{ - - if(mp.find(addr)!=mp.end()) - { - return 1; - } - return 0; +int conn_manager_t::exist(address_t addr) { + if (mp.find(addr) != mp.end()) { + return 1; + } + return 0; } -conn_info_t *& conn_manager_t::find_insert_p(address_t addr) //be aware,the adress may change after rehash +conn_info_t *&conn_manager_t::find_insert_p(address_t addr) // be aware,the adress may change after rehash { -// u64_t u64=0; - //u64=ip; - //u64<<=32u; - //u64|=port; - unordered_map::iterator it=mp.find(addr); - if(it==mp.end()) - { - mp[addr]=new conn_info_t; - //lru.new_key(addr); - } - else - { - //lru.update(addr); - } - return mp[addr]; + // u64_t u64=0; + // u64=ip; + // u64<<=32u; + // u64|=port; + unordered_map::iterator it = mp.find(addr); + if (it == mp.end()) { + mp[addr] = new conn_info_t; + // lru.new_key(addr); + } else { + // lru.update(addr); + } + return mp[addr]; } -conn_info_t & conn_manager_t::find_insert(address_t addr) //be aware,the adress may change after rehash +conn_info_t &conn_manager_t::find_insert(address_t addr) // be aware,the adress may change after rehash { - //u64_t u64=0; - //u64=ip; - //u64<<=32u; - //u64|=port; - unordered_map::iterator it=mp.find(addr); - if(it==mp.end()) - { - mp[addr]=new conn_info_t; - //lru.new_key(addr); - } - else - { - //lru.update(addr); - } - return *mp[addr]; + // u64_t u64=0; + // u64=ip; + // u64<<=32u; + // u64|=port; + unordered_map::iterator it = mp.find(addr); + if (it == mp.end()) { + mp[addr] = new conn_info_t; + // lru.new_key(addr); + } else { + // lru.update(addr); + } + return *mp[addr]; } -int conn_manager_t::erase(unordered_map::iterator erase_it) -{ - delete(erase_it->second); - mp.erase(erase_it->first); - return 0; +int conn_manager_t::erase(unordered_map::iterator erase_it) { + delete (erase_it->second); + mp.erase(erase_it->first); + return 0; } -int conn_manager_t::clear_inactive() -{ - if(get_current_time()-last_clear_time>conn_clear_interval) - { - last_clear_time=get_current_time(); - return clear_inactive0(); - } - return 0; +int conn_manager_t::clear_inactive() { + if (get_current_time() - last_clear_time > conn_clear_interval) { + last_clear_time = get_current_time(); + return clear_inactive0(); + } + return 0; } -int conn_manager_t::clear_inactive0() -{ -//mylog(log_info,"called\n"); - unordered_map::iterator it; - unordered_map::iterator old_it; +int conn_manager_t::clear_inactive0() { + // mylog(log_info,"called\n"); + unordered_map::iterator it; + unordered_map::iterator old_it; - if(disable_conn_clear) return 0; + if (disable_conn_clear) return 0; - //map::iterator it; - int cnt=0; - it=clear_it;//TODO,write it back - int size=mp.size(); - int num_to_clean=size/conn_clear_ratio+conn_clear_min; //clear 1/10 each time,to avoid latency glitch + // map::iterator it; + int cnt = 0; + it = clear_it; // TODO,write it back + int size = mp.size(); + int num_to_clean = size / conn_clear_ratio + conn_clear_min; // clear 1/10 each time,to avoid latency glitch - //mylog(log_trace,"mp.size() %d\n", size); + // mylog(log_trace,"mp.size() %d\n", size); - num_to_clean=min(num_to_clean,(int)mp.size()); - u64_t current_time=get_current_time(); + num_to_clean = min(num_to_clean, (int)mp.size()); + u64_t current_time = get_current_time(); - //mylog(log_info,"here size=%d\n",(int)mp.size()); - for(;;) - { - if(cnt>=num_to_clean) break; - if(mp.begin()==mp.end()) break; - if(it==mp.end()) - { - it=mp.begin(); - } + // mylog(log_info,"here size=%d\n",(int)mp.size()); + for (;;) { + if (cnt >= num_to_clean) break; + if (mp.begin() == mp.end()) break; + if (it == mp.end()) { + it = mp.begin(); + } - if(it->second->conv_manager.s.get_size() >0) - { - //mylog(log_info,"[%s:%d]size %d \n",my_ntoa(get_u64_h(it->first)),get_u64_l(it->first),(int)it->second->conv_manager.get_size()); - it++; - } - else if(current_timesecond->last_active_time+server_conn_timeout) - { - it++; - } - else - { - address_t tmp_addr=it->first;// avoid making get_str() const; - mylog(log_info,"{%s} inactive conn cleared \n",tmp_addr.get_str()); - old_it=it; - it++; - erase(old_it); - } - cnt++; - } - clear_it=it; - return 0; + if (it->second->conv_manager.s.get_size() > 0) { + // mylog(log_info,"[%s:%d]size %d \n",my_ntoa(get_u64_h(it->first)),get_u64_l(it->first),(int)it->second->conv_manager.get_size()); + it++; + } else if (current_time < it->second->last_active_time + server_conn_timeout) { + it++; + } else { + address_t tmp_addr = it->first; // avoid making get_str() const; + mylog(log_info, "{%s} inactive conn cleared \n", tmp_addr.get_str()); + old_it = it; + it++; + erase(old_it); + } + cnt++; + } + clear_it = it; + return 0; } diff --git a/connection.h b/connection.h index 91a391f..615698b 100644 --- a/connection.h +++ b/connection.h @@ -19,365 +19,304 @@ extern int disable_anti_replay; extern int report_interval; -const int disable_conv_clear=0; +const int disable_conv_clear = 0; void server_clear_function(u64_t u64); -template +template struct conv_manager_t // manage the udp connections { - //typedef hash_map map; - unordered_map data_to_conv; //conv and u64 are both supposed to be uniq - unordered_map conv_to_data; + // typedef hash_map map; + unordered_map data_to_conv; // conv and u64 are both supposed to be uniq + unordered_map conv_to_data; - lru_collector_t lru; - //unordered_map conv_last_active_time; + lru_collector_t lru; + // unordered_map conv_last_active_time; - //unordered_map::iterator clear_it; + // unordered_map::iterator clear_it; - void (*additional_clear_function)(T data) =0; + void (*additional_clear_function)(T data) = 0; - long long last_clear_time; + long long last_clear_time; - conv_manager_t() - { - //clear_it=conv_last_active_time.begin(); - long long last_clear_time=0; - additional_clear_function=0; - } - ~conv_manager_t() - { - clear(); - } - int get_size() - { - return conv_to_data.size(); - } - void reserve() - { - data_to_conv.reserve(10007); - conv_to_data.reserve(10007); - //conv_last_active_time.reserve(10007); + conv_manager_t() { + // clear_it=conv_last_active_time.begin(); + long long last_clear_time = 0; + additional_clear_function = 0; + } + ~conv_manager_t() { + clear(); + } + int get_size() { + return conv_to_data.size(); + } + void reserve() { + data_to_conv.reserve(10007); + conv_to_data.reserve(10007); + // conv_last_active_time.reserve(10007); - lru.mp.reserve(10007); - } - void clear() - { - if(disable_conv_clear) return ; + lru.mp.reserve(10007); + } + void clear() { + if (disable_conv_clear) return; - if(additional_clear_function!=0) - { - for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++) - { - //int fd=int((it->second<<32u)>>32u); - additional_clear_function( it->second); - } - } - data_to_conv.clear(); - conv_to_data.clear(); + if (additional_clear_function != 0) { + for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) { + // int fd=int((it->second<<32u)>>32u); + additional_clear_function(it->second); + } + } + data_to_conv.clear(); + conv_to_data.clear(); - lru.clear(); - //conv_last_active_time.clear(); + lru.clear(); + // conv_last_active_time.clear(); - //clear_it=conv_last_active_time.begin(); + // clear_it=conv_last_active_time.begin(); + } + u32_t get_new_conv() { + u32_t conv = get_fake_random_number_nz(); + while (conv_to_data.find(conv) != conv_to_data.end()) { + conv = get_fake_random_number_nz(); + } + return conv; + } + int is_conv_used(u32_t conv) { + return conv_to_data.find(conv) != conv_to_data.end(); + } + int is_data_used(T data) { + return data_to_conv.find(data) != data_to_conv.end(); + } + u32_t find_conv_by_data(T data) { + return data_to_conv[data]; + } + T find_data_by_conv(u32_t conv) { + return conv_to_data[conv]; + } + int update_active_time(u32_t conv) { + // return conv_last_active_time[conv]=get_current_time(); + lru.update(conv); + return 0; + } + int insert_conv(u32_t conv, T data) { + data_to_conv[data] = conv; + conv_to_data[conv] = data; + // conv_last_active_time[conv]=get_current_time(); + lru.new_key(conv); + return 0; + } + int erase_conv(u32_t conv) { + if (disable_conv_clear) return 0; + T data = conv_to_data[conv]; + if (additional_clear_function != 0) { + additional_clear_function(data); + } + conv_to_data.erase(conv); + data_to_conv.erase(data); + // conv_last_active_time.erase(conv); + lru.erase(conv); + return 0; + } + int clear_inactive(char *info = 0) { + if (get_current_time() - last_clear_time > conv_clear_interval) { + last_clear_time = get_current_time(); + return clear_inactive0(info); + } + return 0; + } + int clear_inactive0(char *info) { + if (disable_conv_clear) return 0; - } - u32_t get_new_conv() - { - u32_t conv=get_fake_random_number_nz(); - while(conv_to_data.find(conv)!=conv_to_data.end()) - { - conv=get_fake_random_number_nz(); - } - return conv; - } - int is_conv_used(u32_t conv) - { - return conv_to_data.find(conv)!=conv_to_data.end(); - } - int is_data_used(T data) - { - return data_to_conv.find(data)!=data_to_conv.end(); - } - u32_t find_conv_by_data(T data) - { - return data_to_conv[data]; - } - T find_data_by_conv(u32_t conv) - { - return conv_to_data[conv]; - } - int update_active_time(u32_t conv) - { - //return conv_last_active_time[conv]=get_current_time(); - lru.update(conv); - return 0; - } - int insert_conv(u32_t conv,T data) - { - data_to_conv[data]=conv; - conv_to_data[conv]=data; - //conv_last_active_time[conv]=get_current_time(); - lru.new_key(conv); - return 0; - } - int erase_conv(u32_t conv) - { - if(disable_conv_clear) return 0; - T data=conv_to_data[conv]; - if(additional_clear_function!=0) - { - additional_clear_function(data); - } - conv_to_data.erase(conv); - data_to_conv.erase(data); - //conv_last_active_time.erase(conv); - lru.erase(conv); - return 0; - } - int clear_inactive(char * info=0) - { - if(get_current_time()-last_clear_time>conv_clear_interval) - { - last_clear_time=get_current_time(); - return clear_inactive0(info); - } - return 0; - } - int clear_inactive0(char * info) - { - if(disable_conv_clear) return 0; + unordered_map::iterator it; + unordered_map::iterator old_it; + // map::iterator it; + int cnt = 0; + // it=clear_it; + int size = lru.size(); + int num_to_clean = size / conv_clear_ratio + conv_clear_min; // clear 1/10 each time,to avoid latency glitch - unordered_map::iterator it; - unordered_map::iterator old_it; + num_to_clean = min(num_to_clean, size); - //map::iterator it; - int cnt=0; - //it=clear_it; - int size=lru.size(); - int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch + my_time_t current_time = get_current_time(); + for (;;) { + if (cnt >= num_to_clean) break; + if (lru.empty()) break; - num_to_clean=min(num_to_clean,size); + u32_t conv; + my_time_t ts = lru.peek_back(conv); - my_time_t current_time=get_current_time(); - for(;;) - { - if(cnt>=num_to_clean) break; - if(lru.empty()) break; + if (current_time - ts < conv_timeout) break; - u32_t conv; - my_time_t ts=lru.peek_back(conv); + erase_conv(conv); + if (info == 0) { + mylog(log_info, "conv %x cleared\n", conv); + } else { + mylog(log_info, "[%s]conv %x cleared\n", info, conv); + } + cnt++; + } + return 0; + } - if(current_time- ts < conv_timeout) break; + /* +conv_manager_t(); +~conv_manager_t(); +int get_size(); +void reserve(); +void clear(); +u32_t get_new_conv(); +int is_conv_used(u32_t conv); +int is_u64_used(T u64); +u32_t find_conv_by_u64(T u64); +T find_u64_by_conv(u32_t conv); +int update_active_time(u32_t conv); +int insert_conv(u32_t conv,T u64); +int erase_conv(u32_t conv); +int clear_inactive(char * ip_port=0); +int clear_inactive0(char * ip_port);*/ +}; // g_conv_manager; - erase_conv(conv); - if(info==0) - { - mylog(log_info,"conv %x cleared\n",conv); - } - else - { - mylog(log_info,"[%s]conv %x cleared\n",info,conv); - } - cnt++; - } - return 0; - } - - - /* - conv_manager_t(); - ~conv_manager_t(); - int get_size(); - void reserve(); - void clear(); - u32_t get_new_conv(); - int is_conv_used(u32_t conv); - int is_u64_used(T u64); - u32_t find_conv_by_u64(T u64); - T find_u64_by_conv(u32_t conv); - int update_active_time(u32_t conv); - int insert_conv(u32_t conv,T u64); - int erase_conv(u32_t conv); - int clear_inactive(char * ip_port=0); - int clear_inactive0(char * ip_port);*/ -};//g_conv_manager; - - - -struct inner_stat_t -{ - u64_t input_packet_num; - u64_t input_packet_size; - u64_t output_packet_num; - u64_t output_packet_size; +struct inner_stat_t { + u64_t input_packet_num; + u64_t input_packet_size; + u64_t output_packet_num; + u64_t output_packet_size; }; -struct stat_t -{ - u64_t last_report_time; - inner_stat_t normal_to_fec; - inner_stat_t fec_to_normal; - stat_t() - { - memset(this,0,sizeof(stat_t)); - } - void report_as_client() - { - if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000) - { - last_report_time=get_current_time(); - inner_stat_t &a=normal_to_fec; - inner_stat_t &b=fec_to_normal; - mylog(log_info,"[report]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt,%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n", - a.input_packet_num,a.input_packet_size,a.output_packet_num,a.output_packet_size, - b.output_packet_num,b.output_packet_size,b.input_packet_num,b.input_packet_size - ); - } - } - void report_as_server(address_t &addr) - { - if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000) - { - last_report_time=get_current_time(); - inner_stat_t &a=fec_to_normal; - inner_stat_t &b=normal_to_fec; - mylog(log_info,"[report][%s]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n", - addr.get_str(), - a.output_packet_num,a.output_packet_size,a.input_packet_num,a.input_packet_size, - b.input_packet_num,b.input_packet_size,b.output_packet_num,b.output_packet_size - ); - } - } +struct stat_t { + u64_t last_report_time; + inner_stat_t normal_to_fec; + inner_stat_t fec_to_normal; + stat_t() { + memset(this, 0, sizeof(stat_t)); + } + void report_as_client() { + if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) { + last_report_time = get_current_time(); + inner_stat_t &a = normal_to_fec; + inner_stat_t &b = fec_to_normal; + mylog(log_info, "[report]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt,%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n", + a.input_packet_num, a.input_packet_size, a.output_packet_num, a.output_packet_size, + b.output_packet_num, b.output_packet_size, b.input_packet_num, b.input_packet_size); + } + } + void report_as_server(address_t &addr) { + if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) { + last_report_time = get_current_time(); + inner_stat_t &a = fec_to_normal; + inner_stat_t &b = normal_to_fec; + mylog(log_info, "[report][%s]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n", + addr.get_str(), + a.output_packet_num, a.output_packet_size, a.input_packet_num, a.input_packet_size, + b.input_packet_num, b.input_packet_size, b.output_packet_num, b.output_packet_size); + } + } }; - -struct conn_info_t:not_copy_able_t //stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can -//handle multiple clients +struct conn_info_t : not_copy_able_t // stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can +// handle multiple clients { - union tmp_union_t - { - conv_manager_t c; - conv_manager_t s; - //avoid templates here and there, avoid pointer and type cast - tmp_union_t() - { - if(program_mode==client_mode) - { - new( &c ) conv_manager_t(); - } - else - { - assert(program_mode==server_mode); - new( &s ) conv_manager_t(); - } - } - ~tmp_union_t() - { - if(program_mode==client_mode) - { - c.~conv_manager_t(); - } - else - { - assert(program_mode==server_mode); - s.~conv_manager_t(); - } - } - }conv_manager; + union tmp_union_t { + conv_manager_t c; + conv_manager_t s; + // avoid templates here and there, avoid pointer and type cast + tmp_union_t() { + if (program_mode == client_mode) { + new (&c) conv_manager_t(); + } else { + assert(program_mode == server_mode); + new (&s) conv_manager_t(); + } + } + ~tmp_union_t() { + if (program_mode == client_mode) { + c.~conv_manager_t(); + } else { + assert(program_mode == server_mode); + s.~conv_manager_t(); + } + } + } conv_manager; + fec_encode_manager_t fec_encode_manager; + fec_decode_manager_t fec_decode_manager; + ev_timer timer; + // my_timer_t timer; - fec_encode_manager_t fec_encode_manager; - fec_decode_manager_t fec_decode_manager; - ev_timer timer; - //my_timer_t timer; + u64_t last_active_time; + stat_t stat; - u64_t last_active_time; - stat_t stat; + struct ev_loop *loop = 0; + int local_listen_fd; - struct ev_loop* loop=0; - int local_listen_fd; + int remote_fd; // only used for client + fd64_t remote_fd64; // only used for client - int remote_fd; //only used for client - fd64_t remote_fd64;//only used for client + // ip_port_t ip_port; + address_t addr; // only used for server - //ip_port_t ip_port; - address_t addr;//only used for server + conn_info_t() { + if (program_mode == server_mode) { + conv_manager.s.additional_clear_function = server_clear_function; + } else { + assert(program_mode == client_mode); + } + } - conn_info_t() - { - if(program_mode==server_mode) - { - conv_manager.s.additional_clear_function=server_clear_function; - } - else - { - assert(program_mode==client_mode); - } - } - - ~conn_info_t() - { - if(loop) - ev_timer_stop(loop,&timer); - } - void update_active_time() - { - last_active_time=get_current_time(); - } - /* - conn_info_t(const conn_info_t &b) - { - assert(0==1); - }*/ + ~conn_info_t() { + if (loop) + ev_timer_stop(loop, &timer); + } + void update_active_time() { + last_active_time = get_current_time(); + } + /* + conn_info_t(const conn_info_t &b) + { + assert(0==1); + }*/ }; /* struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections { - unordered_map mp;// to conn_info_t; - unordered_map::iterator clear_it; - long long last_clear_time; + unordered_map mp;// to conn_info_t; + unordered_map::iterator clear_it; + long long last_clear_time; - conn_manager_t(); - conn_manager_t(const conn_info_t &b) - { - assert(0==1); - } - int exist(ip_port_t); - conn_info_t *& find_p(ip_port_t); //be aware,the adress may change after rehash - conn_info_t & find(ip_port_t) ; //be aware,the adress may change after rehash - int insert(ip_port_t); + conn_manager_t(); + conn_manager_t(const conn_info_t &b) + { + assert(0==1); + } + int exist(ip_port_t); + conn_info_t *& find_p(ip_port_t); //be aware,the adress may change after rehash + conn_info_t & find(ip_port_t) ; //be aware,the adress may change after rehash + int insert(ip_port_t); - int erase(unordered_map::iterator erase_it); - int clear_inactive(); - int clear_inactive0(); + int erase(unordered_map::iterator erase_it); + int clear_inactive(); + int clear_inactive0(); };*/ -struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections +struct conn_manager_t // manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections { + unordered_map mp; // put it at end so that it de-consturcts first + unordered_map::iterator clear_it; + long long last_clear_time; - unordered_map mp; //put it at end so that it de-consturcts first - unordered_map::iterator clear_it; - - long long last_clear_time; - - conn_manager_t(); - int exist(address_t addr); - conn_info_t *& find_insert_p(address_t addr); //be aware,the adress may change after rehash //not true? - conn_info_t & find_insert(address_t addr) ; //be aware,the adress may change after rehash - - int erase(unordered_map::iterator erase_it); -int clear_inactive(); -int clear_inactive0(); + conn_manager_t(); + int exist(address_t addr); + conn_info_t *&find_insert_p(address_t addr); // be aware,the adress may change after rehash //not true? + conn_info_t &find_insert(address_t addr); // be aware,the adress may change after rehash + int erase(unordered_map::iterator erase_it); + int clear_inactive(); + int clear_inactive0(); }; - - extern conn_manager_t conn_manager; - #endif /* CONNECTION_H_ */ diff --git a/delay_manager.cpp b/delay_manager.cpp index fcb51b4..f8a9aa4 100644 --- a/delay_manager.cpp +++ b/delay_manager.cpp @@ -8,125 +8,106 @@ #include "log.h" #include "packet.h" -int delay_data_t::handle() -{ - return my_send(dest,data,len)>=0; +int delay_data_t::handle() { + return my_send(dest, data, len) >= 0; } +delay_manager_t::delay_manager_t() { + capacity = 0; -delay_manager_t::delay_manager_t() -{ - capacity=0; + // if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) + //{ + // mylog(log_fatal,"timer_fd create error"); + // myexit(1); + // } - //if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) - //{ - // mylog(log_fatal,"timer_fd create error"); - // myexit(1); - //} - - //itimerspec zero_its; - //memset(&zero_its, 0, sizeof(zero_its)); - - //timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); + // itimerspec zero_its; + // memset(&zero_its, 0, sizeof(zero_its)); + // timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); } -delay_manager_t::~delay_manager_t() -{ - //TODO ,we currently dont need to deconstruct it +delay_manager_t::~delay_manager_t() { + // TODO ,we currently dont need to deconstruct it } /* int delay_manager_t::get_timer_fd() { - return timer_fd; + return timer_fd; }*/ -//int add(my_time_t delay,const dest_t &dest,const char *data,int len); -int delay_manager_t::add(my_time_t delay,const dest_t &dest,char *data,int len) -{ - delay_data_t delay_data; - delay_data.dest=dest; - //delay_data.data=data; - delay_data.len=len; +// int add(my_time_t delay,const dest_t &dest,const char *data,int len); +int delay_manager_t::add(my_time_t delay, const dest_t &dest, char *data, int len) { + delay_data_t delay_data; + delay_data.dest = dest; + // delay_data.data=data; + delay_data.len = len; - if(capacity!=0&&int(delay_mp.size()) >=capacity) - { - mylog(log_warn,"max pending packet reached,ignored\n"); - return -1; - } - if(delay==0) - { - static char buf[buf_len]; - delay_data.data=buf; - memcpy(buf,data,len); - int ret=delay_data.handle(); - if (ret != 0) { - mylog(log_trace, "handle() return %d\n", ret); - } - return 0; - } + if (capacity != 0 && int(delay_mp.size()) >= capacity) { + mylog(log_warn, "max pending packet reached,ignored\n"); + return -1; + } + if (delay == 0) { + static char buf[buf_len]; + delay_data.data = buf; + memcpy(buf, data, len); + int ret = delay_data.handle(); + if (ret != 0) { + mylog(log_trace, "handle() return %d\n", ret); + } + return 0; + } - delay_data_t tmp=delay_data; - tmp.data=(char *)malloc(delay_data.len+100); - if(!tmp.data) - { + delay_data_t tmp = delay_data; + tmp.data = (char *)malloc(delay_data.len + 100); + if (!tmp.data) { mylog(log_warn, "malloc() returned null in delay_manager_t::add()"); return -1; } - memcpy(tmp.data,data,delay_data.len); + memcpy(tmp.data, data, delay_data.len); - my_time_t tmp_time=get_current_time_us(); - tmp_time+=delay; + my_time_t tmp_time = get_current_time_us(); + tmp_time += delay; - delay_mp.insert(make_pair(tmp_time,tmp)); + delay_mp.insert(make_pair(tmp_time, tmp)); - ////check(); check everytime when add, is it better ?? + ////check(); check everytime when add, is it better ?? - return 0; + return 0; } -int delay_manager_t::check() -{ - if(!delay_mp.empty()) - { - my_time_t current_time; +int delay_manager_t::check() { + if (!delay_mp.empty()) { + my_time_t current_time; - multimap::iterator it; - while(1) - { - int ret=0; - it=delay_mp.begin(); - if(it==delay_mp.end()) break; + multimap::iterator it; + while (1) { + int ret = 0; + it = delay_mp.begin(); + if (it == delay_mp.end()) break; - current_time=get_current_time_us(); - if(it->first <= current_time) - { - ret=it->second.handle(); - if (ret != 0) { - mylog(log_trace, "handle() return %d\n", ret); - } - free(it->second.data); - delay_mp.erase(it); - } - else - { - break; - } - - } - if(!delay_mp.empty()) - { - const double m=1000*1000; - double timer_value=delay_mp.begin()->first/m -get_current_time_us()/m; // be aware of negative value, and be aware of uint - if(timer_value<0) timer_value=0; // set it to 0 if negative, although libev support negative value - ev_timer_stop(loop, &timer); - ev_timer_set(&timer, timer_value,0 ); - ev_timer_start(loop, &timer); - } - else - { - ev_timer_stop(loop, &timer); //not necessary - } - } - return 0; + current_time = get_current_time_us(); + if (it->first <= current_time) { + ret = it->second.handle(); + if (ret != 0) { + mylog(log_trace, "handle() return %d\n", ret); + } + free(it->second.data); + delay_mp.erase(it); + } else { + break; + } + } + if (!delay_mp.empty()) { + const double m = 1000 * 1000; + double timer_value = delay_mp.begin()->first / m - get_current_time_us() / m; // be aware of negative value, and be aware of uint + if (timer_value < 0) timer_value = 0; // set it to 0 if negative, although libev support negative value + ev_timer_stop(loop, &timer); + ev_timer_set(&timer, timer_value, 0); + ev_timer_start(loop, &timer); + } else { + ev_timer_stop(loop, &timer); // not necessary + } + } + return 0; } diff --git a/delay_manager.h b/delay_manager.h index 1bab80f..48f624e 100644 --- a/delay_manager.h +++ b/delay_manager.h @@ -12,132 +12,130 @@ #include "packet.h" #include "log.h" -//enum delay_type_t {none=0,enum_sendto_u64,enum_send_fd,client_to_local,client_to_remote,server_to_local,server_to_remote}; +// enum delay_type_t {none=0,enum_sendto_u64,enum_send_fd,client_to_local,client_to_remote,server_to_local,server_to_remote}; /* struct fd_ip_port_t { - int fd; - u32_t ip; - u32_t port; + int fd; + u32_t ip; + u32_t port; }; union dest_t { - fd_ip_port_t fd_ip_port; - int fd; - u64_t u64; + fd_ip_port_t fd_ip_port; + int fd; + u64_t u64; }; */ /* struct my_timer_t { - int timer_fd; - fd64_t timer_fd64; - my_timer_t() - { - if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) - { - mylog(log_fatal,"timer_fd create error"); - myexit(1); - } - timer_fd64=fd_manager.create(timer_fd); - } - my_timer_t(const my_timer_t &b) - { - assert(0==1); - } - ~my_timer_t() - { - fd_manager.fd64_close(timer_fd64); - } - int add_fd_to_epoll(int epoll_fd) - { - epoll_event ev;; - ev.events = EPOLLIN; - ev.data.u64 = timer_fd; - int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev); - if (ret!= 0) { - mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); - myexit(-1); - } - return 0; - } - int add_fd64_to_epoll(int epoll_fd) - { - epoll_event ev;; - ev.events = EPOLLIN; - ev.data.u64 = timer_fd64; - int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev); - if (ret!= 0) { - mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); - myexit(-1); - } - return 0; - } - int get_timer_fd() - { - return timer_fd; - } - fd64_t get_timer_fd64() - { - return timer_fd64; - } - int set_timer_repeat_us(my_time_t my_time) - { - itimerspec its; - memset(&its,0,sizeof(its)); - its.it_interval.tv_sec=my_time/1000000llu; - its.it_interval.tv_nsec=my_time%1000000llu*1000llu; - its.it_value.tv_nsec=1; //imidiately - timerfd_settime(timer_fd,0,&its,0); - return 0; - } - int set_timer_abs_us(my_time_t my_time) - { - itimerspec its; - memset(&its,0,sizeof(its)); - its.it_value.tv_sec=my_time/1000000llu; - its.it_value.tv_nsec=my_time%1000000llu*1000llu; - timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0); - return 0; - } + int timer_fd; + fd64_t timer_fd64; + my_timer_t() + { + if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) + { + mylog(log_fatal,"timer_fd create error"); + myexit(1); + } + timer_fd64=fd_manager.create(timer_fd); + } + my_timer_t(const my_timer_t &b) + { + assert(0==1); + } + ~my_timer_t() + { + fd_manager.fd64_close(timer_fd64); + } + int add_fd_to_epoll(int epoll_fd) + { + epoll_event ev;; + ev.events = EPOLLIN; + ev.data.u64 = timer_fd; + int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev); + if (ret!= 0) { + mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); + myexit(-1); + } + return 0; + } + int add_fd64_to_epoll(int epoll_fd) + { + epoll_event ev;; + ev.events = EPOLLIN; + ev.data.u64 = timer_fd64; + int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev); + if (ret!= 0) { + mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); + myexit(-1); + } + return 0; + } + int get_timer_fd() + { + return timer_fd; + } + fd64_t get_timer_fd64() + { + return timer_fd64; + } + int set_timer_repeat_us(my_time_t my_time) + { + itimerspec its; + memset(&its,0,sizeof(its)); + its.it_interval.tv_sec=my_time/1000000llu; + its.it_interval.tv_nsec=my_time%1000000llu*1000llu; + its.it_value.tv_nsec=1; //imidiately + timerfd_settime(timer_fd,0,&its,0); + return 0; + } + int set_timer_abs_us(my_time_t my_time) + { + itimerspec its; + memset(&its,0,sizeof(its)); + its.it_value.tv_sec=my_time/1000000llu; + its.it_value.tv_nsec=my_time%1000000llu*1000llu; + timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0); + return 0; + } };*/ - -struct delay_data_t -{ - dest_t dest; - //int left_time;// - char * data; - int len; - int handle(); +struct delay_data_t { + dest_t dest; + // int left_time;// + char *data; + int len; + int handle(); }; -struct delay_manager_t -{ - ev_timer timer; - struct ev_loop *loop=0; - void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)=0; +struct delay_manager_t { + ev_timer timer; + struct ev_loop *loop = 0; + void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0; - //int timer_fd; - int capacity; - multimap delay_mp; //unit us,1 us=0.001ms - delay_manager_t(); - delay_manager_t(delay_manager_t &b) - { - assert(0==1); - } - void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)) - { - this->loop=loop; - this->cb=cb; - ev_init(&timer,cb); - } - int set_capacity(int a){capacity=a;return 0;} - ~delay_manager_t(); - ev_timer& get_timer(); - int check(); - int add(my_time_t delay,const dest_t &dest,char *data,int len); + // int timer_fd; + int capacity; + multimap delay_mp; // unit us,1 us=0.001ms + delay_manager_t(); + delay_manager_t(delay_manager_t &b) { + assert(0 == 1); + } + void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) { + this->loop = loop; + this->cb = cb; + ev_init(&timer, cb); + } + int set_capacity(int a) { + capacity = a; + return 0; + } + ~delay_manager_t(); + ev_timer &get_timer(); + int check(); + int add(my_time_t delay, const dest_t &dest, char *data, int len); }; #endif /* DELAY_MANAGER_H_ */ diff --git a/fd_manager.cpp b/fd_manager.cpp index da249bd..eb5f340 100644 --- a/fd_manager.cpp +++ b/fd_manager.cpp @@ -5,59 +5,48 @@ * Author: root */ - #include "fd_manager.h" -int fd_manager_t::fd_exist(int fd) -{ - return fd_to_fd64_mp.find(fd)!=fd_to_fd64_mp.end(); +int fd_manager_t::fd_exist(int fd) { + return fd_to_fd64_mp.find(fd) != fd_to_fd64_mp.end(); } -int fd_manager_t::exist(fd64_t fd64) -{ - return fd64_to_fd_mp.find(fd64)!=fd64_to_fd_mp.end(); +int fd_manager_t::exist(fd64_t fd64) { + return fd64_to_fd_mp.find(fd64) != fd64_to_fd_mp.end(); } -int fd_manager_t::to_fd(fd64_t fd64) -{ - assert(exist(fd64)); - return fd64_to_fd_mp[fd64]; +int fd_manager_t::to_fd(fd64_t fd64) { + assert(exist(fd64)); + return fd64_to_fd_mp[fd64]; } -void fd_manager_t::fd64_close(fd64_t fd64) -{ - assert(exist(fd64)); - int fd=fd64_to_fd_mp[fd64]; - fd64_to_fd_mp.erase(fd64); - fd_to_fd64_mp.erase(fd); - if(exist_info(fd64)) - { - fd_info_mp.erase(fd64); - } - sock_close(fd); +void fd_manager_t::fd64_close(fd64_t fd64) { + assert(exist(fd64)); + int fd = fd64_to_fd_mp[fd64]; + fd64_to_fd_mp.erase(fd64); + fd_to_fd64_mp.erase(fd); + if (exist_info(fd64)) { + fd_info_mp.erase(fd64); + } + sock_close(fd); } -void fd_manager_t::reserve(int n) -{ - fd_to_fd64_mp.reserve(n); - fd64_to_fd_mp.reserve(n); - fd_info_mp.reserve(n); +void fd_manager_t::reserve(int n) { + fd_to_fd64_mp.reserve(n); + fd64_to_fd_mp.reserve(n); + fd_info_mp.reserve(n); } -u64_t fd_manager_t::create(int fd) -{ - assert(!fd_exist(fd)); - fd64_t fd64=counter++; - fd_to_fd64_mp[fd]=fd64; - fd64_to_fd_mp[fd64]=fd; - return fd64; +u64_t fd_manager_t::create(int fd) { + assert(!fd_exist(fd)); + fd64_t fd64 = counter++; + fd_to_fd64_mp[fd] = fd64; + fd64_to_fd_mp[fd64] = fd; + return fd64; } -fd_manager_t::fd_manager_t() -{ - counter=u32_t(-1); - counter+=100; - reserve(10007); +fd_manager_t::fd_manager_t() { + counter = u32_t(-1); + counter += 100; + reserve(10007); } -fd_info_t & fd_manager_t::get_info(fd64_t fd64) -{ - assert(exist(fd64)); - return fd_info_mp[fd64]; +fd_info_t& fd_manager_t::get_info(fd64_t fd64) { + assert(exist(fd64)); + return fd_info_mp[fd64]; } -int fd_manager_t::exist_info(fd64_t fd64) -{ - return fd_info_mp.find(fd64)!=fd_info_mp.end(); +int fd_manager_t::exist_info(fd64_t fd64) { + return fd_info_mp.find(fd64) != fd_info_mp.end(); } diff --git a/fd_manager.h b/fd_manager.h index c48db26..33e7149 100644 --- a/fd_manager.h +++ b/fd_manager.h @@ -11,27 +11,26 @@ #include "common.h" #include "packet.h" - - -struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create -//this class is not strictly necessary,it just makes epoll fd handling easier +struct fd_manager_t // conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create +// this class is not strictly necessary,it just makes epoll fd handling easier { - fd_info_t & get_info(fd64_t fd64); - int exist_info(fd64_t); - int exist(fd64_t fd64); - int to_fd(fd64_t); - void fd64_close(fd64_t fd64); - void reserve(int n); - u64_t create(int fd); - fd_manager_t(); -private: - u64_t counter; - unordered_map fd_to_fd64_mp; - unordered_map fd64_to_fd_mp; - unordered_map fd_info_mp; - int fd_exist(int fd); - //void remove_fd(int fd); - //fd64_t fd_to_fd64(int fd); + fd_info_t& get_info(fd64_t fd64); + int exist_info(fd64_t); + int exist(fd64_t fd64); + int to_fd(fd64_t); + void fd64_close(fd64_t fd64); + void reserve(int n); + u64_t create(int fd); + fd_manager_t(); + + private: + u64_t counter; + unordered_map fd_to_fd64_mp; + unordered_map fd64_to_fd_mp; + unordered_map fd_info_mp; + int fd_exist(int fd); + // void remove_fd(int fd); + // fd64_t fd_to_fd64(int fd); }; extern fd_manager_t fd_manager; diff --git a/fec_manager.cpp b/fec_manager.cpp index 960e95e..5d132c8 100644 --- a/fec_manager.cpp +++ b/fec_manager.cpp @@ -11,917 +11,787 @@ #include "lib/rs.h" #include "fd_manager.h" -//int g_fec_data_num=20; -//int g_fec_redundant_num=10; -//int g_fec_mtu=1250; -//int g_fec_queue_len=200; -//int g_fec_timeout=8*1000; //8ms -//int g_fec_mode=0; +// int g_fec_data_num=20; +// int g_fec_redundant_num=10; +// int g_fec_mtu=1250; +// int g_fec_queue_len=200; +// int g_fec_timeout=8*1000; //8ms +// int g_fec_mode=0; fec_parameter_t g_fec_par; -int debug_fec_enc=0; -int debug_fec_dec=0; -//int dynamic_update_fec=1; +int debug_fec_enc = 0; +int debug_fec_dec = 0; +// int dynamic_update_fec=1; -const int encode_fast_send=1; -const int decode_fast_send=1; +const int encode_fast_send = 1; +const int decode_fast_send = 1; -int short_packet_optimize=1; -int header_overhead=40; +int short_packet_optimize = 1; +int header_overhead = 40; -u32_t fec_buff_num=2000;// how many packet can fec_decode_manager hold. shouldnt be very large,or it will cost huge memory +u32_t fec_buff_num = 2000; // how many packet can fec_decode_manager hold. shouldnt be very large,or it will cost huge memory - -blob_encode_t::blob_encode_t() -{ - clear(); +blob_encode_t::blob_encode_t() { + clear(); } -int blob_encode_t::clear() -{ - counter=0; - current_len=(int)sizeof(u32_t); - return 0; +int blob_encode_t::clear() { + counter = 0; + current_len = (int)sizeof(u32_t); + return 0; } -int blob_encode_t::get_num() -{ - return counter; +int blob_encode_t::get_num() { + return counter; } -int blob_encode_t::get_shard_len(int n) -{ - return round_up_div(current_len,n); +int blob_encode_t::get_shard_len(int n) { + return round_up_div(current_len, n); } -int blob_encode_t::get_shard_len(int n,int next_packet_len) -{ - return round_up_div(current_len+(int)sizeof(u16_t)+next_packet_len,n); +int blob_encode_t::get_shard_len(int n, int next_packet_len) { + return round_up_div(current_len + (int)sizeof(u16_t) + next_packet_len, n); } -int blob_encode_t::input(char *s,int len) -{ - assert(current_len+len+sizeof(u16_t) +100=0); - counter++; - assert(counter<=max_blob_packet_num); - write_u16(input_buf+current_len,len); - current_len+=sizeof(u16_t); - memcpy(input_buf+current_len,s,len); - current_len+=len; - return 0; +int blob_encode_t::input(char *s, int len) { + assert(current_len + len + sizeof(u16_t) + 100 < sizeof(input_buf)); + assert(len <= 65535 && len >= 0); + counter++; + assert(counter <= max_blob_packet_num); + write_u16(input_buf + current_len, len); + current_len += sizeof(u16_t); + memcpy(input_buf + current_len, s, len); + current_len += len; + return 0; } -int blob_encode_t::output(int n,char ** &s_arr,int & len) -{ - len=round_up_div(current_len,n); - write_u32(input_buf,counter); - for(int i=0;i current_len) { + mylog(log_info, "failed 0\n"); + return -1; + } - if(parser_pos+(int)sizeof(u32_t)>current_len) {mylog(log_info,"failed 0\n");return -1;} + n = (int)read_u32(input_buf + parser_pos); + if (n > max_blob_packet_num) { + mylog(log_info, "failed 1\n"); + return -1; + } + s_arr = output_buf; + len_arr = output_len; - n=(int)read_u32(input_buf+parser_pos); - if(n>max_blob_packet_num) {mylog(log_info,"failed 1\n");return -1;} - s_arr=output_buf; - len_arr=output_len; - - parser_pos+=sizeof(u32_t); - for(int i=0;icurrent_len) {mylog(log_info,"failed2 \n");return -1;} - len_arr[i]=(int)read_u16(input_buf+parser_pos); - parser_pos+=(int)sizeof(u16_t); - if(parser_pos+len_arr[i]>current_len) {mylog(log_info,"failed 3 %d %d %d\n",parser_pos,len_arr[i],current_len);return -1;} - s_arr[i]=input_buf+parser_pos; - parser_pos+=len_arr[i]; - } - return 0; + parser_pos += sizeof(u32_t); + for (int i = 0; i < n; i++) { + if (parser_pos + (int)sizeof(u16_t) > current_len) { + mylog(log_info, "failed2 \n"); + return -1; + } + len_arr[i] = (int)read_u16(input_buf + parser_pos); + parser_pos += (int)sizeof(u16_t); + if (parser_pos + len_arr[i] > current_len) { + mylog(log_info, "failed 3 %d %d %d\n", parser_pos, len_arr[i], current_len); + return -1; + } + s_arr[i] = input_buf + parser_pos; + parser_pos += len_arr[i]; + } + return 0; } - -fec_encode_manager_t::~fec_encode_manager_t() -{ - clear_all(); - //fd_manager.fd64_close(timer_fd64); +fec_encode_manager_t::~fec_encode_manager_t() { + clear_all(); + // fd_manager.fd64_close(timer_fd64); } /* u64_t fec_encode_manager_t::get_timer_fd64() { - return timer_fd64; + return timer_fd64; }*/ -fec_encode_manager_t::fec_encode_manager_t() -{ - //int timer_fd; +fec_encode_manager_t::fec_encode_manager_t() { + // int timer_fd; - /* - if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) - { - mylog(log_fatal,"timer_fd create error"); - myexit(1); - } - timer_fd64=fd_manager.create(timer_fd);*/ + /* + if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) + { + mylog(log_fatal,"timer_fd create error"); + myexit(1); + } + timer_fd64=fd_manager.create(timer_fd);*/ + /////reset_fec_parameter(g_fec_data_num,g_fec_redundant_num,g_fec_mtu,g_fec_queue_len,g_fec_timeout,g_fec_mode); - /////reset_fec_parameter(g_fec_data_num,g_fec_redundant_num,g_fec_mtu,g_fec_queue_len,g_fec_timeout,g_fec_mode); - - fec_par.clone(g_fec_par); - clear_data(); - + fec_par.clone(g_fec_par); + clear_data(); } /* int fec_encode_manager_t::reset_fec_parameter(int data_num,int redundant_num,int mtu,int queue_len,int timeout,int mode) { - fec_data_num=data_num; - fec_redundant_num=redundant_num; - fec_mtu=mtu; - fec_queue_len=queue_len; - fec_timeout=timeout; - fec_mode=mode; + fec_data_num=data_num; + fec_redundant_num=redundant_num; + fec_mtu=mtu; + fec_queue_len=queue_len; + fec_timeout=timeout; + fec_mode=mode; - assert(data_num+redundant_num=0); - //assert(len<=fec_mtu);//relax this limitation - char * p=input_buf[counter]+sizeof(u32_t)+4*sizeof(char);//copy directly to final position,avoid unnecessary copy. - //remember to change this,if protocol is modified - - write_u16(p,(u16_t)((u32_t)len)); //TODO omit this u16 for data packet while sending - p+=sizeof(u16_t); - memcpy(p,s,len); - input_len[counter]=len+sizeof(u16_t); - } - else - { - assert(0==1); - } - counter++; - return 0; -} -int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/) -{ - if(counter==0&&fec_par.version!=g_fec_par.version) - { - fec_par.clone(g_fec_par); - } - - int about_to_fec=0; - int delayed_append=0; - //int counter_back=counter; - assert(fec_par.mode==0||fec_par.mode==1); - - if(fec_par.mode==0&& s!=0 &&counter==0) - { - int out_len=blob_encode.get_shard_len(fec_par.get_tail().x,len); - if(out_len>fec_par.mtu) - { - mylog(log_warn,"message too long ori_len=%d out_len=%d fec_mtu=%d,ignored\n",len,out_len,fec_par.mtu); - return -1; - } - } - if(fec_par.mode==1&&s!=0&&len>fec_par.mtu) - { - mylog(log_warn,"mode==1,message len=%d,len>fec_mtu,fec_mtu=%d,packet may not be delivered\n",len,fec_par.mtu); - //return -1; - } - if(s==0&&counter==0) - { - mylog(log_warn,"unexpected s==0&&counter==0\n"); - return -1; - } - if(s==0) about_to_fec=1;//now - - if(fec_par.mode==0&& blob_encode.get_shard_len(fec_par.get_tail().x,len)>fec_par.mtu) {about_to_fec=1; delayed_append=1;}//fec then add packet - - if(fec_par.mode==0) assert(counter(u32_t)fec_par.mtu) continue; - - u32_t new_len=(shard_len+header_overhead)*(tmp_x+tmp_y); - if(new_len=1&&best_data_num<=fec_par.rs_cnt); - actual_redundant_num=fec_par.rs_par[best_data_num-1].y; - } - - assert(blob_encode.output(actual_data_num,blob_output,fec_len)==0); - - if(debug_fec_enc) - mylog(log_debug,"[enc]seq=%08x x=%d y=%d len=%d cnt=%d\n",seq,actual_data_num,actual_redundant_num,fec_len,counter); - else - mylog(log_trace,"[enc]seq=%08x x=%d y=%d len=%d cnt=%d\n",seq,actual_data_num,actual_redundant_num,fec_len,counter); - } - else - { - assert(counter<=fec_par.rs_cnt); - actual_data_num=counter; - actual_redundant_num=fec_par.rs_par[counter-1].y; - - int sum_ori=0; - for(int i=0;i=0); - if(input_len[i]>fec_len) fec_len=input_len[i]; - } - - int sum=fec_len*counter; - - if(debug_fec_enc) - mylog(log_debug,"[enc]seq=%08x x=%d y=%d len=%d sum_ori=%d sum=%d\n",seq,actual_data_num,actual_redundant_num,fec_len,sum_ori,sum); - else - mylog(log_trace,"[enc]seq=%08x x=%d y=%d len=%d sum_ori=%d sum=%d\n",seq,actual_data_num,actual_redundant_num,fec_len,sum_ori,sum); - } - - //mylog(log_trace,"%d %d %d\n",actual_data_num,actual_redundant_num,fec_len); - - char *tmp_output_buf[max_fec_packet_num+5]={0}; - for(int i=0;i=1); - assert(counter<=255); - int input_buf_idx=counter-1; - assert(ready_for_output==0); - ready_for_output=1; - first_packet_time_for_output=0; - output_n=1; + assert(blob_encode.input(s, len) == 0); + } else if (fec_par.mode == 1) // for tpe 1 use input_buf and counter + { + mylog(log_trace, "counter=%d\n", counter); + assert(len <= 65535 && len >= 0); + // assert(len<=fec_mtu);//relax this limitation + char *p = input_buf[counter] + sizeof(u32_t) + 4 * sizeof(char); // copy directly to final position,avoid unnecessary copy. + // remember to change this,if protocol is modified - - int tmp_idx=0; - write_u32(input_buf[input_buf_idx]+tmp_idx,seq); - tmp_idx+=sizeof(u32_t); - - input_buf[input_buf_idx][tmp_idx++]=(unsigned char)fec_par.mode; - input_buf[input_buf_idx][tmp_idx++]=(unsigned char)0; - input_buf[input_buf_idx][tmp_idx++]=(unsigned char)0; - input_buf[input_buf_idx][tmp_idx++]=(unsigned char)((u32_t)input_buf_idx); - - output_len[0]=input_len[input_buf_idx]+tmp_idx; - output_buf[0]=input_buf[input_buf_idx]; - - if(0) - { - printf("seq=%u,buf_idx=%d\n",seq,input_buf_idx); - for(int j=0;j fec_par.mtu) { + mylog(log_warn, "message too long ori_len=%d out_len=%d fec_mtu=%d,ignored\n", len, out_len, fec_par.mtu); + return -1; + } + } + if (fec_par.mode == 1 && s != 0 && len > fec_par.mtu) { + mylog(log_warn, "mode==1,message len=%d,len>fec_mtu,fec_mtu=%d,packet may not be delivered\n", len, fec_par.mtu); + // return -1; + } + if (s == 0 && counter == 0) { + mylog(log_warn, "unexpected s==0&&counter==0\n"); + return -1; + } + if (s == 0) about_to_fec = 1; // now + + if (fec_par.mode == 0 && blob_encode.get_shard_len(fec_par.get_tail().x, len) > fec_par.mtu) { + about_to_fec = 1; + delayed_append = 1; + } // fec then add packet + + if (fec_par.mode == 0) assert(counter < fec_par.queue_len); // counter will never equal fec_pending_num,if that happens fec should already been done. + if (fec_par.mode == 1) assert(counter < fec_par.get_tail().x); + + if (s != 0 && !delayed_append) { + append(s, len); + } + + if (fec_par.mode == 0 && counter == fec_par.queue_len) about_to_fec = 1; + + if (fec_par.mode == 1 && counter == fec_par.get_tail().x) about_to_fec = 1; + + if (about_to_fec) { + char **blob_output = 0; + int fec_len = -1; + mylog(log_trace, "counter=%d\n", counter); + + if (counter == 0) { + mylog(log_warn, "unexpected counter==0 here\n"); + return -1; + } + + int actual_data_num; + int actual_redundant_num; + + if (fec_par.mode == 0) { + int tail_x = fec_par.get_tail().x; + int tail_y = fec_par.get_tail().y; + actual_data_num = tail_x; + actual_redundant_num = tail_y; + + if (short_packet_optimize) { + u32_t best_len = (blob_encode.get_shard_len(tail_x, 0) + header_overhead) * (tail_x + tail_y); + int best_data_num = tail_x; + assert(tail_x <= fec_par.rs_cnt); + for (int i = 1; i < tail_x; i++) { + assert(fec_par.rs_par[i - 1].x == i); + int tmp_x = fec_par.rs_par[i - 1].x; + int tmp_y = fec_par.rs_par[i - 1].y; + assert(tmp_x == i); + u32_t shard_len = blob_encode.get_shard_len(tmp_x, 0); + if (shard_len > (u32_t)fec_par.mtu) continue; + + u32_t new_len = (shard_len + header_overhead) * (tmp_x + tmp_y); + if (new_len < best_len) { + best_len = new_len; + best_data_num = tmp_x; + } + } + actual_data_num = best_data_num; + assert(best_data_num >= 1 && best_data_num <= fec_par.rs_cnt); + actual_redundant_num = fec_par.rs_par[best_data_num - 1].y; + } + + assert(blob_encode.output(actual_data_num, blob_output, fec_len) == 0); + + if (debug_fec_enc) + mylog(log_debug, "[enc]seq=%08x x=%d y=%d len=%d cnt=%d\n", seq, actual_data_num, actual_redundant_num, fec_len, counter); + else + mylog(log_trace, "[enc]seq=%08x x=%d y=%d len=%d cnt=%d\n", seq, actual_data_num, actual_redundant_num, fec_len, counter); + } else { + assert(counter <= fec_par.rs_cnt); + actual_data_num = counter; + actual_redundant_num = fec_par.rs_par[counter - 1].y; + + int sum_ori = 0; + for (int i = 0; i < counter; i++) { + sum_ori += input_len[i]; + assert(input_len[i] >= 0); + if (input_len[i] > fec_len) fec_len = input_len[i]; + } + + int sum = fec_len * counter; + + if (debug_fec_enc) + mylog(log_debug, "[enc]seq=%08x x=%d y=%d len=%d sum_ori=%d sum=%d\n", seq, actual_data_num, actual_redundant_num, fec_len, sum_ori, sum); + else + mylog(log_trace, "[enc]seq=%08x x=%d y=%d len=%d sum_ori=%d sum=%d\n", seq, actual_data_num, actual_redundant_num, fec_len, sum_ori, sum); + } + + // mylog(log_trace,"%d %d %d\n",actual_data_num,actual_redundant_num,fec_len); + + char *tmp_output_buf[max_fec_packet_num + 5] = {0}; + for (int i = 0; i < actual_data_num + actual_redundant_num; i++) { + int tmp_idx = 0; + + write_u32(input_buf[i] + tmp_idx, seq); + tmp_idx += sizeof(u32_t); + input_buf[i][tmp_idx++] = (unsigned char)fec_par.mode; + if (fec_par.mode == 1 && i < actual_data_num) { + input_buf[i][tmp_idx++] = (unsigned char)0; + input_buf[i][tmp_idx++] = (unsigned char)0; + } else { + input_buf[i][tmp_idx++] = (unsigned char)actual_data_num; + input_buf[i][tmp_idx++] = (unsigned char)actual_redundant_num; + } + input_buf[i][tmp_idx++] = (unsigned char)i; + + tmp_output_buf[i] = input_buf[i] + tmp_idx; //////caution ,trick here. + + if (fec_par.mode == 0) { + output_len[i] = tmp_idx + fec_len; + if (i < actual_data_num) { + memcpy(input_buf[i] + tmp_idx, blob_output[i], fec_len); + } + } else { + if (i < actual_data_num) { + output_len[i] = tmp_idx + input_len[i]; + memset(tmp_output_buf[i] + input_len[i], 0, fec_len - input_len[i]); + } else + output_len[i] = tmp_idx + fec_len; + } + output_buf[i] = input_buf[i]; // output_buf points to same block of memory with different offset + } + + if (0) { + printf("seq=%u,fec_len=%d,%d %d,before fec\n", seq, fec_len, actual_data_num, actual_redundant_num); + + for (int i = 0; i < actual_data_num; i++) { + printf("{"); + for (int j = 0; j < 8 + fec_len; j++) { + log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)input_buf[i][j]); + } + printf("},\n"); + // log_bare(log_warn,"") + } + } + // output_len=blob_len+sizeof(u32_t)+4*sizeof(char);/////remember to change this 4,if modified the protocol + rs_encode2(actual_data_num, actual_data_num + actual_redundant_num, tmp_output_buf, fec_len); + + if (0) { + printf("seq=%u,fec_len=%d,%d %d,after fec\n", seq, fec_len, actual_data_num, actual_redundant_num); + for (int i = 0; i < actual_data_num + actual_redundant_num; i++) { + printf("{"); + for (int j = 0; j < 8 + fec_len; j++) { + log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)output_buf[i][j]); + } + printf("},\n"); + // log_bare(log_warn,"") + } + } + + // mylog(log_trace,"!!! s= %d\n"); + assert(ready_for_output == 0); + ready_for_output = 1; + first_packet_time_for_output = first_packet_time; + first_packet_time = 0; + seq++; + counter = 0; + output_n = actual_data_num + actual_redundant_num; + blob_encode.clear(); + + my_itimerspec its; + memset(&its, 0, sizeof(its)); + ev_timer_stop(loop, &timer); + // timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0); + + if (encode_fast_send && fec_par.mode == 1) { + int packet_to_send[max_fec_packet_num + 5] = {0}; + int packet_to_send_counter = 0; + + // assert(counter!=0); + if (s != 0) + packet_to_send[packet_to_send_counter++] = actual_data_num - 1; + for (int i = actual_data_num; i < actual_data_num + actual_redundant_num; i++) { + packet_to_send[packet_to_send_counter++] = i; + } + output_n = packet_to_send_counter; // re write + for (int i = 0; i < packet_to_send_counter; i++) { + output_buf[i] = output_buf[packet_to_send[i]]; + output_len[i] = output_len[packet_to_send[i]]; + } + } + } else { + if (encode_fast_send && s != 0 && fec_par.mode == 1) { + assert(counter >= 1); + assert(counter <= 255); + int input_buf_idx = counter - 1; + assert(ready_for_output == 0); + ready_for_output = 1; + first_packet_time_for_output = 0; + output_n = 1; + + int tmp_idx = 0; + write_u32(input_buf[input_buf_idx] + tmp_idx, seq); + tmp_idx += sizeof(u32_t); + + input_buf[input_buf_idx][tmp_idx++] = (unsigned char)fec_par.mode; + input_buf[input_buf_idx][tmp_idx++] = (unsigned char)0; + input_buf[input_buf_idx][tmp_idx++] = (unsigned char)0; + input_buf[input_buf_idx][tmp_idx++] = (unsigned char)((u32_t)input_buf_idx); + + output_len[0] = input_len[input_buf_idx] + tmp_idx; + output_buf[0] = input_buf[input_buf_idx]; + + if (0) { + printf("seq=%u,buf_idx=%d\n", seq, input_buf_idx); + for (int j = 0; j < output_len[0]; j++) { + log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)output_buf[0][j]); + } + printf("\n"); + } + } + } + + if (s != 0 && delayed_append) { + assert(fec_par.mode != 1); + append(s, len); + } + + return 0; } -int fec_encode_manager_t::output(int &n,char ** &s_arr,int *&len) -{ - if(!ready_for_output) - { - n=-1; - len=0; - s_arr=0; - } - else - { - n=output_n; - len=output_len; - s_arr=output_buf; - ready_for_output=0; - } - return 0; +int fec_encode_manager_t::output(int &n, char **&s_arr, int *&len) { + if (!ready_for_output) { + n = -1; + len = 0; + s_arr = 0; + } else { + n = output_n; + len = output_len; + s_arr = output_buf; + ready_for_output = 0; + } + return 0; } /* int fec_decode_manager_t::re_init() { - clear(); - return 0; + clear(); + return 0; }*/ -int fec_decode_manager_t::input(char *s,int len) -{ - assert(s!=0); - assert(len+100=max_fec_packet_num) - { - mylog(log_warn,"data_num+redundant_num>=max_fec_packet_num\n"); - return -1; - } - if(!anti_replay.is_vaild(seq)) - { - mylog(log_trace,"!anti_replay.is_vaild(seq) ,seq =%u\n",seq); - return 0; - } + if (type == 0 && data_num == 0) { + mylog(log_warn, "unexpected type==0&&data_num==0\n"); + return -1; + } + if (data_num + redundant_num >= max_fec_packet_num) { + mylog(log_warn, "data_num+redundant_num>=max_fec_packet_num\n"); + return -1; + } + if (!anti_replay.is_vaild(seq)) { + mylog(log_trace, "!anti_replay.is_vaild(seq) ,seq =%u\n", seq); + return 0; + } - if(mp[seq].fec_done!=0) - { - mylog(log_debug,"fec already done, ignore, seq=%u\n",seq); - return -1; - } + if (mp[seq].fec_done != 0) { + mylog(log_debug, "fec already done, ignore, seq=%u\n", seq); + return -1; + } - if(mp[seq].group_mp.find(inner_index)!=mp[seq].group_mp.end() ) - { - mylog(log_debug,"dup fec index\n");//duplicate can happen on a normal network, so its just log_debug - return -1; - } + if (mp[seq].group_mp.find(inner_index) != mp[seq].group_mp.end()) { + mylog(log_debug, "dup fec index\n"); // duplicate can happen on a normal network, so its just log_debug + return -1; + } + if (mp[seq].type == -1) + mp[seq].type = type; + else { + if (mp[seq].type != type) { + mylog(log_warn, "type mismatch\n"); + return -1; + } + } - if(mp[seq].type==-1) - mp[seq].type=type; - else - { - if(mp[seq].type!=type) - { - mylog(log_warn,"type mismatch\n"); - return -1; - } - } + if (data_num != 0) { + // mp[seq].data_counter++; - if(data_num!=0) - { - //mp[seq].data_counter++; + if (mp[seq].data_num == -1) { + mp[seq].data_num = data_num; + mp[seq].redundant_num = redundant_num; + mp[seq].len = len; + } else { + if (mp[seq].data_num != data_num || mp[seq].redundant_num != redundant_num || mp[seq].len != len) { + mylog(log_warn, "unexpected mp[seq].data_num!=data_num||mp[seq].redundant_num!=redundant_num||mp[seq].len!=len\n"); + return -1; + } + } + } - if(mp[seq].data_num==-1) - { - mp[seq].data_num=data_num; - mp[seq].redundant_num=redundant_num; - mp[seq].len=len; - } - else - { - if(mp[seq].data_num!=data_num||mp[seq].redundant_num!=redundant_num||mp[seq].len!=len) - { - mylog(log_warn,"unexpected mp[seq].data_num!=data_num||mp[seq].redundant_num!=redundant_num||mp[seq].len!=len\n"); - return -1; - } - } - } + // mylog(log_info,"mp.size()=%d index=%d\n",mp.size(),index); - //mylog(log_info,"mp.size()=%d index=%d\n",mp.size(),index); + if (fec_data[index].used != 0) { + u32_t tmp_seq = fec_data[index].seq; + anti_replay.set_invaild(tmp_seq); - if(fec_data[index].used!=0) - { - u32_t tmp_seq=fec_data[index].seq; - anti_replay.set_invaild(tmp_seq); + auto tmp_it = mp.find(tmp_seq); + if (tmp_it != mp.end()) { + int x = tmp_it->second.data_num; + int y = tmp_it->second.redundant_num; + int cnt = tmp_it->second.group_mp.size(); - auto tmp_it=mp.find(tmp_seq); - if(tmp_it!=mp.end()) - { - int x=tmp_it->second.data_num; - int y=tmp_it->second.redundant_num; - int cnt=tmp_it->second.group_mp.size(); + if (cnt < x) { + if (debug_fec_dec) + mylog(log_debug, "[dec][failed]seq=%08x x=%d y=%d cnt=%d\n", tmp_seq, x, y, cnt); + else + mylog(log_trace, "[dec][failed]seq=%08x x=%d y=%d cnt=%d\n", tmp_seq, x, y, cnt); + } + mp.erase(tmp_it); + } + if (tmp_seq == seq) { + mylog(log_warn, "unexpected tmp_seq==seq ,seq=%d\n", seq); + return -1; + } + } - if(cnt &inner_mp = mp[seq].group_mp; - map &inner_mp=mp[seq].group_mp; + int about_to_fec = 0; + if (type == 0) { + // assert((int)inner_mp.size()<=data_num); + if ((int)inner_mp.size() > data_num) { + mylog(log_warn, "inner_mp.size()>data_num\n"); + anti_replay.set_invaild(seq); + goto end; + } + if ((int)inner_mp.size() == data_num) + about_to_fec = 1; + } else { + if (mp[seq].data_num != -1) { + if ((int)inner_mp.size() > mp[seq].data_num + 1) { + mylog(log_warn, "inner_mp.size()>data_num+1\n"); + anti_replay.set_invaild(seq); + goto end; + } + if ((int)inner_mp.size() >= mp[seq].data_num) { + about_to_fec = 1; + } + } + } + if (about_to_fec) { + int group_data_num = mp[seq].data_num; + int group_redundant_num = mp[seq].redundant_num; - int about_to_fec=0; - if(type==0) - { - //assert((int)inner_mp.size()<=data_num); - if((int)inner_mp.size()>data_num) - { - mylog(log_warn,"inner_mp.size()>data_num\n"); - anti_replay.set_invaild(seq); - goto end; - } - if((int)inner_mp.size()==data_num) - about_to_fec=1; - } - else - { - if(mp[seq].data_num!=-1) - { - if((int)inner_mp.size()>mp[seq].data_num+1) - { - mylog(log_warn,"inner_mp.size()>data_num+1\n"); - anti_replay.set_invaild(seq); - goto end; - } - if((int)inner_mp.size()>=mp[seq].data_num) - { - about_to_fec=1; - } - } - } + int x_got = 0; + int y_got = 0; + // mylog(log_error,"fec here!\n"); + if (type == 0) { + char *fec_tmp_arr[max_fec_packet_num + 5] = {0}; + for (auto it = inner_mp.begin(); it != inner_mp.end(); it++) { + if (it->first < group_data_num) + x_got++; + else + y_got++; + fec_tmp_arr[it->first] = fec_data[it->second].buf; + } + assert(rs_decode2(group_data_num, group_data_num + group_redundant_num, fec_tmp_arr, len) == 0); // the input data has been modified in-place + // this line should always succeed + mp[seq].fec_done = 1; + if (debug_fec_dec) + mylog(log_debug, "[dec]seq=%08x x=%d y=%d len=%d cnt=%d X=%d Y=%d\n", seq, group_data_num, group_redundant_num, len, int(inner_mp.size()), x_got, y_got); + else + mylog(log_trace, "[dec]seq=%08x x=%d y=%d len=%d cnt=%d X=%d Y=%d\n", seq, group_data_num, group_redundant_num, len, int(inner_mp.size()), x_got, y_got); - if(about_to_fec) - { - int group_data_num=mp[seq].data_num; - int group_redundant_num=mp[seq].redundant_num; + blob_decode.clear(); + for (int i = 0; i < group_data_num; i++) { + blob_decode.input(fec_tmp_arr[i], len); + } + if (blob_decode.output(output_n, output_s_arr, output_len_arr) != 0) { + mylog(log_warn, "blob_decode failed\n"); + // ready_for_output=0; + anti_replay.set_invaild(seq); + goto end; + } + assert(ready_for_output == 0); + ready_for_output = 1; + anti_replay.set_invaild(seq); + } else // type==1 + { + int max_len = -1; + int fec_result_ok = 1; + int data_check_ok = 1; + int debug_num = inner_mp.size(); - int x_got=0; - int y_got=0; - //mylog(log_error,"fec here!\n"); - if(type==0) - { - char *fec_tmp_arr[max_fec_packet_num+5]={0}; - for(auto it=inner_mp.begin();it!=inner_mp.end();it++) - { - if(it->first first]=fec_data[it->second].buf; - } - assert(rs_decode2(group_data_num,group_data_num+group_redundant_num,fec_tmp_arr,len)==0); //the input data has been modified in-place - //this line should always succeed - mp[seq].fec_done=1; + int missed_packet[max_fec_packet_num + 5]; + int missed_packet_counter = 0; - if(debug_fec_dec) - mylog(log_debug,"[dec]seq=%08x x=%d y=%d len=%d cnt=%d X=%d Y=%d\n",seq,group_data_num,group_redundant_num,len,int(inner_mp.size()),x_got,y_got); - else - mylog(log_trace,"[dec]seq=%08x x=%d y=%d len=%d cnt=%d X=%d Y=%d\n",seq,group_data_num,group_redundant_num,len,int(inner_mp.size()),x_got,y_got); + // outupt_s_arr_buf[max_fec_packet_num+5]={0}; - blob_decode.clear(); - for(int i=0;ifirst < group_data_num) + x_got++; + else + y_got++; - int max_len=-1; - int fec_result_ok=1; - int data_check_ok=1; - int debug_num=inner_mp.size(); + output_s_arr_buf[it->first] = fec_data[it->second].buf; + if (fec_data[it->second].len < (int)sizeof(u16_t)) { + mylog(log_warn, "fec_data[it->second].len<(int)sizeof(u16_t)"); + data_check_ok = 0; + } - int missed_packet[max_fec_packet_num+5]; - int missed_packet_counter=0; + if (fec_data[it->second].len > max_len) + max_len = fec_data[it->second].len; + } + if (max_len != mp[seq].len) { + data_check_ok = 0; + mylog(log_warn, "max_len!=mp[seq].len"); + } + if (data_check_ok == 0) { + // ready_for_output=0; + mylog(log_warn, "data_check_ok==0\n"); + anti_replay.set_invaild(seq); + goto end; + } + for (auto it = inner_mp.begin(); it != inner_mp.end(); it++) { + int tmp_idx = it->second; + assert(max_len >= fec_data[tmp_idx].len); // guarenteed by data_check_ok + memset(fec_data[tmp_idx].buf + fec_data[tmp_idx].len, 0, max_len - fec_data[tmp_idx].len); + } - //outupt_s_arr_buf[max_fec_packet_num+5]={0}; + for (int i = 0; i < group_data_num; i++) { + if (output_s_arr_buf[i] == 0 || i == inner_index) // only missed packet +current packet + { + missed_packet[missed_packet_counter++] = i; + } + } + mylog(log_trace, "fec done,%d %d,missed_packet_counter=%d\n", group_data_num, group_redundant_num, missed_packet_counter); - //memset(output_s_arr_buf,0,sizeof(output_s_arr_buf));//in efficient + assert(rs_decode2(group_data_num, group_data_num + group_redundant_num, output_s_arr_buf, max_len) == 0); // this should always succeed + mp[seq].fec_done = 1; - for(int i=0;ifirst first]=fec_data[it->second].buf; - if(fec_data[it->second].len<(int)sizeof(u16_t)) - { - mylog(log_warn,"fec_data[it->second].len<(int)sizeof(u16_t)"); - data_check_ok=0; - } + for (int i = 0; i < group_data_num; i++) { + output_len_arr_buf[i] = read_u16(output_s_arr_buf[i]); + sum_ori += output_len_arr_buf[i]; + output_s_arr_buf[i] += sizeof(u16_t); + if (output_len_arr_buf[i] > max_data_len) { + mylog(log_warn, "invaild len %d,seq= %u,data_num= %d r_num= %d,i= %d\n", output_len_arr_buf[i], seq, group_data_num, group_redundant_num, i); + fec_result_ok = 0; + for (int i = 0; i < missed_packet_counter; i++) { + log_bare(log_warn, "%d ", missed_packet[i]); + } + log_bare(log_warn, "\n"); + // break; + } + } - if(fec_data[it->second].len > max_len) - max_len=fec_data[it->second].len; - } - if(max_len!=mp[seq].len) - { - data_check_ok=0; - mylog(log_warn,"max_len!=mp[seq].len"); - } - if(data_check_ok==0) - { - //ready_for_output=0; - mylog(log_warn,"data_check_ok==0\n"); - anti_replay.set_invaild(seq); - goto end; - } - for(auto it=inner_mp.begin();it!=inner_mp.end();it++) - { - int tmp_idx=it->second; - assert(max_len>=fec_data[tmp_idx].len);//guarenteed by data_check_ok - memset(fec_data[tmp_idx].buf+fec_data[tmp_idx].len,0,max_len-fec_data[tmp_idx].len); - } + int sum = max_len * group_data_num; - for(int i=0;imax_data_len) - { - mylog(log_warn,"invaild len %d,seq= %u,data_num= %d r_num= %d,i= %d\n",output_len_arr_buf[i],seq,group_data_num,group_redundant_num,i); - fec_result_ok=0; - for(int i=0;i+1 at the moment) - unsigned char y;//fec_redundant_num - }rs_par[max_fec_packet_num+10]; + int rs_cnt = 0; + struct rs_parameter_t // parameters for reed solomon + { + unsigned char x; // AKA fec_data_num (x should be same as +1 at the moment) + unsigned char y; // fec_redundant_num + } rs_par[max_fec_packet_num + 10]; - int rs_from_str(char * s)//todo inefficient - { - vector str_vec=string_to_vec(s,","); - if(str_vec.size()<1) - { - mylog(log_warn,"failed to parse [%s]\n",s); - return -1; - } - vector par_vec; - for(int i=0;i<(int)str_vec.size();i++) - { - rs_parameter_t tmp_par; - string &tmp_str=str_vec[i]; - int x,y; - if(sscanf((char *)tmp_str.c_str(),"%d:%d",&x,&y)!=2) - { - mylog(log_warn,"failed to parse [%s]\n",tmp_str.c_str()); - return -1; - } - if(x<1||y<0||x+y>max_fec_packet_num) - { - mylog(log_warn,"invaild value x=%d y=%d, x should >=1, y should >=0, x +y should <%d\n",x,y,max_fec_packet_num); - return -1; - } - tmp_par.x=x; - tmp_par.y=y; - par_vec.push_back(tmp_par); - } - assert(par_vec.size()==str_vec.size()); + int rs_from_str(char *s) // todo inefficient + { + vector str_vec = string_to_vec(s, ","); + if (str_vec.size() < 1) { + mylog(log_warn, "failed to parse [%s]\n", s); + return -1; + } + vector par_vec; + for (int i = 0; i < (int)str_vec.size(); i++) { + rs_parameter_t tmp_par; + string &tmp_str = str_vec[i]; + int x, y; + if (sscanf((char *)tmp_str.c_str(), "%d:%d", &x, &y) != 2) { + mylog(log_warn, "failed to parse [%s]\n", tmp_str.c_str()); + return -1; + } + if (x < 1 || y < 0 || x + y > max_fec_packet_num) { + mylog(log_warn, "invaild value x=%d y=%d, x should >=1, y should >=0, x +y should <%d\n", x, y, max_fec_packet_num); + return -1; + } + tmp_par.x = x; + tmp_par.y = y; + par_vec.push_back(tmp_par); + } + assert(par_vec.size() == str_vec.size()); - int found_problem=0; - for(int i=1;i<(int)par_vec.size();i++) - { - if(par_vec[i].x<=par_vec[i-1].x) - { - mylog(log_warn,"error in [%s], x in x:y should be in ascend order\n",s); - return -1; - } - int now_x=par_vec[i].x; - int now_y=par_vec[i].y; - int pre_x=par_vec[i-1].x; - int pre_y=par_vec[i-1].y; + int found_problem = 0; + for (int i = 1; i < (int)par_vec.size(); i++) { + if (par_vec[i].x <= par_vec[i - 1].x) { + mylog(log_warn, "error in [%s], x in x:y should be in ascend order\n", s); + return -1; + } + int now_x = par_vec[i].x; + int now_y = par_vec[i].y; + int pre_x = par_vec[i - 1].x; + int pre_y = par_vec[i - 1].y; - double now_ratio=double(par_vec[i].y)/par_vec[i].x; - double pre_ratio=double(par_vec[i-1].y)/par_vec[i-1].x; + double now_ratio = double(par_vec[i].y) / par_vec[i].x; + double pre_ratio = double(par_vec[i - 1].y) / par_vec[i - 1].x; - if(pre_ratio+0.0001max_fec_packet_num) - { - in_y=max_fec_packet_num-in_x; - assert(in_y>=0&&in_y<=max_fec_packet_num); - } + if (in_x + in_y > max_fec_packet_num) { + in_y = max_fec_packet_num - in_x; + assert(in_y >= 0 && in_y <= max_fec_packet_num); + } - rs_par[in_x-1].x=in_x; - rs_par[in_x-1].y=in_y; - } - } - rs_cnt=par_vec[par_vec.size()-1].x; + rs_par[in_x - 1].x = in_x; + rs_par[in_x - 1].y = in_y; + } + } + rs_cnt = par_vec[par_vec.size() - 1].x; - return 0; - } + return 0; + } - char *rs_to_str()//todo inefficient - { - static char res[rs_str_len]; - string tmp_string; - char tmp_buf[100]; - assert(rs_cnt>=1); - for(int i=0;i= 1); + for (int i = 0; i < rs_cnt; i++) { + sprintf(tmp_buf, "%d:%d", int(rs_par[i].x), int(rs_par[i].y)); + if (i != 0) + tmp_string += ","; + tmp_string += tmp_buf; + } + strcpy(res, tmp_string.c_str()); + return res; + } - rs_parameter_t get_tail() - { - assert(rs_cnt>=1); - return rs_par[rs_cnt-1]; - } + rs_parameter_t get_tail() { + assert(rs_cnt >= 1); + return rs_par[rs_cnt - 1]; + } + int clone(fec_parameter_t &other) { + version = other.version; + mtu = other.mtu; + queue_len = other.queue_len; + timeout = other.timeout; + mode = other.mode; - int clone(fec_parameter_t & other) - { - version=other.version; - mtu=other.mtu; - queue_len=other.queue_len; - timeout=other.timeout; - mode=other.mode; + assert(other.rs_cnt >= 1); + rs_cnt = other.rs_cnt; + memcpy(rs_par, other.rs_par, sizeof(rs_parameter_t) * rs_cnt); - assert(other.rs_cnt>=1); - rs_cnt=other.rs_cnt; - memcpy(rs_par,other.rs_par,sizeof(rs_parameter_t)*rs_cnt); + return 0; + } - return 0; - } + int copy_fec(fec_parameter_t &other) { + assert(other.rs_cnt >= 1); + rs_cnt = other.rs_cnt; + memcpy(rs_par, other.rs_par, sizeof(rs_parameter_t) * rs_cnt); - int copy_fec(fec_parameter_t & other) - { - assert(other.rs_cnt>=1); - rs_cnt=other.rs_cnt; - memcpy(rs_par,other.rs_par,sizeof(rs_parameter_t)*rs_cnt); - - return 0; - } + return 0; + } }; extern fec_parameter_t g_fec_par; -//extern int dynamic_update_fec; +// extern int dynamic_update_fec; -const int anti_replay_timeout=120*1000;// 120s +const int anti_replay_timeout = 120 * 1000; // 120s -struct anti_replay_t -{ +struct anti_replay_t { + struct info_t { + my_time_t my_time; + int index; + }; - struct info_t - { - my_time_t my_time; - int index; - }; + u64_t replay_buffer[anti_replay_buff_size]; + unordered_map mp; + int index; + anti_replay_t() { + clear(); + } + int clear() { + memset(replay_buffer, -1, sizeof(replay_buffer)); + mp.clear(); + mp.rehash(anti_replay_buff_size * 3); + index = 0; + return 0; + } + void set_invaild(u32_t seq) { + if (is_vaild(seq) == 0) { + mylog(log_trace, "seq %u exist\n", seq); + // assert(mp.find(seq)!=mp.end()); + // mp[seq].my_time=get_current_time_rough(); + return; + } + if (replay_buffer[index] != u64_t(i64_t(-1))) { + assert(mp.find(replay_buffer[index]) != mp.end()); + mp.erase(replay_buffer[index]); + } + replay_buffer[index] = seq; + assert(mp.find(seq) == mp.end()); + mp[seq].my_time = get_current_time(); + mp[seq].index = index; + index++; + if (index == int(anti_replay_buff_size)) index = 0; + } + int is_vaild(u32_t seq) { + if (mp.find(seq) == mp.end()) return 1; - u64_t replay_buffer[anti_replay_buff_size]; - unordered_map mp; - int index; - anti_replay_t() - { - clear(); - } - int clear() - { - memset(replay_buffer,-1,sizeof(replay_buffer)); - mp.clear(); - mp.rehash(anti_replay_buff_size*3); - index=0; - return 0; - } - void set_invaild(u32_t seq) - { + if (get_current_time() - mp[seq].my_time > anti_replay_timeout) { + replay_buffer[mp[seq].index] = u64_t(i64_t(-1)); + mp.erase(seq); + return 1; + } - if(is_vaild(seq)==0) - { - mylog(log_trace,"seq %u exist\n",seq); - //assert(mp.find(seq)!=mp.end()); - //mp[seq].my_time=get_current_time_rough(); - return; - } - if(replay_buffer[index]!=u64_t(i64_t(-1))) - { - assert(mp.find(replay_buffer[index])!=mp.end()); - mp.erase(replay_buffer[index]); - } - replay_buffer[index]=seq; - assert(mp.find(seq)==mp.end()); - mp[seq].my_time=get_current_time(); - mp[seq].index=index; - index++; - if(index==int(anti_replay_buff_size)) index=0; - } - int is_vaild(u32_t seq) - { - if(mp.find(seq)==mp.end()) return 1; - - if(get_current_time()-mp[seq].my_time>anti_replay_timeout) - { - replay_buffer[mp[seq].index]=u64_t(i64_t(-1)); - mp.erase(seq); - return 1; - } - - return 0; - } + return 0; + } }; -struct blob_encode_t -{ - char input_buf[(max_fec_packet_num+5)*buf_len]; - int current_len; - int counter; +struct blob_encode_t { + char input_buf[(max_fec_packet_num + 5) * buf_len]; + int current_len; + int counter; - char *output_buf[max_fec_packet_num+100]; + char *output_buf[max_fec_packet_num + 100]; - blob_encode_t(); + blob_encode_t(); int clear(); int get_num(); int get_shard_len(int n); - int get_shard_len(int n,int next_packet_len); + int get_shard_len(int n, int next_packet_len); - int input(char *s,int len); //len=use len=0 for second and following packet - int output(int n,char ** &s_arr,int & len); + int input(char *s, int len); // len=use len=0 for second and following packet + int output(int n, char **&s_arr, int &len); }; -struct blob_decode_t -{ - char input_buf[(max_fec_packet_num+5)*buf_len]; - int current_len; - int last_len; - int counter; +struct blob_decode_t { + char input_buf[(max_fec_packet_num + 5) * buf_len]; + int current_len; + int last_len; + int counter; - char *output_buf[max_blob_packet_num+100]; - int output_len[max_blob_packet_num+100]; + char *output_buf[max_blob_packet_num + 100]; + int output_len[max_blob_packet_num + 100]; - blob_decode_t(); - int clear(); - int input(char *input,int len); - int output(int &n,char ** &output,int *&len_arr); + blob_decode_t(); + int clear(); + int input(char *input, int len); + int output(int &n, char **&output, int *&len_arr); }; -class fec_encode_manager_t:not_copy_able_t -{ +class fec_encode_manager_t : not_copy_able_t { + private: + u32_t seq; -private: - u32_t seq; + // int fec_mode; + // int fec_data_num,fec_redundant_num; + // int fec_mtu; + // int fec_queue_len; + // int fec_timeout; + fec_parameter_t fec_par; - //int fec_mode; - //int fec_data_num,fec_redundant_num; - //int fec_mtu; - //int fec_queue_len; - //int fec_timeout; - fec_parameter_t fec_par; + my_time_t first_packet_time; + my_time_t first_packet_time_for_output; + blob_encode_t blob_encode; + char input_buf[max_fec_packet_num + 5][buf_len]; + int input_len[max_fec_packet_num + 100]; - my_time_t first_packet_time; - my_time_t first_packet_time_for_output; + char *output_buf[max_fec_packet_num + 100]; + int output_len[max_fec_packet_num + 100]; + int counter; + // int timer_fd; + // u64_t timer_fd64; - blob_encode_t blob_encode; - char input_buf[max_fec_packet_num+5][buf_len]; - int input_len[max_fec_packet_num+100]; + int ready_for_output; + u32_t output_n; - char *output_buf[max_fec_packet_num+100]; - int output_len[max_fec_packet_num+100]; + int append(char *s, int len); - int counter; - //int timer_fd; - //u64_t timer_fd64; + ev_timer timer; + struct ev_loop *loop = 0; + void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0; - int ready_for_output; - u32_t output_n; + public: + fec_encode_manager_t(); + ~fec_encode_manager_t(); - int append(char *s,int len); + fec_parameter_t &get_fec_par() { + return fec_par; + } + void set_data(void *data) { + timer.data = data; + } - ev_timer timer; - struct ev_loop *loop=0; - void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)=0; + void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) { + this->loop = loop; + this->cb = cb; + ev_init(&timer, cb); + } -public: - fec_encode_manager_t(); - ~fec_encode_manager_t(); + int clear_data() { + counter = 0; + blob_encode.clear(); + ready_for_output = 0; - fec_parameter_t & get_fec_par() - { - return fec_par; - } - void set_data(void * data) - { - timer.data=data; - } + seq = (u32_t)get_fake_random_number(); // TODO temp solution for a bug. + if (loop) { + ev_timer_stop(loop, &timer); + } + return 0; + } + int clear_all() { + // itimerspec zero_its; + // memset(&zero_its, 0, sizeof(zero_its)); + // timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); - void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)) - { - this->loop=loop; - this->cb=cb; - ev_init(&timer,cb); - } + if (loop) { + ev_timer_stop(loop, &timer); + loop = 0; + cb = 0; + } - int clear_data() - { - counter=0; - blob_encode.clear(); - ready_for_output=0; + clear_data(); - seq=(u32_t)get_fake_random_number(); //TODO temp solution for a bug. + return 0; + } - if(loop) - { - ev_timer_stop(loop,&timer); - } - return 0; - } - int clear_all() - { + my_time_t get_first_packet_time() { + return first_packet_time_for_output; + } - //itimerspec zero_its; - //memset(&zero_its, 0, sizeof(zero_its)); - //timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); + int get_pending_time() { + return fec_par.timeout; + } - if(loop) - { - ev_timer_stop(loop,&timer); - loop=0; - cb=0; - } - - clear_data(); - - return 0; - } - - my_time_t get_first_packet_time() - { - return first_packet_time_for_output; - } - - int get_pending_time() - { - return fec_par.timeout; - } - - int get_type() - { - return fec_par.mode; - } - //u64_t get_timer_fd64(); - int reset_fec_parameter(int data_num,int redundant_num,int mtu,int pending_num,int pending_time,int type); - int input(char *s,int len/*,int &is_first_packet*/); - int output(int &n,char ** &s_arr,int *&len); + int get_type() { + return fec_par.mode; + } + // u64_t get_timer_fd64(); + int reset_fec_parameter(int data_num, int redundant_num, int mtu, int pending_num, int pending_time, int type); + int input(char *s, int len /*,int &is_first_packet*/); + int output(int &n, char **&s_arr, int *&len); }; -struct fec_data_t -{ - int used; - u32_t seq; - int type; - int data_num; - int redundant_num; - int idx; - char buf[buf_len]; - int len; +struct fec_data_t { + int used; + u32_t seq; + int type; + int data_num; + int redundant_num; + int idx; + char buf[buf_len]; + int len; }; -struct fec_group_t -{ - int type=-1; - int data_num=-1; - int redundant_num=-1; - int len=-1; - int fec_done=0; - //int data_counter=0; - map group_mp; +struct fec_group_t { + int type = -1; + int data_num = -1; + int redundant_num = -1; + int len = -1; + int fec_done = 0; + // int data_counter=0; + map group_mp; }; -class fec_decode_manager_t:not_copy_able_t -{ - anti_replay_t anti_replay; - fec_data_t *fec_data=0; - unordered_map mp; - blob_decode_t blob_decode; +class fec_decode_manager_t : not_copy_able_t { + anti_replay_t anti_replay; + fec_data_t *fec_data = 0; + unordered_map mp; + blob_decode_t blob_decode; - int index; + int index; - int output_n; - char ** output_s_arr; - int * output_len_arr; - int ready_for_output; + int output_n; + char **output_s_arr; + int *output_len_arr; + int ready_for_output; - char *output_s_arr_buf[max_fec_packet_num+100];//only for type=1,for type=0 the buf inside blot_t is used - int output_len_arr_buf[max_fec_packet_num+100];//same + char *output_s_arr_buf[max_fec_packet_num + 100]; // only for type=1,for type=0 the buf inside blot_t is used + int output_len_arr_buf[max_fec_packet_num + 100]; // same -public: - fec_decode_manager_t() - { - fec_data=new fec_data_t[fec_buff_num+5]; - assert(fec_data!=0); - clear(); - } - /* - fec_decode_manager_t(const fec_decode_manager_t &b) - { - assert(0==1);//not allowed to copy - }*/ - ~fec_decode_manager_t() - { - mylog(log_debug,"fec_decode_manager destroyed\n"); - if(fec_data!=0) - { - mylog(log_debug,"fec_data freed\n"); - delete fec_data; - } - } - int clear() - { - anti_replay.clear(); - mp.clear(); - mp.rehash(fec_buff_num*3); + public: + fec_decode_manager_t() { + fec_data = new fec_data_t[fec_buff_num + 5]; + assert(fec_data != 0); + clear(); + } + /* + fec_decode_manager_t(const fec_decode_manager_t &b) + { + assert(0==1);//not allowed to copy + }*/ + ~fec_decode_manager_t() { + mylog(log_debug, "fec_decode_manager destroyed\n"); + if (fec_data != 0) { + mylog(log_debug, "fec_data freed\n"); + delete fec_data; + } + } + int clear() { + anti_replay.clear(); + mp.clear(); + mp.rehash(fec_buff_num * 3); - for(int i=0;i<(int)fec_buff_num;i++) - fec_data[i].used=0; - ready_for_output=0; - index=0; + for (int i = 0; i < (int)fec_buff_num; i++) + fec_data[i].used = 0; + ready_for_output = 0; + index = 0; - return 0; - } + return 0; + } - //int re_init(); - int input(char *s,int len); - int output(int &n,char ** &s_arr,int* &len_arr); + // int re_init(); + int input(char *s, int len); + int output(int &n, char **&s_arr, int *&len_arr); }; #endif /* FEC_MANAGER_H_ */ diff --git a/lib/rs.cpp b/lib/rs.cpp index 20e2279..187b30c 100644 --- a/lib/rs.cpp +++ b/lib/rs.cpp @@ -8,69 +8,57 @@ #include "stdlib.h" #include "string.h" -void rs_encode(void *code,char *data[],int size) -{ - int k=get_k(code); - int n=get_n(code); - for(int i=k;i #include -int log_level=log_info; +int log_level = log_info; -int enable_log_position=0; -int enable_log_color=1; +int enable_log_position = 0; +int enable_log_color = 1; +void log0(const char* file, const char* function, int line, int level, const char* str, ...) { + if (level > log_level) return; + if (level > log_trace || level < 0) return; -void log0(const char * file,const char * function,int line,int level,const char* str, ...) { + time_t timer; + char buffer[100]; + struct tm* tm_info; - if(level>log_level) return ; - if(level>log_trace||level<0) return ; + time(&timer); + tm_info = localtime(&timer); + if (enable_log_color) + printf("%s", log_color[level]); - time_t timer; - char buffer[100]; - struct tm* tm_info; + strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", tm_info); + printf("[%s][%s]", buffer, log_text[level]); - time(&timer); - tm_info = localtime(&timer); + if (enable_log_position) printf("[%s,func:%s,line:%d]", file, function, line); - if(enable_log_color) - printf("%s",log_color[level]); + va_list vlist; + va_start(vlist, str); + vfprintf(stdout, str, vlist); + va_end(vlist); + if (enable_log_color) + printf("%s", RESET); - strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", tm_info); - printf("[%s][%s]",buffer,log_text[level]); + // printf("\n"); + // if(enable_log_color) + // printf(log_color[level]); + fflush(stdout); - if(enable_log_position)printf("[%s,func:%s,line:%d]",file,function,line); - - va_list vlist; - va_start(vlist, str); - vfprintf(stdout, str, vlist); - va_end(vlist); - if(enable_log_color) - printf("%s",RESET); - - //printf("\n"); - //if(enable_log_color) - //printf(log_color[level]); - fflush(stdout); - - if(log_level==log_fatal) - { - about_to_exit=1; - } + if (log_level == log_fatal) { + about_to_exit = 1; + } } -void log_bare(int level,const char* str, ...) -{ - if(level>log_level) return ; - if(level>log_trace||level<0) return ; - if(enable_log_color) - printf("%s",log_color[level]); - va_list vlist; - va_start(vlist, str); - vfprintf(stdout, str, vlist); - va_end(vlist); - if(enable_log_color) - printf("%s",RESET); - fflush(stdout); - +void log_bare(int level, const char* str, ...) { + if (level > log_level) return; + if (level > log_trace || level < 0) return; + if (enable_log_color) + printf("%s", log_color[level]); + va_list vlist; + va_start(vlist, str); + vfprintf(stdout, str, vlist); + va_end(vlist); + if (enable_log_color) + printf("%s", RESET); + fflush(stdout); } diff --git a/log.h b/log.h old mode 100755 new mode 100644 index 3eefc75..7c7bdf8 --- a/log.h +++ b/log.h @@ -2,60 +2,54 @@ #ifndef _LOG_MYLOG_H_ #define _LOG_MYLOG_H_ - -#include -#include -#include -#include +#include +#include +#include +#include #include -#include +#include #include #include using namespace std; - -#define RED "\x1B[31m" -#define GRN "\x1B[32m" -#define YEL "\x1B[33m" -#define BLU "\x1B[34m" -#define MAG "\x1B[35m" -#define CYN "\x1B[36m" -#define WHT "\x1B[37m" +#define RED "\x1B[31m" +#define GRN "\x1B[32m" +#define YEL "\x1B[33m" +#define BLU "\x1B[34m" +#define MAG "\x1B[35m" +#define CYN "\x1B[36m" +#define WHT "\x1B[37m" #define RESET "\x1B[0m" +const int log_never = 0; +const int log_fatal = 1; +const int log_error = 2; +const int log_warn = 3; +const int log_info = 4; +const int log_debug = 5; +const int log_trace = 6; +const int log_end = 7; -const int log_never=0; -const int log_fatal=1; -const int log_error=2; -const int log_warn=3; -const int log_info=4; -const int log_debug=5; -const int log_trace=6; -const int log_end=7; - -const char log_text[][20]={"NEVER","FATAL","ERROR","WARN","INFO","DEBUG","TRACE",""}; -const char log_color[][20]={RED,RED,RED,YEL,GRN,MAG,""}; +const char log_text[][20] = {"NEVER", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", ""}; +const char log_color[][20] = {RED, RED, RED, YEL, GRN, MAG, ""}; extern int log_level; extern int enable_log_position; extern int enable_log_color; - #ifdef MY_DEBUG -#define mylog(__first_argu__dummy_abcde__,...) printf(__VA_ARGS__) +#define mylog(__first_argu__dummy_abcde__, ...) printf(__VA_ARGS__) #else -#define mylog(...) log0(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__) +#define mylog(...) log0(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) #endif - //#define mylog(__first_argu__dummy_abcde__,...) {;} -void log0(const char * file,const char * function,int line,int level,const char* str, ...); - -void log_bare(int level,const char* str, ...); +void log0(const char* file, const char* function, int line, int level, const char* str, ...); +void log_bare(int level, const char* str, ...); #endif diff --git a/main.cpp b/main.cpp index e4cf1cb..326d9bc 100644 --- a/main.cpp +++ b/main.cpp @@ -13,106 +13,97 @@ #include "git_version.h" using namespace std; +static void print_help() { + char git_version_buf[100] = {0}; + strncpy(git_version_buf, gitversion, 10); -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("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(" --report turn on send/recv report, and set a period for reporting, unit: s\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(" --report turn on send/recv report, and set a period for reporting, unit: s\n"); + printf("advanced options:\n"); + printf(" --mode fec-mode,available values: 0,1; mode 0(default) costs less bandwidth,no mtu problem.\n"); + printf(" mode 1 usually introduces less latency, but you have to care about mtu.\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. you typically shouldnt change this value.\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 defend burst packet loss.\n"); + printf(" default value: 0. do not use if you dont know what it means.\n"); + printf(" -f,--fec x1:y1,x2:y2,.. similiar to -f/--fec above,fine-grained fec parameters,may help save bandwidth.\n"); + printf(" example: \"-f 1:3,2:4,10:6,20:10\". check repo for details\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-checksum disable checksum to save a bit bandwdith and cpu\n"); + // printf(" --disable-xor disable xor\n"); - printf("advanced options:\n"); - printf(" --mode fec-mode,available values: 0,1; mode 0(default) costs less bandwidth,no mtu problem.\n"); - printf(" mode 1 usually introduces less latency, but you have to care about mtu.\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. you typically shouldnt change this value.\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 defend burst packet loss.\n"); - printf(" default value: 0. do not use if you dont know what it means.\n"); - printf(" -f,--fec x1:y1,x2:y2,.. similiar to -f/--fec above,fine-grained fec parameters,may help save bandwidth.\n"); - printf(" example: \"-f 1:3,2:4,10:6,20:10\". check repo for details\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-checksum disable checksum to save a bit bandwdith 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("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 fec queue len, only for mode 0, fec will be performed immediately after queue is full.\n"); - printf(" default value: 200. \n"); + printf(" default value: 200. \n"); printf(" --decode-buf size of buffer of fec decoder,unit: packet, default: 2000\n"); -// printf(" --fix-latency try to stabilize latency, only for mode 0\n"); + // printf(" --fix-latency try to stabilize latency, only for mode 0\n"); printf(" --delay-capacity max number of delayed packets, 0 means unlimited, default: 0\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(" --out-addr ip:port force all output packets of '-r' end to go through this address, port 0 for random port.\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(" --out-addr ip:port force all output packets of '-r' end to go through this address, port 0 for random port.\n"); #ifdef __linux__ - printf(" --out-interface force all output packets of '-r' end to go through this interface.\n"); + printf(" --out-interface force all output packets of '-r' end to go through this interface.\n"); #endif - 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("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"); + // printf("common options,these options must be same on both side\n"); } - -void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) -{ - mylog(log_info, "got sigpipe, ignored"); +void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) { + mylog(log_info, "got sigpipe, ignored"); } -void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) -{ - mylog(log_info, "got sigterm, exit"); - myexit(0); +void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) { + mylog(log_info, "got sigterm, exit"); + myexit(0); } -void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) -{ - mylog(log_info, "got sigint, exit"); - myexit(0); +void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) { + mylog(log_info, "got sigint, exit"); + myexit(0); } +int main(int argc, char *argv[]) { + working_mode = tunnel_mode; + init_ws(); + // unit_test(); - -int main(int argc, char *argv[]) -{ - working_mode=tunnel_mode; - init_ws(); - //unit_test(); - - struct ev_loop* loop=ev_default_loop(0); + struct ev_loop *loop = ev_default_loop(0); #if !defined(__MINGW32__) ev_signal signal_watcher_sigpipe; ev_signal_init(&signal_watcher_sigpipe, sigpipe_cb, SIGPIPE); ev_signal_start(loop, &signal_watcher_sigpipe); #else - enable_log_color=0; + enable_log_color = 0; #endif ev_signal signal_watcher_sigterm; @@ -123,47 +114,39 @@ int main(int argc, char *argv[]) ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT); ev_signal_start(loop, &signal_watcher_sigint); - assert(sizeof(u64_t)==8); - assert(sizeof(i64_t)==8); - assert(sizeof(u32_t)==4); - assert(sizeof(i32_t)==4); - assert(sizeof(u16_t)==2); - assert(sizeof(i16_t)==2); - dup2(1, 2); //redirect stderr to stdout - int i, j, k; + assert(sizeof(u64_t) == 8); + assert(sizeof(i64_t) == 8); + assert(sizeof(u32_t) == 4); + assert(sizeof(i32_t) == 4); + assert(sizeof(u16_t) == 2); + 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); - } - } + 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); + process_arg(argc, argv); - delay_manager.set_capacity(delay_capacity); + delay_manager.set_capacity(delay_capacity); - if(strlen(tun_dev)==0) - { - sprintf(tun_dev,"tun%u",get_fake_random_number()%1000); - } + if (strlen(tun_dev) == 0) { + sprintf(tun_dev, "tun%u", get_fake_random_number() % 1000); + } - if(program_mode==client_mode) - { - tunnel_client_event_loop(); - } - else - { - tunnel_server_event_loop(); - } + if (program_mode == client_mode) { + tunnel_client_event_loop(); + } else { + tunnel_server_event_loop(); + } - return 0; + return 0; } - diff --git a/misc.cpp b/misc.cpp index 84b283e..5918e57 100644 --- a/misc.cpp +++ b/misc.cpp @@ -5,1100 +5,890 @@ * Author: root */ - #include "misc.h" +char fifo_file[1000] = ""; -char fifo_file[1000]=""; +int mtu_warn = 1350; -int mtu_warn=1350; +int disable_mtu_warn = 1; +int disable_fec = 0; +int disable_checksum = 0; -int disable_mtu_warn=1; -int disable_fec=0; -int disable_checksum=0; +int debug_force_flush_fec = 0; -int debug_force_flush_fec=0; +int jitter_min = 0 * 1000; +int jitter_max = 0 * 1000; +int output_interval_min = 0 * 1000; +int output_interval_max = 0 * 1000; -int jitter_min=0*1000; -int jitter_max=0*1000; +int fix_latency = 0; -int output_interval_min=0*1000; -int output_interval_max=0*1000; - -int fix_latency=0; - - -address_t local_addr,remote_addr; -address_t *out_addr=0; -char *out_interface=0; -//u32_t local_ip_uint32,remote_ip_uint32=0; -//char local_ip[100], remote_ip[100]; -//int local_port = -1, remote_port = -1; +address_t local_addr, remote_addr; +address_t *out_addr = 0; +char *out_interface = 0; +// u32_t local_ip_uint32,remote_ip_uint32=0; +// char local_ip[100], remote_ip[100]; +// int local_port = -1, remote_port = -1; conn_manager_t conn_manager; delay_manager_t delay_manager; fd_manager_t fd_manager; -int time_mono_test=0; +int time_mono_test = 0; -int delay_capacity=0; +int delay_capacity = 0; +char sub_net[100] = "10.22.22.0"; +u32_t sub_net_uint32 = 0; -char sub_net[100]="10.22.22.0"; -u32_t sub_net_uint32=0; +char tun_dev[100] = ""; -char tun_dev[100]=""; +int keep_reconnect = 0; +int tun_mtu = 1500; -int keep_reconnect=0; +int mssfix = default_mtu; -int tun_mtu=1500; +int manual_set_tun = 0; +int persist_tun = 0; -int mssfix=default_mtu; +char rs_par_str[rs_str_len] = "20:10"; -int manual_set_tun=0; -int persist_tun=0; +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) { + static my_time_t out_delay_buf[max_fec_packet_num + 100] = {0}; + // static int out_len_buf[max_fec_packet_num+100]={0}; + // static int counter=0; + out_delay = out_delay_buf; + // out_len=out_len_buf; + inner_stat_t &inner_stat = conn_info.stat.normal_to_fec; + if (disable_fec) { + if (data == 0) { + out_n = 0; + return 0; + } + // assert(data!=0); + inner_stat.input_packet_num++; + inner_stat.input_packet_size += len; + inner_stat.output_packet_num++; + inner_stat.output_packet_size += len; -char rs_par_str[rs_str_len]="20:10"; + out_n = 1; + static char *data_static; + data_static = data; + static int len_static; + len_static = len; + out_arr = &data_static; + out_len = &len_static; + out_delay[0] = 0; + } else { + if (data != 0) { + inner_stat.input_packet_num++; + inner_stat.input_packet_size += len; + } + // counter++; -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) -{ + conn_info.fec_encode_manager.input(data, len); - static my_time_t out_delay_buf[max_fec_packet_num+100]={0}; - //static int out_len_buf[max_fec_packet_num+100]={0}; - //static int counter=0; - out_delay=out_delay_buf; - //out_len=out_len_buf; - inner_stat_t &inner_stat=conn_info.stat.normal_to_fec; - if(disable_fec) - { - if(data==0) - { - out_n=0; - return 0; - } - //assert(data!=0); - inner_stat.input_packet_num++; - inner_stat.input_packet_size+=len; - inner_stat.output_packet_num++; - inner_stat.output_packet_size+=len; + // if(counter%5==0) + // conn_info.fec_encode_manager.input(0,0); - out_n=1; - static char *data_static; - data_static=data; - static int len_static; - len_static=len; - out_arr=&data_static; - out_len=&len_static; - out_delay[0]=0; + // int n; + // char **s_arr; + // int s_len; - } - else - { - if(data!=0) - { - inner_stat.input_packet_num++; - inner_stat.input_packet_size+=len; - } - //counter++; + conn_info.fec_encode_manager.output(out_n, out_arr, out_len); - conn_info.fec_encode_manager.input(data,len); + if (out_n > 0) { + my_time_t common_latency = 0; + my_time_t first_packet_time = conn_info.fec_encode_manager.get_first_packet_time(); - //if(counter%5==0) - //conn_info.fec_encode_manager.input(0,0); + if (fix_latency == 1 && conn_info.fec_encode_manager.get_type() == 0) { + my_time_t current_time = get_current_time_us(); + my_time_t tmp; + assert(first_packet_time != 0); + // mylog(log_info,"current_time=%llu first_packlet_time=%llu fec_pending_time=%llu\n",current_time,first_packet_time,(my_time_t)fec_pending_time); + if ((my_time_t)conn_info.fec_encode_manager.get_pending_time() >= (current_time - first_packet_time)) { + tmp = (my_time_t)conn_info.fec_encode_manager.get_pending_time() - (current_time - first_packet_time); + // mylog(log_info,"tmp=%llu\n",tmp); + } else { + tmp = 0; + // mylog(log_info,"0\n"); + } + common_latency += tmp; + } - //int n; - //char **s_arr; - //int s_len; + common_latency += random_between(jitter_min, jitter_max); + out_delay_buf[0] = common_latency; - conn_info.fec_encode_manager.output(out_n,out_arr,out_len); + for (int i = 1; i < out_n; i++) { + out_delay_buf[i] = out_delay_buf[i - 1] + (my_time_t)(random_between(output_interval_min, output_interval_max) / (out_n - 1)); + } + } - if(out_n>0) - { - my_time_t common_latency=0; - my_time_t first_packet_time=conn_info.fec_encode_manager.get_first_packet_time(); + if (out_n > 0) { + log_bare(log_trace, "seq= %u ", read_u32(out_arr[0])); + } + for (int i = 0; i < out_n; i++) { + inner_stat.output_packet_num++; + inner_stat.output_packet_size += out_len[i]; - if(fix_latency==1&&conn_info.fec_encode_manager.get_type()==0) - { - my_time_t current_time=get_current_time_us(); - my_time_t tmp; - assert(first_packet_time!=0); - //mylog(log_info,"current_time=%llu first_packlet_time=%llu fec_pending_time=%llu\n",current_time,first_packet_time,(my_time_t)fec_pending_time); - if((my_time_t)conn_info.fec_encode_manager.get_pending_time() >=(current_time - first_packet_time)) - { - tmp=(my_time_t)conn_info.fec_encode_manager.get_pending_time()-(current_time - first_packet_time); - //mylog(log_info,"tmp=%llu\n",tmp); - } - else - { - tmp=0; - //mylog(log_info,"0\n"); - } - common_latency+=tmp; - } + log_bare(log_trace, "%d ", out_len[i]); + } - common_latency+=random_between(jitter_min,jitter_max); + log_bare(log_trace, "\n"); + } - out_delay_buf[0]=common_latency; + mylog(log_trace, "from_normal_to_fec input_len=%d,output_n=%d\n", len, out_n); - for(int i=1;i0) - { - log_bare(log_trace,"seq= %u ",read_u32(out_arr[0])); - } - for(int i=0;i",n); - /* - for(int i=0;i\n",s_arr[i]); - }*/ - //my_send(dest,data,len); - return 0; + // printf("",n); + /* + for(int i=0;i\n",s_arr[i]); + }*/ + // my_send(dest,data,len); + return 0; } +int delay_send(my_time_t delay, const dest_t &dest, char *data, int len) { + // int rand=random()%100; + // mylog(log_info,"rand = %d\n",rand); -int delay_send(my_time_t delay,const dest_t &dest,char *data,int len) -{ - //int rand=random()%100; - //mylog(log_info,"rand = %d\n",rand); - - if (dest.cook&&random_drop != 0) { - if (get_fake_random_number() % 10000 < (u32_t) random_drop) { - return 0; - } - } - return delay_manager.add(delay,dest,data,len);; + if (dest.cook && random_drop != 0) { + if (get_fake_random_number() % 10000 < (u32_t)random_drop) { + return 0; + } + } + return delay_manager.add(delay, dest, data, len); + ; } -int print_parameter() -{ - mylog(log_info,"jitter_min=%d jitter_max=%d output_interval_min=%d output_interval_max=%d fec_timeout=%d fec_mtu=%d fec_queue_len=%d fec_mode=%d\n", - jitter_min/1000,jitter_max/1000,output_interval_min/1000,output_interval_max/1000,g_fec_par.timeout/1000,g_fec_par.mtu,g_fec_par.queue_len,g_fec_par.mode); - mylog(log_info,"fec_str=%s\n",rs_par_str); - mylog(log_info,"fec_inner_parameter=%s\n",g_fec_par.rs_to_str()); - return 0; +int print_parameter() { + mylog(log_info, "jitter_min=%d jitter_max=%d output_interval_min=%d output_interval_max=%d fec_timeout=%d fec_mtu=%d fec_queue_len=%d fec_mode=%d\n", + jitter_min / 1000, jitter_max / 1000, output_interval_min / 1000, output_interval_max / 1000, g_fec_par.timeout / 1000, g_fec_par.mtu, g_fec_par.queue_len, g_fec_par.mode); + mylog(log_info, "fec_str=%s\n", rs_par_str); + mylog(log_info, "fec_inner_parameter=%s\n", g_fec_par.rs_to_str()); + return 0; } -int handle_command(char *s) -{ - int len=strlen(s); - while(len>=1&&s[len-1]=='\n') - s[len-1]=0; - mylog(log_info,"got data from fifo,len=%d,s=[%s]\n",len,s); - int a=-1,b=-1; - if(strncmp(s,"fec",strlen("fec"))==0) - { - mylog(log_info,"got command [fec]\n"); - char tmp_str[max_fec_packet_num*10+100]; - fec_parameter_t tmp_par; - sscanf(s,"fec %s",tmp_str); - /* - if(a<1||b<0||a+b>254) - { - mylog(log_warn,"invaild value\n"); - return -1; - }*/ - int ret=tmp_par.rs_from_str(tmp_str); - if(ret!=0) - { - mylog(log_warn,"failed to parse [%s]\n",tmp_str); - return -1; - } - int version=g_fec_par.version; - g_fec_par.copy_fec(tmp_par); - g_fec_par.version=version+1; - strcpy(rs_par_str,tmp_str); - //g_fec_data_num=a; - //g_fec_redundant_num=b; - } - else if(strncmp(s,"mtu",strlen("mtu"))==0) - { - mylog(log_info,"got command [mtu]\n"); - sscanf(s,"mtu %d",&a); - if(a<100||a>2000) - { - mylog(log_warn,"invaild value\n"); - return -1; - } - g_fec_par.mtu=a; - } - else if(strncmp(s,"queue-len",strlen("queue-len"))==0) - { - mylog(log_info,"got command [queue-len]\n"); - sscanf(s,"queue-len %d",&a); - if(a<1||a>10000) - { - mylog(log_warn,"invaild value\n"); - return -1; - } - g_fec_par.queue_len=a; - } - else if(strncmp(s,"mode",strlen("mode"))==0) - { - mylog(log_info,"got command [mode]\n"); - sscanf(s,"mode %d",&a); - if(a!=0&&a!=1) - { - mylog(log_warn,"invaild value\n"); - return -1; - } - if(g_fec_par.mode!=a) - { - g_fec_par.mode=a; +int handle_command(char *s) { + int len = strlen(s); + while (len >= 1 && s[len - 1] == '\n') + s[len - 1] = 0; + mylog(log_info, "got data from fifo,len=%d,s=[%s]\n", len, s); + int a = -1, b = -1; + if (strncmp(s, "fec", strlen("fec")) == 0) { + mylog(log_info, "got command [fec]\n"); + char tmp_str[max_fec_packet_num * 10 + 100]; + fec_parameter_t tmp_par; + sscanf(s, "fec %s", tmp_str); + /* + if(a<1||b<0||a+b>254) + { + mylog(log_warn,"invaild value\n"); + return -1; + }*/ + int ret = tmp_par.rs_from_str(tmp_str); + if (ret != 0) { + mylog(log_warn, "failed to parse [%s]\n", tmp_str); + return -1; + } + int version = g_fec_par.version; + g_fec_par.copy_fec(tmp_par); + g_fec_par.version = version + 1; + strcpy(rs_par_str, tmp_str); + // g_fec_data_num=a; + // g_fec_redundant_num=b; + } else if (strncmp(s, "mtu", strlen("mtu")) == 0) { + mylog(log_info, "got command [mtu]\n"); + sscanf(s, "mtu %d", &a); + if (a < 100 || a > 2000) { + mylog(log_warn, "invaild value\n"); + return -1; + } + g_fec_par.mtu = a; + } else if (strncmp(s, "queue-len", strlen("queue-len")) == 0) { + mylog(log_info, "got command [queue-len]\n"); + sscanf(s, "queue-len %d", &a); + if (a < 1 || a > 10000) { + mylog(log_warn, "invaild value\n"); + return -1; + } + g_fec_par.queue_len = a; + } else if (strncmp(s, "mode", strlen("mode")) == 0) { + mylog(log_info, "got command [mode]\n"); + sscanf(s, "mode %d", &a); + if (a != 0 && a != 1) { + mylog(log_warn, "invaild value\n"); + return -1; + } + if (g_fec_par.mode != a) { + g_fec_par.mode = a; - assert(g_fec_par.rs_from_str(rs_par_str)==0); //re parse rs_par_str,not necessary at the moment, for futher use - g_fec_par.version++; - } - } - else if(strncmp(s,"timeout",strlen("timeout"))==0) - { - mylog(log_info,"got command [timeout]\n"); - sscanf(s,"timeout %d",&a); - if(a<0||a>1000) - { - mylog(log_warn,"invaild value\n"); - return -1; - } - g_fec_par.timeout=a*1000; - } - else - { - mylog(log_info,"unknown command\n"); - } - print_parameter(); + assert(g_fec_par.rs_from_str(rs_par_str) == 0); // re parse rs_par_str,not necessary at the moment, for futher use + g_fec_par.version++; + } + } else if (strncmp(s, "timeout", strlen("timeout")) == 0) { + mylog(log_info, "got command [timeout]\n"); + sscanf(s, "timeout %d", &a); + if (a < 0 || a > 1000) { + mylog(log_warn, "invaild value\n"); + return -1; + } + g_fec_par.timeout = a * 1000; + } else { + mylog(log_info, "unknown command\n"); + } + print_parameter(); - return 0; + return 0; } -static void empty_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - +static void empty_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { } -int unit_test() -{ +int unit_test() { + { + union test_t { + u64_t u64; + char arry[8]; + } test111; - { - union test_t - { - u64_t u64; - char arry[8]; - }test111; + assert((void *)&test111.u64 == (void *)&test111.arry[0]); + // printf("%llx,%llx\n",&ttt.u64,&ttt.arry[0]); - assert((void*)&test111.u64==(void*)&test111.arry[0]); - //printf("%llx,%llx\n",&ttt.u64,&ttt.arry[0]); + // printf("%lld\n",get_fake_random_number_64()); + // printf("%lld\n",get_fake_random_number_64()); + // printf("%lld\n",get_fake_random_number_64()); -// printf("%lld\n",get_fake_random_number_64()); -// printf("%lld\n",get_fake_random_number_64()); -// printf("%lld\n",get_fake_random_number_64()); + // printf("%x\n",get_fake_random_number()); + // printf("%x\n",get_fake_random_number()); + // printf("%x\n",get_fake_random_number()); -// printf("%x\n",get_fake_random_number()); -// printf("%x\n",get_fake_random_number()); -// printf("%x\n",get_fake_random_number()); + char buf[10]; + get_fake_random_chars(buf, 10); + for (int i = 0; i < 10; i++) + printf("<%d>", (int)buf[i]); + printf("\n"); - char buf[10]; - get_fake_random_chars(buf,10); - for(int i=0;i<10;i++) - printf("<%d>",(int)buf[i]); - printf("\n"); + get_fake_random_chars(buf, 10); + for (int i = 0; i < 10; i++) + printf("<%d>", (int)buf[i]); + printf("\n"); + } - get_fake_random_chars(buf,10); - for(int i=0;i<10;i++) - printf("<%d>",(int)buf[i]); - printf("\n"); - } + int i, j, k; + void *code = fec_new(3, 6); + char arr[6][100] = + { + "aaa", "bbb", "ccc", "ddd", "eee", "fff"}; + char *data[6]; + for (i = 0; i < 6; i++) { + data[i] = arr[i]; + } + rs_encode2(3, 6, data, 3); + // printf("%d %d",(int)(unsigned char)arr[5][0],(int)('a'^'b'^'c'^'d'^'e')); + for (i = 0; i < 6; i++) { + printf("<%s>", data[i]); + } - int i,j,k; - void *code=fec_new(3,6); - char arr[6][100]= - { - "aaa","bbb","ccc" - ,"ddd","eee","fff" - }; - char *data[6]; - for(i=0;i<6;i++) - { - data[i]=arr[i]; - } - rs_encode2(3,6,data,3); - //printf("%d %d",(int)(unsigned char)arr[5][0],(int)('a'^'b'^'c'^'d'^'e')); + data[0] = 0; + // data[1]=0; + // data[5]=0; - for(i=0;i<6;i++) - { - printf("<%s>",data[i]); - } + int ret = rs_decode2(3, 6, data, 3); + printf("ret:%d\n", ret); - data[0]=0; - //data[1]=0; - //data[5]=0; + for (i = 0; i < 6; i++) { + printf("<%s>", data[i]); + } + fec_free(code); - int ret=rs_decode2(3,6,data,3); - printf("ret:%d\n",ret); + char arr2[6][100] = + { + "aaa11111", "", "ccc333333333", "ddd444", "eee5555", "ff6666"}; + blob_encode_t blob_encode; + for (int i = 0; i < 6; i++) + blob_encode.input(arr2[i], strlen(arr2[i])); - for(i=0;i<6;i++) - { - printf("<%s>",data[i]); - } - fec_free(code); + char **output; + int shard_len; + blob_encode.output(7, output, shard_len); + printf("", shard_len); + blob_decode_t blob_decode; + for (int i = 0; i < 7; i++) { + blob_decode.input(output[i], shard_len); + } - char arr2[6][100]= - { - "aaa11111","","ccc333333333" - ,"ddd444","eee5555","ff6666" - }; - blob_encode_t blob_encode; - for(int i=0;i<6;i++) - blob_encode.input(arr2[i],strlen(arr2[i])); + char **decode_output; + int *len_arr; + int num; - char **output; - int shard_len; - blob_encode.output(7,output,shard_len); + ret = blob_decode.output(num, decode_output, len_arr); + printf("\n", num, ret); + for (int i = 0; i < num; i++) { + char buf[1000] = {0}; + memcpy(buf, decode_output[i], len_arr[i]); + printf("<%d:%s>", len_arr[i], buf); + } + printf("\n"); + static fec_encode_manager_t fec_encode_manager; + static fec_decode_manager_t fec_decode_manager; - printf("",shard_len); - blob_decode_t blob_decode; - for(int i=0;i<7;i++) - { - blob_decode.input(output[i],shard_len); - } + // dynamic_update_fec=0; - char **decode_output; - int * len_arr; - int num; + fec_encode_manager.set_loop_and_cb(ev_default_loop(0), empty_cb); + { + string a = "11111"; + string b = "22"; + string c = "33333333"; - ret=blob_decode.output(num,decode_output,len_arr); + fec_encode_manager.input((char *)a.c_str(), a.length()); + fec_encode_manager.input((char *)b.c_str(), b.length()); + fec_encode_manager.input((char *)c.c_str(), c.length()); + fec_encode_manager.input(0, 0); - printf("\n",num,ret); - for(int i=0;i",len_arr[i],buf); - } - printf("\n"); - static fec_encode_manager_t fec_encode_manager; - static fec_decode_manager_t fec_decode_manager; + int n; + char **s_arr; + int *len; - //dynamic_update_fec=0; + fec_encode_manager.output(n, s_arr, len); + printf("", n, len[0]); - fec_encode_manager.set_loop_and_cb(ev_default_loop(0),empty_cb); + for (int i = 0; i < n; i++) { + fec_decode_manager.input(s_arr[i], len[i]); + } - { + { + int n; + char **s_arr; + int *len_arr; + fec_decode_manager.output(n, s_arr, len_arr); + printf("", n); + for (int i = 0; i < n; i++) { + s_arr[i][len_arr[i]] = 0; + printf("<%s>\n", s_arr[i]); + } + } + } - string a = "11111"; - string b = "22"; - string c = "33333333"; + { + string a = "aaaaaaa"; + string b = "bbbbbbbbbbbbb"; + string c = "ccc"; - fec_encode_manager.input((char *) a.c_str(), a.length()); - fec_encode_manager.input((char *) b.c_str(), b.length()); - fec_encode_manager.input((char *) c.c_str(), c.length()); - fec_encode_manager.input(0, 0); + fec_encode_manager.input((char *)a.c_str(), a.length()); + fec_encode_manager.input((char *)b.c_str(), b.length()); + fec_encode_manager.input((char *)c.c_str(), c.length()); + fec_encode_manager.input(0, 0); - int n; - char **s_arr; - int *len; + int n; + char **s_arr; + int *len; + fec_encode_manager.output(n, s_arr, len); + printf("", n, len[0]); - fec_encode_manager.output(n,s_arr,len); - printf("",n,len[0]); + for (int i = 0; i < n; i++) { + if (i == 1 || i == 3 || i == 5 || i == 0) + fec_decode_manager.input(s_arr[i], len[i]); + } - for(int i=0;i", n); + for (int i = 0; i < n; i++) { + s_arr[i][len_arr[i]] = 0; + printf("<%s>\n", s_arr[i]); + } + } + } - { - int n;char ** s_arr;int* len_arr; - fec_decode_manager.output(n,s_arr,len_arr); - printf("",n); - for(int i=0;i\n",s_arr[i]); - } - } + printf("ok here.\n"); + for (int i = 0; i < 10; i++) { + string a = "aaaaaaaaaaaaaaaaaaaaaaa"; + string b = "bbbbbbbbbbbbb"; + string c = "cccccccccccccccccc"; + printf("======\n"); + int n; + char **s_arr; + int *len; + fec_decode_manager.output(n, s_arr, len); - } + // fec_encode_manager.reset_fec_parameter(3,2,g_fec_mtu,g_fec_queue_len,g_fec_timeout,1); - { - string a = "aaaaaaa"; - string b = "bbbbbbbbbbbbb"; - string c = "ccc"; + fec_parameter_t &fec_par = fec_encode_manager.get_fec_par(); + fec_par.mtu = g_fec_par.mtu; + fec_par.queue_len = g_fec_par.queue_len; + fec_par.timeout = g_fec_par.timeout; + fec_par.mode = 1; + fec_par.rs_from_str((char *)"3:2"); + fec_encode_manager.input((char *)a.c_str(), a.length()); + fec_encode_manager.output(n, s_arr, len); - fec_encode_manager.input((char *) a.c_str(), a.length()); - fec_encode_manager.input((char *) b.c_str(), b.length()); - fec_encode_manager.input((char *) c.c_str(), c.length()); - fec_encode_manager.input(0, 0); + printf("n=<%d>\n", n); + assert(n == 1); - int n; - char **s_arr; - int * len; + fec_decode_manager.input(s_arr[0], len[0]); + fec_decode_manager.output(n, s_arr, len); + assert(n == 1); + printf("%s\n", s_arr[0]); - fec_encode_manager.output(n,s_arr,len); - printf("",n,len[0]); + fec_encode_manager.input((char *)b.c_str(), b.length()); + fec_encode_manager.output(n, s_arr, len); + assert(n == 1); + // fec_decode_manager.input(s_arr[0],len[0]); - for(int i=0;i",n); - for(int i=0;i\n",s_arr[i]); - } - } - } + assert(n == 3); - printf("ok here.\n"); - for(int i=0;i<10;i++) - { - string a = "aaaaaaaaaaaaaaaaaaaaaaa"; - string b = "bbbbbbbbbbbbb"; - string c = "cccccccccccccccccc"; + fec_decode_manager.input(s_arr[0], len[0]); + // printf("n=%d\n",n); + { + int n; + char **s_arr; + int *len; + fec_decode_manager.output(n, s_arr, len); + assert(n == 1); + printf("%s\n", s_arr[0]); + } + fec_decode_manager.input(s_arr[1], len[1]); - printf("======\n"); - int n; - char **s_arr; - int * len; - fec_decode_manager.output(n,s_arr,len); + { + int n; + char **s_arr; + int *len; + fec_decode_manager.output(n, s_arr, len); + assert(n == 1); + printf("n=%d\n", n); + s_arr[0][len[0]] = 0; + printf("%s\n", s_arr[0]); + } + } - //fec_encode_manager.reset_fec_parameter(3,2,g_fec_mtu,g_fec_queue_len,g_fec_timeout,1); - - fec_parameter_t &fec_par=fec_encode_manager.get_fec_par(); - fec_par.mtu=g_fec_par.mtu; - fec_par.queue_len=g_fec_par.queue_len; - fec_par.timeout=g_fec_par.timeout; - fec_par.mode=1; - fec_par.rs_from_str((char *)"3:2"); - - fec_encode_manager.input((char *) a.c_str(), a.length()); - fec_encode_manager.output(n,s_arr,len); - - printf("n=<%d>\n",n); - assert(n==1); - - fec_decode_manager.input(s_arr[0],len[0]); - - fec_decode_manager.output(n,s_arr,len); - assert(n==1); - printf("%s\n",s_arr[0]); - - fec_encode_manager.input((char *) b.c_str(), b.length()); - fec_encode_manager.output(n,s_arr,len); - assert(n==1); - //fec_decode_manager.input(s_arr[0],len[0]); - - - fec_encode_manager.input((char *) c.c_str(), c.length()); - fec_encode_manager.output(n,s_arr,len); - - assert(n==3); - - fec_decode_manager.input(s_arr[0],len[0]); - //printf("n=%d\n",n); - - - { - int n; - char **s_arr; - int * len; - fec_decode_manager.output(n,s_arr,len); - assert(n==1); - printf("%s\n",s_arr[0]); - } - - fec_decode_manager.input(s_arr[1],len[1]); - - { - int n; - char **s_arr; - int * len; - fec_decode_manager.output(n,s_arr,len); - assert(n==1); - printf("n=%d\n",n); - s_arr[0][len[0]]=0; - printf("%s\n",s_arr[0]); - } - - } - - myexit(0); - return 0; + myexit(0); + return 0; } - -void process_arg(int argc, char *argv[]) -{ - int is_client=0,is_server=0; - int i, j, k; - int opt; +void process_arg(int argc, char *argv[]) { + int is_client = 0, is_server = 0; + int i, j, k; + int opt; static struct option long_options[] = - { - {"log-level", required_argument, 0, 1}, - {"log-position", no_argument, 0, 1}, - {"disable-color", no_argument, 0, 1}, - {"enable-color", no_argument, 0, 1}, - {"disable-filter", no_argument, 0, 1}, - {"disable-fec", no_argument, 0, 1}, - {"disable-obscure", no_argument, 0, 1}, - {"disable-xor", no_argument, 0, 1}, - {"disable-checksum", no_argument, 0, 1}, - {"fix-latency", no_argument, 0, 1}, - {"sock-buf", required_argument, 0, 1}, - {"random-drop", required_argument, 0, 1}, - {"report", required_argument, 0, 1}, - {"delay-capacity", required_argument, 0, 1}, - {"mtu", required_argument, 0, 1}, - {"mode", required_argument, 0,1}, - {"timeout", required_argument, 0,1}, - {"decode-buf", required_argument, 0,1}, - {"queue-len", required_argument, 0,'q'}, - {"fec", required_argument, 0,'f'}, - {"jitter", required_argument, 0,'j'}, - {"out-addr", required_argument, 0,1}, - {"out-interface", required_argument, 0, 1}, - {"key", required_argument, 0,'k'}, - {"header-overhead", required_argument, 0, 1}, - //{"debug-fec", no_argument, 0, 1}, - {"debug-fec-enc", no_argument, 0, 1}, - {"debug-fec-dec", no_argument, 0, 1}, - {"fifo", required_argument, 0, 1}, - {"sub-net", required_argument, 0, 1}, - {"tun-dev", required_argument, 0, 1}, - {"tun-mtu", required_argument, 0, 1}, - {"mssfix", required_argument, 0, 1}, - {"keep-reconnect", no_argument, 0, 1}, - {"persist-tun", no_argument, 0, 1}, - {"manual-set-tun", no_argument, 0, 1}, - {"interval", required_argument, 0,'i'}, - {NULL, 0, 0, 0} - }; + { + {"log-level", required_argument, 0, 1}, + {"log-position", no_argument, 0, 1}, + {"disable-color", no_argument, 0, 1}, + {"enable-color", no_argument, 0, 1}, + {"disable-filter", no_argument, 0, 1}, + {"disable-fec", no_argument, 0, 1}, + {"disable-obscure", no_argument, 0, 1}, + {"disable-xor", no_argument, 0, 1}, + {"disable-checksum", no_argument, 0, 1}, + {"fix-latency", no_argument, 0, 1}, + {"sock-buf", required_argument, 0, 1}, + {"random-drop", required_argument, 0, 1}, + {"report", required_argument, 0, 1}, + {"delay-capacity", required_argument, 0, 1}, + {"mtu", required_argument, 0, 1}, + {"mode", required_argument, 0, 1}, + {"timeout", required_argument, 0, 1}, + {"decode-buf", required_argument, 0, 1}, + {"queue-len", required_argument, 0, 'q'}, + {"fec", required_argument, 0, 'f'}, + {"jitter", required_argument, 0, 'j'}, + {"out-addr", required_argument, 0, 1}, + {"out-interface", required_argument, 0, 1}, + {"key", required_argument, 0, 'k'}, + {"header-overhead", required_argument, 0, 1}, + //{"debug-fec", no_argument, 0, 1}, + {"debug-fec-enc", no_argument, 0, 1}, + {"debug-fec-dec", no_argument, 0, 1}, + {"fifo", required_argument, 0, 1}, + {"sub-net", required_argument, 0, 1}, + {"tun-dev", required_argument, 0, 1}, + {"tun-mtu", required_argument, 0, 1}, + {"mssfix", required_argument, 0, 1}, + {"keep-reconnect", no_argument, 0, 1}, + {"persist-tun", no_argument, 0, 1}, + {"manual-set-tun", no_argument, 0, 1}, + {"interval", required_argument, 0, 'i'}, + {NULL, 0, 0, 0}}; int option_index = 0; - assert(g_fec_par.rs_from_str(rs_par_str)==0); + assert(g_fec_par.rs_from_str(rs_par_str) == 0); - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"--unit-test")==0) - { - unit_test(); - myexit(0); - } - } + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "--unit-test") == 0) { + unit_test(); + myexit(0); + } + } - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"--log-level")==0) - { - if(i 1000 * 10) { + mylog(log_fatal, "jitter must be between 0 and 10,000(10 second)\n"); + myexit(-1); + } + jitter_min = 0; + jitter_max = jitter; - 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) - { - //string opt_key; - //opt_key+=opt; - switch (opt) - { - case 'k': - sscanf(optarg,"%s\n",key_string); - mylog(log_debug,"key=%s\n",key_string); - if(strlen(key_string)==0) - { - mylog(log_fatal,"key len=0??\n"); - myexit(-1); - } - break; - case 'j': - if (strchr(optarg, ':') == 0) - { - int jitter; - sscanf(optarg,"%d\n",&jitter); - if(jitter<0 ||jitter>1000*10) - { - mylog(log_fatal,"jitter must be between 0 and 10,000(10 second)\n"); - myexit(-1); - } - jitter_min=0; - jitter_max=jitter; + } else { + sscanf(optarg, "%d:%d\n", &jitter_min, &jitter_max); + if (jitter_min < 0 || jitter_max < 0 || jitter_min > jitter_max) { + mylog(log_fatal, " must satisfy 0<=jmin<=jmax\n"); + myexit(-1); + } + } + jitter_min *= 1000; + jitter_max *= 1000; + break; + case 'i': + if (strchr(optarg, ':') == 0) { + int output_interval = -1; + sscanf(optarg, "%d\n", &output_interval); + if (output_interval < 0 || output_interval > 1000 * 10) { + mylog(log_fatal, "output_interval must be between 0 and 10,000(10 second)\n"); + myexit(-1); + } + output_interval_min = output_interval_max = output_interval; + } else { + sscanf(optarg, "%d:%d\n", &output_interval_min, &output_interval_max); + if (output_interval_min < 0 || output_interval_max < 0 || output_interval_min > output_interval_max) { + mylog(log_fatal, " must satisfy 0<=output_interval_min<=output_interval_max\n"); + myexit(-1); + } + } + output_interval_min *= 1000; + output_interval_max *= 1000; + break; + case 'f': + if (strchr(optarg, ':') == 0) { + mylog(log_fatal, "invalid format for f"); + myexit(-1); + } else { + strcpy(rs_par_str, optarg); + // sscanf(optarg,"%d:%d\n",&g_fec_data_num,&g_fec_redundant_num); + /* + if(g_fec_data_num<1 ||g_fec_redundant_num<0||g_fec_data_num+g_fec_redundant_num>254) + { + mylog(log_fatal,"fec_data_num<1 ||fec_redundant_num<0||fec_data_num+fec_redundant_num>254\n"); + myexit(-1); + }*/ + } + break; + case 'q': + sscanf(optarg, "%d", &g_fec_par.queue_len); + if (g_fec_par.queue_len < 1 || g_fec_par.queue_len > 10000) { + mylog(log_fatal, "fec_pending_num should be between 1 and 10000\n"); + myexit(-1); + } + break; + case 'c': + is_client = 1; + break; + case 's': + is_server = 1; + break; + case 'l': + no_l = 0; + local_addr.from_str(optarg); + break; + case 'r': + no_r = 0; + remote_addr.from_str(optarg); + break; + case 'h': + break; + case 1: + if (strcmp(long_options[option_index].name, "log-level") == 0) { + } else if (strcmp(long_options[option_index].name, "disable-filter") == 0) { + disable_replay_filter = 1; + // enable_log_color=0; + } else if (strcmp(long_options[option_index].name, "disable-color") == 0) { + // enable_log_color=0; + } else if (strcmp(long_options[option_index].name, "enable-color") == 0) { + // enable_log_color=0; + } else if (strcmp(long_options[option_index].name, "disable-fec") == 0) { + disable_fec = 1; + } else if (strcmp(long_options[option_index].name, "disable-obscure") == 0) { + mylog(log_info, "obscure disabled\n"); + disable_obscure = 1; + } else if (strcmp(long_options[option_index].name, "disable-xor") == 0) { + mylog(log_info, "xor disabled\n"); + disable_xor = 1; + } else if (strcmp(long_options[option_index].name, "disable-checksum") == 0) { + disable_checksum = 1; + mylog(log_warn, "checksum disabled\n"); + } else if (strcmp(long_options[option_index].name, "fix-latency") == 0) { + mylog(log_info, "fix-latency enabled\n"); + fix_latency = 1; + } + else if (strcmp(long_options[option_index].name, "log-position") == 0) { + enable_log_position = 1; + } else if (strcmp(long_options[option_index].name, "random-drop") == 0) { + sscanf(optarg, "%d", &random_drop); + if (random_drop < 0 || random_drop > 10000) { + mylog(log_fatal, "random_drop must be between 0 10000 \n"); + myexit(-1); + } + mylog(log_info, "random_drop=%d\n", random_drop); + } else if (strcmp(long_options[option_index].name, "delay-capacity") == 0) { + sscanf(optarg, "%d", &delay_capacity); - } - else - { - sscanf(optarg,"%d:%d\n",&jitter_min,&jitter_max); - if(jitter_min<0 ||jitter_max<0||jitter_min>jitter_max) - { - mylog(log_fatal," must satisfy 0<=jmin<=jmax\n"); - myexit(-1); - } - } - jitter_min*=1000; - jitter_max*=1000; - break; - case 'i': - if (strchr(optarg, ':') == 0) - { - int output_interval=-1; - sscanf(optarg,"%d\n",&output_interval); - if(output_interval<0||output_interval>1000*10) - { - mylog(log_fatal,"output_interval must be between 0 and 10,000(10 second)\n"); - myexit(-1); - } - output_interval_min=output_interval_max=output_interval; - } - else - { - sscanf(optarg,"%d:%d\n",&output_interval_min,&output_interval_max); - if(output_interval_min<0 ||output_interval_max<0||output_interval_min>output_interval_max) - { - mylog(log_fatal," must satisfy 0<=output_interval_min<=output_interval_max\n"); - myexit(-1); - } - } - output_interval_min*=1000; - output_interval_max*=1000; - break; - case 'f': - if (strchr(optarg, ':') == 0) - { - mylog(log_fatal,"invalid format for f"); - myexit(-1); - } - else - { - strcpy(rs_par_str,optarg); - //sscanf(optarg,"%d:%d\n",&g_fec_data_num,&g_fec_redundant_num); - /* - if(g_fec_data_num<1 ||g_fec_redundant_num<0||g_fec_data_num+g_fec_redundant_num>254) - { - mylog(log_fatal,"fec_data_num<1 ||fec_redundant_num<0||fec_data_num+fec_redundant_num>254\n"); - myexit(-1); - }*/ - } - break; - case 'q': - sscanf(optarg,"%d",&g_fec_par.queue_len); - if(g_fec_par.queue_len<1||g_fec_par.queue_len>10000) - { + if (delay_capacity < 0) { + mylog(log_fatal, "delay_capacity must be >=0 \n"); + myexit(-1); + } + } else if (strcmp(long_options[option_index].name, "report") == 0) { + sscanf(optarg, "%d", &report_interval); - mylog(log_fatal,"fec_pending_num should be between 1 and 10000\n"); - myexit(-1); - } - break; - case 'c': - is_client = 1; - break; - case 's': - is_server = 1; - break; - case 'l': - no_l = 0; - local_addr.from_str(optarg); - break; - case 'r': - no_r = 0; - remote_addr.from_str(optarg); - break; - case 'h': - break; - case 1: - if(strcmp(long_options[option_index].name,"log-level")==0) - { - } - else if(strcmp(long_options[option_index].name,"disable-filter")==0) - { - disable_replay_filter=1; - //enable_log_color=0; - } - else if(strcmp(long_options[option_index].name,"disable-color")==0) - { - //enable_log_color=0; - } - else if(strcmp(long_options[option_index].name,"enable-color")==0) - { - //enable_log_color=0; - } - else if(strcmp(long_options[option_index].name,"disable-fec")==0) - { - disable_fec=1; - } - else if(strcmp(long_options[option_index].name,"disable-obscure")==0) - { - mylog(log_info,"obscure disabled\n"); - disable_obscure=1; - } - else if(strcmp(long_options[option_index].name,"disable-xor")==0) - { - mylog(log_info,"xor disabled\n"); - disable_xor=1; - } - else if(strcmp(long_options[option_index].name,"disable-checksum")==0) - { - disable_checksum=1; - mylog(log_warn,"checksum disabled\n"); - } - else if(strcmp(long_options[option_index].name,"fix-latency")==0) - { - mylog(log_info,"fix-latency enabled\n"); - fix_latency=1; - } + if (report_interval <= 0) { + mylog(log_fatal, "report_interval must be >0 \n"); + myexit(-1); + } + } else if (strcmp(long_options[option_index].name, "sock-buf") == 0) { + int tmp = -1; + sscanf(optarg, "%d", &tmp); + if (10 <= tmp && tmp <= 10 * 1024) { + socket_buf_size = tmp * 1024; + } else { + mylog(log_fatal, "sock-buf value must be between 1 and 10240 (kbyte) \n"); + myexit(-1); + } + } else if (strcmp(long_options[option_index].name, "decode-buf") == 0) { + sscanf(optarg, "%d", &fec_buff_num); + if (fec_buff_num < 300 || fec_buff_num > 20000) { + mylog(log_fatal, "decode-buf value must be between 300 and 20000 (kbyte) \n"); + myexit(-1); + } + mylog(log_info, "decode-buf=%d\n", fec_buff_num); + } else if (strcmp(long_options[option_index].name, "mode") == 0) { + sscanf(optarg, "%d", &g_fec_par.mode); + if (g_fec_par.mode != 0 && g_fec_par.mode != 1) { + mylog(log_fatal, "mode should be 0 or 1\n"); + myexit(-1); + } + } else if (strcmp(long_options[option_index].name, "mtu") == 0) { + sscanf(optarg, "%d", &g_fec_par.mtu); + if (g_fec_par.mtu < 100 || g_fec_par.mtu > 2000) { + mylog(log_fatal, "fec_mtu should be between 100 and 2000\n"); + myexit(-1); + } + } else if (strcmp(long_options[option_index].name, "out-addr") == 0) { + // has_b = true; + mylog(log_debug, "out-addr=%s\n", optarg); + out_addr = new address_t(); + out_addr->from_str(optarg); + } else if (strcmp(long_options[option_index].name, "out-interface") == 0) { + out_interface = new char[strlen(optarg) + 10]; + sscanf(optarg, "%s\n", out_interface); + mylog(log_debug, "out-interface=%s\n", out_interface); + if (strlen(out_interface) == 0) { + mylog(log_fatal, "out_interface string len=0??\n"); + myexit(-1); + } + } else if (strcmp(long_options[option_index].name, "timeout") == 0) { + sscanf(optarg, "%d", &g_fec_par.timeout); + if (g_fec_par.timeout < 0 || g_fec_par.timeout > 1000) { + mylog(log_fatal, "fec_pending_time should be between 0 and 1000(1s)\n"); + myexit(-1); + } + g_fec_par.timeout *= 1000; + } else if (strcmp(long_options[option_index].name, "debug-fec-enc") == 0) { + debug_fec_enc = 1; + mylog(log_info, "debug_fec_enc enabled\n"); + } else if (strcmp(long_options[option_index].name, "debug-fec-dec") == 0) { + debug_fec_dec = 1; + mylog(log_info, "debug_fec_dec enabled\n"); + } else if (strcmp(long_options[option_index].name, "fifo") == 0) { + sscanf(optarg, "%s", fifo_file); - else if(strcmp(long_options[option_index].name,"log-position")==0) - { - enable_log_position=1; - } - else if(strcmp(long_options[option_index].name,"random-drop")==0) - { - sscanf(optarg,"%d",&random_drop); - if(random_drop<0||random_drop>10000) - { - mylog(log_fatal,"random_drop must be between 0 10000 \n"); - myexit(-1); - } - mylog(log_info,"random_drop=%d\n",random_drop); - } - else if(strcmp(long_options[option_index].name,"delay-capacity")==0) - { - sscanf(optarg,"%d",&delay_capacity); + 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, "manual-set-tun") == 0) { + manual_set_tun = 1; + mylog(log_info, "manual_set_tun enabled\n"); + } else if (strcmp(long_options[option_index].name, "persist-tun") == 0) { + persist_tun = 1; + mylog(log_info, "persist_tun enabled\n"); + } else if (strcmp(long_options[option_index].name, "sub-net") == 0) { + sscanf(optarg, "%s", sub_net); + mylog(log_info, "sub_net %s\n", sub_net); - if(delay_capacity<0) - { - mylog(log_fatal,"delay_capacity must be >=0 \n"); - myexit(-1); - } - } - else if(strcmp(long_options[option_index].name,"report")==0) - { - sscanf(optarg,"%d",&report_interval); + } else if (strcmp(long_options[option_index].name, "tun-dev") == 0) { + sscanf(optarg, "%s", tun_dev); + mylog(log_info, "tun_dev=%s\n", tun_dev); - if(report_interval<=0) - { - mylog(log_fatal,"report_interval must be >0 \n"); - myexit(-1); - } - } - else if(strcmp(long_options[option_index].name,"sock-buf")==0) - { - int tmp=-1; - sscanf(optarg,"%d",&tmp); - if(10<=tmp&&tmp<=10*1024) - { - socket_buf_size=tmp*1024; - } - else - { - mylog(log_fatal,"sock-buf value must be between 1 and 10240 (kbyte) \n"); - myexit(-1); - } - } - else if(strcmp(long_options[option_index].name,"decode-buf")==0) - { - sscanf(optarg,"%d",&fec_buff_num); - if(fec_buff_num<300 || fec_buff_num>20000) - { - mylog(log_fatal,"decode-buf value must be between 300 and 20000 (kbyte) \n"); - myexit(-1); - } - mylog(log_info,"decode-buf=%d\n",fec_buff_num); - } - else if(strcmp(long_options[option_index].name,"mode")==0) - { - sscanf(optarg,"%d",&g_fec_par.mode); - if(g_fec_par.mode!=0&&g_fec_par.mode!=1) - { - mylog(log_fatal,"mode should be 0 or 1\n"); - myexit(-1); - } - } - else if(strcmp(long_options[option_index].name,"mtu")==0) - { - sscanf(optarg,"%d",&g_fec_par.mtu); - if(g_fec_par.mtu<100||g_fec_par.mtu>2000) - { - mylog(log_fatal,"fec_mtu should be between 100 and 2000\n"); - myexit(-1); - } - } - else if(strcmp(long_options[option_index].name,"out-addr")==0) - { - //has_b = true; - mylog(log_debug,"out-addr=%s\n",optarg); - out_addr=new address_t(); - out_addr->from_str(optarg); - } - else if(strcmp(long_options[option_index].name,"out-interface")==0) - { - out_interface=new char[strlen(optarg)+10]; - sscanf(optarg,"%s\n",out_interface); - mylog(log_debug,"out-interface=%s\n",out_interface); - if(strlen(out_interface)==0) - { - mylog(log_fatal,"out_interface string len=0??\n"); - myexit(-1); - } - } - else if(strcmp(long_options[option_index].name,"timeout")==0) - { - sscanf(optarg,"%d",&g_fec_par.timeout); - if(g_fec_par.timeout<0||g_fec_par.timeout>1000) - { + } 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, "header-overhead") == 0) { + sscanf(optarg, "%d", &header_overhead); + mylog(log_warn, "changed header_overhead,header_overhead=%d\n", header_overhead); + } else if (strcmp(long_options[option_index].name, "mssfix") == 0) { + sscanf(optarg, "%d", &mssfix); + mylog(log_warn, "mssfix=%d\n", mssfix); + } else { + mylog(log_fatal, "unknown option\n"); + myexit(-1); + } + break; + default: + mylog(log_fatal, "unknown option <%x>", opt); + myexit(-1); + } + } - mylog(log_fatal,"fec_pending_time should be between 0 and 1000(1s)\n"); - myexit(-1); - } - g_fec_par.timeout*=1000; - } - else if(strcmp(long_options[option_index].name,"debug-fec-enc")==0) - { - debug_fec_enc=1; - mylog(log_info,"debug_fec_enc enabled\n"); - } - else if(strcmp(long_options[option_index].name,"debug-fec-dec")==0) - { - debug_fec_dec=1; - mylog(log_info,"debug_fec_dec enabled\n"); - } - else if(strcmp(long_options[option_index].name,"fifo")==0) - { - sscanf(optarg,"%s",fifo_file); + if (is_client == 0 && is_server == 0) { + mylog(log_fatal, "-s -c hasnt been set\n"); + myexit(-1); + } + if (is_client == 1 && is_server == 1) { + mylog(log_fatal, "-s -c cant be both set\n"); + myexit(-1); + } + if (is_client == 1) { + program_mode = client_mode; + } else { + program_mode = server_mode; + } - 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,"manual-set-tun")==0) - { - manual_set_tun=1; - mylog(log_info,"manual_set_tun enabled\n"); - } - else if(strcmp(long_options[option_index].name,"persist-tun")==0) - { - persist_tun=1; - mylog(log_info,"persist_tun enabled\n"); - } - else if(strcmp(long_options[option_index].name,"sub-net")==0) - { - sscanf(optarg,"%s",sub_net); - mylog(log_info,"sub_net %s\n",sub_net); + if (working_mode == tunnel_mode) { + if (no_l) + mylog(log_fatal, "error: -l not found\n"); + if (no_r) + mylog(log_fatal, "error: -r not found\n"); + if (no_l || no_r) + myexit(-1); + } else if (working_mode == tun_dev_mode) { + if (program_mode == client_mode && no_r) { + mylog(log_fatal, "error: -r not found\n"); + myexit(-1); + } else if (program_mode == server_mode && no_l) { + mylog(log_fatal, "error: -l not found\n"); + myexit(-1); + } + } - } - else if(strcmp(long_options[option_index].name,"tun-dev")==0) - { - sscanf(optarg,"%s",tun_dev); - mylog(log_info,"tun_dev=%s\n",tun_dev); - - } - 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,"header-overhead")==0) - { - sscanf(optarg,"%d",&header_overhead); - mylog(log_warn,"changed header_overhead,header_overhead=%d\n",header_overhead); - } - else if(strcmp(long_options[option_index].name,"mssfix")==0) - { - sscanf(optarg,"%d",&mssfix); - mylog(log_warn,"mssfix=%d\n",mssfix); - } - else - { - mylog(log_fatal,"unknown option\n"); - myexit(-1); - } - break; - default: - mylog(log_fatal,"unknown option <%x>", opt); - myexit(-1); - } - } - - if (is_client == 0 && is_server == 0) - { - mylog(log_fatal,"-s -c hasnt been set\n"); - myexit(-1); - } - if (is_client == 1 && is_server == 1) - { - mylog(log_fatal,"-s -c cant be both set\n"); - myexit(-1); - } - if(is_client==1) - { - program_mode=client_mode; - } - else - { - program_mode=server_mode; - } - - - if(working_mode==tunnel_mode) - { - if (no_l) - mylog(log_fatal,"error: -l not found\n"); - if (no_r) - mylog(log_fatal,"error: -r not found\n"); - if (no_l || no_r) - myexit(-1); - } - else if(working_mode==tun_dev_mode) - { - if(program_mode==client_mode&&no_r) - { - mylog(log_fatal,"error: -r not found\n"); - myexit(-1); - } - else if(program_mode==server_mode&&no_l) - { - mylog(log_fatal,"error: -l not found\n"); - myexit(-1); - } - } - - int ret=g_fec_par.rs_from_str(rs_par_str); - if(ret!=0) - { - mylog(log_fatal,"failed to parse [%s]\n",rs_par_str); - myexit(-1); - } - - print_parameter(); + int ret = g_fec_par.rs_from_str(rs_par_str); + if (ret != 0) { + mylog(log_fatal, "failed to parse [%s]\n", rs_par_str); + myexit(-1); + } + print_parameter(); } - diff --git a/misc.h b/misc.h index c0ff9da..6ed637e 100644 --- a/misc.h +++ b/misc.h @@ -14,8 +14,6 @@ #include "delay_manager.h" #include "fec_manager.h" - - extern char fifo_file[1000]; extern int mtu_warn; @@ -26,7 +24,6 @@ extern int disable_checksum; extern int debug_force_flush_fec; - extern int jitter_min; extern int jitter_max; @@ -35,12 +32,11 @@ extern int output_interval_max; extern int fix_latency; -//extern u32_t local_ip_uint32,remote_ip_uint32; -//extern char local_ip[100], remote_ip[100]; -//extern int local_port, remote_port; +// extern u32_t local_ip_uint32,remote_ip_uint32; +// extern char local_ip[100], remote_ip[100]; +// extern int local_port, remote_port; - -extern address_t local_addr,remote_addr; +extern address_t local_addr, remote_addr; extern address_t *out_addr; extern char *out_interface; @@ -62,17 +58,16 @@ extern int mssfix; extern int manual_set_tun; extern int persist_tun; +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); -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); - -int delay_send(my_time_t delay,const dest_t &dest,char *data,int len); +int delay_send(my_time_t delay, const dest_t &dest, char *data, int len); int print_parameter(); int handle_command(char *s); int unit_test(); -//void print_help(); +// void print_help(); void process_arg(int argc, char *argv[]); diff --git a/my_ev.h b/my_ev.h index c0c0e24..5278bf0 100644 --- a/my_ev.h +++ b/my_ev.h @@ -2,4 +2,3 @@ #include "my_ev_common.h" #include "ev.h" - diff --git a/my_ev_common.h b/my_ev_common.h index 5129fd4..c724c97 100644 --- a/my_ev_common.h +++ b/my_ev_common.h @@ -1,13 +1,15 @@ #define EV_STANDALONE 1 -#define EV_COMMON void *data; unsigned long long u64; +#define EV_COMMON \ + void *data; \ + unsigned long long u64; #define EV_COMPAT3 0 //#define EV_VERIFY 2 #if defined(__MINGW32__) -# define EV_FD_TO_WIN32_HANDLE(fd) (fd) -# define EV_WIN32_HANDLE_TO_FD(handle) (handle) -# define EV_WIN32_CLOSE_FD(fd) closesocket (fd) -# define FD_SETSIZE 4096 +#define EV_FD_TO_WIN32_HANDLE(fd) (fd) +#define EV_WIN32_HANDLE_TO_FD(handle) (handle) +#define EV_WIN32_CLOSE_FD(fd) closesocket(fd) +#define FD_SETSIZE 4096 #endif diff --git a/packet.cpp b/packet.cpp index be28c71..607e1b9 100644 --- a/packet.cpp +++ b/packet.cpp @@ -5,375 +5,333 @@ * Author: root */ - #include "common.h" #include "log.h" #include "packet.h" #include "misc.h" -int iv_min=4; -int iv_max=32;//< 256; -u64_t packet_send_count=0; -u64_t dup_packet_send_count=0; -u64_t packet_recv_count=0; -u64_t dup_packet_recv_count=0; +int iv_min = 4; +int iv_max = 32; //< 256; +u64_t packet_send_count = 0; +u64_t dup_packet_send_count = 0; +u64_t packet_recv_count = 0; +u64_t dup_packet_recv_count = 0; typedef u64_t anti_replay_seq_t; -int disable_replay_filter=0; +int disable_replay_filter = 0; -int disable_obscure=0; -int disable_xor=0; +int disable_obscure = 0; +int disable_xor = 0; -int random_drop=0; +int random_drop = 0; -char key_string[1000]= ""; +char key_string[1000] = ""; -//int local_listen_fd=-1; +// int local_listen_fd=-1; - -void encrypt_0(char * input,int &len,char *key) -{ - int i,j; - if(key[0]==0) return; - for(i=0,j=0;i 65535||in_len<0) - return -1; - int iv_len=iv_min+rand()%(iv_max-iv_min); - get_fake_random_chars(output,iv_len); - memcpy(output+iv_len,input,in_len); + int i, j, k; + if (in_len > 65535 || in_len < 0) + return -1; + int iv_len = iv_min + rand() % (iv_max - iv_min); + get_fake_random_chars(output, iv_len); + memcpy(output + iv_len, input, in_len); - output[iv_len+in_len]=(uint8_t)iv_len; + output[iv_len + in_len] = (uint8_t)iv_len; - output[iv_len+in_len]^=output[0]; - output[iv_len+in_len]^=key_string[0]; + output[iv_len + in_len] ^= output[0]; + output[iv_len + in_len] ^= key_string[0]; - for(i=0,j=0,k=1;i=0); - assert(len= 0); + assert(len < buf_len); - int iv_len=random_between(iv_min,iv_max); - get_fake_random_chars(data+len,iv_len); - data[iv_len+len]=(uint8_t)iv_len; - for(int i=0,j=0;i 65535||in_len<0) - { - mylog(log_debug,"in_len > 65535||in_len<0 , %d",in_len); - return -1; - } - int iv_len= int ((uint8_t)(input[in_len-1]^input[0]^key_string[0]) ); - out_len=in_len-1-iv_len; - if(out_len<0) - { - mylog(log_debug,"%d %d\n",in_len,out_len); - return -1; - } - for(i=0,j=0,k=1;i 65535 || in_len < 0) { + mylog(log_debug, "in_len > 65535||in_len<0 , %d", in_len); + return -1; + } + int iv_len = int((uint8_t)(input[in_len - 1] ^ input[0] ^ key_string[0])); + out_len = in_len - 1 - iv_len; + if (out_len < 0) { + mylog(log_debug, "%d %d\n", in_len, out_len); + return -1; + } + for (i = 0, j = 0, k = 1; i < in_len; i++, j++, k++) { + if (j == iv_len) j = 0; + if (key_string[k] == 0) k = 0; + output[i] = input[iv_len + i] ^ input[j] ^ key_string[k]; + } + dup_packet_recv_count++; + return 0; } /* int sendto_fd_ip_port (int fd,u32_t ip,int port,char * buf, int len,int flags) { - sockaddr_in tmp_sockaddr; + sockaddr_in tmp_sockaddr; - memset(&tmp_sockaddr,0,sizeof(tmp_sockaddr)); - tmp_sockaddr.sin_family = AF_INET; - tmp_sockaddr.sin_addr.s_addr = ip; - tmp_sockaddr.sin_port = htons(uint16_t(port)); + memset(&tmp_sockaddr,0,sizeof(tmp_sockaddr)); + tmp_sockaddr.sin_family = AF_INET; + tmp_sockaddr.sin_addr.s_addr = ip; + tmp_sockaddr.sin_port = htons(uint16_t(port)); - return sendto(fd, buf, - len , 0, - (struct sockaddr *) &tmp_sockaddr, - sizeof(tmp_sockaddr)); + return sendto(fd, buf, + len , 0, + (struct sockaddr *) &tmp_sockaddr, + sizeof(tmp_sockaddr)); }*/ -int sendto_fd_addr (int fd,address_t addr,char * buf, int len,int flags) -{ - - return sendto(fd, buf, - len , 0, - (struct sockaddr *) &addr.inner, - addr.get_len()); +int sendto_fd_addr(int fd, address_t addr, char *buf, int len, int flags) { + return sendto(fd, buf, + len, 0, + (struct sockaddr *)&addr.inner, + addr.get_len()); } /* int sendto_ip_port (u32_t ip,int port,char * buf, int len,int flags) { - return sendto_fd_ip_port(local_listen_fd,ip,port,buf,len,flags); + return sendto_fd_ip_port(local_listen_fd,ip,port,buf,len,flags); }*/ -int send_fd (int fd,char * buf, int len,int flags) -{ - return send(fd,buf,len,flags); +int send_fd(int fd, char *buf, int len, int flags) { + return send(fd, buf, len, flags); } -int my_send(const dest_t &dest,char *data,int len) -{ - if(dest.cook) - { - do_cook(data,len); - } - switch(dest.type) - { - case type_fd_addr: - { - return sendto_fd_addr(dest.inner.fd,dest.inner.fd_addr.addr,data,len,0); - break; - } - case type_fd64_addr: - { - if(!fd_manager.exist(dest.inner.fd64)) return -1; - int fd=fd_manager.to_fd(dest.inner.fd64); +int my_send(const dest_t &dest, char *data, int len) { + if (dest.cook) { + do_cook(data, len); + } + switch (dest.type) { + case type_fd_addr: { + return sendto_fd_addr(dest.inner.fd, dest.inner.fd_addr.addr, data, len, 0); + break; + } + case type_fd64_addr: { + if (!fd_manager.exist(dest.inner.fd64)) return -1; + int fd = fd_manager.to_fd(dest.inner.fd64); - return sendto_fd_addr(fd,dest.inner.fd64_addr.addr,data,len,0); - break; - } - case type_fd: - { - return send_fd(dest.inner.fd,data,len,0); - break; - } - case type_write_fd: - { - return write(dest.inner.fd,data,len); - break; - } - case type_fd64: - { + return sendto_fd_addr(fd, dest.inner.fd64_addr.addr, data, len, 0); + break; + } + case type_fd: { + return send_fd(dest.inner.fd, data, len, 0); + break; + } + case type_write_fd: { + return write(dest.inner.fd, data, len); + break; + } + case type_fd64: { + if (!fd_manager.exist(dest.inner.fd64)) return -1; + int fd = fd_manager.to_fd(dest.inner.fd64); - if(!fd_manager.exist(dest.inner.fd64)) return -1; - int fd=fd_manager.to_fd(dest.inner.fd64); + return send_fd(fd, data, len, 0); + break; + } + /* + case type_fd64_ip_port_conv: + { + if(!fd_manager.exist(dest.inner.fd64)) return -1; + int fd=fd_manager.to_fd(dest.inner.fd64); - return send_fd(fd,data,len,0); - break; - } - /* - case type_fd64_ip_port_conv: - { - if(!fd_manager.exist(dest.inner.fd64)) return -1; - int fd=fd_manager.to_fd(dest.inner.fd64); + char *new_data; + int new_len; - char *new_data; - int new_len; + put_conv(dest.conv,data,len,new_data,new_len); + return sendto_fd_ip_port(fd,dest.inner.fd64_ip_port.ip_port.ip,dest.inner.fd64_ip_port.ip_port.port,new_data,new_len,0); + break; + }*/ - put_conv(dest.conv,data,len,new_data,new_len); - return sendto_fd_ip_port(fd,dest.inner.fd64_ip_port.ip_port.ip,dest.inner.fd64_ip_port.ip_port.port,new_data,new_len,0); - break; - }*/ + /* + case type_fd64_conv: + { + char *new_data; + int new_len; + put_conv(dest.conv,data,len,new_data,new_len); - /* - case type_fd64_conv: - { - char *new_data; - int new_len; - put_conv(dest.conv,data,len,new_data,new_len); - - if(!fd_manager.exist(dest.inner.fd64)) return -1; - int fd=fd_manager.to_fd(dest.inner.fd64); - return send_fd(fd,new_data,new_len,0); - }*/ - /* - case type_fd: - { - send_fd(dest.inner.fd,data,len,0); - break; - }*/ - default: - assert(0==1); - } - return 0; + if(!fd_manager.exist(dest.inner.fd64)) return -1; + int fd=fd_manager.to_fd(dest.inner.fd64); + return send_fd(fd,new_data,new_len,0); + }*/ + /* + case type_fd: + { + send_fd(dest.inner.fd,data,len,0); + break; + }*/ + default: + assert(0 == 1); + } + return 0; } /* * this function comes from http://www.hackersdelight.org/hdcodetxt/crc.c.txt */ -unsigned int crc32h(unsigned char *message,int len) { - assert(len>=0); - int i, crc; - unsigned int byte, c; - const unsigned int g0 = 0xEDB88320, g1 = g0>>1, - g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, - g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; +unsigned int crc32h(unsigned char *message, int len) { + assert(len >= 0); + int i, crc; + unsigned int byte, c; + const unsigned int g0 = 0xEDB88320, g1 = g0 >> 1, + g2 = g0 >> 2, g3 = g0 >> 3, g4 = g0 >> 4, g5 = g0 >> 5, + g6 = (g0 >> 6) ^ g0, g7 = ((g0 >> 6) ^ g0) >> 1; - i = 0; - crc = 0xFFFFFFFF; - while (i!=len) { // Get next byte. - byte = message[i]; - crc = crc ^ byte; - c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^ - ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^ - ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^ - ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0); - crc = ((unsigned)crc >> 8) ^ c; - i = i + 1; - } - return ~crc; + i = 0; + crc = 0xFFFFFFFF; + while (i != len) { // Get next byte. + byte = message[i]; + crc = crc ^ byte; + c = ((crc << 31 >> 31) & g7) ^ ((crc << 30 >> 31) & g6) ^ + ((crc << 29 >> 31) & g5) ^ ((crc << 28 >> 31) & g4) ^ + ((crc << 27 >> 31) & g3) ^ ((crc << 26 >> 31) & g2) ^ + ((crc << 25 >> 31) & g1) ^ ((crc << 24 >> 31) & g0); + crc = ((unsigned)crc >> 8) ^ c; + i = i + 1; + } + return ~crc; } -int put_conv0(u32_t conv,const char * input,int len_in,char *&output,int &len_out) -{ - assert(len_in>=0); - static char buf[buf_len]; - output=buf; - u32_t n_conv=htonl(conv); - memcpy(output,&n_conv,sizeof(n_conv)); - memcpy(output+sizeof(n_conv),input,len_in); - u32_t crc32=crc32h((unsigned char *)output,len_in+sizeof(crc32)); - u32_t crc32_n=htonl(crc32); - len_out=len_in+(int)(sizeof(n_conv))+(int)sizeof(crc32_n); - memcpy(output+len_in+(int)(sizeof(n_conv)),&crc32_n,sizeof(crc32_n)); - return 0; +int put_conv0(u32_t conv, const char *input, int len_in, char *&output, int &len_out) { + assert(len_in >= 0); + static char buf[buf_len]; + output = buf; + u32_t n_conv = htonl(conv); + memcpy(output, &n_conv, sizeof(n_conv)); + memcpy(output + sizeof(n_conv), input, len_in); + u32_t crc32 = crc32h((unsigned char *)output, len_in + sizeof(crc32)); + u32_t crc32_n = htonl(crc32); + len_out = len_in + (int)(sizeof(n_conv)) + (int)sizeof(crc32_n); + memcpy(output + len_in + (int)(sizeof(n_conv)), &crc32_n, sizeof(crc32_n)); + return 0; } -int get_conv0(u32_t &conv,const char *input,int len_in,char *&output,int &len_out ) -{ - assert(len_in>=0); - u32_t n_conv; - memcpy(&n_conv,input,sizeof(n_conv)); - conv=ntohl(n_conv); - output=(char *)input+sizeof(n_conv); - u32_t crc32_n; - len_out=len_in-(int)sizeof(n_conv)-(int)sizeof(crc32_n); - if(len_out<0) - { - mylog(log_debug,"len_out<0\n"); - return -1; - } - memcpy(&crc32_n,input+len_in-(int)sizeof(crc32_n),sizeof(crc32_n)); - u32_t crc32=ntohl(crc32_n); - if(crc32!=crc32h((unsigned char *)input,len_in-(int)sizeof(crc32_n))) - { - mylog(log_debug,"crc32 check failed\n"); - return -1; - } - return 0; +int get_conv0(u32_t &conv, const char *input, int len_in, char *&output, int &len_out) { + assert(len_in >= 0); + u32_t n_conv; + memcpy(&n_conv, input, sizeof(n_conv)); + conv = ntohl(n_conv); + output = (char *)input + sizeof(n_conv); + u32_t crc32_n; + len_out = len_in - (int)sizeof(n_conv) - (int)sizeof(crc32_n); + if (len_out < 0) { + mylog(log_debug, "len_out<0\n"); + return -1; + } + memcpy(&crc32_n, input + len_in - (int)sizeof(crc32_n), sizeof(crc32_n)); + u32_t crc32 = ntohl(crc32_n); + if (crc32 != crc32h((unsigned char *)input, len_in - (int)sizeof(crc32_n))) { + mylog(log_debug, "crc32 check failed\n"); + return -1; + } + return 0; } -int put_crc32(char * s,int &len) -{ - if(disable_checksum)return 0; - assert(len>=0); - //if(len<0) return -1; - u32_t crc32=crc32h((unsigned char *)s,len); - write_u32(s+len,crc32); - len+=sizeof(u32_t); +int put_crc32(char *s, int &len) { + if (disable_checksum) return 0; + assert(len >= 0); + // if(len<0) return -1; + u32_t crc32 = crc32h((unsigned char *)s, len); + write_u32(s + len, crc32); + len += sizeof(u32_t); - - return 0; + return 0; } -int do_cook(char * data,int &len) -{ - put_crc32(data,len); - if(!disable_obscure)do_obscure(data,len); - if(!disable_xor)encrypt_0(data,len,key_string); - return 0; +int do_cook(char *data, int &len) { + put_crc32(data, len); + if (!disable_obscure) do_obscure(data, len); + if (!disable_xor) encrypt_0(data, len, key_string); + return 0; } -int de_cook(char * s,int &len) -{ - if(!disable_xor)decrypt_0(s,len,key_string); - if(!disable_obscure) - { - int ret=de_obscure(s,len); - if(ret!=0) - { - mylog(log_debug,"de_obscure fail\n"); - return ret; - } - } - int ret=rm_crc32(s,len); - if(ret!=0) - { - mylog(log_debug,"rm_crc32 fail\n"); - return ret; - } - return 0; +int de_cook(char *s, int &len) { + if (!disable_xor) decrypt_0(s, len, key_string); + if (!disable_obscure) { + int ret = de_obscure(s, len); + if (ret != 0) { + mylog(log_debug, "de_obscure fail\n"); + return ret; + } + } + int ret = rm_crc32(s, len); + if (ret != 0) { + mylog(log_debug, "rm_crc32 fail\n"); + return ret; + } + return 0; } -int rm_crc32(char * s,int &len) -{ - if(disable_checksum)return 0; - assert(len>=0); - len-=sizeof(u32_t); - if(len<0) return -1; - u32_t crc32_in=read_u32(s+len); - u32_t crc32=crc32h((unsigned char *)s,len); - if(crc32!=crc32_in) return -1; - return 0; +int rm_crc32(char *s, int &len) { + if (disable_checksum) return 0; + assert(len >= 0); + len -= sizeof(u32_t); + if (len < 0) return -1; + u32_t crc32_in = read_u32(s + len); + u32_t crc32 = crc32h((unsigned char *)s, len); + if (crc32 != crc32_in) return -1; + return 0; } /* int do_obs() @@ -381,31 +339,25 @@ int do_obs() } int de_obs()*/ -int put_conv(u32_t conv,const char * input,int len_in,char *&output,int &len_out) -{ - static char buf[buf_len]; - output=buf; - u32_t n_conv=htonl(conv); - memcpy(output,&n_conv,sizeof(n_conv)); - memcpy(output+sizeof(n_conv),input,len_in); - len_out=len_in+(int)(sizeof(n_conv)); +int put_conv(u32_t conv, const char *input, int len_in, char *&output, int &len_out) { + static char buf[buf_len]; + output = buf; + u32_t n_conv = htonl(conv); + memcpy(output, &n_conv, sizeof(n_conv)); + memcpy(output + sizeof(n_conv), input, len_in); + len_out = len_in + (int)(sizeof(n_conv)); - return 0; + return 0; } -int get_conv(u32_t &conv,const char *input,int len_in,char *&output,int &len_out ) -{ - u32_t n_conv; - memcpy(&n_conv,input,sizeof(n_conv)); - conv=ntohl(n_conv); - output=(char *)input+sizeof(n_conv); - len_out=len_in-(int)sizeof(n_conv); - if(len_out<0) - { - mylog(log_debug,"len_out<0\n"); - return -1; - } - return 0; +int get_conv(u32_t &conv, const char *input, int len_in, char *&output, int &len_out) { + u32_t n_conv; + memcpy(&n_conv, input, sizeof(n_conv)); + conv = ntohl(n_conv); + output = (char *)input + sizeof(n_conv); + len_out = len_in - (int)sizeof(n_conv); + if (len_out < 0) { + mylog(log_debug, "len_out<0\n"); + return -1; + } + return 0; } - - - diff --git a/packet.h b/packet.h index 3693660..b8d2582 100644 --- a/packet.h +++ b/packet.h @@ -12,7 +12,7 @@ #include "fd_manager.h" extern int iv_min; -extern int iv_max;//< 256; +extern int iv_max; //< 256; extern u64_t packet_send_count; extern u64_t dup_packet_send_count; @@ -24,24 +24,23 @@ extern int random_drop; extern int disable_obscure; extern int disable_xor; +int my_send(const dest_t &dest, char *data, int len); -int my_send(const dest_t &dest,char *data,int len); +void encrypt_0(char *input, int &len, char *key); +void decrypt_0(char *input, int &len, char *key); +int add_seq(char *data, int &data_len); +int remove_seq(char *data, int &data_len); +int do_obscure(const char *input, int in_len, char *output, int &out_len); +int de_obscure(const char *input, int in_len, char *output, int &out_len); -void encrypt_0(char * input,int &len,char *key); -void decrypt_0(char * input,int &len,char *key); -int add_seq(char * data,int &data_len ); -int remove_seq(char * data,int &data_len); -int do_obscure(const char * input, int in_len,char *output,int &out_len); -int de_obscure(const char * input, int in_len,char *output,int &out_len); +// int sendto_fd_u64 (int fd,u64_t u64,char * buf, int len,int flags); +int sendto_ip_port(u32_t ip, int port, char *buf, int len, int flags); +int send_fd(int fd, char *buf, int len, int flags); -//int sendto_fd_u64 (int fd,u64_t u64,char * buf, int len,int flags); -int sendto_ip_port (u32_t ip,int port,char * buf, int len,int flags); -int send_fd (int fd,char * buf, int len,int flags); - -int put_conv(u32_t conv,const char * input,int len_in,char *&output,int &len_out); -int get_conv(u32_t &conv,const char *input,int len_in,char *&output,int &len_out ); -int put_crc32(char * s,int &len); -int rm_crc32(char * s,int &len); -int do_cook(char * data,int &len); -int de_cook(char * s,int &len); +int put_conv(u32_t conv, const char *input, int len_in, char *&output, int &len_out); +int get_conv(u32_t &conv, const char *input, int len_in, char *&output, int &len_out); +int put_crc32(char *s, int &len); +int rm_crc32(char *s, int &len); +int do_cook(char *data, int &len); +int de_cook(char *s, int &len); #endif /* PACKET_H_ */ diff --git a/tunnel.h b/tunnel.h index a074154..8fab77b 100644 --- a/tunnel.h +++ b/tunnel.h @@ -8,7 +8,6 @@ #ifndef TUNNEL_H_ #define TUNNEL_H_ - #include "misc.h" int tunnel_client_event_loop(); diff --git a/tunnel_client.cpp b/tunnel_client.cpp index e129f67..83ccf05 100644 --- a/tunnel_client.cpp +++ b/tunnel_client.cpp @@ -1,453 +1,422 @@ #include "tunnel.h" -void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out) -{ - fd64_t &remote_fd64=conn_info.remote_fd64; - int & local_listen_fd=conn_info.local_listen_fd; +void data_from_local_or_fec_timeout(conn_info_t &conn_info, int is_time_out) { + fd64_t &remote_fd64 = conn_info.remote_fd64; + int &local_listen_fd = conn_info.local_listen_fd; - char data[buf_len]; - int data_len; - address_t addr; - u32_t conv; - int out_n;char **out_arr;int *out_len;my_time_t *out_delay; - dest_t dest; - dest.type=type_fd64; - dest.inner.fd64=remote_fd64; - dest.cook=1; + char data[buf_len]; + int data_len; + address_t addr; + u32_t conv; + int out_n; + char **out_arr; + int *out_len; + my_time_t *out_delay; + dest_t dest; + dest.type = type_fd64; + dest.inner.fd64 = remote_fd64; + dest.cook = 1; - if(is_time_out) - { - //fd64_t fd64=events[idx].data.u64; - mylog(log_trace,"events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n"); + if (is_time_out) { + // fd64_t fd64=events[idx].data.u64; + mylog(log_trace, "events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n"); - //uint64_t value; - //if(!fd_manager.exist(fd64)) //fd64 has been closed - //{ - // mylog(log_trace,"!fd_manager.exist(fd64)"); - // continue; - //} - //if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8) - //{ - // mylog(log_trace,"(ret=read(fd_manager.to_fd(fd64), &value, 8))!=8,ret=%d\n",ret); - // continue; - //} - //if(value==0) - //{ - // mylog(log_debug,"value==0\n"); - // continue; - //} - //assert(value==1); - from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay); - } - else//events[idx].data.u64 == (u64_t)local_listen_fd - { - mylog(log_trace,"events[idx].data.u64 == (u64_t)local_listen_fd\n"); - address_t::storage_t udp_new_addr_in={0}; - socklen_t udp_new_addr_len = sizeof(address_t::storage_t); - if ((data_len = recvfrom(local_listen_fd, data, max_data_len+1, 0, - (struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { - mylog(log_debug,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error()); - return; - }; + // uint64_t value; + // if(!fd_manager.exist(fd64)) //fd64 has been closed + //{ + // mylog(log_trace,"!fd_manager.exist(fd64)"); + // continue; + // } + // if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8) + //{ + // mylog(log_trace,"(ret=read(fd_manager.to_fd(fd64), &value, 8))!=8,ret=%d\n",ret); + // continue; + // } + // if(value==0) + //{ + // mylog(log_debug,"value==0\n"); + // continue; + // } + // assert(value==1); + from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); + } else // events[idx].data.u64 == (u64_t)local_listen_fd + { + mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n"); + address_t::storage_t udp_new_addr_in = {0}; + socklen_t udp_new_addr_len = sizeof(address_t::storage_t); + if ((data_len = recvfrom(local_listen_fd, data, max_data_len + 1, 0, + (struct sockaddr *)&udp_new_addr_in, &udp_new_addr_len)) == -1) { + mylog(log_debug, "recv_from error,this shouldnt happen,err=%s,but we can try to continue\n", get_sock_error()); + return; + }; - if(data_len==max_data_len+1) - { - mylog(log_warn,"huge packet from upper level, data_len > %d, packet truncated, dropped\n",max_data_len); - return ; - } - - if(!disable_mtu_warn&&data_len>=mtu_warn) - { - mylog(log_warn,"huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",data_len,mtu_warn); - } - - - addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len); - - mylog(log_trace,"Received packet from %s, len: %d\n", addr.get_str(),data_len); - - //u64_t u64=ip_port.to_u64(); - - if(!conn_info.conv_manager.c.is_data_used(addr)) - { - if(conn_info.conv_manager.c.get_size() >=max_conv_num) - { - mylog(log_warn,"ignored new udp connect bc max_conv_num exceed\n"); - return; - } - conv=conn_info.conv_manager.c.get_new_conv(); - conn_info.conv_manager.c.insert_conv(conv,addr); - mylog(log_info,"new packet from %s,conv_id=%x\n",addr.get_str(),conv); - } - else - { - conv=conn_info.conv_manager.c.find_conv_by_data(addr); - mylog(log_trace,"conv=%d\n",conv); - } - conn_info.conv_manager.c.update_active_time(conv); - char * new_data; - int new_len; - put_conv(conv,data,data_len,new_data,new_len); - - - mylog(log_trace,"data_len=%d new_len=%d\n",data_len,new_len); - from_normal_to_fec(conn_info,new_data,new_len,out_n,out_arr,out_len,out_delay); - - } - mylog(log_trace,"out_n=%d\n",out_n); - for(int i=0;idata); - - data_from_local_or_fec_timeout(conn_info,0); -} - -static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); - - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - - char data[buf_len]; - if(!fd_manager.exist(watcher->u64)) //fd64 has been closed - { - mylog(log_trace,"!fd_manager.exist(events[idx].data.u64)"); - return; - } - fd64_t &remote_fd64=conn_info.remote_fd64; - int &remote_fd=conn_info.remote_fd; - - assert(watcher->u64==remote_fd64); - - int fd=fd_manager.to_fd(remote_fd64); - - int data_len =recv(fd,data,max_data_len+1,0); - - if(data_len==max_data_len+1) - { - mylog(log_warn,"huge packet, data_len > %d, packet truncated, dropped\n",max_data_len); - return ; + if (data_len == max_data_len + 1) { + mylog(log_warn, "huge packet from upper level, data_len > %d, packet truncated, dropped\n", max_data_len); + return; } + if (!disable_mtu_warn && data_len >= mtu_warn) { + mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn); + } - mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd,data_len); - if(data_len<0) - { - if(get_sock_errno()==ECONNREFUSED) - { - mylog(log_debug, "recv failed %d ,udp_fd%d,errno:%s\n", data_len,remote_fd,get_sock_error()); - } + addr.from_sockaddr((struct sockaddr *)&udp_new_addr_in, udp_new_addr_len); - mylog(log_warn, "recv failed %d ,udp_fd%d,errno:%s\n", data_len,remote_fd,get_sock_error()); - return; - } - if(!disable_mtu_warn&&data_len>mtu_warn) - { - mylog(log_warn,"huge packet,data len=%d (>%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",data_len,mtu_warn); - } + mylog(log_trace, "Received packet from %s, len: %d\n", addr.get_str(), data_len); - if(de_cook(data,data_len)!=0) - { - mylog(log_debug,"de_cook error"); - return; - } + // u64_t u64=ip_port.to_u64(); - int out_n;char **out_arr;int *out_len;my_time_t *out_delay; - from_fec_to_normal(conn_info,data,data_len,out_n,out_arr,out_len,out_delay); + if (!conn_info.conv_manager.c.is_data_used(addr)) { + if (conn_info.conv_manager.c.get_size() >= max_conv_num) { + mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n"); + return; + } + conv = conn_info.conv_manager.c.get_new_conv(); + conn_info.conv_manager.c.insert_conv(conv, addr); + mylog(log_info, "new packet from %s,conv_id=%x\n", addr.get_str(), conv); + } else { + conv = conn_info.conv_manager.c.find_conv_by_data(addr); + mylog(log_trace, "conv=%d\n", conv); + } + conn_info.conv_manager.c.update_active_time(conv); + char *new_data; + int new_len; + put_conv(conv, data, data_len, new_data, new_len); - mylog(log_trace,"out_n=%d\n",out_n); + mylog(log_trace, "data_len=%d new_len=%d\n", data_len, new_len); + from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay); + } + mylog(log_trace, "out_n=%d\n", out_n); + for (int i = 0; i < out_n; i++) { + delay_send(out_delay[i], dest, out_arr[i], out_len[i]); + } +} +static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + assert(!(revents & EV_ERROR)); - for(int i=0;idata); - conn_info.conv_manager.c.update_active_time(conv); - - address_t addr=conn_info.conv_manager.c.find_data_by_conv(conv); - dest_t dest; - dest.inner.fd_addr.fd=conn_info.local_listen_fd; - dest.inner.fd_addr.addr=addr; - dest.type=type_fd_addr; - - delay_send(out_delay[i],dest,new_data,new_len); - } + data_from_local_or_fec_timeout(conn_info, 0); } -static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); - int fifo_fd=watcher->fd; +static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + assert(!(revents & EV_ERROR)); - char buf[buf_len]; - int len=read (fifo_fd, buf, sizeof (buf)); - if(len<0) - { - mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error()); - return; - } - buf[len]=0; - handle_command(buf); + conn_info_t &conn_info = *((conn_info_t *)watcher->data); + + char data[buf_len]; + if (!fd_manager.exist(watcher->u64)) // fd64 has been closed + { + mylog(log_trace, "!fd_manager.exist(events[idx].data.u64)"); + return; + } + fd64_t &remote_fd64 = conn_info.remote_fd64; + int &remote_fd = conn_info.remote_fd; + + assert(watcher->u64 == remote_fd64); + + int fd = fd_manager.to_fd(remote_fd64); + + int data_len = recv(fd, data, max_data_len + 1, 0); + + if (data_len == max_data_len + 1) { + mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len); + return; + } + + mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd, data_len); + if (data_len < 0) { + if (get_sock_errno() == ECONNREFUSED) { + mylog(log_debug, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error()); + } + + mylog(log_warn, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error()); + return; + } + if (!disable_mtu_warn && data_len > mtu_warn) { + mylog(log_warn, "huge packet,data len=%d (>%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn); + } + + if (de_cook(data, data_len) != 0) { + mylog(log_debug, "de_cook error"); + return; + } + + int out_n; + char **out_arr; + int *out_len; + my_time_t *out_delay; + from_fec_to_normal(conn_info, data, data_len, out_n, out_arr, out_len, out_delay); + + mylog(log_trace, "out_n=%d\n", out_n); + + for (int i = 0; i < out_n; i++) { + u32_t conv; + char *new_data; + int new_len; + if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) { + mylog(log_debug, "get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0"); + continue; + } + if (!conn_info.conv_manager.c.is_conv_used(conv)) { + mylog(log_trace, "!conn_info.conv_manager.is_conv_used(conv)"); + continue; + } + + conn_info.conv_manager.c.update_active_time(conv); + + address_t addr = conn_info.conv_manager.c.find_data_by_conv(conv); + dest_t dest; + dest.inner.fd_addr.fd = conn_info.local_listen_fd; + dest.inner.fd_addr.addr = addr; + dest.type = type_fd_addr; + + delay_send(out_delay[i], dest, new_data, new_len); + } } -static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + assert(!(revents & EV_ERROR)); + int fifo_fd = watcher->fd; - //uint64_t value; - //read(delay_manager.get_timer_fd(), &value, 8); - //mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); - - //do nothing + char buf[buf_len]; + int len = read(fifo_fd, buf, sizeof(buf)); + if (len < 0) { + mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error()); + return; + } + buf[len] = 0; + handle_command(buf); } -static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { + assert(!(revents & EV_ERROR)); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - - data_from_local_or_fec_timeout(conn_info,1); + // uint64_t value; + // read(delay_manager.get_timer_fd(), &value, 8); + // mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); + // do nothing } -static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { + assert(!(revents & EV_ERROR)); - uint64_t value; + conn_info_t &conn_info = *((conn_info_t *)watcher->data); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - - //read(conn_info.timer.get_timer_fd(), &value, 8); - conn_info.conv_manager.c.clear_inactive(); - mylog(log_trace,"events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd()\n"); - - conn_info.stat.report_as_client(); - - if(debug_force_flush_fec) - { - int out_n;char **out_arr;int *out_len;my_time_t *out_delay; - dest_t dest; - dest.type=type_fd64; - dest.inner.fd64=conn_info.remote_fd64; - dest.cook=1; - from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay); - for(int i=0;idata); + + // read(conn_info.timer.get_timer_fd(), &value, 8); + conn_info.conv_manager.c.clear_inactive(); + mylog(log_trace, "events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd()\n"); + + conn_info.stat.report_as_client(); + + if (debug_force_flush_fec) { + int out_n; + char **out_arr; + int *out_len; + my_time_t *out_delay; + dest_t dest; + dest.type = type_fd64; + dest.inner.fd64 = conn_info.remote_fd64; + dest.cook = 1; + from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); + for (int i = 0; i < out_n; i++) { + delay_send(out_delay[i], dest, out_arr[i], out_len[i]); + } + } } -int tunnel_client_event_loop() -{ - int i, j, k;int ret; - int yes = 1; - //int epoll_fd; +static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) { + assert(!(revents & EV_ERROR)); + delay_manager.check(); +} - conn_info_t *conn_info_p=new conn_info_t; - conn_info_t &conn_info=*conn_info_p; //huge size of conn_info,do not allocate on stack +int tunnel_client_event_loop() { + int i, j, k; + int ret; + int yes = 1; + // int epoll_fd; - int &local_listen_fd=conn_info.local_listen_fd; - new_listen_socket2(local_listen_fd,local_addr); + conn_info_t *conn_info_p = new conn_info_t; + conn_info_t &conn_info = *conn_info_p; // huge size of conn_info,do not allocate on stack - //epoll_fd = epoll_create1(0); - //assert(epoll_fd>0); + int &local_listen_fd = conn_info.local_listen_fd; + new_listen_socket2(local_listen_fd, local_addr); - //const int max_events = 4096; - //struct epoll_event ev, events[max_events]; - //if (epoll_fd < 0) { - // mylog(log_fatal,"epoll return %d\n", epoll_fd); - // myexit(-1); - //} + // epoll_fd = epoll_create1(0); + // assert(epoll_fd>0); - struct ev_loop * loop= ev_default_loop(0); - assert(loop != NULL); + // const int max_events = 4096; + // struct epoll_event ev, events[max_events]; + // if (epoll_fd < 0) { + // mylog(log_fatal,"epoll return %d\n", epoll_fd); + // myexit(-1); + // } - conn_info.loop=loop; + struct ev_loop *loop = ev_default_loop(0); + assert(loop != NULL); - //ev.events = EPOLLIN; - //ev.data.u64 = local_listen_fd; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev); - //if (ret!=0) { - // mylog(log_fatal,"add udp_listen_fd error\n"); - // myexit(-1); - //} - struct ev_io local_listen_watcher; - local_listen_watcher.data=&conn_info; + conn_info.loop = loop; + + // ev.events = EPOLLIN; + // ev.data.u64 = local_listen_fd; + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev); + // if (ret!=0) { + // mylog(log_fatal,"add udp_listen_fd error\n"); + // myexit(-1); + // } + struct ev_io local_listen_watcher; + local_listen_watcher.data = &conn_info; ev_io_init(&local_listen_watcher, local_listen_cb, local_listen_fd, EV_READ); ev_io_start(loop, &local_listen_watcher); - int & remote_fd=conn_info.remote_fd; - fd64_t &remote_fd64=conn_info.remote_fd64; + int &remote_fd = conn_info.remote_fd; + fd64_t &remote_fd64 = conn_info.remote_fd64; - assert(new_connected_socket2(remote_fd,remote_addr,out_addr,out_interface)==0); - remote_fd64=fd_manager.create(remote_fd); + assert(new_connected_socket2(remote_fd, remote_addr, out_addr, out_interface) == 0); + remote_fd64 = fd_manager.create(remote_fd); - mylog(log_debug,"remote_fd64=%llu\n",remote_fd64); + mylog(log_debug, "remote_fd64=%llu\n", remote_fd64); - //ev.events = EPOLLIN; - //ev.data.u64 = remote_fd64; + // ev.events = EPOLLIN; + // ev.data.u64 = remote_fd64; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, remote_fd, &ev); - //if (ret!= 0) { - // mylog(log_fatal,"add raw_fd error\n"); - // myexit(-1); - //} + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, remote_fd, &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add raw_fd error\n"); + // myexit(-1); + // } - struct ev_io remote_watcher; - remote_watcher.data=&conn_info; - remote_watcher.u64=remote_fd64; + struct ev_io remote_watcher; + remote_watcher.data = &conn_info; + remote_watcher.u64 = remote_fd64; ev_io_init(&remote_watcher, remote_cb, remote_fd, EV_READ); ev_io_start(loop, &remote_watcher); + // ev.events = EPOLLIN; + // ev.data.u64 = delay_manager.get_timer_fd(); - //ev.events = EPOLLIN; - //ev.data.u64 = delay_manager.get_timer_fd(); + // mylog(log_debug,"delay_manager.get_timer_fd()=%d\n",delay_manager.get_timer_fd()); + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); + // myexit(-1); + // } - //mylog(log_debug,"delay_manager.get_timer_fd()=%d\n",delay_manager.get_timer_fd()); - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev); - //if (ret!= 0) { - // mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); - // myexit(-1); - //} - - delay_manager.set_loop_and_cb(loop,delay_manager_cb); + delay_manager.set_loop_and_cb(loop, delay_manager_cb); conn_info.fec_encode_manager.set_data(&conn_info); - conn_info.fec_encode_manager.set_loop_and_cb(loop,fec_encode_cb); + conn_info.fec_encode_manager.set_loop_and_cb(loop, fec_encode_cb); - //u64_t tmp_fd64=conn_info.fec_encode_manager.get_timer_fd64(); - //ev.events = EPOLLIN; - //ev.data.u64 = tmp_fd64; - - //mylog(log_debug,"conn_info.fec_encode_manager.get_timer_fd64()=%llu\n",conn_info.fec_encode_manager.get_timer_fd64()); - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(tmp_fd64), &ev); - //if (ret!= 0) { - // mylog(log_fatal,"add fec_encode_manager.get_timer_fd64() error\n"); - // myexit(-1); - //} - - conn_info.timer.data=&conn_info; - ev_init(&conn_info.timer,conn_timer_cb); - ev_timer_set(&conn_info.timer, 0, timer_interval/1000.0 ); - ev_timer_start(loop,&conn_info.timer); - //conn_info.timer.add_fd_to_epoll(epoll_fd); - //conn_info.timer.set_timer_repeat_us(timer_interval*1000); - - //mylog(log_debug,"conn_info.timer.get_timer_fd()=%d\n",conn_info.timer.get_timer_fd()); + // u64_t tmp_fd64=conn_info.fec_encode_manager.get_timer_fd64(); + // ev.events = EPOLLIN; + // ev.data.u64 = tmp_fd64; + // mylog(log_debug,"conn_info.fec_encode_manager.get_timer_fd64()=%llu\n",conn_info.fec_encode_manager.get_timer_fd64()); + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(tmp_fd64), &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add fec_encode_manager.get_timer_fd64() error\n"); + // myexit(-1); + // } + conn_info.timer.data = &conn_info; + ev_init(&conn_info.timer, conn_timer_cb); + ev_timer_set(&conn_info.timer, 0, timer_interval / 1000.0); + ev_timer_start(loop, &conn_info.timer); + // conn_info.timer.add_fd_to_epoll(epoll_fd); + // conn_info.timer.set_timer_repeat_us(timer_interval*1000); + // mylog(log_debug,"conn_info.timer.get_timer_fd()=%d\n",conn_info.timer.get_timer_fd()); struct ev_io fifo_watcher; - int fifo_fd=-1; + int fifo_fd = -1; - if(fifo_file[0]!=0) - { - fifo_fd=create_fifo(fifo_file); - //ev.events = EPOLLIN; - //ev.data.u64 = fifo_fd; + if (fifo_file[0] != 0) { + fifo_fd = create_fifo(fifo_file); + // ev.events = EPOLLIN; + // ev.data.u64 = fifo_fd; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev); - //if (ret!= 0) { - // mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); - // myexit(-1); - //} - mylog(log_info,"fifo_file=%s\n",fifo_file); + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); + // myexit(-1); + // } + mylog(log_info, "fifo_file=%s\n", fifo_file); - ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); - ev_io_start(loop, &fifo_watcher); + ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); + ev_io_start(loop, &fifo_watcher); + } - } + ev_prepare prepare_watcher; + ev_init(&prepare_watcher, prepare_cb); + ev_prepare_start(loop, &prepare_watcher); - ev_prepare prepare_watcher; - ev_init(&prepare_watcher,prepare_cb); - ev_prepare_start(loop,&prepare_watcher); + mylog(log_info, "now listening at %s\n", local_addr.get_str()); - mylog(log_info,"now listening at %s\n",local_addr.get_str()); + ev_run(loop, 0); - ev_run(loop, 0); + mylog(log_warn, "ev_run returned\n"); + myexit(0); - mylog(log_warn,"ev_run returned\n"); - myexit(0); + /* + while(1)//////////////////////// + { + if(about_to_exit) myexit(0); - /* - while(1)//////////////////////// - { - if(about_to_exit) myexit(0); + int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000); + if (nfds < 0) { //allow zero + if(errno==EINTR ) + { + mylog(log_info,"epoll interrupted by signal continue\n"); + } + else + { + mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno)); + myexit(-1); + } + } + int idx; + for (idx = 0; idx < nfds; ++idx) { + if(events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd()) + { - int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000); - if (nfds < 0) { //allow zero - if(errno==EINTR ) - { - mylog(log_info,"epoll interrupted by signal continue\n"); - } - else - { - mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno)); - myexit(-1); - } - } - int idx; - for (idx = 0; idx < nfds; ++idx) { - if(events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd()) - { + } - } + else if (events[idx].data.u64 == (u64_t)fifo_fd) + { - else if (events[idx].data.u64 == (u64_t)fifo_fd) - { + } + else if (events[idx].data.u64 == (u64_t)local_listen_fd||events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()) + { - } - else if (events[idx].data.u64 == (u64_t)local_listen_fd||events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()) - { + } + else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) { - } - else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) { + } + else if(events[idx].data.u64>u32_t(-1) ) + { - } - else if(events[idx].data.u64>u32_t(-1) ) - { - - } - else - { - mylog(log_fatal,"unknown fd,this should never happen\n"); - myexit(-1); - } - } - //delay_manager.check(); - }*/ - return 0; + } + else + { + mylog(log_fatal,"unknown fd,this should never happen\n"); + myexit(-1); + } + } + //delay_manager.check(); + }*/ + return 0; } diff --git a/tunnel_server.cpp b/tunnel_server.cpp index 673aacc..aaa82c7 100644 --- a/tunnel_server.cpp +++ b/tunnel_server.cpp @@ -11,493 +11,454 @@ static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int re static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents); static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents); -enum tmp_mode_t{is_from_remote=0,is_fec_timeout,is_conn_timer}; +enum tmp_mode_t { is_from_remote = 0, + is_fec_timeout, + is_conn_timer }; -void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_t fd64,tmp_mode_t mode) -{ - int ret; +void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t &conn_info, fd64_t fd64, tmp_mode_t mode) { + int ret; - char data[buf_len]; - int data_len; - u32_t conv; - //fd64_t fd64=events[idx].data.u64; - //mylog(log_trace,"events[idx].data.u64 >u32_t(-1),%llu\n",(u64_t)events[idx].data.u64); + char data[buf_len]; + int data_len; + u32_t conv; + // fd64_t fd64=events[idx].data.u64; + // mylog(log_trace,"events[idx].data.u64 >u32_t(-1),%llu\n",(u64_t)events[idx].data.u64); + // assert(fd_manager.exist_info(fd64)); + // ip_port_t ip_port=fd_manager.get_info(fd64).ip_port; - //assert(fd_manager.exist_info(fd64)); - //ip_port_t ip_port=fd_manager.get_info(fd64).ip_port; + // conn_info_t &conn_info=conn_manager.find(ip_port); + address_t &addr = conn_info.addr; + assert(conn_manager.exist(addr)); + int &local_listen_fd = conn_info.local_listen_fd; - //conn_info_t &conn_info=conn_manager.find(ip_port); - address_t &addr=conn_info.addr; - assert(conn_manager.exist(addr)); + int out_n = -2; + char **out_arr; + int *out_len; + my_time_t *out_delay; - int &local_listen_fd=conn_info.local_listen_fd; + dest_t dest; + dest.inner.fd_addr.fd = local_listen_fd; + dest.inner.fd_addr.addr = addr; + dest.type = type_fd_addr; + dest.cook = 1; - int out_n=-2;char **out_arr;int *out_len;my_time_t *out_delay; - - dest_t dest; - dest.inner.fd_addr.fd=local_listen_fd; - dest.inner.fd_addr.addr=addr; - dest.type=type_fd_addr; - dest.cook=1; - - if(mode==is_fec_timeout) - { - assert(fd64==0); - //uint64_t value; - //if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8) - //{ - // mylog(log_trace,"fd_manager.to_fd(fd64), &value, 8)!=8 ,%d\n",ret); - // continue; - //} - //if(value==0) - //{ - // mylog(log_trace,"value==0\n"); - // continue; - //} - //assert(value==1); - from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay); - } - else if(mode==is_conn_timer) - { - assert(fd64==0); - //uint64_t value; - //read(conn_info.timer.get_timer_fd(), &value, 8); - conn_info.conv_manager.s.clear_inactive(); - if(debug_force_flush_fec) - { - from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay); - } - - conn_info.stat.report_as_server(addr); - return; - } - else if(mode==is_from_remote) - { - if(!fd_manager.exist(fd64)) //fd64 has been closed - { - mylog(log_warn,"!fd_manager.exist(fd64)\n"); - return; - } - - //fd64_t &fd64 =conn_info.remote_fd64; - assert(conn_info.conv_manager.s.is_data_used(fd64)); - - conv=conn_info.conv_manager.s.find_conv_by_data(fd64); - conn_info.conv_manager.s.update_active_time(conv); - conn_info.update_active_time(); - - int fd=fd_manager.to_fd(fd64); - data_len=recv(fd,data,max_data_len+1,0); - - if(data_len==max_data_len+1) - { - mylog(log_warn,"huge packet from upper level, data_len > %d, packet truncated, dropped\n",max_data_len); - return ; - } - - mylog(log_trace,"received a packet from udp_fd,len:%d,conv=%d\n",data_len,conv); - - if(data_len<0) - { - mylog(log_debug,"udp fd,recv_len<0 continue,%s\n",get_sock_error()); - - return; - } - - if(!disable_mtu_warn&&data_len>=mtu_warn) - { - mylog(log_warn,"huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",data_len,mtu_warn); - } - - char * new_data; - int new_len; - put_conv(conv,data,data_len,new_data,new_len); - - from_normal_to_fec(conn_info,new_data,new_len,out_n,out_arr,out_len,out_delay); - } - else - { - assert(0==1); - } - - mylog(log_trace,"out_n=%d\n",out_n); - for(int i=0;ifd; - int ret; - - mylog(log_trace,"events[idx].data.u64 == (u64_t)local_listen_fd\n"); - char data[buf_len]; - int data_len; - address_t::storage_t udp_new_addr_in={0}; - socklen_t udp_new_addr_len = sizeof(address_t::storage_t); - if ((data_len = recvfrom(local_listen_fd, data, max_data_len+1, 0, - (struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { - mylog(log_error,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error()); - return; - }; - - if(data_len==max_data_len+1) - { - mylog(log_warn,"huge packet, data_len > %d, packet truncated, dropped\n",max_data_len); - return ; + if (mode == is_fec_timeout) { + assert(fd64 == 0); + // uint64_t value; + // if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8) + //{ + // mylog(log_trace,"fd_manager.to_fd(fd64), &value, 8)!=8 ,%d\n",ret); + // continue; + // } + // if(value==0) + //{ + // mylog(log_trace,"value==0\n"); + // continue; + // } + // assert(value==1); + from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); + } else if (mode == is_conn_timer) { + assert(fd64 == 0); + // uint64_t value; + // read(conn_info.timer.get_timer_fd(), &value, 8); + conn_info.conv_manager.s.clear_inactive(); + if (debug_force_flush_fec) { + from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); } - address_t addr; - addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len); + conn_info.stat.report_as_server(addr); + return; + } else if (mode == is_from_remote) { + if (!fd_manager.exist(fd64)) // fd64 has been closed + { + mylog(log_warn, "!fd_manager.exist(fd64)\n"); + return; + } - mylog(log_trace,"Received packet from %s,len: %d\n", addr.get_str(),data_len); + // fd64_t &fd64 =conn_info.remote_fd64; + assert(conn_info.conv_manager.s.is_data_used(fd64)); - if(!disable_mtu_warn&&data_len>=mtu_warn)///////////////////////delete this for type 0 in furture - { - mylog(log_warn,"huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",data_len,mtu_warn); - } + conv = conn_info.conv_manager.s.find_conv_by_data(fd64); + conn_info.conv_manager.s.update_active_time(conv); + conn_info.update_active_time(); + int fd = fd_manager.to_fd(fd64); + data_len = recv(fd, data, max_data_len + 1, 0); - if(de_cook(data,data_len)!=0) - { - mylog(log_debug,"de_cook error"); - return; - } + if (data_len == max_data_len + 1) { + mylog(log_warn, "huge packet from upper level, data_len > %d, packet truncated, dropped\n", max_data_len); + return; + } + mylog(log_trace, "received a packet from udp_fd,len:%d,conv=%d\n", data_len, conv); + if (data_len < 0) { + mylog(log_debug, "udp fd,recv_len<0 continue,%s\n", get_sock_error()); - if(!conn_manager.exist(addr)) - { - if(conn_manager.mp.size() >=max_conn_num) - { - mylog(log_warn,"new connection %s ignored bc max_conn_num exceed\n",addr.get_str()); - return; - } + return; + } - //conn_manager.insert(addr); - conn_info_t &conn_info=conn_manager.find_insert(addr); - conn_info.addr=addr; - conn_info.loop=ev_default_loop(0); - conn_info.local_listen_fd=local_listen_fd; + if (!disable_mtu_warn && data_len >= mtu_warn) { + mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn); + } - //u64_t fec_fd64=conn_info.fec_encode_manager.get_timer_fd64(); - //mylog(log_debug,"fec_fd64=%llu\n",fec_fd64); - //ev.events = EPOLLIN; - //ev.data.u64 = fec_fd64; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(fec_fd64), &ev); + char *new_data; + int new_len; + put_conv(conv, data, data_len, new_data, new_len); - //fd_manager.get_info(fec_fd64).ip_port=ip_port; + from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay); + } else { + assert(0 == 1); + } - conn_info.timer.data=&conn_info; - ev_init(&conn_info.timer,conn_timer_cb); - ev_timer_set(&conn_info.timer, 0, timer_interval/1000.0 ); - ev_timer_start(loop,&conn_info.timer); - - //conn_info.timer.add_fd64_to_epoll(epoll_fd); - //conn_info.timer.set_timer_repeat_us(timer_interval*1000); - - //mylog(log_debug,"conn_info.timer.get_timer_fd64()=%llu\n",conn_info.timer.get_timer_fd64()); - - //u64_t timer_fd64=conn_info.timer.get_timer_fd64(); - //fd_manager.get_info(timer_fd64).ip_port=ip_port; - - - - conn_info.fec_encode_manager.set_data(&conn_info); - conn_info.fec_encode_manager.set_loop_and_cb(loop,fec_encode_cb); - - - mylog(log_info,"new connection from %s\n",addr.get_str()); - - } - conn_info_t &conn_info=conn_manager.find_insert(addr); - - conn_info.update_active_time(); - int out_n;char **out_arr;int *out_len;my_time_t *out_delay; - from_fec_to_normal(conn_info,data,data_len,out_n,out_arr,out_len,out_delay); - - mylog(log_trace,"out_n= %d\n",out_n); - for(int i=0;i=max_conv_num) - { - mylog(log_warn,"ignored new udp connect bc max_conv_num exceed\n"); - continue; - } - - int new_udp_fd; - ret=new_connected_socket2(new_udp_fd,remote_addr,out_addr,out_interface); - - if (ret != 0) { - mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str()); - continue; - } - - fd64_t fd64 = fd_manager.create(new_udp_fd); - //ev.events = EPOLLIN; - //ev.data.u64 = fd64; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_udp_fd, &ev); - - conn_info.conv_manager.s.insert_conv(conv, fd64); - fd_manager.get_info(fd64).addr=addr; - - ev_io &io_watcher=fd_manager.get_info(fd64).io_watcher; - io_watcher.u64=fd64; - io_watcher.data=&conn_info; - - ev_init(&io_watcher,remote_cb); - ev_io_set(&io_watcher,new_udp_fd,EV_READ); - ev_io_start(conn_info.loop,&io_watcher); - - - mylog(log_info,"[%s]new conv %x,fd %d created,fd64=%llu\n",addr.get_str(),conv,new_udp_fd,fd64); - } - conn_info.conv_manager.s.update_active_time(conv); - fd64_t fd64= conn_info.conv_manager.s.find_data_by_conv(conv); - dest_t dest; - dest.type=type_fd64; - dest.inner.fd64=fd64; - delay_send(out_delay[i],dest,new_data,new_len); - } + mylog(log_trace, "out_n=%d\n", out_n); + for (int i = 0; i < out_n; i++) { + delay_send(out_delay[i], dest, out_arr[i], out_len[i]); + } } -static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + assert(!(revents & EV_ERROR)); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - fd64_t fd64=watcher->u64; + int local_listen_fd = watcher->fd; + int ret; - data_from_remote_or_fec_timeout_or_conn_timer(conn_info,fd64,is_from_remote); + mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n"); + char data[buf_len]; + int data_len; + address_t::storage_t udp_new_addr_in = {0}; + socklen_t udp_new_addr_len = sizeof(address_t::storage_t); + if ((data_len = recvfrom(local_listen_fd, data, max_data_len + 1, 0, + (struct sockaddr *)&udp_new_addr_in, &udp_new_addr_len)) == -1) { + mylog(log_error, "recv_from error,this shouldnt happen,err=%s,but we can try to continue\n", get_sock_error()); + return; + }; + + if (data_len == max_data_len + 1) { + mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len); + return; + } + + address_t addr; + addr.from_sockaddr((struct sockaddr *)&udp_new_addr_in, udp_new_addr_len); + + mylog(log_trace, "Received packet from %s,len: %d\n", addr.get_str(), data_len); + + if (!disable_mtu_warn && data_len >= mtu_warn) ///////////////////////delete this for type 0 in furture + { + mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn); + } + + if (de_cook(data, data_len) != 0) { + mylog(log_debug, "de_cook error"); + return; + } + + if (!conn_manager.exist(addr)) { + if (conn_manager.mp.size() >= max_conn_num) { + mylog(log_warn, "new connection %s ignored bc max_conn_num exceed\n", addr.get_str()); + return; + } + + // conn_manager.insert(addr); + conn_info_t &conn_info = conn_manager.find_insert(addr); + conn_info.addr = addr; + conn_info.loop = ev_default_loop(0); + conn_info.local_listen_fd = local_listen_fd; + + // u64_t fec_fd64=conn_info.fec_encode_manager.get_timer_fd64(); + // mylog(log_debug,"fec_fd64=%llu\n",fec_fd64); + // ev.events = EPOLLIN; + // ev.data.u64 = fec_fd64; + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(fec_fd64), &ev); + + // fd_manager.get_info(fec_fd64).ip_port=ip_port; + + conn_info.timer.data = &conn_info; + ev_init(&conn_info.timer, conn_timer_cb); + ev_timer_set(&conn_info.timer, 0, timer_interval / 1000.0); + ev_timer_start(loop, &conn_info.timer); + + // conn_info.timer.add_fd64_to_epoll(epoll_fd); + // conn_info.timer.set_timer_repeat_us(timer_interval*1000); + + // mylog(log_debug,"conn_info.timer.get_timer_fd64()=%llu\n",conn_info.timer.get_timer_fd64()); + + // u64_t timer_fd64=conn_info.timer.get_timer_fd64(); + // fd_manager.get_info(timer_fd64).ip_port=ip_port; + + conn_info.fec_encode_manager.set_data(&conn_info); + conn_info.fec_encode_manager.set_loop_and_cb(loop, fec_encode_cb); + + mylog(log_info, "new connection from %s\n", addr.get_str()); + } + conn_info_t &conn_info = conn_manager.find_insert(addr); + + conn_info.update_active_time(); + int out_n; + char **out_arr; + int *out_len; + my_time_t *out_delay; + from_fec_to_normal(conn_info, data, data_len, out_n, out_arr, out_len, out_delay); + + mylog(log_trace, "out_n= %d\n", out_n); + for (int i = 0; i < out_n; i++) { + u32_t conv; + char *new_data; + int new_len; + if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) { + mylog(log_debug, "get_conv failed"); + continue; + } + + if (!conn_info.conv_manager.s.is_conv_used(conv)) { + if (conn_info.conv_manager.s.get_size() >= max_conv_num) { + mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n"); + continue; + } + + int new_udp_fd; + ret = new_connected_socket2(new_udp_fd, remote_addr, out_addr, out_interface); + + if (ret != 0) { + mylog(log_warn, "[%s]new_connected_socket failed\n", addr.get_str()); + continue; + } + + fd64_t fd64 = fd_manager.create(new_udp_fd); + // ev.events = EPOLLIN; + // ev.data.u64 = fd64; + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_udp_fd, &ev); + + conn_info.conv_manager.s.insert_conv(conv, fd64); + fd_manager.get_info(fd64).addr = addr; + + ev_io &io_watcher = fd_manager.get_info(fd64).io_watcher; + io_watcher.u64 = fd64; + io_watcher.data = &conn_info; + + ev_init(&io_watcher, remote_cb); + ev_io_set(&io_watcher, new_udp_fd, EV_READ); + ev_io_start(conn_info.loop, &io_watcher); + + mylog(log_info, "[%s]new conv %x,fd %d created,fd64=%llu\n", addr.get_str(), conv, new_udp_fd, fd64); + } + conn_info.conv_manager.s.update_active_time(conv); + fd64_t fd64 = conn_info.conv_manager.s.find_data_by_conv(conv); + dest_t dest; + dest.type = type_fd64; + dest.inner.fd64 = fd64; + delay_send(out_delay[i], dest, new_data, new_len); + } } -static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + assert(!(revents & EV_ERROR)); - int fifo_fd=watcher->fd; + conn_info_t &conn_info = *((conn_info_t *)watcher->data); + fd64_t fd64 = watcher->u64; - char buf[buf_len]; - int len=read (fifo_fd, buf, sizeof (buf)); - if(len<0) - { - mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error()); - return; - } - buf[len]=0; - handle_command(buf); + data_from_remote_or_fec_timeout_or_conn_timer(conn_info, fd64, is_from_remote); } -static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + assert(!(revents & EV_ERROR)); - //uint64_t value; - //read(delay_manager.get_timer_fd(), &value, 8); - //mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); - - //do nothing + int fifo_fd = watcher->fd; + char buf[buf_len]; + int len = read(fifo_fd, buf, sizeof(buf)); + if (len < 0) { + mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error()); + return; + } + buf[len] = 0; + handle_command(buf); } -static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { + assert(!(revents & EV_ERROR)); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); + // uint64_t value; + // read(delay_manager.get_timer_fd(), &value, 8); + // mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); - data_from_remote_or_fec_timeout_or_conn_timer(conn_info,0,is_fec_timeout); + // do nothing } -static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { + assert(!(revents & EV_ERROR)); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); + conn_info_t &conn_info = *((conn_info_t *)watcher->data); - data_from_remote_or_fec_timeout_or_conn_timer(conn_info,0,is_conn_timer); + data_from_remote_or_fec_timeout_or_conn_timer(conn_info, 0, is_fec_timeout); } -static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { + assert(!(revents & EV_ERROR)); - delay_manager.check(); + conn_info_t &conn_info = *((conn_info_t *)watcher->data); + + data_from_remote_or_fec_timeout_or_conn_timer(conn_info, 0, is_conn_timer); } -static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - assert(!(revents&EV_ERROR)); +static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) { + assert(!(revents & EV_ERROR)); - //uint64_t value; - //read(timer.get_timer_fd(), &value, 8); - conn_manager.clear_inactive(); - mylog(log_trace,"events[idx].data.u64==(u64_t)timer.get_timer_fd()\n"); + delay_manager.check(); } -int tunnel_server_event_loop() -{ +static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) { + assert(!(revents & EV_ERROR)); - int i, j, k;int ret; - int yes = 1; - //int epoll_fd; - //int remote_fd; + // uint64_t value; + // read(timer.get_timer_fd(), &value, 8); + conn_manager.clear_inactive(); + mylog(log_trace, "events[idx].data.u64==(u64_t)timer.get_timer_fd()\n"); +} - int local_listen_fd; - new_listen_socket2(local_listen_fd,local_addr); +int tunnel_server_event_loop() { + int i, j, k; + int ret; + int yes = 1; + // int epoll_fd; + // int remote_fd; - //epoll_fd = epoll_create1(0); - //assert(epoll_fd>0); + int local_listen_fd; + new_listen_socket2(local_listen_fd, local_addr); - //const int max_events = 4096; - //struct epoll_event ev, events[max_events]; - //if (epoll_fd < 0) { - // mylog(log_fatal,"epoll return %d\n", epoll_fd); - // myexit(-1); - //} + // epoll_fd = epoll_create1(0); + // assert(epoll_fd>0); - struct ev_loop * loop= ev_default_loop(0); - assert(loop != NULL); + // const int max_events = 4096; + // struct epoll_event ev, events[max_events]; + // if (epoll_fd < 0) { + // mylog(log_fatal,"epoll return %d\n", epoll_fd); + // myexit(-1); + // } - //ev.events = EPOLLIN; - //ev.data.u64 = local_listen_fd; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev); - //if (ret!=0) { - // mylog(log_fatal,"add udp_listen_fd error\n"); - // myexit(-1); - //} - struct ev_io local_listen_watcher; + struct ev_loop *loop = ev_default_loop(0); + assert(loop != NULL); + + // ev.events = EPOLLIN; + // ev.data.u64 = local_listen_fd; + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev); + // if (ret!=0) { + // mylog(log_fatal,"add udp_listen_fd error\n"); + // myexit(-1); + // } + struct ev_io local_listen_watcher; ev_io_init(&local_listen_watcher, local_listen_cb, local_listen_fd, EV_READ); ev_io_start(loop, &local_listen_watcher); - //ev.events = EPOLLIN; - //ev.data.u64 = delay_manager.get_timer_fd(); - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev); - //if (ret!= 0) { - // mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); - // myexit(-1); - //} + // ev.events = EPOLLIN; + // ev.data.u64 = delay_manager.get_timer_fd(); + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); + // myexit(-1); + // } - delay_manager.set_loop_and_cb(loop,delay_manager_cb); + delay_manager.set_loop_and_cb(loop, delay_manager_cb); - //mylog(log_debug," delay_manager.get_timer_fd() =%d\n", delay_manager.get_timer_fd()); + // mylog(log_debug," delay_manager.get_timer_fd() =%d\n", delay_manager.get_timer_fd()); - mylog(log_info,"now listening at %s\n",local_addr.get_str()); + mylog(log_info, "now listening at %s\n", local_addr.get_str()); - //my_timer_t timer; - //timer.add_fd_to_epoll(epoll_fd); - //timer.set_timer_repeat_us(timer_interval*1000); + // my_timer_t timer; + // timer.add_fd_to_epoll(epoll_fd); + // timer.set_timer_repeat_us(timer_interval*1000); - ev_timer global_timer; - ev_init(&global_timer,global_timer_cb); - ev_timer_set(&global_timer, 0, timer_interval/1000.0 ); - ev_timer_start(loop,&global_timer); + ev_timer global_timer; + ev_init(&global_timer, global_timer_cb); + ev_timer_set(&global_timer, 0, timer_interval / 1000.0); + ev_timer_start(loop, &global_timer); - //mylog(log_debug," timer.get_timer_fd() =%d\n",timer.get_timer_fd()); + // mylog(log_debug," timer.get_timer_fd() =%d\n",timer.get_timer_fd()); struct ev_io fifo_watcher; - int fifo_fd=-1; + int fifo_fd = -1; - if(fifo_file[0]!=0) - { - fifo_fd=create_fifo(fifo_file); - //ev.events = EPOLLIN; - //ev.data.u64 = fifo_fd; + if (fifo_file[0] != 0) { + fifo_fd = create_fifo(fifo_file); + // ev.events = EPOLLIN; + // ev.data.u64 = fifo_fd; - //ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev); - //if (ret!= 0) { - //mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); - //myexit(-1); - //} - ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); - ev_io_start(loop, &fifo_watcher); + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); + // myexit(-1); + //} + ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); + ev_io_start(loop, &fifo_watcher); - mylog(log_info,"fifo_file=%s\n",fifo_file); - } + mylog(log_info, "fifo_file=%s\n", fifo_file); + } - ev_prepare prepare_watcher; - ev_init(&prepare_watcher,prepare_cb); - ev_prepare_start(loop,&prepare_watcher); + ev_prepare prepare_watcher; + ev_init(&prepare_watcher, prepare_cb); + ev_prepare_start(loop, &prepare_watcher); + + ev_run(loop, 0); + + mylog(log_warn, "ev_run returned\n"); + myexit(0); + + /* + while(1)//////////////////////// + { + + if(about_to_exit) myexit(0); + + int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000); + if (nfds < 0) { //allow zero + if(errno==EINTR ) + { + mylog(log_info,"epoll interrupted by signal,continue\n"); + } + else + { + mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno)); + myexit(-1); + } + } + int idx; + for (idx = 0; idx < nfds; ++idx) + { + if(events[idx].data.u64==(u64_t)timer.get_timer_fd()) + { + + } + + else if (events[idx].data.u64 == (u64_t)fifo_fd) + { + + } + + else if (events[idx].data.u64 == (u64_t)local_listen_fd) + { - ev_run(loop, 0); + } + else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) { - mylog(log_warn,"ev_run returned\n"); - myexit(0); - - /* - while(1)//////////////////////// - { - - if(about_to_exit) myexit(0); - - int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000); - if (nfds < 0) { //allow zero - if(errno==EINTR ) - { - mylog(log_info,"epoll interrupted by signal,continue\n"); - } - else - { - mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno)); - myexit(-1); - } - } - int idx; - for (idx = 0; idx < nfds; ++idx) - { - if(events[idx].data.u64==(u64_t)timer.get_timer_fd()) - { - - } - - else if (events[idx].data.u64 == (u64_t)fifo_fd) - { - - } - - else if (events[idx].data.u64 == (u64_t)local_listen_fd) - { + } + else if (events[idx].data.u64 >u32_t(-1)) + { - } - else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) { + } + else + { + mylog(log_fatal,"unknown fd,this should never happen\n"); + myexit(-1); + } + } - } - else if (events[idx].data.u64 >u32_t(-1)) - { - - - } - else - { - mylog(log_fatal,"unknown fd,this should never happen\n"); - myexit(-1); - } - } - - }*/ - - - return 0; + }*/ + return 0; }