19 Commits

Author SHA1 Message Date
Yancey Wang
470b5d50bb Merge pull request #327 from lsylsy2/crc32
Import fast crc32 from Stephan Brumme
2025-05-03 13:33:13 -07:00
lsylsy2
dfc6ac0d8c Import fast crc32 from Stephan Brumme 2024-06-16 22:40:14 +08:00
yancey
17694ecaa9 fix more sanitizer complaint 2023-07-22 18:16:33 -04:00
yancey
c3debb0290 sync udp2raw bugfix 2023-07-22 14:45:53 -04:00
Yancey Wang
3ac5e6b40d Update CMakeLists.txt 2023-06-04 21:45:31 -04:00
Yancey Wang
ca5444b4a7 Update ISSUE_TEMPLATE.md 2023-05-10 00:07:31 -04:00
yancey
61b24a3697 supress complier warning 2023-02-07 06:40:40 -05:00
yancey
41cac842a8 fix indent problem with clang-format 2023-02-07 05:34:06 -05:00
yancey
43dfb12d9e rework pr 2023-02-07 05:32:40 -05:00
Yancey Wang
dab380366d Merge pull request #297 from wwbfred/branch_libev
Fix a bug mentioned in #290
2023-02-07 05:25:37 -05:00
yancey
a0c9cce148 add .clang-format 2023-02-07 05:03:49 -05:00
yancey
0775131ab5 update cmake 2023-02-07 04:54:42 -05:00
yancey
49b3b6ec11 add CMakeLists.txt 2023-02-06 07:59:37 -05:00
Fred Wu
c6437cccbb Update misc.cpp 2022-07-02 16:03:34 +08:00
Fred Wu
0261c75c29 Update fec_manager.h 2022-07-02 16:02:30 +08:00
Fred Wu
89e7e294f2 Update misc.cpp
Fix a bug which resets all parameters to default value when writing a fec parameter to the fifo file.
2022-07-02 15:59:02 +08:00
Fred Wu
3b1b5d32d6 Clone a fec_parameter_t with fec changed only 2022-07-02 15:48:39 +08:00
Yancey Wang
fd72361dea Update README.md 2021-12-09 09:26:53 -05:00
wangyu
3375c6ac9d refine huge packet log 2021-01-16 14:40:03 -05:00
32 changed files with 5952 additions and 5438 deletions

4
.clang-format Normal file
View File

@@ -0,0 +1,4 @@
SortIncludes: false
BasedOnStyle: Google
ColumnLimit: 0
IndentWidth: 4

35
CMakeLists.txt Normal file
View File

@@ -0,0 +1,35 @@
#note: experimental
# currently only used for generating `compile_commands.json` for clangd
# to build this project, it's suggested to use `makefile` instead
cmake_minimum_required(VERSION 3.7)
project(speederv2)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES
main.cpp
log.cpp
common.cpp
lib/fec.cpp
lib/rs.cpp
packet.cpp
delay_manager.cpp
fd_manager.cpp
connection.cpp
fec_manager.cpp
misc.cpp
tunnel_client.cpp
tunnel_server.cpp
my_ev.cpp
)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers -O2 -g -fsanitize=address,undefined")
#target_include_directories(speederv2 PRIVATE .)
#set(CMAKE_LINK_LIBRARY_FLAG "-lrt")
add_executable(speederv2 ${SOURCE_FILES})
target_link_libraries(speederv2 rt)
target_link_libraries(speederv2 pthread)
include_directories(SYSTEM "libev")
include_directories(".")

View File

@@ -1 +1 @@
English Only (except for bug reporting). English Only.

View File

@@ -15,7 +15,7 @@ Assume your local network to your server is lossy. Just establish a VPN connecti
[UDPspeeder Wiki](https://github.com/wangyu-/UDPspeeder/wiki) [UDPspeeder Wiki](https://github.com/wangyu-/UDPspeeder/wiki)
[简体中文](/doc/README.zh-cn.md)(内容更丰富) [简体中文](/doc/README.zh-cn.md)
# Efficacy # Efficacy
tested on a link with 100ms latency and 10% packet loss at both direction tested on a link with 100ms latency and 10% packet loss at both direction

View File

@@ -16,7 +16,6 @@ int about_to_exit=0;
raw_mode_t raw_mode = mode_faketcp; raw_mode_t raw_mode = mode_faketcp;
unordered_map<int, const char *> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}}; unordered_map<int, const char *> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}};
// static int random_number_fd=-1; // static int random_number_fd=-1;
char iptables_rule[200] = ""; char iptables_rule[200] = "";
// int is_client = 0, is_server = 0; // int is_client = 0, is_server = 0;
@@ -27,8 +26,7 @@ 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__) #if defined(__MINGW32__)
WORD wVersionRequested; WORD wVersionRequested;
WSADATA wsaData; WSADATA wsaData;
@@ -57,18 +55,17 @@ int init_ws()
printf("Could not find a usable version of Winsock.dll\n"); printf("Could not find a usable version of Winsock.dll\n");
WSACleanup(); WSACleanup();
exit(-1); exit(-1);
} } else {
else
{
printf("The Winsock 2.2 dll was found okay"); printf("The Winsock 2.2 dll was found okay");
} }
int tmp[] = {0, 100, 200, 300, 500, 800, 1000, 2000, 3000, 4000, -1}; int tmp[] = {0, 100, 200, 300, 500, 800, 1000, 2000, 3000, 4000, -1};
int succ = 0; int succ = 0;
for(int i=1;tmp[i]!=-1;i++) for (int i = 1; tmp[i] != -1; i++) {
{ if (_setmaxstdio(100) == -1)
if(_setmaxstdio(100)==-1) break; break;
else succ=i; else
succ = i;
} }
printf(", _setmaxstdio() was set to %d\n", tmp[succ]); printf(", _setmaxstdio() was set to %d\n", tmp[succ]);
#endif #endif
@@ -76,8 +73,7 @@ return 0;
} }
#if defined(__MINGW32__) #if defined(__MINGW32__)
int inet_pton(int af, const char *src, void *dst) int inet_pton(int af, const char *src, void *dst) {
{
struct sockaddr_storage ss; struct sockaddr_storage ss;
int size = sizeof(ss); int size = sizeof(ss);
char src_copy[INET6_ADDRSTRLEN + 1]; char src_copy[INET6_ADDRSTRLEN + 1];
@@ -100,8 +96,7 @@ int inet_pton(int af, const char *src, void *dst)
return 0; return 0;
} }
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
{
struct sockaddr_storage ss; struct sockaddr_storage ss;
unsigned long s = size; unsigned long s = size;
@@ -119,11 +114,9 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
return NULL; return NULL;
} }
/* cannot direclty use &size because of strict aliasing rules */ /* cannot direclty use &size because of strict aliasing rules */
return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)? return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0) ? dst : NULL;
dst : NULL;
} }
char *get_sock_error() char *get_sock_error() {
{
static char buf[1000]; static char buf[1000];
int e = WSAGetLastError(); int e = WSAGetLastError();
wchar_t *s = NULL; wchar_t *s = NULL;
@@ -137,26 +130,21 @@ char *get_sock_error()
LocalFree(s); LocalFree(s);
return buf; return buf;
} }
int get_sock_errno() int get_sock_errno() {
{
return WSAGetLastError(); return WSAGetLastError();
} }
#else #else
char *get_sock_error() char *get_sock_error() {
{
static char buf[1000]; static char buf[1000];
sprintf(buf, "%d:%s", errno, strerror(errno)); sprintf(buf, "%d:%s", errno, strerror(errno));
return buf; return buf;
} }
int get_sock_errno() int get_sock_errno() {
{
return errno; return errno;
} }
#endif #endif
struct my_random_t {
struct my_random_t
{
std::random_device rd; std::random_device rd;
std::mt19937 gen; std::mt19937 gen;
std::uniform_int_distribution<u64_t> dis64; std::uniform_int_distribution<u64_t> dis64;
@@ -164,23 +152,19 @@ struct my_random_t
std::uniform_int_distribution<unsigned char> dis8; std::uniform_int_distribution<unsigned char> dis8;
my_random_t() my_random_t() {
{
std::mt19937 gen_tmp(rd()); std::mt19937 gen_tmp(rd());
gen = gen_tmp; gen = gen_tmp;
gen.discard(700000); // magic gen.discard(700000); // magic
} }
u64_t gen64() u64_t gen64() {
{
return dis64(gen); return dis64(gen);
} }
u32_t gen32() u32_t gen32() {
{
return dis32(gen); return dis32(gen);
} }
unsigned char gen8() unsigned char gen8() {
{
return dis8(gen); return dis8(gen);
} }
/*int random_number_fd; /*int random_number_fd;
@@ -201,74 +185,57 @@ struct my_random_t
}*/ }*/
} my_random; } my_random;
int address_t::from_str(char *str) int address_t::from_str(char *str) {
{
clear(); clear();
char ip_addr_str[100];u32_t port; char ip_addr_str[100];
u32_t port;
mylog(log_info, "parsing address: %s\n", str); mylog(log_info, "parsing address: %s\n", str);
int is_ipv6 = 0; int is_ipv6 = 0;
if(sscanf(str, "[%[^]]]:%u", ip_addr_str,&port)==2) if (sscanf(str, "[%[^]]]:%u", ip_addr_str, &port) == 2) {
{
mylog(log_info, "its an ipv6 adress\n"); mylog(log_info, "its an ipv6 adress\n");
inner.ipv6.sin6_family = AF_INET6; inner.ipv6.sin6_family = AF_INET6;
is_ipv6 = 1; is_ipv6 = 1;
} } else if (sscanf(str, "%[^:]:%u", ip_addr_str, &port) == 2) {
else if(sscanf(str, "%[^:]:%u", ip_addr_str,&port)==2)
{
mylog(log_info, "its an ipv4 adress\n"); mylog(log_info, "its an ipv4 adress\n");
inner.ipv4.sin_family = AF_INET; inner.ipv4.sin_family = AF_INET;
} } else {
else
{
mylog(log_error, "failed to parse\n"); mylog(log_error, "failed to parse\n");
myexit(-1); 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) if (port > 65535) {
{
mylog(log_error, "invalid port: %d\n", port); mylog(log_error, "invalid port: %d\n", port);
myexit(-1); myexit(-1);
} }
int ret = -100; int ret = -100;
if(is_ipv6) if (is_ipv6) {
{
ret = inet_pton(AF_INET6, ip_addr_str, &(inner.ipv6.sin6_addr)); ret = inet_pton(AF_INET6, ip_addr_str, &(inner.ipv6.sin6_addr));
inner.ipv6.sin6_port = htons(port); inner.ipv6.sin6_port = htons(port);
if (ret == 0) // 0 if address type doesnt match 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); mylog(log_error, "ip_addr %s is not an ipv6 address, %d\n", ip_addr_str, ret);
myexit(-1); myexit(-1);
} } else if (ret == 1) // inet_pton returns 1 on success
else if(ret==1) // inet_pton returns 1 on success
{ {
// okay // okay
} } else {
else
{
mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret); mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret);
myexit(-1); myexit(-1);
} }
} } else {
else
{
ret = inet_pton(AF_INET, ip_addr_str, &(inner.ipv4.sin_addr)); ret = inet_pton(AF_INET, ip_addr_str, &(inner.ipv4.sin_addr));
inner.ipv4.sin_port = htons(port); inner.ipv4.sin_port = htons(port);
if(ret==0) if (ret == 0) {
{
mylog(log_error, "ip_addr %s is not an ipv4 address, %d\n", ip_addr_str, ret); mylog(log_error, "ip_addr %s is not an ipv4 address, %d\n", ip_addr_str, ret);
myexit(-1); myexit(-1);
} } else if (ret == 1) {
else if(ret==1)
{
// okay // okay
} } else {
else
{
mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret); mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret);
myexit(-1); myexit(-1);
} }
@@ -277,8 +244,7 @@ int address_t::from_str(char *str)
return 0; return 0;
} }
int address_t::from_str_ip_only(char * str) int address_t::from_str_ip_only(char *str) {
{
clear(); clear();
u32_t type; u32_t type;
@@ -291,12 +257,9 @@ int address_t::from_str_ip_only(char * str)
((sockaddr *)&inner)->sa_family = type; ((sockaddr *)&inner)->sa_family = type;
int ret; int ret;
if(type==AF_INET) if (type == AF_INET) {
{
ret = inet_pton(type, str, &inner.ipv4.sin_addr); ret = inet_pton(type, str, &inner.ipv4.sin_addr);
} } else {
else
{
ret = inet_pton(type, str, &inner.ipv6.sin6_addr); ret = inet_pton(type, str, &inner.ipv6.sin6_addr);
} }
@@ -304,43 +267,33 @@ int address_t::from_str_ip_only(char * str)
{ {
mylog(log_error, "confusion in parsing %s, %d\n", str, ret); mylog(log_error, "confusion in parsing %s, %d\n", str, ret);
myexit(-1); myexit(-1);
} } else if (ret == 1) // inet_pton returns 1 on success
else if(ret==1) // inet_pton returns 1 on success
{ {
// okay // okay
} } else {
else
{
mylog(log_error, "ip_addr %s is invalid, %d\n", str, ret); mylog(log_error, "ip_addr %s is invalid, %d\n", str, ret);
myexit(-1); myexit(-1);
} }
return 0; return 0;
} }
char * address_t::get_str() char *address_t::get_str() {
{
static char res[max_addr_len]; static char res[max_addr_len];
to_str(res); to_str(res);
return res; return res;
} }
void address_t::to_str(char * s) void address_t::to_str(char *s) {
{
// static char res[max_addr_len]; // static char res[max_addr_len];
char ip_addr[max_addr_len]; char ip_addr[max_addr_len];
u32_t port; u32_t port;
const char *ret = 0; const char *ret = 0;
if(get_type()==AF_INET6) if (get_type() == AF_INET6) {
{
ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len); ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len);
port = inner.ipv6.sin6_port; port = inner.ipv6.sin6_port;
} } else if (get_type() == AF_INET) {
else if(get_type()==AF_INET)
{
ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len); ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len);
port = inner.ipv4.sin_port; port = inner.ipv4.sin_port;
} } else {
else
{
assert(0 == 1); assert(0 == 1);
} }
@@ -353,32 +306,24 @@ void address_t::to_str(char * s)
port = ntohs(port); port = ntohs(port);
ip_addr[max_addr_len - 1] = 0; ip_addr[max_addr_len - 1] = 0;
if(get_type()==AF_INET6) if (get_type() == AF_INET6) {
{
sprintf(s, "[%s]:%u", ip_addr, (u32_t)port); sprintf(s, "[%s]:%u", ip_addr, (u32_t)port);
}else } else {
{
sprintf(s, "%s:%u", ip_addr, (u32_t)port); sprintf(s, "%s:%u", ip_addr, (u32_t)port);
} }
// return res; // return res;
} }
char* address_t::get_ip() char *address_t::get_ip() {
{
char ip_addr[max_addr_len]; char ip_addr[max_addr_len];
static char s[max_addr_len]; static char s[max_addr_len];
const char *ret = 0; const char *ret = 0;
if(get_type()==AF_INET6) if (get_type() == AF_INET6) {
{
ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len); ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len);
} } else if (get_type() == AF_INET) {
else if(get_type()==AF_INET)
{
ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len); ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len);
} } else {
else
{
assert(0 == 1); assert(0 == 1);
} }
@@ -389,43 +334,33 @@ char* address_t::get_ip()
} }
ip_addr[max_addr_len - 1] = 0; ip_addr[max_addr_len - 1] = 0;
if(get_type()==AF_INET6) if (get_type() == AF_INET6) {
{
sprintf(s, "%s", ip_addr); sprintf(s, "%s", ip_addr);
}else } else {
{
sprintf(s, "%s", ip_addr); sprintf(s, "%s", ip_addr);
} }
return s; return s;
} }
int address_t::from_sockaddr(sockaddr * addr,socklen_t slen) int address_t::from_sockaddr(sockaddr *addr, socklen_t slen) {
{
clear(); clear();
// memset(&inner,0,sizeof(inner)); // memset(&inner,0,sizeof(inner));
if(addr->sa_family==AF_INET6) if (addr->sa_family == AF_INET6) {
{
assert(slen == sizeof(sockaddr_in6)); assert(slen == sizeof(sockaddr_in6));
// inner.ipv6= *( (sockaddr_in6*) addr ); // inner.ipv6= *( (sockaddr_in6*) addr );
memcpy(&inner, addr, slen); memcpy(&inner, addr, slen);
} } else if (addr->sa_family == AF_INET) {
else if(addr->sa_family==AF_INET)
{
assert(slen == sizeof(sockaddr_in)); assert(slen == sizeof(sockaddr_in));
// inner.ipv4= *( (sockaddr_in*) addr ); // inner.ipv4= *( (sockaddr_in*) addr );
memcpy(&inner, addr, slen); memcpy(&inner, addr, slen);
} } else {
else
{
assert(0 == 1); assert(0 == 1);
} }
return 0; return 0;
} }
int address_t::new_connected_udp_fd() int address_t::new_connected_udp_fd() {
{
int new_udp_fd; int new_udp_fd;
new_udp_fd = socket(get_type(), SOCK_DGRAM, IPPROTO_UDP); new_udp_fd = socket(get_type(), SOCK_DGRAM, IPPROTO_UDP);
if (new_udp_fd < 0) { if (new_udp_fd < 0) {
@@ -447,13 +382,11 @@ int address_t::new_connected_udp_fd()
return new_udp_fd; return new_udp_fd;
} }
void get_fake_random_chars(char * s,int len) void get_fake_random_chars(char *s, int len) {
{
char *p = s; char *p = s;
int left = len; int left = len;
while(left>=(int)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*)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(); u64_t tmp = my_random.gen64();
@@ -462,22 +395,21 @@ void get_fake_random_chars(char * s,int len)
p += sizeof(u64_t); p += sizeof(u64_t);
left -= sizeof(u64_t); left -= sizeof(u64_t);
} }
if(left) if (left) {
{
u64_t tmp = my_random.gen64(); u64_t tmp = my_random.gen64();
memcpy(p, &tmp, left); memcpy(p, &tmp, left);
} }
} }
int random_between(u32_t a,u32_t b) int random_between(u32_t a, u32_t b) {
{ if (a > b) {
if(a>b)
{
mylog(log_fatal, "min >max?? %d %d\n", a, b); mylog(log_fatal, "min >max?? %d %d\n", a, b);
myexit(1); myexit(1);
} }
if(a==b)return a; if (a == b)
else return a+get_fake_random_number()%(b+1-a); return a;
else
return a + get_fake_random_number() % (b + 1 - a);
} }
/* /*
@@ -495,8 +427,7 @@ u64_t get_current_time_us()
return (uint64_t(tmp_time.tv_sec))*1000llu*1000llu+ (uint64_t(tmp_time.tv_nsec))/1000llu; return (uint64_t(tmp_time.tv_sec))*1000llu*1000llu+ (uint64_t(tmp_time.tv_nsec))/1000llu;
}*/ }*/
u64_t get_current_time_us() u64_t get_current_time_us() {
{
static u64_t value_fix = 0; static u64_t value_fix = 0;
static u64_t largest_value = 0; static u64_t largest_value = 0;
@@ -504,12 +435,9 @@ u64_t get_current_time_us()
u64_t fixed_value = raw_value + value_fix; u64_t fixed_value = raw_value + value_fix;
if(fixed_value< largest_value) if (fixed_value < largest_value) {
{
value_fix += largest_value - fixed_value; value_fix += largest_value - fixed_value;
} } else {
else
{
largest_value = fixed_value; largest_value = fixed_value;
} }
@@ -517,49 +445,41 @@ u64_t get_current_time_us()
return raw_value + value_fix; // new fixed value return raw_value + value_fix; // new fixed value
} }
u64_t get_current_time() u64_t get_current_time() {
{
return get_current_time_us() / 1000lu; return get_current_time_us() / 1000lu;
} }
u64_t pack_u64(u32_t a,u32_t b) u64_t pack_u64(u32_t a, u32_t b) {
{
u64_t ret = a; u64_t ret = a;
ret <<= 32u; ret <<= 32u;
ret += b; ret += b;
return ret; return ret;
} }
u32_t get_u64_h(u64_t a) u32_t get_u64_h(u64_t a) {
{
return a >> 32u; return a >> 32u;
} }
u32_t get_u64_l(u64_t a) u32_t get_u64_l(u64_t a) {
{
return (a << 32u) >> 32u; return (a << 32u) >> 32u;
} }
void write_u16(char * p,u16_t w) void write_u16(char *p, u16_t w) {
{
*(unsigned char *)(p + 1) = (w & 0xff); *(unsigned char *)(p + 1) = (w & 0xff);
*(unsigned char *)(p + 0) = (w >> 8); *(unsigned char *)(p + 0) = (w >> 8);
} }
u16_t read_u16(char * p) u16_t read_u16(char *p) {
{
u16_t res; u16_t res;
res = *(const unsigned char *)(p + 0); res = *(const unsigned char *)(p + 0);
res = *(const unsigned char *)(p + 1) + (res << 8); res = *(const unsigned char *)(p + 1) + (res << 8);
return res; return res;
} }
void write_u32(char * p,u32_t l) void write_u32(char *p, u32_t l) {
{
*(unsigned char *)(p + 3) = (unsigned char)((l >> 0) & 0xff); *(unsigned char *)(p + 3) = (unsigned char)((l >> 0) & 0xff);
*(unsigned char *)(p + 2) = (unsigned char)((l >> 8) & 0xff); *(unsigned char *)(p + 2) = (unsigned char)((l >> 8) & 0xff);
*(unsigned char *)(p + 1) = (unsigned char)((l >> 16) & 0xff); *(unsigned char *)(p + 1) = (unsigned char)((l >> 16) & 0xff);
*(unsigned char *)(p + 0) = (unsigned char)((l >> 24) & 0xff); *(unsigned char *)(p + 0) = (unsigned char)((l >> 24) & 0xff);
} }
u32_t read_u32(char * p) u32_t read_u32(char *p) {
{
u32_t res; u32_t res;
res = *(const unsigned char *)(p + 0); res = *(const unsigned char *)(p + 0);
res = *(const unsigned char *)(p + 1) + (res << 8); res = *(const unsigned char *)(p + 1) + (res << 8);
@@ -568,26 +488,21 @@ u32_t read_u32(char * p)
return res; return res;
} }
void write_u64(char * s,u64_t a) void write_u64(char *s, u64_t a) {
{
assert(0 == 1); assert(0 == 1);
} }
u64_t read_u64(char * s) u64_t read_u64(char *s) {
{
assert(0 == 1); assert(0 == 1);
return 0; return 0;
} }
char *my_ntoa(u32_t ip) {
char * my_ntoa(u32_t ip)
{
in_addr a; in_addr a;
a.s_addr = ip; a.s_addr = ip;
return inet_ntoa(a); return inet_ntoa(a);
} }
u64_t get_fake_random_number_64() u64_t get_fake_random_number_64() {
{
// u64_t ret; // u64_t ret;
// int size=read(random_fd.get_fd(),&ret,sizeof(ret)); // int size=read(random_fd.get_fd(),&ret,sizeof(ret));
// if(size!=sizeof(ret)) // if(size!=sizeof(ret))
@@ -599,8 +514,7 @@ u64_t get_fake_random_number_64()
return my_random.gen64(); return my_random.gen64();
} }
u32_t get_fake_random_number() u32_t get_fake_random_number() {
{
// u32_t ret; // u32_t ret;
// int size=read(random_fd.get_fd(),&ret,sizeof(ret)); // int size=read(random_fd.get_fd(),&ret,sizeof(ret));
// if(size!=sizeof(ret)) // if(size!=sizeof(ret))
@@ -613,8 +527,7 @@ u32_t get_fake_random_number()
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; u32_t ret = 0;
while(ret==0) while (ret == 0) {
{
ret = get_fake_random_number(); ret = get_fake_random_number();
} }
return ret; return ret;
@@ -692,7 +605,6 @@ unsigned short csum(const unsigned short *ptr,int nbytes) {
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; long sum;
@@ -701,12 +613,10 @@ unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int n
sum = 0; sum = 0;
unsigned short *tmp = (unsigned short *)&ph; unsigned short *tmp = (unsigned short *)&ph;
for(int i=0;i<6;i++) for (int i = 0; i < 6; i++) {
{
sum += *tmp++; sum += *tmp++;
} }
while (nbytes > 1) { while (nbytes > 1) {
sum += *ptr++; sum += *ptr++;
nbytes -= 2; nbytes -= 2;
@@ -724,30 +634,25 @@ unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int n
return (answer); return (answer);
} }
int set_buf_size(int fd,int socket_buf_size) 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) {
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()); mylog(log_fatal, "SO_SNDBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, get_sock_error());
myexit(1); myexit(1);
} }
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0) 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()); mylog(log_fatal, "SO_RCVBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, get_sock_error());
myexit(1); myexit(1);
} }
return 0; return 0;
} }
void myexit(int a) void myexit(int a) {
{
if (enable_log_color) if (enable_log_color)
printf("%s\n", RESET); printf("%s\n", RESET);
// clear_iptables_rule(); // clear_iptables_rule();
exit(a); exit(a);
} }
void signal_handler(int sig) void signal_handler(int sig) {
{
about_to_exit = 1; about_to_exit = 1;
// myexit(0); // myexit(0);
} }
@@ -780,7 +685,6 @@ int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
} }
*/ */
/* /*
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)
{ {
@@ -840,41 +744,32 @@ int create_new_udp(int &new_udp_fd,int remote_address_uint32,int remote_port)
return 0; return 0;
}*/ }*/
int round_up_div(int a,int b) int round_up_div(int a, int b) {
{
return (a + b - 1) / b; return (a + b - 1) / b;
} }
int create_fifo(char * file) int create_fifo(char *file) {
{
#if !defined(__MINGW32__) #if !defined(__MINGW32__)
if(mkfifo (file, 0666)!=0) if (mkfifo(file, 0666) != 0) {
{ if (errno == EEXIST) {
if(errno==EEXIST)
{
mylog(log_warn, "warning fifo file %s exist\n", file); mylog(log_warn, "warning fifo file %s exist\n", file);
} } else {
else
{
mylog(log_fatal, "create fifo file %s failed\n", file); mylog(log_fatal, "create fifo file %s failed\n", file);
myexit(-1); myexit(-1);
} }
} }
int fifo_fd = open(file, O_RDWR); int fifo_fd = open(file, O_RDWR);
if(fifo_fd<0) if (fifo_fd < 0) {
{
mylog(log_fatal, "create fifo file %s failed\n", file); mylog(log_fatal, "create fifo file %s failed\n", file);
myexit(-1); myexit(-1);
} }
struct stat st; struct stat st;
if (fstat(fifo_fd, &st)!=0) if (fstat(fifo_fd, &st) != 0) {
{
mylog(log_fatal, "fstat failed for fifo file %s\n", file); mylog(log_fatal, "fstat failed for fifo file %s\n", file);
myexit(-1); myexit(-1);
} }
if(!S_ISFIFO(st.st_mode)) if (!S_ISFIFO(st.st_mode)) {
{
mylog(log_fatal, "%s is not a fifo\n", file); mylog(log_fatal, "%s is not a fifo\n", file);
myexit(-1); myexit(-1);
} }
@@ -946,8 +841,7 @@ int new_connected_socket(int &fd,u32_t ip,int port)
return 0; return 0;
} }
*/ */
int new_listen_socket2(int &fd,address_t &addr) int new_listen_socket2(int &fd, address_t &addr) {
{
fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP); fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
int yes = 1; int yes = 1;
@@ -964,8 +858,7 @@ int new_listen_socket2(int &fd,address_t &addr)
return 0; return 0;
} }
int new_connected_socket2(int &fd,address_t &addr,address_t *bind_addr,char * interface_string) 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); fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) { if (fd < 0) {
mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str()); mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str());
@@ -999,14 +892,11 @@ int new_connected_socket2(int &fd,address_t &addr,address_t *bind_addr,char * in
return 0; return 0;
} }
u32_t djb2(unsigned char *str, int len) {
u32_t djb2(unsigned char *str,int len)
{
u32_t hash = 5381; u32_t hash = 5381;
int c; int c;
int i=0; for (int i=0; i<len ;i++) {
while(c = *str++,i++!=len) c = *(str++);
{
hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */ hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */
} }
@@ -1014,25 +904,23 @@ u32_t djb2(unsigned char *str,int len)
return hash; return hash;
} }
u32_t sdbm(unsigned char *str,int len) u32_t sdbm(unsigned char *str, int len) {
{
u32_t hash = 0; u32_t hash = 0;
int c; int c;
int i=0; for (int i=0; i<len ;i++) {
while(c = *str++,i++!=len) c = *(str++);
{
hash = c + (hash << 6) + (hash << 16) - hash; hash = c + (hash << 6) + (hash << 16) - hash;
} }
// hash=htonl(hash); // hash=htonl(hash);
return hash; return hash;
} }
vector<string> string_to_vec(const char *s, const char *sp) { vector<string> string_to_vec(const char *s, const char *sp) {
vector<string> res; vector<string> res;
string str = s; string str = s;
char *p = strtok((char *)str.c_str(), sp); char *p = strtok((char *)str.c_str(), sp);
while (p != NULL) while (p != NULL) {
{
res.push_back(p); res.push_back(p);
// printf ("%s\n",p); // printf ("%s\n",p);
p = strtok(NULL, sp); p = strtok(NULL, sp);
@@ -1044,4 +932,3 @@ vector<string> string_to_vec(const char * s,const char * sp) {
}*/ }*/
return res; return res;
} }

169
common.h
View File

@@ -51,7 +51,6 @@ typedef int socklen_t;
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <map> #include <map>
@@ -60,7 +59,6 @@ typedef int socklen_t;
#include <vector> #include <vector>
using namespace std; 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 long long i64_t;
@@ -70,7 +68,6 @@ typedef int i32_t;
typedef unsigned short u16_t; typedef unsigned short u16_t;
typedef short i16_t; typedef short i16_t;
#if defined(__MINGW32__) #if defined(__MINGW32__)
int inet_pton(int af, const char *src, void *dst); int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
@@ -83,20 +80,17 @@ int init_ws();
#if defined(__MINGW32__) #if defined(__MINGW32__)
typedef SOCKET my_fd_t; typedef SOCKET my_fd_t;
inline int sock_close(my_fd_t fd) inline int sock_close(my_fd_t fd) {
{
return closesocket(fd); return closesocket(fd);
} }
#else #else
typedef int my_fd_t; typedef int my_fd_t;
inline int sock_close(my_fd_t fd) inline int sock_close(my_fd_t fd) {
{
return close(fd); return close(fd);
} }
#endif #endif
struct my_itimerspec { struct my_itimerspec {
struct timespec it_interval; /* Timer interval */ struct timespec it_interval; /* Timer interval */
struct timespec it_value; /* Initial expiration */ struct timespec it_value; /* Initial expiration */
@@ -136,7 +130,6 @@ const int conn_clear_min=1;
const u32_t conv_clear_interval = 1000; const u32_t conv_clear_interval = 1000;
const u32_t conn_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;
@@ -152,21 +145,26 @@ 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 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 server_conn_timeout = conv_timeout + 20000; // for test
extern int about_to_exit; 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; 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 program_mode_t program_mode;
extern unordered_map<int, const char *> raw_mode_tostring; extern unordered_map<int, const char *> 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 working_mode_t working_mode;
extern int socket_buf_size; extern int socket_buf_size;
// typedef u32_t id_t; // typedef u32_t id_t;
typedef u64_t iv_t; typedef u64_t iv_t;
@@ -178,7 +176,12 @@ typedef u64_t anti_replay_seq_t;
typedef u64_t fd64_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_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_addr,
type_fd64,
type_fd,
type_write_fd,
type_fd_addr /*,type_fd*/ };
/* /*
struct ip_port_t struct ip_port_t
@@ -201,7 +204,6 @@ struct fd_ip_port_t
ip_port_t ip_port; ip_port_t ip_port;
};*/ };*/
struct pseudo_header { struct pseudo_header {
u32_t source_address; u32_t source_address;
u32_t dest_address; u32_t dest_address;
@@ -215,10 +217,8 @@ u32_t sdbm(unsigned char *str,int len);
struct address_t // TODO scope id struct address_t // TODO scope id
{ {
struct hash_function struct hash_function {
{ u32_t operator()(const address_t &key) const {
u32_t operator()(const address_t &key) const
{
return sdbm((unsigned char *)&key.inner, sizeof(key.inner)); return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
} }
}; };
@@ -234,8 +234,7 @@ struct address_t //TODO scope id
{ {
clear(); clear();
}*/ }*/
void clear() void clear() {
{
memset(&inner, 0, sizeof(inner)); memset(&inner, 0, sizeof(inner));
} }
/* /*
@@ -248,17 +247,13 @@ struct address_t //TODO scope id
return 0; return 0;
}*/ }*/
int from_ip_port_new(int type, void * ip, int port) int from_ip_port_new(int type, void *ip, int port) {
{
clear(); clear();
if(type==AF_INET) if (type == AF_INET) {
{
inner.ipv4.sin_family = AF_INET; inner.ipv4.sin_family = AF_INET;
inner.ipv4.sin_port = htons(port); inner.ipv4.sin_port = htons(port);
inner.ipv4.sin_addr.s_addr = *((u32_t *)ip); inner.ipv4.sin_addr.s_addr = *((u32_t *)ip);
} } else if (type == AF_INET6) {
else if(type==AF_INET6)
{
inner.ipv6.sin6_family = AF_INET6; inner.ipv6.sin6_family = AF_INET6;
inner.ipv6.sin6_port = htons(port); inner.ipv6.sin6_port = htons(port);
inner.ipv6.sin6_addr = *((in6_addr *)ip); inner.ipv6.sin6_addr = *((in6_addr *)ip);
@@ -275,24 +270,20 @@ struct address_t //TODO scope id
char *get_str(); char *get_str();
void to_str(char *); void to_str(char *);
inline int is_vaild() inline int is_vaild() {
{
u32_t ret = ((sockaddr *)&inner)->sa_family; u32_t ret = ((sockaddr *)&inner)->sa_family;
return (ret == AF_INET || ret == AF_INET6); return (ret == AF_INET || ret == AF_INET6);
} }
inline u32_t get_type() inline u32_t get_type() {
{
assert(is_vaild()); assert(is_vaild());
u32_t ret = ((sockaddr *)&inner)->sa_family; u32_t ret = ((sockaddr *)&inner)->sa_family;
return ret; return ret;
} }
inline u32_t get_len() inline u32_t get_len() {
{
u32_t type = get_type(); u32_t type = get_type();
switch(type) switch (type) {
{
case AF_INET: case AF_INET:
return sizeof(sockaddr_in); return sizeof(sockaddr_in);
case AF_INET6: case AF_INET6:
@@ -303,11 +294,9 @@ struct address_t //TODO scope id
return -1; return -1;
} }
inline u32_t get_port() inline u32_t get_port() {
{
u32_t type = get_type(); u32_t type = get_type();
switch(type) switch (type) {
{
case AF_INET: case AF_INET:
return ntohs(inner.ipv4.sin_port); return ntohs(inner.ipv4.sin_port);
case AF_INET6: case AF_INET6:
@@ -318,11 +307,9 @@ struct address_t //TODO scope id
return -1; return -1;
} }
inline void set_port(int port) inline void set_port(int port) {
{
u32_t type = get_type(); u32_t type = get_type();
switch(type) switch (type) {
{
case AF_INET: case AF_INET:
inner.ipv4.sin_port = htons(port); inner.ipv4.sin_port = htons(port);
break; break;
@@ -335,8 +322,7 @@ struct address_t //TODO scope id
return; return;
} }
bool operator == (const address_t &b) const bool operator==(const address_t &b) const {
{
// return this->data==b.data; // return this->data==b.data;
return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0; return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0;
} }
@@ -348,44 +334,36 @@ struct address_t //TODO scope id
namespace std { namespace std {
template <> template <>
struct hash<address_t> struct hash<address_t> {
{ std::size_t operator()(const address_t &key) const {
std::size_t operator()(const address_t& key) const
{
// return address_t::hash_function(k); // return address_t::hash_function(k);
return sdbm((unsigned char *)&key.inner, sizeof(key.inner)); return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
} }
}; };
} } // namespace std
struct fd64_addr_t struct fd64_addr_t {
{
fd64_t fd64; fd64_t fd64;
address_t addr; address_t addr;
}; };
struct fd_addr_t struct fd_addr_t {
{
int fd; int fd;
address_t addr; address_t addr;
}; };
union inner_t union inner_t {
{
fd64_t fd64; fd64_t fd64;
int fd; int fd;
fd64_addr_t fd64_addr; fd64_addr_t fd64_addr;
fd_addr_t fd_addr; fd_addr_t fd_addr;
}; };
struct dest_t struct dest_t {
{
dest_type type; dest_type type;
inner_t inner; inner_t inner;
u32_t conv; u32_t conv;
int cook = 0; int cook = 0;
}; };
struct fd_info_t struct fd_info_t {
{
address_t addr; address_t addr;
ev_io io_watcher; ev_io io_watcher;
}; };
@@ -453,31 +431,23 @@ int new_connected_socket(int &fd,u32_t ip,int port);
int new_listen_socket2(int &fd, address_t &addr); 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_connected_socket2(int &fd, address_t &addr, address_t *bind_addr, char *out_interface);
struct not_copy_able_t struct not_copy_able_t {
{ not_copy_able_t() {
not_copy_able_t()
{
} }
not_copy_able_t(const not_copy_able_t &other) not_copy_able_t(const not_copy_able_t &other) {
{
assert(0 == 1); assert(0 == 1);
} }
const not_copy_able_t & operator=(const not_copy_able_t &other) const not_copy_able_t &operator=(const not_copy_able_t &other) {
{
assert(0 == 1); assert(0 == 1);
return other; return other;
} }
}; };
template <class key_t> template <class key_t>
struct lru_collector_t:not_copy_able_t struct lru_collector_t : not_copy_able_t {
{
// typedef void* key_t; // typedef void* key_t;
//#define key_t void* //#define key_t void*
struct lru_pair_t struct lru_pair_t {
{
key_t key; key_t key;
my_time_t ts; my_time_t ts;
}; };
@@ -485,65 +455,61 @@ struct lru_collector_t:not_copy_able_t
unordered_map<key_t, typename list<lru_pair_t>::iterator> mp; unordered_map<key_t, typename list<lru_pair_t>::iterator> mp;
list<lru_pair_t> q; list<lru_pair_t> q;
int update(key_t key) int update(key_t key) {
{
assert(mp.find(key) != mp.end()); assert(mp.find(key) != mp.end());
auto it = mp[key]; auto it = mp[key];
q.erase(it); q.erase(it);
my_time_t value = get_current_time(); my_time_t value = get_current_time();
if(!q.empty()) if (!q.empty()) {
{
assert(value >= q.front().ts); assert(value >= q.front().ts);
} }
lru_pair_t tmp; tmp.key=key; tmp.ts=value; lru_pair_t tmp;
tmp.key = key;
tmp.ts = value;
q.push_front(tmp); q.push_front(tmp);
mp[key] = q.begin(); mp[key] = q.begin();
return 0; return 0;
} }
int new_key(key_t key) int new_key(key_t key) {
{
assert(mp.find(key) == mp.end()); assert(mp.find(key) == mp.end());
my_time_t value = get_current_time(); my_time_t value = get_current_time();
if(!q.empty()) if (!q.empty()) {
{
assert(value >= q.front().ts); assert(value >= q.front().ts);
} }
lru_pair_t tmp; tmp.key=key; tmp.ts=value; lru_pair_t tmp;
tmp.key = key;
tmp.ts = value;
q.push_front(tmp); q.push_front(tmp);
mp[key] = q.begin(); mp[key] = q.begin();
return 0; return 0;
} }
int size() int size() {
{
return q.size(); return q.size();
} }
int empty() int empty() {
{
return q.empty(); return q.empty();
} }
void clear() void clear() {
{ mp.clear();
mp.clear(); q.clear(); q.clear();
} }
my_time_t ts_of(key_t key) my_time_t ts_of(key_t key) {
{
assert(mp.find(key) != mp.end()); assert(mp.find(key) != mp.end());
return mp[key]->ts; return mp[key]->ts;
} }
my_time_t peek_back(key_t &key) my_time_t peek_back(key_t &key) {
{
assert(!q.empty()); assert(!q.empty());
auto it=q.end(); it--; auto it = q.end();
it--;
key = it->key; key = it->key;
return it->ts; return it->ts;
} }
void erase(key_t key) void erase(key_t key) {
{
assert(mp.find(key) != mp.end()); assert(mp.find(key) != mp.end());
q.erase(mp[key]); q.erase(mp[key]);
mp.erase(key); mp.erase(key);
@@ -558,7 +524,6 @@ struct lru_collector_t:not_copy_able_t
}*/ }*/
}; };
vector<string> string_to_vec(const char *s, const char *sp); vector<string> string_to_vec(const char *s, const char *sp);
#endif /* COMMON_H_ */ #endif /* COMMON_H_ */

View File

@@ -27,22 +27,16 @@ void server_clear_function(u64_t u64)//used in conv_manager in server mode.for s
ev_io_stop(loop, &watcher); ev_io_stop(loop, &watcher);
fd_manager.fd64_close(fd64); fd_manager.fd64_close(fd64);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
conn_manager_t::conn_manager_t() conn_manager_t::conn_manager_t() {
{
mp.reserve(10007); mp.reserve(10007);
last_clear_time = 0; last_clear_time = 0;
} }
int conn_manager_t::exist(address_t addr) int conn_manager_t::exist(address_t addr) {
{ if (mp.find(addr) != mp.end()) {
if(mp.find(addr)!=mp.end())
{
return 1; return 1;
} }
return 0; return 0;
@@ -55,13 +49,10 @@ conn_info_t *& conn_manager_t::find_insert_p(address_t addr) //be aware,the adr
// u64<<=32u; // u64<<=32u;
// u64|=port; // u64|=port;
unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr); unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr);
if(it==mp.end()) if (it == mp.end()) {
{
mp[addr] = new conn_info_t; mp[addr] = new conn_info_t;
// lru.new_key(addr); // lru.new_key(addr);
} } else {
else
{
// lru.update(addr); // lru.update(addr);
} }
return mp[addr]; return mp[addr];
@@ -73,35 +64,28 @@ conn_info_t & conn_manager_t::find_insert(address_t addr) //be aware,the adress
// u64<<=32u; // u64<<=32u;
// u64|=port; // u64|=port;
unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr); unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr);
if(it==mp.end()) if (it == mp.end()) {
{
mp[addr] = new conn_info_t; mp[addr] = new conn_info_t;
// lru.new_key(addr); // lru.new_key(addr);
} } else {
else
{
// lru.update(addr); // lru.update(addr);
} }
return *mp[addr]; return *mp[addr];
} }
int conn_manager_t::erase(unordered_map<address_t,conn_info_t*>::iterator erase_it) int conn_manager_t::erase(unordered_map<address_t, conn_info_t *>::iterator erase_it) {
{
delete (erase_it->second); delete (erase_it->second);
mp.erase(erase_it->first); mp.erase(erase_it->first);
return 0; return 0;
} }
int conn_manager_t::clear_inactive() int conn_manager_t::clear_inactive() {
{ if (get_current_time() - last_clear_time > conn_clear_interval) {
if(get_current_time()-last_clear_time>conn_clear_interval)
{
last_clear_time = get_current_time(); last_clear_time = get_current_time();
return clear_inactive0(); return clear_inactive0();
} }
return 0; return 0;
} }
int conn_manager_t::clear_inactive0() int conn_manager_t::clear_inactive0() {
{
// mylog(log_info,"called\n"); // mylog(log_info,"called\n");
unordered_map<address_t, conn_info_t *>::iterator it; unordered_map<address_t, conn_info_t *>::iterator it;
unordered_map<address_t, conn_info_t *>::iterator old_it; unordered_map<address_t, conn_info_t *>::iterator old_it;
@@ -120,26 +104,19 @@ int conn_manager_t::clear_inactive0()
u64_t current_time = get_current_time(); u64_t current_time = get_current_time();
// mylog(log_info,"here size=%d\n",(int)mp.size()); // mylog(log_info,"here size=%d\n",(int)mp.size());
for(;;) for (;;) {
{
if (cnt >= num_to_clean) break; if (cnt >= num_to_clean) break;
if (mp.begin() == mp.end()) break; if (mp.begin() == mp.end()) break;
if(it==mp.end()) if (it == mp.end()) {
{
it = mp.begin(); it = mp.begin();
} }
if(it->second->conv_manager.s.get_size() >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()); // 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++; it++;
} } else if (current_time < it->second->last_active_time + server_conn_timeout) {
else if(current_time<it->second->last_active_time+server_conn_timeout)
{
it++; it++;
} } else {
else
{
address_t tmp_addr = it->first; // avoid making get_str() const; address_t tmp_addr = it->first; // avoid making get_str() const;
mylog(log_info, "{%s} inactive conn cleared \n", tmp_addr.get_str()); mylog(log_info, "{%s} inactive conn cleared \n", tmp_addr.get_str());
old_it = it; old_it = it;

View File

@@ -39,36 +39,29 @@ struct conv_manager_t // manage the udp connections
long long last_clear_time; long long last_clear_time;
conv_manager_t() conv_manager_t() {
{
// clear_it=conv_last_active_time.begin(); // clear_it=conv_last_active_time.begin();
long long last_clear_time = 0; long long last_clear_time = 0;
additional_clear_function = 0; additional_clear_function = 0;
} }
~conv_manager_t() ~conv_manager_t() {
{
clear(); clear();
} }
int get_size() int get_size() {
{
return conv_to_data.size(); return conv_to_data.size();
} }
void reserve() void reserve() {
{
data_to_conv.reserve(10007); data_to_conv.reserve(10007);
conv_to_data.reserve(10007); conv_to_data.reserve(10007);
// conv_last_active_time.reserve(10007); // conv_last_active_time.reserve(10007);
lru.mp.reserve(10007); lru.mp.reserve(10007);
} }
void clear() void clear() {
{
if (disable_conv_clear) return; if (disable_conv_clear) return;
if(additional_clear_function!=0) if (additional_clear_function != 0) {
{ for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) {
for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++)
{
// int fd=int((it->second<<32u)>>32u); // int fd=int((it->second<<32u)>>32u);
additional_clear_function(it->second); additional_clear_function(it->second);
} }
@@ -80,53 +73,42 @@ struct conv_manager_t // manage the udp connections
// conv_last_active_time.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 get_new_conv() {
{
u32_t conv = get_fake_random_number_nz(); u32_t conv = get_fake_random_number_nz();
while(conv_to_data.find(conv)!=conv_to_data.end()) while (conv_to_data.find(conv) != conv_to_data.end()) {
{
conv = get_fake_random_number_nz(); conv = get_fake_random_number_nz();
} }
return conv; return conv;
} }
int is_conv_used(u32_t conv) int is_conv_used(u32_t conv) {
{
return conv_to_data.find(conv) != conv_to_data.end(); return conv_to_data.find(conv) != conv_to_data.end();
} }
int is_data_used(T data) int is_data_used(T data) {
{
return data_to_conv.find(data) != data_to_conv.end(); return data_to_conv.find(data) != data_to_conv.end();
} }
u32_t find_conv_by_data(T data) u32_t find_conv_by_data(T data) {
{
return data_to_conv[data]; return data_to_conv[data];
} }
T find_data_by_conv(u32_t conv) T find_data_by_conv(u32_t conv) {
{
return conv_to_data[conv]; return conv_to_data[conv];
} }
int update_active_time(u32_t conv) int update_active_time(u32_t conv) {
{
// return conv_last_active_time[conv]=get_current_time(); // return conv_last_active_time[conv]=get_current_time();
lru.update(conv); lru.update(conv);
return 0; return 0;
} }
int insert_conv(u32_t conv,T data) int insert_conv(u32_t conv, T data) {
{
data_to_conv[data] = conv; data_to_conv[data] = conv;
conv_to_data[conv] = data; conv_to_data[conv] = data;
// conv_last_active_time[conv]=get_current_time(); // conv_last_active_time[conv]=get_current_time();
lru.new_key(conv); lru.new_key(conv);
return 0; return 0;
} }
int erase_conv(u32_t conv) int erase_conv(u32_t conv) {
{
if (disable_conv_clear) return 0; if (disable_conv_clear) return 0;
T data = conv_to_data[conv]; T data = conv_to_data[conv];
if(additional_clear_function!=0) if (additional_clear_function != 0) {
{
additional_clear_function(data); additional_clear_function(data);
} }
conv_to_data.erase(conv); conv_to_data.erase(conv);
@@ -135,20 +117,16 @@ struct conv_manager_t // manage the udp connections
lru.erase(conv); lru.erase(conv);
return 0; return 0;
} }
int clear_inactive(char * info=0) int clear_inactive(char *info = 0) {
{ if (get_current_time() - last_clear_time > conv_clear_interval) {
if(get_current_time()-last_clear_time>conv_clear_interval)
{
last_clear_time = get_current_time(); last_clear_time = get_current_time();
return clear_inactive0(info); return clear_inactive0(info);
} }
return 0; return 0;
} }
int clear_inactive0(char * info) int clear_inactive0(char *info) {
{
if (disable_conv_clear) return 0; if (disable_conv_clear) return 0;
unordered_map<u32_t, u64_t>::iterator it; unordered_map<u32_t, u64_t>::iterator it;
unordered_map<u32_t, u64_t>::iterator old_it; unordered_map<u32_t, u64_t>::iterator old_it;
@@ -161,8 +139,7 @@ struct conv_manager_t // manage the udp connections
num_to_clean = min(num_to_clean, size); num_to_clean = min(num_to_clean, size);
my_time_t current_time = get_current_time(); my_time_t current_time = get_current_time();
for(;;) for (;;) {
{
if (cnt >= num_to_clean) break; if (cnt >= num_to_clean) break;
if (lru.empty()) break; if (lru.empty()) break;
@@ -172,12 +149,9 @@ struct conv_manager_t // manage the udp connections
if (current_time - ts < conv_timeout) break; if (current_time - ts < conv_timeout) break;
erase_conv(conv); erase_conv(conv);
if(info==0) if (info == 0) {
{
mylog(log_info, "conv %x cleared\n", conv); mylog(log_info, "conv %x cleared\n", conv);
} } else {
else
{
mylog(log_info, "[%s]conv %x cleared\n", info, conv); mylog(log_info, "[%s]conv %x cleared\n", info, conv);
} }
cnt++; cnt++;
@@ -185,7 +159,6 @@ struct conv_manager_t // manage the udp connections
return 0; return 0;
} }
/* /*
conv_manager_t(); conv_manager_t();
~conv_manager_t(); ~conv_manager_t();
@@ -204,89 +177,70 @@ struct conv_manager_t // manage the udp connections
int clear_inactive0(char * ip_port);*/ int clear_inactive0(char * ip_port);*/
}; // g_conv_manager; }; // g_conv_manager;
struct inner_stat_t {
struct inner_stat_t
{
u64_t input_packet_num; u64_t input_packet_num;
u64_t input_packet_size; u64_t input_packet_size;
u64_t output_packet_num; u64_t output_packet_num;
u64_t output_packet_size; u64_t output_packet_size;
}; };
struct stat_t struct stat_t {
{
u64_t last_report_time; u64_t last_report_time;
inner_stat_t normal_to_fec; inner_stat_t normal_to_fec;
inner_stat_t fec_to_normal; inner_stat_t fec_to_normal;
stat_t() stat_t() {
{ clear();
}
void clear(){
memset(this, 0, sizeof(stat_t)); memset(this, 0, sizeof(stat_t));
} }
void report_as_client() void report_as_client() {
{ if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) {
if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000)
{
last_report_time = get_current_time(); last_report_time = get_current_time();
inner_stat_t &a = normal_to_fec; inner_stat_t &a = normal_to_fec;
inner_stat_t &b = fec_to_normal; 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", 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, 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 b.output_packet_num, b.output_packet_size, b.input_packet_num, b.input_packet_size);
);
} }
} }
void report_as_server(address_t &addr) void report_as_server(address_t &addr) {
{ if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) {
if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000)
{
last_report_time = get_current_time(); last_report_time = get_current_time();
inner_stat_t &a = fec_to_normal; inner_stat_t &a = fec_to_normal;
inner_stat_t &b = normal_to_fec; 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", 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(), addr.get_str(),
a.output_packet_num, a.output_packet_size, a.input_packet_num, a.input_packet_size, 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 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 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 // handle multiple clients
{ {
union tmp_union_t union tmp_union_t {
{
conv_manager_t<address_t> c; conv_manager_t<address_t> c;
conv_manager_t<u64_t> s; conv_manager_t<u64_t> s;
// avoid templates here and there, avoid pointer and type cast // avoid templates here and there, avoid pointer and type cast
tmp_union_t() tmp_union_t() {
{ if (program_mode == client_mode) {
if(program_mode==client_mode)
{
new (&c) conv_manager_t<address_t>(); new (&c) conv_manager_t<address_t>();
} } else {
else
{
assert(program_mode == server_mode); assert(program_mode == server_mode);
new (&s) conv_manager_t<u64_t>(); new (&s) conv_manager_t<u64_t>();
} }
} }
~tmp_union_t() ~tmp_union_t() {
{ if (program_mode == client_mode) {
if(program_mode==client_mode)
{
c.~conv_manager_t<address_t>(); c.~conv_manager_t<address_t>();
} } else {
else
{
assert(program_mode == server_mode); assert(program_mode == server_mode);
s.~conv_manager_t<u64_t>(); s.~conv_manager_t<u64_t>();
} }
} }
} conv_manager; } conv_manager;
fec_encode_manager_t fec_encode_manager; fec_encode_manager_t fec_encode_manager;
fec_decode_manager_t fec_decode_manager; fec_decode_manager_t fec_decode_manager;
ev_timer timer; ev_timer timer;
@@ -304,25 +258,19 @@ struct conn_info_t:not_copy_able_t //stores info for a raw connection.for cl
// ip_port_t ip_port; // ip_port_t ip_port;
address_t addr; // only used for server address_t addr; // only used for server
conn_info_t() conn_info_t() {
{ if (program_mode == server_mode) {
if(program_mode==server_mode)
{
conv_manager.s.additional_clear_function = server_clear_function; conv_manager.s.additional_clear_function = server_clear_function;
} } else {
else
{
assert(program_mode == client_mode); assert(program_mode == client_mode);
} }
} }
~conn_info_t() ~conn_info_t() {
{
if (loop) if (loop)
ev_timer_stop(loop, &timer); ev_timer_stop(loop, &timer);
} }
void update_active_time() void update_active_time() {
{
last_active_time = get_current_time(); last_active_time = get_current_time();
} }
/* /*
@@ -357,8 +305,6 @@ struct conn_manager_t //manager for connections. for client,we dont need conn_m
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<address_t, conn_info_t *> mp; // put it at end so that it de-consturcts first unordered_map<address_t, conn_info_t *> mp; // put it at end so that it de-consturcts first
unordered_map<address_t, conn_info_t *>::iterator clear_it; unordered_map<address_t, conn_info_t *>::iterator clear_it;
@@ -372,12 +318,8 @@ struct conn_manager_t //manager for connections. for client,we dont need conn_m
int erase(unordered_map<address_t, conn_info_t *>::iterator erase_it); int erase(unordered_map<address_t, conn_info_t *>::iterator erase_it);
int clear_inactive(); int clear_inactive();
int clear_inactive0(); int clear_inactive0();
}; };
extern conn_manager_t conn_manager; extern conn_manager_t conn_manager;
#endif /* CONNECTION_H_ */ #endif /* CONNECTION_H_ */

1245
crc32/Crc32.cpp Normal file

File diff suppressed because it is too large Load Diff

69
crc32/Crc32.h Normal file
View File

@@ -0,0 +1,69 @@
// //////////////////////////////////////////////////////////
// Crc32.h
// Copyright (c) 2011-2019 Stephan Brumme. All rights reserved.
// Slicing-by-16 contributed by Bulat Ziganshin
// Tableless bytewise CRC contributed by Hagai Gold
// see http://create.stephan-brumme.com/disclaimer.html
//
// if running on an embedded system, you might consider shrinking the
// big Crc32Lookup table by undefining these lines:
#define CRC32_USE_LOOKUP_TABLE_BYTE
#define CRC32_USE_LOOKUP_TABLE_SLICING_BY_4
#define CRC32_USE_LOOKUP_TABLE_SLICING_BY_8
#define CRC32_USE_LOOKUP_TABLE_SLICING_BY_16
// - crc32_bitwise doesn't need it at all
// - crc32_halfbyte has its own small lookup table
// - crc32_1byte_tableless and crc32_1byte_tableless2 don't need it at all
// - crc32_1byte needs only Crc32Lookup[0]
// - crc32_4bytes needs only Crc32Lookup[0..3]
// - crc32_8bytes needs only Crc32Lookup[0..7]
// - crc32_4x8bytes needs only Crc32Lookup[0..7]
// - crc32_16bytes needs all of Crc32Lookup
// using the aforementioned #defines the table is automatically fitted to your needs
// uint8_t, uint32_t, int32_t
#include <stdint.h>
// size_t
#include <cstddef>
// crc32_fast selects the fastest algorithm depending on flags (CRC32_USE_LOOKUP_...)
/// compute CRC32 using the fastest algorithm for large datasets on modern CPUs
uint32_t crc32_fast (const void* data, size_t length, uint32_t previousCrc32 = 0);
/// merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA))
uint32_t crc32_combine (uint32_t crcA, uint32_t crcB, size_t lengthB);
/// compute CRC32 (bitwise algorithm)
uint32_t crc32_bitwise (const void* data, size_t length, uint32_t previousCrc32 = 0);
/// compute CRC32 (half-byte algoritm)
uint32_t crc32_halfbyte(const void* data, size_t length, uint32_t previousCrc32 = 0);
#ifdef CRC32_USE_LOOKUP_TABLE_BYTE
/// compute CRC32 (standard algorithm)
uint32_t crc32_1byte (const void* data, size_t length, uint32_t previousCrc32 = 0);
#endif
/// compute CRC32 (byte algorithm) without lookup tables
uint32_t crc32_1byte_tableless (const void* data, size_t length, uint32_t previousCrc32 = 0);
/// compute CRC32 (byte algorithm) without lookup tables
uint32_t crc32_1byte_tableless2(const void* data, size_t length, uint32_t previousCrc32 = 0);
#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_4
/// compute CRC32 (Slicing-by-4 algorithm)
uint32_t crc32_4bytes (const void* data, size_t length, uint32_t previousCrc32 = 0);
#endif
#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_8
/// compute CRC32 (Slicing-by-8 algorithm)
uint32_t crc32_8bytes (const void* data, size_t length, uint32_t previousCrc32 = 0);
/// compute CRC32 (Slicing-by-8 algorithm), unroll inner loop 4 times
uint32_t crc32_4x8bytes(const void* data, size_t length, uint32_t previousCrc32 = 0);
#endif
#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16
/// compute CRC32 (Slicing-by-16 algorithm)
uint32_t crc32_16bytes (const void* data, size_t length, uint32_t previousCrc32 = 0);
/// compute CRC32 (Slicing-by-16 algorithm, prefetch upcoming data blocks)
uint32_t crc32_16bytes_prefetch(const void* data, size_t length, uint32_t previousCrc32 = 0, size_t prefetchAhead = 256);
#endif

10
crc32/LICENSE Normal file
View File

@@ -0,0 +1,10 @@
zlib License
Copyright (c) 2011-2016 Stephan Brumme
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@@ -8,14 +8,11 @@
#include "log.h" #include "log.h"
#include "packet.h" #include "packet.h"
int delay_data_t::handle() int delay_data_t::handle() {
{
return my_send(dest, data, len) >= 0; return my_send(dest, data, len) >= 0;
} }
delay_manager_t::delay_manager_t() {
delay_manager_t::delay_manager_t()
{
capacity = 0; capacity = 0;
// if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) // if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0)
@@ -28,10 +25,8 @@ delay_manager_t::delay_manager_t()
// memset(&zero_its, 0, sizeof(zero_its)); // memset(&zero_its, 0, sizeof(zero_its));
// timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); // timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0);
} }
delay_manager_t::~delay_manager_t() delay_manager_t::~delay_manager_t() {
{
// TODO ,we currently dont need to deconstruct it // TODO ,we currently dont need to deconstruct it
} }
@@ -42,20 +37,17 @@ int delay_manager_t::get_timer_fd()
}*/ }*/
// int add(my_time_t delay,const dest_t &dest,const char *data,int 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) int delay_manager_t::add(my_time_t delay, const dest_t &dest, char *data, int len) {
{
delay_data_t delay_data; delay_data_t delay_data;
delay_data.dest = dest; delay_data.dest = dest;
// delay_data.data=data; // delay_data.data=data;
delay_data.len = len; delay_data.len = len;
if(capacity!=0&&int(delay_mp.size()) >=capacity) if (capacity != 0 && int(delay_mp.size()) >= capacity) {
{
mylog(log_warn, "max pending packet reached,ignored\n"); mylog(log_warn, "max pending packet reached,ignored\n");
return -1; return -1;
} }
if(delay==0) if (delay == 0) {
{
static char buf[buf_len]; static char buf[buf_len];
delay_data.data = buf; delay_data.data = buf;
memcpy(buf, data, len); memcpy(buf, data, len);
@@ -68,8 +60,7 @@ int delay_manager_t::add(my_time_t delay,const dest_t &dest,char *data,int len)
delay_data_t tmp = delay_data; delay_data_t tmp = delay_data;
tmp.data = (char *)malloc(delay_data.len + 100); tmp.data = (char *)malloc(delay_data.len + 100);
if(!tmp.data) if (!tmp.data) {
{
mylog(log_warn, "malloc() returned null in delay_manager_t::add()"); mylog(log_warn, "malloc() returned null in delay_manager_t::add()");
return -1; return -1;
} }
@@ -85,46 +76,36 @@ int delay_manager_t::add(my_time_t delay,const dest_t &dest,char *data,int len)
return 0; return 0;
} }
int delay_manager_t::check() int delay_manager_t::check() {
{ if (!delay_mp.empty()) {
if(!delay_mp.empty())
{
my_time_t current_time; my_time_t current_time;
multimap<my_time_t, delay_data_t>::iterator it; multimap<my_time_t, delay_data_t>::iterator it;
while(1) while (1) {
{
int ret = 0; int ret = 0;
it = delay_mp.begin(); it = delay_mp.begin();
if (it == delay_mp.end()) break; if (it == delay_mp.end()) break;
current_time = get_current_time_us(); current_time = get_current_time_us();
if(it->first <= current_time) if (it->first <= current_time) {
{
ret = it->second.handle(); ret = it->second.handle();
if (ret != 0) { if (ret != 0) {
mylog(log_trace, "handle() return %d\n", ret); mylog(log_trace, "handle() return %d\n", ret);
} }
free(it->second.data); free(it->second.data);
delay_mp.erase(it); delay_mp.erase(it);
} } else {
else
{
break; break;
} }
} }
if(!delay_mp.empty()) if (!delay_mp.empty()) {
{
const double m = 1000 * 1000; 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 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 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_stop(loop, &timer);
ev_timer_set(&timer, timer_value, 0); ev_timer_set(&timer, timer_value, 0);
ev_timer_start(loop, &timer); ev_timer_start(loop, &timer);
} } else {
else
{
ev_timer_stop(loop, &timer); // not necessary ev_timer_stop(loop, &timer); // not necessary
} }
} }

View File

@@ -103,9 +103,7 @@ struct my_timer_t
} }
};*/ };*/
struct delay_data_t {
struct delay_data_t
{
dest_t dest; dest_t dest;
// int left_time;// // int left_time;//
char *data; char *data;
@@ -113,8 +111,7 @@ struct delay_data_t
int handle(); int handle();
}; };
struct delay_manager_t struct delay_manager_t {
{
ev_timer timer; ev_timer timer;
struct ev_loop *loop = 0; struct ev_loop *loop = 0;
void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0; void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0;
@@ -123,17 +120,18 @@ struct delay_manager_t
int capacity; int capacity;
multimap<my_time_t, delay_data_t> delay_mp; // unit us,1 us=0.001ms multimap<my_time_t, delay_data_t> delay_mp; // unit us,1 us=0.001ms
delay_manager_t(); delay_manager_t();
delay_manager_t(delay_manager_t &b) delay_manager_t(delay_manager_t &b) {
{
assert(0 == 1); assert(0 == 1);
} }
void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)) 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->loop = loop;
this->cb = cb; this->cb = cb;
ev_init(&timer, cb); ev_init(&timer, cb);
} }
int set_capacity(int a){capacity=a;return 0;} int set_capacity(int a) {
capacity = a;
return 0;
}
~delay_manager_t(); ~delay_manager_t();
ev_timer &get_timer(); ev_timer &get_timer();
int check(); int check();

View File

@@ -5,59 +5,48 @@
* Author: root * Author: root
*/ */
#include "fd_manager.h" #include "fd_manager.h"
int fd_manager_t::fd_exist(int fd) int fd_manager_t::fd_exist(int fd) {
{
return fd_to_fd64_mp.find(fd) != fd_to_fd64_mp.end(); return fd_to_fd64_mp.find(fd) != fd_to_fd64_mp.end();
} }
int fd_manager_t::exist(fd64_t fd64) int fd_manager_t::exist(fd64_t fd64) {
{
return fd64_to_fd_mp.find(fd64) != fd64_to_fd_mp.end(); return fd64_to_fd_mp.find(fd64) != fd64_to_fd_mp.end();
} }
int fd_manager_t::to_fd(fd64_t fd64) int fd_manager_t::to_fd(fd64_t fd64) {
{
assert(exist(fd64)); assert(exist(fd64));
return fd64_to_fd_mp[fd64]; return fd64_to_fd_mp[fd64];
} }
void fd_manager_t::fd64_close(fd64_t fd64) void fd_manager_t::fd64_close(fd64_t fd64) {
{
assert(exist(fd64)); assert(exist(fd64));
int fd = fd64_to_fd_mp[fd64]; int fd = fd64_to_fd_mp[fd64];
fd64_to_fd_mp.erase(fd64); fd64_to_fd_mp.erase(fd64);
fd_to_fd64_mp.erase(fd); fd_to_fd64_mp.erase(fd);
if(exist_info(fd64)) if (exist_info(fd64)) {
{
fd_info_mp.erase(fd64); fd_info_mp.erase(fd64);
} }
sock_close(fd); sock_close(fd);
} }
void fd_manager_t::reserve(int n) void fd_manager_t::reserve(int n) {
{
fd_to_fd64_mp.reserve(n); fd_to_fd64_mp.reserve(n);
fd64_to_fd_mp.reserve(n); fd64_to_fd_mp.reserve(n);
fd_info_mp.reserve(n); fd_info_mp.reserve(n);
} }
u64_t fd_manager_t::create(int fd) u64_t fd_manager_t::create(int fd) {
{
assert(!fd_exist(fd)); assert(!fd_exist(fd));
fd64_t fd64 = counter++; fd64_t fd64 = counter++;
fd_to_fd64_mp[fd] = fd64; fd_to_fd64_mp[fd] = fd64;
fd64_to_fd_mp[fd64] = fd; fd64_to_fd_mp[fd64] = fd;
return fd64; return fd64;
} }
fd_manager_t::fd_manager_t() fd_manager_t::fd_manager_t() {
{
counter = u32_t(-1); counter = u32_t(-1);
counter += 100; counter += 100;
reserve(10007); reserve(10007);
} }
fd_info_t & fd_manager_t::get_info(fd64_t fd64) fd_info_t& fd_manager_t::get_info(fd64_t fd64) {
{
assert(exist(fd64)); assert(exist(fd64));
return fd_info_mp[fd64]; return fd_info_mp[fd64];
} }
int fd_manager_t::exist_info(fd64_t fd64) int fd_manager_t::exist_info(fd64_t fd64) {
{
return fd_info_mp.find(fd64) != fd_info_mp.end(); return fd_info_mp.find(fd64) != fd_info_mp.end();
} }

View File

@@ -11,8 +11,6 @@
#include "common.h" #include "common.h"
#include "packet.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 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 // this class is not strictly necessary,it just makes epoll fd handling easier
{ {
@@ -24,6 +22,7 @@ struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict
void reserve(int n); void reserve(int n);
u64_t create(int fd); u64_t create(int fd);
fd_manager_t(); fd_manager_t();
private: private:
u64_t counter; u64_t counter;
unordered_map<int, fd64_t> fd_to_fd64_mp; unordered_map<int, fd64_t> fd_to_fd64_mp;

View File

@@ -32,34 +32,27 @@ 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() {
blob_encode_t::blob_encode_t()
{
clear(); clear();
} }
int blob_encode_t::clear() int blob_encode_t::clear() {
{
counter = 0; counter = 0;
current_len = (int)sizeof(u32_t); current_len = (int)sizeof(u32_t);
return 0; return 0;
} }
int blob_encode_t::get_num() int blob_encode_t::get_num() {
{
return counter; return counter;
} }
int blob_encode_t::get_shard_len(int n) int blob_encode_t::get_shard_len(int n) {
{
return round_up_div(current_len, n); return round_up_div(current_len, n);
} }
int blob_encode_t::get_shard_len(int n,int next_packet_len) 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); return round_up_div(current_len + (int)sizeof(u16_t) + next_packet_len, n);
} }
int blob_encode_t::input(char *s,int len) int blob_encode_t::input(char *s, int len) {
{
assert(current_len + len + sizeof(u16_t) + 100 < sizeof(input_buf)); assert(current_len + len + sizeof(u16_t) + 100 < sizeof(input_buf));
assert(len <= 65535 && len >= 0); assert(len <= 65535 && len >= 0);
counter++; counter++;
@@ -71,32 +64,26 @@ int blob_encode_t::input(char *s,int len)
return 0; return 0;
} }
int blob_encode_t::output(int n,char ** &s_arr,int & len) int blob_encode_t::output(int n, char **&s_arr, int &len) {
{
len = round_up_div(current_len, n); len = round_up_div(current_len, n);
write_u32(input_buf, counter); write_u32(input_buf, counter);
for(int i=0;i<n;i++) for (int i = 0; i < n; i++) {
{
output_buf[i] = input_buf + len * i; output_buf[i] = input_buf + len * i;
} }
s_arr = output_buf; s_arr = output_buf;
return 0; return 0;
} }
blob_decode_t::blob_decode_t() blob_decode_t::blob_decode_t() {
{
clear(); clear();
} }
int blob_decode_t::clear() int blob_decode_t::clear() {
{
current_len = 0; current_len = 0;
last_len = -1; last_len = -1;
counter = 0; counter = 0;
return 0; return 0;
} }
int blob_decode_t::input(char *s,int len) int blob_decode_t::input(char *s, int len) {
{ if (last_len != -1) {
if(last_len!=-1)
{
assert(last_len == len); assert(last_len == len);
} }
counter++; counter++;
@@ -107,34 +94,41 @@ int blob_decode_t::input(char *s,int len)
current_len += len; current_len += len;
return 0; return 0;
} }
int blob_decode_t::output(int &n,char ** &s_arr,int *&len_arr) int blob_decode_t::output(int &n, char **&s_arr, int *&len_arr) {
{
int parser_pos = 0; int parser_pos = 0;
if(parser_pos+(int)sizeof(u32_t)>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); n = (int)read_u32(input_buf + parser_pos);
if(n>max_blob_packet_num) {mylog(log_info,"failed 1\n");return -1;} if (n > max_blob_packet_num) {
mylog(log_info, "failed 1\n");
return -1;
}
s_arr = output_buf; s_arr = output_buf;
len_arr = output_len; len_arr = output_len;
parser_pos += sizeof(u32_t); parser_pos += sizeof(u32_t);
for(int i=0;i<n;i++) for (int i = 0; i < n; i++) {
{ if (parser_pos + (int)sizeof(u16_t) > current_len) {
if(parser_pos+(int)sizeof(u16_t)>current_len) {mylog(log_info,"failed2 \n");return -1;} mylog(log_info, "failed2 \n");
return -1;
}
len_arr[i] = (int)read_u16(input_buf + parser_pos); len_arr[i] = (int)read_u16(input_buf + parser_pos);
parser_pos += (int)sizeof(u16_t); 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;} 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; s_arr[i] = input_buf + parser_pos;
parser_pos += len_arr[i]; parser_pos += len_arr[i];
} }
return 0; return 0;
} }
fec_encode_manager_t::~fec_encode_manager_t() {
fec_encode_manager_t::~fec_encode_manager_t()
{
clear_all(); clear_all();
// fd_manager.fd64_close(timer_fd64); // fd_manager.fd64_close(timer_fd64);
} }
@@ -144,8 +138,7 @@ u64_t fec_encode_manager_t::get_timer_fd64()
return timer_fd64; return timer_fd64;
}*/ }*/
fec_encode_manager_t::fec_encode_manager_t() fec_encode_manager_t::fec_encode_manager_t() {
{
// int timer_fd; // int timer_fd;
/* /*
@@ -156,12 +149,10 @@ fec_encode_manager_t::fec_encode_manager_t()
} }
timer_fd64=fd_manager.create(timer_fd);*/ 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); fec_par.clone(g_fec_par);
clear_data(); 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) int fec_encode_manager_t::reset_fec_parameter(int data_num,int redundant_num,int mtu,int queue_len,int timeout,int mode)
@@ -180,10 +171,8 @@ int fec_encode_manager_t::reset_fec_parameter(int data_num,int redundant_num,int
clear_data(); clear_data();
return 0; return 0;
}*/ }*/
int fec_encode_manager_t::append(char *s,int len/*,int &is_first_packet*/) int fec_encode_manager_t::append(char *s, int len /*,int &is_first_packet*/) {
{ if (counter == 0) {
if(counter==0)
{
first_packet_time = get_current_time_us(); first_packet_time = get_current_time_us();
const double m = 1000 * 1000; const double m = 1000 * 1000;
@@ -195,8 +184,7 @@ int fec_encode_manager_t::append(char *s,int len/*,int &is_first_packet*/)
if (fec_par.mode == 0) // for type 0 use blob if (fec_par.mode == 0) // for type 0 use blob
{ {
assert(blob_encode.input(s, len) == 0); assert(blob_encode.input(s, len) == 0);
} } else if (fec_par.mode == 1) // for tpe 1 use input_buf and counter
else if(fec_par.mode==1)//for tpe 1 use input_buf and counter
{ {
mylog(log_trace, "counter=%d\n", counter); mylog(log_trace, "counter=%d\n", counter);
assert(len <= 65535 && len >= 0); assert(len <= 65535 && len >= 0);
@@ -208,18 +196,14 @@ int fec_encode_manager_t::append(char *s,int len/*,int &is_first_packet*/)
p += sizeof(u16_t); p += sizeof(u16_t);
memcpy(p, s, len); memcpy(p, s, len);
input_len[counter] = len + sizeof(u16_t); input_len[counter] = len + sizeof(u16_t);
} } else {
else
{
assert(0 == 1); assert(0 == 1);
} }
counter++; counter++;
return 0; return 0;
} }
int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/) int fec_encode_manager_t::input(char *s, int len /*,int &is_first_packet*/) {
{ if (counter == 0 && fec_par.version != g_fec_par.version) {
if(counter==0&&fec_par.version!=g_fec_par.version)
{
fec_par.clone(g_fec_par); fec_par.clone(g_fec_par);
} }
@@ -228,35 +212,32 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
// int counter_back=counter; // int counter_back=counter;
assert(fec_par.mode == 0 || fec_par.mode == 1); assert(fec_par.mode == 0 || fec_par.mode == 1);
if(fec_par.mode==0&& s!=0 &&counter==0) if (fec_par.mode == 0 && s != 0 && counter == 0) {
{
int out_len = blob_encode.get_shard_len(fec_par.get_tail().x, len); int out_len = blob_encode.get_shard_len(fec_par.get_tail().x, len);
if(out_len>fec_par.mtu) 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); 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; return -1;
} }
} }
if(fec_par.mode==1&&s!=0&&len>fec_par.mtu) 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); 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; // return -1;
} }
if(s==0&&counter==0) if (s == 0 && counter == 0) {
{
mylog(log_warn, "unexpected s==0&&counter==0\n"); mylog(log_warn, "unexpected s==0&&counter==0\n");
return -1; return -1;
} }
if (s == 0) about_to_fec = 1; // now 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 && 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 == 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 (fec_par.mode == 1) assert(counter < fec_par.get_tail().x);
if (s != 0 && !delayed_append) {
if(s!=0&&!delayed_append)
{
append(s, len); append(s, len);
} }
@@ -264,15 +245,12 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
if (fec_par.mode == 1 && counter == fec_par.get_tail().x) about_to_fec = 1; if (fec_par.mode == 1 && counter == fec_par.get_tail().x) about_to_fec = 1;
if (about_to_fec) {
if(about_to_fec)
{
char **blob_output = 0; char **blob_output = 0;
int fec_len = -1; int fec_len = -1;
mylog(log_trace, "counter=%d\n", counter); mylog(log_trace, "counter=%d\n", counter);
if(counter==0) if (counter == 0) {
{
mylog(log_warn, "unexpected counter==0 here\n"); mylog(log_warn, "unexpected counter==0 here\n");
return -1; return -1;
} }
@@ -280,22 +258,17 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
int actual_data_num; int actual_data_num;
int actual_redundant_num; int actual_redundant_num;
if(fec_par.mode==0) if (fec_par.mode == 0) {
{
int tail_x = fec_par.get_tail().x; int tail_x = fec_par.get_tail().x;
int tail_y = fec_par.get_tail().y; int tail_y = fec_par.get_tail().y;
actual_data_num = tail_x; actual_data_num = tail_x;
actual_redundant_num = tail_y; actual_redundant_num = tail_y;
if(short_packet_optimize) if (short_packet_optimize) {
{
u32_t best_len = (blob_encode.get_shard_len(tail_x, 0) + header_overhead) * (tail_x + tail_y); u32_t best_len = (blob_encode.get_shard_len(tail_x, 0) + header_overhead) * (tail_x + tail_y);
int best_data_num = tail_x; int best_data_num = tail_x;
assert(tail_x <= fec_par.rs_cnt); assert(tail_x <= fec_par.rs_cnt);
for(int i=1;i<tail_x;i++) for (int i = 1; i < tail_x; i++) {
{
assert(fec_par.rs_par[i - 1].x == i); assert(fec_par.rs_par[i - 1].x == i);
int tmp_x = fec_par.rs_par[i - 1].x; int tmp_x = fec_par.rs_par[i - 1].x;
int tmp_y = fec_par.rs_par[i - 1].y; int tmp_y = fec_par.rs_par[i - 1].y;
@@ -304,8 +277,7 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
if (shard_len > (u32_t)fec_par.mtu) continue; if (shard_len > (u32_t)fec_par.mtu) continue;
u32_t new_len = (shard_len + header_overhead) * (tmp_x + tmp_y); u32_t new_len = (shard_len + header_overhead) * (tmp_x + tmp_y);
if(new_len<best_len) if (new_len < best_len) {
{
best_len = new_len; best_len = new_len;
best_data_num = tmp_x; best_data_num = tmp_x;
} }
@@ -321,16 +293,13 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
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); 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 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); 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 {
else
{
assert(counter <= fec_par.rs_cnt); assert(counter <= fec_par.rs_cnt);
actual_data_num = counter; actual_data_num = counter;
actual_redundant_num = fec_par.rs_par[counter - 1].y; actual_redundant_num = fec_par.rs_par[counter - 1].y;
int sum_ori = 0; int sum_ori = 0;
for(int i=0;i<counter;i++) for (int i = 0; i < counter; i++) {
{
sum_ori += input_len[i]; sum_ori += input_len[i];
assert(input_len[i] >= 0); assert(input_len[i] >= 0);
if (input_len[i] > fec_len) fec_len = input_len[i]; if (input_len[i] > fec_len) fec_len = input_len[i];
@@ -347,19 +316,16 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
// mylog(log_trace,"%d %d %d\n",actual_data_num,actual_redundant_num,fec_len); // 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}; char *tmp_output_buf[max_fec_packet_num + 5] = {0};
for(int i=0;i<actual_data_num+actual_redundant_num;i++) for (int i = 0; i < actual_data_num + actual_redundant_num; i++) {
{
int tmp_idx = 0; int tmp_idx = 0;
write_u32(input_buf[i] + tmp_idx, seq); write_u32(input_buf[i] + tmp_idx, seq);
tmp_idx += sizeof(u32_t); tmp_idx += sizeof(u32_t);
input_buf[i][tmp_idx++] = (unsigned char)fec_par.mode; input_buf[i][tmp_idx++] = (unsigned char)fec_par.mode;
if (fec_par.mode == 1 && i < actual_data_num) 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;
input_buf[i][tmp_idx++] = (unsigned char)0; input_buf[i][tmp_idx++] = (unsigned char)0;
} else } else {
{
input_buf[i][tmp_idx++] = (unsigned char)actual_data_num; 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)actual_redundant_num;
} }
@@ -367,38 +333,27 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
tmp_output_buf[i] = input_buf[i] + tmp_idx; //////caution ,trick here. tmp_output_buf[i] = input_buf[i] + tmp_idx; //////caution ,trick here.
if(fec_par.mode==0) if (fec_par.mode == 0) {
{
output_len[i] = tmp_idx + fec_len; output_len[i] = tmp_idx + fec_len;
if(i<actual_data_num) if (i < actual_data_num) {
{
memcpy(input_buf[i] + tmp_idx, blob_output[i], fec_len); memcpy(input_buf[i] + tmp_idx, blob_output[i], fec_len);
} }
} } else {
else if (i < actual_data_num) {
{
if(i<actual_data_num)
{
output_len[i] = tmp_idx + input_len[i]; output_len[i] = tmp_idx + input_len[i];
memset(tmp_output_buf[i] + input_len[i], 0, fec_len - input_len[i]); memset(tmp_output_buf[i] + input_len[i], 0, fec_len - input_len[i]);
} } else
else
output_len[i] = tmp_idx + fec_len; output_len[i] = tmp_idx + fec_len;
} }
output_buf[i] = input_buf[i]; // output_buf points to same block of memory with different offset output_buf[i] = input_buf[i]; // output_buf points to same block of memory with different offset
} }
if(0) if (0) {
{
printf("seq=%u,fec_len=%d,%d %d,before fec\n", seq, fec_len, actual_data_num, actual_redundant_num); 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++) for (int i = 0; i < actual_data_num; i++) {
{
printf("{"); printf("{");
for(int j=0;j<8+fec_len;j++) for (int j = 0; j < 8 + fec_len; j++) {
{
log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)input_buf[i][j]); log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)input_buf[i][j]);
} }
printf("},\n"); printf("},\n");
@@ -408,14 +363,11 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
// output_len=blob_len+sizeof(u32_t)+4*sizeof(char);/////remember to change this 4,if modified the protocol // 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); rs_encode2(actual_data_num, actual_data_num + actual_redundant_num, tmp_output_buf, fec_len);
if(0) if (0) {
{
printf("seq=%u,fec_len=%d,%d %d,after fec\n", seq, fec_len, actual_data_num, actual_redundant_num); 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++) for (int i = 0; i < actual_data_num + actual_redundant_num; i++) {
{
printf("{"); printf("{");
for(int j=0;j<8+fec_len;j++) for (int j = 0; j < 8 + fec_len; j++) {
{
log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)output_buf[i][j]); log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)output_buf[i][j]);
} }
printf("},\n"); printf("},\n");
@@ -438,32 +390,24 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
ev_timer_stop(loop, &timer); ev_timer_stop(loop, &timer);
// timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0); // timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0);
if(encode_fast_send&&fec_par.mode==1) if (encode_fast_send && fec_par.mode == 1) {
{
int packet_to_send[max_fec_packet_num + 5] = {0}; int packet_to_send[max_fec_packet_num + 5] = {0};
int packet_to_send_counter = 0; int packet_to_send_counter = 0;
// assert(counter!=0); // assert(counter!=0);
if (s != 0) if (s != 0)
packet_to_send[packet_to_send_counter++] = actual_data_num - 1; 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++) for (int i = actual_data_num; i < actual_data_num + actual_redundant_num; i++) {
{
packet_to_send[packet_to_send_counter++] = i; packet_to_send[packet_to_send_counter++] = i;
} }
output_n = packet_to_send_counter; // re write output_n = packet_to_send_counter; // re write
for(int i=0;i<packet_to_send_counter;i++) for (int i = 0; i < packet_to_send_counter; i++) {
{
output_buf[i] = output_buf[packet_to_send[i]]; output_buf[i] = output_buf[packet_to_send[i]];
output_len[i] = output_len[packet_to_send[i]]; output_len[i] = output_len[packet_to_send[i]];
} }
} }
} } else {
else if (encode_fast_send && s != 0 && fec_par.mode == 1) {
{
if(encode_fast_send&&s!=0&&fec_par.mode==1)
{
assert(counter >= 1); assert(counter >= 1);
assert(counter <= 255); assert(counter <= 255);
int input_buf_idx = counter - 1; int input_buf_idx = counter - 1;
@@ -472,7 +416,6 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
first_packet_time_for_output = 0; first_packet_time_for_output = 0;
output_n = 1; output_n = 1;
int tmp_idx = 0; int tmp_idx = 0;
write_u32(input_buf[input_buf_idx] + tmp_idx, seq); write_u32(input_buf[input_buf_idx] + tmp_idx, seq);
tmp_idx += sizeof(u32_t); tmp_idx += sizeof(u32_t);
@@ -485,11 +428,9 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
output_len[0] = input_len[input_buf_idx] + tmp_idx; output_len[0] = input_len[input_buf_idx] + tmp_idx;
output_buf[0] = input_buf[input_buf_idx]; output_buf[0] = input_buf[input_buf_idx];
if(0) if (0) {
{
printf("seq=%u,buf_idx=%d\n", seq, input_buf_idx); printf("seq=%u,buf_idx=%d\n", seq, input_buf_idx);
for(int j=0;j<output_len[0];j++) for (int j = 0; j < output_len[0]; j++) {
{
log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)output_buf[0][j]); log_bare(log_warn, "0x%02x,", (u32_t)(unsigned char)output_buf[0][j]);
} }
printf("\n"); printf("\n");
@@ -497,8 +438,7 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
} }
} }
if(s!=0&&delayed_append) if (s != 0 && delayed_append) {
{
assert(fec_par.mode != 1); assert(fec_par.mode != 1);
append(s, len); append(s, len);
} }
@@ -506,16 +446,12 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
return 0; return 0;
} }
int fec_encode_manager_t::output(int &n,char ** &s_arr,int *&len) int fec_encode_manager_t::output(int &n, char **&s_arr, int *&len) {
{ if (!ready_for_output) {
if(!ready_for_output)
{
n = -1; n = -1;
len = 0; len = 0;
s_arr = 0; s_arr = 0;
} } else {
else
{
n = output_n; n = output_n;
len = output_len; len = output_len;
s_arr = output_buf; s_arr = output_buf;
@@ -530,15 +466,13 @@ int fec_decode_manager_t::re_init()
return 0; return 0;
}*/ }*/
int fec_decode_manager_t::input(char *s,int len) int fec_decode_manager_t::input(char *s, int len) {
{
assert(s != 0); assert(s != 0);
assert(len + 100 < buf_len); // guarenteed by upper level assert(len + 100 < buf_len); // guarenteed by upper level
int tmp_idx = 0; int tmp_idx = 0;
int tmp_header_len = sizeof(u32_t) + sizeof(char) * 4; int tmp_header_len = sizeof(u32_t) + sizeof(char) * 4;
if(len<tmp_header_len) if (len < tmp_header_len) {
{
mylog(log_warn, "len =%d\n", len); mylog(log_warn, "len =%d\n", len);
return -1; return -1;
} }
@@ -552,80 +486,63 @@ int fec_decode_manager_t::input(char *s,int len)
// mylog(log_trace,"input\n"); // mylog(log_trace,"input\n");
if(len<0) if (len < 0) {
{
mylog(log_warn, "len<0\n"); mylog(log_warn, "len<0\n");
return -1; return -1;
} }
if(type==1) if (type == 1) {
{ if (len < (int)sizeof(u16_t)) {
if(len<(int)sizeof(u16_t))
{
mylog(log_warn, "type==1&&len<2\n"); mylog(log_warn, "type==1&&len<2\n");
return -1; return -1;
} }
if(data_num==0&&(int)( read_u16(s+tmp_idx)+sizeof(u16_t))!=len) if (data_num == 0 && (int)(read_u16(s + tmp_idx) + sizeof(u16_t)) != len) {
{
mylog(log_warn, "inner_index<data_num&&read_u16(s+tmp_idx)+sizeof(u16_t)!=len %d %d\n", (int)(read_u16(s + tmp_idx) + sizeof(u16_t)), len); mylog(log_warn, "inner_index<data_num&&read_u16(s+tmp_idx)+sizeof(u16_t)!=len %d %d\n", (int)(read_u16(s + tmp_idx) + sizeof(u16_t)), len);
return -1; return -1;
} }
} }
if(type==0&&data_num==0) if (type == 0 && data_num == 0) {
{
mylog(log_warn, "unexpected type==0&&data_num==0\n"); mylog(log_warn, "unexpected type==0&&data_num==0\n");
return -1; return -1;
} }
if(data_num+redundant_num>=max_fec_packet_num) if (data_num + redundant_num >= max_fec_packet_num) {
{
mylog(log_warn, "data_num+redundant_num>=max_fec_packet_num\n"); mylog(log_warn, "data_num+redundant_num>=max_fec_packet_num\n");
return -1; return -1;
} }
if(!anti_replay.is_vaild(seq)) if (!anti_replay.is_vaild(seq)) {
{
mylog(log_trace, "!anti_replay.is_vaild(seq) ,seq =%u\n", seq); mylog(log_trace, "!anti_replay.is_vaild(seq) ,seq =%u\n", seq);
return 0; return 0;
} }
if(mp[seq].fec_done!=0) if (mp[seq].fec_done != 0) {
{
mylog(log_debug, "fec already done, ignore, seq=%u\n", seq); mylog(log_debug, "fec already done, ignore, seq=%u\n", seq);
return -1; return -1;
} }
if(mp[seq].group_mp.find(inner_index)!=mp[seq].group_mp.end() ) 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 mylog(log_debug, "dup fec index\n"); // duplicate can happen on a normal network, so its just log_debug
return -1; return -1;
} }
if (mp[seq].type == -1) if (mp[seq].type == -1)
mp[seq].type = type; mp[seq].type = type;
else else {
{ if (mp[seq].type != type) {
if(mp[seq].type!=type)
{
mylog(log_warn, "type mismatch\n"); mylog(log_warn, "type mismatch\n");
return -1; return -1;
} }
} }
if(data_num!=0) if (data_num != 0) {
{
// mp[seq].data_counter++; // mp[seq].data_counter++;
if(mp[seq].data_num==-1) if (mp[seq].data_num == -1) {
{
mp[seq].data_num = data_num; mp[seq].data_num = data_num;
mp[seq].redundant_num = redundant_num; mp[seq].redundant_num = redundant_num;
mp[seq].len = len; mp[seq].len = len;
} } else {
else if (mp[seq].data_num != data_num || mp[seq].redundant_num != redundant_num || mp[seq].len != len) {
{
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"); mylog(log_warn, "unexpected mp[seq].data_num!=data_num||mp[seq].redundant_num!=redundant_num||mp[seq].len!=len\n");
return -1; return -1;
} }
@@ -634,20 +551,17 @@ int fec_decode_manager_t::input(char *s,int len)
// 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) if (fec_data[index].used != 0) {
{
u32_t tmp_seq = fec_data[index].seq; u32_t tmp_seq = fec_data[index].seq;
anti_replay.set_invaild(tmp_seq); anti_replay.set_invaild(tmp_seq);
auto tmp_it = mp.find(tmp_seq); auto tmp_it = mp.find(tmp_seq);
if(tmp_it!=mp.end()) if (tmp_it != mp.end()) {
{
int x = tmp_it->second.data_num; int x = tmp_it->second.data_num;
int y = tmp_it->second.redundant_num; int y = tmp_it->second.redundant_num;
int cnt = tmp_it->second.group_mp.size(); int cnt = tmp_it->second.group_mp.size();
if(cnt<x) if (cnt < x) {
{
if (debug_fec_dec) if (debug_fec_dec)
mylog(log_debug, "[dec][failed]seq=%08x x=%d y=%d cnt=%d\n", tmp_seq, x, y, cnt); mylog(log_debug, "[dec][failed]seq=%08x x=%d y=%d cnt=%d\n", tmp_seq, x, y, cnt);
else else
@@ -655,8 +569,7 @@ int fec_decode_manager_t::input(char *s,int len)
} }
mp.erase(tmp_it); mp.erase(tmp_it);
} }
if(tmp_seq==seq) if (tmp_seq == seq) {
{
mylog(log_warn, "unexpected tmp_seq==seq ,seq=%d\n", seq); mylog(log_warn, "unexpected tmp_seq==seq ,seq=%d\n", seq);
return -1; return -1;
} }
@@ -677,51 +590,39 @@ int fec_decode_manager_t::input(char *s,int len)
map<int, int> &inner_mp = mp[seq].group_mp; map<int, int> &inner_mp = mp[seq].group_mp;
int about_to_fec = 0; int about_to_fec = 0;
if(type==0) if (type == 0) {
{
// assert((int)inner_mp.size()<=data_num); // assert((int)inner_mp.size()<=data_num);
if((int)inner_mp.size()>data_num) if ((int)inner_mp.size() > data_num) {
{
mylog(log_warn, "inner_mp.size()>data_num\n"); mylog(log_warn, "inner_mp.size()>data_num\n");
anti_replay.set_invaild(seq); anti_replay.set_invaild(seq);
goto end; goto end;
} }
if ((int)inner_mp.size() == data_num) if ((int)inner_mp.size() == data_num)
about_to_fec = 1; about_to_fec = 1;
} } else {
else if (mp[seq].data_num != -1) {
{ if ((int)inner_mp.size() > mp[seq].data_num + 1) {
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"); mylog(log_warn, "inner_mp.size()>data_num+1\n");
anti_replay.set_invaild(seq); anti_replay.set_invaild(seq);
goto end; goto end;
} }
if((int)inner_mp.size()>=mp[seq].data_num) if ((int)inner_mp.size() >= mp[seq].data_num) {
{
about_to_fec = 1; about_to_fec = 1;
} }
} }
} }
if (about_to_fec) {
if(about_to_fec)
{
int group_data_num = mp[seq].data_num; int group_data_num = mp[seq].data_num;
int group_redundant_num = mp[seq].redundant_num; int group_redundant_num = mp[seq].redundant_num;
int x_got = 0; int x_got = 0;
int y_got = 0; int y_got = 0;
// mylog(log_error,"fec here!\n"); // mylog(log_error,"fec here!\n");
if(type==0) if (type == 0) {
{
char *fec_tmp_arr[max_fec_packet_num + 5] = {0}; char *fec_tmp_arr[max_fec_packet_num + 5] = {0};
for(auto it=inner_mp.begin();it!=inner_mp.end();it++) for (auto it = inner_mp.begin(); it != inner_mp.end(); it++) {
{
if (it->first < group_data_num) if (it->first < group_data_num)
x_got++; x_got++;
else else
@@ -738,12 +639,10 @@ int fec_decode_manager_t::input(char *s,int len)
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); 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);
blob_decode.clear(); blob_decode.clear();
for(int i=0;i<group_data_num;i++) for (int i = 0; i < group_data_num; i++) {
{
blob_decode.input(fec_tmp_arr[i], len); blob_decode.input(fec_tmp_arr[i], len);
} }
if(blob_decode.output(output_n,output_s_arr,output_len_arr)!=0) if (blob_decode.output(output_n, output_s_arr, output_len_arr) != 0) {
{
mylog(log_warn, "blob_decode failed\n"); mylog(log_warn, "blob_decode failed\n");
// ready_for_output=0; // ready_for_output=0;
anti_replay.set_invaild(seq); anti_replay.set_invaild(seq);
@@ -752,11 +651,8 @@ int fec_decode_manager_t::input(char *s,int len)
assert(ready_for_output == 0); assert(ready_for_output == 0);
ready_for_output = 1; ready_for_output = 1;
anti_replay.set_invaild(seq); anti_replay.set_invaild(seq);
} } else // type==1
else//type==1
{ {
int max_len = -1; int max_len = -1;
int fec_result_ok = 1; int fec_result_ok = 1;
int data_check_ok = 1; int data_check_ok = 1;
@@ -769,20 +665,17 @@ int fec_decode_manager_t::input(char *s,int len)
// memset(output_s_arr_buf,0,sizeof(output_s_arr_buf));//in efficient // memset(output_s_arr_buf,0,sizeof(output_s_arr_buf));//in efficient
for(int i=0;i<group_data_num+group_redundant_num;i++) for (int i = 0; i < group_data_num + group_redundant_num; i++) {
{
output_s_arr_buf[i] = 0; output_s_arr_buf[i] = 0;
} }
for(auto it=inner_mp.begin();it!=inner_mp.end();it++) for (auto it = inner_mp.begin(); it != inner_mp.end(); it++) {
{
if (it->first < group_data_num) if (it->first < group_data_num)
x_got++; x_got++;
else else
y_got++; y_got++;
output_s_arr_buf[it->first] = fec_data[it->second].buf; output_s_arr_buf[it->first] = fec_data[it->second].buf;
if(fec_data[it->second].len<(int)sizeof(u16_t)) if (fec_data[it->second].len < (int)sizeof(u16_t)) {
{
mylog(log_warn, "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; data_check_ok = 0;
} }
@@ -790,27 +683,23 @@ int fec_decode_manager_t::input(char *s,int len)
if (fec_data[it->second].len > max_len) if (fec_data[it->second].len > max_len)
max_len = fec_data[it->second].len; max_len = fec_data[it->second].len;
} }
if(max_len!=mp[seq].len) if (max_len != mp[seq].len) {
{
data_check_ok = 0; data_check_ok = 0;
mylog(log_warn, "max_len!=mp[seq].len"); mylog(log_warn, "max_len!=mp[seq].len");
} }
if(data_check_ok==0) if (data_check_ok == 0) {
{
// ready_for_output=0; // ready_for_output=0;
mylog(log_warn, "data_check_ok==0\n"); mylog(log_warn, "data_check_ok==0\n");
anti_replay.set_invaild(seq); anti_replay.set_invaild(seq);
goto end; goto end;
} }
for(auto it=inner_mp.begin();it!=inner_mp.end();it++) for (auto it = inner_mp.begin(); it != inner_mp.end(); it++) {
{
int tmp_idx = it->second; int tmp_idx = it->second;
assert(max_len >= fec_data[tmp_idx].len); // guarenteed by data_check_ok 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); memset(fec_data[tmp_idx].buf + fec_data[tmp_idx].len, 0, max_len - fec_data[tmp_idx].len);
} }
for(int i=0;i<group_data_num;i++) for (int i = 0; i < group_data_num; i++) {
{
if (output_s_arr_buf[i] == 0 || i == inner_index) // only missed packet +current packet if (output_s_arr_buf[i] == 0 || i == inner_index) // only missed packet +current packet
{ {
missed_packet[missed_packet_counter++] = i; missed_packet[missed_packet_counter++] = i;
@@ -823,17 +712,14 @@ int fec_decode_manager_t::input(char *s,int len)
int sum_ori = 0; int sum_ori = 0;
for(int i=0;i<group_data_num;i++) for (int i = 0; i < group_data_num; i++) {
{
output_len_arr_buf[i] = read_u16(output_s_arr_buf[i]); output_len_arr_buf[i] = read_u16(output_s_arr_buf[i]);
sum_ori += output_len_arr_buf[i]; sum_ori += output_len_arr_buf[i];
output_s_arr_buf[i] += sizeof(u16_t); output_s_arr_buf[i] += sizeof(u16_t);
if(output_len_arr_buf[i]>max_data_len) 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); 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; fec_result_ok = 0;
for(int i=0;i<missed_packet_counter;i++) for (int i = 0; i < missed_packet_counter; i++) {
{
log_bare(log_warn, "%d ", missed_packet[i]); log_bare(log_warn, "%d ", missed_packet[i]);
} }
log_bare(log_warn, "\n"); log_bare(log_warn, "\n");
@@ -848,50 +734,38 @@ int fec_decode_manager_t::input(char *s,int len)
else else
mylog(log_trace, "[dec]seq=%08x x=%d y=%d len=%d sum_ori=%d sum=%d X=%d Y=%d\n", seq, group_data_num, group_redundant_num, max_len, sum_ori, sum, x_got, y_got); mylog(log_trace, "[dec]seq=%08x x=%d y=%d len=%d sum_ori=%d sum=%d X=%d Y=%d\n", seq, group_data_num, group_redundant_num, max_len, sum_ori, sum, x_got, y_got);
if(fec_result_ok) if (fec_result_ok) {
{
output_n = group_data_num; output_n = group_data_num;
if(decode_fast_send) if (decode_fast_send) {
{
output_n = missed_packet_counter; output_n = missed_packet_counter;
for(int i=0;i<missed_packet_counter;i++) for (int i = 0; i < missed_packet_counter; i++) {
{
output_s_arr_buf[i] = output_s_arr_buf[missed_packet[i]]; output_s_arr_buf[i] = output_s_arr_buf[missed_packet[i]];
output_len_arr_buf[i] = output_len_arr_buf[missed_packet[i]]; output_len_arr_buf[i] = output_len_arr_buf[missed_packet[i]];
} }
} }
output_s_arr = output_s_arr_buf; output_s_arr = output_s_arr_buf;
output_len_arr = output_len_arr_buf; output_len_arr = output_len_arr_buf;
assert(ready_for_output == 0); assert(ready_for_output == 0);
ready_for_output = 1; ready_for_output = 1;
} } else {
else
{
// fec_not_ok: // fec_not_ok:
ready_for_output = 0; ready_for_output = 0;
} }
anti_replay.set_invaild(seq); anti_replay.set_invaild(seq);
} // end of type==1 } // end of type==1
} } else // not about_to_fec
else //not about_to_fec
{
if(decode_fast_send)
{
if(type==1&&data_num==0)
{ {
if (decode_fast_send) {
if (type == 1 && data_num == 0) {
assert(ready_for_output == 0); assert(ready_for_output == 0);
output_n = 1; output_n = 1;
int check_len = read_u16(fec_data[index].buf); int check_len = read_u16(fec_data[index].buf);
output_s_arr_buf[0] = fec_data[index].buf + sizeof(u16_t); output_s_arr_buf[0] = fec_data[index].buf + sizeof(u16_t);
output_len_arr_buf[0] = fec_data[index].len - sizeof(u16_t); output_len_arr_buf[0] = fec_data[index].len - sizeof(u16_t);
if(output_len_arr_buf[0]!=check_len) if (output_len_arr_buf[0] != check_len) {
{
mylog(log_warn, "len mismatch %d %d\n", output_len_arr_buf[0], check_len); mylog(log_warn, "len mismatch %d %d\n", output_len_arr_buf[0], check_len);
} }
output_s_arr = output_s_arr_buf; output_s_arr = output_s_arr_buf;
@@ -908,16 +782,12 @@ int fec_decode_manager_t::input(char *s,int len)
return 0; return 0;
} }
int fec_decode_manager_t::output(int &n,char ** &s_arr,int* &len_arr) int fec_decode_manager_t::output(int &n, char **&s_arr, int *&len_arr) {
{ if (!ready_for_output) {
if(!ready_for_output)
{
n = -1; n = -1;
s_arr = 0; s_arr = 0;
len_arr = 0; len_arr = 0;
} } else {
else
{
ready_for_output = 0; ready_for_output = 0;
n = output_n; n = output_n;
s_arr = output_s_arr; s_arr = output_s_arr;

View File

@@ -23,8 +23,7 @@ extern int header_overhead;
extern int debug_fec_enc; extern int debug_fec_enc;
extern int debug_fec_dec; extern int debug_fec_dec;
struct fec_parameter_t struct fec_parameter_t {
{
int version = 0; int version = 0;
int mtu = default_mtu; int mtu = default_mtu;
int queue_len = 200; int queue_len = 200;
@@ -41,24 +40,20 @@ struct fec_parameter_t
int rs_from_str(char *s) // todo inefficient int rs_from_str(char *s) // todo inefficient
{ {
vector<string> str_vec = string_to_vec(s, ","); vector<string> str_vec = string_to_vec(s, ",");
if(str_vec.size()<1) if (str_vec.size() < 1) {
{
mylog(log_warn, "failed to parse [%s]\n", s); mylog(log_warn, "failed to parse [%s]\n", s);
return -1; return -1;
} }
vector<rs_parameter_t> par_vec; vector<rs_parameter_t> par_vec;
for(int i=0;i<(int)str_vec.size();i++) for (int i = 0; i < (int)str_vec.size(); i++) {
{
rs_parameter_t tmp_par; rs_parameter_t tmp_par;
string &tmp_str = str_vec[i]; string &tmp_str = str_vec[i];
int x, y; int x, y;
if(sscanf((char *)tmp_str.c_str(),"%d:%d",&x,&y)!=2) if (sscanf((char *)tmp_str.c_str(), "%d:%d", &x, &y) != 2) {
{
mylog(log_warn, "failed to parse [%s]\n", tmp_str.c_str()); mylog(log_warn, "failed to parse [%s]\n", tmp_str.c_str());
return -1; return -1;
} }
if(x<1||y<0||x+y>max_fec_packet_num) 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); 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; return -1;
} }
@@ -69,10 +64,8 @@ struct fec_parameter_t
assert(par_vec.size() == str_vec.size()); assert(par_vec.size() == str_vec.size());
int found_problem = 0; int found_problem = 0;
for(int i=1;i<(int)par_vec.size();i++) for (int i = 1; i < (int)par_vec.size(); i++) {
{ if (par_vec[i].x <= par_vec[i - 1].x) {
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); mylog(log_warn, "error in [%s], x in x:y should be in ascend order\n", s);
return -1; return -1;
} }
@@ -84,36 +77,29 @@ struct fec_parameter_t
double now_ratio = double(par_vec[i].y) / par_vec[i].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; double pre_ratio = double(par_vec[i - 1].y) / par_vec[i - 1].x;
if(pre_ratio+0.0001<now_ratio) if (pre_ratio + 0.0001 < now_ratio) {
{ if (found_problem == 0) {
if(found_problem==0)
{
mylog(log_warn, "possible problems: %d/%d<%d/%d", pre_y, pre_x, now_y, now_x); mylog(log_warn, "possible problems: %d/%d<%d/%d", pre_y, pre_x, now_y, now_x);
found_problem = 1; found_problem = 1;
} } else {
else
{
log_bare(log_warn, ", %d/%d<%d/%d", pre_y, pre_x, now_y, now_x); log_bare(log_warn, ", %d/%d<%d/%d", pre_y, pre_x, now_y, now_x);
} }
} }
} }
if(found_problem) if (found_problem) {
{
log_bare(log_warn, " in %s\n", s); log_bare(log_warn, " in %s\n", s);
} }
{ // special treatment for first parameter { // special treatment for first parameter
int x = par_vec[0].x; int x = par_vec[0].x;
int y = par_vec[0].y; int y = par_vec[0].y;
for(int i=1;i<=x;i++) for (int i = 1; i <= x; i++) {
{
rs_par[i - 1].x = i; rs_par[i - 1].x = i;
rs_par[i - 1].y = y; rs_par[i - 1].y = y;
} }
} }
for(int i=1;i<(int)par_vec.size();i++) for (int i = 1; i < (int)par_vec.size(); i++) {
{
int now_x = par_vec[i].x; int now_x = par_vec[i].x;
int now_y = par_vec[i].y; int now_y = par_vec[i].y;
int pre_x = par_vec[i - 1].x; int pre_x = par_vec[i - 1].x;
@@ -125,8 +111,7 @@ struct fec_parameter_t
double pre_ratio = double(par_vec[i - 1].y) / par_vec[i - 1].x; double pre_ratio = double(par_vec[i - 1].y) / par_vec[i - 1].x;
// double k= double(now_y-pre_y)/double(now_x-pre_x); // double k= double(now_y-pre_y)/double(now_x-pre_x);
for(int j=pre_x+1;j<=now_x-1;j++) for (int j = pre_x + 1; j <= now_x - 1; j++) {
{
int in_x = j; int in_x = j;
//////// int in_y= double(pre_y) + double(in_x-pre_x)*k+ 0.9999;// round to upper //////// int in_y= double(pre_y) + double(in_x-pre_x)*k+ 0.9999;// round to upper
@@ -136,8 +121,7 @@ struct fec_parameter_t
////// int in_y= in_x*in_ratio + 0.9999; ////// int in_y= in_x*in_ratio + 0.9999;
int in_y = pre_y + (now_y - pre_y) * (in_x - pre_x) / distance + 0.9999; int in_y = pre_y + (now_y - pre_y) * (in_x - pre_x) / distance + 0.9999;
if(in_x+in_y>max_fec_packet_num) if (in_x + in_y > max_fec_packet_num) {
{
in_y = max_fec_packet_num - in_x; in_y = max_fec_packet_num - in_x;
assert(in_y >= 0 && in_y <= max_fec_packet_num); assert(in_y >= 0 && in_y <= max_fec_packet_num);
} }
@@ -157,8 +141,7 @@ struct fec_parameter_t
string tmp_string; string tmp_string;
char tmp_buf[100]; char tmp_buf[100];
assert(rs_cnt >= 1); assert(rs_cnt >= 1);
for(int i=0;i<rs_cnt;i++) for (int i = 0; i < rs_cnt; i++) {
{
sprintf(tmp_buf, "%d:%d", int(rs_par[i].x), int(rs_par[i].y)); sprintf(tmp_buf, "%d:%d", int(rs_par[i].x), int(rs_par[i].y));
if (i != 0) if (i != 0)
tmp_string += ","; tmp_string += ",";
@@ -168,15 +151,12 @@ struct fec_parameter_t
return res; return res;
} }
rs_parameter_t get_tail() rs_parameter_t get_tail() {
{
assert(rs_cnt >= 1); assert(rs_cnt >= 1);
return rs_par[rs_cnt - 1]; return rs_par[rs_cnt - 1];
} }
int clone(fec_parameter_t &other) {
int clone(fec_parameter_t & other)
{
version = other.version; version = other.version;
mtu = other.mtu; mtu = other.mtu;
queue_len = other.queue_len; queue_len = other.queue_len;
@@ -190,7 +170,13 @@ struct fec_parameter_t
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);
return 0;
}
}; };
extern fec_parameter_t g_fec_par; extern fec_parameter_t g_fec_par;
@@ -198,11 +184,8 @@ extern fec_parameter_t g_fec_par;
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 {
struct info_t
{
my_time_t my_time; my_time_t my_time;
int index; int index;
}; };
@@ -210,30 +193,24 @@ struct anti_replay_t
u64_t replay_buffer[anti_replay_buff_size]; u64_t replay_buffer[anti_replay_buff_size];
unordered_map<u32_t, info_t> mp; unordered_map<u32_t, info_t> mp;
int index; int index;
anti_replay_t() anti_replay_t() {
{
clear(); clear();
} }
int clear() int clear() {
{
memset(replay_buffer, -1, sizeof(replay_buffer)); memset(replay_buffer, -1, sizeof(replay_buffer));
mp.clear(); mp.clear();
mp.rehash(anti_replay_buff_size * 3); mp.rehash(anti_replay_buff_size * 3);
index = 0; index = 0;
return 0; return 0;
} }
void set_invaild(u32_t seq) void set_invaild(u32_t seq) {
{ if (is_vaild(seq) == 0) {
if(is_vaild(seq)==0)
{
mylog(log_trace, "seq %u exist\n", seq); mylog(log_trace, "seq %u exist\n", seq);
// assert(mp.find(seq)!=mp.end()); // assert(mp.find(seq)!=mp.end());
// mp[seq].my_time=get_current_time_rough(); // mp[seq].my_time=get_current_time_rough();
return; return;
} }
if(replay_buffer[index]!=u64_t(i64_t(-1))) if (replay_buffer[index] != u64_t(i64_t(-1))) {
{
assert(mp.find(replay_buffer[index]) != mp.end()); assert(mp.find(replay_buffer[index]) != mp.end());
mp.erase(replay_buffer[index]); mp.erase(replay_buffer[index]);
} }
@@ -244,12 +221,10 @@ struct anti_replay_t
index++; index++;
if (index == int(anti_replay_buff_size)) index = 0; if (index == int(anti_replay_buff_size)) index = 0;
} }
int is_vaild(u32_t seq) int is_vaild(u32_t seq) {
{
if (mp.find(seq) == mp.end()) return 1; if (mp.find(seq) == mp.end()) return 1;
if(get_current_time()-mp[seq].my_time>anti_replay_timeout) if (get_current_time() - mp[seq].my_time > anti_replay_timeout) {
{
replay_buffer[mp[seq].index] = u64_t(i64_t(-1)); replay_buffer[mp[seq].index] = u64_t(i64_t(-1));
mp.erase(seq); mp.erase(seq);
return 1; return 1;
@@ -259,8 +234,7 @@ struct anti_replay_t
} }
}; };
struct blob_encode_t struct blob_encode_t {
{
char input_buf[(max_fec_packet_num + 5) * buf_len]; char input_buf[(max_fec_packet_num + 5) * buf_len];
int current_len; int current_len;
int counter; int counter;
@@ -279,8 +253,7 @@ struct blob_encode_t
int output(int n, char **&s_arr, int &len); int output(int n, char **&s_arr, int &len);
}; };
struct blob_decode_t struct blob_decode_t {
{
char input_buf[(max_fec_packet_num + 5) * buf_len]; char input_buf[(max_fec_packet_num + 5) * buf_len];
int current_len; int current_len;
int last_len; int last_len;
@@ -295,9 +268,7 @@ struct blob_decode_t
int output(int &n, char **&output, int *&len_arr); 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: private:
u32_t seq; u32_t seq;
@@ -308,11 +279,9 @@ private:
// int fec_timeout; // int fec_timeout;
fec_parameter_t fec_par; fec_parameter_t fec_par;
my_time_t first_packet_time; my_time_t first_packet_time;
my_time_t first_packet_time_for_output; my_time_t first_packet_time_for_output;
blob_encode_t blob_encode; blob_encode_t blob_encode;
char input_buf[max_fec_packet_num + 5][buf_len]; char input_buf[max_fec_packet_num + 5][buf_len];
int input_len[max_fec_packet_num + 100]; int input_len[max_fec_packet_num + 100];
@@ -337,46 +306,37 @@ public:
fec_encode_manager_t(); fec_encode_manager_t();
~fec_encode_manager_t(); ~fec_encode_manager_t();
fec_parameter_t & get_fec_par() fec_parameter_t &get_fec_par() {
{
return fec_par; return fec_par;
} }
void set_data(void * data) void set_data(void *data) {
{
timer.data = data; timer.data = data;
} }
void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) {
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->loop = loop;
this->cb = cb; this->cb = cb;
ev_init(&timer, cb); ev_init(&timer, cb);
} }
int clear_data() int clear_data() {
{
counter = 0; counter = 0;
blob_encode.clear(); blob_encode.clear();
ready_for_output = 0; ready_for_output = 0;
seq = (u32_t)get_fake_random_number(); // TODO temp solution for a bug. seq = (u32_t)get_fake_random_number(); // TODO temp solution for a bug.
if(loop) if (loop) {
{
ev_timer_stop(loop, &timer); ev_timer_stop(loop, &timer);
} }
return 0; return 0;
} }
int clear_all() int clear_all() {
{
// itimerspec zero_its; // itimerspec zero_its;
// memset(&zero_its, 0, sizeof(zero_its)); // memset(&zero_its, 0, sizeof(zero_its));
// timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); // timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0);
if(loop) if (loop) {
{
ev_timer_stop(loop, &timer); ev_timer_stop(loop, &timer);
loop = 0; loop = 0;
cb = 0; cb = 0;
@@ -387,18 +347,15 @@ public:
return 0; return 0;
} }
my_time_t get_first_packet_time() my_time_t get_first_packet_time() {
{
return first_packet_time_for_output; return first_packet_time_for_output;
} }
int get_pending_time() int get_pending_time() {
{
return fec_par.timeout; return fec_par.timeout;
} }
int get_type() int get_type() {
{
return fec_par.mode; return fec_par.mode;
} }
// u64_t get_timer_fd64(); // u64_t get_timer_fd64();
@@ -406,8 +363,7 @@ public:
int input(char *s, int len /*,int &is_first_packet*/); int input(char *s, int len /*,int &is_first_packet*/);
int output(int &n, char **&s_arr, int *&len); int output(int &n, char **&s_arr, int *&len);
}; };
struct fec_data_t struct fec_data_t {
{
int used; int used;
u32_t seq; u32_t seq;
int type; int type;
@@ -417,8 +373,7 @@ struct fec_data_t
char buf[buf_len]; char buf[buf_len];
int len; int len;
}; };
struct fec_group_t struct fec_group_t {
{
int type = -1; int type = -1;
int data_num = -1; int data_num = -1;
int redundant_num = -1; int redundant_num = -1;
@@ -427,8 +382,7 @@ struct fec_group_t
// int data_counter=0; // int data_counter=0;
map<int, int> group_mp; map<int, int> group_mp;
}; };
class fec_decode_manager_t:not_copy_able_t class fec_decode_manager_t : not_copy_able_t {
{
anti_replay_t anti_replay; anti_replay_t anti_replay;
fec_data_t *fec_data = 0; fec_data_t *fec_data = 0;
unordered_map<u32_t, fec_group_t> mp; unordered_map<u32_t, fec_group_t> mp;
@@ -445,8 +399,7 @@ class fec_decode_manager_t:not_copy_able_t
int output_len_arr_buf[max_fec_packet_num + 100]; // same int output_len_arr_buf[max_fec_packet_num + 100]; // same
public: public:
fec_decode_manager_t() fec_decode_manager_t() {
{
fec_data = new fec_data_t[fec_buff_num + 5]; fec_data = new fec_data_t[fec_buff_num + 5];
assert(fec_data != 0); assert(fec_data != 0);
clear(); clear();
@@ -456,17 +409,14 @@ public:
{ {
assert(0==1);//not allowed to copy assert(0==1);//not allowed to copy
}*/ }*/
~fec_decode_manager_t() ~fec_decode_manager_t() {
{
mylog(log_debug, "fec_decode_manager destroyed\n"); mylog(log_debug, "fec_decode_manager destroyed\n");
if(fec_data!=0) if (fec_data != 0) {
{
mylog(log_debug, "fec_data freed\n"); mylog(log_debug, "fec_data freed\n");
delete fec_data; delete[] fec_data;
} }
} }
int clear() int clear() {
{
anti_replay.clear(); anti_replay.clear();
mp.clear(); mp.clear();
mp.rehash(fec_buff_num * 3); mp.rehash(fec_buff_num * 3);

View File

@@ -8,35 +8,29 @@
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
void rs_encode(void *code,char *data[],int size) void rs_encode(void *code, char *data[], int size) {
{
int k = get_k(code); int k = get_k(code);
int n = get_n(code); int n = get_n(code);
for(int i=k;i<n;i++) for (int i = k; i < n; i++) {
{
fec_encode(code, (void **)data, data[i], i, size); fec_encode(code, (void **)data, data[i], i, size);
} }
return; return;
} }
int rs_decode(void *code,char *data[],int size) int rs_decode(void *code, char *data[], int size) {
{
int k = get_k(code); int k = get_k(code);
int n = get_n(code); int n = get_n(code);
int index[n]; int index[n];
int count = 0; int count = 0;
for(int i=0;i<n;i++) for (int i = 0; i < n; i++) {
{ if (data[i] != 0) {
if(data[i]!=0)
{
index[count++] = i; index[count++] = i;
} }
} }
if (count < k) if (count < k)
return -1; return -1;
for(int i=0;i<n;i++) for (int i = 0; i < n; i++) {
{
if (i < count) if (i < count)
data[i] = data[index[i]]; data[i] = data[index[i]];
else else
@@ -46,31 +40,25 @@ int rs_decode(void *code,char *data[],int size)
} }
static void *(*table)[256] = 0; static void *(*table)[256] = 0;
void* get_code(int k,int n) void *get_code(int k, int n) {
{ if (table == 0) {
if (table==0)
{
table = (void *(*)[256])malloc(sizeof(void *) * 256 * 256); table = (void *(*)[256])malloc(sizeof(void *) * 256 * 256);
if(!table) if (!table) {
{
return table; return table;
} }
memset(table, 0, sizeof(void *) * 256 * 256); memset(table, 0, sizeof(void *) * 256 * 256);
} }
if(table[k][n]==0) if (table[k][n] == 0) {
{
table[k][n] = fec_new(k, n); table[k][n] = fec_new(k, n);
} }
return table[k][n]; return table[k][n];
} }
void rs_encode2(int k,int n,char *data[],int size) void rs_encode2(int k, int n, char *data[], int size) {
{
void *code = get_code(k, n); void *code = get_code(k, n);
rs_encode(code, data, size); rs_encode(code, data, size);
} }
int rs_decode2(int k,int n,char *data[],int size) int rs_decode2(int k, int n, char *data[], int size) {
{
void *code = get_code(k, n); void *code = get_code(k, n);
return rs_decode(code, data, size); return rs_decode(code, data, size);
} }

View File

@@ -22,7 +22,6 @@
// the function will always succeed,except malloc fail.if malloc fail,it will call exit() // the function will always succeed,except malloc fail.if malloc fail,it will call exit()
void rs_encode(void *code, char *data[], int size); void rs_encode(void *code, char *data[], int size);
// input: // input:
// data[0.....n-1] points to original data and redundate data,in right order // data[0.....n-1] points to original data and redundate data,in right order
// if data[i] is missing ,set poniter data[i] to 0 (point it to null) // if data[i] is missing ,set poniter data[i] to 0 (point it to null)
@@ -39,13 +38,8 @@ void rs_encode(void *code,char *data[],int size);
// 2. if the input data[0.....n-1] contains x non-zero pointers,after called rs_decode,there will still be exactly x non-zero poninters in data[0.....n-1],just the order may change. // 2. if the input data[0.....n-1] contains x non-zero pointers,after called rs_decode,there will still be exactly x non-zero poninters in data[0.....n-1],just the order may change.
int rs_decode(void *code, char *data[], int size); int rs_decode(void *code, char *data[], int size);
void rs_encode2(int k, int n, char *data[], int size); void rs_encode2(int k, int n, char *data[], int size);
int rs_decode2(int k, int n, char *data[], int size); int rs_decode2(int k, int n, char *data[], int size);
#endif /* LIB_RS_H_ */ #endif /* LIB_RS_H_ */

10
log.cpp Executable file → Normal file
View File

@@ -6,13 +6,10 @@ int log_level=log_info;
int enable_log_position = 0; int enable_log_position = 0;
int enable_log_color = 1; int enable_log_color = 1;
void log0(const char* file, const char* function, int line, int level, const char* str, ...) { void log0(const char* file, const char* function, int line, int level, const char* str, ...) {
if (level > log_level) return; if (level > log_level) return;
if (level > log_trace || level < 0) return; if (level > log_trace || level < 0) return;
time_t timer; time_t timer;
char buffer[100]; char buffer[100];
struct tm* tm_info; struct tm* tm_info;
@@ -40,14 +37,12 @@ void log0(const char * file,const char * function,int line,int level,const char*
// printf(log_color[level]); // printf(log_color[level]);
fflush(stdout); fflush(stdout);
if(log_level==log_fatal) if (log_level == log_fatal) {
{
about_to_exit = 1; about_to_exit = 1;
} }
} }
void log_bare(int level,const char* str, ...) void log_bare(int level, const char* str, ...) {
{
if (level > log_level) return; if (level > log_level) return;
if (level > log_trace || level < 0) return; if (level > log_trace || level < 0) return;
if (enable_log_color) if (enable_log_color)
@@ -59,5 +54,4 @@ void log_bare(int level,const char* str, ...)
if (enable_log_color) if (enable_log_color)
printf("%s", RESET); printf("%s", RESET);
fflush(stdout); fflush(stdout);
} }

6
log.h Executable file → Normal file
View File

@@ -2,7 +2,6 @@
#ifndef _LOG_MYLOG_H_ #ifndef _LOG_MYLOG_H_
#define _LOG_MYLOG_H_ #define _LOG_MYLOG_H_
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@@ -15,7 +14,6 @@
using namespace std; using namespace std;
#define RED "\x1B[31m" #define RED "\x1B[31m"
#define GRN "\x1B[32m" #define GRN "\x1B[32m"
#define YEL "\x1B[33m" #define YEL "\x1B[33m"
@@ -25,7 +23,6 @@ using namespace std;
#define WHT "\x1B[37m" #define WHT "\x1B[37m"
#define RESET "\x1B[0m" #define RESET "\x1B[0m"
const int log_never = 0; const int log_never = 0;
const int log_fatal = 1; const int log_fatal = 1;
const int log_error = 2; const int log_error = 2;
@@ -42,7 +39,6 @@ extern int log_level;
extern int enable_log_position; extern int enable_log_position;
extern int enable_log_color; extern int enable_log_color;
#ifdef MY_DEBUG #ifdef MY_DEBUG
#define mylog(__first_argu__dummy_abcde__, ...) printf(__VA_ARGS__) #define mylog(__first_argu__dummy_abcde__, ...) printf(__VA_ARGS__)
@@ -50,12 +46,10 @@ extern int enable_log_color;
#define mylog(...) log0(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) #define mylog(...) log0(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#endif #endif
//#define mylog(__first_argu__dummy_abcde__,...) {;} //#define mylog(__first_argu__dummy_abcde__,...) {;}
void log0(const char* file, const char* function, int line, 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, ...); void log_bare(int level, const char* str, ...);
#endif #endif

View File

@@ -13,9 +13,7 @@
#include "git_version.h" #include "git_version.h"
using namespace std; using namespace std;
static void print_help() {
static void print_help()
{
char git_version_buf[100] = {0}; char git_version_buf[100] = {0};
strncpy(git_version_buf, gitversion, 10); strncpy(git_version_buf, gitversion, 10);
@@ -80,28 +78,21 @@ static void print_help()
// 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) {
void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents)
{
mylog(log_info, "got sigpipe, ignored"); mylog(log_info, "got sigpipe, ignored");
} }
void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) {
{
mylog(log_info, "got sigterm, exit"); mylog(log_info, "got sigterm, exit");
myexit(0); myexit(0);
} }
void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) {
{
mylog(log_info, "got sigint, exit"); mylog(log_info, "got sigint, exit");
myexit(0); myexit(0);
} }
int main(int argc, char *argv[]) {
int main(int argc, char *argv[])
{
working_mode = tunnel_mode; working_mode = tunnel_mode;
init_ws(); init_ws();
// unit_test(); // unit_test();
@@ -132,15 +123,12 @@ int main(int argc, char *argv[])
dup2(1, 2); // redirect stderr to stdout dup2(1, 2); // redirect stderr to stdout
int i, j, k; int i, j, k;
if (argc == 1) if (argc == 1) {
{
print_help(); print_help();
myexit(-1); myexit(-1);
} }
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++) {
{ if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0)
{
print_help(); print_help();
myexit(0); myexit(0);
} }
@@ -150,20 +138,15 @@ int main(int argc, char *argv[])
delay_manager.set_capacity(delay_capacity); delay_manager.set_capacity(delay_capacity);
if(strlen(tun_dev)==0) if (strlen(tun_dev) == 0) {
{
sprintf(tun_dev, "tun%u", get_fake_random_number() % 1000); sprintf(tun_dev, "tun%u", get_fake_random_number() % 1000);
} }
if(program_mode==client_mode) if (program_mode == client_mode) {
{
tunnel_client_event_loop(); tunnel_client_event_loop();
} } else {
else
{
tunnel_server_event_loop(); tunnel_server_event_loop();
} }
return 0; return 0;
} }

View File

@@ -10,7 +10,7 @@ cc_amd64=/toolchains/lede-sdk-17.01.2-x86-64_gcc-5.4.0_musl-1.1.16.Linux-x86_64/
#cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ #cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++
SOURCES0=main.cpp log.cpp common.cpp lib/fec.cpp lib/rs.cpp packet.cpp delay_manager.cpp fd_manager.cpp connection.cpp fec_manager.cpp misc.cpp tunnel_client.cpp tunnel_server.cpp SOURCES0=main.cpp log.cpp common.cpp lib/fec.cpp lib/rs.cpp crc32/Crc32.cpp packet.cpp delay_manager.cpp fd_manager.cpp connection.cpp fec_manager.cpp misc.cpp tunnel_client.cpp tunnel_server.cpp
SOURCES=${SOURCES0} my_ev.cpp -isystem libev SOURCES=${SOURCES0} my_ev.cpp -isystem libev
NAME=speederv2 NAME=speederv2

479
misc.cpp

File diff suppressed because it is too large Load Diff

5
misc.h
View File

@@ -14,8 +14,6 @@
#include "delay_manager.h" #include "delay_manager.h"
#include "fec_manager.h" #include "fec_manager.h"
extern char fifo_file[1000]; extern char fifo_file[1000];
extern int mtu_warn; extern int mtu_warn;
@@ -26,7 +24,6 @@ extern int disable_checksum;
extern int debug_force_flush_fec; extern int debug_force_flush_fec;
extern int jitter_min; extern int jitter_min;
extern int jitter_max; extern int jitter_max;
@@ -39,7 +36,6 @@ extern int fix_latency;
// extern char local_ip[100], remote_ip[100]; // extern char local_ip[100], remote_ip[100];
// extern int local_port, remote_port; // 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 address_t *out_addr;
@@ -62,7 +58,6 @@ extern int mssfix;
extern int manual_set_tun; extern int manual_set_tun;
extern int persist_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_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_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);

View File

@@ -2,4 +2,3 @@
#include "my_ev_common.h" #include "my_ev_common.h"
#include "ev.h" #include "ev.h"

View File

@@ -1,6 +1,8 @@
#define EV_STANDALONE 1 #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_COMPAT3 0
//#define EV_VERIFY 2 //#define EV_VERIFY 2

View File

@@ -5,11 +5,11 @@
* Author: root * Author: root
*/ */
#include "common.h" #include "common.h"
#include "log.h" #include "log.h"
#include "packet.h" #include "packet.h"
#include "misc.h" #include "misc.h"
#include "crc32/Crc32.h"
int iv_min = 4; int iv_min = 4;
int iv_max = 32; //< 256; int iv_max = 32; //< 256;
@@ -30,30 +30,24 @@ char key_string[1000]= "";
// int local_listen_fd=-1; // int local_listen_fd=-1;
void encrypt_0(char *input, int &len, char *key) {
void encrypt_0(char * input,int &len,char *key)
{
int i, j; int i, j;
if (key[0] == 0) return; if (key[0] == 0) return;
for(i=0,j=0;i<len;i++,j++) for (i = 0, j = 0; i < len; i++, j++) {
{
if (key[j] == 0) j = 0; if (key[j] == 0) j = 0;
input[i] ^= key[j]; input[i] ^= key[j];
} }
} }
void decrypt_0(char * input,int &len,char *key) void decrypt_0(char *input, int &len, char *key) {
{
int i, j; int i, j;
if (key[0] == 0) return; if (key[0] == 0) return;
for(i=0,j=0;i<len;i++,j++) for (i = 0, j = 0; i < len; i++, j++) {
{
if (key[j] == 0) j = 0; if (key[j] == 0) j = 0;
input[i] ^= key[j]; input[i] ^= key[j];
} }
} }
int do_obscure_old(const char * input, int in_len,char *output,int &out_len) int do_obscure_old(const char *input, int in_len, char *output, int &out_len) {
{
// memcpy(output,input,in_len); // memcpy(output,input,in_len);
// out_len=in_len; // out_len=in_len;
// return 0; // return 0;
@@ -70,29 +64,25 @@ int do_obscure_old(const char * input, int in_len,char *output,int &out_len)
output[iv_len + in_len] ^= output[0]; output[iv_len + in_len] ^= output[0];
output[iv_len + in_len] ^= key_string[0]; output[iv_len + in_len] ^= key_string[0];
for(i=0,j=0,k=1;i<in_len;i++,j++,k++) for (i = 0, j = 0, k = 1; i < in_len; i++, j++, k++) {
{
if (j == iv_len) j = 0; if (j == iv_len) j = 0;
if (key_string[k] == 0) k = 0; if (key_string[k] == 0) k = 0;
output[iv_len + i] ^= output[j]; output[iv_len + i] ^= output[j];
output[iv_len + i] ^= key_string[k]; output[iv_len + i] ^= key_string[k];
} }
out_len = iv_len + in_len + 1; out_len = iv_len + in_len + 1;
return 0; return 0;
} }
int do_obscure(char * data,int &len) int do_obscure(char *data, int &len) {
{
assert(len >= 0); assert(len >= 0);
assert(len < buf_len); assert(len < buf_len);
int iv_len = random_between(iv_min, iv_max); int iv_len = random_between(iv_min, iv_max);
get_fake_random_chars(data + len, iv_len); get_fake_random_chars(data + len, iv_len);
data[iv_len + len] = (uint8_t)iv_len; data[iv_len + len] = (uint8_t)iv_len;
for(int i=0,j=0;i<len;i++,j++) for (int i = 0, j = 0; i < len; i++, j++) {
{
if (j == iv_len) j = 0; if (j == iv_len) j = 0;
data[i] ^= data[len + j]; data[i] ^= data[len + j];
} }
@@ -101,47 +91,40 @@ int do_obscure(char * data,int &len)
return 0; return 0;
} }
int de_obscure(char * data,int &len) int de_obscure(char *data, int &len) {
{
if (len < 1) return -1; if (len < 1) return -1;
int iv_len = int((uint8_t)data[len - 1]); int iv_len = int((uint8_t)data[len - 1]);
if (len < 1 + iv_len) return -1; if (len < 1 + iv_len) return -1;
len = len - 1 - iv_len; len = len - 1 - iv_len;
for(int i=0,j=0;i<len;i++,j++) for (int i = 0, j = 0; i < len; i++, j++) {
{
if (j == iv_len) j = 0; if (j == iv_len) j = 0;
data[i] ^= data[len + j]; data[i] ^= data[len + j];
} }
return 0; return 0;
} }
int de_obscure_old(const char * input, int in_len,char *output,int &out_len) int de_obscure_old(const char *input, int in_len, char *output, int &out_len) {
{
// memcpy(output,input,in_len); // memcpy(output,input,in_len);
// out_len=in_len; // out_len=in_len;
// return 0; // return 0;
int i, j, k; int i, j, k;
if (in_len > 65535||in_len<0) if (in_len > 65535 || in_len < 0) {
{
mylog(log_debug, "in_len > 65535||in_len<0 , %d", in_len); mylog(log_debug, "in_len > 65535||in_len<0 , %d", in_len);
return -1; return -1;
} }
int iv_len = int((uint8_t)(input[in_len - 1] ^ input[0] ^ key_string[0])); int iv_len = int((uint8_t)(input[in_len - 1] ^ input[0] ^ key_string[0]));
out_len = in_len - 1 - iv_len; out_len = in_len - 1 - iv_len;
if(out_len<0) if (out_len < 0) {
{
mylog(log_debug, "%d %d\n", in_len, out_len); mylog(log_debug, "%d %d\n", in_len, out_len);
return -1; return -1;
} }
for(i=0,j=0,k=1;i<in_len;i++,j++,k++) for (i = 0, j = 0, k = 1; i < in_len; i++, j++, k++) {
{
if (j == iv_len) j = 0; if (j == iv_len) j = 0;
if (key_string[k] == 0) k = 0; if (key_string[k] == 0) k = 0;
output[i] = input[iv_len + i] ^ input[j] ^ key_string[k]; output[i] = input[iv_len + i] ^ input[j] ^ key_string[k];
} }
dup_packet_recv_count++; dup_packet_recv_count++;
return 0; return 0;
@@ -164,9 +147,7 @@ int sendto_fd_ip_port (int fd,u32_t ip,int port,char * buf, int len,int flags)
sizeof(tmp_sockaddr)); sizeof(tmp_sockaddr));
}*/ }*/
int sendto_fd_addr (int fd,address_t addr,char * buf, int len,int flags) int sendto_fd_addr(int fd, address_t addr, char *buf, int len, int flags) {
{
return sendto(fd, buf, return sendto(fd, buf,
len, 0, len, 0,
(struct sockaddr *)&addr.inner, (struct sockaddr *)&addr.inner,
@@ -178,45 +159,35 @@ 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) int send_fd(int fd, char *buf, int len, int flags) {
{
return send(fd, buf, len, flags); return send(fd, buf, len, flags);
} }
int my_send(const dest_t &dest,char *data,int len) int my_send(const dest_t &dest, char *data, int len) {
{ if (dest.cook) {
if(dest.cook)
{
do_cook(data, len); do_cook(data, len);
} }
switch(dest.type) switch (dest.type) {
{ case type_fd_addr: {
case type_fd_addr:
{
return sendto_fd_addr(dest.inner.fd, dest.inner.fd_addr.addr, data, len, 0); return sendto_fd_addr(dest.inner.fd, dest.inner.fd_addr.addr, data, len, 0);
break; break;
} }
case type_fd64_addr: case type_fd64_addr: {
{
if (!fd_manager.exist(dest.inner.fd64)) return -1; if (!fd_manager.exist(dest.inner.fd64)) return -1;
int fd = fd_manager.to_fd(dest.inner.fd64); int fd = fd_manager.to_fd(dest.inner.fd64);
return sendto_fd_addr(fd, dest.inner.fd64_addr.addr, data, len, 0); return sendto_fd_addr(fd, dest.inner.fd64_addr.addr, data, len, 0);
break; break;
} }
case type_fd: case type_fd: {
{
return send_fd(dest.inner.fd, data, len, 0); return send_fd(dest.inner.fd, data, len, 0);
break; break;
} }
case type_write_fd: case type_write_fd: {
{
return write(dest.inner.fd, data, len); return write(dest.inner.fd, data, len);
break; break;
} }
case type_fd64: case type_fd64: {
{
if (!fd_manager.exist(dest.inner.fd64)) return -1; if (!fd_manager.exist(dest.inner.fd64)) return -1;
int fd = fd_manager.to_fd(dest.inner.fd64); int fd = fd_manager.to_fd(dest.inner.fd64);
@@ -260,48 +231,20 @@ int my_send(const dest_t &dest,char *data,int len)
return 0; return 0;
} }
/* int put_conv0(u32_t conv, const char *input, int len_in, char *&output, int &len_out) {
* 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;
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); assert(len_in >= 0);
static char buf[buf_len]; static char buf[buf_len];
output = buf; output = buf;
u32_t n_conv = htonl(conv); u32_t n_conv = htonl(conv);
memcpy(output, &n_conv, sizeof(n_conv)); memcpy(output, &n_conv, sizeof(n_conv));
memcpy(output + sizeof(n_conv), input, len_in); memcpy(output + sizeof(n_conv), input, len_in);
u32_t crc32=crc32h((unsigned char *)output,len_in+sizeof(crc32)); u32_t crc32 = (u32_t)crc32_fast(output, len_in + sizeof(crc32));
u32_t crc32_n = htonl(crc32); u32_t crc32_n = htonl(crc32);
len_out = len_in + (int)(sizeof(n_conv)) + (int)sizeof(crc32_n); 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)); memcpy(output + len_in + (int)(sizeof(n_conv)), &crc32_n, sizeof(crc32_n));
return 0; return 0;
} }
int get_conv0(u32_t &conv,const char *input,int len_in,char *&output,int &len_out ) int get_conv0(u32_t &conv, const char *input, int len_in, char *&output, int &len_out) {
{
assert(len_in >= 0); assert(len_in >= 0);
u32_t n_conv; u32_t n_conv;
memcpy(&n_conv, input, sizeof(n_conv)); memcpy(&n_conv, input, sizeof(n_conv));
@@ -309,69 +252,59 @@ int get_conv0(u32_t &conv,const char *input,int len_in,char *&output,int &len_ou
output = (char *)input + sizeof(n_conv); output = (char *)input + sizeof(n_conv);
u32_t crc32_n; u32_t crc32_n;
len_out = len_in - (int)sizeof(n_conv) - (int)sizeof(crc32_n); len_out = len_in - (int)sizeof(n_conv) - (int)sizeof(crc32_n);
if(len_out<0) if (len_out < 0) {
{
mylog(log_debug, "len_out<0\n"); mylog(log_debug, "len_out<0\n");
return -1; return -1;
} }
memcpy(&crc32_n, input + len_in - (int)sizeof(crc32_n), sizeof(crc32_n)); memcpy(&crc32_n, input + len_in - (int)sizeof(crc32_n), sizeof(crc32_n));
u32_t crc32 = ntohl(crc32_n); u32_t crc32 = ntohl(crc32_n);
if(crc32!=crc32h((unsigned char *)input,len_in-(int)sizeof(crc32_n))) if (crc32 != (u32_t)crc32_fast(input, len_in - sizeof(crc32_n))) {
{
mylog(log_debug, "crc32 check failed\n"); mylog(log_debug, "crc32 check failed\n");
return -1; return -1;
} }
return 0; return 0;
} }
int put_crc32(char * s,int &len) int put_crc32(char *s, int &len) {
{
if (disable_checksum) return 0; if (disable_checksum) return 0;
assert(len >= 0); assert(len >= 0);
// if(len<0) return -1; // if(len<0) return -1;
u32_t crc32=crc32h((unsigned char *)s,len); u32_t crc32 = (u32_t)crc32_fast(s, len);
write_u32(s + len, crc32); write_u32(s + len, crc32);
len += sizeof(u32_t); len += sizeof(u32_t);
return 0; return 0;
} }
int do_cook(char * data,int &len) int do_cook(char *data, int &len) {
{
put_crc32(data, len); put_crc32(data, len);
if (!disable_obscure) do_obscure(data, len); if (!disable_obscure) do_obscure(data, len);
if (!disable_xor) encrypt_0(data, len, key_string); if (!disable_xor) encrypt_0(data, len, key_string);
return 0; return 0;
} }
int de_cook(char * s,int &len) int de_cook(char *s, int &len) {
{
if (!disable_xor) decrypt_0(s, len, key_string); if (!disable_xor) decrypt_0(s, len, key_string);
if(!disable_obscure) if (!disable_obscure) {
{
int ret = de_obscure(s, len); int ret = de_obscure(s, len);
if(ret!=0) if (ret != 0) {
{
mylog(log_debug, "de_obscure fail\n"); mylog(log_debug, "de_obscure fail\n");
return ret; return ret;
} }
} }
int ret = rm_crc32(s, len); int ret = rm_crc32(s, len);
if(ret!=0) if (ret != 0) {
{
mylog(log_debug, "rm_crc32 fail\n"); mylog(log_debug, "rm_crc32 fail\n");
return ret; return ret;
} }
return 0; return 0;
} }
int rm_crc32(char * s,int &len) int rm_crc32(char *s, int &len) {
{
if (disable_checksum) return 0; if (disable_checksum) return 0;
assert(len >= 0); assert(len >= 0);
len -= sizeof(u32_t); len -= sizeof(u32_t);
if (len < 0) return -1; if (len < 0) return -1;
u32_t crc32_in = read_u32(s + len); u32_t crc32_in = read_u32(s + len);
u32_t crc32=crc32h((unsigned char *)s,len); u32_t crc32 = (u32_t)crc32_fast(s, len);
if (crc32 != crc32_in) return -1; if (crc32 != crc32_in) return -1;
return 0; return 0;
} }
@@ -381,8 +314,7 @@ int do_obs()
} }
int de_obs()*/ int de_obs()*/
int put_conv(u32_t conv,const char * input,int len_in,char *&output,int &len_out) int put_conv(u32_t conv, const char *input, int len_in, char *&output, int &len_out) {
{
static char buf[buf_len]; static char buf[buf_len];
output = buf; output = buf;
u32_t n_conv = htonl(conv); u32_t n_conv = htonl(conv);
@@ -392,20 +324,15 @@ int put_conv(u32_t conv,const char * input,int len_in,char *&output,int &len_out
return 0; return 0;
} }
int get_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) {
{
u32_t n_conv; u32_t n_conv;
memcpy(&n_conv, input, sizeof(n_conv)); memcpy(&n_conv, input, sizeof(n_conv));
conv = ntohl(n_conv); conv = ntohl(n_conv);
output = (char *)input + sizeof(n_conv); output = (char *)input + sizeof(n_conv);
len_out = len_in - (int)sizeof(n_conv); len_out = len_in - (int)sizeof(n_conv);
if(len_out<0) if (len_out < 0) {
{
mylog(log_debug, "len_out<0\n"); mylog(log_debug, "len_out<0\n");
return -1; return -1;
} }
return 0; return 0;
} }

View File

@@ -24,7 +24,6 @@ extern int random_drop;
extern int disable_obscure; extern int disable_obscure;
extern int disable_xor; 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 encrypt_0(char *input, int &len, char *key);

View File

@@ -8,7 +8,6 @@
#ifndef TUNNEL_H_ #ifndef TUNNEL_H_
#define TUNNEL_H_ #define TUNNEL_H_
#include "misc.h" #include "misc.h"
int tunnel_client_event_loop(); int tunnel_client_event_loop();

View File

@@ -1,7 +1,6 @@
#include "tunnel.h" #include "tunnel.h"
void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out) void data_from_local_or_fec_timeout(conn_info_t &conn_info, int is_time_out) {
{
fd64_t &remote_fd64 = conn_info.remote_fd64; fd64_t &remote_fd64 = conn_info.remote_fd64;
int &local_listen_fd = conn_info.local_listen_fd; int &local_listen_fd = conn_info.local_listen_fd;
@@ -9,14 +8,16 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
int data_len; int data_len;
address_t addr; address_t addr;
u32_t conv; u32_t conv;
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; int out_n;
char **out_arr;
int *out_len;
my_time_t *out_delay;
dest_t dest; dest_t dest;
dest.type = type_fd64; dest.type = type_fd64;
dest.inner.fd64 = remote_fd64; dest.inner.fd64 = remote_fd64;
dest.cook = 1; dest.cook = 1;
if(is_time_out) if (is_time_out) {
{
// fd64_t fd64=events[idx].data.u64; // fd64_t fd64=events[idx].data.u64;
mylog(log_trace, "events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n"); mylog(log_trace, "events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n");
@@ -38,8 +39,7 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
// } // }
// assert(value==1); // assert(value==1);
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); 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
else//events[idx].data.u64 == (u64_t)local_listen_fd
{ {
mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n"); mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n");
address_t::storage_t udp_new_addr_in = {0}; address_t::storage_t udp_new_addr_in = {0};
@@ -50,37 +50,30 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
return; return;
}; };
if(data_len==max_data_len+1) 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);
mylog(log_warn,"huge packet, data_len > %d, packet truncated, dropped\n",max_data_len);
return; return;
} }
if(!disable_mtu_warn&&data_len>=mtu_warn) 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_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); 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); mylog(log_trace, "Received packet from %s, len: %d\n", addr.get_str(), data_len);
// u64_t u64=ip_port.to_u64(); // u64_t u64=ip_port.to_u64();
if(!conn_info.conv_manager.c.is_data_used(addr)) if (!conn_info.conv_manager.c.is_data_used(addr)) {
{ if (conn_info.conv_manager.c.get_size() >= max_conv_num) {
if(conn_info.conv_manager.c.get_size() >=max_conv_num)
{
mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n"); mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
return; return;
} }
conv = conn_info.conv_manager.c.get_new_conv(); conv = conn_info.conv_manager.c.get_new_conv();
conn_info.conv_manager.c.insert_conv(conv, addr); conn_info.conv_manager.c.insert_conv(conv, addr);
mylog(log_info, "new packet from %s,conv_id=%x\n", addr.get_str(), conv); mylog(log_info, "new packet from %s,conv_id=%x\n", addr.get_str(), conv);
} } else {
else
{
conv = conn_info.conv_manager.c.find_conv_by_data(addr); conv = conn_info.conv_manager.c.find_conv_by_data(addr);
mylog(log_trace, "conv=%d\n", conv); mylog(log_trace, "conv=%d\n", conv);
} }
@@ -89,19 +82,15 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
int new_len; int new_len;
put_conv(conv, data, data_len, new_data, 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); 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); 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); mylog(log_trace, "out_n=%d\n", out_n);
for(int i=0;i<out_n;i++) for (int i = 0; i < out_n; i++) {
{
delay_send(out_delay[i], dest, out_arr[i], out_len[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) static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
conn_info_t &conn_info = *((conn_info_t *)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
@@ -109,8 +98,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
data_from_local_or_fec_timeout(conn_info, 0); data_from_local_or_fec_timeout(conn_info, 0);
} }
static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
conn_info_t &conn_info = *((conn_info_t *)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
@@ -130,52 +118,46 @@ static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
int data_len = recv(fd, data, max_data_len + 1, 0); int data_len = recv(fd, data, max_data_len + 1, 0);
if(data_len==max_data_len+1) if (data_len == max_data_len + 1) {
{
mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len); mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len);
return; return;
} }
mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd, data_len); mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd, data_len);
if(data_len<0) if (data_len < 0) {
{ if (get_sock_errno() == ECONNREFUSED) {
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_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()); mylog(log_warn, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error());
return; return;
} }
if(!disable_mtu_warn&&data_len>mtu_warn) 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_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) if (de_cook(data, data_len) != 0) {
{
mylog(log_debug, "de_cook error"); mylog(log_debug, "de_cook error");
return; return;
} }
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; 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); 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); mylog(log_trace, "out_n=%d\n", out_n);
for(int i=0;i<out_n;i++) for (int i = 0; i < out_n; i++) {
{
u32_t conv; u32_t conv;
char *new_data; char *new_data;
int new_len; int new_len;
if(get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0) 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"); mylog(log_debug, "get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0");
continue; continue;
} }
if(!conn_info.conv_manager.c.is_conv_used(conv)) if (!conn_info.conv_manager.c.is_conv_used(conv)) {
{
mylog(log_trace, "!conn_info.conv_manager.is_conv_used(conv)"); mylog(log_trace, "!conn_info.conv_manager.is_conv_used(conv)");
continue; continue;
} }
@@ -192,15 +174,13 @@ static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
} }
} }
static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
int fifo_fd = watcher->fd; int fifo_fd = watcher->fd;
char buf[buf_len]; char buf[buf_len];
int len = read(fifo_fd, buf, sizeof(buf)); int len = read(fifo_fd, buf, sizeof(buf));
if(len<0) if (len < 0) {
{
mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error()); mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error());
return; return;
} }
@@ -208,8 +188,7 @@ static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
handle_command(buf); handle_command(buf);
} }
static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
// uint64_t value; // uint64_t value;
@@ -219,18 +198,15 @@ static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int
// do nothing // do nothing
} }
static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); 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_local_or_fec_timeout(conn_info, 1); data_from_local_or_fec_timeout(conn_info, 1);
} }
static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
uint64_t value; uint64_t value;
@@ -243,35 +219,34 @@ static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int re
conn_info.stat.report_as_client(); conn_info.stat.report_as_client();
if(debug_force_flush_fec) if (debug_force_flush_fec) {
{ int out_n;
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; char **out_arr;
int *out_len;
my_time_t *out_delay;
dest_t dest; dest_t dest;
dest.type = type_fd64; dest.type = type_fd64;
dest.inner.fd64 = conn_info.remote_fd64; dest.inner.fd64 = conn_info.remote_fd64;
dest.cook = 1; dest.cook = 1;
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
for(int i=0;i<out_n;i++) for (int i = 0; i < out_n; i++) {
{
delay_send(out_delay[i], dest, out_arr[i], out_len[i]); delay_send(out_delay[i], dest, out_arr[i], out_len[i]);
} }
} }
} }
static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
delay_manager.check(); delay_manager.check();
} }
int tunnel_client_event_loop() int tunnel_client_event_loop() {
{ int i, j, k;
int i, j, k;int ret; int ret;
int yes = 1; int yes = 1;
// int epoll_fd; // int epoll_fd;
conn_info_t *conn_info_p = new conn_info_t; 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 conn_info_t &conn_info = *conn_info_p; // huge size of conn_info,do not allocate on stack
@@ -330,7 +305,6 @@ int tunnel_client_event_loop()
ev_io_init(&remote_watcher, remote_cb, remote_fd, EV_READ); ev_io_init(&remote_watcher, remote_cb, remote_fd, EV_READ);
ev_io_start(loop, &remote_watcher); ev_io_start(loop, &remote_watcher);
// ev.events = EPOLLIN; // ev.events = EPOLLIN;
// ev.data.u64 = delay_manager.get_timer_fd(); // ev.data.u64 = delay_manager.get_timer_fd();
@@ -366,15 +340,11 @@ int tunnel_client_event_loop()
// mylog(log_debug,"conn_info.timer.get_timer_fd()=%d\n",conn_info.timer.get_timer_fd()); // mylog(log_debug,"conn_info.timer.get_timer_fd()=%d\n",conn_info.timer.get_timer_fd());
struct ev_io fifo_watcher; struct ev_io fifo_watcher;
int fifo_fd = -1; int fifo_fd = -1;
if(fifo_file[0]!=0) if (fifo_file[0] != 0) {
{
fifo_fd = create_fifo(fifo_file); fifo_fd = create_fifo(fifo_file);
// ev.events = EPOLLIN; // ev.events = EPOLLIN;
// ev.data.u64 = fifo_fd; // ev.data.u64 = fifo_fd;
@@ -388,7 +358,6 @@ int tunnel_client_event_loop()
ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ);
ev_io_start(loop, &fifo_watcher); ev_io_start(loop, &fifo_watcher);
} }
ev_prepare prepare_watcher; ev_prepare prepare_watcher;

View File

@@ -11,10 +11,11 @@ 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 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); 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) void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t &conn_info, fd64_t fd64, tmp_mode_t mode) {
{
int ret; int ret;
char data[buf_len]; char data[buf_len];
@@ -23,18 +24,19 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
// fd64_t fd64=events[idx].data.u64; // 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); // mylog(log_trace,"events[idx].data.u64 >u32_t(-1),%llu\n",(u64_t)events[idx].data.u64);
// assert(fd_manager.exist_info(fd64)); // assert(fd_manager.exist_info(fd64));
// ip_port_t ip_port=fd_manager.get_info(fd64).ip_port; // ip_port_t ip_port=fd_manager.get_info(fd64).ip_port;
// conn_info_t &conn_info=conn_manager.find(ip_port); // conn_info_t &conn_info=conn_manager.find(ip_port);
address_t &addr = conn_info.addr; address_t &addr = conn_info.addr;
assert(conn_manager.exist(addr)); assert(conn_manager.exist(addr));
int &local_listen_fd = conn_info.local_listen_fd; int &local_listen_fd = conn_info.local_listen_fd;
int out_n=-2;char **out_arr;int *out_len;my_time_t *out_delay; int out_n = -2;
char **out_arr;
int *out_len;
my_time_t *out_delay;
dest_t dest; dest_t dest;
dest.inner.fd_addr.fd = local_listen_fd; dest.inner.fd_addr.fd = local_listen_fd;
@@ -42,8 +44,7 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
dest.type = type_fd_addr; dest.type = type_fd_addr;
dest.cook = 1; dest.cook = 1;
if(mode==is_fec_timeout) if (mode == is_fec_timeout) {
{
assert(fd64 == 0); assert(fd64 == 0);
// uint64_t value; // uint64_t value;
// if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8) // if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8)
@@ -58,23 +59,18 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
// } // }
// assert(value==1); // assert(value==1);
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
} } else if (mode == is_conn_timer) {
else if(mode==is_conn_timer)
{
assert(fd64 == 0); assert(fd64 == 0);
// uint64_t value; // uint64_t value;
// read(conn_info.timer.get_timer_fd(), &value, 8); // read(conn_info.timer.get_timer_fd(), &value, 8);
conn_info.conv_manager.s.clear_inactive(); conn_info.conv_manager.s.clear_inactive();
if(debug_force_flush_fec) if (debug_force_flush_fec) {
{
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay); from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
} }
conn_info.stat.report_as_server(addr); conn_info.stat.report_as_server(addr);
return; return;
} } else if (mode == is_from_remote) {
else if(mode==is_from_remote)
{
if (!fd_manager.exist(fd64)) // fd64 has been closed if (!fd_manager.exist(fd64)) // fd64 has been closed
{ {
mylog(log_warn, "!fd_manager.exist(fd64)\n"); mylog(log_warn, "!fd_manager.exist(fd64)\n");
@@ -91,23 +87,20 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
int fd = fd_manager.to_fd(fd64); int fd = fd_manager.to_fd(fd64);
data_len = recv(fd, data, max_data_len + 1, 0); data_len = recv(fd, data, max_data_len + 1, 0);
if(data_len==max_data_len+1) 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);
mylog(log_warn,"huge packet, data_len > %d, packet truncated, dropped\n",max_data_len);
return; return;
} }
mylog(log_trace, "received a packet from udp_fd,len:%d,conv=%d\n", data_len, conv); mylog(log_trace, "received a packet from udp_fd,len:%d,conv=%d\n", data_len, conv);
if(data_len<0) if (data_len < 0) {
{
mylog(log_debug, "udp fd,recv_len<0 continue,%s\n", get_sock_error()); mylog(log_debug, "udp fd,recv_len<0 continue,%s\n", get_sock_error());
return; return;
} }
if(!disable_mtu_warn&&data_len>=mtu_warn) 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_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);
} }
@@ -116,21 +109,17 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
put_conv(conv, data, data_len, new_data, 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); from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay);
} } else {
else
{
assert(0 == 1); assert(0 == 1);
} }
mylog(log_trace, "out_n=%d\n", out_n); mylog(log_trace, "out_n=%d\n", out_n);
for(int i=0;i<out_n;i++) for (int i = 0; i < out_n; i++) {
{
delay_send(out_delay[i], dest, out_arr[i], out_len[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) static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
int local_listen_fd = watcher->fd; int local_listen_fd = watcher->fd;
@@ -147,8 +136,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
return; return;
}; };
if(data_len==max_data_len+1) if (data_len == max_data_len + 1) {
{
mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len); mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len);
return; return;
} }
@@ -163,19 +151,13 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
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_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) {
if(de_cook(data,data_len)!=0)
{
mylog(log_debug, "de_cook error"); mylog(log_debug, "de_cook error");
return; return;
} }
if (!conn_manager.exist(addr)) {
if (conn_manager.mp.size() >= max_conn_num) {
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()); mylog(log_warn, "new connection %s ignored bc max_conn_num exceed\n", addr.get_str());
return; return;
} }
@@ -207,38 +189,32 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
// u64_t timer_fd64=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; // 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_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);
mylog(log_info, "new connection from %s\n", addr.get_str()); mylog(log_info, "new connection from %s\n", addr.get_str());
} }
conn_info_t &conn_info = conn_manager.find_insert(addr); conn_info_t &conn_info = conn_manager.find_insert(addr);
conn_info.update_active_time(); conn_info.update_active_time();
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; 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); 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); mylog(log_trace, "out_n= %d\n", out_n);
for(int i=0;i<out_n;i++) for (int i = 0; i < out_n; i++) {
{
u32_t conv; u32_t conv;
char *new_data; char *new_data;
int new_len; int new_len;
if(get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0) if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) {
{
mylog(log_debug, "get_conv failed"); mylog(log_debug, "get_conv failed");
continue; continue;
} }
if (!conn_info.conv_manager.s.is_conv_used(conv)) {
if (!conn_info.conv_manager.s.is_conv_used(conv)) if (conn_info.conv_manager.s.get_size() >= max_conv_num) {
{
if(conn_info.conv_manager.s.get_size() >=max_conv_num)
{
mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n"); mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
continue; continue;
} }
@@ -267,7 +243,6 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
ev_io_set(&io_watcher, new_udp_fd, EV_READ); ev_io_set(&io_watcher, new_udp_fd, EV_READ);
ev_io_start(conn_info.loop, &io_watcher); 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); 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); conn_info.conv_manager.s.update_active_time(conv);
@@ -279,8 +254,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
} }
} }
static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
conn_info_t &conn_info = *((conn_info_t *)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
@@ -289,16 +263,14 @@ static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
data_from_remote_or_fec_timeout_or_conn_timer(conn_info, fd64, is_from_remote); data_from_remote_or_fec_timeout_or_conn_timer(conn_info, fd64, is_from_remote);
} }
static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
int fifo_fd = watcher->fd; int fifo_fd = watcher->fd;
char buf[buf_len]; char buf[buf_len];
int len = read(fifo_fd, buf, sizeof(buf)); int len = read(fifo_fd, buf, sizeof(buf));
if(len<0) if (len < 0) {
{
mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error()); mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error());
return; return;
} }
@@ -306,8 +278,7 @@ static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
handle_command(buf); handle_command(buf);
} }
static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
// uint64_t value; // uint64_t value;
@@ -315,11 +286,9 @@ static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int
// mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); // mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n");
// do nothing // do nothing
} }
static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
conn_info_t &conn_info = *((conn_info_t *)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
@@ -327,8 +296,7 @@ static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int re
data_from_remote_or_fec_timeout_or_conn_timer(conn_info, 0, is_fec_timeout); data_from_remote_or_fec_timeout_or_conn_timer(conn_info, 0, is_fec_timeout);
} }
static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
conn_info_t &conn_info = *((conn_info_t *)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
@@ -336,15 +304,13 @@ static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int re
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_conn_timer);
} }
static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
delay_manager.check(); delay_manager.check();
} }
static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{
assert(!(revents & EV_ERROR)); assert(!(revents & EV_ERROR));
// uint64_t value; // uint64_t value;
@@ -353,10 +319,9 @@ static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int
mylog(log_trace, "events[idx].data.u64==(u64_t)timer.get_timer_fd()\n"); mylog(log_trace, "events[idx].data.u64==(u64_t)timer.get_timer_fd()\n");
} }
int tunnel_server_event_loop() int tunnel_server_event_loop() {
{ int i, j, k;
int ret;
int i, j, k;int ret;
int yes = 1; int yes = 1;
// int epoll_fd; // int epoll_fd;
// int remote_fd; // int remote_fd;
@@ -417,8 +382,7 @@ int tunnel_server_event_loop()
int fifo_fd = -1; int fifo_fd = -1;
if(fifo_file[0]!=0) if (fifo_file[0] != 0) {
{
fifo_fd = create_fifo(fifo_file); fifo_fd = create_fifo(fifo_file);
// ev.events = EPOLLIN; // ev.events = EPOLLIN;
// ev.data.u64 = fifo_fd; // ev.data.u64 = fifo_fd;
@@ -438,7 +402,6 @@ int tunnel_server_event_loop()
ev_init(&prepare_watcher, prepare_cb); ev_init(&prepare_watcher, prepare_cb);
ev_prepare_start(loop, &prepare_watcher); ev_prepare_start(loop, &prepare_watcher);
ev_run(loop, 0); ev_run(loop, 0);
mylog(log_warn, "ev_run returned\n"); mylog(log_warn, "ev_run returned\n");
@@ -497,7 +460,5 @@ int tunnel_server_event_loop()
}*/ }*/
return 0; return 0;
} }