13 Commits

Author SHA1 Message Date
wangyu
7d349251d0 update 2020-07-14 01:33:59 -04:00
wangyu
0c941e5dbd add target release2 2020-07-14 00:10:32 -04:00
wangyu
55606b63f9 refactor --bind and --interface, fix --key 2020-07-13 22:23:17 -04:00
wangyu-
5bb65af72c Merge pull request #227 from Llorx/branch_libev
Bind to address
2020-07-13 21:12:14 -04:00
wangyu
fbe6c2a308 support cross compile for win and mac 2020-07-13 12:51:49 -04:00
llorx
b270199031 Error reporting 2019-11-05 00:04:02 +01:00
llorx
c6b0c3e5bc Small condition merge 2019-11-04 23:44:22 +01:00
llorx
939b347129 Bind to interface
Allow binding to interface instead of IP with SO_BINDTODEVICE.
2019-11-04 23:26:11 +01:00
llorx
79dccfd697 Bind to address
Allow binding to address before sending UDP packets.
2019-11-04 22:46:41 +01:00
root
ecc90928d3 some useless change 2019-04-08 07:48:11 -04:00
root
f7c2d15adc Merge branch 'branch_libev' of https://github.com/wangyu-/UDPspeeder into branch_libev 2019-04-08 07:31:18 -04:00
root
cacf0bcfcb fix clock goes backward, simpilify timer, hopefully it works 2019-04-08 07:31:13 -04:00
wangyu-
bf818a04a8 improved log for fec_done 2019-01-21 05:57:42 -06:00
13 changed files with 164 additions and 84 deletions

View File

@@ -495,25 +495,31 @@ u64_t get_current_time_us()
return (uint64_t(tmp_time.tv_sec))*1000llu*1000llu+ (uint64_t(tmp_time.tv_nsec))/1000llu;
}*/
u64_t get_current_time()//ms
{
//timespec tmp_time;
//clock_gettime(CLOCK_MONOTONIC, &tmp_time);
//return ((u64_t)tmp_time.tv_sec)*1000llu+((u64_t)tmp_time.tv_nsec)/(1000*1000llu);
return (u64_t)(ev_time()*1000);
}
u64_t get_current_time_rough()//ms
{
return (u64_t)(ev_now(ev_default_loop(0))*1000);
}
u64_t get_current_time_us()
{
//timespec tmp_time;
//clock_gettime(CLOCK_MONOTONIC, &tmp_time);
//return (uint64_t(tmp_time.tv_sec))*1000llu*1000llu+ (uint64_t(tmp_time.tv_nsec))/1000llu;
return (u64_t)(ev_time()*1000*1000);
static u64_t value_fix=0;
static u64_t largest_value=0;
u64_t raw_value=(u64_t)(ev_time()*1000*1000);
u64_t fixed_value=raw_value+value_fix;
if(fixed_value< largest_value)
{
value_fix+= largest_value- fixed_value;
}
else
{
largest_value=fixed_value;
}
//printf("<%lld,%lld,%lld>\n",raw_value,value_fix,raw_value + value_fix);
return raw_value + value_fix; //new fixed value
}
u64_t get_current_time()
{
return get_current_time_us()/1000lu;
}
u64_t pack_u64(u32_t a,u32_t b)
@@ -947,7 +953,7 @@ int new_listen_socket2(int &fd,address_t &addr)
int yes = 1;
if (::bind(fd, (struct sockaddr*) &addr.inner, addr.get_len()) == -1) {
mylog(log_fatal,"socket bind error\n");
mylog(log_fatal,"socket bind error=%s\n",get_sock_error());
//perror("socket bind error");
myexit(1);
}
@@ -958,13 +964,28 @@ int new_listen_socket2(int &fd,address_t &addr)
return 0;
}
int new_connected_socket2(int &fd,address_t &addr)
int new_connected_socket2(int &fd,address_t &addr,address_t *bind_addr,char * interface_string)
{
fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str());
return -1;
}
if (bind_addr && ::bind(fd, (struct sockaddr*) &bind_addr->inner, bind_addr->get_len()) == -1) {
mylog(log_fatal,"socket bind error=%s\n", get_sock_error());
//perror("socket bind error");
myexit(1);
}
#ifdef __linux__
if (interface_string && ::setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_string, strlen(interface_string)) < 0) {
mylog(log_fatal,"socket interface bind error=%s\n", get_sock_error());
//perror("socket bind error");
myexit(1);
}
#endif
setnonblocking(fd);
set_buf_size(fd, socket_buf_size);

View File

@@ -32,11 +32,16 @@
//#include <net/if.h>
#include <stdarg.h>
#include <assert.h>
#if !defined(NO_LIBEV_EMBED)
#include <my_ev.h>
#else
#include "ev.h"
#endif
#if defined(__MINGW32__)
#include <winsock2.h>
#include <Ws2tcpip.h >
#include <ws2tcpip.h>
typedef int socklen_t;
#else
#include <sys/socket.h>
@@ -386,7 +391,7 @@ struct fd_info_t
};
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);
@@ -446,7 +451,7 @@ int new_listen_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);
int new_connected_socket2(int &fd,address_t &addr,address_t *bind_addr,char *out_interface);
struct not_copy_able_t
{

View File

@@ -22,7 +22,7 @@ void server_clear_function(u64_t u64)//used in conv_manager in server mode.for s
address_t &addr=fd_manager.get_info(fd64).addr;//
assert(conn_manager.exist(addr));//
ev_loop *loop =conn_manager.find_insert(addr).loop; // overkill ? should we just use ev_default_loop(0)?
struct ev_loop *loop =conn_manager.find_insert(addr).loop; // overkill ? should we just use ev_default_loop(0)?
ev_io_stop(loop,&watcher);

View File

@@ -295,7 +295,7 @@ struct conn_info_t:not_copy_able_t //stores info for a raw connection.for cl
u64_t last_active_time;
stat_t stat;
ev_loop* loop=0;
struct ev_loop* loop=0;
int local_listen_fd;
int remote_fd; //only used for client

View File

@@ -116,14 +116,11 @@ int delay_manager_t::check()
}
if(!delay_mp.empty())
{
//itimerspec its;
//memset(&its.it_interval,0,sizeof(its.it_interval));
//its.it_value.tv_sec=delay_mp.begin()->first/1000000llu;
//its.it_value.tv_nsec=(delay_mp.begin()->first%1000000llu)*1000llu;
//timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0);
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, delay_mp.begin()->first /1000000.0 - ev_now(loop),0 ); //we should use ev_now here.
ev_timer_set(&timer, timer_value,0 );
ev_timer_start(loop, &timer);
}
else

View File

@@ -184,19 +184,13 @@ int fec_encode_manager_t::append(char *s,int len/*,int &is_first_packet*/)
{
if(counter==0)
{
my_itimerspec its;
memset(&its.it_interval,0,sizeof(its.it_interval));
first_packet_time=get_current_time_us();
my_time_t tmp_time=fec_par.timeout+first_packet_time;
its.it_value.tv_sec=tmp_time/1000000llu;
its.it_value.tv_nsec=(tmp_time%1000000llu)*1000llu;
//timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0);
const double m=1000*1000;
ev_timer_stop(loop, &timer);
ev_timer_set(&timer, tmp_time/1000000.0 - ev_now(loop) ,0 ); //we should use ev_now here.
ev_timer_set(&timer, fec_par.timeout/m,0 );
ev_timer_start(loop, &timer);
//ev_timer_set(loop,)
}
if(fec_par.mode==0)//for type 0 use blob
{
@@ -596,7 +590,7 @@ int fec_decode_manager_t::input(char *s,int len)
if(mp[seq].fec_done!=0)
{
mylog(log_debug,"fec already done, ignore\n");
mylog(log_debug,"fec already done, ignore, seq=%u\n",seq);
return -1;
}

View File

@@ -239,7 +239,7 @@ struct anti_replay_t
}
replay_buffer[index]=seq;
assert(mp.find(seq)==mp.end());
mp[seq].my_time=get_current_time_rough();
mp[seq].my_time=get_current_time();
mp[seq].index=index;
index++;
if(index==int(anti_replay_buff_size)) index=0;
@@ -248,7 +248,7 @@ struct anti_replay_t
{
if(mp.find(seq)==mp.end()) return 1;
if(get_current_time_rough()-mp[seq].my_time>anti_replay_timeout)
if(get_current_time()-mp[seq].my_time>anti_replay_timeout)
{
replay_buffer[mp[seq].index]=u64_t(i64_t(-1));
mp.erase(seq);

View File

@@ -66,6 +66,10 @@ static void print_help()
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");
printf(" --out-addr ip:port force all output packets of '-r' end to go through this address, port 0 for random port.\n");
#ifdef __linux__
printf(" --out-interface <string> force all output packets of '-r' end to go through this interface.\n");
#endif
printf("log and help options:\n");
printf(" --log-level <number> 0: never 1: fatal 2: error 3: warn \n");
printf(" 4: info (default) 5: debug 6: trace\n");

109
makefile
View File

@@ -1,40 +1,66 @@
cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
cc_local=g++
#cc_mips34kc=/toolchains/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
cc_mips24kc_be=/toolchains/lede-sdk-17.01.2-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/bin/mips-openwrt-linux-musl-g++
cc_mips24kc_le=/toolchains/lede-sdk-17.01.2-ramips-mt7621_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-5.4.0_musl-1.1.16/bin/mipsel-openwrt-linux-musl-g++
#cc_arm= /toolchains/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ -march=armv6 -marm
cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++
cc_mingw_cross=i686-w64-mingw32-g++-posix
cc_mac_cross=o64-clang++ -stdlib=libc++
#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
SOURCES=${SOURCES0} my_ev.cpp -isystem libev
NAME=speederv2
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers ${OPT}
SOURCES=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 -isystem libev
NAME=speederv2
TARGETS=amd64 arm mips24kc_be x86 mips24kc_le
TAR=${NAME}_binaries.tar.gz `echo ${TARGETS}|sed -r 's/([^ ]+)/speederv2_\1/g'` version.txt
TAR=${NAME}_binaries.tar.gz `echo ${TARGETS}|sed -r 's/([^ ]+)/${NAME}_\1/g'` version.txt
export STAGING_DIR=/tmp/ #just for supress warning of staging_dir not define
# targets for nativei (non-cross) compile
all:git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O3
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O2
freebsd:git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O3
cygwin:git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O3 -D_GNU_SOURCE
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O2
mingw:git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -ggdb -static -O2 -lws2_32
mingw_wepoll:git_version #to compile you need a pacthed version of libev with wepoll backend
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES0} ${FLAGS} -ggdb -static -O2 -DNO_LIBEV_EMBED -D_WIN32 -lev -lws2_32
mac:git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -ggdb -O3
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -ggdb -O2
cygwin:git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O2 -D_GNU_SOURCE
#targes for general cross compile
cross:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O2
cross2:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O2
cross3:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O2
#targets only for debug purpose
fast: git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb
debug: git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
@@ -42,45 +68,50 @@ debug2: git_version
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -ggdb
mips24kc_be: git_version
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
#targets only for 'make release'
mips24kc_be_debug: git_version
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -ggdb
mips24kc_be: git_version
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O2
mips24kc_le: git_version
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O2
amd64:git_version
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
amd64_debug:git_version
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -ggdb
x86:git_version
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O2
x86:git_version #to build this you need 'g++-multilib' installed
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O2 -m32
arm:git_version
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O2 -ggdb
arm_debug:git_version
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -ggdb
cross:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
cross2:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
cross3:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
release: ${TARGETS}
release: ${TARGETS}
cp git_version.h version.txt
tar -zcvf ${TAR}
#targets for cross compile windows targets on linux
mingw_cross:git_version #to build this and the below one you need 'mingw-w64' installed (the cross compile version on linux)
${cc_mingw_cross} -o ${NAME}.exe -I. ${SOURCES} ${FLAGS} -ggdb -static -O2 -lws2_32
mingw_cross_wepoll:git_version #to compile you need a pacthed version of libev with wepoll backend installed
${cc_mingw_cross} -o ${NAME}_wepoll.exe -I. ${SOURCES0} ${FLAGS} -ggdb -static -O2 -DNO_LIBEV_EMBED -D_WIN32 -lev -lws2_32
#targets for cross compile macos targets on linux
mac_cross:git_version #need to install 'osxcross' first.
${cc_mac_cross} -o ${NAME}_mac -I. ${SOURCES} ${FLAGS} -ggdb -O2
#release2 includes all binary in 'release' plus win and mac cross compile targets
release2: ${TARGETS} mingw_cross mingw_cross_wepoll mac_cross
cp git_version.h version.txt
tar -zcvf ${TAR} ${NAME}.exe ${NAME}_wepoll.exe ${NAME}_mac
clean:
rm -f ${TAR}
rm -f speeder speeder_cross
rm -f ${NAME} ${NAME}_cross ${NAME}.exe ${NAME}_wepoll.exe ${NAME}_mac
rm -f git_version.h
git_version:
echo "const char * const gitversion = \"$(shell git rev-parse HEAD)\";" > git_version.h
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > git_version.h

View File

@@ -28,7 +28,10 @@ int output_interval_max=0*1000;
int fix_latency=0;
address_t local_addr,remote_addr;
address_t *out_addr=0;
char *out_interface=0;
//u32_t local_ip_uint32,remote_ip_uint32=0;
//char local_ip[100], remote_ip[100];
//int local_port = -1, remote_port = -1;
@@ -654,6 +657,9 @@ void process_arg(int argc, char *argv[])
{"queue-len", required_argument, 0,'q'},
{"fec", required_argument, 0,'f'},
{"jitter", required_argument, 0,'j'},
{"out-addr", required_argument, 0,1},
{"out-interface", required_argument, 0, 1},
{"key", required_argument, 0,'k'},
{"header-overhead", required_argument, 0, 1},
//{"debug-fec", no_argument, 0, 1},
{"debug-fec-enc", no_argument, 0, 1},
@@ -944,6 +950,24 @@ void process_arg(int argc, char *argv[])
myexit(-1);
}
}
else if(strcmp(long_options[option_index].name,"out-addr")==0)
{
//has_b = true;
mylog(log_debug,"out-addr=%s\n",optarg);
out_addr=new address_t();
out_addr->from_str(optarg);
}
else if(strcmp(long_options[option_index].name,"out-interface")==0)
{
out_interface=new char[strlen(optarg)+10];
sscanf(optarg,"%s\n",out_interface);
mylog(log_debug,"out-interface=%s\n",out_interface);
if(strlen(out_interface)==0)
{
mylog(log_fatal,"out_interface string len=0??\n");
myexit(-1);
}
}
else if(strcmp(long_options[option_index].name,"timeout")==0)
{
sscanf(optarg,"%d",&g_fec_par.timeout);

4
misc.h
View File

@@ -39,8 +39,12 @@ extern int fix_latency;
//extern char local_ip[100], remote_ip[100];
//extern int local_port, remote_port;
extern address_t local_addr,remote_addr;
extern address_t *out_addr;
extern char *out_interface;
extern conn_manager_t conn_manager;
extern delay_manager_t delay_manager;
extern fd_manager_t fd_manager;

View File

@@ -295,7 +295,7 @@ int tunnel_client_event_loop()
int & remote_fd=conn_info.remote_fd;
fd64_t &remote_fd64=conn_info.remote_fd64;
assert(new_connected_socket2(remote_fd,remote_addr)==0);
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);

View File

@@ -232,7 +232,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
}
int new_udp_fd;
ret=new_connected_socket2(new_udp_fd,remote_addr);
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());