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

169
common.h
View File

@@ -51,7 +51,6 @@ typedef int socklen_t;
#include <netinet/in.h>
#endif
#include <unordered_map>
#include <unordered_set>
#include <map>
@@ -60,7 +59,6 @@ typedef int socklen_t;
#include <vector>
using namespace std;
typedef unsigned long long u64_t; // this works on most platform,avoid using the PRId64
typedef long long i64_t;
@@ -70,7 +68,6 @@ typedef int i32_t;
typedef unsigned short u16_t;
typedef short i16_t;
#if defined(__MINGW32__)
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
@@ -83,20 +80,17 @@ int init_ws();
#if defined(__MINGW32__)
typedef SOCKET my_fd_t;
inline int sock_close(my_fd_t fd)
{
inline int sock_close(my_fd_t fd) {
return closesocket(fd);
}
#else
typedef int my_fd_t;
inline int sock_close(my_fd_t fd)
{
inline int sock_close(my_fd_t fd) {
return close(fd);
}
#endif
struct my_itimerspec {
struct timespec it_interval; /* Timer interval */
struct timespec it_value; /* Initial expiration */
@@ -136,7 +130,6 @@ const int conn_clear_min=1;
const u32_t conv_clear_interval = 1000;
const u32_t conn_clear_interval = 1000;
const i32_t max_fail_time = 0; // disable
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 u32_t server_conn_timeout = conv_timeout + 20000; // for test
extern int about_to_exit;
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
enum raw_mode_t { mode_faketcp = 0,
mode_udp,
mode_icmp,
mode_end };
extern raw_mode_t raw_mode;
enum program_mode_t {unset_mode=0,client_mode,server_mode};
enum program_mode_t { unset_mode = 0,
client_mode,
server_mode };
extern program_mode_t program_mode;
extern unordered_map<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 int socket_buf_size;
// typedef u32_t id_t;
typedef u64_t iv_t;
@@ -178,7 +176,12 @@ typedef u64_t anti_replay_seq_t;
typedef u64_t fd64_t;
// enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd64_ip_port_conv,type_fd64_conv/*,type_fd*/};
enum dest_type{none=0,type_fd64_addr,type_fd64,type_fd,type_write_fd,type_fd_addr/*,type_fd*/};
enum dest_type { none = 0,
type_fd64_addr,
type_fd64,
type_fd,
type_write_fd,
type_fd_addr /*,type_fd*/ };
/*
struct ip_port_t
@@ -201,7 +204,6 @@ struct fd_ip_port_t
ip_port_t ip_port;
};*/
struct pseudo_header {
u32_t source_address;
u32_t dest_address;
@@ -215,10 +217,8 @@ u32_t sdbm(unsigned char *str,int len);
struct address_t // TODO scope id
{
struct hash_function
{
u32_t operator()(const address_t &key) const
{
struct hash_function {
u32_t operator()(const address_t &key) const {
return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
}
};
@@ -234,8 +234,7 @@ struct address_t //TODO scope id
{
clear();
}*/
void clear()
{
void clear() {
memset(&inner, 0, sizeof(inner));
}
/*
@@ -248,17 +247,13 @@ struct address_t //TODO scope id
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();
if(type==AF_INET)
{
if (type == AF_INET) {
inner.ipv4.sin_family = AF_INET;
inner.ipv4.sin_port = htons(port);
inner.ipv4.sin_addr.s_addr = *((u32_t *)ip);
}
else if(type==AF_INET6)
{
} else if (type == AF_INET6) {
inner.ipv6.sin6_family = AF_INET6;
inner.ipv6.sin6_port = htons(port);
inner.ipv6.sin6_addr = *((in6_addr *)ip);
@@ -275,24 +270,20 @@ struct address_t //TODO scope id
char *get_str();
void to_str(char *);
inline int is_vaild()
{
inline int is_vaild() {
u32_t ret = ((sockaddr *)&inner)->sa_family;
return (ret == AF_INET || ret == AF_INET6);
}
inline u32_t get_type()
{
inline u32_t get_type() {
assert(is_vaild());
u32_t ret = ((sockaddr *)&inner)->sa_family;
return ret;
}
inline u32_t get_len()
{
inline u32_t get_len() {
u32_t type = get_type();
switch(type)
{
switch (type) {
case AF_INET:
return sizeof(sockaddr_in);
case AF_INET6:
@@ -303,11 +294,9 @@ struct address_t //TODO scope id
return -1;
}
inline u32_t get_port()
{
inline u32_t get_port() {
u32_t type = get_type();
switch(type)
{
switch (type) {
case AF_INET:
return ntohs(inner.ipv4.sin_port);
case AF_INET6:
@@ -318,11 +307,9 @@ struct address_t //TODO scope id
return -1;
}
inline void set_port(int port)
{
inline void set_port(int port) {
u32_t type = get_type();
switch(type)
{
switch (type) {
case AF_INET:
inner.ipv4.sin_port = htons(port);
break;
@@ -335,8 +322,7 @@ struct address_t //TODO scope id
return;
}
bool operator == (const address_t &b) const
{
bool operator==(const address_t &b) const {
// return this->data==b.data;
return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0;
}
@@ -348,44 +334,36 @@ struct address_t //TODO scope id
namespace std {
template <>
struct hash<address_t>
{
std::size_t operator()(const address_t& key) const
{
struct hash<address_t> {
std::size_t operator()(const address_t &key) const {
// return address_t::hash_function(k);
return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
}
};
}
} // namespace std
struct fd64_addr_t
{
struct fd64_addr_t {
fd64_t fd64;
address_t addr;
};
struct fd_addr_t
{
struct fd_addr_t {
int fd;
address_t addr;
};
union inner_t
{
union inner_t {
fd64_t fd64;
int fd;
fd64_addr_t fd64_addr;
fd_addr_t fd_addr;
};
struct dest_t
{
struct dest_t {
dest_type type;
inner_t inner;
u32_t conv;
int cook = 0;
};
struct fd_info_t
{
struct fd_info_t {
address_t addr;
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_connected_socket2(int &fd, address_t &addr, address_t *bind_addr, char *out_interface);
struct not_copy_able_t
{
not_copy_able_t()
{
struct 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);
}
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);
return other;
}
};
template <class key_t>
struct lru_collector_t:not_copy_able_t
{
struct lru_collector_t : not_copy_able_t {
// typedef void* key_t;
//#define key_t void*
struct lru_pair_t
{
struct lru_pair_t {
key_t key;
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;
list<lru_pair_t> q;
int update(key_t key)
{
int update(key_t key) {
assert(mp.find(key) != mp.end());
auto it = mp[key];
q.erase(it);
my_time_t value = get_current_time();
if(!q.empty())
{
if (!q.empty()) {
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);
mp[key] = q.begin();
return 0;
}
int new_key(key_t key)
{
int new_key(key_t key) {
assert(mp.find(key) == mp.end());
my_time_t value = get_current_time();
if(!q.empty())
{
if (!q.empty()) {
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);
mp[key] = q.begin();
return 0;
}
int size()
{
int size() {
return q.size();
}
int empty()
{
int empty() {
return q.empty();
}
void clear()
{
mp.clear(); q.clear();
void clear() {
mp.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());
return mp[key]->ts;
}
my_time_t peek_back(key_t &key)
{
my_time_t peek_back(key_t &key) {
assert(!q.empty());
auto it=q.end(); it--;
auto it = q.end();
it--;
key = it->key;
return it->ts;
}
void erase(key_t key)
{
void erase(key_t key) {
assert(mp.find(key) != mp.end());
q.erase(mp[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);
#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);
fd_manager.fd64_close(fd64);
}
////////////////////////////////////////////////////////////////////
conn_manager_t::conn_manager_t()
{
conn_manager_t::conn_manager_t() {
mp.reserve(10007);
last_clear_time = 0;
}
int conn_manager_t::exist(address_t addr)
{
if(mp.find(addr)!=mp.end())
{
int conn_manager_t::exist(address_t addr) {
if (mp.find(addr) != mp.end()) {
return 1;
}
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|=port;
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;
// lru.new_key(addr);
}
else
{
} else {
// lru.update(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|=port;
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;
// lru.new_key(addr);
}
else
{
} else {
// lru.update(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);
mp.erase(erase_it->first);
return 0;
}
int conn_manager_t::clear_inactive()
{
if(get_current_time()-last_clear_time>conn_clear_interval)
{
int conn_manager_t::clear_inactive() {
if (get_current_time() - last_clear_time > conn_clear_interval) {
last_clear_time = get_current_time();
return clear_inactive0();
}
return 0;
}
int conn_manager_t::clear_inactive0()
{
int conn_manager_t::clear_inactive0() {
// mylog(log_info,"called\n");
unordered_map<address_t, conn_info_t *>::iterator 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();
// mylog(log_info,"here size=%d\n",(int)mp.size());
for(;;)
{
for (;;) {
if (cnt >= num_to_clean) break;
if (mp.begin() == mp.end()) break;
if(it==mp.end())
{
if (it == mp.end()) {
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());
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++;
}
else
{
} else {
address_t tmp_addr = it->first; // avoid making get_str() const;
mylog(log_info, "{%s} inactive conn cleared \n", tmp_addr.get_str());
old_it = it;

View File

@@ -39,36 +39,29 @@ struct conv_manager_t // manage the udp connections
long long last_clear_time;
conv_manager_t()
{
conv_manager_t() {
// clear_it=conv_last_active_time.begin();
long long last_clear_time = 0;
additional_clear_function = 0;
}
~conv_manager_t()
{
~conv_manager_t() {
clear();
}
int get_size()
{
int get_size() {
return conv_to_data.size();
}
void reserve()
{
void reserve() {
data_to_conv.reserve(10007);
conv_to_data.reserve(10007);
// conv_last_active_time.reserve(10007);
lru.mp.reserve(10007);
}
void clear()
{
void clear() {
if (disable_conv_clear) return;
if(additional_clear_function!=0)
{
for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++)
{
if (additional_clear_function != 0) {
for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) {
// int fd=int((it->second<<32u)>>32u);
additional_clear_function(it->second);
}
@@ -80,53 +73,42 @@ struct conv_manager_t // manage the udp connections
// conv_last_active_time.clear();
// 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();
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();
}
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();
}
int is_data_used(T data)
{
int is_data_used(T data) {
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];
}
T find_data_by_conv(u32_t conv)
{
T find_data_by_conv(u32_t 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();
lru.update(conv);
return 0;
}
int insert_conv(u32_t conv,T data)
{
int insert_conv(u32_t conv, T data) {
data_to_conv[data] = conv;
conv_to_data[conv] = data;
// conv_last_active_time[conv]=get_current_time();
lru.new_key(conv);
return 0;
}
int erase_conv(u32_t conv)
{
int erase_conv(u32_t conv) {
if (disable_conv_clear) return 0;
T data = conv_to_data[conv];
if(additional_clear_function!=0)
{
if (additional_clear_function != 0) {
additional_clear_function(data);
}
conv_to_data.erase(conv);
@@ -135,20 +117,16 @@ struct conv_manager_t // manage the udp connections
lru.erase(conv);
return 0;
}
int clear_inactive(char * info=0)
{
if(get_current_time()-last_clear_time>conv_clear_interval)
{
int clear_inactive(char *info = 0) {
if (get_current_time() - last_clear_time > conv_clear_interval) {
last_clear_time = get_current_time();
return clear_inactive0(info);
}
return 0;
}
int clear_inactive0(char * info)
{
int clear_inactive0(char *info) {
if (disable_conv_clear) return 0;
unordered_map<u32_t, u64_t>::iterator 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);
my_time_t current_time = get_current_time();
for(;;)
{
for (;;) {
if (cnt >= num_to_clean) break;
if (lru.empty()) break;
@@ -172,12 +149,9 @@ struct conv_manager_t // manage the udp connections
if (current_time - ts < conv_timeout) break;
erase_conv(conv);
if(info==0)
{
if (info == 0) {
mylog(log_info, "conv %x cleared\n", conv);
}
else
{
} else {
mylog(log_info, "[%s]conv %x cleared\n", info, conv);
}
cnt++;
@@ -185,7 +159,6 @@ struct conv_manager_t // manage the udp connections
return 0;
}
/*
conv_manager_t();
~conv_manager_t();
@@ -204,89 +177,70 @@ struct conv_manager_t // manage the udp connections
int clear_inactive0(char * ip_port);*/
}; // g_conv_manager;
struct inner_stat_t
{
struct inner_stat_t {
u64_t input_packet_num;
u64_t input_packet_size;
u64_t output_packet_num;
u64_t output_packet_size;
};
struct stat_t
{
struct stat_t {
u64_t last_report_time;
inner_stat_t normal_to_fec;
inner_stat_t fec_to_normal;
stat_t()
{
stat_t() {
clear();
}
void clear(){
memset(this, 0, sizeof(stat_t));
}
void report_as_client()
{
if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000)
{
void report_as_client() {
if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) {
last_report_time = get_current_time();
inner_stat_t &a = normal_to_fec;
inner_stat_t &b = fec_to_normal;
mylog(log_info, "[report]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt,%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n",
a.input_packet_num, a.input_packet_size, a.output_packet_num, a.output_packet_size,
b.output_packet_num,b.output_packet_size,b.input_packet_num,b.input_packet_size
);
b.output_packet_num, b.output_packet_size, b.input_packet_num, b.input_packet_size);
}
}
void report_as_server(address_t &addr)
{
if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000)
{
void report_as_server(address_t &addr) {
if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) {
last_report_time = get_current_time();
inner_stat_t &a = fec_to_normal;
inner_stat_t &b = normal_to_fec;
mylog(log_info, "[report][%s]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n",
addr.get_str(),
a.output_packet_num, a.output_packet_size, a.input_packet_num, a.input_packet_size,
b.input_packet_num,b.input_packet_size,b.output_packet_num,b.output_packet_size
);
b.input_packet_num, b.input_packet_size, b.output_packet_num, b.output_packet_size);
}
}
};
struct conn_info_t : not_copy_able_t // stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can
// handle multiple clients
{
union tmp_union_t
{
union tmp_union_t {
conv_manager_t<address_t> c;
conv_manager_t<u64_t> s;
// avoid templates here and there, avoid pointer and type cast
tmp_union_t()
{
if(program_mode==client_mode)
{
tmp_union_t() {
if (program_mode == client_mode) {
new (&c) conv_manager_t<address_t>();
}
else
{
} else {
assert(program_mode == server_mode);
new (&s) conv_manager_t<u64_t>();
}
}
~tmp_union_t()
{
if(program_mode==client_mode)
{
~tmp_union_t() {
if (program_mode == client_mode) {
c.~conv_manager_t<address_t>();
}
else
{
} else {
assert(program_mode == server_mode);
s.~conv_manager_t<u64_t>();
}
}
} conv_manager;
fec_encode_manager_t fec_encode_manager;
fec_decode_manager_t fec_decode_manager;
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;
address_t addr; // only used for server
conn_info_t()
{
if(program_mode==server_mode)
{
conn_info_t() {
if (program_mode == server_mode) {
conv_manager.s.additional_clear_function = server_clear_function;
}
else
{
} else {
assert(program_mode == client_mode);
}
}
~conn_info_t()
{
~conn_info_t() {
if (loop)
ev_timer_stop(loop, &timer);
}
void update_active_time()
{
void update_active_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
{
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;
@@ -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 clear_inactive();
int clear_inactive0();
};
extern conn_manager_t conn_manager;
#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 "packet.h"
int delay_data_t::handle()
{
int delay_data_t::handle() {
return my_send(dest, data, len) >= 0;
}
delay_manager_t::delay_manager_t()
{
delay_manager_t::delay_manager_t() {
capacity = 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));
// 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
}
@@ -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 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.dest = dest;
// delay_data.data=data;
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");
return -1;
}
if(delay==0)
{
if (delay == 0) {
static char buf[buf_len];
delay_data.data = buf;
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;
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()");
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;
}
int delay_manager_t::check()
{
if(!delay_mp.empty())
{
int delay_manager_t::check() {
if (!delay_mp.empty()) {
my_time_t current_time;
multimap<my_time_t, delay_data_t>::iterator it;
while(1)
{
while (1) {
int ret = 0;
it = delay_mp.begin();
if (it == delay_mp.end()) break;
current_time = get_current_time_us();
if(it->first <= current_time)
{
if (it->first <= current_time) {
ret = it->second.handle();
if (ret != 0) {
mylog(log_trace, "handle() return %d\n", ret);
}
free(it->second.data);
delay_mp.erase(it);
}
else
{
} else {
break;
}
}
if(!delay_mp.empty())
{
if (!delay_mp.empty()) {
const double m = 1000 * 1000;
double timer_value = delay_mp.begin()->first / m - get_current_time_us() / m; // be aware of negative value, and be aware of uint
if (timer_value < 0) timer_value = 0; // set it to 0 if negative, although libev support negative value
ev_timer_stop(loop, &timer);
ev_timer_set(&timer, timer_value, 0);
ev_timer_start(loop, &timer);
}
else
{
} else {
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;
// int left_time;//
char *data;
@@ -113,8 +111,7 @@ struct delay_data_t
int handle();
};
struct delay_manager_t
{
struct delay_manager_t {
ev_timer timer;
struct ev_loop *loop = 0;
void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0;
@@ -123,17 +120,18 @@ struct delay_manager_t
int capacity;
multimap<my_time_t, delay_data_t> delay_mp; // unit us,1 us=0.001ms
delay_manager_t();
delay_manager_t(delay_manager_t &b)
{
delay_manager_t(delay_manager_t &b) {
assert(0 == 1);
}
void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents))
{
void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) {
this->loop = loop;
this->cb = cb;
ev_init(&timer, cb);
}
int set_capacity(int a){capacity=a;return 0;}
int set_capacity(int a) {
capacity = a;
return 0;
}
~delay_manager_t();
ev_timer &get_timer();
int check();

View File

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

View File

@@ -11,8 +11,6 @@
#include "common.h"
#include "packet.h"
struct fd_manager_t // conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create
// this class is not strictly necessary,it just makes epoll fd handling easier
{
@@ -24,6 +22,7 @@ struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict
void reserve(int n);
u64_t create(int fd);
fd_manager_t();
private:
u64_t counter;
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
blob_encode_t::blob_encode_t()
{
blob_encode_t::blob_encode_t() {
clear();
}
int blob_encode_t::clear()
{
int blob_encode_t::clear() {
counter = 0;
current_len = (int)sizeof(u32_t);
return 0;
}
int blob_encode_t::get_num()
{
int blob_encode_t::get_num() {
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);
}
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);
}
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(len <= 65535 && len >= 0);
counter++;
@@ -71,32 +64,26 @@ int blob_encode_t::input(char *s,int len)
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);
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;
}
s_arr = output_buf;
return 0;
}
blob_decode_t::blob_decode_t()
{
blob_decode_t::blob_decode_t() {
clear();
}
int blob_decode_t::clear()
{
int blob_decode_t::clear() {
current_len = 0;
last_len = -1;
counter = 0;
return 0;
}
int blob_decode_t::input(char *s,int len)
{
if(last_len!=-1)
{
int blob_decode_t::input(char *s, int len) {
if (last_len != -1) {
assert(last_len == len);
}
counter++;
@@ -107,34 +94,41 @@ int blob_decode_t::input(char *s,int len)
current_len += len;
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;
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);
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;
len_arr = output_len;
parser_pos += sizeof(u32_t);
for(int i=0;i<n;i++)
{
if(parser_pos+(int)sizeof(u16_t)>current_len) {mylog(log_info,"failed2 \n");return -1;}
for (int i = 0; i < n; i++) {
if (parser_pos + (int)sizeof(u16_t) > current_len) {
mylog(log_info, "failed2 \n");
return -1;
}
len_arr[i] = (int)read_u16(input_buf + parser_pos);
parser_pos += (int)sizeof(u16_t);
if(parser_pos+len_arr[i]>current_len) {mylog(log_info,"failed 3 %d %d %d\n",parser_pos,len_arr[i],current_len);return -1;}
if (parser_pos + len_arr[i] > current_len) {
mylog(log_info, "failed 3 %d %d %d\n", parser_pos, len_arr[i], current_len);
return -1;
}
s_arr[i] = input_buf + parser_pos;
parser_pos += len_arr[i];
}
return 0;
}
fec_encode_manager_t::~fec_encode_manager_t()
{
fec_encode_manager_t::~fec_encode_manager_t() {
clear_all();
// fd_manager.fd64_close(timer_fd64);
}
@@ -144,8 +138,7 @@ u64_t fec_encode_manager_t::get_timer_fd64()
return timer_fd64;
}*/
fec_encode_manager_t::fec_encode_manager_t()
{
fec_encode_manager_t::fec_encode_manager_t() {
// int timer_fd;
/*
@@ -156,12 +149,10 @@ fec_encode_manager_t::fec_encode_manager_t()
}
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);
fec_par.clone(g_fec_par);
clear_data();
}
/*
int fec_encode_manager_t::reset_fec_parameter(int data_num,int redundant_num,int mtu,int queue_len,int timeout,int mode)
@@ -180,10 +171,8 @@ int fec_encode_manager_t::reset_fec_parameter(int data_num,int redundant_num,int
clear_data();
return 0;
}*/
int fec_encode_manager_t::append(char *s,int len/*,int &is_first_packet*/)
{
if(counter==0)
{
int fec_encode_manager_t::append(char *s, int len /*,int &is_first_packet*/) {
if (counter == 0) {
first_packet_time = get_current_time_us();
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
{
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);
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);
memcpy(p, s, len);
input_len[counter] = len + sizeof(u16_t);
}
else
{
} else {
assert(0 == 1);
}
counter++;
return 0;
}
int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
{
if(counter==0&&fec_par.version!=g_fec_par.version)
{
int fec_encode_manager_t::input(char *s, int len /*,int &is_first_packet*/) {
if (counter == 0 && fec_par.version != g_fec_par.version) {
fec_par.clone(g_fec_par);
}
@@ -228,35 +212,32 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
// int counter_back=counter;
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);
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);
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);
// return -1;
}
if(s==0&&counter==0)
{
if (s == 0 && counter == 0) {
mylog(log_warn, "unexpected s==0&&counter==0\n");
return -1;
}
if (s == 0) about_to_fec = 1; // now
if(fec_par.mode==0&& blob_encode.get_shard_len(fec_par.get_tail().x,len)>fec_par.mtu) {about_to_fec=1; delayed_append=1;}//fec then add packet
if (fec_par.mode == 0 && blob_encode.get_shard_len(fec_par.get_tail().x, len) > fec_par.mtu) {
about_to_fec = 1;
delayed_append = 1;
} // fec then add packet
if (fec_par.mode == 0) assert(counter < fec_par.queue_len); // counter will never equal fec_pending_num,if that happens fec should already been done.
if (fec_par.mode == 1) assert(counter < fec_par.get_tail().x);
if(s!=0&&!delayed_append)
{
if (s != 0 && !delayed_append) {
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(about_to_fec)
{
if (about_to_fec) {
char **blob_output = 0;
int fec_len = -1;
mylog(log_trace, "counter=%d\n", counter);
if(counter==0)
{
if (counter == 0) {
mylog(log_warn, "unexpected counter==0 here\n");
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_redundant_num;
if(fec_par.mode==0)
{
if (fec_par.mode == 0) {
int tail_x = fec_par.get_tail().x;
int tail_y = fec_par.get_tail().y;
actual_data_num = tail_x;
actual_redundant_num = tail_y;
if(short_packet_optimize)
{
if (short_packet_optimize) {
u32_t best_len = (blob_encode.get_shard_len(tail_x, 0) + header_overhead) * (tail_x + tail_y);
int best_data_num = tail_x;
assert(tail_x <= fec_par.rs_cnt);
for(int i=1;i<tail_x;i++)
{
for (int i = 1; i < tail_x; i++) {
assert(fec_par.rs_par[i - 1].x == i);
int tmp_x = fec_par.rs_par[i - 1].x;
int tmp_y = fec_par.rs_par[i - 1].y;
@@ -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;
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_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);
else
mylog(log_trace, "[enc]seq=%08x x=%d y=%d len=%d cnt=%d\n", seq, actual_data_num, actual_redundant_num, fec_len, counter);
}
else
{
} else {
assert(counter <= fec_par.rs_cnt);
actual_data_num = counter;
actual_redundant_num = fec_par.rs_par[counter - 1].y;
int sum_ori = 0;
for(int i=0;i<counter;i++)
{
for (int i = 0; i < counter; i++) {
sum_ori += input_len[i];
assert(input_len[i] >= 0);
if (input_len[i] > fec_len) fec_len = input_len[i];
@@ -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);
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;
write_u32(input_buf[i] + tmp_idx, seq);
tmp_idx += sizeof(u32_t);
input_buf[i][tmp_idx++] = (unsigned char)fec_par.mode;
if (fec_par.mode == 1 && i < actual_data_num)
{
if (fec_par.mode == 1 && i < actual_data_num) {
input_buf[i][tmp_idx++] = (unsigned char)0;
input_buf[i][tmp_idx++] = (unsigned char)0;
} else
{
} else {
input_buf[i][tmp_idx++] = (unsigned char)actual_data_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.
if(fec_par.mode==0)
{
if (fec_par.mode == 0) {
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);
}
}
else
{
if(i<actual_data_num)
{
} else {
if (i < actual_data_num) {
output_len[i] = tmp_idx + input_len[i];
memset(tmp_output_buf[i] + input_len[i], 0, fec_len - input_len[i]);
}
else
} else
output_len[i] = tmp_idx + fec_len;
}
output_buf[i] = input_buf[i]; // output_buf points to same block of memory with different offset
}
if(0)
{
if (0) {
printf("seq=%u,fec_len=%d,%d %d,before fec\n", seq, fec_len, actual_data_num, actual_redundant_num);
for(int i=0;i<actual_data_num;i++)
{
for (int i = 0; i < actual_data_num; i++) {
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]);
}
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
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);
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("{");
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]);
}
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);
// 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_counter = 0;
// assert(counter!=0);
if (s != 0)
packet_to_send[packet_to_send_counter++] = actual_data_num - 1;
for(int i=actual_data_num;i<actual_data_num+actual_redundant_num;i++)
{
for (int i = actual_data_num; i < actual_data_num + actual_redundant_num; i++) {
packet_to_send[packet_to_send_counter++] = i;
}
output_n = packet_to_send_counter; // re write
for(int i=0;i<packet_to_send_counter;i++)
{
for (int i = 0; i < packet_to_send_counter; i++) {
output_buf[i] = output_buf[packet_to_send[i]];
output_len[i] = output_len[packet_to_send[i]];
}
}
}
else
{
if(encode_fast_send&&s!=0&&fec_par.mode==1)
{
} else {
if (encode_fast_send && s != 0 && fec_par.mode == 1) {
assert(counter >= 1);
assert(counter <= 255);
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;
output_n = 1;
int tmp_idx = 0;
write_u32(input_buf[input_buf_idx] + tmp_idx, seq);
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_buf[0] = input_buf[input_buf_idx];
if(0)
{
if (0) {
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]);
}
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);
append(s, len);
}
@@ -506,16 +446,12 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
return 0;
}
int fec_encode_manager_t::output(int &n,char ** &s_arr,int *&len)
{
if(!ready_for_output)
{
int fec_encode_manager_t::output(int &n, char **&s_arr, int *&len) {
if (!ready_for_output) {
n = -1;
len = 0;
s_arr = 0;
}
else
{
} else {
n = output_n;
len = output_len;
s_arr = output_buf;
@@ -530,15 +466,13 @@ int fec_decode_manager_t::re_init()
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(len + 100 < buf_len); // guarenteed by upper level
int tmp_idx = 0;
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);
return -1;
}
@@ -552,80 +486,63 @@ int fec_decode_manager_t::input(char *s,int len)
// mylog(log_trace,"input\n");
if(len<0)
{
if (len < 0) {
mylog(log_warn, "len<0\n");
return -1;
}
if(type==1)
{
if(len<(int)sizeof(u16_t))
{
if (type == 1) {
if (len < (int)sizeof(u16_t)) {
mylog(log_warn, "type==1&&len<2\n");
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);
return -1;
}
}
if(type==0&&data_num==0)
{
if (type == 0 && data_num == 0) {
mylog(log_warn, "unexpected type==0&&data_num==0\n");
return -1;
}
if(data_num+redundant_num>=max_fec_packet_num)
{
if (data_num + redundant_num >= max_fec_packet_num) {
mylog(log_warn, "data_num+redundant_num>=max_fec_packet_num\n");
return -1;
}
if(!anti_replay.is_vaild(seq))
{
if (!anti_replay.is_vaild(seq)) {
mylog(log_trace, "!anti_replay.is_vaild(seq) ,seq =%u\n", seq);
return 0;
}
if(mp[seq].fec_done!=0)
{
if (mp[seq].fec_done != 0) {
mylog(log_debug, "fec already done, ignore, seq=%u\n", seq);
return -1;
}
if(mp[seq].group_mp.find(inner_index)!=mp[seq].group_mp.end() )
{
if (mp[seq].group_mp.find(inner_index) != mp[seq].group_mp.end()) {
mylog(log_debug, "dup fec index\n"); // duplicate can happen on a normal network, so its just log_debug
return -1;
}
if (mp[seq].type == -1)
mp[seq].type = type;
else
{
if(mp[seq].type!=type)
{
else {
if (mp[seq].type != type) {
mylog(log_warn, "type mismatch\n");
return -1;
}
}
if(data_num!=0)
{
if (data_num != 0) {
// mp[seq].data_counter++;
if(mp[seq].data_num==-1)
{
if (mp[seq].data_num == -1) {
mp[seq].data_num = data_num;
mp[seq].redundant_num = redundant_num;
mp[seq].len = len;
}
else
{
if(mp[seq].data_num!=data_num||mp[seq].redundant_num!=redundant_num||mp[seq].len!=len)
{
} else {
if (mp[seq].data_num != data_num || mp[seq].redundant_num != redundant_num || mp[seq].len != len) {
mylog(log_warn, "unexpected mp[seq].data_num!=data_num||mp[seq].redundant_num!=redundant_num||mp[seq].len!=len\n");
return -1;
}
@@ -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);
if(fec_data[index].used!=0)
{
if (fec_data[index].used != 0) {
u32_t tmp_seq = fec_data[index].seq;
anti_replay.set_invaild(tmp_seq);
auto tmp_it = mp.find(tmp_seq);
if(tmp_it!=mp.end())
{
if (tmp_it != mp.end()) {
int x = tmp_it->second.data_num;
int y = tmp_it->second.redundant_num;
int cnt = tmp_it->second.group_mp.size();
if(cnt<x)
{
if (cnt < x) {
if (debug_fec_dec)
mylog(log_debug, "[dec][failed]seq=%08x x=%d y=%d cnt=%d\n", tmp_seq, x, y, cnt);
else
@@ -655,8 +569,7 @@ int fec_decode_manager_t::input(char *s,int len)
}
mp.erase(tmp_it);
}
if(tmp_seq==seq)
{
if (tmp_seq == seq) {
mylog(log_warn, "unexpected tmp_seq==seq ,seq=%d\n", seq);
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;
int about_to_fec = 0;
if(type==0)
{
if (type == 0) {
// 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");
anti_replay.set_invaild(seq);
goto end;
}
if ((int)inner_mp.size() == data_num)
about_to_fec = 1;
}
else
{
if(mp[seq].data_num!=-1)
{
if((int)inner_mp.size()>mp[seq].data_num+1)
{
} else {
if (mp[seq].data_num != -1) {
if ((int)inner_mp.size() > mp[seq].data_num + 1) {
mylog(log_warn, "inner_mp.size()>data_num+1\n");
anti_replay.set_invaild(seq);
goto end;
}
if((int)inner_mp.size()>=mp[seq].data_num)
{
if ((int)inner_mp.size() >= mp[seq].data_num) {
about_to_fec = 1;
}
}
}
if(about_to_fec)
{
if (about_to_fec) {
int group_data_num = mp[seq].data_num;
int group_redundant_num = mp[seq].redundant_num;
int x_got = 0;
int y_got = 0;
// mylog(log_error,"fec here!\n");
if(type==0)
{
if (type == 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)
x_got++;
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);
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);
}
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");
// ready_for_output=0;
anti_replay.set_invaild(seq);
@@ -752,11 +651,8 @@ int fec_decode_manager_t::input(char *s,int len)
assert(ready_for_output == 0);
ready_for_output = 1;
anti_replay.set_invaild(seq);
}
else//type==1
} else // type==1
{
int max_len = -1;
int fec_result_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
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;
}
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)
x_got++;
else
y_got++;
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)");
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)
max_len = fec_data[it->second].len;
}
if(max_len!=mp[seq].len)
{
if (max_len != mp[seq].len) {
data_check_ok = 0;
mylog(log_warn, "max_len!=mp[seq].len");
}
if(data_check_ok==0)
{
if (data_check_ok == 0) {
// ready_for_output=0;
mylog(log_warn, "data_check_ok==0\n");
anti_replay.set_invaild(seq);
goto end;
}
for(auto it=inner_mp.begin();it!=inner_mp.end();it++)
{
for (auto it = inner_mp.begin(); it != inner_mp.end(); it++) {
int tmp_idx = it->second;
assert(max_len >= fec_data[tmp_idx].len); // guarenteed by data_check_ok
memset(fec_data[tmp_idx].buf + fec_data[tmp_idx].len, 0, max_len - fec_data[tmp_idx].len);
}
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
{
missed_packet[missed_packet_counter++] = i;
@@ -823,17 +712,14 @@ int fec_decode_manager_t::input(char *s,int len)
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]);
sum_ori += output_len_arr_buf[i];
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);
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, "\n");
@@ -848,50 +734,38 @@ int fec_decode_manager_t::input(char *s,int len)
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);
if(fec_result_ok)
{
if (fec_result_ok) {
output_n = group_data_num;
if(decode_fast_send)
{
if (decode_fast_send) {
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_len_arr_buf[i] = output_len_arr_buf[missed_packet[i]];
}
}
output_s_arr = output_s_arr_buf;
output_len_arr = output_len_arr_buf;
assert(ready_for_output == 0);
ready_for_output = 1;
}
else
{
} else {
// fec_not_ok:
ready_for_output = 0;
}
anti_replay.set_invaild(seq);
} // end of type==1
}
else //not about_to_fec
{
if(decode_fast_send)
{
if(type==1&&data_num==0)
} else // not about_to_fec
{
if (decode_fast_send) {
if (type == 1 && data_num == 0) {
assert(ready_for_output == 0);
output_n = 1;
int check_len = read_u16(fec_data[index].buf);
output_s_arr_buf[0] = fec_data[index].buf + 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);
}
output_s_arr = output_s_arr_buf;
@@ -908,16 +782,12 @@ int fec_decode_manager_t::input(char *s,int len)
return 0;
}
int fec_decode_manager_t::output(int &n,char ** &s_arr,int* &len_arr)
{
if(!ready_for_output)
{
int fec_decode_manager_t::output(int &n, char **&s_arr, int *&len_arr) {
if (!ready_for_output) {
n = -1;
s_arr = 0;
len_arr = 0;
}
else
{
} else {
ready_for_output = 0;
n = output_n;
s_arr = output_s_arr;

View File

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

View File

@@ -8,35 +8,29 @@
#include "stdlib.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 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);
}
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 n = get_n(code);
int index[n];
int count = 0;
for(int i=0;i<n;i++)
{
if(data[i]!=0)
{
for (int i = 0; i < n; i++) {
if (data[i] != 0) {
index[count++] = i;
}
}
if (count < k)
return -1;
for(int i=0;i<n;i++)
{
for (int i = 0; i < n; i++) {
if (i < count)
data[i] = data[index[i]];
else
@@ -46,31 +40,25 @@ int rs_decode(void *code,char *data[],int size)
}
static void *(*table)[256] = 0;
void* get_code(int k,int n)
{
if (table==0)
{
void *get_code(int k, int n) {
if (table == 0) {
table = (void *(*)[256])malloc(sizeof(void *) * 256 * 256);
if(!table)
{
if (!table) {
return table;
}
memset(table, 0, sizeof(void *) * 256 * 256);
}
if(table[k][n]==0)
{
if (table[k][n] == 0) {
table[k][n] = fec_new(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);
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);
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()
void rs_encode(void *code, char *data[], int size);
// input:
// 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)
@@ -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.
int rs_decode(void *code, 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);
#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_color = 1;
void log0(const char* file, const char* function, int line, int level, const char* str, ...) {
if (level > log_level) return;
if (level > log_trace || level < 0) return;
time_t timer;
char buffer[100];
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]);
fflush(stdout);
if(log_level==log_fatal)
{
if (log_level == log_fatal) {
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_trace || level < 0) return;
if (enable_log_color)
@@ -59,5 +54,4 @@ void log_bare(int level,const char* str, ...)
if (enable_log_color)
printf("%s", RESET);
fflush(stdout);
}

6
log.h Executable file → Normal file
View File

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

View File

@@ -13,9 +13,7 @@
#include "git_version.h"
using namespace std;
static void print_help()
{
static void print_help() {
char git_version_buf[100] = {0};
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");
}
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");
}
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");
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");
myexit(0);
}
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
working_mode = tunnel_mode;
init_ws();
// unit_test();
@@ -132,15 +123,12 @@ int main(int argc, char *argv[])
dup2(1, 2); // redirect stderr to stdout
int i, j, k;
if (argc == 1)
{
if (argc == 1) {
print_help();
myexit(-1);
}
for (i = 0; i < argc; i++)
{
if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0)
{
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
print_help();
myexit(0);
}
@@ -150,20 +138,15 @@ int main(int argc, char *argv[])
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);
}
if(program_mode==client_mode)
{
if (program_mode == client_mode) {
tunnel_client_event_loop();
}
else
{
} else {
tunnel_server_event_loop();
}
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++
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
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 "fec_manager.h"
extern char fifo_file[1000];
extern int mtu_warn;
@@ -26,7 +24,6 @@ extern int disable_checksum;
extern int debug_force_flush_fec;
extern int jitter_min;
extern int jitter_max;
@@ -39,7 +36,6 @@ extern int fix_latency;
// extern char local_ip[100], remote_ip[100];
// extern int local_port, remote_port;
extern address_t local_addr, remote_addr;
extern address_t *out_addr;
@@ -62,7 +58,6 @@ extern int mssfix;
extern int manual_set_tun;
extern int persist_tun;
int from_normal_to_fec(conn_info_t &conn_info, char *data, int len, int &out_n, char **&out_arr, int *&out_len, my_time_t *&out_delay);
int from_fec_to_normal(conn_info_t &conn_info, char *data, int len, int &out_n, char **&out_arr, int *&out_len, my_time_t *&out_delay);

View File

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

View File

@@ -1,6 +1,8 @@
#define EV_STANDALONE 1
#define EV_COMMON void *data; unsigned long long u64;
#define EV_COMMON \
void *data; \
unsigned long long u64;
#define EV_COMPAT3 0
//#define EV_VERIFY 2

View File

@@ -5,11 +5,11 @@
* Author: root
*/
#include "common.h"
#include "log.h"
#include "packet.h"
#include "misc.h"
#include "crc32/Crc32.h"
int iv_min = 4;
int iv_max = 32; //< 256;
@@ -30,30 +30,24 @@ char key_string[1000]= "";
// 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;
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;
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;
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;
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);
// out_len=in_len;
// 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] ^= 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 (key_string[k] == 0) k = 0;
output[iv_len + i] ^= output[j];
output[iv_len + i] ^= key_string[k];
}
out_len = iv_len + in_len + 1;
return 0;
}
int do_obscure(char * data,int &len)
{
int do_obscure(char *data, int &len) {
assert(len >= 0);
assert(len < buf_len);
int iv_len = random_between(iv_min, iv_max);
get_fake_random_chars(data + len, iv_len);
data[iv_len + len] = (uint8_t)iv_len;
for(int i=0,j=0;i<len;i++,j++)
{
for (int i = 0, j = 0; i < len; i++, j++) {
if (j == iv_len) j = 0;
data[i] ^= data[len + j];
}
@@ -101,47 +91,40 @@ int do_obscure(char * data,int &len)
return 0;
}
int de_obscure(char * data,int &len)
{
int de_obscure(char *data, int &len) {
if (len < 1) return -1;
int iv_len = int((uint8_t)data[len - 1]);
if (len < 1 + iv_len) return -1;
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;
data[i] ^= data[len + j];
}
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);
// out_len=in_len;
// return 0;
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);
return -1;
}
int iv_len = int((uint8_t)(input[in_len - 1] ^ input[0] ^ key_string[0]));
out_len = in_len - 1 - iv_len;
if(out_len<0)
{
if (out_len < 0) {
mylog(log_debug, "%d %d\n", in_len, out_len);
return -1;
}
for(i=0,j=0,k=1;i<in_len;i++,j++,k++)
{
for (i = 0, j = 0, k = 1; i < in_len; i++, j++, k++) {
if (j == iv_len) j = 0;
if (key_string[k] == 0) k = 0;
output[i] = input[iv_len + i] ^ input[j] ^ key_string[k];
}
dup_packet_recv_count++;
return 0;
@@ -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));
}*/
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,
len, 0,
(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);
}*/
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);
}
int my_send(const dest_t &dest,char *data,int len)
{
if(dest.cook)
{
int my_send(const dest_t &dest, char *data, int len) {
if (dest.cook) {
do_cook(data, len);
}
switch(dest.type)
{
case type_fd_addr:
{
switch (dest.type) {
case type_fd_addr: {
return sendto_fd_addr(dest.inner.fd, dest.inner.fd_addr.addr, data, len, 0);
break;
}
case type_fd64_addr:
{
case type_fd64_addr: {
if (!fd_manager.exist(dest.inner.fd64)) return -1;
int fd = fd_manager.to_fd(dest.inner.fd64);
return sendto_fd_addr(fd, dest.inner.fd64_addr.addr, data, len, 0);
break;
}
case type_fd:
{
case type_fd: {
return send_fd(dest.inner.fd, data, len, 0);
break;
}
case type_write_fd:
{
case type_write_fd: {
return write(dest.inner.fd, data, len);
break;
}
case type_fd64:
{
case type_fd64: {
if (!fd_manager.exist(dest.inner.fd64)) return -1;
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;
}
/*
* 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)
{
int put_conv0(u32_t conv, const char *input, int len_in, char *&output, int &len_out) {
assert(len_in >= 0);
static char buf[buf_len];
output = buf;
u32_t n_conv = htonl(conv);
memcpy(output, &n_conv, sizeof(n_conv));
memcpy(output + sizeof(n_conv), input, len_in);
u32_t crc32=crc32h((unsigned char *)output,len_in+sizeof(crc32));
u32_t crc32 = (u32_t)crc32_fast(output, len_in + sizeof(crc32));
u32_t crc32_n = htonl(crc32);
len_out = len_in + (int)(sizeof(n_conv)) + (int)sizeof(crc32_n);
memcpy(output + len_in + (int)(sizeof(n_conv)), &crc32_n, sizeof(crc32_n));
return 0;
}
int get_conv0(u32_t &conv,const char *input,int len_in,char *&output,int &len_out )
{
int get_conv0(u32_t &conv, const char *input, int len_in, char *&output, int &len_out) {
assert(len_in >= 0);
u32_t n_conv;
memcpy(&n_conv, input, sizeof(n_conv));
@@ -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);
u32_t 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");
return -1;
}
memcpy(&crc32_n, input + len_in - (int)sizeof(crc32_n), sizeof(crc32_n));
u32_t crc32 = ntohl(crc32_n);
if(crc32!=crc32h((unsigned char *)input,len_in-(int)sizeof(crc32_n)))
{
if (crc32 != (u32_t)crc32_fast(input, len_in - sizeof(crc32_n))) {
mylog(log_debug, "crc32 check failed\n");
return -1;
}
return 0;
}
int put_crc32(char * s,int &len)
{
int put_crc32(char *s, int &len) {
if (disable_checksum) return 0;
assert(len >= 0);
// if(len<0) return -1;
u32_t crc32=crc32h((unsigned char *)s,len);
u32_t crc32 = (u32_t)crc32_fast(s, len);
write_u32(s + len, crc32);
len += sizeof(u32_t);
return 0;
}
int do_cook(char * data,int &len)
{
int do_cook(char *data, int &len) {
put_crc32(data, len);
if (!disable_obscure) do_obscure(data, len);
if (!disable_xor) encrypt_0(data, len, key_string);
return 0;
}
int de_cook(char * s,int &len)
{
int de_cook(char *s, int &len) {
if (!disable_xor) decrypt_0(s, len, key_string);
if(!disable_obscure)
{
if (!disable_obscure) {
int ret = de_obscure(s, len);
if(ret!=0)
{
if (ret != 0) {
mylog(log_debug, "de_obscure fail\n");
return ret;
}
}
int ret = rm_crc32(s, len);
if(ret!=0)
{
if (ret != 0) {
mylog(log_debug, "rm_crc32 fail\n");
return ret;
}
return 0;
}
int rm_crc32(char * s,int &len)
{
int rm_crc32(char *s, int &len) {
if (disable_checksum) return 0;
assert(len >= 0);
len -= sizeof(u32_t);
if (len < 0) return -1;
u32_t crc32_in = read_u32(s + len);
u32_t crc32=crc32h((unsigned char *)s,len);
u32_t crc32 = (u32_t)crc32_fast(s, len);
if (crc32 != crc32_in) return -1;
return 0;
}
@@ -381,8 +314,7 @@ int do_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];
output = buf;
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;
}
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;
memcpy(&n_conv, input, sizeof(n_conv));
conv = ntohl(n_conv);
output = (char *)input + sizeof(n_conv);
len_out = len_in - (int)sizeof(n_conv);
if(len_out<0)
{
if (len_out < 0) {
mylog(log_debug, "len_out<0\n");
return -1;
}
return 0;
}

View File

@@ -24,7 +24,6 @@ extern int random_drop;
extern int disable_obscure;
extern int disable_xor;
int my_send(const dest_t &dest, char *data, int len);
void encrypt_0(char *input, int &len, char *key);

View File

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

View File

@@ -1,7 +1,6 @@
#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;
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;
address_t addr;
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.type = type_fd64;
dest.inner.fd64 = remote_fd64;
dest.cook = 1;
if(is_time_out)
{
if (is_time_out) {
// fd64_t fd64=events[idx].data.u64;
mylog(log_trace, "events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n");
@@ -38,8 +39,7 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
// }
// assert(value==1);
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
}
else//events[idx].data.u64 == (u64_t)local_listen_fd
} else // events[idx].data.u64 == (u64_t)local_listen_fd
{
mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n");
address_t::storage_t udp_new_addr_in = {0};
@@ -50,37 +50,30 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
return;
};
if(data_len==max_data_len+1)
{
mylog(log_warn,"huge packet, data_len > %d, packet truncated, dropped\n",max_data_len);
if (data_len == max_data_len + 1) {
mylog(log_warn, "huge packet from upper level, data_len > %d, packet truncated, dropped\n", max_data_len);
return;
}
if(!disable_mtu_warn&&data_len>=mtu_warn)
{
if (!disable_mtu_warn && data_len >= mtu_warn) {
mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn);
}
addr.from_sockaddr((struct sockaddr *)&udp_new_addr_in, udp_new_addr_len);
mylog(log_trace, "Received packet from %s, len: %d\n", addr.get_str(), data_len);
// u64_t u64=ip_port.to_u64();
if(!conn_info.conv_manager.c.is_data_used(addr))
{
if(conn_info.conv_manager.c.get_size() >=max_conv_num)
{
if (!conn_info.conv_manager.c.is_data_used(addr)) {
if (conn_info.conv_manager.c.get_size() >= max_conv_num) {
mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
return;
}
conv = conn_info.conv_manager.c.get_new_conv();
conn_info.conv_manager.c.insert_conv(conv, addr);
mylog(log_info, "new packet from %s,conv_id=%x\n", addr.get_str(), conv);
}
else
{
} else {
conv = conn_info.conv_manager.c.find_conv_by_data(addr);
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;
put_conv(conv, data, data_len, new_data, new_len);
mylog(log_trace, "data_len=%d new_len=%d\n", data_len, new_len);
from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay);
}
mylog(log_trace, "out_n=%d\n", out_n);
for(int i=0;i<out_n;i++)
{
for (int i = 0; i < out_n; i++) {
delay_send(out_delay[i], dest, out_arr[i], out_len[i]);
}
}
static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
assert(!(revents & EV_ERROR));
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
@@ -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);
}
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));
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);
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);
return;
}
mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd, data_len);
if(data_len<0)
{
if(get_sock_errno()==ECONNREFUSED)
{
if (data_len < 0) {
if (get_sock_errno() == ECONNREFUSED) {
mylog(log_debug, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error());
}
mylog(log_warn, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error());
return;
}
if(!disable_mtu_warn&&data_len>mtu_warn)
{
if (!disable_mtu_warn && data_len > mtu_warn) {
mylog(log_warn, "huge packet,data len=%d (>%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn);
}
if(de_cook(data,data_len)!=0)
{
if (de_cook(data, data_len) != 0) {
mylog(log_debug, "de_cook error");
return;
}
int out_n;char **out_arr;int *out_len;my_time_t *out_delay;
int out_n;
char **out_arr;
int *out_len;
my_time_t *out_delay;
from_fec_to_normal(conn_info, data, data_len, out_n, out_arr, out_len, out_delay);
mylog(log_trace, "out_n=%d\n", out_n);
for(int i=0;i<out_n;i++)
{
for (int i = 0; i < out_n; i++) {
u32_t conv;
char *new_data;
int new_len;
if(get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0)
{
if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) {
mylog(log_debug, "get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0");
continue;
}
if(!conn_info.conv_manager.c.is_conv_used(conv))
{
if (!conn_info.conv_manager.c.is_conv_used(conv)) {
mylog(log_trace, "!conn_info.conv_manager.is_conv_used(conv)");
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));
int fifo_fd = watcher->fd;
char buf[buf_len];
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());
return;
}
@@ -208,8 +188,7 @@ static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
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));
// uint64_t value;
@@ -219,18 +198,15 @@ static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int
// 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));
conn_info_t &conn_info = *((conn_info_t *)watcher->data);
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));
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();
if(debug_force_flush_fec)
{
int out_n;char **out_arr;int *out_len;my_time_t *out_delay;
if (debug_force_flush_fec) {
int out_n;
char **out_arr;
int *out_len;
my_time_t *out_delay;
dest_t dest;
dest.type = type_fd64;
dest.inner.fd64 = conn_info.remote_fd64;
dest.cook = 1;
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
for(int i=0;i<out_n;i++)
{
for (int i = 0; i < out_n; 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));
delay_manager.check();
}
int tunnel_client_event_loop()
{
int i, j, k;int ret;
int tunnel_client_event_loop() {
int i, j, k;
int ret;
int yes = 1;
// int epoll_fd;
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
@@ -330,7 +305,6 @@ int tunnel_client_event_loop()
ev_io_init(&remote_watcher, remote_cb, remote_fd, EV_READ);
ev_io_start(loop, &remote_watcher);
// ev.events = EPOLLIN;
// ev.data.u64 = delay_manager.get_timer_fd();
@@ -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());
struct ev_io fifo_watcher;
int fifo_fd = -1;
if(fifo_file[0]!=0)
{
if (fifo_file[0] != 0) {
fifo_fd = create_fifo(fifo_file);
// ev.events = EPOLLIN;
// 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_start(loop, &fifo_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 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;
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;
// mylog(log_trace,"events[idx].data.u64 >u32_t(-1),%llu\n",(u64_t)events[idx].data.u64);
// assert(fd_manager.exist_info(fd64));
// ip_port_t ip_port=fd_manager.get_info(fd64).ip_port;
// conn_info_t &conn_info=conn_manager.find(ip_port);
address_t &addr = conn_info.addr;
assert(conn_manager.exist(addr));
int &local_listen_fd = conn_info.local_listen_fd;
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.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.cook = 1;
if(mode==is_fec_timeout)
{
if (mode == is_fec_timeout) {
assert(fd64 == 0);
// uint64_t value;
// 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);
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);
// uint64_t value;
// read(conn_info.timer.get_timer_fd(), &value, 8);
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);
}
conn_info.stat.report_as_server(addr);
return;
}
else if(mode==is_from_remote)
{
} else if (mode == is_from_remote) {
if (!fd_manager.exist(fd64)) // fd64 has been closed
{
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);
data_len = recv(fd, data, max_data_len + 1, 0);
if(data_len==max_data_len+1)
{
mylog(log_warn,"huge packet, data_len > %d, packet truncated, dropped\n",max_data_len);
if (data_len == max_data_len + 1) {
mylog(log_warn, "huge packet from upper level, data_len > %d, packet truncated, dropped\n", max_data_len);
return;
}
mylog(log_trace, "received a packet from udp_fd,len:%d,conv=%d\n", data_len, conv);
if(data_len<0)
{
if (data_len < 0) {
mylog(log_debug, "udp fd,recv_len<0 continue,%s\n", get_sock_error());
return;
}
if(!disable_mtu_warn&&data_len>=mtu_warn)
{
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);
}
@@ -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);
from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay);
}
else
{
} else {
assert(0 == 1);
}
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]);
}
}
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));
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;
};
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);
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);
}
if(de_cook(data,data_len)!=0)
{
if (de_cook(data, data_len) != 0) {
mylog(log_debug, "de_cook error");
return;
}
if(!conn_manager.exist(addr))
{
if(conn_manager.mp.size() >=max_conn_num)
{
if (!conn_manager.exist(addr)) {
if (conn_manager.mp.size() >= max_conn_num) {
mylog(log_warn, "new connection %s ignored bc max_conn_num exceed\n", addr.get_str());
return;
}
@@ -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();
// fd_manager.get_info(timer_fd64).ip_port=ip_port;
conn_info.fec_encode_manager.set_data(&conn_info);
conn_info.fec_encode_manager.set_loop_and_cb(loop, fec_encode_cb);
mylog(log_info, "new connection from %s\n", addr.get_str());
}
conn_info_t &conn_info = conn_manager.find_insert(addr);
conn_info.update_active_time();
int out_n;char **out_arr;int *out_len;my_time_t *out_delay;
int out_n;
char **out_arr;
int *out_len;
my_time_t *out_delay;
from_fec_to_normal(conn_info, data, data_len, out_n, out_arr, out_len, out_delay);
mylog(log_trace, "out_n= %d\n", out_n);
for(int i=0;i<out_n;i++)
{
for (int i = 0; i < out_n; i++) {
u32_t conv;
char *new_data;
int new_len;
if(get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0)
{
if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) {
mylog(log_debug, "get_conv failed");
continue;
}
if (!conn_info.conv_manager.s.is_conv_used(conv))
{
if(conn_info.conv_manager.s.get_size() >=max_conv_num)
{
if (!conn_info.conv_manager.s.is_conv_used(conv)) {
if (conn_info.conv_manager.s.get_size() >= max_conv_num) {
mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
continue;
}
@@ -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_start(conn_info.loop, &io_watcher);
mylog(log_info, "[%s]new conv %x,fd %d created,fd64=%llu\n", addr.get_str(), conv, new_udp_fd, fd64);
}
conn_info.conv_manager.s.update_active_time(conv);
@@ -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));
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);
}
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));
int fifo_fd = watcher->fd;
char buf[buf_len];
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());
return;
}
@@ -306,8 +278,7 @@ static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
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));
// 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");
// 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));
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);
}
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));
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);
}
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));
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));
// 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");
}
int tunnel_server_event_loop()
{
int i, j, k;int ret;
int tunnel_server_event_loop() {
int i, j, k;
int ret;
int yes = 1;
// int epoll_fd;
// int remote_fd;
@@ -417,8 +382,7 @@ int tunnel_server_event_loop()
int fifo_fd = -1;
if(fifo_file[0]!=0)
{
if (fifo_file[0] != 0) {
fifo_fd = create_fifo(fifo_file);
// ev.events = EPOLLIN;
// ev.data.u64 = fifo_fd;
@@ -438,7 +402,6 @@ int tunnel_server_event_loop()
ev_init(&prepare_watcher, prepare_cb);
ev_prepare_start(loop, &prepare_watcher);
ev_run(loop, 0);
mylog(log_warn, "ev_run returned\n");
@@ -497,7 +460,5 @@ int tunnel_server_event_loop()
}*/
return 0;
}