mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-09-16 04:04:27 +08:00
Compare commits
14 Commits
df4c9f1b3f
...
modify
Author | SHA1 | Date | |
---|---|---|---|
|
ab103ec470 | ||
|
3ac43ee66e | ||
|
6b74695184 | ||
|
3e56cebbcd | ||
|
e325a5b6f2 | ||
|
1a3fa9e4fd | ||
|
2836daefc4 | ||
|
5eecdb76b3 | ||
|
9d3d8c9080 | ||
|
7125ccfbef | ||
|
f12896284e | ||
|
02078aeb4d | ||
|
654150f5d7 | ||
|
541330ce51 |
@@ -1,4 +0,0 @@
|
||||
SortIncludes: false
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 0
|
||||
IndentWidth: 4
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/udp2raw*
|
@@ -1,35 +0,0 @@
|
||||
#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(udp2raw)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(SOURCE_FILES
|
||||
main.cpp
|
||||
lib/md5.cpp
|
||||
lib/pbkdf2-sha1.cpp
|
||||
lib/pbkdf2-sha256.cpp
|
||||
encrypt.cpp
|
||||
log.cpp
|
||||
network.cpp
|
||||
common.cpp
|
||||
connection.cpp
|
||||
misc.cpp
|
||||
fd_manager.cpp
|
||||
client.cpp
|
||||
server.cpp
|
||||
lib/aes_faster_c/aes.cpp
|
||||
lib/aes_faster_c/wrapper.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")
|
||||
|
||||
add_executable(udp2raw ${SOURCE_FILES})
|
||||
target_link_libraries(udp2raw rt)
|
||||
target_link_libraries(udp2raw pthread)
|
||||
include_directories(SYSTEM "libev")
|
||||
include_directories(".")
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM alpine:3.6 as builder
|
||||
|
||||
WORKDIR /
|
||||
|
||||
RUN apk add --no-cache git build-base linux-headers && \
|
||||
git clone https://github.com/wangyu-/udp2raw-tunnel.git && \
|
||||
cd udp2raw-tunnel && \
|
||||
make dynamic
|
||||
|
||||
FROM alpine:3.6
|
||||
RUN apk add --no-cache libstdc++ iptables
|
||||
COPY --from=builder /udp2raw-tunnel/udp2raw_dynamic /bin/
|
||||
ENTRYPOINT [ "/bin/udp2raw_dynamic" ]
|
@@ -1 +1,6 @@
|
||||
English Only.
|
||||
For English speaking user:
|
||||
https://github.com/wangyu-/UDPspeeder/wiki/Issue-Guide
|
||||
|
||||
中文用户请看:
|
||||
https://github.com/wangyu-/UDPspeeder/wiki/发Issue前请看
|
||||
(否则Issue可能被忽略,或被直接关掉)
|
||||
|
@@ -14,7 +14,7 @@ or
|
||||
|
||||
[udp2raw wiki](https://github.com/wangyu-/udp2raw-tunnel/wiki)
|
||||
|
||||
[简体中文](/doc/README.zh-cn.md)
|
||||
[简体中文](/doc/README.zh-cn.md)(内容更丰富)
|
||||
|
||||
|
||||
# Support Platforms
|
||||
@@ -26,7 +26,7 @@ For Windows and MacOS users, use the udp2raw in [this repo](https://github.com/w
|
||||
### Send/Receive UDP Packets with ICMP/FakeTCP/UDP headers
|
||||
ICMP/FakeTCP headers help you bypass UDP blocking, UDP QOS or improper UDP NAT behavior on some ISPs. In ICMP header mode,udp2raw works like an ICMP tunnel.
|
||||
|
||||
UDP headers are also supported. In UDP header mode, it behaves just like a normal UDP tunnel, and you can just make use of the other features (such as encryption, anti-replay, or connection stabilization).
|
||||
UDP headers are also supported. In UDP header mode, it behaves just like a normal UDP tunnel, and you can just make use of the other features (such as encryption, anti-replay, or connection stalization).
|
||||
|
||||
### Simulated TCP with Real-time/Out-of-Order Delivery
|
||||
In FakeTCP header mode,udp2raw simulates 3-way handshake while establishing a connection,simulates seq and ack_seq while data transferring. It also simulates a few TCP options such as: `MSS`, `sackOk`, `TS`, `TS_ack`, `wscale`. Firewalls will regard FakeTCP as a TCP connection, but its essentially UDP: it supports real-time/out-of-order delivery(just as normal UDP does), no congestion control or re-transmission. So there wont be any TCP over TCP problem when using OpenVPN.
|
||||
@@ -38,7 +38,7 @@ In FakeTCP header mode,udp2raw simulates 3-way handshake while establishing a co
|
||||
|
||||
[Notes on encryption](https://github.com/wangyu-/udp2raw-tunnel/wiki/Notes-on-encryption)
|
||||
|
||||
### Failure Dectection & Stabilization (Connection Recovery)
|
||||
### Failure Dectection & Stablization (Connection Recovery)
|
||||
Conection failures are detected by heartbeats. If timed-out, client will automatically change port number and reconnect. If reconnection is successful, the previous connection will be recovered, and all existing UDP conversations will stay vaild.
|
||||
|
||||
For example, if you use udp2raw + OpenVPN, OpenVPN won't lose connection after any reconnect, **even if network cable is re-plugged or WiFi access point is changed**.
|
||||
@@ -83,7 +83,7 @@ Now,an encrypted raw tunnel has been established between client and server throu
|
||||
### Note
|
||||
To run on Android, check [Android_Guide](/doc/android_guide.md)
|
||||
|
||||
`-a` option automatically adds an iptables rule (or a few iptables rules) for you, udp2raw relies on this iptables rule to work stably. Be aware you dont forget `-a` (its a common mistake). If you dont want udp2raw to add iptables rule automatically, you can add it manually(take a look at `-g` option) and omit `-a`.
|
||||
`-a` option automatically adds an iptables rule (or a few iptables rules) for you, udp2raw relys on this iptables rule to work stably. Be aware you dont forget `-a` (its a common mistake). If you dont want udp2raw to add iptables rule automatically, you can add it manually(take a look at `-g` option) and omit `-a`.
|
||||
|
||||
|
||||
# Advanced Topic
|
||||
|
452
client.cpp
452
client.cpp
@@ -14,6 +14,7 @@ u64_t laste_detect_time = 0;
|
||||
int use_udp_for_detection=0;
|
||||
int use_tcp_for_detection=1;
|
||||
|
||||
|
||||
extern pcap_t *pcap_handle;
|
||||
|
||||
extern int pcap_captured_full_len;
|
||||
@@ -33,10 +34,15 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
|
||||
#ifdef UDP2RAW_MP
|
||||
//mylog(log_debug,"pcap cnt :%d\n",pcap_cnt);
|
||||
if (send_with_pcap && !pcap_header_captured) {
|
||||
if (get_current_time() - laste_detect_time > detect_interval) {
|
||||
if(send_with_pcap&&!pcap_header_captured)
|
||||
{
|
||||
|
||||
if(get_current_time()-laste_detect_time>detect_interval)
|
||||
{
|
||||
laste_detect_time=get_current_time();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
@@ -51,9 +57,11 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
address_t tmp_addr=remote_addr;
|
||||
tmp_addr.set_port(port);
|
||||
|
||||
if (use_udp_for_detection) {
|
||||
if(use_udp_for_detection)
|
||||
{
|
||||
int new_udp_fd=socket(tmp_addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (new_udp_fd < 0) {
|
||||
if(new_udp_fd<0)
|
||||
{
|
||||
mylog(log_warn,"create new_udp_fd error\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -61,17 +69,20 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
u64_t tmp=get_true_random_number();
|
||||
|
||||
int ret=sendto(new_udp_fd,(char*)(&tmp),sizeof(tmp),0,(struct sockaddr *)&tmp_addr.inner,tmp_addr.get_len());
|
||||
if (ret == -1) {
|
||||
if(ret==-1)
|
||||
{
|
||||
mylog(log_warn,"sendto() failed\n");
|
||||
}
|
||||
sock_close(new_udp_fd);
|
||||
}
|
||||
|
||||
if (use_tcp_for_detection) {
|
||||
if(use_tcp_for_detection)
|
||||
{
|
||||
static int last_tcp_fd=-1;
|
||||
|
||||
int new_tcp_fd=socket(tmp_addr.get_type(), SOCK_STREAM, IPPROTO_TCP);
|
||||
if (new_tcp_fd < 0) {
|
||||
if(new_tcp_fd<0)
|
||||
{
|
||||
mylog(log_warn,"create new_tcp_fd error\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -83,24 +94,29 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
//close(new_tcp_fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
mylog(log_info,"waiting for a use-able packet to be captured\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (raw_info.disabled) {
|
||||
if(raw_info.disabled)
|
||||
{
|
||||
conn_info.state.client_current_state=client_idle;
|
||||
conn_info.my_id=get_true_random_number_nz();
|
||||
|
||||
mylog(log_info,"state back to client_idle\n");
|
||||
}
|
||||
|
||||
if (conn_info.state.client_current_state == client_idle) {
|
||||
if(conn_info.state.client_current_state==client_idle)
|
||||
{
|
||||
raw_info.rst_received=0;
|
||||
raw_info.disabled=0;
|
||||
|
||||
fail_time_counter++;
|
||||
if (max_fail_time > 0 && fail_time_counter > max_fail_time) {
|
||||
if(max_fail_time>0&&fail_time_counter>max_fail_time)
|
||||
{
|
||||
mylog(log_fatal,"max_fail_time exceed\n");
|
||||
myexit(-1);
|
||||
}
|
||||
@@ -108,10 +124,14 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
conn_info.blob->anti_replay.re_init();
|
||||
conn_info.my_id = get_true_random_number_nz(); ///todo no need to do this everytime
|
||||
|
||||
|
||||
|
||||
address_t tmp_addr;
|
||||
//u32_t new_ip=0;
|
||||
if (!force_source_ip) {
|
||||
if (get_src_adress2(tmp_addr, remote_addr) != 0) {
|
||||
if(!force_source_ip)
|
||||
{
|
||||
if(get_src_adress2(tmp_addr,remote_addr)!=0)
|
||||
{
|
||||
mylog(log_warn,"get_src_adress() failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -129,42 +149,55 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
send_info.src_ip=new_ip;
|
||||
}*/
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addr=source_addr;
|
||||
}
|
||||
|
||||
send_info.new_src_ip.from_address_t(tmp_addr);
|
||||
|
||||
if (force_source_port == 0) {
|
||||
if (force_source_port == 0)
|
||||
{
|
||||
send_info.src_port = client_bind_to_a_new_port2(bind_fd,tmp_addr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
send_info.src_port = source_port;
|
||||
}
|
||||
|
||||
if (raw_mode == mode_icmp) {
|
||||
if (raw_mode == mode_icmp)
|
||||
{
|
||||
send_info.dst_port = send_info.src_port;
|
||||
}
|
||||
|
||||
mylog(log_info, "using port %d\n", send_info.src_port);
|
||||
init_filter(send_info.src_port);
|
||||
|
||||
if (raw_mode == mode_icmp || raw_mode == mode_udp) {
|
||||
if(raw_mode==mode_icmp||raw_mode==mode_udp)
|
||||
{
|
||||
conn_info.state.client_current_state=client_handshake1;
|
||||
|
||||
mylog(log_info,"state changed from client_idle to client_pre_handshake\n");
|
||||
}
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if (use_tcp_dummy_socket) {
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
if(use_tcp_dummy_socket)
|
||||
{
|
||||
setnonblocking(bind_fd);
|
||||
int ret=connect(bind_fd,(struct sockaddr *)&remote_addr.inner,remote_addr.get_len());
|
||||
mylog(log_debug,"ret=%d,errno=%s, %d %s\n",ret,get_sock_error(),bind_fd,remote_addr.get_str());
|
||||
//mylog(log_info,"ret=%d,errno=,%d %s\n",ret,bind_fd,remote_addr.get_str());
|
||||
conn_info.state.client_current_state=client_tcp_handshake_dummy;
|
||||
mylog(log_info,"state changed from client_idle to client_tcp_handshake_dummy\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
conn_info.state.client_current_state=client_tcp_handshake;
|
||||
mylog(log_info,"state changed from client_idle to client_tcp_handshake\n");
|
||||
}
|
||||
|
||||
}
|
||||
conn_info.last_state_time=get_current_time();
|
||||
conn_info.last_hb_sent_time=0;
|
||||
@@ -173,14 +206,20 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
if(conn_info.state.client_current_state==client_tcp_handshake) //send and resend syn
|
||||
{
|
||||
assert(raw_mode==mode_faketcp);
|
||||
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
|
||||
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout)
|
||||
{
|
||||
conn_info.state.client_current_state = client_idle;
|
||||
mylog(log_info, "state back to client_idle from client_tcp_handshake\n");
|
||||
return 0;
|
||||
|
||||
} else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) {
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if (conn_info.last_hb_sent_time == 0) {
|
||||
}
|
||||
else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval)
|
||||
{
|
||||
|
||||
if (raw_mode == mode_faketcp)
|
||||
{
|
||||
if (conn_info.last_hb_sent_time == 0)
|
||||
{
|
||||
send_info.psh = 0;
|
||||
send_info.syn = 1;
|
||||
send_info.ack = 0;
|
||||
@@ -195,27 +234,40 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
conn_info.last_hb_sent_time = get_current_time();
|
||||
mylog(log_info, "(re)sent tcp syn\n");
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
} else if (conn_info.state.client_current_state == client_tcp_handshake_dummy) {
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_tcp_handshake_dummy)
|
||||
{
|
||||
assert(raw_mode==mode_faketcp);
|
||||
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
|
||||
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout)
|
||||
{
|
||||
conn_info.state.client_current_state = client_idle;
|
||||
mylog(log_info, "state back to client_idle from client_tcp_handshake_dummy\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
} else if (conn_info.state.client_current_state == client_handshake1) // send and resend handshake1
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_handshake1)//send and resend handshake1
|
||||
{
|
||||
if(get_current_time()-conn_info.last_state_time>client_handshake_timeout)
|
||||
{
|
||||
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
|
||||
conn_info.state.client_current_state=client_idle;
|
||||
mylog(log_info,"state back to client_idle from client_handshake1\n");
|
||||
return 0;
|
||||
|
||||
} else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) {
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if (conn_info.last_hb_sent_time == 0) {
|
||||
}
|
||||
else if(get_current_time()-conn_info.last_hb_sent_time>client_retry_interval)
|
||||
{
|
||||
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
if(conn_info.last_hb_sent_time==0)
|
||||
{
|
||||
send_info.seq++;
|
||||
send_info.ack_seq=recv_info.seq+1;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
@@ -232,7 +284,10 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
send_handshake(raw_info,conn_info.my_id,0,const_id);
|
||||
|
||||
send_info.seq+=raw_info.send_info.data_len;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
send_handshake(raw_info,conn_info.my_id,0,const_id);
|
||||
if(raw_mode==mode_icmp)
|
||||
send_info.my_icmp_seq++;
|
||||
@@ -241,18 +296,27 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
conn_info.last_hb_sent_time=get_current_time();
|
||||
mylog(log_info,"(re)sent handshake1\n");
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
} else if (conn_info.state.client_current_state == client_handshake2) {
|
||||
if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) {
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_handshake2)
|
||||
{
|
||||
if(get_current_time()-conn_info.last_state_time>client_handshake_timeout)
|
||||
{
|
||||
conn_info.state.client_current_state=client_idle;
|
||||
mylog(log_info,"state back to client_idle from client_handshake2\n");
|
||||
return 0;
|
||||
} else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) {
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if (conn_info.last_hb_sent_time == 0) {
|
||||
}
|
||||
else if(get_current_time()-conn_info.last_hb_sent_time>client_retry_interval)
|
||||
{
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
if(conn_info.last_hb_sent_time==0)
|
||||
{
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
raw_info.reserved_send_seq=send_info.seq;
|
||||
@@ -261,7 +325,10 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id);
|
||||
send_info.seq+=raw_info.send_info.data_len;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id);
|
||||
if(raw_mode==mode_icmp)
|
||||
send_info.my_icmp_seq++;
|
||||
@@ -270,31 +337,41 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
mylog(log_info,"(re)sent handshake2\n");
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
} else if (conn_info.state.client_current_state == client_ready) {
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_ready)
|
||||
{
|
||||
fail_time_counter=0;
|
||||
mylog(log_trace,"time %llu,%llu\n",get_current_time(),conn_info.last_state_time);
|
||||
|
||||
if (get_current_time() - conn_info.last_hb_recv_time > client_conn_timeout) {
|
||||
if(get_current_time()-conn_info.last_hb_recv_time>client_conn_timeout)
|
||||
{
|
||||
conn_info.state.client_current_state=client_idle;
|
||||
conn_info.my_id=get_true_random_number_nz();
|
||||
mylog(log_info,"state back to client_idle from client_ready bc of server-->client direction timeout\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (get_current_time() - conn_info.last_oppsite_roller_time > client_conn_uplink_timeout) {
|
||||
if(get_current_time()- conn_info.last_oppsite_roller_time>client_conn_uplink_timeout)
|
||||
{
|
||||
conn_info.state.client_current_state=client_idle;
|
||||
conn_info.my_id=get_true_random_number_nz();
|
||||
mylog(log_info,"state back to client_idle from client_ready bc of client-->server direction timeout\n");
|
||||
}
|
||||
|
||||
if (get_current_time() - conn_info.last_hb_sent_time < heartbeat_interval) {
|
||||
|
||||
if(get_current_time()-conn_info.last_hb_sent_time<heartbeat_interval)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
mylog(log_debug,"heartbeat sent <%x,%x>\n",conn_info.oppsite_id,conn_info.my_id);
|
||||
|
||||
if(hb_mode==0)
|
||||
@@ -303,22 +380,27 @@ int client_on_timer(conn_info_t &conn_info) // for client. called when a timer
|
||||
send_safer(conn_info,'h',hb_buf,hb_len);
|
||||
conn_info.last_hb_sent_time=get_current_time();
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"unknown state,this shouldnt happen.\n");
|
||||
myexit(-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info, char type, char *data, int data_len) {
|
||||
int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info,char type,char *data,int data_len)
|
||||
{
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) {
|
||||
if(!recv_info.new_src_ip.equal(send_info.new_dst_ip)||recv_info.src_port!=send_info.dst_port)
|
||||
{
|
||||
mylog(log_warn,"unexpected adress %s %s %d %d,this shouldnt happen.\n",recv_info.new_src_ip.get_str1(),send_info.new_dst_ip.get_str2(),recv_info.src_port,send_info.dst_port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn_info.state.client_current_state == client_handshake2) {
|
||||
if(conn_info.state.client_current_state==client_handshake2)
|
||||
{
|
||||
mylog(log_info,"changed state from to client_handshake2 to client_ready\n");
|
||||
conn_info.state.client_current_state=client_ready;
|
||||
conn_info.last_hb_sent_time=0;
|
||||
@@ -326,11 +408,14 @@ int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info, char type, char *dat
|
||||
conn_info.last_oppsite_roller_time=conn_info.last_hb_recv_time;
|
||||
client_on_timer(conn_info);
|
||||
}
|
||||
if (data_len >= 0 && type == 'h') {
|
||||
if(data_len>=0&&type=='h')
|
||||
{
|
||||
mylog(log_debug,"[hb]heart beat received,oppsite_roller=%d\n",int(conn_info.oppsite_roller));
|
||||
conn_info.last_hb_recv_time=get_current_time();
|
||||
return 0;
|
||||
} else if (data_len >= int(sizeof(u32_t)) && type == 'd') {
|
||||
}
|
||||
else if(data_len>= int( sizeof(u32_t))&&type=='d')
|
||||
{
|
||||
mylog(log_trace,"received a data from fake tcp,len:%d\n",data_len);
|
||||
|
||||
if(hb_mode==0)
|
||||
@@ -340,7 +425,8 @@ int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info, char type, char *dat
|
||||
memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id));
|
||||
tmp_conv_id=ntohl(tmp_conv_id);
|
||||
|
||||
if (!conn_info.blob->conv_manager.c.is_conv_used(tmp_conv_id)) {
|
||||
if(!conn_info.blob->conv_manager.c.is_conv_used(tmp_conv_id))
|
||||
{
|
||||
mylog(log_info,"unknow conv %d,ignore\n",tmp_conv_id);
|
||||
return 0;
|
||||
}
|
||||
@@ -357,13 +443,17 @@ int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info, char type, char *dat
|
||||
|
||||
//tmp_sockaddr.sin_port= htons(uint16_t((u64<<32u)>>32u));
|
||||
|
||||
|
||||
int ret=sendto(udp_fd,data+sizeof(u32_t),data_len -(sizeof(u32_t)),0,(struct sockaddr *)&tmp_addr.inner,tmp_addr.get_len());
|
||||
|
||||
if (ret < 0) {
|
||||
if(ret<0)
|
||||
{
|
||||
mylog(log_warn,"sento returned %d,%s,%02x,%s\n",ret,get_sock_error(),int(tmp_addr.get_type()),tmp_addr.get_str());
|
||||
//perror("ret<0");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_warn,"unknown packet,this shouldnt happen.\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -371,8 +461,7 @@ int client_on_raw_recv_hs2_or_ready(conn_info_t &conn_info, char type, char *dat
|
||||
}
|
||||
int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a packet.
|
||||
{
|
||||
char *data;
|
||||
int data_len;
|
||||
char* data;int data_len;
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
@@ -384,31 +473,41 @@ int client_on_raw_recv(conn_info_t &conn_info) // called when raw fd received a
|
||||
if(pre_recv_raw_packet()<0) return -1;
|
||||
#endif
|
||||
|
||||
if (conn_info.state.client_current_state == client_idle) {
|
||||
if(conn_info.state.client_current_state==client_idle )
|
||||
{
|
||||
discard_raw_packet();
|
||||
//recv(raw_recv_fd, 0,0, 0 );
|
||||
} else if (conn_info.state.client_current_state == client_tcp_handshake || conn_info.state.client_current_state == client_tcp_handshake_dummy) // received syn ack
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_tcp_handshake||conn_info.state.client_current_state==client_tcp_handshake_dummy)//received syn ack
|
||||
{
|
||||
assert(raw_mode==mode_faketcp);
|
||||
if (recv_raw0(raw_info, data, data_len) < 0) {
|
||||
if(recv_raw0(raw_info,data,data_len)<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (data_len >= max_data_len + 1) {
|
||||
if(data_len>=max_data_len+1)
|
||||
{
|
||||
mylog(log_debug,"data_len=%d >= max_data_len+1,ignored",data_len);
|
||||
return -1;
|
||||
}
|
||||
if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) {
|
||||
if(!recv_info.new_src_ip.equal(send_info.new_dst_ip)||recv_info.src_port!=send_info.dst_port)
|
||||
{
|
||||
mylog(log_debug,"unexpected adress %s %s %d %d\n",recv_info.new_src_ip.get_str1(),send_info.new_dst_ip.get_str2(),recv_info.src_port,send_info.dst_port);
|
||||
return -1;
|
||||
}
|
||||
if (data_len == 0 && raw_info.recv_info.syn == 1 && raw_info.recv_info.ack == 1) {
|
||||
if (conn_info.state.client_current_state == client_tcp_handshake) {
|
||||
if (recv_info.ack_seq != send_info.seq + 1) {
|
||||
if(data_len==0&&raw_info.recv_info.syn==1&&raw_info.recv_info.ack==1)
|
||||
{
|
||||
if(conn_info.state.client_current_state==client_tcp_handshake)
|
||||
{
|
||||
if(recv_info.ack_seq!=send_info.seq+1)
|
||||
{
|
||||
mylog(log_debug,"seq ack_seq mis match\n");
|
||||
return -1;
|
||||
}
|
||||
mylog(log_info,"state changed from client_tcp_handshake to client_handshake1\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
send_info.seq=recv_info.ack_seq-1;
|
||||
mylog(log_info,"state changed from client_tcp_dummy to client_handshake1\n");
|
||||
//send_info.ack_seq=recv_info.seq+1;
|
||||
@@ -419,21 +518,27 @@ int client_on_raw_recv(conn_info_t &conn_info) // called when raw fd received a
|
||||
conn_info.last_hb_sent_time=0;
|
||||
client_on_timer(conn_info);
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_debug,"unexpected packet type,expected:syn ack\n");
|
||||
return -1;
|
||||
}
|
||||
} else if (conn_info.state.client_current_state == client_handshake1) // recevied respond of handshake1
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_handshake1)//recevied respond of handshake1
|
||||
{
|
||||
if(recv_bare(raw_info,data,data_len)!=0)
|
||||
{
|
||||
if (recv_bare(raw_info, data, data_len) != 0) {
|
||||
mylog(log_debug,"recv_bare failed!\n");
|
||||
return -1;
|
||||
}
|
||||
if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) {
|
||||
if(!recv_info.new_src_ip.equal(send_info.new_dst_ip)||recv_info.src_port!=send_info.dst_port)
|
||||
{
|
||||
mylog(log_debug,"unexpected adress %s %s %d %d\n",recv_info.new_src_ip.get_str1(),send_info.new_dst_ip.get_str2(),recv_info.src_port,send_info.dst_port);
|
||||
return -1;
|
||||
}
|
||||
if (data_len < int(3 * sizeof(my_id_t))) {
|
||||
if(data_len<int( 3*sizeof(my_id_t)))
|
||||
{
|
||||
mylog(log_debug,"too short to be a handshake\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -449,17 +554,22 @@ int client_on_raw_recv(conn_info_t &conn_info) // called when raw fd received a
|
||||
memcpy(&tmp_oppsite_const_id,&data[sizeof(my_id_t)*2],sizeof(tmp_oppsite_const_id));
|
||||
tmp_oppsite_const_id=ntohl(tmp_oppsite_const_id);
|
||||
|
||||
if (tmp_my_id != conn_info.my_id) {
|
||||
if(tmp_my_id!=conn_info.my_id)
|
||||
{
|
||||
mylog(log_debug,"tmp_my_id doesnt match\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if (recv_info.ack_seq != send_info.seq) {
|
||||
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
if(recv_info.ack_seq!=send_info.seq)
|
||||
{
|
||||
mylog(log_debug,"seq ack_seq mis match\n");
|
||||
return -1;
|
||||
}
|
||||
if (recv_info.seq != send_info.ack_seq) {
|
||||
if(recv_info.seq!=send_info.ack_seq)
|
||||
{
|
||||
mylog(log_debug,"seq ack_seq mis match\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -474,17 +584,20 @@ int client_on_raw_recv(conn_info_t &conn_info) // called when raw fd received a
|
||||
client_on_timer(conn_info);
|
||||
|
||||
return 0;
|
||||
} else if (conn_info.state.client_current_state == client_handshake2 || conn_info.state.client_current_state == client_ready) // received heartbeat or data
|
||||
}
|
||||
else if(conn_info.state.client_current_state==client_handshake2||conn_info.state.client_current_state==client_ready)//received heartbeat or data
|
||||
{
|
||||
vector<char> type_vec;
|
||||
vector<string> data_vec;
|
||||
recv_safer_multi(conn_info,type_vec,data_vec);
|
||||
if (data_vec.empty()) {
|
||||
if(data_vec.empty())
|
||||
{
|
||||
mylog(log_debug,"recv_safer failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)type_vec.size(); i++) {
|
||||
for(int i=0;i<(int)type_vec.size();i++)
|
||||
{
|
||||
char type=type_vec[i];
|
||||
char *data=(char *)data_vec[i].c_str(); //be careful, do not append data to it
|
||||
int data_len=data_vec[i].length();
|
||||
@@ -492,13 +605,16 @@ int client_on_raw_recv(conn_info_t &conn_info) // called when raw fd received a
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"unknown state,this shouldnt happen.\n");
|
||||
myexit(-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int client_on_udp_recv(conn_info_t &conn_info) {
|
||||
int client_on_udp_recv(conn_info_t &conn_info)
|
||||
{
|
||||
int recv_len;
|
||||
char buf[buf_len];
|
||||
address_t::storage_t udp_new_addr_in={{0}};
|
||||
@@ -510,12 +626,14 @@ int client_on_udp_recv(conn_info_t &conn_info) {
|
||||
//myexit(1);
|
||||
};
|
||||
|
||||
if (recv_len == max_data_len + 1) {
|
||||
if(recv_len==max_data_len+1)
|
||||
{
|
||||
mylog(log_warn,"huge packet, data_len > %d,dropped\n",max_data_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recv_len >= mtu_warn) {
|
||||
if(recv_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 ",recv_len,mtu_warn);
|
||||
}
|
||||
|
||||
@@ -523,45 +641,53 @@ int client_on_udp_recv(conn_info_t &conn_info) {
|
||||
tmp_addr.from_sockaddr((sockaddr *)&udp_new_addr_in,udp_new_addr_len);
|
||||
u32_t conv;
|
||||
|
||||
if (!conn_info.blob->conv_manager.c.is_data_used(tmp_addr)) {
|
||||
if (conn_info.blob->conv_manager.c.get_size() >= max_conv_num) {
|
||||
if(!conn_info.blob->conv_manager.c.is_data_used(tmp_addr))
|
||||
{
|
||||
if(conn_info.blob->conv_manager.c.get_size() >=max_conv_num)
|
||||
{
|
||||
mylog(log_warn,"ignored new udp connect bc max_conv_num exceed\n");
|
||||
return -1;
|
||||
}
|
||||
conv=conn_info.blob->conv_manager.c.get_new_conv();
|
||||
conn_info.blob->conv_manager.c.insert_conv(conv,tmp_addr);
|
||||
mylog(log_info,"new packet from %s,conv_id=%x\n",tmp_addr.get_str(),conv);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
conv=conn_info.blob->conv_manager.c.find_conv_by_data(tmp_addr);
|
||||
}
|
||||
|
||||
conn_info.blob->conv_manager.c.update_active_time(conv);
|
||||
|
||||
if (conn_info.state.client_current_state == client_ready) {
|
||||
if(conn_info.state.client_current_state==client_ready)
|
||||
{
|
||||
send_data_safer(conn_info,buf,recv_len,conv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
|
||||
void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||
{
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
client_on_udp_recv(conn_info);
|
||||
}
|
||||
void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
|
||||
void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||
{
|
||||
if(is_udp2raw_mp)assert(0==1);
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
client_on_raw_recv(conn_info);
|
||||
}
|
||||
#ifdef UDP2RAW_MP
|
||||
void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) {
|
||||
void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents)
|
||||
{
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
|
||||
if (send_with_pcap && !pcap_header_captured) {
|
||||
int empty = 0;
|
||||
char *p;
|
||||
int len;
|
||||
if(send_with_pcap&&!pcap_header_captured)
|
||||
{
|
||||
int empty=0;char *p;int len;
|
||||
pthread_mutex_lock(&queue_mutex);
|
||||
empty=my_queue.empty();
|
||||
if (!empty) {
|
||||
if(!empty)
|
||||
{
|
||||
my_queue.peek_front(p,len);
|
||||
my_queue.pop_front();
|
||||
}
|
||||
@@ -583,21 +709,22 @@ void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) {
|
||||
}
|
||||
|
||||
//mylog(log_info,"async_cb called\n");
|
||||
while (1) {
|
||||
int empty = 0;
|
||||
char *p;
|
||||
int len;
|
||||
while(1)
|
||||
{
|
||||
int empty=0;char *p;int len;
|
||||
pthread_mutex_lock(&queue_mutex);
|
||||
empty=my_queue.empty();
|
||||
if (!empty) {
|
||||
if(!empty)
|
||||
{
|
||||
my_queue.peek_front(p,len);
|
||||
my_queue.pop_front();
|
||||
}
|
||||
pthread_mutex_unlock(&queue_mutex);
|
||||
|
||||
if(empty) break;
|
||||
if (g_fix_gro == 0 && len > max_data_len) {
|
||||
mylog(log_warn, "huge packet %d > %d, dropped. maybe you need to turn down mtu at upper level, or maybe you need the --fix-gro option\n", len, max_data_len);
|
||||
if(g_fix_gro==0&&len>max_data_len)
|
||||
{
|
||||
mylog(log_warn,"huge packet %d > %d, dropped\n",len,max_data_len);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -610,18 +737,21 @@ void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) {
|
||||
void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
||||
{
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
client_on_timer(conn_info);
|
||||
}
|
||||
void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
|
||||
void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||
{
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
|
||||
char buf[buf_len];
|
||||
int fifo_fd=watcher->fd;
|
||||
|
||||
int len=read (fifo_fd, buf, sizeof (buf));
|
||||
if (len < 0) {
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error());
|
||||
return;
|
||||
}
|
||||
@@ -629,15 +759,20 @@ void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
|
||||
while(len>=1&&buf[len-1]=='\n')
|
||||
buf[len-1]=0;
|
||||
mylog(log_info,"got data from fifo,len=%d,s=[%s]\n",len,buf);
|
||||
if (strcmp(buf, "reconnect") == 0) {
|
||||
if(strcmp(buf,"reconnect")==0)
|
||||
{
|
||||
mylog(log_info,"received command: reconnect\n");
|
||||
conn_info.state.client_current_state=client_idle;
|
||||
conn_info.my_id=get_true_random_number_nz();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_info,"unknown command\n");
|
||||
}
|
||||
|
||||
}
|
||||
int client_event_loop() {
|
||||
int client_event_loop()
|
||||
{
|
||||
char buf[buf_len];
|
||||
|
||||
conn_info_t conn_info;
|
||||
@@ -648,8 +783,10 @@ int client_event_loop() {
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
#ifdef UDP2RAW_LINUX
|
||||
if (lower_level) {
|
||||
if (lower_level_manual) {
|
||||
if(lower_level)
|
||||
{
|
||||
if(lower_level_manual)
|
||||
{
|
||||
int index;
|
||||
init_ifindex(if_name,raw_send_fd,index);
|
||||
//init_ifindex(if_name);
|
||||
@@ -660,26 +797,37 @@ int client_event_loop() {
|
||||
send_info.addr_ll.sll_protocol = htons(ETH_P_IP);
|
||||
memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN);
|
||||
mylog(log_info,"we are running at lower-level (manual) mode\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
u32_t dest_ip;
|
||||
string if_name_string;
|
||||
string hw_string;
|
||||
assert(remote_addr.get_type()==AF_INET);
|
||||
|
||||
if (retry_on_error == 0) {
|
||||
if (find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr, dest_ip, if_name_string, hw_string) != 0) {
|
||||
if(retry_on_error==0)
|
||||
{
|
||||
if(find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr,dest_ip,if_name_string,hw_string)!=0)
|
||||
{
|
||||
mylog(log_fatal,"auto detect lower-level info failed for %s,specific it manually\n",remote_addr.get_ip());
|
||||
myexit(-1);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int ok=0;
|
||||
while (!ok) {
|
||||
if (find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr, dest_ip, if_name_string, hw_string) != 0) {
|
||||
while(!ok)
|
||||
{
|
||||
if(find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr,dest_ip,if_name_string,hw_string)!=0)
|
||||
{
|
||||
mylog(log_warn,"auto detect lower-level info failed for %s,retry in %d seconds\n",remote_addr.get_ip(),retry_on_error_interval);
|
||||
sleep(retry_on_error_interval);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ok=1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mylog(log_info,"we are running at lower-level (auto) mode,%s %s %s\n",my_ntoa(dest_ip),if_name_string.c_str(),hw_string.c_str());
|
||||
@@ -708,17 +856,20 @@ int client_event_loop() {
|
||||
memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN);
|
||||
//mylog(log_info,"we are running at lower-level (manual) mode\n");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UDP2RAW_MP
|
||||
|
||||
address_t tmp_addr;
|
||||
if (get_src_adress2(tmp_addr, remote_addr) != 0) {
|
||||
if(get_src_adress2(tmp_addr,remote_addr)!=0)
|
||||
{
|
||||
mylog(log_error,"get_src_adress() failed\n");
|
||||
myexit(-1);
|
||||
}
|
||||
if (strcmp(dev, "") == 0) {
|
||||
if(strcmp(dev,"")==0)
|
||||
{
|
||||
mylog(log_info,"--dev have not been set, trying to detect automatically, available devices:\n");
|
||||
|
||||
mylog(log_info,"available device(device name: ip address ; description):\n");
|
||||
@@ -728,7 +879,8 @@ int client_event_loop() {
|
||||
int found=0;
|
||||
|
||||
pcap_if_t *interfaces,*d;
|
||||
if (pcap_findalldevs(&interfaces, errbuf) == -1) {
|
||||
if(pcap_findalldevs(&interfaces,errbuf)==-1)
|
||||
{
|
||||
mylog(log_fatal,"error in pcap_findalldevs(),%s\n",errbuf);
|
||||
myexit(-1);
|
||||
}
|
||||
@@ -737,61 +889,82 @@ int client_event_loop() {
|
||||
log_bare(log_warn,"%s:", d->name);
|
||||
int cnt=0;
|
||||
for(pcap_addr_t *a=d->addresses; a!=NULL; a=a->next) {
|
||||
if (a->addr == NULL) {
|
||||
if(a->addr==NULL)
|
||||
{
|
||||
log_bare(log_debug," [a->addr==NULL]");
|
||||
continue;
|
||||
}
|
||||
if (a->addr->sa_family == AF_INET || a->addr->sa_family == AF_INET6) {
|
||||
if(a->addr->sa_family == AF_INET||a->addr->sa_family == AF_INET6)
|
||||
{
|
||||
cnt++;
|
||||
|
||||
if (a->addr->sa_family == AF_INET) {
|
||||
if(a->addr->sa_family ==AF_INET)
|
||||
{
|
||||
char s[max_addr_len];
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in*)a->addr)->sin_addr, s,max_addr_len);
|
||||
log_bare(log_warn," [%s]", s);
|
||||
|
||||
if (a->addr->sa_family == raw_ip_version) {
|
||||
if (((struct sockaddr_in *)a->addr)->sin_addr.s_addr == tmp_addr.inner.ipv4.sin_addr.s_addr) {
|
||||
if(a->addr->sa_family==raw_ip_version)
|
||||
{
|
||||
if(((struct sockaddr_in*)a->addr)->sin_addr.s_addr ==tmp_addr.inner.ipv4.sin_addr.s_addr)
|
||||
{
|
||||
found++;
|
||||
strcpy(dev,d->name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(a->addr->sa_family ==AF_INET6);
|
||||
|
||||
char s[max_addr_len];
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6*)a->addr)->sin6_addr, s,max_addr_len);
|
||||
log_bare(log_warn," [%s]", s);
|
||||
|
||||
if (a->addr->sa_family == raw_ip_version) {
|
||||
if (memcmp(&((struct sockaddr_in6 *)a->addr)->sin6_addr, &tmp_addr.inner.ipv6.sin6_addr, sizeof(struct in6_addr)) == 0) {
|
||||
if(a->addr->sa_family==raw_ip_version)
|
||||
{
|
||||
if( memcmp( &((struct sockaddr_in6*)a->addr)->sin6_addr,&tmp_addr.inner.ipv6.sin6_addr,sizeof(struct in6_addr))==0 )
|
||||
{
|
||||
found++;
|
||||
strcpy(dev,d->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_bare(log_debug," [unknow:%d]",int(a->addr->sa_family));
|
||||
}
|
||||
}
|
||||
if(cnt==0) log_bare(log_warn," [no ip found]");
|
||||
if (d->description == 0) {
|
||||
if(d->description==0)
|
||||
{
|
||||
log_bare(log_warn,"; (no description available)");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_bare(log_warn,"; %s", d->description);
|
||||
}
|
||||
log_bare(log_warn,"\n");
|
||||
}
|
||||
|
||||
if (found == 0) {
|
||||
if(found==0)
|
||||
{
|
||||
mylog(log_fatal,"no matched device found for ip: [%s]\n",tmp_addr.get_ip());
|
||||
myexit(-1);
|
||||
} else if (found == 1) {
|
||||
}
|
||||
else if(found==1)
|
||||
{
|
||||
mylog(log_info,"using device:[%s], ip: [%s]\n",dev,tmp_addr.get_ip());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"more than one devices found for ip: [%s] , you need to use --dev manually\n",tmp_addr.get_ip());
|
||||
myexit(-1);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_info,"--dev has been manually set, using device:[%s]\n",dev);
|
||||
}
|
||||
#endif
|
||||
@@ -799,15 +972,17 @@ int client_event_loop() {
|
||||
send_info.src_port=0;
|
||||
memset(&send_info.new_src_ip,0,sizeof(send_info.new_src_ip));
|
||||
|
||||
int i, j, k;
|
||||
int ret;
|
||||
int i, j, k;int ret;
|
||||
|
||||
|
||||
send_info.new_dst_ip.from_address_t(remote_addr);
|
||||
send_info.dst_port=remote_addr.get_port();
|
||||
|
||||
|
||||
udp_fd=socket(local_addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
|
||||
set_buf_size(udp_fd,socket_buf_size);
|
||||
|
||||
|
||||
if (::bind(udp_fd, (struct sockaddr*) &local_addr.inner, local_addr.get_len()) == -1) {
|
||||
mylog(log_fatal,"socket bind error\n");
|
||||
//perror("socket bind error");
|
||||
@@ -835,12 +1010,14 @@ int client_event_loop() {
|
||||
// myexit(-1);
|
||||
//}
|
||||
|
||||
|
||||
struct ev_io udp_accept_watcher;
|
||||
|
||||
udp_accept_watcher.data=&conn_info;
|
||||
ev_io_init(&udp_accept_watcher, udp_accept_cb, udp_fd, EV_READ);
|
||||
ev_io_start(loop, &udp_accept_watcher);
|
||||
|
||||
|
||||
//ev.events = EPOLLIN;
|
||||
//ev.data.u64 = raw_recv_fd;
|
||||
|
||||
@@ -881,7 +1058,8 @@ int client_event_loop() {
|
||||
struct ev_io fifo_watcher;
|
||||
fifo_watcher.data=&conn_info;
|
||||
|
||||
if (fifo_file[0] != 0) {
|
||||
if(fifo_file[0]!=0)
|
||||
{
|
||||
fifo_fd=create_fifo(fifo_file);
|
||||
|
||||
ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ);
|
||||
|
502
common.cpp
502
common.cpp
File diff suppressed because it is too large
Load Diff
174
common.h
174
common.h
@@ -44,6 +44,7 @@ const int is_udp2raw_mp = 1;
|
||||
#include <libnet.h>
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#define UDP2RAW_LINUX
|
||||
const int is_udp2raw_mp=0;
|
||||
@@ -79,6 +80,7 @@ typedef int socklen_t;
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include<unordered_map>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
@@ -98,6 +100,7 @@ using namespace std;
|
||||
#define UDP2RAW_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
|
||||
defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \
|
||||
defined(__LITTLE_ENDIAN__) || \
|
||||
@@ -112,10 +115,12 @@ using namespace std;
|
||||
#error "endian detection conflicts"
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(UDP2RAW_BIG_ENDIAN) && !defined(UDP2RAW_LITTLE_ENDIAN)
|
||||
#error "endian detection failed"
|
||||
#endif
|
||||
|
||||
|
||||
#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);
|
||||
@@ -127,17 +132,20 @@ int get_sock_errno();
|
||||
|
||||
#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
|
||||
|
||||
|
||||
typedef unsigned long long u64_t; //this works on most platform,avoid using the PRId64
|
||||
typedef long long i64_t;
|
||||
|
||||
@@ -180,8 +188,10 @@ u32_t sdbm(unsigned char *str, int len);
|
||||
|
||||
struct address_t //TODO scope id
|
||||
{
|
||||
struct hash_function {
|
||||
u32_t operator()(const address_t &key) const {
|
||||
struct hash_function
|
||||
{
|
||||
u32_t operator()(const address_t &key) const
|
||||
{
|
||||
return sdbm((unsigned char*)&key.inner,sizeof(key.inner));
|
||||
}
|
||||
};
|
||||
@@ -193,13 +203,16 @@ struct address_t // TODO scope id
|
||||
};
|
||||
storage_t inner;
|
||||
|
||||
address_t() {
|
||||
address_t()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
memset(&inner,0,sizeof(inner));
|
||||
}
|
||||
int from_ip_port(u32_t ip, int port) {
|
||||
int from_ip_port(u32_t ip, int port)
|
||||
{
|
||||
clear();
|
||||
inner.ipv4.sin_family=AF_INET;
|
||||
inner.ipv4.sin_port=htons(port);
|
||||
@@ -207,13 +220,17 @@ struct address_t // TODO scope id
|
||||
return 0;
|
||||
}
|
||||
|
||||
int from_ip_port_new(int type, void *ip, int port) {
|
||||
int from_ip_port_new(int type, void * ip, int port)
|
||||
{
|
||||
clear();
|
||||
if (type == AF_INET) {
|
||||
if(type==AF_INET)
|
||||
{
|
||||
inner.ipv4.sin_family=AF_INET;
|
||||
inner.ipv4.sin_port=htons(port);
|
||||
inner.ipv4.sin_addr.s_addr=*((u32_t *)ip);
|
||||
} else if (type == AF_INET6) {
|
||||
}
|
||||
else if(type==AF_INET6)
|
||||
{
|
||||
inner.ipv6.sin6_family=AF_INET6;
|
||||
inner.ipv6.sin6_port=htons(port);
|
||||
inner.ipv6.sin6_addr=*((in6_addr*)ip);
|
||||
@@ -230,15 +247,18 @@ struct address_t // TODO scope id
|
||||
char* get_str();
|
||||
void to_str(char *);
|
||||
|
||||
inline u32_t get_type() {
|
||||
inline u32_t get_type()
|
||||
{
|
||||
u32_t ret=((sockaddr*)&inner)->sa_family;
|
||||
assert(ret==AF_INET||ret==AF_INET6);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline u32_t get_len() {
|
||||
inline u32_t get_len()
|
||||
{
|
||||
u32_t type=get_type();
|
||||
switch (type) {
|
||||
switch(type)
|
||||
{
|
||||
case AF_INET:
|
||||
return sizeof(sockaddr_in);
|
||||
case AF_INET6:
|
||||
@@ -249,9 +269,11 @@ struct address_t // TODO scope id
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline u32_t get_port() {
|
||||
inline u32_t get_port()
|
||||
{
|
||||
u32_t type=get_type();
|
||||
switch (type) {
|
||||
switch(type)
|
||||
{
|
||||
case AF_INET:
|
||||
return ntohs(inner.ipv4.sin_port);
|
||||
case AF_INET6:
|
||||
@@ -262,9 +284,11 @@ struct address_t // TODO scope id
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline void set_port(int port) {
|
||||
inline void set_port(int port)
|
||||
{
|
||||
u32_t type=get_type();
|
||||
switch (type) {
|
||||
switch(type)
|
||||
{
|
||||
case AF_INET:
|
||||
inner.ipv4.sin_port=htons(port);
|
||||
break;
|
||||
@@ -277,7 +301,8 @@ struct address_t // TODO scope id
|
||||
return ;
|
||||
}
|
||||
|
||||
bool operator==(const address_t &b) const {
|
||||
bool operator == (const address_t &b) const
|
||||
{
|
||||
//return this->data==b.data;
|
||||
return memcmp(&this->inner,&b.inner,sizeof(this->inner))==0;
|
||||
}
|
||||
@@ -289,13 +314,16 @@ struct address_t // TODO scope id
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<address_t> {
|
||||
std::size_t operator()(const address_t &key) const {
|
||||
struct hash<address_t>
|
||||
{
|
||||
std::size_t operator()(const address_t& key) const
|
||||
{
|
||||
|
||||
//return address_t::hash_function(k);
|
||||
return sdbm((unsigned char*)&key.inner,sizeof(key.inner));
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
}
|
||||
|
||||
union my_ip_t //just a simple version of address_t,stores ip only
|
||||
{
|
||||
@@ -309,15 +337,21 @@ union my_ip_t // just a simple version of address_t,stores ip only
|
||||
char * get_str2() const;
|
||||
|
||||
int from_address_t(address_t a);
|
||||
|
||||
};
|
||||
|
||||
struct not_copy_able_t {
|
||||
not_copy_able_t() {
|
||||
struct not_copy_able_t
|
||||
{
|
||||
not_copy_able_t()
|
||||
{
|
||||
|
||||
}
|
||||
not_copy_able_t(const not_copy_able_t &other) {
|
||||
not_copy_able_t(const not_copy_able_t &other)
|
||||
{
|
||||
assert(0==1);
|
||||
}
|
||||
const not_copy_able_t &operator=(const not_copy_able_t &other) {
|
||||
const not_copy_able_t & operator=(const not_copy_able_t &other)
|
||||
{
|
||||
assert(0==1);
|
||||
return other;
|
||||
}
|
||||
@@ -334,43 +368,44 @@ const int buf_len = max_data_len + 400;
|
||||
#ifdef UDP2RAW_MP
|
||||
const int queue_len=200;
|
||||
|
||||
struct queue_t {
|
||||
struct queue_t
|
||||
{
|
||||
char data[queue_len][huge_buf_len];
|
||||
int data_len[queue_len];
|
||||
|
||||
int head=0;
|
||||
int tail=0;
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
head=tail=0;
|
||||
}
|
||||
int empty() {
|
||||
if (head == tail)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
int empty()
|
||||
{
|
||||
if(head==tail) return 1;
|
||||
else return 0;
|
||||
}
|
||||
int full() {
|
||||
if ((tail + 1) % queue_len == head)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
int full()
|
||||
{
|
||||
if( (tail+1)%queue_len==head ) return 1;
|
||||
else return 0;
|
||||
}
|
||||
void peek_front(char *&p, int &len) {
|
||||
void peek_front(char * & p,int &len)
|
||||
{
|
||||
assert(!empty());
|
||||
p=data[head];
|
||||
len=data_len[head];
|
||||
}
|
||||
void pop_front() {
|
||||
void pop_front()
|
||||
{
|
||||
assert(!empty());
|
||||
head++;
|
||||
head %= queue_len;
|
||||
head++;head%=queue_len;
|
||||
}
|
||||
void push_back(char *p, int len) {
|
||||
void push_back(char * p,int len)
|
||||
{
|
||||
assert(!full());
|
||||
memcpy(data[tail],p,len);
|
||||
data_len[tail]=len;
|
||||
tail++;
|
||||
tail %= queue_len;
|
||||
tail++;tail%=queue_len;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -439,10 +474,12 @@ int create_fifo(char *file);
|
||||
void print_binary_chars(const char * a,int len);
|
||||
|
||||
template <class key_t>
|
||||
struct lru_collector_t : not_copy_able_t {
|
||||
struct lru_collector_t:not_copy_able_t
|
||||
{
|
||||
//typedef void* key_t;
|
||||
//#define key_t void*
|
||||
struct lru_pair_t {
|
||||
struct lru_pair_t
|
||||
{
|
||||
key_t key;
|
||||
my_time_t ts;
|
||||
};
|
||||
@@ -450,61 +487,65 @@ struct lru_collector_t : not_copy_able_t {
|
||||
unordered_map<key_t,typename list<lru_pair_t>::iterator> mp;
|
||||
|
||||
list<lru_pair_t> q;
|
||||
int update(key_t key) {
|
||||
int update(key_t key)
|
||||
{
|
||||
assert(mp.find(key)!=mp.end());
|
||||
auto it=mp[key];
|
||||
q.erase(it);
|
||||
|
||||
my_time_t value=get_current_time();
|
||||
if (!q.empty()) {
|
||||
if(!q.empty())
|
||||
{
|
||||
assert(value >=q.front().ts);
|
||||
}
|
||||
lru_pair_t tmp;
|
||||
tmp.key = key;
|
||||
tmp.ts = value;
|
||||
lru_pair_t tmp; tmp.key=key; tmp.ts=value;
|
||||
q.push_front( tmp);
|
||||
mp[key]=q.begin();
|
||||
|
||||
return 0;
|
||||
}
|
||||
int new_key(key_t key) {
|
||||
int new_key(key_t key)
|
||||
{
|
||||
assert(mp.find(key)==mp.end());
|
||||
|
||||
my_time_t value=get_current_time();
|
||||
if (!q.empty()) {
|
||||
if(!q.empty())
|
||||
{
|
||||
assert(value >=q.front().ts);
|
||||
}
|
||||
lru_pair_t tmp;
|
||||
tmp.key = key;
|
||||
tmp.ts = value;
|
||||
lru_pair_t tmp; tmp.key=key; tmp.ts=value;
|
||||
q.push_front( tmp);
|
||||
mp[key]=q.begin();
|
||||
|
||||
return 0;
|
||||
}
|
||||
int size() {
|
||||
int size()
|
||||
{
|
||||
return q.size();
|
||||
}
|
||||
int empty() {
|
||||
int empty()
|
||||
{
|
||||
return q.empty();
|
||||
}
|
||||
void clear() {
|
||||
mp.clear();
|
||||
q.clear();
|
||||
void clear()
|
||||
{
|
||||
mp.clear(); q.clear();
|
||||
}
|
||||
my_time_t ts_of(key_t key) {
|
||||
my_time_t ts_of(key_t key)
|
||||
{
|
||||
assert(mp.find(key)!=mp.end());
|
||||
return mp[key]->ts;
|
||||
}
|
||||
|
||||
my_time_t peek_back(key_t &key) {
|
||||
my_time_t peek_back(key_t &key)
|
||||
{
|
||||
assert(!q.empty());
|
||||
auto it = q.end();
|
||||
it--;
|
||||
auto it=q.end(); it--;
|
||||
key=it->key;
|
||||
return it->ts;
|
||||
}
|
||||
void erase(key_t key) {
|
||||
void erase(key_t key)
|
||||
{
|
||||
assert(mp.find(key)!=mp.end());
|
||||
q.erase(mp[key]);
|
||||
mp.erase(key);
|
||||
@@ -519,4 +560,5 @@ struct lru_collector_t : not_copy_able_t {
|
||||
}*/
|
||||
};
|
||||
|
||||
|
||||
#endif /* COMMON_H_ */
|
||||
|
284
connection.cpp
284
connection.cpp
@@ -15,53 +15,67 @@ const int disable_conn_clear = 0; // a raw connection is called conn.
|
||||
|
||||
conn_manager_t conn_manager;
|
||||
|
||||
anti_replay_seq_t anti_replay_t::get_new_seq_for_send() {
|
||||
anti_replay_seq_t anti_replay_t::get_new_seq_for_send()
|
||||
{
|
||||
return anti_replay_seq++;
|
||||
}
|
||||
anti_replay_t::anti_replay_t() {
|
||||
anti_replay_t::anti_replay_t()
|
||||
{
|
||||
max_packet_received=0;
|
||||
anti_replay_seq=get_true_random_number_64()/10;//random first seq
|
||||
//memset(window,0,sizeof(window)); //not necessary
|
||||
}
|
||||
void anti_replay_t::re_init() {
|
||||
void anti_replay_t::re_init()
|
||||
{
|
||||
max_packet_received=0;
|
||||
//memset(window,0,sizeof(window));
|
||||
}
|
||||
|
||||
int anti_replay_t::is_vaild(u64_t seq) {
|
||||
int anti_replay_t::is_vaild(u64_t seq)
|
||||
{
|
||||
if(disable_anti_replay) return 1;
|
||||
//if(disabled) return 0;
|
||||
|
||||
if (seq == max_packet_received)
|
||||
return 0;
|
||||
else if (seq > max_packet_received) {
|
||||
if (seq - max_packet_received >= anti_replay_window_size) {
|
||||
if(seq==max_packet_received) return 0;
|
||||
else if(seq>max_packet_received)
|
||||
{
|
||||
if(seq-max_packet_received>=anti_replay_window_size)
|
||||
{
|
||||
memset(window,0,sizeof(window));
|
||||
window[seq%anti_replay_window_size]=1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u64_t i=max_packet_received+1;i<seq;i++)
|
||||
window[i%anti_replay_window_size]=0;
|
||||
window[seq%anti_replay_window_size]=1;
|
||||
}
|
||||
max_packet_received=seq;
|
||||
return 1;
|
||||
} else if (seq < max_packet_received) {
|
||||
if (max_packet_received - seq >= anti_replay_window_size)
|
||||
return 0;
|
||||
else {
|
||||
if (window[seq % anti_replay_window_size] == 1)
|
||||
return 0;
|
||||
else {
|
||||
}
|
||||
else if(seq<max_packet_received)
|
||||
{
|
||||
if(max_packet_received-seq>=anti_replay_window_size) return 0;
|
||||
else
|
||||
{
|
||||
if (window[seq%anti_replay_window_size]==1) return 0;
|
||||
else
|
||||
{
|
||||
window[seq%anti_replay_window_size]=1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0; //for complier check
|
||||
}
|
||||
|
||||
void conn_info_t::recover(const conn_info_t &conn_info) {
|
||||
|
||||
|
||||
|
||||
void conn_info_t::recover(const conn_info_t &conn_info)
|
||||
{
|
||||
raw_info=conn_info.raw_info;
|
||||
|
||||
raw_info.rst_received=0;
|
||||
@@ -77,9 +91,11 @@ void conn_info_t::recover(const conn_info_t &conn_info) {
|
||||
my_roller=0;//no need to set,but for easier debug,set it to zero
|
||||
oppsite_roller=0;//same as above
|
||||
last_oppsite_roller_time=0;
|
||||
|
||||
}
|
||||
|
||||
void conn_info_t::re_init() {
|
||||
void conn_info_t::re_init()
|
||||
{
|
||||
//send_packet_info.protocol=g_packet_info_send.protocol;
|
||||
if(program_mode==server_mode)
|
||||
state.server_current_state=server_idle;
|
||||
@@ -94,37 +110,49 @@ void conn_info_t::re_init() {
|
||||
oppsite_roller=0;
|
||||
last_oppsite_roller_time=0;
|
||||
}
|
||||
conn_info_t::conn_info_t() {
|
||||
conn_info_t::conn_info_t()
|
||||
{
|
||||
blob=0;
|
||||
re_init();
|
||||
}
|
||||
void conn_info_t::prepare() {
|
||||
void conn_info_t::prepare()
|
||||
{
|
||||
assert(blob==0);
|
||||
blob=new blob_t;
|
||||
if (program_mode == server_mode) {
|
||||
if(program_mode==server_mode)
|
||||
{
|
||||
blob->conv_manager.s.additional_clear_function=server_clear_function;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(program_mode==client_mode);
|
||||
}
|
||||
}
|
||||
|
||||
conn_info_t::conn_info_t(const conn_info_t &b) {
|
||||
conn_info_t::conn_info_t(const conn_info_t&b)
|
||||
{
|
||||
assert(0==1);
|
||||
//mylog(log_error,"called!!!!!!!!!!!!!\n");
|
||||
}
|
||||
|
||||
conn_info_t &conn_info_t::operator=(const conn_info_t &b) {
|
||||
conn_info_t& conn_info_t::operator=(const conn_info_t& b)
|
||||
{
|
||||
mylog(log_fatal,"not allowed\n");
|
||||
myexit(-1);
|
||||
return *this;
|
||||
}
|
||||
conn_info_t::~conn_info_t() {
|
||||
if (program_mode == server_mode) {
|
||||
if (state.server_current_state == server_ready) {
|
||||
conn_info_t::~conn_info_t()
|
||||
{
|
||||
if(program_mode==server_mode)
|
||||
{
|
||||
if(state.server_current_state==server_ready)
|
||||
{
|
||||
assert(blob!=0);
|
||||
assert(oppsite_const_id!=0);
|
||||
//assert(conn_manager.const_id_mp.find(oppsite_const_id)!=conn_manager.const_id_mp.end()); // conn_manager 's deconstuction function erases it
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(blob==0);
|
||||
assert(oppsite_const_id==0);
|
||||
}
|
||||
@@ -138,7 +166,9 @@ conn_info_t::~conn_info_t() {
|
||||
//send_packet_info.protocol=g_packet_info_send.protocol;
|
||||
}
|
||||
|
||||
conn_manager_t::conn_manager_t() {
|
||||
|
||||
conn_manager_t::conn_manager_t()
|
||||
{
|
||||
ready_num=0;
|
||||
mp.reserve(10007);
|
||||
//clear_it=mp.begin();
|
||||
@@ -149,12 +179,14 @@ conn_manager_t::conn_manager_t() {
|
||||
//current_ready_ip=0;
|
||||
// current_ready_port=0;
|
||||
}
|
||||
int conn_manager_t::exist(address_t addr) {
|
||||
int conn_manager_t::exist(address_t addr)
|
||||
{
|
||||
//u64_t u64=0;
|
||||
//u64=ip;
|
||||
//u64<<=32u;
|
||||
//u64|=port;
|
||||
if (mp.find(addr) != mp.end()) {
|
||||
if(mp.find(addr)!=mp.end())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -176,10 +208,13 @@ conn_info_t *&conn_manager_t::find_insert_p(address_t addr) // be aware,the adr
|
||||
//u64<<=32u;
|
||||
//u64|=port;
|
||||
unordered_map<address_t,conn_info_t*>::iterator it=mp.find(addr);
|
||||
if (it == mp.end()) {
|
||||
if(it==mp.end())
|
||||
{
|
||||
mp[addr]=new conn_info_t;
|
||||
//lru.new_key(addr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//lru.update(addr);
|
||||
}
|
||||
return mp[addr];
|
||||
@@ -191,16 +226,21 @@ conn_info_t &conn_manager_t::find_insert(address_t addr) // be aware,the adress
|
||||
//u64<<=32u;
|
||||
//u64|=port;
|
||||
unordered_map<address_t,conn_info_t*>::iterator it=mp.find(addr);
|
||||
if (it == mp.end()) {
|
||||
if(it==mp.end())
|
||||
{
|
||||
mp[addr]=new conn_info_t;
|
||||
//lru.new_key(addr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//lru.update(addr);
|
||||
}
|
||||
return *mp[addr];
|
||||
}
|
||||
int conn_manager_t::erase(unordered_map<address_t, conn_info_t *>::iterator erase_it) {
|
||||
if (erase_it->second->state.server_current_state == server_ready) {
|
||||
int conn_manager_t::erase(unordered_map<address_t,conn_info_t*>::iterator erase_it)
|
||||
{
|
||||
if(erase_it->second->state.server_current_state==server_ready)
|
||||
{
|
||||
ready_num--;
|
||||
assert(i32_t(ready_num)!=-1);
|
||||
assert(erase_it->second!=0);
|
||||
@@ -212,6 +252,7 @@ int conn_manager_t::erase(unordered_map<address_t, conn_info_t *>::iterator eras
|
||||
assert(erase_it->second->oppsite_const_id!=0);
|
||||
assert(const_id_mp.find(erase_it->second->oppsite_const_id)!=const_id_mp.end());
|
||||
|
||||
|
||||
//assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end());
|
||||
|
||||
const_id_mp.erase(erase_it->second->oppsite_const_id);
|
||||
@@ -223,24 +264,30 @@ int conn_manager_t::erase(unordered_map<address_t, conn_info_t *>::iterator eras
|
||||
//close(erase_it->second->timer_fd);// close will auto delte it from epoll
|
||||
delete(erase_it->second);
|
||||
mp.erase(erase_it->first);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(erase_it->second->blob==0);
|
||||
assert(erase_it->second->timer_fd64 ==0);
|
||||
|
||||
|
||||
assert(erase_it->second->oppsite_const_id==0);
|
||||
delete(erase_it->second);
|
||||
mp.erase(erase_it->first);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int conn_manager_t::clear_inactive() {
|
||||
if (get_current_time() - last_clear_time > conn_clear_interval) {
|
||||
int conn_manager_t::clear_inactive()
|
||||
{
|
||||
if(get_current_time()-last_clear_time>conn_clear_interval)
|
||||
{
|
||||
last_clear_time=get_current_time();
|
||||
return clear_inactive0();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int conn_manager_t::clear_inactive0() {
|
||||
int conn_manager_t::clear_inactive0()
|
||||
{
|
||||
unordered_map<address_t,conn_info_t*>::iterator it;
|
||||
unordered_map<address_t,conn_info_t*>::iterator old_it;
|
||||
|
||||
@@ -257,22 +304,31 @@ int conn_manager_t::clear_inactive0() {
|
||||
num_to_clean=min(num_to_clean,(int)mp.size());
|
||||
u64_t current_time=get_current_time();
|
||||
|
||||
for (;;) {
|
||||
for(;;)
|
||||
{
|
||||
if(cnt>=num_to_clean) break;
|
||||
if(mp.begin()==mp.end()) break;
|
||||
|
||||
if (it == mp.end()) {
|
||||
if(it==mp.end())
|
||||
{
|
||||
it=mp.begin();
|
||||
}
|
||||
|
||||
if (it->second->state.server_current_state == server_ready && current_time - it->second->last_hb_recv_time <= server_conn_timeout) {
|
||||
if(it->second->state.server_current_state==server_ready &¤t_time - it->second->last_hb_recv_time <=server_conn_timeout)
|
||||
{
|
||||
it++;
|
||||
} else if (it->second->state.server_current_state != server_ready && current_time - it->second->last_state_time <= server_handshake_timeout) {
|
||||
}
|
||||
else if(it->second->state.server_current_state!=server_ready&& current_time - it->second->last_state_time <=server_handshake_timeout )
|
||||
{
|
||||
it++;
|
||||
} else if (it->second->blob != 0 && it->second->blob->conv_manager.s.get_size() > 0) {
|
||||
}
|
||||
else if(it->second->blob!=0&&it->second->blob->conv_manager.s.get_size() >0)
|
||||
{
|
||||
assert(it->second->state.server_current_state==server_ready);
|
||||
it++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_info,"[%s:%d]inactive conn cleared \n",it->second->raw_info.recv_info.new_src_ip.get_str1(),it->second->raw_info.recv_info.src_port);
|
||||
old_it=it;
|
||||
it++;
|
||||
@@ -285,10 +341,13 @@ int conn_manager_t::clear_inactive0() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int send_bare(raw_info_t &raw_info,const char* data,int len)//send function with encryption but no anti replay,this is used when client and server verifys each other
|
||||
//you have to design the protocol carefully, so that you wont be affect by relay attack
|
||||
{
|
||||
if (len < 0) {
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_debug,"input_len <0\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -298,6 +357,7 @@ int send_bare(raw_info_t &raw_info, const char *data, int len) // send function
|
||||
char send_data_buf[buf_len]; //buf for send data and send hb
|
||||
char send_data_buf2[buf_len];
|
||||
|
||||
|
||||
//static send_bare[buf_len];
|
||||
iv_t iv=get_true_random_number_64();
|
||||
padding_t padding=get_true_random_number_64();
|
||||
@@ -309,7 +369,8 @@ int send_bare(raw_info_t &raw_info, const char *data, int len) // send function
|
||||
memcpy(send_data_buf+sizeof(iv)+sizeof(padding)+1,data,len);
|
||||
int new_len=len+sizeof(iv)+sizeof(padding)+1;
|
||||
|
||||
if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) {
|
||||
if(my_encrypt(send_data_buf,send_data_buf2,new_len)!=0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
send_raw0(raw_info,send_data_buf2,new_len);
|
||||
@@ -319,22 +380,26 @@ int reserved_parse_bare(const char *input, int input_len, char *&data, int &len)
|
||||
{
|
||||
static char recv_data_buf[buf_len];
|
||||
|
||||
if (input_len < 0) {
|
||||
if(input_len<0)
|
||||
{
|
||||
mylog(log_debug,"input_len <0\n");
|
||||
return -1;
|
||||
}
|
||||
if (my_decrypt(input, recv_data_buf, input_len) != 0) {
|
||||
if(my_decrypt(input,recv_data_buf,input_len)!=0)
|
||||
{
|
||||
mylog(log_debug,"decrypt_fail in recv bare\n");
|
||||
return -1;
|
||||
}
|
||||
if (recv_data_buf[sizeof(iv_t) + sizeof(padding_t)] != 'b') {
|
||||
if(recv_data_buf[sizeof(iv_t)+sizeof(padding_t)]!='b')
|
||||
{
|
||||
mylog(log_debug,"not a bare packet\n");
|
||||
return -1;
|
||||
}
|
||||
len=input_len;
|
||||
data=recv_data_buf+sizeof(iv_t)+sizeof(padding_t)+1;
|
||||
len-=sizeof(iv_t)+sizeof(padding_t)+1;
|
||||
if (len < 0) {
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_debug,"len <0\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -346,18 +411,21 @@ int recv_bare(raw_info_t &raw_info, char *&data, int &len) // recv function wit
|
||||
packet_info_t &send_info=raw_info.send_info;
|
||||
packet_info_t &recv_info=raw_info.recv_info;
|
||||
|
||||
if (recv_raw0(raw_info, data, len) < 0) {
|
||||
if(recv_raw0(raw_info,data,len)<0)
|
||||
{
|
||||
//printf("recv_raw_fail in recv bare\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len >= max_data_len + 1) {
|
||||
if(len>=max_data_len+1)
|
||||
{
|
||||
mylog(log_debug,"data_len=%d >= max_data_len+1,ignored",len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mylog(log_trace,"data len=%d\n",len);
|
||||
if ((raw_mode == mode_faketcp && (recv_info.syn == 1 || recv_info.ack != 1))) {
|
||||
if ((raw_mode == mode_faketcp && (recv_info.syn == 1 || recv_info.ack != 1)))
|
||||
{
|
||||
mylog(log_debug,"unexpect packet type recv_info.syn=%d recv_info.ack=%d \n",recv_info.syn,recv_info.ack);
|
||||
return -1;
|
||||
}
|
||||
@@ -369,14 +437,10 @@ int send_handshake(raw_info_t &raw_info, my_id_t id1, my_id_t id2, my_id_t id3)
|
||||
packet_info_t &send_info=raw_info.send_info;
|
||||
packet_info_t &recv_info=raw_info.recv_info;
|
||||
|
||||
char *data;
|
||||
int len;
|
||||
char * data;int len;
|
||||
//len=sizeof(id_t)*3;
|
||||
if(numbers_to_char(id1,id2,id3,data,len)!=0) return -1;
|
||||
if (send_bare(raw_info, data, len) != 0) {
|
||||
mylog(log_warn, "send bare fail\n");
|
||||
return -1;
|
||||
}
|
||||
if(send_bare(raw_info,data,len)!=0) {mylog(log_warn,"send bare fail\n");return -1;}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
@@ -392,14 +456,17 @@ int recv_handshake(packet_info_t &info,id_t &id1,id_t &id2,id_t &id3)
|
||||
|
||||
int send_safer(conn_info_t &conn_info,char type,const char* data,int len) //safer transfer function with anti-replay,when mutually verification is done.
|
||||
{
|
||||
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
if (type != 'h' && type != 'd') {
|
||||
if(type!='h'&&type!='d')
|
||||
{
|
||||
mylog(log_warn,"first byte is not h or d ,%x\n",type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char send_data_buf[buf_len]; //buf for send data and send hb
|
||||
char send_data_buf2[buf_len];
|
||||
|
||||
@@ -415,6 +482,7 @@ int send_safer(conn_info_t &conn_info, char type, const char *data, int len) //
|
||||
|
||||
memcpy(send_data_buf+sizeof(n_tmp_id)*2,&n_seq,sizeof(n_seq));
|
||||
|
||||
|
||||
send_data_buf[sizeof(n_tmp_id)*2+sizeof(n_seq)]=type;
|
||||
send_data_buf[sizeof(n_tmp_id)*2+sizeof(n_seq)+1]=conn_info.my_roller;
|
||||
|
||||
@@ -422,24 +490,33 @@ int send_safer(conn_info_t &conn_info, char type, const char *data, int len) //
|
||||
|
||||
int new_len=len+sizeof(n_seq)+sizeof(n_tmp_id)*2+2;
|
||||
|
||||
if (g_fix_gro == 0) {
|
||||
if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) {
|
||||
if(g_fix_gro==0)
|
||||
{
|
||||
if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (my_encrypt(send_data_buf, send_data_buf2 + 2, new_len) != 0) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_encrypt(send_data_buf, send_data_buf2+2, new_len) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
write_u16(send_data_buf2,new_len);
|
||||
new_len+=2;
|
||||
if (cipher_mode == cipher_xor) {
|
||||
if(cipher_mode==cipher_xor)
|
||||
{
|
||||
send_data_buf2[0]^=gro_xor[0];
|
||||
send_data_buf2[1]^=gro_xor[1];
|
||||
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cbc) {
|
||||
}
|
||||
else if(cipher_mode==cipher_aes128cbc||cipher_mode==cipher_aes128cbc)
|
||||
{
|
||||
aes_ecb_encrypt1(send_data_buf2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(send_raw0(conn_info.raw_info,send_data_buf2,new_len)!=0) return -1;
|
||||
|
||||
if(after_send_raw0(conn_info.raw_info)!=0) return -1;
|
||||
@@ -460,17 +537,21 @@ int send_data_safer(conn_info_t &conn_info, const char *data, int len, u32_t con
|
||||
int new_len=len+sizeof(n_conv_num);
|
||||
send_safer(conn_info,'d',send_data_buf,new_len);
|
||||
return 0;
|
||||
|
||||
}
|
||||
int reserved_parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &type,char* &data,int &len)//subfunction for recv_safer,allow overlap
|
||||
{
|
||||
static char recv_data_buf[buf_len];
|
||||
|
||||
// char *recv_data_buf=recv_data_buf0; //fix strict alias warning
|
||||
if (my_decrypt(input, recv_data_buf, input_len) != 0) {
|
||||
if(my_decrypt(input,recv_data_buf,input_len)!=0)
|
||||
{
|
||||
//printf("decrypt fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//char *a=recv_data_buf;
|
||||
//id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) );
|
||||
my_id_t h_oppsite_id;
|
||||
@@ -487,7 +568,8 @@ int reserved_parse_safer(conn_info_t &conn_info, const char *input, int input_le
|
||||
memcpy(&h_seq,recv_data_buf +sizeof(my_id_t) *2 ,sizeof(h_seq));
|
||||
h_seq=ntoh64(h_seq);
|
||||
|
||||
if (h_oppsite_id != conn_info.oppsite_id || h_my_id != conn_info.my_id) {
|
||||
if(h_oppsite_id!=conn_info.oppsite_id||h_my_id!=conn_info.my_id)
|
||||
{
|
||||
mylog(log_debug,"id and oppsite_id verification failed %x %x %x %x \n",h_oppsite_id,conn_info.oppsite_id,h_my_id,conn_info.my_id);
|
||||
return -1;
|
||||
}
|
||||
@@ -501,36 +583,45 @@ int reserved_parse_safer(conn_info_t &conn_info, const char *input, int input_le
|
||||
data=recv_data_buf+sizeof(anti_replay_seq_t)+sizeof(my_id_t)*2;
|
||||
len=input_len-(sizeof(anti_replay_seq_t)+sizeof(my_id_t)*2 );
|
||||
|
||||
if (data[0] != 'h' && data[0] != 'd') {
|
||||
|
||||
if(data[0]!='h'&&data[0]!='d')
|
||||
{
|
||||
mylog(log_debug,"first byte is not h or d ,%x\n",data[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t roller=data[1];
|
||||
|
||||
|
||||
type=data[0];
|
||||
data+=2;
|
||||
len-=2;
|
||||
|
||||
if (len < 0) {
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_debug,"len <0 ,%d\n",len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (roller != conn_info.oppsite_roller) {
|
||||
if(roller!=conn_info.oppsite_roller)
|
||||
{
|
||||
conn_info.oppsite_roller=roller;
|
||||
conn_info.last_oppsite_roller_time=get_current_time();
|
||||
}
|
||||
if(hb_mode==0)
|
||||
conn_info.my_roller++;//increase on a successful recv
|
||||
else if (hb_mode == 1) {
|
||||
else if(hb_mode==1)
|
||||
{
|
||||
if(type=='h')
|
||||
conn_info.my_roller++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"unknow hb_mode\n");
|
||||
myexit(-1);
|
||||
}
|
||||
|
||||
|
||||
if(after_recv_raw0(conn_info.raw_info)!=0) return -1; //TODO might need to move this function to somewhere else after --fix-gro is introduced
|
||||
|
||||
return 0;
|
||||
@@ -540,8 +631,7 @@ int recv_safer_notused(conn_info_t &conn_info, char &type, char *&data, int &len
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
char *recv_data;
|
||||
int recv_len;
|
||||
char * recv_data;int recv_len;
|
||||
//static char recv_data_buf[buf_len];
|
||||
|
||||
if(recv_raw0(conn_info.raw_info,recv_data,recv_len)!=0) return -1;
|
||||
@@ -554,8 +644,7 @@ int recv_safer_multi(conn_info_t &conn_info, vector<char> &type_arr, vector<stri
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
char *recv_data;
|
||||
int recv_len;
|
||||
char * recv_data;int recv_len;
|
||||
assert(type_arr.empty());
|
||||
assert(data_arr.empty());
|
||||
|
||||
@@ -565,45 +654,55 @@ int recv_safer_multi(conn_info_t &conn_info, vector<char> &type_arr, vector<stri
|
||||
char *data;
|
||||
int len;
|
||||
|
||||
if (g_fix_gro == 0) {
|
||||
if(g_fix_gro==0)
|
||||
{
|
||||
int ret = reserved_parse_safer(conn_info, recv_data, recv_len, type, data, len);
|
||||
if (ret == 0) {
|
||||
if(ret==0)
|
||||
{
|
||||
type_arr.push_back(type);
|
||||
data_arr.emplace_back(data,data+len);
|
||||
//std::copy(data,data+len,data_arr[0]);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
char *ori_recv_data=recv_data;
|
||||
int ori_recv_len=recv_len;
|
||||
//mylog(log_debug,"recv_len:%d\n",recv_len);
|
||||
int cnt=0;
|
||||
while (recv_len >= 16) {
|
||||
while(recv_len>=16)
|
||||
{
|
||||
cnt++;
|
||||
int single_len_no_xor;
|
||||
single_len_no_xor=read_u16(recv_data);
|
||||
int single_len;
|
||||
if (cipher_mode == cipher_xor) {
|
||||
if(cipher_mode==cipher_xor)
|
||||
{
|
||||
recv_data[0]^=gro_xor[0];
|
||||
recv_data[1]^=gro_xor[1];
|
||||
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cbc) {
|
||||
}
|
||||
else if(cipher_mode==cipher_aes128cbc||cipher_mode==cipher_aes128cbc)
|
||||
{
|
||||
aes_ecb_decrypt1(recv_data);
|
||||
}
|
||||
single_len=read_u16(recv_data);
|
||||
recv_len-=2;
|
||||
recv_data+=2;
|
||||
if (single_len > recv_len) {
|
||||
if(single_len > recv_len)
|
||||
{
|
||||
mylog(log_debug,"illegal single_len %d(%d), recv_len %d left,dropped\n",single_len,single_len_no_xor,recv_len);
|
||||
break;
|
||||
}
|
||||
if (single_len > max_data_len) {
|
||||
if(single_len> max_data_len )
|
||||
{
|
||||
mylog(log_warn,"single_len %d(%d) > %d, maybe you need to turn down mtu at upper level\n",single_len,single_len_no_xor,max_data_len);
|
||||
break;
|
||||
}
|
||||
|
||||
int ret = reserved_parse_safer(conn_info, recv_data, single_len, type, data, len);
|
||||
|
||||
if (ret != 0) {
|
||||
if(ret!=0)
|
||||
{
|
||||
mylog(log_debug,"parse failed, offset= %d,single_len=%d(%d)\n",(int)(recv_data-ori_recv_data),single_len,single_len_no_xor);
|
||||
} else{
|
||||
type_arr.push_back(type);
|
||||
@@ -613,13 +712,15 @@ int recv_safer_multi(conn_info_t &conn_info, vector<char> &type_arr, vector<stri
|
||||
recv_data+=single_len;
|
||||
recv_len-=single_len;
|
||||
}
|
||||
if (cnt > 1) {
|
||||
if(cnt>1)
|
||||
{
|
||||
mylog(log_debug,"got a suspected gro packet, %d packets recovered, recv_len=%d, loop_cnt=%d\n",(int)data_arr.size(),ori_recv_len,cnt);
|
||||
}
|
||||
return 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
|
||||
{
|
||||
@@ -637,8 +738,7 @@ void server_clear_function(u64_t u64) // used in conv_manager in server mode.fo
|
||||
{
|
||||
mylog(log_fatal,"fd:%d epoll delete failed!!!!\n",fd);
|
||||
myexit(-1); //this shouldnt happen
|
||||
}*/
|
||||
// no need
|
||||
}*/ //no need
|
||||
|
||||
/*ret= close(fd); //closed fd should be auto removed from epoll
|
||||
|
||||
|
96
connection.h
96
connection.h
@@ -50,29 +50,36 @@ struct conv_manager_t // manage the udp connections
|
||||
|
||||
long long last_clear_time;
|
||||
|
||||
conv_manager_t() {
|
||||
conv_manager_t()
|
||||
{
|
||||
//clear_it=conv_last_active_time.begin();
|
||||
long long last_clear_time=0;
|
||||
additional_clear_function=0;
|
||||
}
|
||||
~conv_manager_t() {
|
||||
~conv_manager_t()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
int get_size() {
|
||||
int get_size()
|
||||
{
|
||||
return conv_to_data.size();
|
||||
}
|
||||
void reserve() {
|
||||
void reserve()
|
||||
{
|
||||
data_to_conv.reserve(10007);
|
||||
conv_to_data.reserve(10007);
|
||||
//conv_last_active_time.reserve(10007);
|
||||
|
||||
lru.mp.reserve(10007);
|
||||
}
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
if(disable_conv_clear) return ;
|
||||
|
||||
if (additional_clear_function != 0) {
|
||||
for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) {
|
||||
if(additional_clear_function!=0)
|
||||
{
|
||||
for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++)
|
||||
{
|
||||
//int fd=int((it->second<<32u)>>32u);
|
||||
additional_clear_function( it->second);
|
||||
}
|
||||
@@ -84,42 +91,53 @@ struct conv_manager_t // manage the udp connections
|
||||
//conv_last_active_time.clear();
|
||||
|
||||
//clear_it=conv_last_active_time.begin();
|
||||
|
||||
}
|
||||
u32_t get_new_conv() {
|
||||
u32_t get_new_conv()
|
||||
{
|
||||
u32_t conv=get_true_random_number_nz();
|
||||
while (conv_to_data.find(conv) != conv_to_data.end()) {
|
||||
while(conv_to_data.find(conv)!=conv_to_data.end())
|
||||
{
|
||||
conv=get_true_random_number_nz();
|
||||
}
|
||||
return conv;
|
||||
}
|
||||
int is_conv_used(u32_t conv) {
|
||||
int is_conv_used(u32_t conv)
|
||||
{
|
||||
return conv_to_data.find(conv)!=conv_to_data.end();
|
||||
}
|
||||
int is_data_used(T data) {
|
||||
int is_data_used(T data)
|
||||
{
|
||||
return data_to_conv.find(data)!=data_to_conv.end();
|
||||
}
|
||||
u32_t find_conv_by_data(T data) {
|
||||
u32_t find_conv_by_data(T data)
|
||||
{
|
||||
return data_to_conv[data];
|
||||
}
|
||||
T find_data_by_conv(u32_t conv) {
|
||||
T find_data_by_conv(u32_t conv)
|
||||
{
|
||||
return conv_to_data[conv];
|
||||
}
|
||||
int update_active_time(u32_t conv) {
|
||||
int update_active_time(u32_t conv)
|
||||
{
|
||||
//return conv_last_active_time[conv]=get_current_time();
|
||||
lru.update(conv);
|
||||
return 0;
|
||||
}
|
||||
int insert_conv(u32_t conv, T data) {
|
||||
int insert_conv(u32_t conv,T data)
|
||||
{
|
||||
data_to_conv[data]=conv;
|
||||
conv_to_data[conv]=data;
|
||||
//conv_last_active_time[conv]=get_current_time();
|
||||
lru.new_key(conv);
|
||||
return 0;
|
||||
}
|
||||
int erase_conv(u32_t conv) {
|
||||
int erase_conv(u32_t conv)
|
||||
{
|
||||
if(disable_conv_clear) return 0;
|
||||
T data=conv_to_data[conv];
|
||||
if (additional_clear_function != 0) {
|
||||
if(additional_clear_function!=0)
|
||||
{
|
||||
additional_clear_function(data);
|
||||
}
|
||||
conv_to_data.erase(conv);
|
||||
@@ -128,16 +146,20 @@ struct conv_manager_t // manage the udp connections
|
||||
lru.erase(conv);
|
||||
return 0;
|
||||
}
|
||||
int clear_inactive(char *info = 0) {
|
||||
if (get_current_time() - last_clear_time > conv_clear_interval) {
|
||||
int clear_inactive(char * info=0)
|
||||
{
|
||||
if(get_current_time()-last_clear_time>conv_clear_interval)
|
||||
{
|
||||
last_clear_time=get_current_time();
|
||||
return clear_inactive0(info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int clear_inactive0(char *info) {
|
||||
int clear_inactive0(char * info)
|
||||
{
|
||||
if(disable_conv_clear) return 0;
|
||||
|
||||
|
||||
unordered_map<u32_t,u64_t>::iterator it;
|
||||
unordered_map<u32_t,u64_t>::iterator old_it;
|
||||
|
||||
@@ -150,7 +172,8 @@ struct conv_manager_t // manage the udp connections
|
||||
num_to_clean=min(num_to_clean,size);
|
||||
|
||||
my_time_t current_time=get_current_time();
|
||||
for (;;) {
|
||||
for(;;)
|
||||
{
|
||||
if(cnt>=num_to_clean) break;
|
||||
if(lru.empty()) break;
|
||||
|
||||
@@ -160,9 +183,12 @@ struct conv_manager_t // manage the udp connections
|
||||
if(current_time- ts < conv_timeout) break;
|
||||
|
||||
erase_conv(conv);
|
||||
if (info == 0) {
|
||||
if(info==0)
|
||||
{
|
||||
mylog(log_info,"conv %x cleared\n",conv);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_info,"[%s]conv %x cleared\n",info,conv);
|
||||
}
|
||||
cnt++;
|
||||
@@ -170,6 +196,7 @@ struct conv_manager_t // manage the udp connections
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
conv_manager_t();
|
||||
~conv_manager_t();
|
||||
@@ -195,18 +222,26 @@ struct blob_t : not_copy_able_t // used in conn_info_t.
|
||||
conv_manager_t<address_t> c;
|
||||
conv_manager_t<u64_t> s;
|
||||
//avoid templates here and there, avoid pointer and type cast
|
||||
tmp_union_t() {
|
||||
if (program_mode == client_mode) {
|
||||
tmp_union_t()
|
||||
{
|
||||
if(program_mode==client_mode)
|
||||
{
|
||||
new( &c ) conv_manager_t<address_t>();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(program_mode==server_mode);
|
||||
new( &s ) conv_manager_t<u64_t>();
|
||||
}
|
||||
}
|
||||
~tmp_union_t() {
|
||||
if (program_mode == client_mode) {
|
||||
~tmp_union_t()
|
||||
{
|
||||
if(program_mode==client_mode)
|
||||
{
|
||||
c.~conv_manager_t<address_t>();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(program_mode==server_mode);
|
||||
s.~conv_manager_t<u64_t>();
|
||||
}
|
||||
@@ -229,6 +264,7 @@ struct conn_info_t // stores info for a raw connection.for client ,there is onl
|
||||
my_id_t my_id;
|
||||
my_id_t oppsite_id;
|
||||
|
||||
|
||||
fd64_t timer_fd64;
|
||||
fd64_t udp_fd64;
|
||||
|
||||
@@ -258,6 +294,7 @@ struct conn_info_t // stores info for a raw connection.for client ,there is onl
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
u32_t ready_num;
|
||||
|
||||
//unordered_map<int,conn_info_t *> udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search
|
||||
@@ -291,6 +328,7 @@ struct conn_manager_t // manager for connections. for client,we dont need conn_
|
||||
int erase(unordered_map<address_t,conn_info_t*>::iterator erase_it);
|
||||
int clear_inactive();
|
||||
int clear_inactive0();
|
||||
|
||||
};
|
||||
|
||||
extern conn_manager_t conn_manager;
|
||||
|
@@ -161,7 +161,7 @@ other options:
|
||||
如果要最大的安全性建议用aes128cbc+hmac_sha1。如果要运行在路由器上,建议用xor+simple,可以节省CPU。但是注意xor+simple只能骗过防火墙的包检测,不能防止真正的攻击者。
|
||||
|
||||
### `--seq-mode`
|
||||
faketcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和真正的tcp流量区分开来(虽然大部分ISP不太可能做这种程度的包检测)。seq-mode可以改变一些seq ack的行为。如果遇到了连接问题,可以尝试更改。在我这边的移动线路用3种模式都没问题。
|
||||
facktcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和真正的tcp流量区分开来(虽然大部分ISP不太可能做这种程度的包检测)。seq-mode可以改变一些seq ack的行为。如果遇到了连接问题,可以尝试更改。在我这边的移动线路用3种模式都没问题。
|
||||
|
||||
### `--keep-rule`
|
||||
定期主动检查iptables,如果udp2raw添加的iptables规则丢了,就重新添加。在一些iptables可能会被其他程序清空的情况下(比如梅林固件和openwrt的路由器)格外有用。
|
||||
|
363
encrypt.cpp
Normal file → Executable file
363
encrypt.cpp
Normal file → Executable file
@@ -28,20 +28,9 @@ unsigned char cipher_key_decrypt[cipher_key_len + 100]; // key for aes etc.
|
||||
|
||||
char gro_xor[256+100];//dirty fix for gro
|
||||
|
||||
unordered_map<int, const char *> auth_mode_tostring = {
|
||||
{auth_none, "none"},
|
||||
{auth_md5, "md5"},
|
||||
{auth_crc32, "crc32"},
|
||||
{auth_simple, "simple"},
|
||||
{auth_hmac_sha1, "hmac_sha1"},
|
||||
};
|
||||
unordered_map<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"},{auth_hmac_sha1,"hmac_sha1"},};
|
||||
|
||||
unordered_map<int, const char *> cipher_mode_tostring = {
|
||||
{cipher_none, "none"},
|
||||
{cipher_aes128cfb, "aes128cfb"},
|
||||
{cipher_aes128cbc, "aes128cbc"},
|
||||
{cipher_xor, "xor"},
|
||||
};
|
||||
unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cfb,"aes128cfb"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"},};
|
||||
//TODO aes-gcm
|
||||
|
||||
auth_mode_t auth_mode=auth_md5;
|
||||
@@ -52,7 +41,8 @@ int aes128cfb_old = 0;
|
||||
|
||||
//TODO key negotiation and forward secrecy
|
||||
|
||||
int my_init_keys(const char *user_passwd, int is_client) {
|
||||
int my_init_keys(const char * user_passwd,int is_client)
|
||||
{
|
||||
char tmp[1000]="";
|
||||
int len=strlen(user_passwd);
|
||||
|
||||
@@ -62,9 +52,11 @@ int my_init_keys(const char *user_passwd, int is_client) {
|
||||
|
||||
md5((uint8_t*)tmp,strlen(tmp),(uint8_t*)normal_key);
|
||||
|
||||
|
||||
if(auth_mode==auth_hmac_sha1)
|
||||
is_hmac_used=1;
|
||||
if (is_hmac_used || g_fix_gro || 1) {
|
||||
if(is_hmac_used||g_fix_gro||1)
|
||||
{
|
||||
unsigned char salt[400]="";
|
||||
char salt_text[400]="udp2raw_salt1";
|
||||
md5((uint8_t*)(salt_text),strlen(salt_text),salt); //TODO different salt per session
|
||||
@@ -80,15 +72,14 @@ int my_init_keys(const char *user_passwd, int is_client) {
|
||||
const char *info_cipher_encrypt="cipher_key server-->client";
|
||||
const char *info_cipher_decrypt="cipher_key client-->server";
|
||||
|
||||
if (is_client) {
|
||||
if(is_client)
|
||||
{
|
||||
const char *tmp;
|
||||
tmp = info_hmac_encrypt;
|
||||
info_hmac_encrypt = info_hmac_decrypt;
|
||||
info_hmac_decrypt = tmp;
|
||||
tmp = info_cipher_encrypt;
|
||||
info_cipher_encrypt = info_cipher_decrypt;
|
||||
info_cipher_decrypt = tmp;
|
||||
} else {
|
||||
tmp=info_hmac_encrypt; info_hmac_encrypt=info_hmac_decrypt;info_hmac_decrypt=tmp;
|
||||
tmp=info_cipher_encrypt; info_cipher_encrypt=info_cipher_decrypt;info_cipher_decrypt=tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
//nop
|
||||
}
|
||||
|
||||
@@ -152,7 +143,8 @@ void simple_hash(unsigned char *str, int len, unsigned char res[8]) // djb2+ sd
|
||||
u32_t hash2 = 0;
|
||||
int c;
|
||||
int i=0;
|
||||
while (c = *str++, i++ != len) {
|
||||
while(c = *str++,i++!=len)
|
||||
{
|
||||
// hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
hash = ((hash << 5) + hash)^c; /* (hash * 33) ^ c */
|
||||
hash2 = c + (hash2 << 6) + (hash2 << 16) - hash2;
|
||||
@@ -164,14 +156,16 @@ void simple_hash(unsigned char *str, int len, unsigned char res[8]) // djb2+ sd
|
||||
memcpy(res+sizeof(hash),&hash2,sizeof(hash2));
|
||||
}
|
||||
|
||||
int auth_md5_cal(const char *data, char *output, int &len) {
|
||||
int auth_md5_cal(const char *data,char * output,int &len)
|
||||
{
|
||||
memcpy(output,data,len);//TODO inefficient code
|
||||
md5((unsigned char *)output,len,(unsigned char *)(output+len));
|
||||
len+=16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auth_hmac_sha1_cal(const char *data, char *output, int &len) {
|
||||
int auth_hmac_sha1_cal(const char *data,char * output,int &len)
|
||||
{
|
||||
mylog(log_trace,"auth_hmac_sha1_cal() is called\n");
|
||||
memcpy(output,data,len);//TODO inefficient code
|
||||
sha1_hmac(hmac_key_encrypt, 20, (const unsigned char *)data, len,(unsigned char *)(output+len));
|
||||
@@ -180,9 +174,11 @@ int auth_hmac_sha1_cal(const char *data, char *output, int &len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auth_hmac_sha1_verify(const char *data, int &len) {
|
||||
int auth_hmac_sha1_verify(const char *data,int &len)
|
||||
{
|
||||
mylog(log_trace,"auth_hmac_sha1_verify() is called\n");
|
||||
if (len < 20) {
|
||||
if(len<20)
|
||||
{
|
||||
mylog(log_trace,"auth_hmac_sha1_verify len<20\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -190,7 +186,8 @@ int auth_hmac_sha1_verify(const char *data, int &len) {
|
||||
|
||||
sha1_hmac(hmac_key_decrypt, 20, (const unsigned char *)data, len-20,(unsigned char *)(res));
|
||||
|
||||
if (memcmp(res, data + len - 20, 20) != 0) {
|
||||
if(memcmp(res,data+len-20,20)!=0)
|
||||
{
|
||||
mylog(log_trace,"auth_hmac_sha1 check failed\n");
|
||||
return -2;
|
||||
}
|
||||
@@ -198,7 +195,8 @@ int auth_hmac_sha1_verify(const char *data, int &len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auth_crc32_cal(const char *data, char *output, int &len) {
|
||||
int auth_crc32_cal(const char *data,char * output,int &len)
|
||||
{
|
||||
memcpy(output,data,len);//TODO inefficient code
|
||||
unsigned int ret=crc32h((unsigned char *)output,len);
|
||||
unsigned int ret_n=htonl(ret);
|
||||
@@ -207,14 +205,16 @@ int auth_crc32_cal(const char *data, char *output, int &len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auth_simple_cal(const char *data, char *output, int &len) {
|
||||
int auth_simple_cal(const char *data,char * output,int &len)
|
||||
{
|
||||
//char res[4];
|
||||
memcpy(output,data,len);//TODO inefficient code
|
||||
simple_hash((unsigned char *)output,len,(unsigned char *)(output+len));
|
||||
len+=8;
|
||||
return 0;
|
||||
}
|
||||
int auth_simple_verify(const char *data, int &len) {
|
||||
int auth_simple_verify(const char *data,int &len)
|
||||
{
|
||||
if(len<8) return -1;
|
||||
unsigned char res[8];
|
||||
len-=8;
|
||||
@@ -224,12 +224,16 @@ int auth_simple_verify(const char *data, int &len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auth_none_cal(const char *data, char *output, int &len) {
|
||||
|
||||
int auth_none_cal(const char *data,char * output,int &len)
|
||||
{
|
||||
memcpy(output,data,len);
|
||||
return 0;
|
||||
}
|
||||
int auth_md5_verify(const char *data, int &len) {
|
||||
if (len < 16) {
|
||||
int auth_md5_verify(const char *data,int &len)
|
||||
{
|
||||
if(len<16)
|
||||
{
|
||||
mylog(log_trace,"auth_md5_verify len<16\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -237,14 +241,16 @@ int auth_md5_verify(const char *data, int &len) {
|
||||
|
||||
md5((unsigned char *)data,len-16,(unsigned char *)md5_res);
|
||||
|
||||
if (memcmp(md5_res, data + len - 16, 16) != 0) {
|
||||
if(memcmp(md5_res,data+len-16,16)!=0)
|
||||
{
|
||||
mylog(log_trace,"auth_md5_verify md5 check failed\n");
|
||||
return -2;
|
||||
}
|
||||
len-=16;
|
||||
return 0;
|
||||
}
|
||||
int auth_none_verify(const char *data, int &len) {
|
||||
int auth_none_verify(const char *data,int &len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -270,10 +276,12 @@ int cipher_xor_decrypt(const char *data, char *output, int &len, char *key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int padding(char *data, int &data_len, int padding_num) {
|
||||
int padding(char *data ,int &data_len,int padding_num)
|
||||
{
|
||||
int old_len=data_len;
|
||||
data_len+=1;
|
||||
if (data_len % padding_num != 0) {
|
||||
if(data_len%padding_num!=0)
|
||||
{
|
||||
data_len= (data_len/padding_num)*padding_num+padding_num;
|
||||
}
|
||||
unsigned char * p= (unsigned char *)&data[data_len-1];
|
||||
@@ -281,48 +289,53 @@ int padding(char *data, int &data_len, int padding_num) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int de_padding(const char *data, int &data_len, int padding_num) {
|
||||
int de_padding(const char *data ,int &data_len,int padding_num)
|
||||
{
|
||||
if(data_len==0) return -1;
|
||||
if((uint8_t)data[data_len-1] >padding_num) return -1;
|
||||
data_len-=(uint8_t)data[data_len-1];
|
||||
if (data_len < 0) {
|
||||
if(data_len<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void aes_ecb_encrypt(const char *data, char *output) {
|
||||
void aes_ecb_encrypt(const char *data,char *output)
|
||||
{
|
||||
static int first_time=1;
|
||||
char *key=(char*)cipher_key_encrypt;
|
||||
if (aes_key_optimize) {
|
||||
if (first_time == 0)
|
||||
key = 0;
|
||||
else
|
||||
first_time = 0;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
AES_ECB_encrypt_buffer((uint8_t*)data,(uint8_t*)key,(uint8_t*)output);
|
||||
}
|
||||
void aes_ecb_encrypt1(char *data) {
|
||||
void aes_ecb_encrypt1(char *data)
|
||||
{
|
||||
char buf[16];
|
||||
memcpy(buf,data,16);
|
||||
aes_ecb_encrypt(buf,data);
|
||||
}
|
||||
void aes_ecb_decrypt(const char *data, char *output) {
|
||||
void aes_ecb_decrypt(const char *data,char *output)
|
||||
{
|
||||
static int first_time=1;
|
||||
char *key=(char*)cipher_key_decrypt;
|
||||
if (aes_key_optimize) {
|
||||
if (first_time == 0)
|
||||
key = 0;
|
||||
else
|
||||
first_time = 0;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
AES_ECB_decrypt_buffer((uint8_t*)data,(uint8_t*)key,(uint8_t*)output);
|
||||
}
|
||||
void aes_ecb_decrypt1(char *data) {
|
||||
void aes_ecb_decrypt1(char *data)
|
||||
{
|
||||
char buf[16];
|
||||
memcpy(buf,data,16);
|
||||
aes_ecb_decrypt(buf,data);
|
||||
}
|
||||
int cipher_aes128cbc_encrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_aes128cbc_encrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
static int first_time=1;
|
||||
|
||||
char buf[buf_len];
|
||||
@@ -330,81 +343,83 @@ int cipher_aes128cbc_encrypt(const char *data, char *output, int &len, char *key
|
||||
|
||||
if(padding(buf,len,16)<0) return -1;
|
||||
|
||||
if (aes_key_optimize) {
|
||||
if (first_time == 0)
|
||||
key = 0;
|
||||
else
|
||||
first_time = 0;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
|
||||
AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
||||
return 0;
|
||||
}
|
||||
int cipher_aes128cfb_encrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_aes128cfb_encrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
static int first_time=1;
|
||||
assert(len>=16);
|
||||
|
||||
char buf[buf_len];
|
||||
memcpy(buf,data,len);//TODO inefficient code
|
||||
if (aes_key_optimize) {
|
||||
if (first_time == 0)
|
||||
key = 0;
|
||||
else
|
||||
first_time = 0;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
if (!aes128cfb_old) {
|
||||
if(!aes128cfb_old)
|
||||
{
|
||||
aes_ecb_encrypt(data,buf); //encrypt the first block
|
||||
}
|
||||
|
||||
AES_CFB_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
||||
return 0;
|
||||
}
|
||||
int auth_crc32_verify(const char *data, int &len) {
|
||||
if (len < int(sizeof(unsigned int))) {
|
||||
int auth_crc32_verify(const char *data,int &len)
|
||||
{
|
||||
if(len<int(sizeof(unsigned int)))
|
||||
{
|
||||
mylog(log_debug,"auth_crc32_verify len<%d\n",int(sizeof(unsigned int)));
|
||||
return -1;
|
||||
}
|
||||
unsigned int ret=crc32h((unsigned char *)data,len-sizeof(unsigned int));
|
||||
unsigned int ret_n=htonl(ret);
|
||||
|
||||
if (memcmp(data + len - sizeof(unsigned int), &ret_n, sizeof(unsigned int)) != 0) {
|
||||
if(memcmp(data+len-sizeof(unsigned int),&ret_n,sizeof(unsigned int))!=0)
|
||||
{
|
||||
mylog(log_debug,"auth_crc32_verify memcmp fail\n");
|
||||
return -1;
|
||||
}
|
||||
len-=sizeof(unsigned int);
|
||||
return 0;
|
||||
}
|
||||
int cipher_none_encrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_none_encrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
memcpy(output,data,len);
|
||||
return 0;
|
||||
}
|
||||
int cipher_aes128cbc_decrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_aes128cbc_decrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
static int first_time=1;
|
||||
if (len % 16 != 0) {
|
||||
mylog(log_debug, "len%%16!=0\n");
|
||||
return -1;
|
||||
}
|
||||
if (aes_key_optimize) {
|
||||
if (first_time == 0)
|
||||
key = 0;
|
||||
else
|
||||
first_time = 0;
|
||||
if(len%16 !=0) {mylog(log_debug,"len%%16!=0\n");return -1;}
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
||||
if(de_padding(output,len,16)<0) return -1;
|
||||
return 0;
|
||||
}
|
||||
int cipher_aes128cfb_decrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_aes128cfb_decrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
static int first_time=1;
|
||||
if(len<16) return -1;
|
||||
|
||||
if (aes_key_optimize) {
|
||||
if (first_time == 0)
|
||||
key = 0;
|
||||
else
|
||||
first_time = 0;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
|
||||
|
||||
AES_CFB_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
||||
|
||||
if(!aes128cfb_old)
|
||||
@@ -413,97 +428,81 @@ int cipher_aes128cfb_decrypt(const char *data, char *output, int &len, char *key
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cipher_none_decrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_none_decrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
memcpy(output,data,len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auth_cal(const char *data, char *output, int &len) {
|
||||
int auth_cal(const char *data,char * output,int &len)
|
||||
{
|
||||
mylog(log_trace,"auth:%d\n",auth_mode);
|
||||
switch (auth_mode) {
|
||||
case auth_crc32:
|
||||
return auth_crc32_cal(data, output, len);
|
||||
case auth_md5:
|
||||
return auth_md5_cal(data, output, len);
|
||||
case auth_simple:
|
||||
return auth_simple_cal(data, output, len);
|
||||
case auth_none:
|
||||
return auth_none_cal(data, output, len);
|
||||
case auth_hmac_sha1:
|
||||
return auth_hmac_sha1_cal(data, output, len);
|
||||
switch(auth_mode)
|
||||
{
|
||||
case auth_crc32:return auth_crc32_cal(data, output, len);
|
||||
case auth_md5:return auth_md5_cal(data, output, len);
|
||||
case auth_simple:return auth_simple_cal(data, output, len);
|
||||
case auth_none:return auth_none_cal(data, output, len);
|
||||
case auth_hmac_sha1:return auth_hmac_sha1_cal(data,output,len);
|
||||
//default: return auth_md5_cal(data,output,len);//default;
|
||||
default:
|
||||
assert(0 == 1);
|
||||
default: assert(0==1);
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
int auth_verify(const char *data, int &len) {
|
||||
int auth_verify(const char *data,int &len)
|
||||
{
|
||||
mylog(log_trace,"auth:%d\n",auth_mode);
|
||||
switch (auth_mode) {
|
||||
case auth_crc32:
|
||||
return auth_crc32_verify(data, len);
|
||||
case auth_md5:
|
||||
return auth_md5_verify(data, len);
|
||||
case auth_simple:
|
||||
return auth_simple_verify(data, len);
|
||||
case auth_none:
|
||||
return auth_none_verify(data, len);
|
||||
case auth_hmac_sha1:
|
||||
return auth_hmac_sha1_verify(data, len);
|
||||
switch(auth_mode)
|
||||
{
|
||||
case auth_crc32:return auth_crc32_verify(data, len);
|
||||
case auth_md5:return auth_md5_verify(data, len);
|
||||
case auth_simple:return auth_simple_verify(data, len);
|
||||
case auth_none:return auth_none_verify(data, len);
|
||||
case auth_hmac_sha1:return auth_hmac_sha1_verify(data,len);
|
||||
//default: return auth_md5_verify(data,len);//default
|
||||
default:
|
||||
assert(0 == 1);
|
||||
default: assert(0==1);
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
int cipher_encrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_encrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
mylog(log_trace,"cipher:%d\n",cipher_mode);
|
||||
switch (cipher_mode) {
|
||||
case cipher_aes128cbc:
|
||||
return cipher_aes128cbc_encrypt(data, output, len, key);
|
||||
case cipher_aes128cfb:
|
||||
return cipher_aes128cfb_encrypt(data, output, len, key);
|
||||
case cipher_xor:
|
||||
return cipher_xor_encrypt(data, output, len, key);
|
||||
case cipher_none:
|
||||
return cipher_none_encrypt(data, output, len, key);
|
||||
switch(cipher_mode)
|
||||
{
|
||||
case cipher_aes128cbc:return cipher_aes128cbc_encrypt(data,output,len, key);
|
||||
case cipher_aes128cfb:return cipher_aes128cfb_encrypt(data,output,len, key);
|
||||
case cipher_xor:return cipher_xor_encrypt(data,output,len, key);
|
||||
case cipher_none:return cipher_none_encrypt(data,output,len, key);
|
||||
//default:return cipher_aes128cbc_encrypt(data,output,len, key);
|
||||
default:
|
||||
assert(0 == 1);
|
||||
default: assert(0==1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int cipher_decrypt(const char *data, char *output, int &len, char *key) {
|
||||
int cipher_decrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
mylog(log_trace,"cipher:%d\n",cipher_mode);
|
||||
switch (cipher_mode) {
|
||||
case cipher_aes128cbc:
|
||||
return cipher_aes128cbc_decrypt(data, output, len, key);
|
||||
case cipher_aes128cfb:
|
||||
return cipher_aes128cfb_decrypt(data, output, len, key);
|
||||
case cipher_xor:
|
||||
return cipher_xor_decrypt(data, output, len, key);
|
||||
case cipher_none:
|
||||
return cipher_none_decrypt(data, output, len, key);
|
||||
switch(cipher_mode)
|
||||
{
|
||||
case cipher_aes128cbc:return cipher_aes128cbc_decrypt(data,output,len, key);
|
||||
case cipher_aes128cfb:return cipher_aes128cfb_decrypt(data,output,len, key);
|
||||
case cipher_xor:return cipher_xor_decrypt(data,output,len, key);
|
||||
case cipher_none:return cipher_none_decrypt(data,output,len, key);
|
||||
// default: return cipher_aes128cbc_decrypt(data,output,len,key);
|
||||
default:
|
||||
assert(0 == 1);
|
||||
default: assert(0==1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int encrypt_AE(const char *data, char *output, int &len /*,char * key*/) {
|
||||
int encrypt_AE(const char *data,char *output,int &len /*,char * key*/)
|
||||
{
|
||||
mylog(log_trace,"encrypt_AE is called\n");
|
||||
char buf[buf_len];
|
||||
char buf2[buf_len];
|
||||
memcpy(buf,data,len);
|
||||
if (cipher_encrypt(buf, buf2, len, (char *)cipher_key_encrypt) != 0) {
|
||||
mylog(log_debug, "cipher_encrypt failed ");
|
||||
return -1;
|
||||
}
|
||||
if (auth_cal(buf2, output, len) != 0) {
|
||||
mylog(log_debug, "auth_cal failed ");
|
||||
return -1;
|
||||
}
|
||||
if(cipher_encrypt(buf,buf2,len,(char *)cipher_key_encrypt) !=0) {mylog(log_debug,"cipher_encrypt failed ");return -1;}
|
||||
if(auth_cal(buf2,output,len)!=0) {mylog(log_debug,"auth_cal failed ");return -1;}
|
||||
|
||||
//printf("%d %x %x\n",len,(int)(output[0]),(int)(output[1]));
|
||||
//print_binary_chars(output,len);
|
||||
@@ -512,77 +511,59 @@ int encrypt_AE(const char *data, char *output, int &len /*,char * key*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decrypt_AE(const char *data, char *output, int &len /*,char * key*/) {
|
||||
int decrypt_AE(const char *data,char *output,int &len /*,char * key*/)
|
||||
{
|
||||
mylog(log_trace,"decrypt_AE is called\n");
|
||||
//printf("%d %x %x\n",len,(int)(data[0]),(int)(data[1]));
|
||||
//print_binary_chars(data,len);
|
||||
|
||||
if (auth_verify(data, len) != 0) {
|
||||
mylog(log_debug, "auth_verify failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (cipher_decrypt(data, output, len, (char *)cipher_key_decrypt) != 0) {
|
||||
mylog(log_debug, "cipher_decrypt failed \n");
|
||||
return -1;
|
||||
}
|
||||
if(auth_verify(data,len)!=0) {mylog(log_debug,"auth_verify failed\n");return -1;}
|
||||
if(cipher_decrypt(data,output,len,(char *)cipher_key_decrypt) !=0) {mylog(log_debug,"cipher_decrypt failed \n"); return -1;}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_encrypt(const char *data, char *output, int &len /*,char * key*/) {
|
||||
if (len < 0) {
|
||||
mylog(log_trace, "len<0");
|
||||
return -1;
|
||||
}
|
||||
if (len > max_data_len) {
|
||||
mylog(log_warn, "len>max_data_len");
|
||||
return -1;
|
||||
}
|
||||
int my_encrypt(const char *data,char *output,int &len /*,char * key*/)
|
||||
{
|
||||
if(len<0) {mylog(log_trace,"len<0");return -1;}
|
||||
if(len>max_data_len) {mylog(log_warn,"len>max_data_len");return -1;}
|
||||
|
||||
if(is_hmac_used)
|
||||
return encrypt_AE(data,output,len);
|
||||
|
||||
|
||||
char buf[buf_len];
|
||||
char buf2[buf_len];
|
||||
memcpy(buf,data,len);
|
||||
if (auth_cal(buf, buf2, len) != 0) {
|
||||
mylog(log_debug, "auth_cal failed ");
|
||||
return -1;
|
||||
}
|
||||
if (cipher_encrypt(buf2, output, len, normal_key) != 0) {
|
||||
mylog(log_debug, "cipher_encrypt failed ");
|
||||
return -1;
|
||||
}
|
||||
if(auth_cal(buf,buf2,len)!=0) {mylog(log_debug,"auth_cal failed ");return -1;}
|
||||
if(cipher_encrypt(buf2,output,len,normal_key) !=0) {mylog(log_debug,"cipher_encrypt failed ");return -1;}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int my_decrypt(const char *data, char *output, int &len /*,char * key*/) {
|
||||
int my_decrypt(const char *data,char *output,int &len /*,char * key*/)
|
||||
{
|
||||
if(len<0) return -1;
|
||||
if (len > max_data_len) {
|
||||
mylog(log_warn, "len>max_data_len");
|
||||
return -1;
|
||||
}
|
||||
if(len>max_data_len) {mylog(log_warn,"len>max_data_len");return -1;}
|
||||
|
||||
if(is_hmac_used)
|
||||
return decrypt_AE(data,output,len);
|
||||
|
||||
if (cipher_decrypt(data, output, len, normal_key) != 0) {
|
||||
mylog(log_debug, "cipher_decrypt failed \n");
|
||||
return -1;
|
||||
}
|
||||
if (auth_verify(output, len) != 0) {
|
||||
mylog(log_debug, "auth_verify failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(cipher_decrypt(data,output,len,normal_key) !=0) {mylog(log_debug,"cipher_decrypt failed \n"); return -1;}
|
||||
if(auth_verify(output,len)!=0) {mylog(log_debug,"auth_verify failed\n");return -1;}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int encrypt_AEAD(uint8_t *data, uint8_t *output, int &len, uint8_t *key, uint8_t *header, int hlen) {
|
||||
|
||||
int encrypt_AEAD(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen)
|
||||
{
|
||||
//TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
int decrypt_AEAD(uint8_t *data, uint8_t *output, int &len, uint8_t *key, uint8_t *header, int hlen) {
|
||||
int decrypt_AEAD(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen)
|
||||
{
|
||||
//TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
20
encrypt.h
Normal file → Executable file
20
encrypt.h
Normal file → Executable file
@@ -1,10 +1,13 @@
|
||||
#ifndef UDP2RAW_ENCRYPTION_H_
|
||||
#define UDP2RAW_ENCRYPTION_H_
|
||||
|
||||
|
||||
|
||||
//#include "aes.h"
|
||||
//#include "md5.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
//using namespace std;
|
||||
//extern char key[16];
|
||||
|
||||
@@ -16,20 +19,15 @@ int my_init_keys(const char *, int);
|
||||
int my_encrypt(const char *data,char *output,int &len);
|
||||
int my_decrypt(const char *data,char *output,int &len);
|
||||
|
||||
|
||||
unsigned short csum(const unsigned short *ptr,int nbytes) ;
|
||||
|
||||
enum auth_mode_t { auth_none = 0,
|
||||
auth_md5,
|
||||
auth_crc32,
|
||||
auth_simple,
|
||||
auth_hmac_sha1,
|
||||
auth_end };
|
||||
|
||||
enum cipher_mode_t { cipher_none = 0,
|
||||
cipher_aes128cbc,
|
||||
cipher_xor,
|
||||
cipher_aes128cfb,
|
||||
cipher_end };
|
||||
enum auth_mode_t {auth_none=0,auth_md5,auth_crc32,auth_simple,auth_hmac_sha1,auth_end};
|
||||
|
||||
|
||||
enum cipher_mode_t {cipher_none=0,cipher_aes128cbc,cipher_xor,cipher_aes128cfb,cipher_end};
|
||||
|
||||
|
||||
extern auth_mode_t auth_mode;
|
||||
extern cipher_mode_t cipher_mode;
|
||||
|
@@ -5,49 +5,60 @@
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
|
||||
#include "fd_manager.h"
|
||||
int fd_manager_t::fd_exist(int fd) {
|
||||
int fd_manager_t::fd_exist(int fd)
|
||||
{
|
||||
return fd_to_fd64_mp.find(fd)!=fd_to_fd64_mp.end();
|
||||
}
|
||||
int fd_manager_t::exist(fd64_t fd64) {
|
||||
int fd_manager_t::exist(fd64_t fd64)
|
||||
{
|
||||
return fd64_to_fd_mp.find(fd64)!=fd64_to_fd_mp.end();
|
||||
}
|
||||
int fd_manager_t::to_fd(fd64_t fd64) {
|
||||
int fd_manager_t::to_fd(fd64_t fd64)
|
||||
{
|
||||
assert(exist(fd64));
|
||||
return fd64_to_fd_mp[fd64];
|
||||
}
|
||||
void fd_manager_t::fd64_close(fd64_t fd64) {
|
||||
void fd_manager_t::fd64_close(fd64_t fd64)
|
||||
{
|
||||
assert(exist(fd64));
|
||||
int fd=fd64_to_fd_mp[fd64];
|
||||
fd64_to_fd_mp.erase(fd64);
|
||||
fd_to_fd64_mp.erase(fd);
|
||||
if (exist_info(fd64)) {
|
||||
if(exist_info(fd64))
|
||||
{
|
||||
fd_info_mp.erase(fd64);
|
||||
}
|
||||
//assert(close(fd)==0);
|
||||
sock_close(fd);
|
||||
}
|
||||
void fd_manager_t::reserve(int n) {
|
||||
void fd_manager_t::reserve(int n)
|
||||
{
|
||||
fd_to_fd64_mp.reserve(n);
|
||||
fd64_to_fd_mp.reserve(n);
|
||||
fd_info_mp.reserve(n);
|
||||
}
|
||||
u64_t fd_manager_t::create(int fd) {
|
||||
u64_t fd_manager_t::create(int fd)
|
||||
{
|
||||
assert(!fd_exist(fd));
|
||||
fd64_t fd64=counter++;
|
||||
fd_to_fd64_mp[fd]=fd64;
|
||||
fd64_to_fd_mp[fd64]=fd;
|
||||
return fd64;
|
||||
}
|
||||
fd_manager_t::fd_manager_t() {
|
||||
fd_manager_t::fd_manager_t()
|
||||
{
|
||||
counter=u32_t(-1);
|
||||
counter+=100;
|
||||
reserve(10007);
|
||||
}
|
||||
fd_info_t& fd_manager_t::get_info(fd64_t fd64) {
|
||||
fd_info_t & fd_manager_t::get_info(fd64_t fd64)
|
||||
{
|
||||
assert(exist(fd64));
|
||||
return fd_info_mp[fd64];
|
||||
}
|
||||
int fd_manager_t::exist_info(fd64_t fd64) {
|
||||
int fd_manager_t::exist_info(fd64_t fd64)
|
||||
{
|
||||
return fd_info_mp.find(fd64)!=fd_info_mp.end();
|
||||
}
|
||||
|
@@ -12,7 +12,8 @@
|
||||
//#include "packet.h"
|
||||
#include "connection.h"
|
||||
|
||||
struct fd_info_t {
|
||||
struct fd_info_t
|
||||
{
|
||||
//ip_port_t ip_port;
|
||||
conn_info_t *p_conn_info;
|
||||
};
|
||||
@@ -28,7 +29,6 @@ struct fd_manager_t // conver fd to a uniq 64bit number,avoid fd value conflict
|
||||
void reserve(int n);
|
||||
u64_t create(int fd);
|
||||
fd_manager_t();
|
||||
|
||||
private:
|
||||
u64_t counter;
|
||||
unordered_map<int,fd64_t> fd_to_fd64_mp;
|
||||
|
9
log.cpp
Normal file → Executable file
9
log.cpp
Normal file → Executable file
@@ -7,9 +7,11 @@ int enable_log_position = 0;
|
||||
int enable_log_color=1;
|
||||
|
||||
void log0(const char * file,const char * function,int line,int level,const char* str, ...) {
|
||||
|
||||
if(level>log_level) return ;
|
||||
if(level>log_trace||level<0) return ;
|
||||
|
||||
|
||||
time_t timer;
|
||||
char buffer[100];
|
||||
struct tm* tm_info;
|
||||
@@ -37,12 +39,14 @@ void log0(const char* file, const char* function, int line, int level, const cha
|
||||
//printf(log_color[level]);
|
||||
fflush(stdout);
|
||||
|
||||
if (log_level == log_fatal) {
|
||||
if(log_level==log_fatal)
|
||||
{
|
||||
about_to_exit=1;
|
||||
}
|
||||
}
|
||||
|
||||
void log_bare(int level, const char* str, ...) {
|
||||
void log_bare(int level,const char* str, ...)
|
||||
{
|
||||
if(level>log_level) return ;
|
||||
if(level>log_trace||level<0) return ;
|
||||
if(enable_log_color)
|
||||
@@ -54,4 +58,5 @@ void log_bare(int level, const char* str, ...) {
|
||||
if(enable_log_color)
|
||||
printf("%s",RESET);
|
||||
fflush(stdout);
|
||||
|
||||
}
|
||||
|
7
log.h
Normal file → Executable file
7
log.h
Normal file → Executable file
@@ -2,10 +2,13 @@
|
||||
#ifndef UDP2RAW_LOG_MYLOG_H_
|
||||
#define UDP2RAW_LOG_MYLOG_H_
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#define RED "\x1B[31m"
|
||||
#define GRN "\x1B[32m"
|
||||
#define YEL "\x1B[33m"
|
||||
@@ -15,6 +18,7 @@ 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;
|
||||
@@ -31,6 +35,7 @@ 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__)
|
||||
|
||||
@@ -38,10 +43,12 @@ extern int enable_log_color;
|
||||
#define mylog(...) log0(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
|
||||
//#define mylog(__first_argu__dummy_abcde__,...) {;}
|
||||
|
||||
void log0(const char * file,const char * function,int line,int level,const char* str, ...);
|
||||
|
||||
void log_bare(int level,const char* str, ...);
|
||||
|
||||
|
||||
#endif
|
||||
|
42
main.cpp
Normal file → Executable file
42
main.cpp
Normal file → Executable file
@@ -7,16 +7,19 @@
|
||||
#include "encrypt.h"
|
||||
#include "fd_manager.h"
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -24,7 +27,8 @@ void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) {
|
||||
int client_event_loop();
|
||||
int server_event_loop();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
assert(sizeof(unsigned short)==2);
|
||||
assert(sizeof(unsigned int)==4);
|
||||
assert(sizeof(unsigned long long)==8);
|
||||
@@ -40,22 +44,25 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
pre_process_arg(argc,argv);
|
||||
|
||||
ev_signal signal_watcher_sigpipe;
|
||||
ev_signal signal_watcher_sigterm;
|
||||
ev_signal signal_watcher_sigint;
|
||||
|
||||
if (program_mode == client_mode) {
|
||||
if(program_mode==client_mode)
|
||||
{
|
||||
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);
|
||||
#endif
|
||||
|
||||
ev_signal signal_watcher_sigterm;
|
||||
ev_signal_init(&signal_watcher_sigterm, sigterm_cb, SIGTERM);
|
||||
ev_signal_start(loop, &signal_watcher_sigterm);
|
||||
|
||||
ev_signal signal_watcher_sigint;
|
||||
ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT);
|
||||
ev_signal_start(loop, &signal_watcher_sigint);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UDP2RAW_LINUX
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGHUP, signal_handler);
|
||||
@@ -66,11 +73,15 @@ int main(int argc, char *argv[]) {
|
||||
mylog(log_fatal,"server mode not supported in multi-platform version\n");
|
||||
myexit(-1);
|
||||
#endif
|
||||
|
||||
}
|
||||
#if !defined(__MINGW32__)
|
||||
if (geteuid() != 0) {
|
||||
if(geteuid() != 0)
|
||||
{
|
||||
mylog(log_warn,"root check failed, it seems like you are using a non-root account. we can try to continue, but it may fail. If you want to run udp2raw as non-root, you have to add iptables rule manually, and grant udp2raw CAP_NET_RAW capability, check README.md in repo for more info.\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_warn,"you can run udp2raw with non-root account for better security. check README.md in repo for more info.\n");
|
||||
}
|
||||
#endif
|
||||
@@ -91,9 +102,12 @@ int main(int argc, char *argv[]) {
|
||||
init_raw_socket();
|
||||
#endif
|
||||
|
||||
if (program_mode == client_mode) {
|
||||
if(program_mode==client_mode)
|
||||
{
|
||||
client_event_loop();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UDP2RAW_LINUX
|
||||
server_event_loop();
|
||||
#else
|
||||
|
46
makefile
46
makefile
@@ -1,13 +1,11 @@
|
||||
cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||
cc_local=g++
|
||||
cc_mips24kc_be=$(shell which g++ || /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=$(shell which g++ || /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= $(shell which c++ || /toolchains/lede-sdk-17.01.2-bcm53xx_gcc-5.4.0_musl-1.1.16_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a9_gcc-5.4.0_musl-1.1.16_eabi/bin/arm-openwrt-linux-c++)
|
||||
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/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_x86=$(shell which c++ || /toolchains/lede-sdk-17.01.2-x86-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-i386_pentium4_gcc-5.4.0_musl-1.1.16/bin/i486-openwrt-linux-c++)
|
||||
cc_amd64=$(shell which c++ || /toolchains/lede-sdk-17.01.2-x86-64_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-x86_64_gcc-5.4.0_musl-1.1.16/bin/x86_64-openwrt-linux-c++)
|
||||
#cc_bcm2708=$(shell which g++ || /home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++)
|
||||
#cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++
|
||||
|
||||
|
||||
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers ${OPT}
|
||||
@@ -38,7 +36,7 @@ all:git_version
|
||||
|
||||
#dynamic link
|
||||
dynamic: git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -O2
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -O3
|
||||
|
||||
#targes for general cross compile
|
||||
|
||||
@@ -57,7 +55,7 @@ fast: git_version
|
||||
${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 -ggdb
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
|
||||
debug2: git_version
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -ggdb -fsanitize=address
|
||||
@@ -65,25 +63,25 @@ debug2: git_version
|
||||
#targets only for 'make release'
|
||||
|
||||
mips24kc_be: git_version
|
||||
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O2
|
||||
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
mips24kc_be_asm_aes: git_version
|
||||
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O2 lib/aes_acc/asm/mips_be.S
|
||||
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips_be.S
|
||||
mips24kc_le: git_version
|
||||
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O2
|
||||
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
mips24kc_le_asm_aes: git_version
|
||||
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O2 lib/aes_acc/asm/mips.S
|
||||
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips.S
|
||||
amd64:git_version
|
||||
${cc_amd64} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O2 -lgcc_eh -ggdb
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
amd64_hw_aes:git_version
|
||||
${cc_amd64} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O2 lib/aes_acc/asm/x64.S -lgcc_eh -ggdb
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/x64.S
|
||||
x86:git_version
|
||||
${cc_x86} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O2 -lgcc_eh -ggdb
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
|
||||
x86_asm_aes:git_version
|
||||
${cc_x86} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O2 lib/aes_acc/asm/x86.S -lgcc_eh -ggdb
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 -m32 lib/aes_acc/asm/x86.S
|
||||
arm:git_version
|
||||
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O2 -lgcc_eh
|
||||
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
arm_asm_aes:git_version
|
||||
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O2 lib/aes_acc/asm/arm.S -lgcc_eh
|
||||
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/arm.S
|
||||
|
||||
release: ${TARGETS}
|
||||
cp git_version.h version.txt
|
||||
@@ -91,22 +89,22 @@ release: ${TARGETS}
|
||||
|
||||
#targets for multi-platform version (native compile)
|
||||
cygwin:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} pcap_wrapper.cpp ${FLAGS} -lrt -ggdb -static -O2 -D_GNU_SOURCE ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} pcap_wrapper.cpp ${FLAGS} -lrt -ggdb -static -O2 -D_GNU_SOURCE
|
||||
|
||||
mingw:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} pcap_wrapper.cpp ${FLAGS} -ggdb -static -O2 -lws2_32 ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} pcap_wrapper.cpp ${FLAGS} -ggdb -static -O2 -lws2_32
|
||||
|
||||
mingw_wepoll:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES0} pcap_wrapper.cpp ${FLAGS} -ggdb -static -O2 -DNO_LIBEV_EMBED -D_WIN32 -lev -lws2_32 ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES0} pcap_wrapper.cpp ${FLAGS} -ggdb -static -O2 -DNO_LIBEV_EMBED -D_WIN32 -lev -lws2_32
|
||||
|
||||
linux:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -O2 ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -O2
|
||||
|
||||
freebsd:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -libverbs -O2 ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -O2
|
||||
|
||||
mac:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -ggdb -O2 ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -ggdb -O2
|
||||
|
||||
#targets for multi-platform version (cross compile)
|
||||
|
||||
|
32
misc.h
32
misc.h
@@ -8,6 +8,7 @@
|
||||
#ifndef MISC_H_
|
||||
#define MISC_H_
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "network.h"
|
||||
@@ -25,6 +26,7 @@ extern int enable_dns_resolve;
|
||||
|
||||
extern int ttl_value;
|
||||
|
||||
|
||||
const u32_t max_handshake_conn_num=10000;
|
||||
const u32_t max_ready_conn_num=1000;
|
||||
const u32_t anti_replay_window_size=4000;
|
||||
@@ -43,6 +45,7 @@ const int conn_clear_min = 1;
|
||||
const u32_t conv_clear_interval=1000;//ms
|
||||
const u32_t conn_clear_interval=1000;//ms
|
||||
|
||||
|
||||
const i32_t max_fail_time=0;//disable
|
||||
|
||||
const u32_t heartbeat_interval=600;//ms
|
||||
@@ -60,25 +63,14 @@ const uint32_t server_conn_timeout = conv_timeout + 60000; // ms. this should b
|
||||
|
||||
const u32_t iptables_rule_keep_interval=20;//unit: second;
|
||||
|
||||
enum server_current_state_t { server_idle = 0,
|
||||
server_handshake1,
|
||||
server_ready }; // server state machine
|
||||
enum client_current_state_t { client_idle = 0,
|
||||
client_tcp_handshake,
|
||||
client_handshake1,
|
||||
client_handshake2,
|
||||
client_ready,
|
||||
client_tcp_handshake_dummy }; // client state machine
|
||||
enum server_current_state_t {server_idle=0,server_handshake1,server_ready}; //server state machine
|
||||
enum client_current_state_t {client_idle=0,client_tcp_handshake,client_handshake1,client_handshake2,client_ready,client_tcp_handshake_dummy};//client state machine
|
||||
|
||||
enum raw_mode_t { mode_faketcp = 0,
|
||||
mode_udp,
|
||||
mode_icmp,
|
||||
mode_end };
|
||||
enum program_mode_t { unset_mode = 0,
|
||||
client_mode,
|
||||
server_mode };
|
||||
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
|
||||
enum program_mode_t {unset_mode=0,client_mode,server_mode};
|
||||
|
||||
union current_state_t {
|
||||
union current_state_t
|
||||
{
|
||||
server_current_state_t server_current_state;
|
||||
client_current_state_t client_current_state;
|
||||
};
|
||||
@@ -107,6 +99,7 @@ extern int fail_time_counter; // determine if the max_fail_time is reached
|
||||
extern int epoll_trigger_counter;//for debug only
|
||||
extern int debug_flag;//for debug only
|
||||
|
||||
|
||||
extern int simple_rule; //deprecated.
|
||||
extern int keep_rule; //whether to monitor the iptables rule periodly,re-add if losted
|
||||
extern int auto_add_iptables_rule;//if -a is set
|
||||
@@ -120,6 +113,7 @@ extern int debug_resend; // debug only
|
||||
extern char key_string[1000];// -k option
|
||||
extern char fifo_file[1000];
|
||||
|
||||
|
||||
extern raw_mode_t raw_mode;
|
||||
extern u32_t raw_ip_version;
|
||||
|
||||
@@ -130,9 +124,11 @@ extern int about_to_exit;
|
||||
|
||||
extern int socket_buf_size;
|
||||
|
||||
|
||||
extern pthread_t keep_thread;
|
||||
extern int keep_thread_running;
|
||||
|
||||
|
||||
int process_lower_level_arg();
|
||||
void print_help();
|
||||
void iptables_rule();
|
||||
@@ -150,6 +146,8 @@ int iptables_gen_add(const char *s, u32_t const_id);
|
||||
int iptables_rule_init(const char * s,u32_t const_id,int keep);
|
||||
int keep_iptables_rule();
|
||||
|
||||
|
||||
|
||||
void signal_handler(int sig);
|
||||
|
||||
#endif /* MISC_H_ */
|
||||
|
@@ -1,8 +1,6 @@
|
||||
|
||||
#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
|
||||
|
||||
//#include <wepoll.h>
|
||||
@@ -17,3 +15,4 @@
|
||||
|
||||
#endif
|
||||
//#define EV_VERIFY 2
|
||||
|
||||
|
970
network.cpp
970
network.cpp
File diff suppressed because it is too large
Load Diff
37
network.h
37
network.h
@@ -47,7 +47,8 @@ extern int send_with_pcap;
|
||||
extern int pcap_header_captured;
|
||||
extern int pcap_header_buf[buf_len];
|
||||
|
||||
struct icmphdr {
|
||||
struct icmphdr
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t check_sum;
|
||||
@@ -56,7 +57,8 @@ struct icmphdr {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct my_iphdr {
|
||||
struct my_iphdr
|
||||
{
|
||||
#ifdef UDP2RAW_LITTLE_ENDIAN
|
||||
unsigned char ihl:4;
|
||||
unsigned char version:4;
|
||||
@@ -76,8 +78,11 @@ struct my_iphdr {
|
||||
/*The options start here. */
|
||||
};
|
||||
|
||||
struct my_udphdr {
|
||||
/*__extension__*/ union {
|
||||
|
||||
struct my_udphdr
|
||||
{
|
||||
/*__extension__*/ union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u_int16_t uh_sport; /* source port */
|
||||
@@ -95,8 +100,11 @@ struct my_udphdr {
|
||||
};
|
||||
};
|
||||
|
||||
struct my_tcphdr {
|
||||
/*__extension__*/ union {
|
||||
|
||||
struct my_tcphdr
|
||||
{
|
||||
/*__extension__*/ union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u_int16_t th_sport; /* source port */
|
||||
@@ -155,7 +163,8 @@ struct my_tcphdr {
|
||||
};
|
||||
};
|
||||
|
||||
struct my_ip6hdr {
|
||||
struct my_ip6hdr
|
||||
{
|
||||
# ifdef UDP2RAW_LITTLE_ENDIAN
|
||||
uint8_t traffic_class_high:4;
|
||||
uint8_t version:4;
|
||||
@@ -176,7 +185,8 @@ struct my_ip6hdr {
|
||||
struct in6_addr dst;
|
||||
};
|
||||
|
||||
struct my_icmphdr {
|
||||
struct my_icmphdr
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t check_sum;
|
||||
@@ -205,6 +215,7 @@ struct packet_info_t // todo change this to union
|
||||
{
|
||||
uint8_t protocol;
|
||||
|
||||
|
||||
//u32_t src_ip;
|
||||
//u32_t dst_ip;
|
||||
my_ip_t new_src_ip;
|
||||
@@ -222,20 +233,22 @@ struct packet_info_t // todo change this to union
|
||||
|
||||
u32_t ts,ts_ack;
|
||||
|
||||
|
||||
uint16_t my_icmp_seq;
|
||||
|
||||
bool has_ts;
|
||||
|
||||
i32_t data_len;
|
||||
|
||||
#ifdef UDP2RAW_LINUX
|
||||
sockaddr_ll addr_ll;
|
||||
#endif
|
||||
|
||||
i32_t data_len;
|
||||
|
||||
packet_info_t();
|
||||
};
|
||||
|
||||
struct raw_info_t {
|
||||
struct raw_info_t
|
||||
{
|
||||
packet_info_t send_info;
|
||||
packet_info_t recv_info;
|
||||
//int last_send_len;
|
||||
@@ -249,6 +262,7 @@ struct raw_info_t {
|
||||
|
||||
};//g_raw_info;
|
||||
|
||||
|
||||
int init_raw_socket();
|
||||
|
||||
void init_filter(int port);
|
||||
@@ -307,4 +321,5 @@ int after_send_raw0(raw_info_t &raw_info);
|
||||
|
||||
int after_recv_raw0(raw_info_t &raw_info);
|
||||
|
||||
|
||||
#endif /* NETWORK_H_ */
|
||||
|
@@ -32,23 +32,26 @@ char *(*pcap_lookupdev)(char *) = 0;
|
||||
|
||||
int (*pcap_findalldevs)(pcap_if_t **, char *)=0;
|
||||
|
||||
struct init_pcap_t {
|
||||
init_pcap_t() {
|
||||
struct init_pcap_t
|
||||
{
|
||||
init_pcap_t()
|
||||
{
|
||||
init_pcap();
|
||||
}
|
||||
|
||||
}do_it;
|
||||
|
||||
static void init_npcap_dll_path() {
|
||||
BOOL(WINAPI * SetDllDirectory)
|
||||
(LPCTSTR);
|
||||
static void init_npcap_dll_path()
|
||||
{
|
||||
BOOL(WINAPI *SetDllDirectory)(LPCTSTR);
|
||||
char sysdir_name[512];
|
||||
int len;
|
||||
|
||||
SetDllDirectory = (BOOL(WINAPI *)(LPCTSTR)) GetProcAddress(GetModuleHandle("kernel32.dll"), "SetDllDirectoryA");
|
||||
if (SetDllDirectory == NULL) {
|
||||
printf("Error in SetDllDirectory\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
len = GetSystemDirectory(sysdir_name, 480); // be safe
|
||||
if (!len)
|
||||
printf("Error in GetSystemDirectory (%d)\n", (int)GetLastError());
|
||||
@@ -58,22 +61,24 @@ static void init_npcap_dll_path() {
|
||||
}
|
||||
}
|
||||
|
||||
#define EXPORT_FUN(XXX) \
|
||||
do { \
|
||||
XXX = (__typeof__(XXX))GetProcAddress(wpcap, #XXX); \
|
||||
} while (0)
|
||||
int init_pcap() {
|
||||
#define EXPORT_FUN(XXX) do{ XXX= (__typeof__(XXX)) GetProcAddress(wpcap, #XXX); }while(0)
|
||||
int init_pcap()
|
||||
{
|
||||
HMODULE wpcap=LoadLibrary("wpcap.dll");
|
||||
if (wpcap != 0) {
|
||||
if(wpcap!=0)
|
||||
{
|
||||
printf("using system32/wpcap.dll\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
init_npcap_dll_path();
|
||||
//SetDllDirectory("C:\\Windows\\System32\\Npcap\\");
|
||||
wpcap=LoadLibrary("wpcap.dll");
|
||||
if(wpcap!=0)
|
||||
printf("using system32/npcap/wpcap.dll\n");
|
||||
}
|
||||
if (wpcap == 0) {
|
||||
if(wpcap==0)
|
||||
{
|
||||
printf("cant not open wpcap.dll, make sure winpcap/npcap is installed\n");
|
||||
exit(-1);
|
||||
}
|
||||
@@ -116,4 +121,5 @@ int init_pcap() {
|
||||
//pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop");
|
||||
*/
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@@ -7,11 +7,13 @@
|
||||
//#include <sys/time.h>
|
||||
//#include <stdint.h>
|
||||
|
||||
struct bpf_program {
|
||||
struct bpf_program
|
||||
{
|
||||
char a[4096];
|
||||
};
|
||||
|
||||
struct pcap_t {
|
||||
struct pcap_t
|
||||
{
|
||||
char a[4096];
|
||||
};
|
||||
|
||||
@@ -34,6 +36,7 @@ typedef enum {
|
||||
PCAP_D_OUT
|
||||
} pcap_direction_t;
|
||||
|
||||
|
||||
struct pcap_addr {
|
||||
struct pcap_addr *next;
|
||||
struct sockaddr *addr; /* address */
|
||||
@@ -53,8 +56,11 @@ struct pcap_if {
|
||||
typedef struct pcap_if pcap_if_t;
|
||||
typedef struct pcap_addr pcap_addr_t;
|
||||
|
||||
|
||||
|
||||
typedef unsigned char u_char;
|
||||
|
||||
|
||||
#define PCAP_ERRBUF_SIZE 256
|
||||
|
||||
#define DLT_NULL 0 /* BSD loopback encapsulation */
|
||||
@@ -106,12 +112,16 @@ extern char *(*pcap_lookupdev)(char *);
|
||||
|
||||
extern int (*pcap_findalldevs)(pcap_if_t **, char *);
|
||||
|
||||
inline int pcap_set_immediate_mode(pcap_t *, int) {
|
||||
inline int pcap_set_immediate_mode(pcap_t *,int)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
int init_pcap();
|
||||
|
||||
|
289
server.cpp
289
server.cpp
@@ -34,7 +34,9 @@ int server_on_timer_multi(conn_info_t &conn_info) // for server. called when a
|
||||
|
||||
assert(conn_info.state.server_current_state==server_ready);
|
||||
|
||||
if (conn_info.state.server_current_state == server_ready) {
|
||||
|
||||
if(conn_info.state.server_current_state==server_ready)
|
||||
{
|
||||
conn_info.blob->conv_manager.s.clear_inactive(ip_port);
|
||||
/*
|
||||
if( get_current_time()-conn_info.last_hb_recv_time>heartbeat_timeout )
|
||||
@@ -47,10 +49,10 @@ int server_on_timer_multi(conn_info_t &conn_info) // for server. called when a
|
||||
|
||||
mylog(log_info,"changed state to server_nothing\n");
|
||||
return 0;
|
||||
}*/
|
||||
// dont need to do this at server,conn_manger will clear expired connections
|
||||
}*/ //dont need to do this at server,conn_manger will clear expired connections
|
||||
|
||||
if (get_current_time() - conn_info.last_hb_sent_time < heartbeat_interval) {
|
||||
if(get_current_time()-conn_info.last_hb_sent_time<heartbeat_interval)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -61,15 +63,19 @@ int server_on_timer_multi(conn_info_t &conn_info) // for server. called when a
|
||||
conn_info.last_hb_sent_time=get_current_time();
|
||||
|
||||
mylog(log_debug,"heart beat sent<%x,%x>\n",conn_info.my_id,conn_info.oppsite_id);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"this shouldnt happen!\n");
|
||||
myexit(-1);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,char *data,int data_len) //called while the state for a connection is server_ready
|
||||
//receives data and heart beat by recv_safer.
|
||||
{
|
||||
|
||||
raw_info_t &raw_info = conn_info.raw_info;
|
||||
packet_info_t &send_info = conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info = conn_info.raw_info.recv_info;
|
||||
@@ -77,6 +83,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info, char *ip_port, char type, c
|
||||
|
||||
//sprintf(ip_port,"%s:%d",my_ntoa(recv_info.src_ip),recv_info.src_port);
|
||||
|
||||
|
||||
/*
|
||||
if (recv_info.src_ip != send_info.dst_ip
|
||||
|| recv_info.src_port != send_info.dst_port) {
|
||||
@@ -89,12 +96,15 @@ int server_on_raw_recv_ready(conn_info_t &conn_info, char *ip_port, char type, c
|
||||
mylog(log_debug,"[%s][hb]received hb \n",ip_port);
|
||||
conn_info.last_hb_recv_time = get_current_time();
|
||||
return 0;
|
||||
} else if (type == 'd' && data_len >= int(sizeof(u32_t))) {
|
||||
} else if (type== 'd' && data_len >=int( sizeof(u32_t) ))
|
||||
{
|
||||
|
||||
//u32_t tmp_conv_id = ntohl(*((u32_t *) &data[0]));
|
||||
my_id_t tmp_conv_id;
|
||||
memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id));
|
||||
tmp_conv_id=ntohl(tmp_conv_id);
|
||||
|
||||
|
||||
if(hb_mode==0)
|
||||
conn_info.last_hb_recv_time = get_current_time();
|
||||
|
||||
@@ -163,6 +173,8 @@ int server_on_raw_recv_ready(conn_info_t &conn_info, char *ip_port, char type, c
|
||||
|
||||
conn_info.blob->conv_manager.s.insert_conv(tmp_conv_id, new_udp_fd64);
|
||||
|
||||
|
||||
|
||||
//assert(conn_manager.udp_fd_mp.find(new_udp_fd)==conn_manager.udp_fd_mp.end());
|
||||
|
||||
//conn_manager.udp_fd_mp[new_udp_fd] = &conn_info;
|
||||
@@ -171,6 +183,9 @@ int server_on_raw_recv_ready(conn_info_t &conn_info, char *ip_port, char type, c
|
||||
|
||||
mylog(log_info, "[%s]new conv conv_id=%x, assigned fd=%d\n",ip_port,
|
||||
tmp_conv_id, new_udp_fd);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
fd64_t fd64 = conn_info.blob->conv_manager.s.find_data_by_conv(tmp_conv_id);
|
||||
@@ -205,10 +220,12 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tm
|
||||
mylog(log_info,"[%s]received handshake oppsite_id:%x my_id:%x\n",ip_port,conn_info.oppsite_id,conn_info.my_id);
|
||||
|
||||
mylog(log_info,"[%s]oppsite const_id:%x \n",ip_port,tmp_oppsite_const_id);
|
||||
if (conn_manager.const_id_mp.find(tmp_oppsite_const_id) == conn_manager.const_id_mp.end()) {
|
||||
if(conn_manager.const_id_mp.find(tmp_oppsite_const_id)==conn_manager.const_id_mp.end())
|
||||
{
|
||||
//conn_manager.const_id_mp=
|
||||
|
||||
if (conn_manager.ready_num >= max_ready_conn_num) {
|
||||
if(conn_manager.ready_num>=max_ready_conn_num)
|
||||
{
|
||||
mylog(log_info,"[%s]max_ready_conn_num,cant turn to ready\n",ip_port);
|
||||
conn_info.state.server_current_state =server_idle;
|
||||
return 0;
|
||||
@@ -220,6 +237,7 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tm
|
||||
conn_manager.ready_num++;
|
||||
conn_manager.const_id_mp[tmp_oppsite_const_id]=&conn_info;
|
||||
|
||||
|
||||
//conn_info.last_state_time=get_current_time(); //dont change this!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
//conn_manager.current_ready_ip=ip;
|
||||
@@ -247,6 +265,7 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tm
|
||||
//assert(conn_manager.timer_fd_mp.find(new_timer_fd)==conn_manager.timer_fd_mp.end());
|
||||
//conn_manager.timer_fd_mp[new_timer_fd] = &conn_info;//pack_u64(ip,port);
|
||||
|
||||
|
||||
//timer_fd_mp[new_timer_fd]
|
||||
/*
|
||||
if(oppsite_const_id!=0&&tmp_oppsite_const_id!=oppsite_const_id) //TODO MOVE TO READY
|
||||
@@ -255,25 +274,28 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tm
|
||||
conv_manager.clear();
|
||||
}*/
|
||||
//oppsite_const_id=tmp_oppsite_const_id;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
conn_info_t &ori_conn_info=*conn_manager.const_id_mp[tmp_oppsite_const_id];
|
||||
|
||||
if (ori_conn_info.state.server_current_state == server_ready) {
|
||||
if (conn_info.last_state_time < ori_conn_info.last_state_time) {
|
||||
if(ori_conn_info.state.server_current_state==server_ready)
|
||||
{
|
||||
if(conn_info.last_state_time<ori_conn_info.last_state_time)
|
||||
{
|
||||
mylog(log_info,"[%s]conn_info.last_state_time<ori_conn_info.last_state_time. ignored new handshake\n",ip_port);
|
||||
conn_info.state.server_current_state=server_idle;
|
||||
conn_info.oppsite_const_id=0;
|
||||
return 0;
|
||||
}
|
||||
address_t addr1;
|
||||
addr1.from_ip_port_new(raw_ip_version, &ori_conn_info.raw_info.recv_info.new_src_ip, ori_conn_info.raw_info.recv_info.src_port);
|
||||
address_t addr1;addr1.from_ip_port_new(raw_ip_version,&ori_conn_info.raw_info.recv_info.new_src_ip,ori_conn_info.raw_info.recv_info.src_port);
|
||||
if(!conn_manager.exist(addr1))//TODO remove this
|
||||
{
|
||||
mylog(log_fatal,"[%s]this shouldnt happen\n",ip_port);
|
||||
myexit(-1);
|
||||
}
|
||||
address_t addr2;
|
||||
addr2.from_ip_port_new(raw_ip_version, &conn_info.raw_info.recv_info.new_src_ip, conn_info.raw_info.recv_info.src_port);
|
||||
address_t addr2;addr2.from_ip_port_new(raw_ip_version,&conn_info.raw_info.recv_info.new_src_ip,conn_info.raw_info.recv_info.src_port);
|
||||
if(!conn_manager.exist(addr2))//TODO remove this
|
||||
{
|
||||
mylog(log_fatal,"[%s]this shouldnt happen2\n",ip_port);
|
||||
@@ -285,8 +307,10 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tm
|
||||
p=p_ori;
|
||||
p_ori=tmp;
|
||||
|
||||
|
||||
mylog(log_info,"[%s]grabbed a connection\n",ip_port);
|
||||
|
||||
|
||||
//ori_conn_info.state.server_current_state=server_ready;
|
||||
ori_conn_info.recover(conn_info);
|
||||
|
||||
@@ -299,10 +323,14 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tm
|
||||
|
||||
ori_conn_info.last_hb_recv_time=get_current_time();
|
||||
|
||||
|
||||
|
||||
conn_info.state.server_current_state=server_idle;
|
||||
conn_info.oppsite_const_id=0;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"[%s]this should never happen\n",ip_port);
|
||||
myexit(-1);
|
||||
}
|
||||
@@ -322,7 +350,8 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info, char *ip_port, char *d
|
||||
//char ip_port[40];
|
||||
//sprintf(ip_port,"%s:%d",my_ntoa(ip),port);
|
||||
|
||||
if (data_len < int(3 * sizeof(my_id_t))) {
|
||||
if(data_len<int( 3*sizeof(my_id_t)))
|
||||
{
|
||||
mylog(log_debug,"[%s] data_len=%d too short to be a handshake\n",ip_port,data_len);
|
||||
return -1;
|
||||
}
|
||||
@@ -338,18 +367,22 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info, char *ip_port, char *d
|
||||
|
||||
if(tmp_my_id==0) //received init handshake again
|
||||
{
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
send_info.seq=recv_info.ack_seq;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
}
|
||||
if (raw_mode == mode_icmp) {
|
||||
if(raw_mode==mode_icmp)
|
||||
{
|
||||
send_info.my_icmp_seq=recv_info.my_icmp_seq;
|
||||
}
|
||||
send_handshake(raw_info,conn_info.my_id,tmp_oppsite_id,const_id); //////////////send
|
||||
|
||||
mylog(log_info,"[%s]changed state to server_handshake1,my_id is %x\n",ip_port,conn_info.my_id);
|
||||
} else if (tmp_my_id == conn_info.my_id) {
|
||||
}
|
||||
else if(tmp_my_id==conn_info.my_id)
|
||||
{
|
||||
conn_info.oppsite_id=tmp_oppsite_id;
|
||||
//id_t tmp_oppsite_const_id=ntohl(* ((u32_t *)&data[sizeof(id_t)*2]));
|
||||
|
||||
@@ -357,24 +390,30 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info, char *ip_port, char *d
|
||||
memcpy(&tmp_oppsite_const_id,&data[sizeof(my_id_t)*2],sizeof(tmp_oppsite_const_id));
|
||||
tmp_oppsite_const_id=ntohl(tmp_oppsite_const_id);
|
||||
|
||||
if (raw_mode == mode_faketcp) {
|
||||
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
send_info.seq=recv_info.ack_seq;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
}
|
||||
|
||||
if (raw_mode == mode_icmp) {
|
||||
if(raw_mode==mode_icmp)
|
||||
{
|
||||
send_info.my_icmp_seq=recv_info.my_icmp_seq;
|
||||
}
|
||||
|
||||
server_on_raw_recv_pre_ready(conn_info,ip_port,tmp_oppsite_const_id);
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_debug,"[%s]invalid my_id %x,my_id is %x\n",ip_port,tmp_my_id,conn_info.my_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int server_on_recv_safer_multi(conn_info_t &conn_info, char type, char *data, int data_len) {
|
||||
int server_on_recv_safer_multi(conn_info_t &conn_info,char type,char *data,int data_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int server_on_raw_recv_multi() //called when server received an raw packet
|
||||
@@ -385,7 +424,8 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
packet_info_t &peek_info=peek_raw_info.recv_info;
|
||||
mylog(log_trace,"got a packet\n");
|
||||
if(pre_recv_raw_packet()<0) return -1;
|
||||
if (peek_raw(peek_raw_info) < 0) {
|
||||
if(peek_raw(peek_raw_info)<0)
|
||||
{
|
||||
discard_raw_packet();
|
||||
//recv(raw_recv_fd, 0,0, 0 );//
|
||||
//struct sockaddr saddr;
|
||||
@@ -393,13 +433,14 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
///recvfrom(raw_recv_fd, 0,0, 0 ,&saddr , &saddr_size);//
|
||||
mylog(log_trace,"peek_raw failed\n");
|
||||
return -1;
|
||||
} else {
|
||||
}else
|
||||
{
|
||||
mylog(log_trace,"peek_raw success\n");
|
||||
}
|
||||
//u32_t ip=peek_info.src_ip;uint16_t port=peek_info.src_port;
|
||||
|
||||
int data_len;
|
||||
char *data;
|
||||
|
||||
int data_len; char *data;
|
||||
|
||||
address_t addr;
|
||||
addr.from_ip_port_new(raw_ip_version,&peek_info.new_src_ip,peek_info.src_port);
|
||||
@@ -409,14 +450,18 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
//sprintf(ip_port,"%s:%d",my_ntoa(ip),port);
|
||||
mylog(log_trace,"[%s]peek_raw\n",ip_port);
|
||||
|
||||
if (raw_mode == mode_faketcp && peek_info.syn == 1) {
|
||||
if (!conn_manager.exist(addr) || conn_manager.find_insert(addr).state.server_current_state != server_ready) { // reply any syn ,before state become ready
|
||||
if(raw_mode==mode_faketcp&&peek_info.syn==1)
|
||||
{
|
||||
if(!conn_manager.exist(addr)||conn_manager.find_insert(addr).state.server_current_state!=server_ready)
|
||||
{//reply any syn ,before state become ready
|
||||
|
||||
raw_info_t tmp_raw_info;
|
||||
if (recv_raw0(tmp_raw_info, data, data_len) < 0) {
|
||||
if(recv_raw0(tmp_raw_info,data,data_len)<0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (data_len >= max_data_len + 1) {
|
||||
if(data_len>=max_data_len+1)
|
||||
{
|
||||
mylog(log_debug,"data_len=%d >= max_data_len+1,ignored",data_len);
|
||||
return -1;
|
||||
}
|
||||
@@ -432,11 +477,13 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
send_info.dst_port = recv_info.src_port;
|
||||
send_info.new_dst_ip = recv_info.new_src_ip;
|
||||
|
||||
if (lower_level) {
|
||||
if(lower_level)
|
||||
{
|
||||
handle_lower_level(raw_info);
|
||||
}
|
||||
|
||||
if (data_len == 0 && raw_info.recv_info.syn == 1 && raw_info.recv_info.ack == 0) {
|
||||
if(data_len==0&&raw_info.recv_info.syn==1&&raw_info.recv_info.ack==0)
|
||||
{
|
||||
send_info.ack_seq = recv_info.seq + 1;
|
||||
|
||||
send_info.psh = 0;
|
||||
@@ -448,14 +495,18 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
send_raw0(raw_info, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
discard_raw_packet();
|
||||
//recv(raw_recv_fd, 0,0,0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!conn_manager.exist(addr)) {
|
||||
if (conn_manager.mp.size() >= max_handshake_conn_num) {
|
||||
if(!conn_manager.exist(addr))
|
||||
{
|
||||
if(conn_manager.mp.size()>=max_handshake_conn_num)
|
||||
{
|
||||
mylog(log_info,"[%s]reached max_handshake_conn_num,ignored new handshake\n",ip_port);
|
||||
discard_raw_packet();
|
||||
//recv(raw_recv_fd, 0,0, 0 );//
|
||||
@@ -464,13 +515,17 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
|
||||
raw_info_t tmp_raw_info;
|
||||
|
||||
if (raw_mode == mode_icmp) {
|
||||
|
||||
if(raw_mode==mode_icmp)
|
||||
{
|
||||
tmp_raw_info.send_info.dst_port=tmp_raw_info.send_info.src_port=addr.get_port();
|
||||
}
|
||||
if (recv_bare(tmp_raw_info, data, data_len) < 0) {
|
||||
if(recv_bare(tmp_raw_info,data,data_len)<0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (data_len < int(3 * sizeof(my_id_t))) {
|
||||
if(data_len<int( 3*sizeof(my_id_t)))
|
||||
{
|
||||
mylog(log_debug,"[%s]too short to be a handshake\n",ip_port);
|
||||
return -1;
|
||||
}
|
||||
@@ -480,7 +535,8 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
memcpy(&zero,&data[sizeof(my_id_t)],sizeof(zero));
|
||||
zero=ntohl(zero);
|
||||
|
||||
if (zero != 0) {
|
||||
if(zero!=0)
|
||||
{
|
||||
mylog(log_debug,"[%s]not a invalid initial handshake\n",ip_port);
|
||||
return -1;
|
||||
}
|
||||
@@ -497,13 +553,16 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
//conn_info.ip_port.ip=ip;
|
||||
//conn_info.ip_port.port=port;
|
||||
|
||||
|
||||
|
||||
send_info.new_src_ip=recv_info.new_dst_ip;
|
||||
send_info.src_port=recv_info.dst_port;
|
||||
|
||||
send_info.dst_port = recv_info.src_port;
|
||||
send_info.new_dst_ip = recv_info.new_src_ip;
|
||||
|
||||
if (lower_level) {
|
||||
if(lower_level)
|
||||
{
|
||||
handle_lower_level(raw_info);
|
||||
}
|
||||
|
||||
@@ -512,6 +571,7 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
|
||||
conn_info.my_id=get_true_random_number_nz();
|
||||
|
||||
|
||||
mylog(log_info,"[%s]created new conn,state: server_handshake1,my_id is %x\n",ip_port,conn_info.my_id);
|
||||
|
||||
conn_info.state.server_current_state = server_handshake1;
|
||||
@@ -521,36 +581,46 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
conn_info_t & conn_info=conn_manager.find_insert(addr);//insert if not exist
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
raw_info_t &raw_info=conn_info.raw_info;
|
||||
|
||||
if (conn_info.state.server_current_state == server_handshake1) {
|
||||
if (recv_bare(raw_info, data, data_len) != 0) {
|
||||
if(conn_info.state.server_current_state==server_handshake1)
|
||||
{
|
||||
if(recv_bare(raw_info,data,data_len)!=0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return server_on_raw_recv_handshake1(conn_info,ip_port,data,data_len);
|
||||
}
|
||||
if (conn_info.state.server_current_state == server_ready) {
|
||||
if(conn_info.state.server_current_state==server_ready)
|
||||
{
|
||||
vector<char> type_vec;
|
||||
vector<string> data_vec;
|
||||
recv_safer_multi(conn_info,type_vec,data_vec);
|
||||
if (data_vec.empty()) {
|
||||
if(data_vec.empty())
|
||||
{
|
||||
mylog(log_debug,"recv_safer failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)type_vec.size(); i++) {
|
||||
for(int i=0;i<(int)type_vec.size();i++)
|
||||
{
|
||||
char type=type_vec[i];
|
||||
char *data=(char *)data_vec[i].c_str(); //be careful, do not append data to it
|
||||
int data_len=data_vec[i].length();
|
||||
server_on_raw_recv_ready(conn_info,ip_port,type,data,data_len);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if (conn_info.state.server_current_state == server_idle) {
|
||||
if(conn_info.state.server_current_state==server_idle)
|
||||
{
|
||||
discard_raw_packet();
|
||||
//recv(raw_recv_fd, 0,0, 0 );//
|
||||
return 0;
|
||||
@@ -560,7 +630,8 @@ int server_on_raw_recv_multi() // called when server received an raw packet
|
||||
return -1;
|
||||
}
|
||||
|
||||
int server_on_udp_recv(conn_info_t &conn_info, fd64_t fd64) {
|
||||
int server_on_udp_recv(conn_info_t &conn_info,fd64_t fd64)
|
||||
{
|
||||
char buf[buf_len];
|
||||
|
||||
if(conn_info.state.server_current_state!=server_ready)//TODO remove this for peformance
|
||||
@@ -581,64 +652,82 @@ int server_on_udp_recv(conn_info_t &conn_info, fd64_t fd64) {
|
||||
|
||||
mylog(log_trace,"received a packet from udp_fd,len:%d\n",recv_len);
|
||||
|
||||
if (recv_len == max_data_len + 1) {
|
||||
if(recv_len==max_data_len+1)
|
||||
{
|
||||
mylog(log_warn,"huge packet, data_len > %d,dropped\n",max_data_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recv_len < 0) {
|
||||
if(recv_len<0)
|
||||
{
|
||||
mylog(log_debug,"udp fd,recv_len<0 continue,%s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recv_len >= mtu_warn) {
|
||||
if(recv_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 ",recv_len,mtu_warn);
|
||||
}
|
||||
|
||||
//conn_info.conv_manager->update_active_time(conv_id); server dosnt update from upd side,only update from raw side. (client updates at both side)
|
||||
|
||||
if (conn_info.state.server_current_state == server_ready) {
|
||||
if(conn_info.state.server_current_state==server_ready)
|
||||
{
|
||||
send_data_safer(conn_info,buf,recv_len,conv_id);
|
||||
//send_data(g_packet_info_send,buf,recv_len,my_id,oppsite_id,conv_id);
|
||||
mylog(log_trace,"send_data_safer ,sent !!\n");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int server_event_loop() {
|
||||
|
||||
int server_event_loop()
|
||||
{
|
||||
char buf[buf_len];
|
||||
|
||||
int i, j, k;
|
||||
int ret;
|
||||
int i, j, k;int ret;
|
||||
|
||||
if (raw_ip_version == AF_INET) {
|
||||
if (local_addr.inner.ipv4.sin_addr.s_addr != 0) {
|
||||
if(raw_ip_version==AF_INET)
|
||||
{
|
||||
if(local_addr.inner.ipv4.sin_addr.s_addr!=0)
|
||||
{
|
||||
bind_addr_used=1;
|
||||
bind_addr.v4=local_addr.inner.ipv4.sin_addr.s_addr;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(raw_ip_version==AF_INET6);
|
||||
char zero_arr[16]={0};
|
||||
if (memcmp(&local_addr.inner.ipv6.sin6_addr, zero_arr, 16) != 0) {
|
||||
if(memcmp(&local_addr.inner.ipv6.sin6_addr,zero_arr,16)!=0)
|
||||
{
|
||||
bind_addr_used=1;
|
||||
bind_addr.v6=local_addr.inner.ipv6.sin6_addr;
|
||||
}
|
||||
}
|
||||
//bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero
|
||||
|
||||
if (lower_level) {
|
||||
if (lower_level_manual) {
|
||||
if(lower_level)
|
||||
{
|
||||
if(lower_level_manual)
|
||||
{
|
||||
init_ifindex(if_name,raw_send_fd,ifindex);
|
||||
mylog(log_info,"we are running at lower-level (manual) mode\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_info,"we are running at lower-level (auto) mode\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
bind_fd=socket(local_addr.get_type(),SOCK_STREAM,0);
|
||||
} else if (raw_mode == mode_udp || raw_mode == mode_icmp) // bind an adress to avoid collision,for icmp,there is no port,just bind a udp port
|
||||
}
|
||||
else if(raw_mode==mode_udp||raw_mode==mode_icmp)//bind an adress to avoid collision,for icmp,there is no port,just bind a udp port
|
||||
{
|
||||
bind_fd=socket(local_addr.get_type(),SOCK_DGRAM,0);
|
||||
}
|
||||
@@ -650,18 +739,24 @@ int server_event_loop() {
|
||||
//temp_bind_addr.sin_port = local_addr.get_port();
|
||||
//temp_bind_addr.sin_addr.s_addr = local_addr.inner.ipv4.sin_addr.s_addr;
|
||||
|
||||
if (bind(bind_fd, (struct sockaddr *)&local_addr.inner, local_addr.get_len()) != 0) {
|
||||
if (bind(bind_fd, (struct sockaddr*)&local_addr.inner, local_addr.get_len()) !=0)
|
||||
{
|
||||
mylog(log_fatal,"bind fail\n");
|
||||
myexit(-1);
|
||||
}
|
||||
|
||||
if (raw_mode == mode_faketcp) {
|
||||
if (listen(bind_fd, SOMAXCONN) != 0) {
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
|
||||
if(listen(bind_fd, SOMAXCONN) != 0 )
|
||||
{
|
||||
mylog(log_fatal,"listen fail\n");
|
||||
myexit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//init_raw_socket();
|
||||
init_filter(local_addr.get_port());//bpf filter
|
||||
|
||||
@@ -693,7 +788,8 @@ int server_event_loop() {
|
||||
|
||||
int fifo_fd=-1;
|
||||
|
||||
if (fifo_file[0] != 0) {
|
||||
if(fifo_file[0]!=0)
|
||||
{
|
||||
fifo_fd=create_fifo(fifo_file);
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.u64 = fifo_fd;
|
||||
@@ -706,32 +802,40 @@ int server_event_loop() {
|
||||
mylog(log_info,"fifo_file=%s\n",fifo_file);
|
||||
}
|
||||
|
||||
|
||||
while(1)////////////////////////
|
||||
{
|
||||
|
||||
if(about_to_exit) myexit(0);
|
||||
|
||||
int nfds = epoll_wait(epollfd, events, max_events, 180 * 1000);
|
||||
if (nfds < 0) { //allow zero
|
||||
if (errno == EINTR) {
|
||||
if(errno==EINTR )
|
||||
{
|
||||
mylog(log_info,"epoll interrupted by signal,continue\n");
|
||||
//myexit(0);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
|
||||
myexit(-1);
|
||||
}
|
||||
}
|
||||
int idx;
|
||||
for (idx = 0; idx < nfds; ++idx) {
|
||||
for (idx = 0; idx < nfds; ++idx)
|
||||
{
|
||||
//mylog(log_debug,"ndfs: %d \n",nfds);
|
||||
epoll_trigger_counter++;
|
||||
//printf("%d %d %d %d\n",timer_fd,raw_recv_fd,raw_send_fd,n);
|
||||
if ((events[idx].data.u64) == (u64_t)timer_fd) {
|
||||
if ((events[idx].data.u64 ) == (u64_t)timer_fd)
|
||||
{
|
||||
if(debug_flag)begin_time=get_current_time();
|
||||
conn_manager.clear_inactive();
|
||||
u64_t dummy;
|
||||
int unused=read(timer_fd, &dummy, 8);
|
||||
//current_time_rough=get_current_time();
|
||||
if (debug_flag) {
|
||||
if(debug_flag)
|
||||
{
|
||||
end_time=get_current_time();
|
||||
mylog(log_debug,"timer_fd,%llu,%llu,%llu\n",begin_time,end_time,end_time-begin_time);
|
||||
}
|
||||
@@ -739,16 +843,22 @@ int server_event_loop() {
|
||||
mylog(log_trace,"epoll_trigger_counter: %d \n",epoll_trigger_counter);
|
||||
epoll_trigger_counter=0;
|
||||
|
||||
} else if (events[idx].data.u64 == (u64_t)raw_recv_fd) {
|
||||
}
|
||||
else if (events[idx].data.u64 == (u64_t)raw_recv_fd)
|
||||
{
|
||||
if(debug_flag)begin_time=get_current_time();
|
||||
server_on_raw_recv_multi();
|
||||
if (debug_flag) {
|
||||
if(debug_flag)
|
||||
{
|
||||
end_time=get_current_time();
|
||||
mylog(log_debug,"raw_recv_fd,%llu,%llu,%llu \n",begin_time,end_time,end_time-begin_time);
|
||||
}
|
||||
} else if (events[idx].data.u64 == (u64_t)fifo_fd) {
|
||||
}
|
||||
else if (events[idx].data.u64 == (u64_t)fifo_fd)
|
||||
{
|
||||
int len=read (fifo_fd, buf, sizeof (buf));
|
||||
if (len < 0) {
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
@@ -758,9 +868,13 @@ int server_event_loop() {
|
||||
buf[len-1]=0;
|
||||
mylog(log_info,"got data from fifo,len=%d,s=[%s]\n",len,buf);
|
||||
mylog(log_info,"unknown command\n");
|
||||
} else if (events[idx].data.u64 > u32_t(-1)) {
|
||||
}
|
||||
else if (events[idx].data.u64>u32_t(-1) )
|
||||
{
|
||||
|
||||
fd64_t fd64=events[idx].data.u64;
|
||||
if (!fd_manager.exist(fd64)) {
|
||||
if(!fd_manager.exist(fd64))
|
||||
{
|
||||
mylog(log_trace ,"fd64 no longer exist\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -769,29 +883,36 @@ int server_event_loop() {
|
||||
conn_info_t &conn_info=*p_conn_info;
|
||||
if(fd64==conn_info.timer_fd64)//////////timer_fd64
|
||||
{
|
||||
|
||||
if(debug_flag)begin_time=get_current_time();
|
||||
int fd=fd_manager.to_fd(fd64);
|
||||
u64_t dummy;
|
||||
int unused=read(fd, &dummy, 8);
|
||||
assert(conn_info.state.server_current_state == server_ready); //TODO remove this for peformance
|
||||
server_on_timer_multi(conn_info);
|
||||
if (debug_flag) {
|
||||
if(debug_flag)
|
||||
{
|
||||
end_time=get_current_time();
|
||||
mylog(log_debug,"(events[idx].data.u64 >>32u) == 2u ,%llu,%llu,%llu \n",begin_time,end_time,end_time-begin_time);
|
||||
}
|
||||
} else // udp_fd64
|
||||
}
|
||||
else//udp_fd64
|
||||
{
|
||||
if(debug_flag)begin_time=get_current_time();
|
||||
server_on_udp_recv(conn_info,fd64);
|
||||
if (debug_flag) {
|
||||
if(debug_flag)
|
||||
{
|
||||
end_time=get_current_time();
|
||||
mylog(log_debug,"(events[idx].data.u64 >>32u) == 1u,%lld,%lld,%lld \n",begin_time,end_time,end_time-begin_time);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"unknown fd,this should never happen\n");
|
||||
myexit(-1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user