22 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
wangyu
af607e4bfa add warning when packet is truncated 2021-01-16 14:08:12 -05:00
wangyu-
6dcc97155b Update ISSUE_TEMPLATE.md 2020-09-20 05:16:31 -04:00
wangyu-
d607c5ff92 Update ISSUE_TEMPLATE.md 2020-09-20 05:13:01 -04:00
32 changed files with 5907 additions and 5372 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,6 +1 @@
For English speaking user English Only.
https://github.com/wangyu-/UDPspeeder/wiki/Issue-Guide
中文用户请看:
https://github.com/wangyu-/UDPspeeder/wiki/发Issue前请看
(否则Issue可能被忽略或被直接关掉)

View File

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

1491
common.cpp

File diff suppressed because it is too large Load Diff

669
common.h
View File

@@ -10,17 +10,17 @@
//#define __STDC_FORMAT_MACROS 1 //#define __STDC_FORMAT_MACROS 1
#include <inttypes.h> #include <inttypes.h>
#include<stdio.h> #include <stdio.h>
#include<string.h> #include <string.h>
#include<stdlib.h> #include <stdlib.h>
#include<getopt.h> #include <getopt.h>
#include<unistd.h> #include <unistd.h>
#include<errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdlib.h> //for exit(0); #include <stdlib.h> //for exit(0);
#include <errno.h> //For errno - the error number #include <errno.h> //For errno - the error number
//#include <netinet/tcp.h> //Provides declarations for tcp header //#include <netinet/tcp.h> //Provides declarations for tcp header
//#include <netinet/udp.h> //#include <netinet/udp.h>
//#include <netinet/ip.h> //Provides declarations for ip header //#include <netinet/ip.h> //Provides declarations for ip header
@@ -44,24 +44,22 @@
#include <ws2tcpip.h> #include <ws2tcpip.h>
typedef int socklen_t; typedef int socklen_t;
#else #else
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <list>
#include <string>
#include <vector>
using namespace std;
#include<unordered_map> typedef unsigned long long u64_t; // this works on most platform,avoid using the PRId64
#include<unordered_set>
#include<map>
#include<list>
#include<string>
#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; typedef long long i64_t;
typedef unsigned int u32_t; typedef unsigned int u32_t;
@@ -70,11 +68,10 @@ typedef int i32_t;
typedef unsigned short u16_t; typedef unsigned short u16_t;
typedef short i16_t; typedef short i16_t;
#if defined(__MINGW32__) #if defined(__MINGW32__)
int inet_pton(int af, const char *src, void *dst); int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#define setsockopt(a,b,c,d,e) setsockopt(a,b,c,(const char *)(d),e) #define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char *)(d), e)
#endif #endif
char *get_sock_error(); char *get_sock_error();
@@ -83,39 +80,36 @@ int init_ws();
#if defined(__MINGW32__) #if defined(__MINGW32__)
typedef SOCKET my_fd_t; typedef SOCKET my_fd_t;
inline int sock_close(my_fd_t fd) inline int sock_close(my_fd_t fd) {
{ return closesocket(fd);
return closesocket(fd);
} }
#else #else
typedef int my_fd_t; typedef int my_fd_t;
inline int sock_close(my_fd_t fd) inline int sock_close(my_fd_t fd) {
{ return close(fd);
return close(fd);
} }
#endif #endif
struct my_itimerspec { struct my_itimerspec {
struct timespec it_interval; /* Timer interval */ struct timespec it_interval; /* Timer interval */
struct timespec it_value; /* Initial expiration */ struct timespec it_value; /* Initial expiration */
}; };
typedef u64_t my_time_t; typedef u64_t my_time_t;
const int max_addr_len=100; const int max_addr_len = 100;
const int max_data_len=3600; const int max_data_len = 3600;
const int buf_len=max_data_len+200; const int buf_len = max_data_len + 200;
const int default_mtu=1250; const int default_mtu = 1250;
//const u32_t timer_interval=400; // const u32_t timer_interval=400;
////const u32_t conv_timeout=180000; ////const u32_t conv_timeout=180000;
//const u32_t conv_timeout=40000;//for test // const u32_t conv_timeout=40000;//for test
const u32_t conv_timeout=180000; const u32_t conv_timeout = 180000;
const int max_conv_num=10000; const int max_conv_num = 10000;
const int max_conn_num=200; const int max_conn_num = 200;
/* /*
const u32_t max_handshake_conn_num=10000; const u32_t max_handshake_conn_num=10000;
@@ -128,46 +122,50 @@ const u32_t client_retry_interval=1000;
const u32_t server_handshake_timeout=10000;// this should be much longer than clients. client retry initially ,server retry passtively*/ const u32_t server_handshake_timeout=10000;// this should be much longer than clients. client retry initially ,server retry passtively*/
const int conv_clear_ratio=30; //conv grabage collecter check 1/30 of all conv one time const int conv_clear_ratio = 30; // conv grabage collecter check 1/30 of all conv one time
const int conn_clear_ratio=50; const int conn_clear_ratio = 50;
const int conv_clear_min=1; const int conv_clear_min = 1;
const int conn_clear_min=1; const int conn_clear_min = 1;
const u32_t conv_clear_interval=1000; const u32_t conv_clear_interval = 1000;
const u32_t conn_clear_interval=1000; const u32_t conn_clear_interval = 1000;
const i32_t max_fail_time = 0; // disable
const i32_t max_fail_time=0;//disable const u32_t heartbeat_interval = 1000;
const u32_t heartbeat_interval=1000; const u32_t timer_interval = 400; // this should be smaller than heartbeat_interval and retry interval;
const u32_t timer_interval=400;//this should be smaller than heartbeat_interval and retry interval; // const uint32_t conv_timeout=120000; //120 second
// const u32_t conv_timeout=120000; //for test
//const uint32_t conv_timeout=120000; //120 second const u32_t client_conn_timeout = 10000;
//const u32_t conv_timeout=120000; //for test const u32_t client_conn_uplink_timeout = client_conn_timeout + 2000;
const u32_t client_conn_timeout=10000;
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;
//const uint32_t server_conn_timeout=conv_timeout+60000;//this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
const u32_t server_conn_timeout=conv_timeout+20000;//for test
// const 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; extern int about_to_exit;
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end}; enum raw_mode_t { mode_faketcp = 0,
mode_udp,
mode_icmp,
mode_end };
extern raw_mode_t raw_mode; extern raw_mode_t raw_mode;
enum program_mode_t {unset_mode=0,client_mode,server_mode}; enum program_mode_t { unset_mode = 0,
client_mode,
server_mode };
extern program_mode_t program_mode; extern program_mode_t program_mode;
extern unordered_map<int, const char*> raw_mode_tostring ; extern unordered_map<int, const char *> raw_mode_tostring;
enum working_mode_t {unset_working_mode=0,tunnel_mode,tun_dev_mode}; enum working_mode_t { unset_working_mode = 0,
tunnel_mode,
tun_dev_mode };
extern working_mode_t working_mode; extern working_mode_t working_mode;
extern int socket_buf_size; extern int socket_buf_size;
// typedef u32_t id_t;
//typedef u32_t id_t;
typedef u64_t iv_t; typedef u64_t iv_t;
@@ -177,31 +175,35 @@ typedef u64_t anti_replay_seq_t;
typedef u64_t fd64_t; typedef u64_t fd64_t;
//enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd64_ip_port_conv,type_fd64_conv/*,type_fd*/}; // enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd64_ip_port_conv,type_fd64_conv/*,type_fd*/};
enum dest_type{none=0,type_fd64_addr,type_fd64,type_fd,type_write_fd,type_fd_addr/*,type_fd*/}; enum dest_type { none = 0,
type_fd64_addr,
type_fd64,
type_fd,
type_write_fd,
type_fd_addr /*,type_fd*/ };
/* /*
struct ip_port_t struct ip_port_t
{ {
u32_t ip; u32_t ip;
int port; int port;
void from_u64(u64_t u64); void from_u64(u64_t u64);
u64_t to_u64(); u64_t to_u64();
char * to_s(); char * to_s();
}; };
struct fd64_ip_port_t struct fd64_ip_port_t
{ {
fd64_t fd64; fd64_t fd64;
ip_port_t ip_port; ip_port_t ip_port;
}; };
struct fd_ip_port_t struct fd_ip_port_t
{ {
int fd; int fd;
ip_port_t ip_port; ip_port_t ip_port;
};*/ };*/
struct pseudo_header { struct pseudo_header {
u32_t source_address; u32_t source_address;
u32_t dest_address; u32_t dest_address;
@@ -210,205 +212,181 @@ struct pseudo_header {
unsigned short tcp_length; unsigned short tcp_length;
}; };
u32_t djb2(unsigned char *str,int len); u32_t djb2(unsigned char *str, int len);
u32_t sdbm(unsigned char *str,int len); u32_t sdbm(unsigned char *str, int len);
struct address_t //TODO scope id struct address_t // TODO scope id
{ {
struct hash_function struct hash_function {
{ u32_t operator()(const address_t &key) const {
u32_t operator()(const address_t &key) const return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
{ }
return sdbm((unsigned char*)&key.inner,sizeof(key.inner)); };
}
};
union storage_t //sockaddr_storage is too huge, we dont use it. union storage_t // sockaddr_storage is too huge, we dont use it.
{
sockaddr_in ipv4;
sockaddr_in6 ipv6;
};
storage_t inner;
/*address_t()
{
clear();
}*/
void clear()
{
memset(&inner,0,sizeof(inner));
}
/*
int from_ip_port(u32_t ip, int port)
{
clear();
inner.ipv4.sin_family=AF_INET;
inner.ipv4.sin_port=htons(port);
inner.ipv4.sin_addr.s_addr=ip;
return 0;
}*/
int from_ip_port_new(int type, void * ip, int port)
{
clear();
if(type==AF_INET)
{
inner.ipv4.sin_family=AF_INET;
inner.ipv4.sin_port=htons(port);
inner.ipv4.sin_addr.s_addr=*((u32_t *)ip);
}
else if(type==AF_INET6)
{
inner.ipv6.sin6_family=AF_INET6;
inner.ipv6.sin6_port=htons(port);
inner.ipv6.sin6_addr=*((in6_addr*)ip);
}
return 0;
}
int from_str(char * str);
int from_str_ip_only(char * str);
int from_sockaddr(sockaddr *,socklen_t);
char* get_str();
void to_str(char *);
inline int is_vaild()
{
u32_t ret=((sockaddr*)&inner)->sa_family;
return (ret==AF_INET||ret==AF_INET6);
}
inline u32_t get_type()
{
assert(is_vaild());
u32_t ret=((sockaddr*)&inner)->sa_family;
return ret;
}
inline u32_t get_len()
{
u32_t type=get_type();
switch(type)
{
case AF_INET:
return sizeof(sockaddr_in);
case AF_INET6:
return sizeof(sockaddr_in6);
default:
assert(0==1);
}
return -1;
}
inline u32_t get_port()
{
u32_t type=get_type();
switch(type)
{
case AF_INET:
return ntohs(inner.ipv4.sin_port);
case AF_INET6:
return ntohs(inner.ipv6.sin6_port);
default:
assert(0==1);
}
return -1;
}
inline void set_port(int port)
{
u32_t type=get_type();
switch(type)
{
case AF_INET:
inner.ipv4.sin_port=htons(port);
break;
case AF_INET6:
inner.ipv6.sin6_port=htons(port);
break;
default:
assert(0==1);
}
return ;
}
bool operator == (const address_t &b) const
{ {
//return this->data==b.data; sockaddr_in ipv4;
return memcmp(&this->inner,&b.inner,sizeof(this->inner))==0; sockaddr_in6 ipv6;
};
storage_t inner;
/*address_t()
{
clear();
}*/
void clear() {
memset(&inner, 0, sizeof(inner));
}
/*
int from_ip_port(u32_t ip, int port)
{
clear();
inner.ipv4.sin_family=AF_INET;
inner.ipv4.sin_port=htons(port);
inner.ipv4.sin_addr.s_addr=ip;
return 0;
}*/
int from_ip_port_new(int type, void *ip, int port) {
clear();
if (type == AF_INET) {
inner.ipv4.sin_family = AF_INET;
inner.ipv4.sin_port = htons(port);
inner.ipv4.sin_addr.s_addr = *((u32_t *)ip);
} else if (type == AF_INET6) {
inner.ipv6.sin6_family = AF_INET6;
inner.ipv6.sin6_port = htons(port);
inner.ipv6.sin6_addr = *((in6_addr *)ip);
}
return 0;
}
int from_str(char *str);
int from_str_ip_only(char *str);
int from_sockaddr(sockaddr *, socklen_t);
char *get_str();
void to_str(char *);
inline int is_vaild() {
u32_t ret = ((sockaddr *)&inner)->sa_family;
return (ret == AF_INET || ret == AF_INET6);
}
inline u32_t get_type() {
assert(is_vaild());
u32_t ret = ((sockaddr *)&inner)->sa_family;
return ret;
}
inline u32_t get_len() {
u32_t type = get_type();
switch (type) {
case AF_INET:
return sizeof(sockaddr_in);
case AF_INET6:
return sizeof(sockaddr_in6);
default:
assert(0 == 1);
}
return -1;
}
inline u32_t get_port() {
u32_t type = get_type();
switch (type) {
case AF_INET:
return ntohs(inner.ipv4.sin_port);
case AF_INET6:
return ntohs(inner.ipv6.sin6_port);
default:
assert(0 == 1);
}
return -1;
}
inline void set_port(int port) {
u32_t type = get_type();
switch (type) {
case AF_INET:
inner.ipv4.sin_port = htons(port);
break;
case AF_INET6:
inner.ipv6.sin6_port = htons(port);
break;
default:
assert(0 == 1);
}
return;
}
bool operator==(const address_t &b) const {
// return this->data==b.data;
return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0;
} }
int new_connected_udp_fd(); int new_connected_udp_fd();
char* get_ip(); char *get_ip();
}; };
namespace std { namespace std {
template <> template <>
struct hash<address_t> struct hash<address_t> {
{ std::size_t operator()(const address_t &key) const {
std::size_t operator()(const address_t& key) const // return address_t::hash_function(k);
{ return sdbm((unsigned char *)&key.inner, sizeof(key.inner));
}
};
} // namespace std
//return address_t::hash_function(k); struct fd64_addr_t {
return sdbm((unsigned char*)&key.inner,sizeof(key.inner)); fd64_t fd64;
} address_t addr;
};
}
struct fd64_addr_t
{
fd64_t fd64;
address_t addr;
}; };
struct fd_addr_t struct fd_addr_t {
{ int fd;
int fd; address_t addr;
address_t addr;
}; };
union inner_t union inner_t {
{ fd64_t fd64;
fd64_t fd64; int fd;
int fd; fd64_addr_t fd64_addr;
fd64_addr_t fd64_addr; fd_addr_t fd_addr;
fd_addr_t fd_addr;
}; };
struct dest_t struct dest_t {
{ dest_type type;
dest_type type; inner_t inner;
inner_t inner; u32_t conv;
u32_t conv; int cook = 0;
int cook=0;
}; };
struct fd_info_t struct fd_info_t {
{ address_t addr;
address_t addr; ev_io io_watcher;
ev_io io_watcher;
}; };
u64_t get_current_time(); u64_t get_current_time();
//u64_t get_current_time_rough(); // u64_t get_current_time_rough();
u64_t get_current_time_us(); u64_t get_current_time_us();
u64_t pack_u64(u32_t a,u32_t b); u64_t pack_u64(u32_t a, u32_t b);
u32_t get_u64_h(u64_t a); u32_t get_u64_h(u64_t a);
u32_t get_u64_l(u64_t a); u32_t get_u64_l(u64_t a);
void write_u16(char *,u16_t a); void write_u16(char *, u16_t a);
u16_t read_u16(char *); u16_t read_u16(char *);
void write_u32(char *,u32_t a); void write_u32(char *, u32_t a);
u32_t read_u32(char *); u32_t read_u32(char *);
void write_u64(char *,u64_t a); void write_u64(char *, u64_t a);
u64_t read_uu64(char *); u64_t read_uu64(char *);
char * my_ntoa(u32_t ip); char *my_ntoa(u32_t ip);
void myexit(int a); void myexit(int a);
void init_random_number_fd(); void init_random_number_fd();
@@ -417,148 +395,135 @@ u32_t get_fake_random_number();
u32_t get_fake_random_number_nz(); u32_t get_fake_random_number_nz();
u64_t ntoh64(u64_t a); u64_t ntoh64(u64_t a);
u64_t hton64(u64_t a); u64_t hton64(u64_t a);
bool larger_than_u16(uint16_t a,uint16_t b); bool larger_than_u16(uint16_t a, uint16_t b);
bool larger_than_u32(u32_t a,u32_t b); bool larger_than_u32(u32_t a, u32_t b);
void setnonblocking(int sock); void setnonblocking(int sock);
int set_buf_size(int fd,int socket_buf_size); int set_buf_size(int fd, int socket_buf_size);
unsigned short csum(const unsigned short *ptr,int nbytes); unsigned short csum(const unsigned short *ptr, int nbytes);
unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes); unsigned short tcp_csum(const pseudo_header &ph, const unsigned short *ptr, int nbytes);
void signal_handler(int sig); void signal_handler(int sig);
//int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len); // int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);
//int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3); // int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3);
void myexit(int a); void myexit(int a);
int add_iptables_rule(char *); int add_iptables_rule(char *);
int clear_iptables_rule(); int clear_iptables_rule();
void get_fake_random_chars(char * s,int len); void get_fake_random_chars(char *s, int len);
int random_between(u32_t a,u32_t b); int random_between(u32_t a, u32_t b);
int set_timer_ms(int epollfd,int &timer_fd,u32_t timer_interval); int set_timer_ms(int epollfd, int &timer_fd, u32_t timer_interval);
int round_up_div(int a,int b); int round_up_div(int a, int b);
int create_fifo(char * file); int create_fifo(char *file);
/* /*
int create_new_udp(int &new_udp_fd,int remote_address_uint32,int remote_port); int create_new_udp(int &new_udp_fd,int remote_address_uint32,int remote_port);
*/ */
int new_listen_socket(int &fd,u32_t ip,int port); int new_listen_socket(int &fd, u32_t ip, int port);
int new_connected_socket(int &fd,u32_t ip,int port); int new_connected_socket(int &fd, u32_t ip, int port);
int new_listen_socket2(int &fd,address_t &addr); int new_listen_socket2(int &fd, address_t &addr);
int new_connected_socket2(int &fd,address_t &addr,address_t *bind_addr,char *out_interface); int new_connected_socket2(int &fd, address_t &addr, address_t *bind_addr, char *out_interface);
struct not_copy_able_t struct not_copy_able_t {
{ not_copy_able_t() {
not_copy_able_t() }
{ not_copy_able_t(const not_copy_able_t &other) {
assert(0 == 1);
} }
not_copy_able_t(const not_copy_able_t &other) const not_copy_able_t &operator=(const not_copy_able_t &other) {
{ assert(0 == 1);
assert(0==1); return other;
} }
const not_copy_able_t & operator=(const not_copy_able_t &other)
{
assert(0==1);
return other;
}
}; };
template <class key_t> template <class key_t>
struct lru_collector_t:not_copy_able_t struct lru_collector_t : not_copy_able_t {
{ // typedef void* key_t;
//typedef void* key_t; //#define key_t void*
//#define key_t void* struct lru_pair_t {
struct lru_pair_t key_t key;
{ my_time_t ts;
key_t key; };
my_time_t ts;
};
unordered_map<key_t,typename list<lru_pair_t>::iterator> mp; unordered_map<key_t, typename list<lru_pair_t>::iterator> mp;
list<lru_pair_t> q; list<lru_pair_t> q;
int update(key_t key) int update(key_t key) {
{ assert(mp.find(key) != mp.end());
assert(mp.find(key)!=mp.end()); auto it = mp[key];
auto it=mp[key]; q.erase(it);
q.erase(it);
my_time_t value=get_current_time(); my_time_t value = get_current_time();
if(!q.empty()) if (!q.empty()) {
{ assert(value >= q.front().ts);
assert(value >=q.front().ts); }
} lru_pair_t tmp;
lru_pair_t tmp; tmp.key=key; tmp.ts=value; tmp.key = key;
q.push_front( tmp); tmp.ts = value;
mp[key]=q.begin(); q.push_front(tmp);
mp[key] = q.begin();
return 0; return 0;
} }
int new_key(key_t key) int new_key(key_t key) {
{ assert(mp.find(key) == mp.end());
assert(mp.find(key)==mp.end());
my_time_t value=get_current_time(); my_time_t value = get_current_time();
if(!q.empty()) if (!q.empty()) {
{ assert(value >= q.front().ts);
assert(value >=q.front().ts); }
} lru_pair_t tmp;
lru_pair_t tmp; tmp.key=key; tmp.ts=value; tmp.key = key;
q.push_front( tmp); tmp.ts = value;
mp[key]=q.begin(); q.push_front(tmp);
mp[key] = q.begin();
return 0; return 0;
} }
int size() int size() {
{ return q.size();
return q.size(); }
} int empty() {
int empty() return q.empty();
{ }
return q.empty(); void clear() {
} mp.clear();
void clear() q.clear();
{ }
mp.clear(); q.clear(); my_time_t ts_of(key_t key) {
} assert(mp.find(key) != mp.end());
my_time_t ts_of(key_t key) return mp[key]->ts;
{ }
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());
assert(!q.empty()); auto it = q.end();
auto it=q.end(); it--; it--;
key=it->key; key = it->key;
return it->ts; return it->ts;
} }
void erase(key_t key) void erase(key_t key) {
{ assert(mp.find(key) != mp.end());
assert(mp.find(key)!=mp.end()); q.erase(mp[key]);
q.erase(mp[key]); mp.erase(key);
mp.erase(key); }
} /*
/* void erase_back()
void erase_back() {
{ assert(!q.empty());
assert(!q.empty()); auto it=q.end(); it--;
auto it=q.end(); it--; key_t key=it->key;
key_t key=it->key; erase(key);
erase(key); }*/
}*/
}; };
vector<string> string_to_vec(const char *s, const char *sp);
vector<string> string_to_vec(const char * s,const char * sp) ;
#endif /* COMMON_H_ */ #endif /* COMMON_H_ */

View File

@@ -7,147 +7,124 @@
#include "connection.h" #include "connection.h"
//const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short. // const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short.
const int disable_conn_clear=0;//a raw connection is called conn. const int disable_conn_clear = 0; // a raw connection is called conn.
int report_interval=0; int report_interval = 0;
void server_clear_function(u64_t u64)//used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection), void server_clear_function(u64_t u64) // used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection),
//so we have to close the fd when conv expires // so we have to close the fd when conv expires
{ {
fd64_t fd64=u64; fd64_t fd64 = u64;
assert(fd_manager.exist(fd64)); assert(fd_manager.exist(fd64));
ev_io &watcher= fd_manager.get_info(fd64).io_watcher; ev_io &watcher = fd_manager.get_info(fd64).io_watcher;
address_t &addr=fd_manager.get_info(fd64).addr;// address_t &addr = fd_manager.get_info(fd64).addr; //
assert(conn_manager.exist(addr));// assert(conn_manager.exist(addr)); //
struct ev_loop *loop =conn_manager.find_insert(addr).loop; // overkill ? should we just use ev_default_loop(0)? struct ev_loop *loop = conn_manager.find_insert(addr).loop; // overkill ? should we just use ev_default_loop(0)?
ev_io_stop(loop,&watcher); ev_io_stop(loop, &watcher);
fd_manager.fd64_close(fd64);
fd_manager.fd64_close(fd64);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
conn_manager_t::conn_manager_t() conn_manager_t::conn_manager_t() {
{ mp.reserve(10007);
mp.reserve(10007); last_clear_time = 0;
last_clear_time=0;
} }
int conn_manager_t::exist(address_t addr) int conn_manager_t::exist(address_t addr) {
{ if (mp.find(addr) != mp.end()) {
return 1;
if(mp.find(addr)!=mp.end()) }
{ return 0;
return 1;
}
return 0;
} }
conn_info_t *& conn_manager_t::find_insert_p(address_t addr) //be aware,the adress may change after rehash conn_info_t *&conn_manager_t::find_insert_p(address_t addr) // be aware,the adress may change after rehash
{ {
// u64_t u64=0; // u64_t u64=0;
//u64=ip; // u64=ip;
//u64<<=32u; // u64<<=32u;
//u64|=port; // u64|=port;
unordered_map<address_t,conn_info_t*>::iterator it=mp.find(addr); unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr);
if(it==mp.end()) if (it == mp.end()) {
{ mp[addr] = new conn_info_t;
mp[addr]=new conn_info_t; // lru.new_key(addr);
//lru.new_key(addr); } else {
} // lru.update(addr);
else }
{ return mp[addr];
//lru.update(addr);
}
return mp[addr];
} }
conn_info_t & conn_manager_t::find_insert(address_t addr) //be aware,the adress may change after rehash conn_info_t &conn_manager_t::find_insert(address_t addr) // be aware,the adress may change after rehash
{ {
//u64_t u64=0; // u64_t u64=0;
//u64=ip; // u64=ip;
//u64<<=32u; // u64<<=32u;
//u64|=port; // u64|=port;
unordered_map<address_t,conn_info_t*>::iterator it=mp.find(addr); unordered_map<address_t, conn_info_t *>::iterator it = mp.find(addr);
if(it==mp.end()) if (it == mp.end()) {
{ mp[addr] = new conn_info_t;
mp[addr]=new conn_info_t; // lru.new_key(addr);
//lru.new_key(addr); } else {
} // lru.update(addr);
else }
{ return *mp[addr];
//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);
delete(erase_it->second); mp.erase(erase_it->first);
mp.erase(erase_it->first); return 0;
return 0;
} }
int conn_manager_t::clear_inactive() int conn_manager_t::clear_inactive() {
{ if (get_current_time() - last_clear_time > conn_clear_interval) {
if(get_current_time()-last_clear_time>conn_clear_interval) last_clear_time = get_current_time();
{ return clear_inactive0();
last_clear_time=get_current_time(); }
return clear_inactive0(); return 0;
}
return 0;
} }
int conn_manager_t::clear_inactive0() int conn_manager_t::clear_inactive0() {
{ // mylog(log_info,"called\n");
//mylog(log_info,"called\n"); unordered_map<address_t, conn_info_t *>::iterator it;
unordered_map<address_t,conn_info_t*>::iterator it; unordered_map<address_t, conn_info_t *>::iterator old_it;
unordered_map<address_t,conn_info_t*>::iterator old_it;
if(disable_conn_clear) return 0; if (disable_conn_clear) return 0;
//map<uint32_t,uint64_t>::iterator it; // map<uint32_t,uint64_t>::iterator it;
int cnt=0; int cnt = 0;
it=clear_it;//TODO,write it back it = clear_it; // TODO,write it back
int size=mp.size(); int size = mp.size();
int num_to_clean=size/conn_clear_ratio+conn_clear_min; //clear 1/10 each time,to avoid latency glitch int num_to_clean = size / conn_clear_ratio + conn_clear_min; // clear 1/10 each time,to avoid latency glitch
//mylog(log_trace,"mp.size() %d\n", size); // mylog(log_trace,"mp.size() %d\n", size);
num_to_clean=min(num_to_clean,(int)mp.size()); num_to_clean = min(num_to_clean, (int)mp.size());
u64_t current_time=get_current_time(); u64_t current_time = get_current_time();
//mylog(log_info,"here size=%d\n",(int)mp.size()); // mylog(log_info,"here size=%d\n",(int)mp.size());
for(;;) for (;;) {
{ if (cnt >= num_to_clean) break;
if(cnt>=num_to_clean) break; if (mp.begin() == mp.end()) break;
if(mp.begin()==mp.end()) break; if (it == mp.end()) {
if(it==mp.end()) it = mp.begin();
{ }
it=mp.begin();
}
if(it->second->conv_manager.s.get_size() >0) if (it->second->conv_manager.s.get_size() > 0) {
{ // mylog(log_info,"[%s:%d]size %d \n",my_ntoa(get_u64_h(it->first)),get_u64_l(it->first),(int)it->second->conv_manager.get_size());
//mylog(log_info,"[%s:%d]size %d \n",my_ntoa(get_u64_h(it->first)),get_u64_l(it->first),(int)it->second->conv_manager.get_size()); it++;
it++; } else if (current_time < it->second->last_active_time + server_conn_timeout) {
} it++;
else if(current_time<it->second->last_active_time+server_conn_timeout) } else {
{ address_t tmp_addr = it->first; // avoid making get_str() const;
it++; mylog(log_info, "{%s} inactive conn cleared \n", tmp_addr.get_str());
} old_it = it;
else it++;
{ erase(old_it);
address_t tmp_addr=it->first;// avoid making get_str() const; }
mylog(log_info,"{%s} inactive conn cleared \n",tmp_addr.get_str()); cnt++;
old_it=it; }
it++; clear_it = it;
erase(old_it); return 0;
}
cnt++;
}
clear_it=it;
return 0;
} }

View File

@@ -19,365 +19,307 @@ extern int disable_anti_replay;
extern int report_interval; extern int report_interval;
const int disable_conv_clear=0; const int disable_conv_clear = 0;
void server_clear_function(u64_t u64); void server_clear_function(u64_t u64);
template <class T> template <class T>
struct conv_manager_t // manage the udp connections struct conv_manager_t // manage the udp connections
{ {
//typedef hash_map map; // typedef hash_map map;
unordered_map<T,u32_t> data_to_conv; //conv and u64 are both supposed to be uniq unordered_map<T, u32_t> data_to_conv; // conv and u64 are both supposed to be uniq
unordered_map<u32_t,T> conv_to_data; unordered_map<u32_t, T> conv_to_data;
lru_collector_t<u32_t> lru; lru_collector_t<u32_t> lru;
//unordered_map<u32_t,u64_t> conv_last_active_time; // unordered_map<u32_t,u64_t> conv_last_active_time;
//unordered_map<u32_t,u64_t>::iterator clear_it; // unordered_map<u32_t,u64_t>::iterator clear_it;
void (*additional_clear_function)(T data) =0; void (*additional_clear_function)(T data) = 0;
long long last_clear_time; long long last_clear_time;
conv_manager_t() conv_manager_t() {
{ // clear_it=conv_last_active_time.begin();
//clear_it=conv_last_active_time.begin(); long long last_clear_time = 0;
long long last_clear_time=0; additional_clear_function = 0;
additional_clear_function=0; }
} ~conv_manager_t() {
~conv_manager_t() clear();
{ }
clear(); int get_size() {
} return conv_to_data.size();
int get_size() }
{ void reserve() {
return conv_to_data.size(); data_to_conv.reserve(10007);
} conv_to_data.reserve(10007);
void reserve() // conv_last_active_time.reserve(10007);
{
data_to_conv.reserve(10007);
conv_to_data.reserve(10007);
//conv_last_active_time.reserve(10007);
lru.mp.reserve(10007); lru.mp.reserve(10007);
} }
void clear() void clear() {
{ if (disable_conv_clear) return;
if(disable_conv_clear) return ;
if(additional_clear_function!=0) if (additional_clear_function != 0) {
{ for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) {
for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++) // int fd=int((it->second<<32u)>>32u);
{ additional_clear_function(it->second);
//int fd=int((it->second<<32u)>>32u); }
additional_clear_function( it->second); }
} data_to_conv.clear();
} conv_to_data.clear();
data_to_conv.clear();
conv_to_data.clear();
lru.clear(); lru.clear();
//conv_last_active_time.clear(); // conv_last_active_time.clear();
//clear_it=conv_last_active_time.begin(); // clear_it=conv_last_active_time.begin();
}
u32_t get_new_conv() {
u32_t conv = get_fake_random_number_nz();
while (conv_to_data.find(conv) != conv_to_data.end()) {
conv = get_fake_random_number_nz();
}
return conv;
}
int is_conv_used(u32_t conv) {
return conv_to_data.find(conv) != conv_to_data.end();
}
int is_data_used(T data) {
return data_to_conv.find(data) != data_to_conv.end();
}
u32_t find_conv_by_data(T data) {
return data_to_conv[data];
}
T find_data_by_conv(u32_t conv) {
return conv_to_data[conv];
}
int update_active_time(u32_t conv) {
// return conv_last_active_time[conv]=get_current_time();
lru.update(conv);
return 0;
}
int insert_conv(u32_t conv, T data) {
data_to_conv[data] = conv;
conv_to_data[conv] = data;
// conv_last_active_time[conv]=get_current_time();
lru.new_key(conv);
return 0;
}
int erase_conv(u32_t conv) {
if (disable_conv_clear) return 0;
T data = conv_to_data[conv];
if (additional_clear_function != 0) {
additional_clear_function(data);
}
conv_to_data.erase(conv);
data_to_conv.erase(data);
// conv_last_active_time.erase(conv);
lru.erase(conv);
return 0;
}
int clear_inactive(char *info = 0) {
if (get_current_time() - last_clear_time > conv_clear_interval) {
last_clear_time = get_current_time();
return clear_inactive0(info);
}
return 0;
}
int clear_inactive0(char *info) {
if (disable_conv_clear) return 0;
} unordered_map<u32_t, u64_t>::iterator it;
u32_t get_new_conv() unordered_map<u32_t, u64_t>::iterator old_it;
{
u32_t conv=get_fake_random_number_nz();
while(conv_to_data.find(conv)!=conv_to_data.end())
{
conv=get_fake_random_number_nz();
}
return conv;
}
int is_conv_used(u32_t conv)
{
return conv_to_data.find(conv)!=conv_to_data.end();
}
int is_data_used(T data)
{
return data_to_conv.find(data)!=data_to_conv.end();
}
u32_t find_conv_by_data(T data)
{
return data_to_conv[data];
}
T find_data_by_conv(u32_t conv)
{
return conv_to_data[conv];
}
int update_active_time(u32_t conv)
{
//return conv_last_active_time[conv]=get_current_time();
lru.update(conv);
return 0;
}
int insert_conv(u32_t conv,T data)
{
data_to_conv[data]=conv;
conv_to_data[conv]=data;
//conv_last_active_time[conv]=get_current_time();
lru.new_key(conv);
return 0;
}
int erase_conv(u32_t conv)
{
if(disable_conv_clear) return 0;
T data=conv_to_data[conv];
if(additional_clear_function!=0)
{
additional_clear_function(data);
}
conv_to_data.erase(conv);
data_to_conv.erase(data);
//conv_last_active_time.erase(conv);
lru.erase(conv);
return 0;
}
int clear_inactive(char * info=0)
{
if(get_current_time()-last_clear_time>conv_clear_interval)
{
last_clear_time=get_current_time();
return clear_inactive0(info);
}
return 0;
}
int clear_inactive0(char * info)
{
if(disable_conv_clear) return 0;
// map<uint32_t,uint64_t>::iterator it;
int cnt = 0;
// it=clear_it;
int size = lru.size();
int num_to_clean = size / conv_clear_ratio + conv_clear_min; // clear 1/10 each time,to avoid latency glitch
unordered_map<u32_t,u64_t>::iterator it; num_to_clean = min(num_to_clean, size);
unordered_map<u32_t,u64_t>::iterator old_it;
//map<uint32_t,uint64_t>::iterator it; my_time_t current_time = get_current_time();
int cnt=0; for (;;) {
//it=clear_it; if (cnt >= num_to_clean) break;
int size=lru.size(); if (lru.empty()) break;
int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch
num_to_clean=min(num_to_clean,size); u32_t conv;
my_time_t ts = lru.peek_back(conv);
my_time_t current_time=get_current_time(); if (current_time - ts < conv_timeout) break;
for(;;)
{
if(cnt>=num_to_clean) break;
if(lru.empty()) break;
u32_t conv; erase_conv(conv);
my_time_t ts=lru.peek_back(conv); if (info == 0) {
mylog(log_info, "conv %x cleared\n", conv);
} else {
mylog(log_info, "[%s]conv %x cleared\n", info, conv);
}
cnt++;
}
return 0;
}
if(current_time- ts < conv_timeout) break; /*
conv_manager_t();
~conv_manager_t();
int get_size();
void reserve();
void clear();
u32_t get_new_conv();
int is_conv_used(u32_t conv);
int is_u64_used(T u64);
u32_t find_conv_by_u64(T u64);
T find_u64_by_conv(u32_t conv);
int update_active_time(u32_t conv);
int insert_conv(u32_t conv,T u64);
int erase_conv(u32_t conv);
int clear_inactive(char * ip_port=0);
int clear_inactive0(char * ip_port);*/
}; // g_conv_manager;
erase_conv(conv); struct inner_stat_t {
if(info==0) u64_t input_packet_num;
{ u64_t input_packet_size;
mylog(log_info,"conv %x cleared\n",conv); u64_t output_packet_num;
} u64_t output_packet_size;
else
{
mylog(log_info,"[%s]conv %x cleared\n",info,conv);
}
cnt++;
}
return 0;
}
/*
conv_manager_t();
~conv_manager_t();
int get_size();
void reserve();
void clear();
u32_t get_new_conv();
int is_conv_used(u32_t conv);
int is_u64_used(T u64);
u32_t find_conv_by_u64(T u64);
T find_u64_by_conv(u32_t conv);
int update_active_time(u32_t conv);
int insert_conv(u32_t conv,T u64);
int erase_conv(u32_t conv);
int clear_inactive(char * ip_port=0);
int clear_inactive0(char * ip_port);*/
};//g_conv_manager;
struct inner_stat_t
{
u64_t input_packet_num;
u64_t input_packet_size;
u64_t output_packet_num;
u64_t output_packet_size;
}; };
struct stat_t struct stat_t {
{ u64_t last_report_time;
u64_t last_report_time; inner_stat_t normal_to_fec;
inner_stat_t normal_to_fec; inner_stat_t fec_to_normal;
inner_stat_t fec_to_normal; stat_t() {
stat_t() clear();
{ }
memset(this,0,sizeof(stat_t)); void clear(){
} memset(this, 0, sizeof(stat_t));
void report_as_client() }
{ void report_as_client() {
if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000) if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) {
{ last_report_time = get_current_time();
last_report_time=get_current_time(); inner_stat_t &a = normal_to_fec;
inner_stat_t &a=normal_to_fec; inner_stat_t &b = fec_to_normal;
inner_stat_t &b=fec_to_normal; mylog(log_info, "[report]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt,%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n",
mylog(log_info,"[report]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt,%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n", a.input_packet_num, a.input_packet_size, a.output_packet_num, a.output_packet_size,
a.input_packet_num,a.input_packet_size,a.output_packet_num,a.output_packet_size, b.output_packet_num, b.output_packet_size, b.input_packet_num, b.input_packet_size);
b.output_packet_num,b.output_packet_size,b.input_packet_num,b.input_packet_size }
); }
} void report_as_server(address_t &addr) {
} if (report_interval != 0 && get_current_time() - last_report_time > u64_t(report_interval) * 1000) {
void report_as_server(address_t &addr) last_report_time = get_current_time();
{ inner_stat_t &a = fec_to_normal;
if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000) 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",
last_report_time=get_current_time(); addr.get_str(),
inner_stat_t &a=fec_to_normal; a.output_packet_num, a.output_packet_size, a.input_packet_num, a.input_packet_size,
inner_stat_t &b=normal_to_fec; b.input_packet_num, b.input_packet_size, b.output_packet_num, b.output_packet_size);
mylog(log_info,"[report][%s]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n", }
addr.get_str(), }
a.output_packet_num,a.output_packet_size,a.input_packet_num,a.input_packet_size,
b.input_packet_num,b.input_packet_size,b.output_packet_num,b.output_packet_size
);
}
}
}; };
struct conn_info_t : not_copy_able_t // stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can
struct conn_info_t:not_copy_able_t //stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can // handle multiple clients
//handle multiple clients
{ {
union tmp_union_t union tmp_union_t {
{ conv_manager_t<address_t> c;
conv_manager_t<address_t> c; conv_manager_t<u64_t> s;
conv_manager_t<u64_t> s; // avoid templates here and there, avoid pointer and type cast
//avoid templates here and there, avoid pointer and type cast tmp_union_t() {
tmp_union_t() if (program_mode == client_mode) {
{ new (&c) conv_manager_t<address_t>();
if(program_mode==client_mode) } else {
{ assert(program_mode == server_mode);
new( &c ) conv_manager_t<address_t>(); new (&s) conv_manager_t<u64_t>();
} }
else }
{ ~tmp_union_t() {
assert(program_mode==server_mode); if (program_mode == client_mode) {
new( &s ) conv_manager_t<u64_t>(); c.~conv_manager_t<address_t>();
} } else {
} assert(program_mode == server_mode);
~tmp_union_t() s.~conv_manager_t<u64_t>();
{ }
if(program_mode==client_mode) }
{ } conv_manager;
c.~conv_manager_t<address_t>();
}
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;
// my_timer_t timer;
fec_encode_manager_t fec_encode_manager; u64_t last_active_time;
fec_decode_manager_t fec_decode_manager; stat_t stat;
ev_timer timer;
//my_timer_t timer;
u64_t last_active_time; struct ev_loop *loop = 0;
stat_t stat; int local_listen_fd;
struct ev_loop* loop=0; int remote_fd; // only used for client
int local_listen_fd; fd64_t remote_fd64; // only used for client
int remote_fd; //only used for client // ip_port_t ip_port;
fd64_t remote_fd64;//only used for client address_t addr; // only used for server
//ip_port_t ip_port; conn_info_t() {
address_t addr;//only used for server if (program_mode == server_mode) {
conv_manager.s.additional_clear_function = server_clear_function;
} else {
assert(program_mode == client_mode);
}
}
conn_info_t() ~conn_info_t() {
{ if (loop)
if(program_mode==server_mode) ev_timer_stop(loop, &timer);
{ }
conv_manager.s.additional_clear_function=server_clear_function; void update_active_time() {
} last_active_time = get_current_time();
else }
{ /*
assert(program_mode==client_mode); conn_info_t(const conn_info_t &b)
} {
} assert(0==1);
}*/
~conn_info_t()
{
if(loop)
ev_timer_stop(loop,&timer);
}
void update_active_time()
{
last_active_time=get_current_time();
}
/*
conn_info_t(const conn_info_t &b)
{
assert(0==1);
}*/
}; };
/* /*
struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections 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<u64_t,conn_info_t*> mp;//<ip,port> to conn_info_t; unordered_map<u64_t,conn_info_t*> mp;//<ip,port> to conn_info_t;
unordered_map<u64_t,conn_info_t*>::iterator clear_it; unordered_map<u64_t,conn_info_t*>::iterator clear_it;
long long last_clear_time; long long last_clear_time;
conn_manager_t(); conn_manager_t();
conn_manager_t(const conn_info_t &b) conn_manager_t(const conn_info_t &b)
{ {
assert(0==1); assert(0==1);
} }
int exist(ip_port_t); int exist(ip_port_t);
conn_info_t *& find_p(ip_port_t); //be aware,the adress may change after rehash conn_info_t *& find_p(ip_port_t); //be aware,the adress may change after rehash
conn_info_t & find(ip_port_t) ; //be aware,the adress may change after rehash conn_info_t & find(ip_port_t) ; //be aware,the adress may change after rehash
int insert(ip_port_t); int insert(ip_port_t);
int erase(unordered_map<u64_t,conn_info_t*>::iterator erase_it); int erase(unordered_map<u64_t,conn_info_t*>::iterator erase_it);
int clear_inactive(); int clear_inactive();
int clear_inactive0(); int clear_inactive0();
};*/ };*/
struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections struct conn_manager_t // manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections
{ {
unordered_map<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;
long long last_clear_time;
unordered_map<address_t,conn_info_t*> mp; //put it at end so that it de-consturcts first conn_manager_t();
unordered_map<address_t,conn_info_t*>::iterator clear_it; int exist(address_t addr);
conn_info_t *&find_insert_p(address_t addr); // be aware,the adress may change after rehash //not true?
long long last_clear_time; conn_info_t &find_insert(address_t addr); // be aware,the adress may change after rehash
conn_manager_t();
int exist(address_t addr);
conn_info_t *& find_insert_p(address_t addr); //be aware,the adress may change after rehash //not true?
conn_info_t & find_insert(address_t addr) ; //be aware,the adress may change after rehash
int erase(unordered_map<address_t,conn_info_t*>::iterator erase_it);
int clear_inactive();
int clear_inactive0();
int erase(unordered_map<address_t, conn_info_t *>::iterator erase_it);
int clear_inactive();
int clear_inactive0();
}; };
extern conn_manager_t conn_manager; extern conn_manager_t conn_manager;
#endif /* CONNECTION_H_ */ #endif /* CONNECTION_H_ */

1245
crc32/Crc32.cpp Normal file

File diff suppressed because it is too large Load Diff

69
crc32/Crc32.h Normal file
View File

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

10
crc32/LICENSE Normal file
View File

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

View File

@@ -8,125 +8,106 @@
#include "log.h" #include "log.h"
#include "packet.h" #include "packet.h"
int delay_data_t::handle() int delay_data_t::handle() {
{ return my_send(dest, data, len) >= 0;
return my_send(dest,data,len)>=0;
} }
delay_manager_t::delay_manager_t() {
capacity = 0;
delay_manager_t::delay_manager_t() // if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0)
{ //{
capacity=0; // mylog(log_fatal,"timer_fd create error");
// myexit(1);
// }
//if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) // itimerspec zero_its;
//{ // memset(&zero_its, 0, sizeof(zero_its));
// mylog(log_fatal,"timer_fd create error");
// myexit(1);
//}
//itimerspec zero_its;
//memset(&zero_its, 0, sizeof(zero_its));
//timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0);
// timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0);
} }
delay_manager_t::~delay_manager_t() delay_manager_t::~delay_manager_t() {
{ // TODO ,we currently dont need to deconstruct it
//TODO ,we currently dont need to deconstruct it
} }
/* /*
int delay_manager_t::get_timer_fd() int delay_manager_t::get_timer_fd()
{ {
return timer_fd; return timer_fd;
}*/ }*/
//int add(my_time_t delay,const dest_t &dest,const char *data,int len); // int add(my_time_t delay,const dest_t &dest,const char *data,int len);
int delay_manager_t::add(my_time_t delay,const dest_t &dest,char *data,int len) int delay_manager_t::add(my_time_t delay, const dest_t &dest, char *data, int len) {
{ delay_data_t delay_data;
delay_data_t delay_data; delay_data.dest = dest;
delay_data.dest=dest; // delay_data.data=data;
//delay_data.data=data; delay_data.len = len;
delay_data.len=len;
if(capacity!=0&&int(delay_mp.size()) >=capacity) if (capacity != 0 && int(delay_mp.size()) >= capacity) {
{ mylog(log_warn, "max pending packet reached,ignored\n");
mylog(log_warn,"max pending packet reached,ignored\n"); return -1;
return -1; }
} if (delay == 0) {
if(delay==0) static char buf[buf_len];
{ delay_data.data = buf;
static char buf[buf_len]; memcpy(buf, data, len);
delay_data.data=buf; int ret = delay_data.handle();
memcpy(buf,data,len); if (ret != 0) {
int ret=delay_data.handle(); mylog(log_trace, "handle() return %d\n", ret);
if (ret != 0) { }
mylog(log_trace, "handle() return %d\n", ret); return 0;
} }
return 0;
}
delay_data_t tmp=delay_data; delay_data_t tmp = delay_data;
tmp.data=(char *)malloc(delay_data.len+100); tmp.data = (char *)malloc(delay_data.len + 100);
if(!tmp.data) if (!tmp.data) {
{
mylog(log_warn, "malloc() returned null in delay_manager_t::add()"); mylog(log_warn, "malloc() returned null in delay_manager_t::add()");
return -1; return -1;
} }
memcpy(tmp.data,data,delay_data.len); memcpy(tmp.data, data, delay_data.len);
my_time_t tmp_time=get_current_time_us(); my_time_t tmp_time = get_current_time_us();
tmp_time+=delay; tmp_time += delay;
delay_mp.insert(make_pair(tmp_time,tmp)); delay_mp.insert(make_pair(tmp_time, tmp));
////check(); check everytime when add, is it better ?? ////check(); check everytime when add, is it better ??
return 0; return 0;
} }
int delay_manager_t::check() int delay_manager_t::check() {
{ if (!delay_mp.empty()) {
if(!delay_mp.empty()) my_time_t current_time;
{
my_time_t current_time;
multimap<my_time_t,delay_data_t>::iterator it; multimap<my_time_t, delay_data_t>::iterator it;
while(1) while (1) {
{ int ret = 0;
int ret=0; it = delay_mp.begin();
it=delay_mp.begin(); if (it == delay_mp.end()) break;
if(it==delay_mp.end()) break;
current_time=get_current_time_us(); current_time = get_current_time_us();
if(it->first <= current_time) if (it->first <= current_time) {
{ ret = it->second.handle();
ret=it->second.handle(); if (ret != 0) {
if (ret != 0) { mylog(log_trace, "handle() return %d\n", ret);
mylog(log_trace, "handle() return %d\n", ret); }
} free(it->second.data);
free(it->second.data); delay_mp.erase(it);
delay_mp.erase(it); } else {
} break;
else }
{ }
break; if (!delay_mp.empty()) {
} const double m = 1000 * 1000;
double timer_value = delay_mp.begin()->first / m - get_current_time_us() / m; // be aware of negative value, and be aware of uint
} if (timer_value < 0) timer_value = 0; // set it to 0 if negative, although libev support negative value
if(!delay_mp.empty()) ev_timer_stop(loop, &timer);
{ ev_timer_set(&timer, timer_value, 0);
const double m=1000*1000; ev_timer_start(loop, &timer);
double timer_value=delay_mp.begin()->first/m -get_current_time_us()/m; // be aware of negative value, and be aware of uint } else {
if(timer_value<0) timer_value=0; // set it to 0 if negative, although libev support negative value ev_timer_stop(loop, &timer); // not necessary
ev_timer_stop(loop, &timer); }
ev_timer_set(&timer, timer_value,0 ); }
ev_timer_start(loop, &timer); return 0;
}
else
{
ev_timer_stop(loop, &timer); //not necessary
}
}
return 0;
} }

View File

@@ -12,132 +12,130 @@
#include "packet.h" #include "packet.h"
#include "log.h" #include "log.h"
//enum delay_type_t {none=0,enum_sendto_u64,enum_send_fd,client_to_local,client_to_remote,server_to_local,server_to_remote}; // enum delay_type_t {none=0,enum_sendto_u64,enum_send_fd,client_to_local,client_to_remote,server_to_local,server_to_remote};
/* /*
struct fd_ip_port_t struct fd_ip_port_t
{ {
int fd; int fd;
u32_t ip; u32_t ip;
u32_t port; u32_t port;
}; };
union dest_t union dest_t
{ {
fd_ip_port_t fd_ip_port; fd_ip_port_t fd_ip_port;
int fd; int fd;
u64_t u64; u64_t u64;
}; };
*/ */
/* /*
struct my_timer_t struct my_timer_t
{ {
int timer_fd; int timer_fd;
fd64_t timer_fd64; fd64_t timer_fd64;
my_timer_t() my_timer_t()
{ {
if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0)
{ {
mylog(log_fatal,"timer_fd create error"); mylog(log_fatal,"timer_fd create error");
myexit(1); myexit(1);
} }
timer_fd64=fd_manager.create(timer_fd); timer_fd64=fd_manager.create(timer_fd);
} }
my_timer_t(const my_timer_t &b) my_timer_t(const my_timer_t &b)
{ {
assert(0==1); assert(0==1);
} }
~my_timer_t() ~my_timer_t()
{ {
fd_manager.fd64_close(timer_fd64); fd_manager.fd64_close(timer_fd64);
} }
int add_fd_to_epoll(int epoll_fd) int add_fd_to_epoll(int epoll_fd)
{ {
epoll_event ev;; epoll_event ev;;
ev.events = EPOLLIN; ev.events = EPOLLIN;
ev.data.u64 = timer_fd; ev.data.u64 = timer_fd;
int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev); int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev);
if (ret!= 0) { if (ret!= 0) {
mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); mylog(log_fatal,"add delay_manager.get_timer_fd() error\n");
myexit(-1); myexit(-1);
} }
return 0; return 0;
} }
int add_fd64_to_epoll(int epoll_fd) int add_fd64_to_epoll(int epoll_fd)
{ {
epoll_event ev;; epoll_event ev;;
ev.events = EPOLLIN; ev.events = EPOLLIN;
ev.data.u64 = timer_fd64; ev.data.u64 = timer_fd64;
int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev); int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &ev);
if (ret!= 0) { if (ret!= 0) {
mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); mylog(log_fatal,"add delay_manager.get_timer_fd() error\n");
myexit(-1); myexit(-1);
} }
return 0; return 0;
} }
int get_timer_fd() int get_timer_fd()
{ {
return timer_fd; return timer_fd;
} }
fd64_t get_timer_fd64() fd64_t get_timer_fd64()
{ {
return timer_fd64; return timer_fd64;
} }
int set_timer_repeat_us(my_time_t my_time) int set_timer_repeat_us(my_time_t my_time)
{ {
itimerspec its; itimerspec its;
memset(&its,0,sizeof(its)); memset(&its,0,sizeof(its));
its.it_interval.tv_sec=my_time/1000000llu; its.it_interval.tv_sec=my_time/1000000llu;
its.it_interval.tv_nsec=my_time%1000000llu*1000llu; its.it_interval.tv_nsec=my_time%1000000llu*1000llu;
its.it_value.tv_nsec=1; //imidiately its.it_value.tv_nsec=1; //imidiately
timerfd_settime(timer_fd,0,&its,0); timerfd_settime(timer_fd,0,&its,0);
return 0; return 0;
} }
int set_timer_abs_us(my_time_t my_time) int set_timer_abs_us(my_time_t my_time)
{ {
itimerspec its; itimerspec its;
memset(&its,0,sizeof(its)); memset(&its,0,sizeof(its));
its.it_value.tv_sec=my_time/1000000llu; its.it_value.tv_sec=my_time/1000000llu;
its.it_value.tv_nsec=my_time%1000000llu*1000llu; its.it_value.tv_nsec=my_time%1000000llu*1000llu;
timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0); timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0);
return 0; return 0;
} }
};*/ };*/
struct delay_data_t {
struct delay_data_t dest_t dest;
{ // int left_time;//
dest_t dest; char *data;
//int left_time;// int len;
char * data; int handle();
int len;
int handle();
}; };
struct delay_manager_t struct delay_manager_t {
{ ev_timer timer;
ev_timer timer; struct ev_loop *loop = 0;
struct ev_loop *loop=0; void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0;
void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)=0;
//int timer_fd; // int timer_fd;
int capacity; int capacity;
multimap<my_time_t,delay_data_t> delay_mp; //unit us,1 us=0.001ms multimap<my_time_t, delay_data_t> delay_mp; // unit us,1 us=0.001ms
delay_manager_t(); delay_manager_t();
delay_manager_t(delay_manager_t &b) delay_manager_t(delay_manager_t &b) {
{ assert(0 == 1);
assert(0==1); }
} void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) {
void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)) this->loop = loop;
{ this->cb = cb;
this->loop=loop; ev_init(&timer, cb);
this->cb=cb; }
ev_init(&timer,cb); int set_capacity(int a) {
} capacity = a;
int set_capacity(int a){capacity=a;return 0;} return 0;
~delay_manager_t(); }
ev_timer& get_timer(); ~delay_manager_t();
int check(); ev_timer &get_timer();
int add(my_time_t delay,const dest_t &dest,char *data,int len); int check();
int add(my_time_t delay, const dest_t &dest, char *data, int len);
}; };
#endif /* DELAY_MANAGER_H_ */ #endif /* DELAY_MANAGER_H_ */

View File

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

View File

@@ -11,27 +11,26 @@
#include "common.h" #include "common.h"
#include "packet.h" #include "packet.h"
struct fd_manager_t // conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create
// this class is not strictly necessary,it just makes epoll fd handling easier
struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create
//this class is not strictly necessary,it just makes epoll fd handling easier
{ {
fd_info_t & get_info(fd64_t fd64); fd_info_t& get_info(fd64_t fd64);
int exist_info(fd64_t); int exist_info(fd64_t);
int exist(fd64_t fd64); int exist(fd64_t fd64);
int to_fd(fd64_t); int to_fd(fd64_t);
void fd64_close(fd64_t fd64); void fd64_close(fd64_t fd64);
void reserve(int n); void reserve(int n);
u64_t create(int fd); u64_t create(int fd);
fd_manager_t(); fd_manager_t();
private:
u64_t counter; private:
unordered_map<int,fd64_t> fd_to_fd64_mp; u64_t counter;
unordered_map<fd64_t,int> fd64_to_fd_mp; unordered_map<int, fd64_t> fd_to_fd64_mp;
unordered_map<fd64_t,fd_info_t> fd_info_mp; unordered_map<fd64_t, int> fd64_to_fd_mp;
int fd_exist(int fd); unordered_map<fd64_t, fd_info_t> fd_info_mp;
//void remove_fd(int fd); int fd_exist(int fd);
//fd64_t fd_to_fd64(int fd); // void remove_fd(int fd);
// fd64_t fd_to_fd64(int fd);
}; };
extern fd_manager_t fd_manager; extern fd_manager_t fd_manager;

File diff suppressed because it is too large Load Diff

View File

@@ -12,476 +12,426 @@
#include "log.h" #include "log.h"
#include "lib/rs.h" #include "lib/rs.h"
const int max_blob_packet_num=30000;//how many packet can be contain in a blob_t ,can be set very large const int max_blob_packet_num = 30000; // how many packet can be contain in a blob_t ,can be set very large
const u32_t anti_replay_buff_size=30000;//can be set very large const u32_t anti_replay_buff_size = 30000; // can be set very large
const int max_fec_packet_num=255;// this is the limitation of the rs lib const int max_fec_packet_num = 255; // this is the limitation of the rs lib
extern u32_t fec_buff_num; extern u32_t fec_buff_num;
const int rs_str_len=max_fec_packet_num*10+100; const int rs_str_len = max_fec_packet_num * 10 + 100;
extern int header_overhead; extern int header_overhead;
extern int debug_fec_enc; extern int debug_fec_enc;
extern int debug_fec_dec; extern int debug_fec_dec;
struct fec_parameter_t struct fec_parameter_t {
{ int version = 0;
int version=0; int mtu = default_mtu;
int mtu=default_mtu; int queue_len = 200;
int queue_len=200; int timeout = 8 * 1000;
int timeout=8*1000; int mode = 0;
int mode=0;
int rs_cnt=0; int rs_cnt = 0;
struct rs_parameter_t //parameters for reed solomon struct rs_parameter_t // parameters for reed solomon
{ {
unsigned char x;//AKA fec_data_num (x should be same as <index of rs_par>+1 at the moment) unsigned char x; // AKA fec_data_num (x should be same as <index of rs_par>+1 at the moment)
unsigned char y;//fec_redundant_num unsigned char y; // fec_redundant_num
}rs_par[max_fec_packet_num+10]; } rs_par[max_fec_packet_num + 10];
int rs_from_str(char * s)//todo inefficient int rs_from_str(char *s) // todo inefficient
{ {
vector<string> str_vec=string_to_vec(s,","); vector<string> str_vec = string_to_vec(s, ",");
if(str_vec.size()<1) if (str_vec.size() < 1) {
{ mylog(log_warn, "failed to parse [%s]\n", s);
mylog(log_warn,"failed to parse [%s]\n",s); return -1;
return -1; }
} vector<rs_parameter_t> par_vec;
vector<rs_parameter_t> par_vec; for (int i = 0; i < (int)str_vec.size(); i++) {
for(int i=0;i<(int)str_vec.size();i++) rs_parameter_t tmp_par;
{ string &tmp_str = str_vec[i];
rs_parameter_t tmp_par; int x, y;
string &tmp_str=str_vec[i]; if (sscanf((char *)tmp_str.c_str(), "%d:%d", &x, &y) != 2) {
int x,y; mylog(log_warn, "failed to parse [%s]\n", tmp_str.c_str());
if(sscanf((char *)tmp_str.c_str(),"%d:%d",&x,&y)!=2) return -1;
{ }
mylog(log_warn,"failed to parse [%s]\n",tmp_str.c_str()); if (x < 1 || y < 0 || x + y > max_fec_packet_num) {
return -1; 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;
if(x<1||y<0||x+y>max_fec_packet_num) }
{ tmp_par.x = x;
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); tmp_par.y = y;
return -1; par_vec.push_back(tmp_par);
} }
tmp_par.x=x; assert(par_vec.size() == str_vec.size());
tmp_par.y=y;
par_vec.push_back(tmp_par);
}
assert(par_vec.size()==str_vec.size());
int found_problem=0; int found_problem = 0;
for(int i=1;i<(int)par_vec.size();i++) for (int i = 1; i < (int)par_vec.size(); i++) {
{ if (par_vec[i].x <= par_vec[i - 1].x) {
if(par_vec[i].x<=par_vec[i-1].x) mylog(log_warn, "error in [%s], x in x:y should be in ascend order\n", s);
{ return -1;
mylog(log_warn,"error in [%s], x in x:y should be in ascend order\n",s); }
return -1; int now_x = par_vec[i].x;
} int now_y = par_vec[i].y;
int now_x=par_vec[i].x; int pre_x = par_vec[i - 1].x;
int now_y=par_vec[i].y; int pre_y = par_vec[i - 1].y;
int pre_x=par_vec[i-1].x;
int pre_y=par_vec[i-1].y;
double now_ratio=double(par_vec[i].y)/par_vec[i].x; double now_ratio = double(par_vec[i].y) / par_vec[i].x;
double pre_ratio=double(par_vec[i-1].y)/par_vec[i-1].x; double pre_ratio = double(par_vec[i - 1].y) / par_vec[i - 1].x;
if(pre_ratio+0.0001<now_ratio) if (pre_ratio + 0.0001 < now_ratio) {
{ if (found_problem == 0) {
if(found_problem==0) mylog(log_warn, "possible problems: %d/%d<%d/%d", pre_y, pre_x, now_y, now_x);
{ found_problem = 1;
mylog(log_warn,"possible problems: %d/%d<%d/%d",pre_y,pre_x,now_y,now_x); } else {
found_problem=1; log_bare(log_warn, ", %d/%d<%d/%d", pre_y, pre_x, now_y, now_x);
} }
else }
{ }
log_bare(log_warn,", %d/%d<%d/%d",pre_y,pre_x,now_y,now_x); if (found_problem) {
} log_bare(log_warn, " in %s\n", s);
} }
}
if(found_problem)
{
log_bare(log_warn," in %s\n",s);
}
{ //special treatment for first parameter { // special treatment for first parameter
int x=par_vec[0].x; int x = par_vec[0].x;
int y=par_vec[0].y; int y = par_vec[0].y;
for(int i=1;i<=x;i++) for (int i = 1; i <= x; i++) {
{ rs_par[i - 1].x = i;
rs_par[i-1].x=i; rs_par[i - 1].y = y;
rs_par[i-1].y=y; }
} }
}
for(int i=1;i<(int)par_vec.size();i++) for (int i = 1; i < (int)par_vec.size(); i++) {
{ int now_x = par_vec[i].x;
int now_x=par_vec[i].x; int now_y = par_vec[i].y;
int now_y=par_vec[i].y; int pre_x = par_vec[i - 1].x;
int pre_x=par_vec[i-1].x; int pre_y = par_vec[i - 1].y;
int pre_y=par_vec[i-1].y; rs_par[now_x - 1].x = now_x;
rs_par[now_x-1].x=now_x; rs_par[now_x - 1].y = now_y;
rs_par[now_x-1].y=now_y;
double now_ratio=double(par_vec[i].y)/par_vec[i].x; double now_ratio = double(par_vec[i].y) / par_vec[i].x;
double pre_ratio=double(par_vec[i-1].y)/par_vec[i-1].x; double pre_ratio = double(par_vec[i - 1].y) / par_vec[i - 1].x;
//double k= double(now_y-pre_y)/double(now_x-pre_x); // double k= double(now_y-pre_y)/double(now_x-pre_x);
for(int j=pre_x+1;j<=now_x-1;j++) for (int j = pre_x + 1; j <= now_x - 1; j++) {
{ int in_x = j;
int in_x=j;
//////// int in_y= double(pre_y) + double(in_x-pre_x)*k+ 0.9999;// round to upper //////// int in_y= double(pre_y) + double(in_x-pre_x)*k+ 0.9999;// round to upper
double distance=now_x-pre_x; double distance = now_x - pre_x;
/////// double in_ratio=pre_ratio*(1.0-(in_x-pre_x)/distance) + now_ratio *(1.0- (now_x-in_x)/distance); /////// double in_ratio=pre_ratio*(1.0-(in_x-pre_x)/distance) + now_ratio *(1.0- (now_x-in_x)/distance);
////// int in_y= in_x*in_ratio + 0.9999; ////// int in_y= in_x*in_ratio + 0.9999;
int in_y= pre_y +(now_y-pre_y) *(in_x-pre_x)/distance +0.9999; int in_y = pre_y + (now_y - pre_y) * (in_x - pre_x) / distance + 0.9999;
if(in_x+in_y>max_fec_packet_num) if (in_x + in_y > max_fec_packet_num) {
{ in_y = max_fec_packet_num - in_x;
in_y=max_fec_packet_num-in_x; assert(in_y >= 0 && in_y <= max_fec_packet_num);
assert(in_y>=0&&in_y<=max_fec_packet_num); }
}
rs_par[in_x-1].x=in_x; rs_par[in_x - 1].x = in_x;
rs_par[in_x-1].y=in_y; rs_par[in_x - 1].y = in_y;
} }
} }
rs_cnt=par_vec[par_vec.size()-1].x; rs_cnt = par_vec[par_vec.size() - 1].x;
return 0; return 0;
} }
char *rs_to_str()//todo inefficient char *rs_to_str() // todo inefficient
{ {
static char res[rs_str_len]; static char res[rs_str_len];
string tmp_string; string tmp_string;
char tmp_buf[100]; char tmp_buf[100];
assert(rs_cnt>=1); assert(rs_cnt >= 1);
for(int i=0;i<rs_cnt;i++) for (int i = 0; i < rs_cnt; i++) {
{ sprintf(tmp_buf, "%d:%d", int(rs_par[i].x), int(rs_par[i].y));
sprintf(tmp_buf,"%d:%d",int(rs_par[i].x),int(rs_par[i].y)); if (i != 0)
if(i!=0) tmp_string += ",";
tmp_string+=","; tmp_string += tmp_buf;
tmp_string+=tmp_buf; }
} strcpy(res, tmp_string.c_str());
strcpy(res,tmp_string.c_str()); return res;
return res; }
}
rs_parameter_t get_tail() rs_parameter_t get_tail() {
{ assert(rs_cnt >= 1);
assert(rs_cnt>=1); return rs_par[rs_cnt - 1];
return rs_par[rs_cnt-1]; }
}
int clone(fec_parameter_t &other) {
version = other.version;
mtu = other.mtu;
queue_len = other.queue_len;
timeout = other.timeout;
mode = other.mode;
int clone(fec_parameter_t & other) assert(other.rs_cnt >= 1);
{ rs_cnt = other.rs_cnt;
version=other.version; memcpy(rs_par, other.rs_par, sizeof(rs_parameter_t) * rs_cnt);
mtu=other.mtu;
queue_len=other.queue_len;
timeout=other.timeout;
mode=other.mode;
assert(other.rs_cnt>=1); return 0;
rs_cnt=other.rs_cnt; }
memcpy(rs_par,other.rs_par,sizeof(rs_parameter_t)*rs_cnt);
return 0;
}
int copy_fec(fec_parameter_t &other) {
assert(other.rs_cnt >= 1);
rs_cnt = other.rs_cnt;
memcpy(rs_par, other.rs_par, sizeof(rs_parameter_t) * rs_cnt);
return 0;
}
}; };
extern fec_parameter_t g_fec_par; extern fec_parameter_t g_fec_par;
//extern int dynamic_update_fec; // extern int dynamic_update_fec;
const int anti_replay_timeout=120*1000;// 120s const int anti_replay_timeout = 120 * 1000; // 120s
struct anti_replay_t struct anti_replay_t {
{ struct info_t {
my_time_t my_time;
int index;
};
struct info_t u64_t replay_buffer[anti_replay_buff_size];
{ unordered_map<u32_t, info_t> mp;
my_time_t my_time; int index;
int index; anti_replay_t() {
}; clear();
}
int clear() {
memset(replay_buffer, -1, sizeof(replay_buffer));
mp.clear();
mp.rehash(anti_replay_buff_size * 3);
index = 0;
return 0;
}
void set_invaild(u32_t seq) {
if (is_vaild(seq) == 0) {
mylog(log_trace, "seq %u exist\n", seq);
// assert(mp.find(seq)!=mp.end());
// mp[seq].my_time=get_current_time_rough();
return;
}
if (replay_buffer[index] != u64_t(i64_t(-1))) {
assert(mp.find(replay_buffer[index]) != mp.end());
mp.erase(replay_buffer[index]);
}
replay_buffer[index] = seq;
assert(mp.find(seq) == mp.end());
mp[seq].my_time = get_current_time();
mp[seq].index = index;
index++;
if (index == int(anti_replay_buff_size)) index = 0;
}
int is_vaild(u32_t seq) {
if (mp.find(seq) == mp.end()) return 1;
u64_t replay_buffer[anti_replay_buff_size]; if (get_current_time() - mp[seq].my_time > anti_replay_timeout) {
unordered_map<u32_t,info_t> mp; replay_buffer[mp[seq].index] = u64_t(i64_t(-1));
int index; mp.erase(seq);
anti_replay_t() return 1;
{ }
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) return 0;
{ }
mylog(log_trace,"seq %u exist\n",seq);
//assert(mp.find(seq)!=mp.end());
//mp[seq].my_time=get_current_time_rough();
return;
}
if(replay_buffer[index]!=u64_t(i64_t(-1)))
{
assert(mp.find(replay_buffer[index])!=mp.end());
mp.erase(replay_buffer[index]);
}
replay_buffer[index]=seq;
assert(mp.find(seq)==mp.end());
mp[seq].my_time=get_current_time();
mp[seq].index=index;
index++;
if(index==int(anti_replay_buff_size)) index=0;
}
int is_vaild(u32_t seq)
{
if(mp.find(seq)==mp.end()) return 1;
if(get_current_time()-mp[seq].my_time>anti_replay_timeout)
{
replay_buffer[mp[seq].index]=u64_t(i64_t(-1));
mp.erase(seq);
return 1;
}
return 0;
}
}; };
struct blob_encode_t struct blob_encode_t {
{ char input_buf[(max_fec_packet_num + 5) * buf_len];
char input_buf[(max_fec_packet_num+5)*buf_len]; int current_len;
int current_len; int counter;
int counter;
char *output_buf[max_fec_packet_num+100]; char *output_buf[max_fec_packet_num + 100];
blob_encode_t(); blob_encode_t();
int clear(); int clear();
int get_num(); int get_num();
int get_shard_len(int n); int get_shard_len(int n);
int get_shard_len(int n,int next_packet_len); int get_shard_len(int n, int next_packet_len);
int input(char *s,int len); //len=use len=0 for second and following packet int input(char *s, int len); // len=use len=0 for second and following packet
int output(int n,char ** &s_arr,int & len); int output(int n, char **&s_arr, int &len);
}; };
struct blob_decode_t struct blob_decode_t {
{ char input_buf[(max_fec_packet_num + 5) * buf_len];
char input_buf[(max_fec_packet_num+5)*buf_len]; int current_len;
int current_len; int last_len;
int last_len; int counter;
int counter;
char *output_buf[max_blob_packet_num+100]; char *output_buf[max_blob_packet_num + 100];
int output_len[max_blob_packet_num+100]; int output_len[max_blob_packet_num + 100];
blob_decode_t(); blob_decode_t();
int clear(); int clear();
int input(char *input,int len); int input(char *input, int len);
int output(int &n,char ** &output,int *&len_arr); int output(int &n, char **&output, int *&len_arr);
}; };
class fec_encode_manager_t:not_copy_able_t class fec_encode_manager_t : not_copy_able_t {
{ private:
u32_t seq;
private: // int fec_mode;
u32_t seq; // int fec_data_num,fec_redundant_num;
// int fec_mtu;
// int fec_queue_len;
// int fec_timeout;
fec_parameter_t fec_par;
//int fec_mode; my_time_t first_packet_time;
//int fec_data_num,fec_redundant_num; my_time_t first_packet_time_for_output;
//int fec_mtu;
//int fec_queue_len;
//int fec_timeout;
fec_parameter_t fec_par;
blob_encode_t blob_encode;
char input_buf[max_fec_packet_num + 5][buf_len];
int input_len[max_fec_packet_num + 100];
my_time_t first_packet_time; char *output_buf[max_fec_packet_num + 100];
my_time_t first_packet_time_for_output; int output_len[max_fec_packet_num + 100];
int counter;
// int timer_fd;
// u64_t timer_fd64;
blob_encode_t blob_encode; int ready_for_output;
char input_buf[max_fec_packet_num+5][buf_len]; u32_t output_n;
int input_len[max_fec_packet_num+100];
char *output_buf[max_fec_packet_num+100]; int append(char *s, int len);
int output_len[max_fec_packet_num+100];
int counter; ev_timer timer;
//int timer_fd; struct ev_loop *loop = 0;
//u64_t timer_fd64; void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0;
int ready_for_output; public:
u32_t output_n; fec_encode_manager_t();
~fec_encode_manager_t();
int append(char *s,int len); fec_parameter_t &get_fec_par() {
return fec_par;
}
void set_data(void *data) {
timer.data = data;
}
ev_timer timer; void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) {
struct ev_loop *loop=0; this->loop = loop;
void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)=0; this->cb = cb;
ev_init(&timer, cb);
}
public: int clear_data() {
fec_encode_manager_t(); counter = 0;
~fec_encode_manager_t(); blob_encode.clear();
ready_for_output = 0;
fec_parameter_t & get_fec_par() seq = (u32_t)get_fake_random_number(); // TODO temp solution for a bug.
{
return fec_par;
}
void set_data(void * data)
{
timer.data=data;
}
if (loop) {
ev_timer_stop(loop, &timer);
}
return 0;
}
int clear_all() {
// itimerspec zero_its;
// memset(&zero_its, 0, sizeof(zero_its));
// timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0);
void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)) if (loop) {
{ ev_timer_stop(loop, &timer);
this->loop=loop; loop = 0;
this->cb=cb; cb = 0;
ev_init(&timer,cb); }
}
int clear_data() clear_data();
{
counter=0;
blob_encode.clear();
ready_for_output=0;
seq=(u32_t)get_fake_random_number(); //TODO temp solution for a bug. return 0;
}
if(loop) my_time_t get_first_packet_time() {
{ return first_packet_time_for_output;
ev_timer_stop(loop,&timer); }
}
return 0;
}
int clear_all()
{
//itimerspec zero_its; int get_pending_time() {
//memset(&zero_its, 0, sizeof(zero_its)); return fec_par.timeout;
//timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0); }
if(loop) int get_type() {
{ return fec_par.mode;
ev_timer_stop(loop,&timer); }
loop=0; // u64_t get_timer_fd64();
cb=0; int reset_fec_parameter(int data_num, int redundant_num, int mtu, int pending_num, int pending_time, int type);
} int input(char *s, int len /*,int &is_first_packet*/);
int output(int &n, char **&s_arr, int *&len);
clear_data();
return 0;
}
my_time_t get_first_packet_time()
{
return first_packet_time_for_output;
}
int get_pending_time()
{
return fec_par.timeout;
}
int get_type()
{
return fec_par.mode;
}
//u64_t get_timer_fd64();
int reset_fec_parameter(int data_num,int redundant_num,int mtu,int pending_num,int pending_time,int type);
int input(char *s,int len/*,int &is_first_packet*/);
int output(int &n,char ** &s_arr,int *&len);
}; };
struct fec_data_t struct fec_data_t {
{ int used;
int used; u32_t seq;
u32_t seq; int type;
int type; int data_num;
int data_num; int redundant_num;
int redundant_num; int idx;
int idx; char buf[buf_len];
char buf[buf_len]; int len;
int len;
}; };
struct fec_group_t struct fec_group_t {
{ int type = -1;
int type=-1; int data_num = -1;
int data_num=-1; int redundant_num = -1;
int redundant_num=-1; int len = -1;
int len=-1; int fec_done = 0;
int fec_done=0; // int data_counter=0;
//int data_counter=0; map<int, int> group_mp;
map<int,int> group_mp;
}; };
class fec_decode_manager_t:not_copy_able_t class fec_decode_manager_t : not_copy_able_t {
{ anti_replay_t anti_replay;
anti_replay_t anti_replay; fec_data_t *fec_data = 0;
fec_data_t *fec_data=0; unordered_map<u32_t, fec_group_t> mp;
unordered_map<u32_t, fec_group_t> mp; blob_decode_t blob_decode;
blob_decode_t blob_decode;
int index; int index;
int output_n; int output_n;
char ** output_s_arr; char **output_s_arr;
int * output_len_arr; int *output_len_arr;
int ready_for_output; int ready_for_output;
char *output_s_arr_buf[max_fec_packet_num+100];//only for type=1,for type=0 the buf inside blot_t is used char *output_s_arr_buf[max_fec_packet_num + 100]; // only for type=1,for type=0 the buf inside blot_t is used
int output_len_arr_buf[max_fec_packet_num+100];//same int output_len_arr_buf[max_fec_packet_num + 100]; // same
public: public:
fec_decode_manager_t() fec_decode_manager_t() {
{ fec_data = new fec_data_t[fec_buff_num + 5];
fec_data=new fec_data_t[fec_buff_num+5]; assert(fec_data != 0);
assert(fec_data!=0); clear();
clear(); }
} /*
/* fec_decode_manager_t(const fec_decode_manager_t &b)
fec_decode_manager_t(const fec_decode_manager_t &b) {
{ assert(0==1);//not allowed to copy
assert(0==1);//not allowed to copy }*/
}*/ ~fec_decode_manager_t() {
~fec_decode_manager_t() mylog(log_debug, "fec_decode_manager destroyed\n");
{ if (fec_data != 0) {
mylog(log_debug,"fec_decode_manager destroyed\n"); mylog(log_debug, "fec_data freed\n");
if(fec_data!=0) delete[] fec_data;
{ }
mylog(log_debug,"fec_data freed\n"); }
delete fec_data; int clear() {
} anti_replay.clear();
} mp.clear();
int clear() mp.rehash(fec_buff_num * 3);
{
anti_replay.clear();
mp.clear();
mp.rehash(fec_buff_num*3);
for(int i=0;i<(int)fec_buff_num;i++) for (int i = 0; i < (int)fec_buff_num; i++)
fec_data[i].used=0; fec_data[i].used = 0;
ready_for_output=0; ready_for_output = 0;
index=0; index = 0;
return 0; return 0;
} }
//int re_init(); // int re_init();
int input(char *s,int len); int input(char *s, int len);
int output(int &n,char ** &s_arr,int* &len_arr); int output(int &n, char **&s_arr, int *&len_arr);
}; };
#endif /* FEC_MANAGER_H_ */ #endif /* FEC_MANAGER_H_ */

View File

@@ -8,69 +8,57 @@
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
void rs_encode(void *code,char *data[],int size) void rs_encode(void *code, char *data[], int size) {
{ int k = get_k(code);
int k=get_k(code); int n = get_n(code);
int n=get_n(code); for (int i = k; i < n; i++) {
for(int i=k;i<n;i++) fec_encode(code, (void **)data, data[i], i, size);
{ }
fec_encode(code, (void **)data, data[i],i, size);
}
return ; return;
} }
int rs_decode(void *code,char *data[],int size) int rs_decode(void *code, char *data[], int size) {
{ int k = get_k(code);
int k=get_k(code); int n = get_n(code);
int n=get_n(code); int index[n];
int index[n]; int count = 0;
int count=0; for (int i = 0; i < n; i++) {
for(int i=0;i<n;i++) if (data[i] != 0) {
{ index[count++] = i;
if(data[i]!=0) }
{ }
index[count++]=i; if (count < k)
} return -1;
} for (int i = 0; i < n; i++) {
if(count<k) if (i < count)
return -1; data[i] = data[index[i]];
for(int i=0;i<n;i++) else
{ data[i] = 0;
if(i<count) }
data[i]=data[index[i]]; return fec_decode(code, (void **)data, index, size);
else
data[i]=0;
}
return fec_decode(code,(void**)data,index,size);
} }
static void * (*table)[256]=0; static void *(*table)[256] = 0;
void* get_code(int k,int n) void *get_code(int k, int n) {
{ if (table == 0) {
if (table==0) table = (void *(*)[256])malloc(sizeof(void *) * 256 * 256);
{ if (!table) {
table=(void* (*)[256]) malloc(sizeof(void*)*256*256); return table;
if(!table) }
{ memset(table, 0, sizeof(void *) * 256 * 256);
return table; }
} if (table[k][n] == 0) {
memset(table,0,sizeof(void*)*256*256); table[k][n] = fec_new(k, n);
} }
if(table[k][n]==0) return table[k][n];
{
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);
void* code=get_code(k,n); rs_encode(code, data, size);
rs_encode(code,data,size);
} }
int rs_decode2(int k,int n,char *data[],int size) int rs_decode2(int k, int n, char *data[], int size) {
{ void *code = get_code(k, n);
void* code=get_code(k,n); return rs_decode(code, data, size);
return rs_decode(code,data,size);
} }

View File

@@ -20,8 +20,7 @@
// //
// info: // info:
// the function will always succeed,except malloc fail.if malloc fail,it will call exit() // the function will always succeed,except malloc fail.if malloc fail,it will call exit()
void rs_encode(void *code,char *data[],int size); void rs_encode(void *code, char *data[], int size);
// input: // input:
// data[0.....n-1] points to original data and redundate data,in right order // data[0.....n-1] points to original data and redundate data,in right order
@@ -37,15 +36,10 @@ void rs_encode(void *code,char *data[],int size);
// advanced info: // advanced info:
// 1. rs_decode wont malloc memory for those zero pointers in data[0.....k-1]. instead it will re-use the memory of other non-zero pointers (and let data[0.....k-1] point to those memory). // 1. rs_decode wont malloc memory for those zero pointers in data[0.....k-1]. instead it will re-use the memory of other non-zero pointers (and let data[0.....k-1] point to those memory).
// 2. if the input data[0.....n-1] contains x non-zero pointers,after called rs_decode,there will still be exactly x non-zero poninters in data[0.....n-1],just the order may change. // 2. if the input data[0.....n-1] contains x non-zero pointers,after called rs_decode,there will still be exactly x non-zero poninters in data[0.....n-1],just the order may change.
int rs_decode(void *code,char *data[],int size); int rs_decode(void *code, char *data[], int size);
void rs_encode2(int k,int n,char *data[],int size);
int rs_decode2(int k,int n,char *data[],int size);
void rs_encode2(int k, int n, char *data[], int size);
int rs_decode2(int k, int n, char *data[], int size);
#endif /* LIB_RS_H_ */ #endif /* LIB_RS_H_ */

88
log.cpp Executable file → Normal file
View File

@@ -1,63 +1,57 @@
#include <common.h> #include <common.h>
#include <log.h> #include <log.h>
int log_level=log_info; int log_level = log_info;
int enable_log_position=0; int enable_log_position = 0;
int enable_log_color=1; int enable_log_color = 1;
void log0(const char* file, const char* function, int line, int level, const char* str, ...) {
if (level > log_level) return;
if (level > log_trace || level < 0) return;
void log0(const char * file,const char * function,int line,int level,const char* str, ...) { time_t timer;
char buffer[100];
struct tm* tm_info;
if(level>log_level) return ; time(&timer);
if(level>log_trace||level<0) return ; tm_info = localtime(&timer);
if (enable_log_color)
printf("%s", log_color[level]);
time_t timer; strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", tm_info);
char buffer[100]; printf("[%s][%s]", buffer, log_text[level]);
struct tm* tm_info;
time(&timer); if (enable_log_position) printf("[%s,func:%s,line:%d]", file, function, line);
tm_info = localtime(&timer);
if(enable_log_color) va_list vlist;
printf("%s",log_color[level]); va_start(vlist, str);
vfprintf(stdout, str, vlist);
va_end(vlist);
if (enable_log_color)
printf("%s", RESET);
strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", tm_info); // printf("\n");
printf("[%s][%s]",buffer,log_text[level]); // if(enable_log_color)
// printf(log_color[level]);
fflush(stdout);
if(enable_log_position)printf("[%s,func:%s,line:%d]",file,function,line); if (log_level == log_fatal) {
about_to_exit = 1;
va_list vlist; }
va_start(vlist, str);
vfprintf(stdout, str, vlist);
va_end(vlist);
if(enable_log_color)
printf("%s",RESET);
//printf("\n");
//if(enable_log_color)
//printf(log_color[level]);
fflush(stdout);
if(log_level==log_fatal)
{
about_to_exit=1;
}
} }
void log_bare(int level,const char* str, ...) void log_bare(int level, const char* str, ...) {
{ if (level > log_level) return;
if(level>log_level) return ; if (level > log_trace || level < 0) return;
if(level>log_trace||level<0) return ; if (enable_log_color)
if(enable_log_color) printf("%s", log_color[level]);
printf("%s",log_color[level]); va_list vlist;
va_list vlist; va_start(vlist, str);
va_start(vlist, str); vfprintf(stdout, str, vlist);
vfprintf(stdout, str, vlist); va_end(vlist);
va_end(vlist); if (enable_log_color)
if(enable_log_color) printf("%s", RESET);
printf("%s",RESET); fflush(stdout);
fflush(stdout);
} }

58
log.h Executable file → Normal file
View File

@@ -2,60 +2,54 @@
#ifndef _LOG_MYLOG_H_ #ifndef _LOG_MYLOG_H_
#define _LOG_MYLOG_H_ #define _LOG_MYLOG_H_
#include <stdio.h>
#include<stdio.h> #include <string.h>
#include<string.h> #include <stdlib.h>
#include<stdlib.h> #include <getopt.h>
#include<getopt.h>
#include <unistd.h> #include <unistd.h>
#include<errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include <set> #include <set>
using namespace std; using namespace std;
#define RED "\x1B[31m"
#define RED "\x1B[31m" #define GRN "\x1B[32m"
#define GRN "\x1B[32m" #define YEL "\x1B[33m"
#define YEL "\x1B[33m" #define BLU "\x1B[34m"
#define BLU "\x1B[34m" #define MAG "\x1B[35m"
#define MAG "\x1B[35m" #define CYN "\x1B[36m"
#define CYN "\x1B[36m" #define WHT "\x1B[37m"
#define WHT "\x1B[37m"
#define RESET "\x1B[0m" #define RESET "\x1B[0m"
const int log_never = 0;
const int log_fatal = 1;
const int log_error = 2;
const int log_warn = 3;
const int log_info = 4;
const int log_debug = 5;
const int log_trace = 6;
const int log_end = 7;
const int log_never=0; const char log_text[][20] = {"NEVER", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", ""};
const int log_fatal=1; const char log_color[][20] = {RED, RED, RED, YEL, GRN, MAG, ""};
const int log_error=2;
const int log_warn=3;
const int log_info=4;
const int log_debug=5;
const int log_trace=6;
const int log_end=7;
const char log_text[][20]={"NEVER","FATAL","ERROR","WARN","INFO","DEBUG","TRACE",""};
const char log_color[][20]={RED,RED,RED,YEL,GRN,MAG,""};
extern int log_level; extern int log_level;
extern int enable_log_position; extern int enable_log_position;
extern int enable_log_color; extern int enable_log_color;
#ifdef MY_DEBUG #ifdef MY_DEBUG
#define mylog(__first_argu__dummy_abcde__,...) printf(__VA_ARGS__) #define mylog(__first_argu__dummy_abcde__, ...) printf(__VA_ARGS__)
#else #else
#define mylog(...) log0(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__) #define mylog(...) log0(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#endif #endif
//#define mylog(__first_argu__dummy_abcde__,...) {;} //#define mylog(__first_argu__dummy_abcde__,...) {;}
void log0(const char * file,const char * function,int line,int level,const char* str, ...); void log0(const char* file, const char* function, int line, int level, const char* str, ...);
void log_bare(int level,const char* str, ...);
void log_bare(int level, const char* str, ...);
#endif #endif

209
main.cpp
View File

@@ -13,106 +13,97 @@
#include "git_version.h" #include "git_version.h"
using namespace std; using namespace std;
static void print_help() {
char git_version_buf[100] = {0};
strncpy(git_version_buf, gitversion, 10);
static void print_help() printf("UDPspeeder V2\n");
{ printf("git version: %s ", git_version_buf);
char git_version_buf[100]={0}; printf("build date: %s %s\n", __DATE__, __TIME__);
strncpy(git_version_buf,gitversion,10); printf("repository: https://github.com/wangyu-/UDPspeeder\n");
printf("\n");
printf("usage:\n");
printf(" run as client: ./this_program -c -l local_listen_ip:local_port -r server_ip:server_port [options]\n");
printf(" run as server: ./this_program -s -l server_listen_ip:server_port -r remote_ip:remote_port [options]\n");
printf("\n");
printf("common options, must be same on both sides:\n");
printf(" -k,--key <string> key for simple xor encryption. if not set, xor is disabled\n");
printf("UDPspeeder V2\n"); printf("main options:\n");
printf("git version: %s ",git_version_buf); printf(" -f,--fec x:y forward error correction, send y redundant packets for every x packets\n");
printf("build date: %s %s\n",__DATE__,__TIME__); printf(" --timeout <number> how long could a packet be held in queue before doing fec, unit: ms, default: 8ms\n");
printf("repository: https://github.com/wangyu-/UDPspeeder\n"); printf(" --report <number> turn on send/recv report, and set a period for reporting, unit: s\n");
printf("\n");
printf("usage:\n");
printf(" run as client: ./this_program -c -l local_listen_ip:local_port -r server_ip:server_port [options]\n");
printf(" run as server: ./this_program -s -l server_listen_ip:server_port -r remote_ip:remote_port [options]\n");
printf("\n");
printf("common options, must be same on both sides:\n");
printf(" -k,--key <string> key for simple xor encryption. if not set, xor is disabled\n");
printf("main options:\n"); printf("advanced options:\n");
printf(" -f,--fec x:y forward error correction, send y redundant packets for every x packets\n"); printf(" --mode <number> fec-mode,available values: 0,1; mode 0(default) costs less bandwidth,no mtu problem.\n");
printf(" --timeout <number> how long could a packet be held in queue before doing fec, unit: ms, default: 8ms\n"); printf(" mode 1 usually introduces less latency, but you have to care about mtu.\n");
printf(" --report <number> turn on send/recv report, and set a period for reporting, unit: s\n"); printf(" --mtu <number> mtu. for mode 0, the program will split packet to segment smaller than mtu value.\n");
printf(" for mode 1, no packet will be split, the program just check if the mtu is exceed.\n");
printf(" default value: 1250. you typically shouldnt change this value.\n");
printf(" -j,--jitter <number> simulated jitter. randomly delay first packet for 0~<number> ms, default value: 0.\n");
printf(" do not use if you dont know what it means.\n");
printf(" -i,--interval <number> scatter each fec group to a interval of <number> ms, to defend burst packet loss.\n");
printf(" default value: 0. do not use if you dont know what it means.\n");
printf(" -f,--fec x1:y1,x2:y2,.. similiar to -f/--fec above,fine-grained fec parameters,may help save bandwidth.\n");
printf(" example: \"-f 1:3,2:4,10:6,20:10\". check repo for details\n");
printf(" --random-drop <number> simulate packet loss, unit: 0.01%%. default value: 0.\n");
printf(" --disable-obscure <number> disable obscure, to save a bit bandwidth and cpu\n");
printf(" --disable-checksum <number> disable checksum to save a bit bandwdith and cpu\n");
// printf(" --disable-xor <number> disable xor\n");
printf("advanced options:\n"); printf("developer options:\n");
printf(" --mode <number> fec-mode,available values: 0,1; mode 0(default) costs less bandwidth,no mtu problem.\n"); printf(" --fifo <string> use a fifo(named pipe) for sending commands to the running program, so that you\n");
printf(" mode 1 usually introduces less latency, but you have to care about mtu.\n"); printf(" can change fec encode parameters dynamically, check readme.md in repository for\n");
printf(" --mtu <number> mtu. for mode 0, the program will split packet to segment smaller than mtu value.\n"); printf(" supported commands.\n");
printf(" for mode 1, no packet will be split, the program just check if the mtu is exceed.\n"); printf(" -j ,--jitter jmin:jmax similiar to -j above, but create jitter randomly between jmin and jmax\n");
printf(" default value: 1250. you typically shouldnt change this value.\n"); printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n");
printf(" -j,--jitter <number> simulated jitter. randomly delay first packet for 0~<number> ms, default value: 0.\n");
printf(" do not use if you dont know what it means.\n");
printf(" -i,--interval <number> scatter each fec group to a interval of <number> ms, to defend burst packet loss.\n");
printf(" default value: 0. do not use if you dont know what it means.\n");
printf(" -f,--fec x1:y1,x2:y2,.. similiar to -f/--fec above,fine-grained fec parameters,may help save bandwidth.\n");
printf(" example: \"-f 1:3,2:4,10:6,20:10\". check repo for details\n");
printf(" --random-drop <number> simulate packet loss, unit: 0.01%%. default value: 0.\n");
printf(" --disable-obscure <number> disable obscure, to save a bit bandwidth and cpu\n");
printf(" --disable-checksum <number> disable checksum to save a bit bandwdith and cpu\n");
//printf(" --disable-xor <number> disable xor\n");
printf("developer options:\n");
printf(" --fifo <string> use a fifo(named pipe) for sending commands to the running program, so that you\n");
printf(" can change fec encode parameters dynamically, check readme.md in repository for\n");
printf(" supported commands.\n");
printf(" -j ,--jitter jmin:jmax similiar to -j above, but create jitter randomly between jmin and jmax\n");
printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n");
printf(" -q,--queue-len <number> fec queue len, only for mode 0, fec will be performed immediately after queue is full.\n"); printf(" -q,--queue-len <number> fec queue len, only for mode 0, fec will be performed immediately after queue is full.\n");
printf(" default value: 200. \n"); printf(" default value: 200. \n");
printf(" --decode-buf <number> size of buffer of fec decoder,unit: packet, default: 2000\n"); printf(" --decode-buf <number> size of buffer of fec decoder,unit: packet, default: 2000\n");
// printf(" --fix-latency <number> try to stabilize latency, only for mode 0\n"); // printf(" --fix-latency <number> try to stabilize latency, only for mode 0\n");
printf(" --delay-capacity <number> max number of delayed packets, 0 means unlimited, default: 0\n"); printf(" --delay-capacity <number> max number of delayed packets, 0 means unlimited, default: 0\n");
printf(" --disable-fec <number> completely disable fec, turn the program into a normal udp tunnel\n"); printf(" --disable-fec <number> completely disable fec, turn the program into a normal udp tunnel\n");
printf(" --sock-buf <number> buf size for socket, >=10 and <=10240, unit: kbyte, default: 1024\n"); printf(" --sock-buf <number> buf size for socket, >=10 and <=10240, unit: kbyte, default: 1024\n");
printf(" --out-addr ip:port force all output packets of '-r' end to go through this address, port 0 for random port.\n"); printf(" --out-addr ip:port force all output packets of '-r' end to go through this address, port 0 for random port.\n");
#ifdef __linux__ #ifdef __linux__
printf(" --out-interface <string> force all output packets of '-r' end to go through this interface.\n"); printf(" --out-interface <string> force all output packets of '-r' end to go through this interface.\n");
#endif #endif
printf("log and help options:\n"); printf("log and help options:\n");
printf(" --log-level <number> 0: never 1: fatal 2: error 3: warn \n"); printf(" --log-level <number> 0: never 1: fatal 2: error 3: warn \n");
printf(" 4: info (default) 5: debug 6: trace\n"); printf(" 4: info (default) 5: debug 6: trace\n");
printf(" --log-position enable file name, function name, line number in log\n"); printf(" --log-position enable file name, function name, line number in log\n");
printf(" --disable-color disable log color\n"); printf(" --disable-color disable log color\n");
printf(" -h,--help print this help message\n"); printf(" -h,--help print this help message\n");
//printf("common options,these options must be same on both side\n"); // printf("common options,these options must be same on both side\n");
} }
void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) {
void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) mylog(log_info, "got sigpipe, ignored");
{
mylog(log_info, "got sigpipe, ignored");
} }
void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) {
{ mylog(log_info, "got sigterm, exit");
mylog(log_info, "got sigterm, exit"); myexit(0);
myexit(0);
} }
void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) {
{ mylog(log_info, "got sigint, exit");
mylog(log_info, "got sigint, exit"); myexit(0);
myexit(0);
} }
int main(int argc, char *argv[]) {
working_mode = tunnel_mode;
init_ws();
// unit_test();
struct ev_loop *loop = ev_default_loop(0);
int main(int argc, char *argv[])
{
working_mode=tunnel_mode;
init_ws();
//unit_test();
struct ev_loop* loop=ev_default_loop(0);
#if !defined(__MINGW32__) #if !defined(__MINGW32__)
ev_signal signal_watcher_sigpipe; ev_signal signal_watcher_sigpipe;
ev_signal_init(&signal_watcher_sigpipe, sigpipe_cb, SIGPIPE); ev_signal_init(&signal_watcher_sigpipe, sigpipe_cb, SIGPIPE);
ev_signal_start(loop, &signal_watcher_sigpipe); ev_signal_start(loop, &signal_watcher_sigpipe);
#else #else
enable_log_color=0; enable_log_color = 0;
#endif #endif
ev_signal signal_watcher_sigterm; ev_signal signal_watcher_sigterm;
@@ -123,47 +114,39 @@ int main(int argc, char *argv[])
ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT); ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT);
ev_signal_start(loop, &signal_watcher_sigint); ev_signal_start(loop, &signal_watcher_sigint);
assert(sizeof(u64_t)==8); assert(sizeof(u64_t) == 8);
assert(sizeof(i64_t)==8); assert(sizeof(i64_t) == 8);
assert(sizeof(u32_t)==4); assert(sizeof(u32_t) == 4);
assert(sizeof(i32_t)==4); assert(sizeof(i32_t) == 4);
assert(sizeof(u16_t)==2); assert(sizeof(u16_t) == 2);
assert(sizeof(i16_t)==2); assert(sizeof(i16_t) == 2);
dup2(1, 2); //redirect stderr to stdout dup2(1, 2); // redirect stderr to stdout
int i, j, k; int i, j, k;
if (argc == 1) if (argc == 1) {
{ print_help();
print_help(); myexit(-1);
myexit( -1); }
} for (i = 0; i < argc; i++) {
for (i = 0; i < argc; i++) if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
{ print_help();
if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0) myexit(0);
{ }
print_help(); }
myexit(0);
}
}
process_arg(argc,argv); process_arg(argc, argv);
delay_manager.set_capacity(delay_capacity); delay_manager.set_capacity(delay_capacity);
if(strlen(tun_dev)==0) if (strlen(tun_dev) == 0) {
{ sprintf(tun_dev, "tun%u", get_fake_random_number() % 1000);
sprintf(tun_dev,"tun%u",get_fake_random_number()%1000); }
}
if(program_mode==client_mode) if (program_mode == client_mode) {
{ tunnel_client_event_loop();
tunnel_client_event_loop(); } else {
} tunnel_server_event_loop();
else }
{
tunnel_server_event_loop();
}
return 0; return 0;
} }

View File

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

1737
misc.cpp

File diff suppressed because it is too large Load Diff

21
misc.h
View File

@@ -14,8 +14,6 @@
#include "delay_manager.h" #include "delay_manager.h"
#include "fec_manager.h" #include "fec_manager.h"
extern char fifo_file[1000]; extern char fifo_file[1000];
extern int mtu_warn; extern int mtu_warn;
@@ -26,7 +24,6 @@ extern int disable_checksum;
extern int debug_force_flush_fec; extern int debug_force_flush_fec;
extern int jitter_min; extern int jitter_min;
extern int jitter_max; extern int jitter_max;
@@ -35,12 +32,11 @@ extern int output_interval_max;
extern int fix_latency; extern int fix_latency;
//extern u32_t local_ip_uint32,remote_ip_uint32; // extern u32_t local_ip_uint32,remote_ip_uint32;
//extern char local_ip[100], remote_ip[100]; // extern char local_ip[100], remote_ip[100];
//extern int local_port, remote_port; // extern int local_port, remote_port;
extern address_t local_addr, remote_addr;
extern address_t local_addr,remote_addr;
extern address_t *out_addr; extern address_t *out_addr;
extern char *out_interface; extern char *out_interface;
@@ -62,17 +58,16 @@ extern int mssfix;
extern int manual_set_tun; extern int manual_set_tun;
extern int persist_tun; extern int persist_tun;
int from_normal_to_fec(conn_info_t &conn_info, char *data, int len, int &out_n, char **&out_arr, int *&out_len, my_time_t *&out_delay);
int from_fec_to_normal(conn_info_t &conn_info, char *data, int len, int &out_n, char **&out_arr, int *&out_len, my_time_t *&out_delay);
int from_normal_to_fec(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay); int delay_send(my_time_t delay, const dest_t &dest, char *data, int len);
int from_fec_to_normal(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay);
int delay_send(my_time_t delay,const dest_t &dest,char *data,int len);
int print_parameter(); int print_parameter();
int handle_command(char *s); int handle_command(char *s);
int unit_test(); int unit_test();
//void print_help(); // void print_help();
void process_arg(int argc, char *argv[]); void process_arg(int argc, char *argv[]);

View File

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

View File

@@ -1,13 +1,15 @@
#define EV_STANDALONE 1 #define EV_STANDALONE 1
#define EV_COMMON void *data; unsigned long long u64; #define EV_COMMON \
void *data; \
unsigned long long u64;
#define EV_COMPAT3 0 #define EV_COMPAT3 0
//#define EV_VERIFY 2 //#define EV_VERIFY 2
#if defined(__MINGW32__) #if defined(__MINGW32__)
# define EV_FD_TO_WIN32_HANDLE(fd) (fd) #define EV_FD_TO_WIN32_HANDLE(fd) (fd)
# define EV_WIN32_HANDLE_TO_FD(handle) (handle) #define EV_WIN32_HANDLE_TO_FD(handle) (handle)
# define EV_WIN32_CLOSE_FD(fd) closesocket (fd) #define EV_WIN32_CLOSE_FD(fd) closesocket(fd)
# define FD_SETSIZE 4096 #define FD_SETSIZE 4096
#endif #endif

View File

@@ -5,375 +5,308 @@
* Author: root * Author: root
*/ */
#include "common.h" #include "common.h"
#include "log.h" #include "log.h"
#include "packet.h" #include "packet.h"
#include "misc.h" #include "misc.h"
#include "crc32/Crc32.h"
int iv_min=4; int iv_min = 4;
int iv_max=32;//< 256; int iv_max = 32; //< 256;
u64_t packet_send_count=0; u64_t packet_send_count = 0;
u64_t dup_packet_send_count=0; u64_t dup_packet_send_count = 0;
u64_t packet_recv_count=0; u64_t packet_recv_count = 0;
u64_t dup_packet_recv_count=0; u64_t dup_packet_recv_count = 0;
typedef u64_t anti_replay_seq_t; typedef u64_t anti_replay_seq_t;
int disable_replay_filter=0; int disable_replay_filter = 0;
int disable_obscure=0; int disable_obscure = 0;
int disable_xor=0; int disable_xor = 0;
int random_drop=0; int random_drop = 0;
char key_string[1000]= ""; char key_string[1000] = "";
//int local_listen_fd=-1; // int local_listen_fd=-1;
void encrypt_0(char *input, int &len, char *key) {
void encrypt_0(char * input,int &len,char *key) int i, j;
{ if (key[0] == 0) return;
int i,j; for (i = 0, j = 0; i < len; i++, j++) {
if(key[0]==0) return; if (key[j] == 0) j = 0;
for(i=0,j=0;i<len;i++,j++) input[i] ^= key[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;
int i,j; if (key[0] == 0) return;
if(key[0]==0) return; for (i = 0, j = 0; i < len; i++, j++) {
for(i=0,j=0;i<len;i++,j++) if (key[j] == 0) j = 0;
{ input[i] ^= key[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);
//memcpy(output,input,in_len); // out_len=in_len;
// out_len=in_len; // return 0;
//return 0;
int i, j, k; int i, j, k;
if (in_len > 65535||in_len<0) if (in_len > 65535 || in_len < 0)
return -1; return -1;
int iv_len=iv_min+rand()%(iv_max-iv_min); int iv_len = iv_min + rand() % (iv_max - iv_min);
get_fake_random_chars(output,iv_len); get_fake_random_chars(output, iv_len);
memcpy(output+iv_len,input,in_len); memcpy(output + iv_len, input, in_len);
output[iv_len+in_len]=(uint8_t)iv_len; output[iv_len + in_len] = (uint8_t)iv_len;
output[iv_len+in_len]^=output[0]; output[iv_len + in_len] ^= output[0];
output[iv_len+in_len]^=key_string[0]; output[iv_len + in_len] ^= key_string[0];
for(i=0,j=0,k=1;i<in_len;i++,j++,k++) for (i = 0, j = 0, k = 1; i < in_len; i++, j++, k++) {
{ if (j == iv_len) j = 0;
if(j==iv_len) j=0; if (key_string[k] == 0) k = 0;
if(key_string[k]==0)k=0; output[iv_len + i] ^= output[j];
output[iv_len+i]^=output[j]; output[iv_len + i] ^= key_string[k];
output[iv_len+i]^=key_string[k]; }
}
out_len = iv_len + in_len + 1;
out_len=iv_len+in_len+1; return 0;
return 0;
} }
int do_obscure(char * data,int &len) int do_obscure(char *data, int &len) {
{ assert(len >= 0);
assert(len>=0); assert(len < buf_len);
assert(len<buf_len);
int iv_len=random_between(iv_min,iv_max); int iv_len = random_between(iv_min, iv_max);
get_fake_random_chars(data+len,iv_len); get_fake_random_chars(data + len, iv_len);
data[iv_len+len]=(uint8_t)iv_len; data[iv_len + len] = (uint8_t)iv_len;
for(int i=0,j=0;i<len;i++,j++) for (int i = 0, j = 0; i < len; i++, j++) {
{ if (j == iv_len) j = 0;
if(j==iv_len)j=0; data[i] ^= data[len + j];
data[i]^=data[len+j]; }
}
len=len+iv_len+1; len = len + iv_len + 1;
return 0; return 0;
} }
int de_obscure(char * data,int &len) int de_obscure(char *data, int &len) {
{ if (len < 1) return -1;
if(len<1) return -1; int iv_len = int((uint8_t)data[len - 1]);
int iv_len=int ((uint8_t) data[len-1]);
if(len<1+iv_len) return -1; if (len < 1 + iv_len) return -1;
len=len-1-iv_len; len = len - 1 - iv_len;
for(int i=0,j=0;i<len;i++,j++) for (int i = 0, j = 0; i < len; i++, j++) {
{ if (j == iv_len) j = 0;
if(j==iv_len)j=0; data[i] ^= data[len + j];
data[i]^=data[len+j]; }
}
return 0; return 0;
} }
int de_obscure_old(const char * input, int in_len,char *output,int &out_len) int de_obscure_old(const char *input, int in_len, char *output, int &out_len) {
{ // memcpy(output,input,in_len);
//memcpy(output,input,in_len); // out_len=in_len;
//out_len=in_len; // return 0;
//return 0;
int i, j, k; int i, j, k;
if (in_len > 65535||in_len<0) if (in_len > 65535 || in_len < 0) {
{ mylog(log_debug, "in_len > 65535||in_len<0 , %d", in_len);
mylog(log_debug,"in_len > 65535||in_len<0 , %d",in_len); return -1;
return -1; }
} int iv_len = int((uint8_t)(input[in_len - 1] ^ input[0] ^ key_string[0]));
int iv_len= int ((uint8_t)(input[in_len-1]^input[0]^key_string[0]) ); out_len = in_len - 1 - iv_len;
out_len=in_len-1-iv_len; if (out_len < 0) {
if(out_len<0) mylog(log_debug, "%d %d\n", in_len, out_len);
{ return -1;
mylog(log_debug,"%d %d\n",in_len,out_len); }
return -1; for (i = 0, j = 0, k = 1; i < in_len; i++, j++, k++) {
} if (j == iv_len) j = 0;
for(i=0,j=0,k=1;i<in_len;i++,j++,k++) if (key_string[k] == 0) k = 0;
{ output[i] = input[iv_len + i] ^ input[j] ^ key_string[k];
if(j==iv_len) j=0; }
if(key_string[k]==0)k=0; dup_packet_recv_count++;
output[i]=input[iv_len+i]^input[j]^key_string[k]; return 0;
}
dup_packet_recv_count++;
return 0;
} }
/* /*
int sendto_fd_ip_port (int fd,u32_t ip,int port,char * buf, int len,int flags) int sendto_fd_ip_port (int fd,u32_t ip,int port,char * buf, int len,int flags)
{ {
sockaddr_in tmp_sockaddr; sockaddr_in tmp_sockaddr;
memset(&tmp_sockaddr,0,sizeof(tmp_sockaddr)); memset(&tmp_sockaddr,0,sizeof(tmp_sockaddr));
tmp_sockaddr.sin_family = AF_INET; tmp_sockaddr.sin_family = AF_INET;
tmp_sockaddr.sin_addr.s_addr = ip; tmp_sockaddr.sin_addr.s_addr = ip;
tmp_sockaddr.sin_port = htons(uint16_t(port)); tmp_sockaddr.sin_port = htons(uint16_t(port));
return sendto(fd, buf, return sendto(fd, buf,
len , 0, len , 0,
(struct sockaddr *) &tmp_sockaddr, (struct sockaddr *) &tmp_sockaddr,
sizeof(tmp_sockaddr)); sizeof(tmp_sockaddr));
}*/ }*/
int sendto_fd_addr (int fd,address_t addr,char * buf, int len,int flags) int sendto_fd_addr(int fd, address_t addr, char *buf, int len, int flags) {
{ return sendto(fd, buf,
len, 0,
return sendto(fd, buf, (struct sockaddr *)&addr.inner,
len , 0, addr.get_len());
(struct sockaddr *) &addr.inner,
addr.get_len());
} }
/* /*
int sendto_ip_port (u32_t ip,int port,char * buf, int len,int flags) int sendto_ip_port (u32_t ip,int port,char * buf, int len,int flags)
{ {
return sendto_fd_ip_port(local_listen_fd,ip,port,buf,len,flags); return sendto_fd_ip_port(local_listen_fd,ip,port,buf,len,flags);
}*/ }*/
int send_fd (int fd,char * buf, int len,int flags) int send_fd(int fd, char *buf, int len, int flags) {
{ return send(fd, buf, len, flags);
return send(fd,buf,len,flags);
} }
int my_send(const dest_t &dest,char *data,int len) int my_send(const dest_t &dest, char *data, int len) {
{ if (dest.cook) {
if(dest.cook) do_cook(data, len);
{ }
do_cook(data,len); switch (dest.type) {
} case type_fd_addr: {
switch(dest.type) return sendto_fd_addr(dest.inner.fd, dest.inner.fd_addr.addr, data, len, 0);
{ break;
case type_fd_addr: }
{ case type_fd64_addr: {
return sendto_fd_addr(dest.inner.fd,dest.inner.fd_addr.addr,data,len,0); if (!fd_manager.exist(dest.inner.fd64)) return -1;
break; int fd = fd_manager.to_fd(dest.inner.fd64);
}
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); return sendto_fd_addr(fd, dest.inner.fd64_addr.addr, data, len, 0);
break; break;
} }
case type_fd: case type_fd: {
{ return send_fd(dest.inner.fd, data, len, 0);
return send_fd(dest.inner.fd,data,len,0); break;
break; }
} case type_write_fd: {
case type_write_fd: return write(dest.inner.fd, data, len);
{ break;
return write(dest.inner.fd,data,len); }
break; case type_fd64: {
} if (!fd_manager.exist(dest.inner.fd64)) return -1;
case type_fd64: int fd = fd_manager.to_fd(dest.inner.fd64);
{
if(!fd_manager.exist(dest.inner.fd64)) return -1; return send_fd(fd, data, len, 0);
int fd=fd_manager.to_fd(dest.inner.fd64); break;
}
/*
case type_fd64_ip_port_conv:
{
if(!fd_manager.exist(dest.inner.fd64)) return -1;
int fd=fd_manager.to_fd(dest.inner.fd64);
return send_fd(fd,data,len,0); char *new_data;
break; int new_len;
}
/*
case type_fd64_ip_port_conv:
{
if(!fd_manager.exist(dest.inner.fd64)) return -1;
int fd=fd_manager.to_fd(dest.inner.fd64);
char *new_data; put_conv(dest.conv,data,len,new_data,new_len);
int new_len; return sendto_fd_ip_port(fd,dest.inner.fd64_ip_port.ip_port.ip,dest.inner.fd64_ip_port.ip_port.port,new_data,new_len,0);
break;
}*/
put_conv(dest.conv,data,len,new_data,new_len); /*
return sendto_fd_ip_port(fd,dest.inner.fd64_ip_port.ip_port.ip,dest.inner.fd64_ip_port.ip_port.port,new_data,new_len,0); case type_fd64_conv:
break; {
}*/ char *new_data;
int new_len;
put_conv(dest.conv,data,len,new_data,new_len);
/* if(!fd_manager.exist(dest.inner.fd64)) return -1;
case type_fd64_conv: int fd=fd_manager.to_fd(dest.inner.fd64);
{ return send_fd(fd,new_data,new_len,0);
char *new_data; }*/
int new_len; /*
put_conv(dest.conv,data,len,new_data,new_len); case type_fd:
{
if(!fd_manager.exist(dest.inner.fd64)) return -1; send_fd(dest.inner.fd,data,len,0);
int fd=fd_manager.to_fd(dest.inner.fd64); break;
return send_fd(fd,new_data,new_len,0); }*/
}*/ default:
/* assert(0 == 1);
case type_fd: }
{ return 0;
send_fd(dest.inner.fd,data,len,0);
break;
}*/
default:
assert(0==1);
}
return 0;
} }
/* int put_conv0(u32_t conv, const char *input, int len_in, char *&output, int &len_out) {
* this function comes from http://www.hackersdelight.org/hdcodetxt/crc.c.txt assert(len_in >= 0);
*/ static char buf[buf_len];
unsigned int crc32h(unsigned char *message,int len) { output = buf;
assert(len>=0); u32_t n_conv = htonl(conv);
int i, crc; memcpy(output, &n_conv, sizeof(n_conv));
unsigned int byte, c; memcpy(output + sizeof(n_conv), input, len_in);
const unsigned int g0 = 0xEDB88320, g1 = g0>>1, u32_t crc32 = (u32_t)crc32_fast(output, len_in + sizeof(crc32));
g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, u32_t crc32_n = htonl(crc32);
g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; len_out = len_in + (int)(sizeof(n_conv)) + (int)sizeof(crc32_n);
memcpy(output + len_in + (int)(sizeof(n_conv)), &crc32_n, sizeof(crc32_n));
return 0;
}
int get_conv0(u32_t &conv, const char *input, int len_in, char *&output, int &len_out) {
assert(len_in >= 0);
u32_t n_conv;
memcpy(&n_conv, input, sizeof(n_conv));
conv = ntohl(n_conv);
output = (char *)input + sizeof(n_conv);
u32_t crc32_n;
len_out = len_in - (int)sizeof(n_conv) - (int)sizeof(crc32_n);
if (len_out < 0) {
mylog(log_debug, "len_out<0\n");
return -1;
}
memcpy(&crc32_n, input + len_in - (int)sizeof(crc32_n), sizeof(crc32_n));
u32_t crc32 = ntohl(crc32_n);
if (crc32 != (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) {
if (disable_checksum) return 0;
assert(len >= 0);
// if(len<0) return -1;
u32_t crc32 = (u32_t)crc32_fast(s, len);
write_u32(s + len, crc32);
len += sizeof(u32_t);
i = 0; return 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 do_cook(char *data, int &len) {
{ put_crc32(data, len);
assert(len_in>=0); if (!disable_obscure) do_obscure(data, len);
static char buf[buf_len]; if (!disable_xor) encrypt_0(data, len, key_string);
output=buf; return 0;
u32_t n_conv=htonl(conv);
memcpy(output,&n_conv,sizeof(n_conv));
memcpy(output+sizeof(n_conv),input,len_in);
u32_t crc32=crc32h((unsigned char *)output,len_in+sizeof(crc32));
u32_t crc32_n=htonl(crc32);
len_out=len_in+(int)(sizeof(n_conv))+(int)sizeof(crc32_n);
memcpy(output+len_in+(int)(sizeof(n_conv)),&crc32_n,sizeof(crc32_n));
return 0;
}
int get_conv0(u32_t &conv,const char *input,int len_in,char *&output,int &len_out )
{
assert(len_in>=0);
u32_t n_conv;
memcpy(&n_conv,input,sizeof(n_conv));
conv=ntohl(n_conv);
output=(char *)input+sizeof(n_conv);
u32_t crc32_n;
len_out=len_in-(int)sizeof(n_conv)-(int)sizeof(crc32_n);
if(len_out<0)
{
mylog(log_debug,"len_out<0\n");
return -1;
}
memcpy(&crc32_n,input+len_in-(int)sizeof(crc32_n),sizeof(crc32_n));
u32_t crc32=ntohl(crc32_n);
if(crc32!=crc32h((unsigned char *)input,len_in-(int)sizeof(crc32_n)))
{
mylog(log_debug,"crc32 check failed\n");
return -1;
}
return 0;
}
int put_crc32(char * s,int &len)
{
if(disable_checksum)return 0;
assert(len>=0);
//if(len<0) return -1;
u32_t crc32=crc32h((unsigned char *)s,len);
write_u32(s+len,crc32);
len+=sizeof(u32_t);
return 0;
} }
int do_cook(char * data,int &len) int de_cook(char *s, int &len) {
{ if (!disable_xor) decrypt_0(s, len, key_string);
put_crc32(data,len); if (!disable_obscure) {
if(!disable_obscure)do_obscure(data,len); int ret = de_obscure(s, len);
if(!disable_xor)encrypt_0(data,len,key_string); if (ret != 0) {
return 0; mylog(log_debug, "de_obscure fail\n");
return ret;
}
}
int ret = rm_crc32(s, len);
if (ret != 0) {
mylog(log_debug, "rm_crc32 fail\n");
return ret;
}
return 0;
} }
int rm_crc32(char *s, int &len) {
int de_cook(char * s,int &len) if (disable_checksum) return 0;
{ assert(len >= 0);
if(!disable_xor)decrypt_0(s,len,key_string); len -= sizeof(u32_t);
if(!disable_obscure) if (len < 0) return -1;
{ u32_t crc32_in = read_u32(s + len);
int ret=de_obscure(s,len); u32_t crc32 = (u32_t)crc32_fast(s, len);
if(ret!=0) if (crc32 != crc32_in) return -1;
{ return 0;
mylog(log_debug,"de_obscure fail\n");
return ret;
}
}
int ret=rm_crc32(s,len);
if(ret!=0)
{
mylog(log_debug,"rm_crc32 fail\n");
return ret;
}
return 0;
}
int rm_crc32(char * s,int &len)
{
if(disable_checksum)return 0;
assert(len>=0);
len-=sizeof(u32_t);
if(len<0) return -1;
u32_t crc32_in=read_u32(s+len);
u32_t crc32=crc32h((unsigned char *)s,len);
if(crc32!=crc32_in) return -1;
return 0;
} }
/* /*
int do_obs() int do_obs()
@@ -381,31 +314,25 @@ int do_obs()
} }
int de_obs()*/ int de_obs()*/
int put_conv(u32_t conv,const char * input,int len_in,char *&output,int &len_out) int put_conv(u32_t conv, const char *input, int len_in, char *&output, int &len_out) {
{ static char buf[buf_len];
static char buf[buf_len]; output = buf;
output=buf; u32_t n_conv = htonl(conv);
u32_t n_conv=htonl(conv); memcpy(output, &n_conv, sizeof(n_conv));
memcpy(output,&n_conv,sizeof(n_conv)); memcpy(output + sizeof(n_conv), input, len_in);
memcpy(output+sizeof(n_conv),input,len_in); len_out = len_in + (int)(sizeof(n_conv));
len_out=len_in+(int)(sizeof(n_conv));
return 0; return 0;
} }
int get_conv(u32_t &conv,const char *input,int len_in,char *&output,int &len_out ) int get_conv(u32_t &conv, const char *input, int len_in, char *&output, int &len_out) {
{ u32_t n_conv;
u32_t n_conv; memcpy(&n_conv, input, sizeof(n_conv));
memcpy(&n_conv,input,sizeof(n_conv)); conv = ntohl(n_conv);
conv=ntohl(n_conv); output = (char *)input + sizeof(n_conv);
output=(char *)input+sizeof(n_conv); len_out = len_in - (int)sizeof(n_conv);
len_out=len_in-(int)sizeof(n_conv); if (len_out < 0) {
if(len_out<0) mylog(log_debug, "len_out<0\n");
{ return -1;
mylog(log_debug,"len_out<0\n"); }
return -1; return 0;
}
return 0;
} }

View File

@@ -12,7 +12,7 @@
#include "fd_manager.h" #include "fd_manager.h"
extern int iv_min; extern int iv_min;
extern int iv_max;//< 256; extern int iv_max; //< 256;
extern u64_t packet_send_count; extern u64_t packet_send_count;
extern u64_t dup_packet_send_count; extern u64_t dup_packet_send_count;
@@ -24,24 +24,23 @@ extern int random_drop;
extern int disable_obscure; extern int disable_obscure;
extern int disable_xor; extern int disable_xor;
int my_send(const dest_t &dest, char *data, int len);
int my_send(const dest_t &dest,char *data,int len); void encrypt_0(char *input, int &len, char *key);
void decrypt_0(char *input, int &len, char *key);
int add_seq(char *data, int &data_len);
int remove_seq(char *data, int &data_len);
int do_obscure(const char *input, int in_len, char *output, int &out_len);
int de_obscure(const char *input, int in_len, char *output, int &out_len);
void encrypt_0(char * input,int &len,char *key); // int sendto_fd_u64 (int fd,u64_t u64,char * buf, int len,int flags);
void decrypt_0(char * input,int &len,char *key); int sendto_ip_port(u32_t ip, int port, char *buf, int len, int flags);
int add_seq(char * data,int &data_len ); int send_fd(int fd, char *buf, int len, int flags);
int remove_seq(char * data,int &data_len);
int do_obscure(const char * input, int in_len,char *output,int &out_len);
int de_obscure(const char * input, int in_len,char *output,int &out_len);
//int sendto_fd_u64 (int fd,u64_t u64,char * buf, int len,int flags); int put_conv(u32_t conv, const char *input, int len_in, char *&output, int &len_out);
int sendto_ip_port (u32_t ip,int port,char * buf, int len,int flags); int get_conv(u32_t &conv, const char *input, int len_in, char *&output, int &len_out);
int send_fd (int fd,char * buf, int len,int flags); int put_crc32(char *s, int &len);
int rm_crc32(char *s, int &len);
int put_conv(u32_t conv,const char * input,int len_in,char *&output,int &len_out); int do_cook(char *data, int &len);
int get_conv(u32_t &conv,const char *input,int len_in,char *&output,int &len_out ); int de_cook(char *s, int &len);
int put_crc32(char * s,int &len);
int rm_crc32(char * s,int &len);
int do_cook(char * data,int &len);
int de_cook(char * s,int &len);
#endif /* PACKET_H_ */ #endif /* PACKET_H_ */

View File

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

View File

@@ -1,439 +1,422 @@
#include "tunnel.h" #include "tunnel.h"
void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out) void data_from_local_or_fec_timeout(conn_info_t &conn_info, int is_time_out) {
{ fd64_t &remote_fd64 = conn_info.remote_fd64;
fd64_t &remote_fd64=conn_info.remote_fd64; int &local_listen_fd = conn_info.local_listen_fd;
int & local_listen_fd=conn_info.local_listen_fd;
char data[buf_len]; char data[buf_len];
int data_len; int data_len;
address_t addr; address_t addr;
u32_t conv; u32_t conv;
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; int out_n;
dest_t dest; char **out_arr;
dest.type=type_fd64; int *out_len;
dest.inner.fd64=remote_fd64; my_time_t *out_delay;
dest.cook=1; 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;
//fd64_t fd64=events[idx].data.u64; mylog(log_trace, "events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n");
mylog(log_trace,"events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()\n");
//uint64_t value; // uint64_t value;
//if(!fd_manager.exist(fd64)) //fd64 has been closed // if(!fd_manager.exist(fd64)) //fd64 has been closed
//{ //{
// mylog(log_trace,"!fd_manager.exist(fd64)"); // mylog(log_trace,"!fd_manager.exist(fd64)");
// continue; // continue;
//} // }
//if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8) // if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8)
//{ //{
// mylog(log_trace,"(ret=read(fd_manager.to_fd(fd64), &value, 8))!=8,ret=%d\n",ret); // mylog(log_trace,"(ret=read(fd_manager.to_fd(fd64), &value, 8))!=8,ret=%d\n",ret);
// continue; // continue;
//} // }
//if(value==0) // if(value==0)
//{ //{
// mylog(log_debug,"value==0\n"); // mylog(log_debug,"value==0\n");
// continue; // continue;
//} // }
//assert(value==1); // assert(value==1);
from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay); from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
} } else // events[idx].data.u64 == (u64_t)local_listen_fd
else//events[idx].data.u64 == (u64_t)local_listen_fd {
{ mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n");
mylog(log_trace,"events[idx].data.u64 == (u64_t)local_listen_fd\n"); address_t::storage_t udp_new_addr_in = {0};
address_t::storage_t udp_new_addr_in={0}; socklen_t udp_new_addr_len = sizeof(address_t::storage_t);
socklen_t udp_new_addr_len = sizeof(address_t::storage_t); if ((data_len = recvfrom(local_listen_fd, data, max_data_len + 1, 0,
if ((data_len = recvfrom(local_listen_fd, data, max_data_len, 0, (struct sockaddr *)&udp_new_addr_in, &udp_new_addr_len)) == -1) {
(struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { mylog(log_debug, "recv_from error,this shouldnt happen,err=%s,but we can try to continue\n", get_sock_error());
mylog(log_debug,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error()); return;
return; };
};
if(!disable_mtu_warn&&data_len>=mtu_warn) if (data_len == max_data_len + 1) {
{ mylog(log_warn, "huge packet from upper level, data_len > %d, packet truncated, dropped\n", max_data_len);
mylog(log_warn,"huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",data_len,mtu_warn); return;
} }
if (!disable_mtu_warn && data_len >= mtu_warn) {
mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn);
}
addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len); addr.from_sockaddr((struct sockaddr *)&udp_new_addr_in, udp_new_addr_len);
mylog(log_trace,"Received packet from %s, len: %d\n", addr.get_str(),data_len); mylog(log_trace, "Received packet from %s, len: %d\n", addr.get_str(), data_len);
//u64_t u64=ip_port.to_u64(); // u64_t u64=ip_port.to_u64();
if(!conn_info.conv_manager.c.is_data_used(addr)) if (!conn_info.conv_manager.c.is_data_used(addr)) {
{ if (conn_info.conv_manager.c.get_size() >= max_conv_num) {
if(conn_info.conv_manager.c.get_size() >=max_conv_num) mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
{ return;
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);
conv=conn_info.conv_manager.c.get_new_conv(); mylog(log_info, "new packet from %s,conv_id=%x\n", addr.get_str(), conv);
conn_info.conv_manager.c.insert_conv(conv,addr); } else {
mylog(log_info,"new packet from %s,conv_id=%x\n",addr.get_str(),conv); conv = conn_info.conv_manager.c.find_conv_by_data(addr);
} mylog(log_trace, "conv=%d\n", conv);
else }
{ conn_info.conv_manager.c.update_active_time(conv);
conv=conn_info.conv_manager.c.find_conv_by_data(addr); char *new_data;
mylog(log_trace,"conv=%d\n",conv); int new_len;
} put_conv(conv, data, data_len, new_data, new_len);
conn_info.conv_manager.c.update_active_time(conv);
char * new_data;
int new_len;
put_conv(conv,data,data_len,new_data,new_len);
mylog(log_trace, "data_len=%d new_len=%d\n", data_len, new_len);
mylog(log_trace,"data_len=%d new_len=%d\n",data_len,new_len); from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay);
from_normal_to_fec(conn_info,new_data,new_len,out_n,out_arr,out_len,out_delay); }
mylog(log_trace, "out_n=%d\n", out_n);
} for (int i = 0; i < out_n; i++) {
mylog(log_trace,"out_n=%d\n",out_n); delay_send(out_delay[i], dest, out_arr[i], out_len[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));
assert(!(revents&EV_ERROR));
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
data_from_local_or_fec_timeout(conn_info,0); data_from_local_or_fec_timeout(conn_info, 0);
} }
static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
char data[buf_len]; char data[buf_len];
if(!fd_manager.exist(watcher->u64)) //fd64 has been closed if (!fd_manager.exist(watcher->u64)) // fd64 has been closed
{ {
mylog(log_trace,"!fd_manager.exist(events[idx].data.u64)"); mylog(log_trace, "!fd_manager.exist(events[idx].data.u64)");
return; return;
} }
fd64_t &remote_fd64=conn_info.remote_fd64; fd64_t &remote_fd64 = conn_info.remote_fd64;
int &remote_fd=conn_info.remote_fd; int &remote_fd = conn_info.remote_fd;
assert(watcher->u64==remote_fd64); assert(watcher->u64 == remote_fd64);
int fd=fd_manager.to_fd(remote_fd64); int fd = fd_manager.to_fd(remote_fd64);
int data_len =recv(fd,data,max_data_len,0); int data_len = recv(fd, data, max_data_len + 1, 0);
mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd,data_len);
if(data_len<0)
{
if(get_sock_errno()==ECONNREFUSED)
{
mylog(log_debug, "recv failed %d ,udp_fd%d,errno:%s\n", data_len,remote_fd,get_sock_error());
}
mylog(log_warn, "recv failed %d ,udp_fd%d,errno:%s\n", data_len,remote_fd,get_sock_error()); if (data_len == max_data_len + 1) {
return; mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len);
} return;
if(!disable_mtu_warn&&data_len>mtu_warn) }
{
mylog(log_warn,"huge packet,data len=%d (>%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",data_len,mtu_warn);
}
if(de_cook(data,data_len)!=0) mylog(log_trace, "received data from udp fd %d, len=%d\n", remote_fd, data_len);
{ if (data_len < 0) {
mylog(log_debug,"de_cook error"); if (get_sock_errno() == ECONNREFUSED) {
return; mylog(log_debug, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error());
} }
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; mylog(log_warn, "recv failed %d ,udp_fd%d,errno:%s\n", data_len, remote_fd, get_sock_error());
from_fec_to_normal(conn_info,data,data_len,out_n,out_arr,out_len,out_delay); return;
}
if (!disable_mtu_warn && data_len > mtu_warn) {
mylog(log_warn, "huge packet,data len=%d (>%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn);
}
mylog(log_trace,"out_n=%d\n",out_n); if (de_cook(data, data_len) != 0) {
mylog(log_debug, "de_cook error");
return;
}
for(int i=0;i<out_n;i++) int out_n;
{ char **out_arr;
u32_t conv; int *out_len;
char *new_data; my_time_t *out_delay;
int new_len; from_fec_to_normal(conn_info, data, data_len, out_n, out_arr, out_len, out_delay);
if(get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0)
{
mylog(log_debug,"get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0");
continue;
}
if(!conn_info.conv_manager.c.is_conv_used(conv))
{
mylog(log_trace,"!conn_info.conv_manager.is_conv_used(conv)");
continue;
}
conn_info.conv_manager.c.update_active_time(conv); mylog(log_trace, "out_n=%d\n", out_n);
address_t addr=conn_info.conv_manager.c.find_data_by_conv(conv); for (int i = 0; i < out_n; i++) {
dest_t dest; u32_t conv;
dest.inner.fd_addr.fd=conn_info.local_listen_fd; char *new_data;
dest.inner.fd_addr.addr=addr; int new_len;
dest.type=type_fd_addr; if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) {
mylog(log_debug, "get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0");
continue;
}
if (!conn_info.conv_manager.c.is_conv_used(conv)) {
mylog(log_trace, "!conn_info.conv_manager.is_conv_used(conv)");
continue;
}
delay_send(out_delay[i],dest,new_data,new_len); conn_info.conv_manager.c.update_active_time(conv);
}
address_t addr = conn_info.conv_manager.c.find_data_by_conv(conv);
dest_t dest;
dest.inner.fd_addr.fd = conn_info.local_listen_fd;
dest.inner.fd_addr.addr = addr;
dest.type = type_fd_addr;
delay_send(out_delay[i], dest, new_data, new_len);
}
} }
static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR)); int fifo_fd = watcher->fd;
int fifo_fd=watcher->fd;
char buf[buf_len]; char buf[buf_len];
int len=read (fifo_fd, buf, sizeof (buf)); int len = read(fifo_fd, buf, sizeof(buf));
if(len<0) if (len < 0) {
{ mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error());
mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error()); return;
return; }
} buf[len] = 0;
buf[len]=0; handle_command(buf);
handle_command(buf);
} }
static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
//uint64_t value; // uint64_t value;
//read(delay_manager.get_timer_fd(), &value, 8); // read(delay_manager.get_timer_fd(), &value, 8);
//mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); // mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n");
//do nothing // do nothing
} }
static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
data_from_local_or_fec_timeout(conn_info,1);
data_from_local_or_fec_timeout(conn_info, 1);
} }
static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
uint64_t value; uint64_t value;
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
//read(conn_info.timer.get_timer_fd(), &value, 8); // read(conn_info.timer.get_timer_fd(), &value, 8);
conn_info.conv_manager.c.clear_inactive(); conn_info.conv_manager.c.clear_inactive();
mylog(log_trace,"events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd()\n"); mylog(log_trace, "events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd()\n");
conn_info.stat.report_as_client(); conn_info.stat.report_as_client();
if(debug_force_flush_fec) if (debug_force_flush_fec) {
{ int out_n;
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; char **out_arr;
dest_t dest; int *out_len;
dest.type=type_fd64; my_time_t *out_delay;
dest.inner.fd64=conn_info.remote_fd64; dest_t dest;
dest.cook=1; dest.type = type_fd64;
from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay); dest.inner.fd64 = conn_info.remote_fd64;
for(int i=0;i<out_n;i++) dest.cook = 1;
{ from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
delay_send(out_delay[i],dest,out_arr[i],out_len[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));
assert(!(revents&EV_ERROR));
delay_manager.check(); delay_manager.check();
} }
int tunnel_client_event_loop() int tunnel_client_event_loop() {
{ int i, j, k;
int i, j, k;int ret; int ret;
int yes = 1; int yes = 1;
//int epoll_fd; // int epoll_fd;
conn_info_t *conn_info_p = new conn_info_t;
conn_info_t &conn_info = *conn_info_p; // huge size of conn_info,do not allocate on stack
conn_info_t *conn_info_p=new conn_info_t; int &local_listen_fd = conn_info.local_listen_fd;
conn_info_t &conn_info=*conn_info_p; //huge size of conn_info,do not allocate on stack new_listen_socket2(local_listen_fd, local_addr);
int &local_listen_fd=conn_info.local_listen_fd; // epoll_fd = epoll_create1(0);
new_listen_socket2(local_listen_fd,local_addr); // assert(epoll_fd>0);
//epoll_fd = epoll_create1(0); // const int max_events = 4096;
//assert(epoll_fd>0); // struct epoll_event ev, events[max_events];
// if (epoll_fd < 0) {
// mylog(log_fatal,"epoll return %d\n", epoll_fd);
// myexit(-1);
// }
//const int max_events = 4096; struct ev_loop *loop = ev_default_loop(0);
//struct epoll_event ev, events[max_events]; assert(loop != NULL);
//if (epoll_fd < 0) {
// mylog(log_fatal,"epoll return %d\n", epoll_fd);
// myexit(-1);
//}
struct ev_loop * loop= ev_default_loop(0); conn_info.loop = loop;
assert(loop != NULL);
conn_info.loop=loop; // ev.events = EPOLLIN;
// ev.data.u64 = local_listen_fd;
//ev.events = EPOLLIN; // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev);
//ev.data.u64 = local_listen_fd; // if (ret!=0) {
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev); // mylog(log_fatal,"add udp_listen_fd error\n");
//if (ret!=0) { // myexit(-1);
// mylog(log_fatal,"add udp_listen_fd error\n"); // }
// myexit(-1); struct ev_io local_listen_watcher;
//} local_listen_watcher.data = &conn_info;
struct ev_io local_listen_watcher;
local_listen_watcher.data=&conn_info;
ev_io_init(&local_listen_watcher, local_listen_cb, local_listen_fd, EV_READ); ev_io_init(&local_listen_watcher, local_listen_cb, local_listen_fd, EV_READ);
ev_io_start(loop, &local_listen_watcher); ev_io_start(loop, &local_listen_watcher);
int & remote_fd=conn_info.remote_fd; int &remote_fd = conn_info.remote_fd;
fd64_t &remote_fd64=conn_info.remote_fd64; fd64_t &remote_fd64 = conn_info.remote_fd64;
assert(new_connected_socket2(remote_fd,remote_addr,out_addr,out_interface)==0); assert(new_connected_socket2(remote_fd, remote_addr, out_addr, out_interface) == 0);
remote_fd64=fd_manager.create(remote_fd); remote_fd64 = fd_manager.create(remote_fd);
mylog(log_debug,"remote_fd64=%llu\n",remote_fd64); mylog(log_debug, "remote_fd64=%llu\n", remote_fd64);
//ev.events = EPOLLIN; // ev.events = EPOLLIN;
//ev.data.u64 = remote_fd64; // ev.data.u64 = remote_fd64;
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, remote_fd, &ev); // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, remote_fd, &ev);
//if (ret!= 0) { // if (ret!= 0) {
// mylog(log_fatal,"add raw_fd error\n"); // mylog(log_fatal,"add raw_fd error\n");
// myexit(-1); // myexit(-1);
//} // }
struct ev_io remote_watcher; struct ev_io remote_watcher;
remote_watcher.data=&conn_info; remote_watcher.data = &conn_info;
remote_watcher.u64=remote_fd64; remote_watcher.u64 = remote_fd64;
ev_io_init(&remote_watcher, remote_cb, remote_fd, EV_READ); ev_io_init(&remote_watcher, remote_cb, remote_fd, EV_READ);
ev_io_start(loop, &remote_watcher); ev_io_start(loop, &remote_watcher);
// ev.events = EPOLLIN;
// ev.data.u64 = delay_manager.get_timer_fd();
//ev.events = EPOLLIN; // mylog(log_debug,"delay_manager.get_timer_fd()=%d\n",delay_manager.get_timer_fd());
//ev.data.u64 = delay_manager.get_timer_fd(); // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev);
// if (ret!= 0) {
// mylog(log_fatal,"add delay_manager.get_timer_fd() error\n");
// myexit(-1);
// }
//mylog(log_debug,"delay_manager.get_timer_fd()=%d\n",delay_manager.get_timer_fd()); delay_manager.set_loop_and_cb(loop, delay_manager_cb);
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev);
//if (ret!= 0) {
// mylog(log_fatal,"add delay_manager.get_timer_fd() error\n");
// myexit(-1);
//}
delay_manager.set_loop_and_cb(loop,delay_manager_cb);
conn_info.fec_encode_manager.set_data(&conn_info); conn_info.fec_encode_manager.set_data(&conn_info);
conn_info.fec_encode_manager.set_loop_and_cb(loop,fec_encode_cb); conn_info.fec_encode_manager.set_loop_and_cb(loop, fec_encode_cb);
//u64_t tmp_fd64=conn_info.fec_encode_manager.get_timer_fd64(); // u64_t tmp_fd64=conn_info.fec_encode_manager.get_timer_fd64();
//ev.events = EPOLLIN; // ev.events = EPOLLIN;
//ev.data.u64 = tmp_fd64; // ev.data.u64 = tmp_fd64;
//mylog(log_debug,"conn_info.fec_encode_manager.get_timer_fd64()=%llu\n",conn_info.fec_encode_manager.get_timer_fd64());
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(tmp_fd64), &ev);
//if (ret!= 0) {
// mylog(log_fatal,"add fec_encode_manager.get_timer_fd64() error\n");
// myexit(-1);
//}
conn_info.timer.data=&conn_info;
ev_init(&conn_info.timer,conn_timer_cb);
ev_timer_set(&conn_info.timer, 0, timer_interval/1000.0 );
ev_timer_start(loop,&conn_info.timer);
//conn_info.timer.add_fd_to_epoll(epoll_fd);
//conn_info.timer.set_timer_repeat_us(timer_interval*1000);
//mylog(log_debug,"conn_info.timer.get_timer_fd()=%d\n",conn_info.timer.get_timer_fd());
// mylog(log_debug,"conn_info.fec_encode_manager.get_timer_fd64()=%llu\n",conn_info.fec_encode_manager.get_timer_fd64());
// ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(tmp_fd64), &ev);
// if (ret!= 0) {
// mylog(log_fatal,"add fec_encode_manager.get_timer_fd64() error\n");
// myexit(-1);
// }
conn_info.timer.data = &conn_info;
ev_init(&conn_info.timer, conn_timer_cb);
ev_timer_set(&conn_info.timer, 0, timer_interval / 1000.0);
ev_timer_start(loop, &conn_info.timer);
// conn_info.timer.add_fd_to_epoll(epoll_fd);
// conn_info.timer.set_timer_repeat_us(timer_interval*1000);
// mylog(log_debug,"conn_info.timer.get_timer_fd()=%d\n",conn_info.timer.get_timer_fd());
struct ev_io fifo_watcher; struct ev_io fifo_watcher;
int fifo_fd=-1; int fifo_fd = -1;
if(fifo_file[0]!=0) if (fifo_file[0] != 0) {
{ fifo_fd = create_fifo(fifo_file);
fifo_fd=create_fifo(fifo_file); // ev.events = EPOLLIN;
//ev.events = EPOLLIN; // ev.data.u64 = fifo_fd;
//ev.data.u64 = fifo_fd;
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev); // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev);
//if (ret!= 0) { // if (ret!= 0) {
// mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); // mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno));
// myexit(-1); // myexit(-1);
//} // }
mylog(log_info,"fifo_file=%s\n",fifo_file); mylog(log_info, "fifo_file=%s\n", fifo_file);
ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ);
ev_io_start(loop, &fifo_watcher); ev_io_start(loop, &fifo_watcher);
}
} ev_prepare prepare_watcher;
ev_init(&prepare_watcher, prepare_cb);
ev_prepare_start(loop, &prepare_watcher);
ev_prepare prepare_watcher; mylog(log_info, "now listening at %s\n", local_addr.get_str());
ev_init(&prepare_watcher,prepare_cb);
ev_prepare_start(loop,&prepare_watcher);
mylog(log_info,"now listening at %s\n",local_addr.get_str()); ev_run(loop, 0);
ev_run(loop, 0); mylog(log_warn, "ev_run returned\n");
myexit(0);
mylog(log_warn,"ev_run returned\n"); /*
myexit(0); while(1)////////////////////////
{
if(about_to_exit) myexit(0);
/* int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000);
while(1)//////////////////////// if (nfds < 0) { //allow zero
{ if(errno==EINTR )
if(about_to_exit) myexit(0); {
mylog(log_info,"epoll interrupted by signal continue\n");
}
else
{
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
myexit(-1);
}
}
int idx;
for (idx = 0; idx < nfds; ++idx) {
if(events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd())
{
int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000); }
if (nfds < 0) { //allow zero
if(errno==EINTR )
{
mylog(log_info,"epoll interrupted by signal continue\n");
}
else
{
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
myexit(-1);
}
}
int idx;
for (idx = 0; idx < nfds; ++idx) {
if(events[idx].data.u64==(u64_t)conn_info.timer.get_timer_fd())
{
} else if (events[idx].data.u64 == (u64_t)fifo_fd)
{
else if (events[idx].data.u64 == (u64_t)fifo_fd) }
{ else if (events[idx].data.u64 == (u64_t)local_listen_fd||events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64())
{
} }
else if (events[idx].data.u64 == (u64_t)local_listen_fd||events[idx].data.u64 == conn_info.fec_encode_manager.get_timer_fd64()) else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) {
{
} }
else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) { else if(events[idx].data.u64>u32_t(-1) )
{
} }
else if(events[idx].data.u64>u32_t(-1) ) else
{ {
mylog(log_fatal,"unknown fd,this should never happen\n");
} myexit(-1);
else }
{ }
mylog(log_fatal,"unknown fd,this should never happen\n"); //delay_manager.check();
myexit(-1); }*/
} return 0;
}
//delay_manager.check();
}*/
return 0;
} }

View File

@@ -11,481 +11,454 @@ static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int re
static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents); static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents);
static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents); static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
enum tmp_mode_t{is_from_remote=0,is_fec_timeout,is_conn_timer}; enum tmp_mode_t { is_from_remote = 0,
is_fec_timeout,
is_conn_timer };
void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_t fd64,tmp_mode_t mode) void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t &conn_info, fd64_t fd64, tmp_mode_t mode) {
{ int ret;
int ret;
char data[buf_len]; char data[buf_len];
int data_len; int data_len;
u32_t conv; u32_t conv;
//fd64_t fd64=events[idx].data.u64; // fd64_t fd64=events[idx].data.u64;
//mylog(log_trace,"events[idx].data.u64 >u32_t(-1),%llu\n",(u64_t)events[idx].data.u64); // mylog(log_trace,"events[idx].data.u64 >u32_t(-1),%llu\n",(u64_t)events[idx].data.u64);
// assert(fd_manager.exist_info(fd64));
// ip_port_t ip_port=fd_manager.get_info(fd64).ip_port;
//assert(fd_manager.exist_info(fd64)); // conn_info_t &conn_info=conn_manager.find(ip_port);
//ip_port_t ip_port=fd_manager.get_info(fd64).ip_port; address_t &addr = conn_info.addr;
assert(conn_manager.exist(addr));
int &local_listen_fd = conn_info.local_listen_fd;
//conn_info_t &conn_info=conn_manager.find(ip_port); int out_n = -2;
address_t &addr=conn_info.addr; char **out_arr;
assert(conn_manager.exist(addr)); int *out_len;
my_time_t *out_delay;
int &local_listen_fd=conn_info.local_listen_fd; dest_t dest;
dest.inner.fd_addr.fd = local_listen_fd;
dest.inner.fd_addr.addr = addr;
dest.type = type_fd_addr;
dest.cook = 1;
int out_n=-2;char **out_arr;int *out_len;my_time_t *out_delay; if (mode == is_fec_timeout) {
assert(fd64 == 0);
// uint64_t value;
// if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8)
//{
// mylog(log_trace,"fd_manager.to_fd(fd64), &value, 8)!=8 ,%d\n",ret);
// continue;
// }
// if(value==0)
//{
// mylog(log_trace,"value==0\n");
// continue;
// }
// assert(value==1);
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
} else if (mode == is_conn_timer) {
assert(fd64 == 0);
// uint64_t value;
// read(conn_info.timer.get_timer_fd(), &value, 8);
conn_info.conv_manager.s.clear_inactive();
if (debug_force_flush_fec) {
from_normal_to_fec(conn_info, 0, 0, out_n, out_arr, out_len, out_delay);
}
dest_t dest; conn_info.stat.report_as_server(addr);
dest.inner.fd_addr.fd=local_listen_fd; return;
dest.inner.fd_addr.addr=addr; } else if (mode == is_from_remote) {
dest.type=type_fd_addr; if (!fd_manager.exist(fd64)) // fd64 has been closed
dest.cook=1; {
mylog(log_warn, "!fd_manager.exist(fd64)\n");
return;
}
if(mode==is_fec_timeout) // fd64_t &fd64 =conn_info.remote_fd64;
{ assert(conn_info.conv_manager.s.is_data_used(fd64));
assert(fd64==0);
//uint64_t value;
//if((ret=read(fd_manager.to_fd(fd64), &value, 8))!=8)
//{
// mylog(log_trace,"fd_manager.to_fd(fd64), &value, 8)!=8 ,%d\n",ret);
// continue;
//}
//if(value==0)
//{
// mylog(log_trace,"value==0\n");
// continue;
//}
//assert(value==1);
from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay);
}
else if(mode==is_conn_timer)
{
assert(fd64==0);
//uint64_t value;
//read(conn_info.timer.get_timer_fd(), &value, 8);
conn_info.conv_manager.s.clear_inactive();
if(debug_force_flush_fec)
{
from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay);
}
conn_info.stat.report_as_server(addr); conv = conn_info.conv_manager.s.find_conv_by_data(fd64);
return; conn_info.conv_manager.s.update_active_time(conv);
} conn_info.update_active_time();
else if(mode==is_from_remote)
{
if(!fd_manager.exist(fd64)) //fd64 has been closed
{
mylog(log_warn,"!fd_manager.exist(fd64)\n");
return;
}
//fd64_t &fd64 =conn_info.remote_fd64; int fd = fd_manager.to_fd(fd64);
assert(conn_info.conv_manager.s.is_data_used(fd64)); data_len = recv(fd, data, max_data_len + 1, 0);
conv=conn_info.conv_manager.s.find_conv_by_data(fd64); if (data_len == max_data_len + 1) {
conn_info.conv_manager.s.update_active_time(conv); mylog(log_warn, "huge packet from upper level, data_len > %d, packet truncated, dropped\n", max_data_len);
conn_info.update_active_time(); return;
}
int fd=fd_manager.to_fd(fd64); mylog(log_trace, "received a packet from udp_fd,len:%d,conv=%d\n", data_len, conv);
data_len=recv(fd,data,max_data_len,0);
mylog(log_trace,"received a packet from udp_fd,len:%d,conv=%d\n",data_len,conv); if (data_len < 0) {
mylog(log_debug, "udp fd,recv_len<0 continue,%s\n", get_sock_error());
if(data_len<0) return;
{ }
mylog(log_debug,"udp fd,recv_len<0 continue,%s\n",get_sock_error());
return; if (!disable_mtu_warn && data_len >= mtu_warn) {
} mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn);
}
if(!disable_mtu_warn&&data_len>=mtu_warn) char *new_data;
{ int new_len;
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); put_conv(conv, data, data_len, new_data, new_len);
}
char * new_data; from_normal_to_fec(conn_info, new_data, new_len, out_n, out_arr, out_len, out_delay);
int new_len; } else {
put_conv(conv,data,data_len,new_data,new_len); assert(0 == 1);
}
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++) {
else delay_send(out_delay[i], dest, out_arr[i], out_len[i]);
{ }
assert(0==1);
}
mylog(log_trace,"out_n=%d\n",out_n);
for(int i=0;i<out_n;i++)
{
delay_send(out_delay[i],dest,out_arr[i],out_len[i]);
}
} }
static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
int local_listen_fd=watcher->fd; int local_listen_fd = watcher->fd;
int ret; int ret;
mylog(log_trace,"events[idx].data.u64 == (u64_t)local_listen_fd\n"); mylog(log_trace, "events[idx].data.u64 == (u64_t)local_listen_fd\n");
char data[buf_len]; char data[buf_len];
int data_len; int data_len;
address_t::storage_t udp_new_addr_in={0}; address_t::storage_t udp_new_addr_in = {0};
socklen_t udp_new_addr_len = sizeof(address_t::storage_t); socklen_t udp_new_addr_len = sizeof(address_t::storage_t);
if ((data_len = recvfrom(local_listen_fd, data, max_data_len, 0, if ((data_len = recvfrom(local_listen_fd, data, max_data_len + 1, 0,
(struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { (struct sockaddr *)&udp_new_addr_in, &udp_new_addr_len)) == -1) {
mylog(log_error,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error()); mylog(log_error, "recv_from error,this shouldnt happen,err=%s,but we can try to continue\n", get_sock_error());
return; return;
}; };
address_t addr; if (data_len == max_data_len + 1) {
addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len); mylog(log_warn, "huge packet, data_len > %d, packet truncated, dropped\n", max_data_len);
return;
}
mylog(log_trace,"Received packet from %s,len: %d\n", addr.get_str(),data_len); address_t addr;
addr.from_sockaddr((struct sockaddr *)&udp_new_addr_in, udp_new_addr_len);
if(!disable_mtu_warn&&data_len>=mtu_warn)///////////////////////delete this for type 0 in furture mylog(log_trace, "Received packet from %s,len: %d\n", addr.get_str(), data_len);
{
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 (!disable_mtu_warn && data_len >= mtu_warn) ///////////////////////delete this for type 0 in furture
{
mylog(log_warn, "huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ", data_len, mtu_warn);
}
if(de_cook(data,data_len)!=0) if (de_cook(data, data_len) != 0) {
{ mylog(log_debug, "de_cook error");
mylog(log_debug,"de_cook error"); return;
return; }
}
if (!conn_manager.exist(addr)) {
if (conn_manager.mp.size() >= max_conn_num) {
mylog(log_warn, "new connection %s ignored bc max_conn_num exceed\n", addr.get_str());
return;
}
// conn_manager.insert(addr);
conn_info_t &conn_info = conn_manager.find_insert(addr);
conn_info.addr = addr;
conn_info.loop = ev_default_loop(0);
conn_info.local_listen_fd = local_listen_fd;
if(!conn_manager.exist(addr)) // u64_t fec_fd64=conn_info.fec_encode_manager.get_timer_fd64();
{ // mylog(log_debug,"fec_fd64=%llu\n",fec_fd64);
if(conn_manager.mp.size() >=max_conn_num) // ev.events = EPOLLIN;
{ // ev.data.u64 = fec_fd64;
mylog(log_warn,"new connection %s ignored bc max_conn_num exceed\n",addr.get_str()); // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(fec_fd64), &ev);
return;
}
//conn_manager.insert(addr); // fd_manager.get_info(fec_fd64).ip_port=ip_port;
conn_info_t &conn_info=conn_manager.find_insert(addr);
conn_info.addr=addr;
conn_info.loop=ev_default_loop(0);
conn_info.local_listen_fd=local_listen_fd;
//u64_t fec_fd64=conn_info.fec_encode_manager.get_timer_fd64(); conn_info.timer.data = &conn_info;
//mylog(log_debug,"fec_fd64=%llu\n",fec_fd64); ev_init(&conn_info.timer, conn_timer_cb);
//ev.events = EPOLLIN; ev_timer_set(&conn_info.timer, 0, timer_interval / 1000.0);
//ev.data.u64 = fec_fd64; ev_timer_start(loop, &conn_info.timer);
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_manager.to_fd(fec_fd64), &ev);
//fd_manager.get_info(fec_fd64).ip_port=ip_port; // conn_info.timer.add_fd64_to_epoll(epoll_fd);
// conn_info.timer.set_timer_repeat_us(timer_interval*1000);
conn_info.timer.data=&conn_info; // mylog(log_debug,"conn_info.timer.get_timer_fd64()=%llu\n",conn_info.timer.get_timer_fd64());
ev_init(&conn_info.timer,conn_timer_cb);
ev_timer_set(&conn_info.timer, 0, timer_interval/1000.0 );
ev_timer_start(loop,&conn_info.timer);
//conn_info.timer.add_fd64_to_epoll(epoll_fd); // u64_t timer_fd64=conn_info.timer.get_timer_fd64();
//conn_info.timer.set_timer_repeat_us(timer_interval*1000); // fd_manager.get_info(timer_fd64).ip_port=ip_port;
//mylog(log_debug,"conn_info.timer.get_timer_fd64()=%llu\n",conn_info.timer.get_timer_fd64()); conn_info.fec_encode_manager.set_data(&conn_info);
conn_info.fec_encode_manager.set_loop_and_cb(loop, fec_encode_cb);
//u64_t timer_fd64=conn_info.timer.get_timer_fd64(); mylog(log_info, "new connection from %s\n", addr.get_str());
//fd_manager.get_info(timer_fd64).ip_port=ip_port; }
conn_info_t &conn_info = conn_manager.find_insert(addr);
conn_info.update_active_time();
int out_n;
char **out_arr;
int *out_len;
my_time_t *out_delay;
from_fec_to_normal(conn_info, data, data_len, out_n, out_arr, out_len, out_delay);
mylog(log_trace, "out_n= %d\n", out_n);
for (int i = 0; i < out_n; i++) {
u32_t conv;
char *new_data;
int new_len;
if (get_conv(conv, out_arr[i], out_len[i], new_data, new_len) != 0) {
mylog(log_debug, "get_conv failed");
continue;
}
conn_info.fec_encode_manager.set_data(&conn_info); if (!conn_info.conv_manager.s.is_conv_used(conv)) {
conn_info.fec_encode_manager.set_loop_and_cb(loop,fec_encode_cb); if (conn_info.conv_manager.s.get_size() >= max_conv_num) {
mylog(log_warn, "ignored new udp connect bc max_conv_num exceed\n");
continue;
}
int new_udp_fd;
ret = new_connected_socket2(new_udp_fd, remote_addr, out_addr, out_interface);
mylog(log_info,"new connection from %s\n",addr.get_str()); if (ret != 0) {
mylog(log_warn, "[%s]new_connected_socket failed\n", addr.get_str());
continue;
}
} fd64_t fd64 = fd_manager.create(new_udp_fd);
conn_info_t &conn_info=conn_manager.find_insert(addr); // ev.events = EPOLLIN;
// ev.data.u64 = fd64;
// ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_udp_fd, &ev);
conn_info.update_active_time(); conn_info.conv_manager.s.insert_conv(conv, fd64);
int out_n;char **out_arr;int *out_len;my_time_t *out_delay; fd_manager.get_info(fd64).addr = addr;
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); ev_io &io_watcher = fd_manager.get_info(fd64).io_watcher;
for(int i=0;i<out_n;i++) io_watcher.u64 = fd64;
{ io_watcher.data = &conn_info;
u32_t conv;
char *new_data;
int new_len;
if(get_conv(conv,out_arr[i],out_len[i],new_data,new_len)!=0)
{
mylog(log_debug,"get_conv failed");
continue;
}
ev_init(&io_watcher, remote_cb);
ev_io_set(&io_watcher, new_udp_fd, EV_READ);
ev_io_start(conn_info.loop, &io_watcher);
if (!conn_info.conv_manager.s.is_conv_used(conv)) mylog(log_info, "[%s]new conv %x,fd %d created,fd64=%llu\n", addr.get_str(), conv, new_udp_fd, fd64);
{ }
if(conn_info.conv_manager.s.get_size() >=max_conv_num) conn_info.conv_manager.s.update_active_time(conv);
{ fd64_t fd64 = conn_info.conv_manager.s.find_data_by_conv(conv);
mylog(log_warn,"ignored new udp connect bc max_conv_num exceed\n"); dest_t dest;
continue; dest.type = type_fd64;
} dest.inner.fd64 = fd64;
delay_send(out_delay[i], dest, new_data, new_len);
int new_udp_fd; }
ret=new_connected_socket2(new_udp_fd,remote_addr,out_addr,out_interface);
if (ret != 0) {
mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str());
continue;
}
fd64_t fd64 = fd_manager.create(new_udp_fd);
//ev.events = EPOLLIN;
//ev.data.u64 = fd64;
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_udp_fd, &ev);
conn_info.conv_manager.s.insert_conv(conv, fd64);
fd_manager.get_info(fd64).addr=addr;
ev_io &io_watcher=fd_manager.get_info(fd64).io_watcher;
io_watcher.u64=fd64;
io_watcher.data=&conn_info;
ev_init(&io_watcher,remote_cb);
ev_io_set(&io_watcher,new_udp_fd,EV_READ);
ev_io_start(conn_info.loop,&io_watcher);
mylog(log_info,"[%s]new conv %x,fd %d created,fd64=%llu\n",addr.get_str(),conv,new_udp_fd,fd64);
}
conn_info.conv_manager.s.update_active_time(conv);
fd64_t fd64= conn_info.conv_manager.s.find_data_by_conv(conv);
dest_t dest;
dest.type=type_fd64;
dest.inner.fd64=fd64;
delay_send(out_delay[i],dest,new_data,new_len);
}
} }
static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
fd64_t fd64=watcher->u64; fd64_t fd64 = watcher->u64;
data_from_remote_or_fec_timeout_or_conn_timer(conn_info,fd64,is_from_remote); data_from_remote_or_fec_timeout_or_conn_timer(conn_info, fd64, is_from_remote);
} }
static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) static void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
int fifo_fd=watcher->fd; int fifo_fd = watcher->fd;
char buf[buf_len]; char buf[buf_len];
int len=read (fifo_fd, buf, sizeof (buf)); int len = read(fifo_fd, buf, sizeof(buf));
if(len<0) if (len < 0) {
{ mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, get_sock_error());
mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error()); return;
return; }
} buf[len] = 0;
buf[len]=0; handle_command(buf);
handle_command(buf);
} }
static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void delay_manager_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
//uint64_t value; // uint64_t value;
//read(delay_manager.get_timer_fd(), &value, 8); // read(delay_manager.get_timer_fd(), &value, 8);
//mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n"); // mylog(log_trace,"events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()\n");
//do nothing
// do nothing
} }
static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void fec_encode_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
data_from_remote_or_fec_timeout_or_conn_timer(conn_info,0,is_fec_timeout); data_from_remote_or_fec_timeout_or_conn_timer(conn_info, 0, is_fec_timeout);
} }
static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void conn_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
conn_info_t & conn_info= *((conn_info_t*)watcher->data); conn_info_t &conn_info = *((conn_info_t *)watcher->data);
data_from_remote_or_fec_timeout_or_conn_timer(conn_info,0,is_conn_timer); data_from_remote_or_fec_timeout_or_conn_timer(conn_info, 0, is_conn_timer);
} }
static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) static void prepare_cb(struct ev_loop *loop, struct ev_prepare *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
delay_manager.check(); delay_manager.check();
} }
static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) static void global_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
{ assert(!(revents & EV_ERROR));
assert(!(revents&EV_ERROR));
//uint64_t value; // uint64_t value;
//read(timer.get_timer_fd(), &value, 8); // read(timer.get_timer_fd(), &value, 8);
conn_manager.clear_inactive(); conn_manager.clear_inactive();
mylog(log_trace,"events[idx].data.u64==(u64_t)timer.get_timer_fd()\n"); mylog(log_trace, "events[idx].data.u64==(u64_t)timer.get_timer_fd()\n");
} }
int tunnel_server_event_loop() int tunnel_server_event_loop() {
{ int i, j, k;
int ret;
int yes = 1;
// int epoll_fd;
// int remote_fd;
int i, j, k;int ret; int local_listen_fd;
int yes = 1; new_listen_socket2(local_listen_fd, local_addr);
//int epoll_fd;
//int remote_fd;
int local_listen_fd; // epoll_fd = epoll_create1(0);
new_listen_socket2(local_listen_fd,local_addr); // assert(epoll_fd>0);
//epoll_fd = epoll_create1(0); // const int max_events = 4096;
//assert(epoll_fd>0); // struct epoll_event ev, events[max_events];
// if (epoll_fd < 0) {
// mylog(log_fatal,"epoll return %d\n", epoll_fd);
// myexit(-1);
// }
//const int max_events = 4096; struct ev_loop *loop = ev_default_loop(0);
//struct epoll_event ev, events[max_events]; assert(loop != NULL);
//if (epoll_fd < 0) {
// mylog(log_fatal,"epoll return %d\n", epoll_fd);
// myexit(-1);
//}
struct ev_loop * loop= ev_default_loop(0); // ev.events = EPOLLIN;
assert(loop != NULL); // ev.data.u64 = local_listen_fd;
// ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev);
//ev.events = EPOLLIN; // if (ret!=0) {
//ev.data.u64 = local_listen_fd; // mylog(log_fatal,"add udp_listen_fd error\n");
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, local_listen_fd, &ev); // myexit(-1);
//if (ret!=0) { // }
// mylog(log_fatal,"add udp_listen_fd error\n"); struct ev_io local_listen_watcher;
// myexit(-1);
//}
struct ev_io local_listen_watcher;
ev_io_init(&local_listen_watcher, local_listen_cb, local_listen_fd, EV_READ); ev_io_init(&local_listen_watcher, local_listen_cb, local_listen_fd, EV_READ);
ev_io_start(loop, &local_listen_watcher); ev_io_start(loop, &local_listen_watcher);
//ev.events = EPOLLIN; // ev.events = EPOLLIN;
//ev.data.u64 = delay_manager.get_timer_fd(); // ev.data.u64 = delay_manager.get_timer_fd();
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev); // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, delay_manager.get_timer_fd(), &ev);
//if (ret!= 0) { // if (ret!= 0) {
// mylog(log_fatal,"add delay_manager.get_timer_fd() error\n"); // mylog(log_fatal,"add delay_manager.get_timer_fd() error\n");
// myexit(-1); // myexit(-1);
//} // }
delay_manager.set_loop_and_cb(loop,delay_manager_cb); delay_manager.set_loop_and_cb(loop, delay_manager_cb);
//mylog(log_debug," delay_manager.get_timer_fd() =%d\n", delay_manager.get_timer_fd()); // mylog(log_debug," delay_manager.get_timer_fd() =%d\n", delay_manager.get_timer_fd());
mylog(log_info,"now listening at %s\n",local_addr.get_str()); mylog(log_info, "now listening at %s\n", local_addr.get_str());
//my_timer_t timer; // my_timer_t timer;
//timer.add_fd_to_epoll(epoll_fd); // timer.add_fd_to_epoll(epoll_fd);
//timer.set_timer_repeat_us(timer_interval*1000); // timer.set_timer_repeat_us(timer_interval*1000);
ev_timer global_timer; ev_timer global_timer;
ev_init(&global_timer,global_timer_cb); ev_init(&global_timer, global_timer_cb);
ev_timer_set(&global_timer, 0, timer_interval/1000.0 ); ev_timer_set(&global_timer, 0, timer_interval / 1000.0);
ev_timer_start(loop,&global_timer); ev_timer_start(loop, &global_timer);
//mylog(log_debug," timer.get_timer_fd() =%d\n",timer.get_timer_fd()); // mylog(log_debug," timer.get_timer_fd() =%d\n",timer.get_timer_fd());
struct ev_io fifo_watcher; struct ev_io fifo_watcher;
int fifo_fd=-1; int fifo_fd = -1;
if(fifo_file[0]!=0) if (fifo_file[0] != 0) {
{ fifo_fd = create_fifo(fifo_file);
fifo_fd=create_fifo(fifo_file); // ev.events = EPOLLIN;
//ev.events = EPOLLIN; // ev.data.u64 = fifo_fd;
//ev.data.u64 = fifo_fd;
//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev); // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fifo_fd, &ev);
//if (ret!= 0) { // if (ret!= 0) {
//mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); // mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno));
//myexit(-1); // myexit(-1);
//} //}
ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ);
ev_io_start(loop, &fifo_watcher); ev_io_start(loop, &fifo_watcher);
mylog(log_info,"fifo_file=%s\n",fifo_file); mylog(log_info, "fifo_file=%s\n", fifo_file);
} }
ev_prepare prepare_watcher; ev_prepare prepare_watcher;
ev_init(&prepare_watcher,prepare_cb); ev_init(&prepare_watcher, prepare_cb);
ev_prepare_start(loop,&prepare_watcher); ev_prepare_start(loop, &prepare_watcher);
ev_run(loop, 0);
mylog(log_warn, "ev_run returned\n");
myexit(0);
/*
while(1)////////////////////////
{
if(about_to_exit) myexit(0);
int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000);
if (nfds < 0) { //allow zero
if(errno==EINTR )
{
mylog(log_info,"epoll interrupted by signal,continue\n");
}
else
{
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
myexit(-1);
}
}
int idx;
for (idx = 0; idx < nfds; ++idx)
{
if(events[idx].data.u64==(u64_t)timer.get_timer_fd())
{
}
else if (events[idx].data.u64 == (u64_t)fifo_fd)
{
}
else if (events[idx].data.u64 == (u64_t)local_listen_fd)
{
ev_run(loop, 0); }
else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) {
mylog(log_warn,"ev_run returned\n"); }
myexit(0); else if (events[idx].data.u64 >u32_t(-1))
{
/*
while(1)////////////////////////
{
if(about_to_exit) myexit(0);
int nfds = epoll_wait(epoll_fd, events, max_events, 180 * 1000);
if (nfds < 0) { //allow zero
if(errno==EINTR )
{
mylog(log_info,"epoll interrupted by signal,continue\n");
}
else
{
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
myexit(-1);
}
}
int idx;
for (idx = 0; idx < nfds; ++idx)
{
if(events[idx].data.u64==(u64_t)timer.get_timer_fd())
{
}
else if (events[idx].data.u64 == (u64_t)fifo_fd)
{
}
else if (events[idx].data.u64 == (u64_t)local_listen_fd)
{
} }
else if (events[idx].data.u64 == (u64_t)delay_manager.get_timer_fd()) { else
{
mylog(log_fatal,"unknown fd,this should never happen\n");
myexit(-1);
}
}
} }*/
else if (events[idx].data.u64 >u32_t(-1))
{
}
else
{
mylog(log_fatal,"unknown fd,this should never happen\n");
myexit(-1);
}
}
}*/
return 0;
return 0;
} }