19 Commits

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

4
.clang-format Normal file
View File

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

35
CMakeLists.txt Normal file
View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

405
common.h
View File

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

View File

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

View File

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

1245
crc32/Crc32.cpp Normal file

File diff suppressed because it is too large Load Diff

69
crc32/Crc32.h Normal file
View File

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

10
crc32/LICENSE Normal file
View File

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

View File

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

View File

@@ -12,7 +12,7 @@
#include "packet.h"
#include "log.h"
//enum delay_type_t {none=0,enum_sendto_u64,enum_send_fd,client_to_local,client_to_remote,server_to_local,server_to_remote};
// enum delay_type_t {none=0,enum_sendto_u64,enum_send_fd,client_to_local,client_to_remote,server_to_local,server_to_remote};
/*
struct fd_ip_port_t
@@ -103,41 +103,39 @@ struct my_timer_t
}
};*/
struct delay_data_t
{
struct delay_data_t {
dest_t dest;
//int left_time;//
char * data;
// int left_time;//
char *data;
int len;
int handle();
};
struct delay_manager_t
{
struct delay_manager_t {
ev_timer timer;
struct ev_loop *loop=0;
void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents)=0;
struct ev_loop *loop = 0;
void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents) = 0;
//int timer_fd;
// int timer_fd;
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 &b)
{
assert(0==1);
delay_manager_t(delay_manager_t &b) {
assert(0 == 1);
}
void set_loop_and_cb(struct ev_loop *loop,void (*cb) (struct ev_loop *loop, struct ev_timer *watcher, int revents))
{
this->loop=loop;
this->cb=cb;
ev_init(&timer,cb);
void set_loop_and_cb(struct ev_loop *loop, void (*cb)(struct ev_loop *loop, struct ev_timer *watcher, int revents)) {
this->loop = loop;
this->cb = cb;
ev_init(&timer, cb);
}
int set_capacity(int a) {
capacity = a;
return 0;
}
int set_capacity(int a){capacity=a;return 0;}
~delay_manager_t();
ev_timer& get_timer();
ev_timer &get_timer();
int check();
int add(my_time_t delay,const dest_t &dest,char *data,int len);
int add(my_time_t delay, const dest_t &dest, char *data, int len);
};
#endif /* DELAY_MANAGER_H_ */

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -20,8 +20,7 @@
//
// info:
// 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:
// 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:
// 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.
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);
int rs_decode(void *code, char *data[], int size);
void rs_encode2(int k, int n, char *data[], int size);
int rs_decode2(int k, int n, char *data[], int size);
#endif /* LIB_RS_H_ */

54
log.cpp Executable file → Normal file
View File

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

44
log.h Executable file → Normal file
View File

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

View File

@@ -13,15 +13,13 @@
#include "git_version.h"
using namespace std;
static void print_help()
{
char git_version_buf[100]={0};
strncpy(git_version_buf,gitversion,10);
static void print_help() {
char git_version_buf[100] = {0};
strncpy(git_version_buf, gitversion, 10);
printf("UDPspeeder V2\n");
printf("git version: %s ",git_version_buf);
printf("build date: %s %s\n",__DATE__,__TIME__);
printf("git version: %s ", git_version_buf);
printf("build date: %s %s\n", __DATE__, __TIME__);
printf("repository: https://github.com/wangyu-/UDPspeeder\n");
printf("\n");
printf("usage:\n");
@@ -51,7 +49,7 @@ static void print_help()
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(" --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");
@@ -62,7 +60,7 @@ static void print_help()
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(" --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(" --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");
@@ -77,42 +75,35 @@ static void print_help()
printf(" --disable-color disable log color\n");
printf(" -h,--help print this help message\n");
//printf("common options,these options must be same on both side\n");
// printf("common options,these options must be same on both side\n");
}
void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents)
{
void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) {
mylog(log_info, "got sigpipe, ignored");
}
void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents)
{
void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) {
mylog(log_info, "got sigterm, exit");
myexit(0);
}
void sigint_cb(struct ev_loop *l, ev_signal *w, int revents)
{
void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) {
mylog(log_info, "got sigint, exit");
myexit(0);
}
int main(int argc, char *argv[])
{
working_mode=tunnel_mode;
int main(int argc, char *argv[]) {
working_mode = tunnel_mode;
init_ws();
//unit_test();
// unit_test();
struct ev_loop* loop=ev_default_loop(0);
struct ev_loop *loop = ev_default_loop(0);
#if !defined(__MINGW32__)
ev_signal signal_watcher_sigpipe;
ev_signal_init(&signal_watcher_sigpipe, sigpipe_cb, SIGPIPE);
ev_signal_start(loop, &signal_watcher_sigpipe);
#else
enable_log_color=0;
enable_log_color = 0;
#endif
ev_signal signal_watcher_sigterm;
@@ -123,47 +114,39 @@ int main(int argc, char *argv[])
ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT);
ev_signal_start(loop, &signal_watcher_sigint);
assert(sizeof(u64_t)==8);
assert(sizeof(i64_t)==8);
assert(sizeof(u32_t)==4);
assert(sizeof(i32_t)==4);
assert(sizeof(u16_t)==2);
assert(sizeof(i16_t)==2);
dup2(1, 2); //redirect stderr to stdout
assert(sizeof(u64_t) == 8);
assert(sizeof(i64_t) == 8);
assert(sizeof(u32_t) == 4);
assert(sizeof(i32_t) == 4);
assert(sizeof(u16_t) == 2);
assert(sizeof(i16_t) == 2);
dup2(1, 2); // redirect stderr to stdout
int i, j, k;
if (argc == 1)
{
if (argc == 1) {
print_help();
myexit( -1);
myexit(-1);
}
for (i = 0; i < argc; i++)
{
if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0)
{
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
print_help();
myexit(0);
}
}
process_arg(argc,argv);
process_arg(argc, argv);
delay_manager.set_capacity(delay_capacity);
if(strlen(tun_dev)==0)
{
sprintf(tun_dev,"tun%u",get_fake_random_number()%1000);
if (strlen(tun_dev) == 0) {
sprintf(tun_dev, "tun%u", get_fake_random_number() % 1000);
}
if(program_mode==client_mode)
{
if (program_mode == client_mode) {
tunnel_client_event_loop();
}
else
{
} else {
tunnel_server_event_loop();
}
return 0;
}

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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