Compare commits
190 Commits
20170821.0
...
20171123.1
Author | SHA1 | Date | |
---|---|---|---|
|
3bc07d5c86 | ||
|
f081ab751d | ||
|
91097eab5d | ||
|
c22b5e9680 | ||
|
9162a533d3 | ||
|
b01b087949 | ||
|
51b45c8f39 | ||
|
995ea8c98d | ||
|
aec81eb0c9 | ||
|
8b59b4afb9 | ||
|
c33bb552cd | ||
|
9516cfe99d | ||
|
5b1e59cae2 | ||
|
211d7ea4d3 | ||
|
7599d99fcc | ||
|
706cb0b583 | ||
|
43ae798e77 | ||
|
2f12d55229 | ||
|
0a4555dd42 | ||
|
14ece87bc3 | ||
|
50f682daf4 | ||
|
d487ca57f7 | ||
|
482e658858 | ||
|
069a9ba2b4 | ||
|
c591902be1 | ||
|
6a825dc51e | ||
|
1bdb6a5720 | ||
|
1afe8d7317 | ||
|
a54a0e269b | ||
|
e8398d0d31 | ||
|
dc43cb740b | ||
|
2e6be9e159 | ||
|
7a23486533 | ||
|
6515d428e9 | ||
|
c3e1dab838 | ||
|
00edb620be | ||
|
95ee6e64dc | ||
|
deeb7395a4 | ||
|
537f8a6311 | ||
|
f34f903317 | ||
|
6e1df4b39f | ||
|
c755a7d7ec | ||
|
6c0642c37e | ||
|
740e10bd04 | ||
|
a549793d82 | ||
|
a989a9f381 | ||
|
54f32f0611 | ||
|
9e173f9513 | ||
|
452661b389 | ||
|
dcde8828c4 | ||
|
fc05e7f080 | ||
|
f096a510b5 | ||
|
8de2506eff | ||
|
3960ca1b36 | ||
|
d778be2bfc | ||
|
0e77b0d5ab | ||
|
545f9796aa | ||
|
32ad8df38d | ||
|
3b0a4c7d08 | ||
|
61d48253f1 | ||
|
e1a97c03b5 | ||
|
6c6b4d2284 | ||
|
3eaf3e908e | ||
|
35603a69e8 | ||
|
4615ab6364 | ||
|
378449ee28 | ||
|
dcc722ff5e | ||
|
661b329930 | ||
|
0de85dd736 | ||
|
fb54df66e4 | ||
|
3cdac6d95c | ||
|
9c51c14ad6 | ||
|
36d6854a57 | ||
|
b239e94342 | ||
|
86483be894 | ||
|
1c831f2911 | ||
|
d250528d29 | ||
|
0de39f1aae | ||
|
09b1cadb45 | ||
|
cf5774d2f4 | ||
|
2810a72a72 | ||
|
f8e64b03de | ||
|
2a4f50a6c6 | ||
|
82771f9e39 | ||
|
9a959c2dcf | ||
|
206dd1565c | ||
|
515d4e1dd8 | ||
|
adbe7d110f | ||
|
0fe1a3d38c | ||
|
9472fe8bb3 | ||
|
a8e5df4b35 | ||
|
cf5babd748 | ||
|
a235a7176e | ||
|
5ef9d3fefa | ||
|
bc3801e17d | ||
|
178327c581 | ||
|
698504aca0 | ||
|
934a65e7bf | ||
|
c8113ccb06 | ||
|
5e8269f8f5 | ||
|
f34d9b2820 | ||
|
6f107ec475 | ||
|
5651efd165 | ||
|
0aba2ab7ba | ||
|
106ac96671 | ||
|
1b72661b49 | ||
|
fc796641a1 | ||
|
91904d6311 | ||
|
3cbad7df23 | ||
|
7fa5b90be8 | ||
|
6c865cc5ab | ||
|
215f2a82f2 | ||
|
063931d1c1 | ||
|
ff6f4b4005 | ||
|
065f4d73fa | ||
|
64f97299a2 | ||
|
67cb1356e4 | ||
|
0cc72802e6 | ||
|
44eb464182 | ||
|
9c64891b28 | ||
|
51bbaa0627 | ||
|
d3290a9a94 | ||
|
9c9c549bd1 | ||
|
c0c7bfda68 | ||
|
87483d2f0d | ||
|
6ef15f0185 | ||
|
16a9b3ba89 | ||
|
1a999fd96d | ||
|
c8694bf080 | ||
|
c467ad5c38 | ||
|
241baede16 | ||
|
d2ebcf6f6d | ||
|
dc52499818 | ||
|
56d4287fc2 | ||
|
d4e2c28cce | ||
|
535642684b | ||
|
cb334f37f0 | ||
|
11ebd6f2ee | ||
|
bd1e7fbc2f | ||
|
1f94c40ccf | ||
|
05156c9366 | ||
|
75e0a7f40a | ||
|
42fb66894f | ||
|
7c4e39cf20 | ||
|
01a1d2b006 | ||
|
57be59e070 | ||
|
fe77bb0c1a | ||
|
cb9504f904 | ||
|
dc4936dc60 | ||
|
53609c25fc | ||
|
60efcbce95 | ||
|
5c4ea515f6 | ||
|
e3b902a950 | ||
|
37f2de2ae4 | ||
|
ae497908a1 | ||
|
b59ba05422 | ||
|
cd34922722 | ||
|
51e5b023b0 | ||
|
b1800fa41a | ||
|
698ff33892 | ||
|
1293b95335 | ||
|
7e74b40977 | ||
|
d1e9bdc5da | ||
|
2b9d5c6db6 | ||
|
b86d475f1f | ||
|
0a7f9b5cc6 | ||
|
eb9633ed59 | ||
|
c0b464aeaf | ||
|
020242b73d | ||
|
2269879a2e | ||
|
057f81007d | ||
|
1f2f0d96fd | ||
|
01e0e51b9b | ||
|
6ef38709a6 | ||
|
57b874ee6d | ||
|
ab0ce3ade3 | ||
|
32f344fd3c | ||
|
968d35178a | ||
|
f8e268769c | ||
|
b9030fe81d | ||
|
e6f0ed035c | ||
|
00e1ddfecc | ||
|
15e1790f73 | ||
|
763b0b7342 | ||
|
c716d617a0 | ||
|
60393d24d8 | ||
|
9e7ed280fc | ||
|
532693edc6 | ||
|
033fa830f7 | ||
|
51464ecbfe |
52
.cproject
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.436825263">
|
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1051378038">
|
||||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.436825263" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1051378038" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||||
<externalSettings/>
|
<externalSettings/>
|
||||||
<extensions>
|
<extensions>
|
||||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
@@ -14,28 +14,17 @@
|
|||||||
</extensions>
|
</extensions>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.436825263" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.1051378038" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.436825263.480908490" name="/" resourcePath="">
|
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.1051378038.1421447843" name="/" resourcePath="">
|
||||||
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1517253393" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
|
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1854135910" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
|
||||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.1797790700" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.708367396" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
||||||
<builder id="cdt.managedbuild.target.gnu.builder.base.1253245139" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
|
<builder id="cdt.managedbuild.target.gnu.builder.base.1743684210" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
|
||||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.2108168419" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1848194835" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1940762076" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1873425854" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.997669137" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1356109619" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"/>
|
||||||
</tool>
|
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1018655568" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
|
||||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.233419498" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.180014749" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.460189617" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
<tool id="cdt.managedbuild.tool.gnu.assembler.base.2017907772" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"/>
|
||||||
</tool>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.54583610" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.2065407163" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.263855663" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
|
||||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
|
||||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
|
||||||
</inputType>
|
|
||||||
</tool>
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.assembler.base.747872161" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1349563828" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
|
||||||
</tool>
|
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -43,16 +32,6 @@
|
|||||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
</cconfiguration>
|
</cconfiguration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
|
||||||
<project id="udp2raw-tunnel-desktop.null.370025459" name="udp2raw-tunnel-desktop"/>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
|
||||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
|
||||||
<configuration configurationName="Default">
|
|
||||||
<resource resourceType="PROJECT" workspacePath="/udp2raw-tunnel-desktop"/>
|
|
||||||
</configuration>
|
|
||||||
</storageModule>
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
|
||||||
<storageModule moduleId="scannerConfiguration">
|
<storageModule moduleId="scannerConfiguration">
|
||||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.436825263;cdt.managedbuild.toolchain.gnu.base.436825263.480908490;cdt.managedbuild.tool.gnu.cpp.compiler.base.1940762076;cdt.managedbuild.tool.gnu.cpp.compiler.input.997669137">
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.436825263;cdt.managedbuild.toolchain.gnu.base.436825263.480908490;cdt.managedbuild.tool.gnu.cpp.compiler.base.1940762076;cdt.managedbuild.tool.gnu.cpp.compiler.input.997669137">
|
||||||
@@ -62,5 +41,8 @@
|
|||||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
</scannerConfigBuildInfo>
|
</scannerConfigBuildInfo>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<project id="udp2raw.null.1592488805" name="udp2raw"/>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||||
</cproject>
|
</cproject>
|
||||||
|
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" ]
|
6
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
For English speaking user:
|
||||||
|
https://github.com/wangyu-/UDPspeeder/wiki/Issue-Guide
|
||||||
|
|
||||||
|
中文用户请看:
|
||||||
|
https://github.com/wangyu-/UDPspeeder/wiki/发Issue前请看
|
||||||
|
(否则Issue可能被忽略,或被直接关掉)
|
141
README.md
@@ -1,21 +1,31 @@
|
|||||||
# Udp2raw-tunnel
|
# Udp2raw-tunnel
|
||||||
|
|
||||||
|
|
||||||
|
A Tunnel which turns UDP Traffic into Encrypted FakeTCP/UDP/ICMP Traffic by using Raw Socket, helps you Bypass UDP FireWalls(or Unstable UDP Environment). It can defend Replay-Attack and supports Multiplexing. It also acts as a Connection Stabilizer.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
A UDP Tunnel which tunnels UDP via FakeTCP/UDP/ICMP Traffic by using Raw Socket,helps you Bypass UDP FireWalls(or Unstable UDP Environment).Its Encrpyted,Anti-Replay and Multiplexed.It aslo acts as a Connection Stablizer.
|
When used alone,udp2raw tunnels only UDP traffic. Nevertheless,if you used udp2raw + any UDP-based VPN together,you can tunnel any traffic(include TCP/UDP/ICMP),currently OpenVPN/L2TP/ShadowVPN and [tinyFecVPN](https://github.com/wangyu-/tinyFecVPN) are confirmed to be supported.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
[简体中文](/doc/README.zh-cn.md)
|
[简体中文](/doc/README.zh-cn.md)
|
||||||
# Support Platforms
|
|
||||||
A Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root access.
|
|
||||||
|
|
||||||
For Winodws/MacOS,virtual image with udp2raw pre-installed has been released,you can load it with Vmware/VirtualBox.The virtual image has been set to auto obtain ip,udp2raw can be run imidiately after boot finished(make sure network mode of virtual machine has been set to bridged)(only udp2raw has to be run under virtual machine,all other programs runs under Windows/MacOS as usual).
|
# Support Platforms
|
||||||
|
Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root access.
|
||||||
|
|
||||||
|
For Windows and MacOS You can run udp2raw inside [this](https://github.com/wangyu-/udp2raw-tunnel/releases/download/20171108.0/lede-17.01.2-x86_virtual_machine_image.zip) 7.5mb virtual machine image(make sure network adapter runs at bridged mode).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
### Send / Receive UDP Packet with fake-tcp/icmp headers
|
### Send/Receive UDP Packets with ICMP/FakeTCP/UDP headers
|
||||||
Fake-tcp/icmp headers help you bypass UDP blocking, UDP QOS or improper UDP NAT behavior on some ISPs. Raw packets with 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.
|
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.
|
||||||
|
|
||||||
### Simulate TCP Handshake
|
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 encrytion, anti-replay, or connection stalization).
|
||||||
Simulates the 3-way handshake, along with seq and ack_seq. TCP options MSS, sackOk, TS, TS_ack, wscale are also simulated. Real-time delivery guaranteed, no TCP over TCP problem when using OpenVPN.
|
|
||||||
|
### 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 following TCP options: `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 congrestion control or re-transmission. So there wont be any TCP over TCP problem when using OpenVPN.
|
||||||
|
|
||||||
### Encrpytion, Anti-Replay
|
### Encrpytion, Anti-Replay
|
||||||
* Encrypt your traffic with AES-128-CBC.
|
* Encrypt your traffic with AES-128-CBC.
|
||||||
@@ -23,9 +33,9 @@ Simulates the 3-way handshake, along with seq and ack_seq. TCP options MSS, sack
|
|||||||
* Defense replay attack with an anti-replay window, smiliar to IPSec and OpenVPN.
|
* Defense replay attack with an anti-replay window, smiliar to IPSec and OpenVPN.
|
||||||
|
|
||||||
### Failure Dectection & Stablization (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.
|
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 the network cable is re-plugged or the WiFi access point is changed**.
|
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**.
|
||||||
|
|
||||||
### Other Features
|
### Other Features
|
||||||
* **Multiplexing** One client can handle multiple UDP connections, all of which share the same raw connection.
|
* **Multiplexing** One client can handle multiple UDP connections, all of which share the same raw connection.
|
||||||
@@ -34,12 +44,28 @@ For example, if you use UDP2RAW + OpenVPN, OpenVPN won't lose connection after a
|
|||||||
|
|
||||||
* **NAT Support** All of the 3 modes work in NAT environments.
|
* **NAT Support** All of the 3 modes work in NAT environments.
|
||||||
|
|
||||||
* **OpenVZ Support** Tested on BandwagonHost.
|
* **OpenVZ Support** Tested on BandwagonHost VPS.
|
||||||
|
|
||||||
* **OpenWRT Support** No dependencies, easy to build. Binary for ar71xx are included in release.
|
* **Easy to Build** No dependencies.To cross-compile udp2raw,all you need to do is just to download a toolchain,modify makefile to point at the toolchain,run `make cross` then everything is done.(Note:Pre-compiled binaries for Desktop,RaspberryPi,Android,some Openwrt Routers are already included in [Releases](https://github.com/wangyu-/udp2raw-tunnel/releases))
|
||||||
|
|
||||||
### Keywords
|
### Keywords
|
||||||
`UDP QoS Bypass` `UDP Blocking Bypass` `OpenVPN TCP over TCP problem` `OpenVPN over ICMP` `UDP to ICMP tunnel` `UDP to TCP tunnel` `UDP over ICMP` `UDP over TCP`
|
`Bypass UDP QoS` `Bypass UDP Blocking` `Bypass OpenVPN TCP over TCP problem` `OpenVPN over ICMP` `UDP to ICMP tunnel` `UDP to TCP tunnel` `UDP over ICMP` `UDP over TCP`
|
||||||
|
|
||||||
|
# Frequently Asked Questions
|
||||||
|
### Q: What is the advantage of using udp2raw FakeTCP mode,why not use a TCP-based VPN(such as OpenVPN TCP mode)?
|
||||||
|
Answer: **TCP doesnt allow real-time/out-of-order delivery**. **If you use OpenVPN TCP mode to turn UDP traffic into TCP,there will be latency issue**:the loss of a single packet blocks all following packet until re-transmission is done. This will cause unacceptable delay for gaming and voice chatting.
|
||||||
|
|
||||||
|
**TCP also has re-transmission and congestion control which cant be disabled.** UDP programs usualy want to control packet sending rate by themselves. If you use OpenVPN TCP mode this cant be done because of the congestion control of underlying TCP protocol. Further more,with the re-transmission of underlying TCP,**if you send too many udp packets via an OpenVPN TCP connection,the connection will become completely unusable for a while**(It will eventually recover as most of the re-transmission is done,but it wont be very soon).
|
||||||
|
|
||||||
|
Those issues exist for almost all TCP-based VPNs.
|
||||||
|
|
||||||
|
For udp2raw there is no underlying TCP protocol,udp2raw just add TCP headers to UDP packets directly by using raw socket. It supports real-time/out-of-order delivery,there is no re-transmission and congestion control. **Udp2raw doesnt have all above issues**.
|
||||||
|
|
||||||
|
### Q: Is udp2raw designed for replacing VPN?
|
||||||
|
Answer: No. Udp2raw is designed for bypassing UDP restrictions. It doesnt have all of the features a VPN has(such as transparently redirect all traffic).
|
||||||
|
|
||||||
|
Instead of replacing VPN,udp2raw can be used with any UDP-based VPN together to grant UDP-based VPN the ablity of bypassing UDP restrictions,while not having the performance issue involved by a TCP-based VPN. Check [this link](https://github.com/wangyu-/udp2raw-tunnel#tunneling-any-traffic-via-raw-traffic-by-using-udp2raw-openvpn) for more info.
|
||||||
|
|
||||||
|
|
||||||
# Getting Started
|
# Getting Started
|
||||||
### Installing
|
### Installing
|
||||||
@@ -63,13 +89,17 @@ Assume your UDP is blocked or being QOS-ed or just poorly supported. Assume your
|
|||||||
Now,an encrypted raw tunnel has been established between client and server through TCP port 4096. Connecting to UDP port 3333 at the client side is equivalent to connecting to port 7777 at the server side. No UDP traffic will be exposed.
|
Now,an encrypted raw tunnel has been established between client and server through TCP port 4096. Connecting to UDP port 3333 at the client side is equivalent to connecting to port 7777 at the server side. No UDP traffic will be exposed.
|
||||||
|
|
||||||
### Note
|
### Note
|
||||||
to run on Android, see [Android_Guide](/doc/android_guide.md)
|
To run on Android, check [Android_Guide](/doc/android_guide.md)
|
||||||
|
|
||||||
|
If you have connection problems.Take a look at `--seq-mode` option.
|
||||||
|
|
||||||
|
You can run udp2raw with a non-root account(for better security).Take a look at [#26](https://github.com/wangyu-/udp2raw-tunnel/issues/26) for more info.
|
||||||
|
|
||||||
# Advanced Topic
|
# Advanced Topic
|
||||||
### Usage
|
### Usage
|
||||||
```
|
```
|
||||||
udp2raw-tunnel
|
udp2raw-tunnel
|
||||||
version: Aug 18 2017 00:29:11
|
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
|
||||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
@@ -82,13 +112,18 @@ common options,these options must be same on both side:
|
|||||||
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
||||||
--auth-mode <string> avaliable values:md5(default),crc32,simple,none
|
--auth-mode <string> avaliable values:md5(default),crc32,simple,none
|
||||||
-a,--auto-rule auto add (and delete) iptables rule
|
-a,--auto-rule auto add (and delete) iptables rule
|
||||||
-g,--gen-rule generate iptables rule then exit
|
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
||||||
|
add it manually.overrides -a
|
||||||
--disable-anti-replay disable anti-replay,not suggested
|
--disable-anti-replay disable anti-replay,not suggested
|
||||||
client options:
|
client options:
|
||||||
--source-ip <ip> force source-ip for raw socket
|
--source-ip <ip> force source-ip for raw socket
|
||||||
--source-port <port> force source-port for raw socket,tcp/udp only
|
--source-port <port> force source-port for raw socket,tcp/udp only
|
||||||
this option disables port changing while re-connecting
|
this option disables port changing while re-connecting
|
||||||
other options:
|
other options:
|
||||||
|
--conf-file <string> read options from a configuration file instead of command line.
|
||||||
|
check example.conf in repo for format
|
||||||
|
--fifo <string> use a fifo(named pipe) for sending commands to the running program,
|
||||||
|
check readme.md in repository for supported commands.
|
||||||
--log-level <number> 0:never 1:fatal 2:error 3:warn
|
--log-level <number> 0:never 1:fatal 2:error 3:warn
|
||||||
4:info (default) 5:debug 6:trace
|
4:info (default) 5:debug 6:trace
|
||||||
--log-position enable file name,function name,line number in log
|
--log-position enable file name,function name,line number in log
|
||||||
@@ -96,24 +131,76 @@ other options:
|
|||||||
--disable-bpf disable the kernel space filter,most time its not necessary
|
--disable-bpf disable the kernel space filter,most time its not necessary
|
||||||
unless you suspect there is a bug
|
unless you suspect there is a bug
|
||||||
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
||||||
--seqmode <number> seq increase mode for faketcp:
|
--force-sock-buf bypass system limitation while setting sock-buf
|
||||||
0:dont increase
|
--seq-mode <number> seq increase mode for faketcp:
|
||||||
1:increase every packet
|
0:static header,do not increase seq and ack_seq
|
||||||
2:increase randomly, about every 3 packets (default)
|
1:increase seq for every packet,simply ack last seq
|
||||||
--lower-level <string> send packet at OSI level 2, format:'if_name#dest_mac_adress'
|
2:increase seq randomly, about every 3 packets,simply ack last seq
|
||||||
ie:'eth0#00:23:45:67:89:b9'.Beta.
|
3:simulate an almost real seq/ack procedure(default)
|
||||||
|
4:similiar to 3,but do not consider TCP Option Window_Scale,
|
||||||
|
maybe useful when firewall doesnt support TCP Option
|
||||||
|
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
|
||||||
|
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
|
||||||
|
the parameter automatically,specify it manually if 'auto' failed
|
||||||
|
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
|
||||||
|
--keep-rule monitor iptables and auto re-add if necessary.implys -a
|
||||||
|
--clear clear any iptables rules added by this program.overrides everything
|
||||||
-h,--help print this help message
|
-h,--help print this help message
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### IPTABLES rule
|
### Iptables rules,`-a` and `-g`
|
||||||
This program sends packets via raw socket. In FakeTCP mode, Linux kernel TCP packet processing has to be blocked by a iptables rule on both sides, otherwise the kernel will automatically send RST for an unrecongized TCP packet and you will sustain from stability / peformance problems. You can use `-a` option to let the program automatically add / delete iptables rule on start / exit. You can also use the `-g` option to generate iptables rule and add it manually.
|
This program sends packets via raw socket. In FakeTCP mode, Linux kernel TCP packet processing has to be blocked by a iptables rule on both sides, otherwise the kernel will automatically send RST for an unrecongized TCP packet and you will sustain from stability / peformance problems. You can use `-a` option to let the program automatically add / delete iptables rule on start / exit. You can also use the `-g` option to generate iptables rule and add it manually.
|
||||||
|
|
||||||
### `cipher-mode` and `auth-mode`
|
### `--cipher-mode` and `--auth-mode`
|
||||||
It is suggested to use `aes128cbc` + `md5` to obtain maximum security. If you want to run the program on a router, you can try `xor` + `simple`, which can fool packet inspection by firewalls the most of time, but it cannot protect you from serious attacks. Mode none is only for debugging purpose. It is not recommended to set the cipher-mode or auth-mode to none.
|
It is suggested to use `aes128cbc` + `md5` to obtain maximum security. If you want to run the program on a router, you can try `xor` + `simple`, which can fool packet inspection by firewalls the most of time, but it cannot protect you from serious attacks. Mode none is only for debugging purpose. It is not recommended to set the cipher-mode or auth-mode to none.
|
||||||
|
|
||||||
### seq-mode
|
### `--seq-mode`
|
||||||
The FakeTCP mode does not behave 100% like a real tcp connection. ISPs may be able to distinguish the simulated tcp traffic from the real TCP traffic (though it's costly). seq-mode can help you change the seq increase behavior slightly. If you experience connection problems, try to change the value.
|
The FakeTCP mode does not behave 100% like a real tcp connection. ISPs may be able to distinguish the simulated tcp traffic from the real TCP traffic (though it's costly). seq-mode can help you change the seq increase behavior slightly. If you experience connection problems, try to change the value.
|
||||||
|
|
||||||
|
### `--lower-level`
|
||||||
|
`--lower-level` allows you to send packet at OSI level 2(link level),so that you can bypass any local iptables rules. If you have a complicated iptables rules which conflicts with udp2raw and you cant(or too lazy to) edit the iptables rules,`--lower-level` can be very useful. Try `--lower-level auto` to auto detect the parameters,you can specify it manually if `auto` fails.
|
||||||
|
|
||||||
|
Manual format `if_name#dest_mac_adress`,ie:`eth0#00:23:45:67:89:b9`.
|
||||||
|
|
||||||
|
### `--keep-rule`
|
||||||
|
Monitor iptables and auto re-add iptables rules(for blocking kernel tcp processing) if necessary.Especially useful when iptables rules may be cleared by other programs(for example,if you are using openwrt,everytime you changed and commited a setting,iptables rule may be cleared and re-constructed).
|
||||||
|
|
||||||
|
### `--conf-file`
|
||||||
|
|
||||||
|
You can also load options from a configuration file in order to keep secrets away from `ps` command.
|
||||||
|
|
||||||
|
For example, rewrite the options for the above `server` example (in Getting Started section) into configuration file:
|
||||||
|
|
||||||
|
`server.conf`
|
||||||
|
|
||||||
|
```
|
||||||
|
-s
|
||||||
|
# You can add comments like this
|
||||||
|
# Comments MUST occupy an entire line
|
||||||
|
# Or they will not work as expected
|
||||||
|
# Listen address
|
||||||
|
-l 0.0.0.0:4096
|
||||||
|
# Remote address
|
||||||
|
-r 127.0.0.1:7777
|
||||||
|
-a
|
||||||
|
-k passwd
|
||||||
|
--raw-mode faketcp
|
||||||
|
```
|
||||||
|
|
||||||
|
Pay attention to the `-k` parameter: In command line mode the quotes around the password will be removed by shell. In configuration files we do not remove quotes.
|
||||||
|
|
||||||
|
Then start the server with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./udp2raw_amd64 --conf-file server.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
### `--fifo`
|
||||||
|
Use a fifo(named pipe) for sending commands to the running program. For example `--fifo fifo.file`.
|
||||||
|
|
||||||
|
At client side,you can use `echo reconnect >fifo.file` to force client to reconnect.Currently no command has been implemented for server.
|
||||||
|
|
||||||
# Peformance Test
|
# Peformance Test
|
||||||
#### Test method:
|
#### Test method:
|
||||||
iperf3 TCP via OpenVPN + udp2raw
|
iperf3 TCP via OpenVPN + udp2raw
|
||||||
@@ -144,10 +231,10 @@ raw_mode: faketcp cipher_mode: aes128cbc auth_mode: md5
|
|||||||
|
|
||||||
# Application
|
# Application
|
||||||
## Tunneling any traffic via raw traffic by using udp2raw +openvpn
|
## Tunneling any traffic via raw traffic by using udp2raw +openvpn
|
||||||

|

|
||||||
1. Bypasses UDP block/UDP QOS
|
1. Bypasses UDP block/UDP QOS
|
||||||
|
|
||||||
2. No TCP ovr TCP problem (TCP over TCP problem http://sites.inka.de/bigred/devel/tcp-tcp.html ,https://community.openvpn.net/openvpn/ticket/2 )
|
2. No TCP over TCP problem (TCP over TCP problem http://sites.inka.de/bigred/devel/tcp-tcp.html ,https://community.openvpn.net/openvpn/ticket/2 )
|
||||||
|
|
||||||
3. OpenVpn over ICMP also becomes a choice
|
3. OpenVpn over ICMP also becomes a choice
|
||||||
|
|
||||||
|
@@ -2,10 +2,11 @@ cmake_minimum_required(VERSION 3.7)
|
|||||||
project(udp2raw_tunnel)
|
project(udp2raw_tunnel)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set_source_files_properties(lib/aes.c lib/md5.c PROPERTIES LANGUAGE CXX )
|
set_source_files_properties(lib/aes_faster_c/aes.c lib/aes_faster_c/wrapper.c lib/md5.c PROPERTIES LANGUAGE CXX )
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
lib/aes.c
|
lib/aes_faster_c/aes.c
|
||||||
|
lib/aes_faster_c/wrapper.c
|
||||||
lib/md5.c
|
lib/md5.c
|
||||||
common.cpp
|
common.cpp
|
||||||
encrypt.cpp
|
encrypt.cpp
|
||||||
@@ -17,3 +18,4 @@ set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -W
|
|||||||
#set(CMAKE_LINK_LIBRARY_FLAG "-lrt")
|
#set(CMAKE_LINK_LIBRARY_FLAG "-lrt")
|
||||||
add_executable(udp2raw_cmake ${SOURCE_FILES})
|
add_executable(udp2raw_cmake ${SOURCE_FILES})
|
||||||
target_link_libraries(udp2raw_cmake rt)
|
target_link_libraries(udp2raw_cmake rt)
|
||||||
|
target_link_libraries(udp2raw_cmake pthread)
|
459
common.cpp
@@ -7,24 +7,10 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int about_to_exit=0;
|
|
||||||
|
|
||||||
raw_mode_t raw_mode=mode_faketcp;
|
|
||||||
unordered_map<int, const char*> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}};
|
|
||||||
int socket_buf_size=1024*1024;
|
|
||||||
static int random_number_fd=-1;
|
static int random_number_fd=-1;
|
||||||
string iptables_pattern="";
|
|
||||||
int iptables_rule_added=0;
|
|
||||||
int iptables_rule_keeped=0;
|
|
||||||
int iptables_rule_keep_index=0;
|
|
||||||
//int iptables_rule_no_clear=0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
program_mode_t program_mode=unset_mode;//0 unset; 1client 2server
|
|
||||||
|
|
||||||
u64_t get_current_time()
|
u64_t get_current_time()
|
||||||
{
|
{
|
||||||
@@ -56,166 +42,6 @@ char * my_ntoa(u32_t ip)
|
|||||||
return inet_ntoa(a);
|
return inet_ntoa(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
int add_iptables_rule(const char * s)
|
|
||||||
{
|
|
||||||
|
|
||||||
iptables_pattern=s;
|
|
||||||
|
|
||||||
string rule="iptables -I INPUT ";
|
|
||||||
rule+=iptables_pattern;
|
|
||||||
rule+=" -j DROP";
|
|
||||||
|
|
||||||
char *output;
|
|
||||||
if(run_command(rule.c_str(),output)==0)
|
|
||||||
{
|
|
||||||
mylog(log_warn,"auto added iptables rule by: %s\n",rule.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mylog(log_fatal,"auto added iptables failed by: %s\n",rule.c_str());
|
|
||||||
//mylog(log_fatal,"reason : %s\n",strerror(errno));
|
|
||||||
myexit(-1);
|
|
||||||
}
|
|
||||||
iptables_rule_added=1;
|
|
||||||
return 0;
|
|
||||||
}*/
|
|
||||||
string chain[2];
|
|
||||||
string rule_keep[2];
|
|
||||||
string rule_keep_add[2];
|
|
||||||
string rule_keep_del[2];
|
|
||||||
u64_t keep_rule_last_time=0;
|
|
||||||
|
|
||||||
pthread_t keep_thread;
|
|
||||||
int keep_thread_running=0;
|
|
||||||
int iptables_gen_add(const char * s,u32_t const_id)
|
|
||||||
{
|
|
||||||
string dummy="";
|
|
||||||
iptables_pattern=s;
|
|
||||||
chain[0] =dummy+ "udp2rawDwrW_C";
|
|
||||||
rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
|
|
||||||
rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
|
|
||||||
|
|
||||||
char *output;
|
|
||||||
run_command(dummy+"iptables -N "+chain[0],output,show_none);
|
|
||||||
run_command(dummy+"iptables -F "+chain[0],output);
|
|
||||||
run_command(dummy+"iptables -I "+chain[0] + " -j DROP",output);
|
|
||||||
|
|
||||||
rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
|
|
||||||
|
|
||||||
run_command(rule_keep_del[0],output,show_none);
|
|
||||||
run_command(rule_keep_del[0],output,show_none);
|
|
||||||
|
|
||||||
if(run_command(rule_keep_add[0],output)!=0)
|
|
||||||
{
|
|
||||||
mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[0].c_str());
|
|
||||||
myexit(-1);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int iptables_rule_init(const char * s,u32_t const_id,int keep)
|
|
||||||
{
|
|
||||||
iptables_pattern=s;
|
|
||||||
iptables_rule_added=1;
|
|
||||||
iptables_rule_keeped=keep;
|
|
||||||
|
|
||||||
string dummy="";
|
|
||||||
char const_id_str[100];
|
|
||||||
sprintf(const_id_str, "%x", const_id);
|
|
||||||
|
|
||||||
chain[0] =dummy+ "udp2rawDwrW_"+const_id_str+"_C0";
|
|
||||||
chain[1] =dummy+ "udp2rawDwrW_"+const_id_str+"_C1";
|
|
||||||
|
|
||||||
rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
|
|
||||||
rule_keep[1]=dummy+ iptables_pattern+" -j " +chain[1];
|
|
||||||
|
|
||||||
rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
|
|
||||||
rule_keep_add[1]=dummy+"iptables -I INPUT "+rule_keep[1];
|
|
||||||
|
|
||||||
rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
|
|
||||||
rule_keep_del[1]=dummy+"iptables -D INPUT "+rule_keep[1];
|
|
||||||
|
|
||||||
keep_rule_last_time=get_current_time();
|
|
||||||
|
|
||||||
char *output;
|
|
||||||
|
|
||||||
for(int i=0;i<=iptables_rule_keeped;i++)
|
|
||||||
{
|
|
||||||
run_command(dummy+"iptables -N "+chain[i],output);
|
|
||||||
run_command(dummy+"iptables -F "+chain[i],output);
|
|
||||||
run_command(dummy+"iptables -I "+chain[i] + " -j DROP",output);
|
|
||||||
|
|
||||||
if(run_command(rule_keep_add[i],output)!=0)
|
|
||||||
{
|
|
||||||
mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[i].c_str());
|
|
||||||
myexit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int keep_iptables_rule() //magic to work on a machine without grep/iptables --check/-m commment
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if(iptables_rule_keeped==0) return 0;
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t tmp_current_time=get_current_time();
|
|
||||||
if(tmp_current_time-keep_rule_last_time<=iptables_rule_keep_interval)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
keep_rule_last_time=tmp_current_time;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
mylog(log_debug,"keep_iptables_rule begin %llu\n",get_current_time());
|
|
||||||
iptables_rule_keep_index+=1;
|
|
||||||
iptables_rule_keep_index%=2;
|
|
||||||
|
|
||||||
string dummy="";
|
|
||||||
char *output;
|
|
||||||
|
|
||||||
int i=iptables_rule_keep_index;
|
|
||||||
|
|
||||||
run_command(dummy + "iptables -N " + chain[i], output,show_none);
|
|
||||||
|
|
||||||
if (run_command(dummy + "iptables -F " + chain[i], output,show_none) != 0)
|
|
||||||
mylog(log_warn, "iptables -F failed %d\n",i);
|
|
||||||
|
|
||||||
if (run_command(dummy + "iptables -I " + chain[i] + " -j DROP",output,show_none) != 0)
|
|
||||||
mylog(log_warn, "iptables -I failed %d\n",i);
|
|
||||||
|
|
||||||
if (run_command(rule_keep_del[i], output,show_none) != 0)
|
|
||||||
mylog(log_warn, "rule_keep_del failed %d\n",i);
|
|
||||||
|
|
||||||
run_command(rule_keep_del[i], output,show_none); //do it twice,incase it fails for unknown random reason
|
|
||||||
|
|
||||||
if(run_command(rule_keep_add[i], output,show_log)!=0)
|
|
||||||
mylog(log_warn, "rule_keep_del failed %d\n",i);
|
|
||||||
|
|
||||||
mylog(log_debug,"keep_iptables_rule end %llu\n",get_current_time());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clear_iptables_rule()
|
|
||||||
{
|
|
||||||
char *output;
|
|
||||||
string dummy="";
|
|
||||||
if(!iptables_rule_added) return 0;
|
|
||||||
|
|
||||||
for(int i=0;i<=iptables_rule_keeped;i++ )
|
|
||||||
{
|
|
||||||
run_command(rule_keep_del[i],output);
|
|
||||||
run_command(dummy+"iptables -F "+chain[i],output);
|
|
||||||
run_command(dummy+"iptables -X "+chain[i],output);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void init_random_number_fd()
|
void init_random_number_fd()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -300,7 +126,7 @@ void setnonblocking(int sock) {
|
|||||||
/*
|
/*
|
||||||
Generic checksum calculation function
|
Generic checksum calculation function
|
||||||
*/
|
*/
|
||||||
unsigned short csum(const unsigned short *ptr,int nbytes) {
|
unsigned short csum(const unsigned short *ptr,int nbytes) {//works both for big and little endian
|
||||||
register long sum;
|
register long sum;
|
||||||
unsigned short oddbyte;
|
unsigned short oddbyte;
|
||||||
register short answer;
|
register short answer;
|
||||||
@@ -323,45 +149,37 @@ unsigned short csum(const unsigned short *ptr,int nbytes) {
|
|||||||
return(answer);
|
return(answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int set_buf_size(int fd)
|
int set_buf_size(int fd,int socket_buf_size,int force_socket_buf)
|
||||||
{
|
{
|
||||||
if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
if(force_socket_buf)
|
||||||
{
|
{
|
||||||
mylog(log_fatal,"SO_SNDBUFFORCE fail,fd %d\n",fd);
|
if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
myexit(1);
|
{
|
||||||
}
|
mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
myexit(1);
|
||||||
{
|
}
|
||||||
mylog(log_fatal,"SO_RCVBUFFORCE fail,fd %d\n",fd);
|
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
myexit(1);
|
{
|
||||||
}
|
mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void myexit(int a)
|
|
||||||
{
|
|
||||||
if(enable_log_color)
|
|
||||||
printf("%s\n",RESET);
|
|
||||||
if(keep_thread_running)
|
|
||||||
{
|
|
||||||
if(pthread_cancel(keep_thread))
|
|
||||||
{
|
|
||||||
mylog(log_warn,"pthread_cancel failed\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mylog(log_info,"pthread_cancel success\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clear_iptables_rule();
|
|
||||||
exit(a);
|
|
||||||
}
|
|
||||||
void signal_handler(int sig)
|
|
||||||
{
|
|
||||||
about_to_exit=1;
|
|
||||||
// myexit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
|
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
|
||||||
{
|
{
|
||||||
static char buf[buf_len];
|
static char buf[buf_len];
|
||||||
@@ -379,17 +197,48 @@ int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
|
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
|
||||||
{
|
{
|
||||||
if(len<int(sizeof(id_t)*3)) return -1;
|
if(len<int(sizeof(id_t)*3)) return -1;
|
||||||
id1=ntohl( *((id_t*)(data+0)) );
|
//id1=ntohl( *((id_t*)(data+0)) );
|
||||||
id2=ntohl( *((id_t*)(data+sizeof(id_t))) );
|
memcpy(&id1,data+0,sizeof(id1));
|
||||||
id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) );
|
id1=ntohl(id1);
|
||||||
|
//id2=ntohl( *((id_t*)(data+sizeof(id_t))) );
|
||||||
|
memcpy(&id2,data+sizeof(id_t),sizeof(id2));
|
||||||
|
id2=ntohl(id2);
|
||||||
|
//id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) );
|
||||||
|
memcpy(&id3,data+sizeof(id_t)*2,sizeof(id3));
|
||||||
|
id3=ntohl(id3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int hex_to_u32(const string & a,u32_t &output)
|
||||||
|
{
|
||||||
|
//string b="0x";
|
||||||
|
//b+=a;
|
||||||
|
if(sscanf(a.c_str(),"%x",&output)==1)
|
||||||
|
{
|
||||||
|
//printf("%s %x\n",a.c_str(),output);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mylog(log_error,"<%s> doesnt contain a hex\n",a.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int hex_to_u32_with_endian(const string & a,u32_t &output)
|
||||||
|
{
|
||||||
|
//string b="0x";
|
||||||
|
//b+=a;
|
||||||
|
if(sscanf(a.c_str(),"%x",&output)==1)
|
||||||
|
{
|
||||||
|
output=htonl(output);
|
||||||
|
//printf("%s %x\n",a.c_str(),output);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mylog(log_error,"<%s> doesnt contain a hex\n",a.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
bool larger_than_u32(u32_t a,u32_t b)
|
bool larger_than_u32(u32_t a,u32_t b)
|
||||||
|
//TODO
|
||||||
|
//looks like this can simply be done by return ((i32_t)(a-b) >0)
|
||||||
{
|
{
|
||||||
|
|
||||||
u32_t smaller,bigger;
|
u32_t smaller,bigger;
|
||||||
@@ -450,6 +299,26 @@ bool larger_than_u16(uint16_t a,uint16_t b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void myexit(int a)
|
||||||
|
{
|
||||||
|
if(enable_log_color)
|
||||||
|
printf("%s\n",RESET);
|
||||||
|
if(keep_thread_running)
|
||||||
|
{
|
||||||
|
if(pthread_cancel(keep_thread))
|
||||||
|
{
|
||||||
|
mylog(log_warn,"pthread_cancel failed\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mylog(log_info,"pthread_cancel success\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clear_iptables_rule();
|
||||||
|
exit(a);
|
||||||
|
}
|
||||||
|
|
||||||
vector<string> string_to_vec(const char * s,const char * sp) {
|
vector<string> string_to_vec(const char * s,const char * sp) {
|
||||||
vector<string> res;
|
vector<string> res;
|
||||||
string str=s;
|
string str=s;
|
||||||
@@ -458,8 +327,13 @@ vector<string> string_to_vec(const char * s,const char * sp) {
|
|||||||
{
|
{
|
||||||
res.push_back(p);
|
res.push_back(p);
|
||||||
//printf ("%s\n",p);
|
//printf ("%s\n",p);
|
||||||
p = strtok (NULL, sp);
|
p = strtok(NULL, sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for(int i=0;i<(int)res.size();i++)
|
||||||
|
{
|
||||||
|
printf("<<%s>>\n",res[i].c_str());
|
||||||
|
}*/
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,33 +349,38 @@ vector< vector <string> > string_to_vec2(const char * s)
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
int read_file(const char * file,char * &output)
|
int read_file(const char * file,string &output)
|
||||||
{
|
{
|
||||||
static char buf[1024*1024+100];
|
const int max_len=3*1024*1024;
|
||||||
buf[sizeof(buf)-1]=0;
|
// static char buf[max_len+100];
|
||||||
|
string buf0;
|
||||||
|
buf0.reserve(max_len+200);
|
||||||
|
char * buf=(char *)buf0.c_str();
|
||||||
|
buf[max_len]=0;
|
||||||
|
//buf[sizeof(buf)-1]=0;
|
||||||
int fd=open(file,O_RDONLY);
|
int fd=open(file,O_RDONLY);
|
||||||
if(fd==-1)
|
if(fd==-1)
|
||||||
{
|
{
|
||||||
mylog(log_error,"read_file %s fail\n",file);
|
mylog(log_error,"read_file %s fail\n",file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int len=read(fd,buf,1024*1024);
|
int len=read(fd,buf,max_len);
|
||||||
if(len==1024*1024)
|
if(len==max_len)
|
||||||
{
|
{
|
||||||
buf[0]=0;
|
buf[0]=0;
|
||||||
mylog(log_error,"too long,buf not larger enough\n");
|
mylog(log_error,"%s too long,buf not large enough\n",file);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
else if(len<0)
|
else if(len<0)
|
||||||
{
|
{
|
||||||
buf[0]=0;
|
buf[0]=0;
|
||||||
mylog(log_error,"read fail %d\n",len);
|
mylog(log_error,"%s read fail %d\n",file,len);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output=buf;
|
|
||||||
buf[len]=0;
|
buf[len]=0;
|
||||||
|
output=buf;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -607,3 +486,133 @@ int run_command_no_log(string command0,char * &output) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
// Remove preceding and trailing characters
|
||||||
|
string trim(const string& str, char c) {
|
||||||
|
size_t first = str.find_first_not_of(c);
|
||||||
|
if(string::npos==first)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
size_t last = str.find_last_not_of(c);
|
||||||
|
return str.substr(first,(last-first+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> parse_conf_line(const string& s0)
|
||||||
|
{
|
||||||
|
string s=s0;
|
||||||
|
s.reserve(s.length()+200);
|
||||||
|
char *buf=(char *)s.c_str();
|
||||||
|
//char buf[s.length()+200];
|
||||||
|
char *p=buf;
|
||||||
|
int i=int(s.length())-1;
|
||||||
|
int j;
|
||||||
|
vector<string>res;
|
||||||
|
strcpy(buf,(char *)s.c_str());
|
||||||
|
while(i>=0)
|
||||||
|
{
|
||||||
|
if(buf[i]==' ' || buf[i]== '\t')
|
||||||
|
buf[i]=0;
|
||||||
|
else break;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
while(*p!=0)
|
||||||
|
{
|
||||||
|
if(*p==' ' || *p== '\t')
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
int new_len=strlen(p);
|
||||||
|
if(new_len==0)return res;
|
||||||
|
if(p[0]=='#') return res;
|
||||||
|
if(p[0]!='-')
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"line :<%s> not begin with '-' ",s.c_str());
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<new_len;i++)
|
||||||
|
{
|
||||||
|
if(p[i]==' '||p[i]=='\t')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i==new_len)
|
||||||
|
{
|
||||||
|
res.push_back(p);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
j=i;
|
||||||
|
while(p[j]==' '||p[j]=='\t')
|
||||||
|
j++;
|
||||||
|
p[i]=0;
|
||||||
|
res.push_back(p);
|
||||||
|
res.push_back(p+j);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int create_fifo(char * file)
|
||||||
|
{
|
||||||
|
if(mkfifo (file, 0666)!=0)
|
||||||
|
{
|
||||||
|
if(errno==EEXIST)
|
||||||
|
{
|
||||||
|
mylog(log_warn,"warning fifo file %s exist\n",file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"create fifo file %s failed\n",file);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int fifo_fd=open (file, O_RDWR);
|
||||||
|
if(fifo_fd<0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"create fifo file %s failed\n",file);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fifo_fd, &st)!=0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"fstat failed for fifo file %s\n",file);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!S_ISFIFO(st.st_mode))
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"%s is not a fifo\n",file);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setnonblocking(fifo_fd);
|
||||||
|
return fifo_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip_port_t::from_u64(u64_t u64)
|
||||||
|
{
|
||||||
|
ip=get_u64_h(u64);
|
||||||
|
port=get_u64_l(u64);
|
||||||
|
}
|
||||||
|
u64_t ip_port_t::to_u64()
|
||||||
|
{
|
||||||
|
return pack_u64(ip,port);
|
||||||
|
}
|
||||||
|
char * ip_port_t::to_s()
|
||||||
|
{
|
||||||
|
static char res[40];
|
||||||
|
sprintf(res,"%s:%d",my_ntoa(ip),port);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
111
common.h
@@ -5,8 +5,8 @@
|
|||||||
* Author: wangyu
|
* Author: wangyu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMMON_H_
|
#ifndef UDP2RAW_COMMON_H_
|
||||||
#define COMMON_H_
|
#define UDP2RAW_COMMON_H_
|
||||||
#define __STDC_FORMAT_MACROS 1
|
#define __STDC_FORMAT_MACROS 1
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/socket.h> //for socket ofcourse
|
#include <sys/socket.h> //for socket ofcourse
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <stdlib.h> //for exit(0);
|
#include <stdlib.h> //for exit(0);
|
||||||
#include <errno.h> //For errno - the error number
|
#include <errno.h> //For errno - the error number
|
||||||
#include <netinet/tcp.h> //Provides declarations for tcp header
|
#include <netinet/tcp.h> //Provides declarations for tcp header
|
||||||
@@ -47,8 +48,11 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include<unordered_map>
|
#include<unordered_map>
|
||||||
#include<vector>
|
#include <fstream>
|
||||||
#include<string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
@@ -58,56 +62,6 @@ typedef long long i64_t;
|
|||||||
typedef unsigned int u32_t;
|
typedef unsigned int u32_t;
|
||||||
typedef int i32_t;
|
typedef int i32_t;
|
||||||
|
|
||||||
|
|
||||||
const int max_data_len=1600;
|
|
||||||
const int buf_len=max_data_len+400;
|
|
||||||
const u32_t max_handshake_conn_num=10000;
|
|
||||||
const u32_t max_ready_conn_num=1000;
|
|
||||||
const u32_t anti_replay_window_size=1000;
|
|
||||||
const int max_conv_num=10000;
|
|
||||||
|
|
||||||
const u32_t client_handshake_timeout=5000;
|
|
||||||
const u32_t client_retry_interval=1000;
|
|
||||||
|
|
||||||
const u32_t server_handshake_timeout=10000;// this should be much longer than clients. client retry initially ,server retry passtively
|
|
||||||
|
|
||||||
const int conv_clear_ratio=10; //conv grabage collecter check 1/10 of all conv one time
|
|
||||||
const int conn_clear_ratio=30;
|
|
||||||
const int conv_clear_min=5;
|
|
||||||
const int conn_clear_min=1;
|
|
||||||
|
|
||||||
const u32_t conv_clear_interval=1000;
|
|
||||||
const u32_t conn_clear_interval=1000;
|
|
||||||
|
|
||||||
|
|
||||||
const i32_t max_fail_time=0;//disable
|
|
||||||
|
|
||||||
const u32_t heartbeat_interval=1000;
|
|
||||||
|
|
||||||
const u32_t timer_interval=400;//this should be smaller than heartbeat_interval and retry interval;
|
|
||||||
|
|
||||||
//const uint32_t conv_timeout=120000; //120 second
|
|
||||||
const u32_t conv_timeout=30000; //for test
|
|
||||||
|
|
||||||
const u32_t client_conn_timeout=10000;
|
|
||||||
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;
|
|
||||||
|
|
||||||
//const uint32_t server_conn_timeout=conv_timeout+60000;//this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
|
|
||||||
const u32_t server_conn_timeout=conv_timeout+10000;//for test
|
|
||||||
|
|
||||||
//const u32_t iptables_rule_keep_interval=4000;
|
|
||||||
|
|
||||||
extern int about_to_exit;
|
|
||||||
extern pthread_t keep_thread;
|
|
||||||
extern int keep_thread_running;
|
|
||||||
|
|
||||||
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
|
|
||||||
extern raw_mode_t raw_mode;
|
|
||||||
enum program_mode_t {unset_mode=0,client_mode,server_mode};
|
|
||||||
extern program_mode_t program_mode;
|
|
||||||
extern unordered_map<int, const char*> raw_mode_tostring ;
|
|
||||||
extern int socket_buf_size;
|
|
||||||
|
|
||||||
typedef u32_t id_t;
|
typedef u32_t id_t;
|
||||||
|
|
||||||
typedef u64_t iv_t;
|
typedef u64_t iv_t;
|
||||||
@@ -116,6 +70,24 @@ typedef u64_t padding_t;
|
|||||||
|
|
||||||
typedef u64_t anti_replay_seq_t;
|
typedef u64_t anti_replay_seq_t;
|
||||||
|
|
||||||
|
|
||||||
|
struct ip_port_t
|
||||||
|
{
|
||||||
|
u32_t ip;
|
||||||
|
int port;
|
||||||
|
void from_u64(u64_t u64);
|
||||||
|
u64_t to_u64();
|
||||||
|
char * to_s();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef u64_t fd64_t;
|
||||||
|
|
||||||
|
const int max_data_len=1600;
|
||||||
|
const int buf_len=max_data_len+400;
|
||||||
|
|
||||||
u64_t get_current_time();
|
u64_t get_current_time();
|
||||||
u64_t pack_u64(u32_t a,u32_t b);
|
u64_t pack_u64(u32_t a,u32_t b);
|
||||||
|
|
||||||
@@ -125,7 +97,6 @@ u32_t get_u64_l(u64_t a);
|
|||||||
|
|
||||||
char * my_ntoa(u32_t ip);
|
char * my_ntoa(u32_t ip);
|
||||||
|
|
||||||
void myexit(int a);
|
|
||||||
void init_random_number_fd();
|
void init_random_number_fd();
|
||||||
u64_t get_true_random_number_64();
|
u64_t get_true_random_number_64();
|
||||||
u32_t get_true_random_number();
|
u32_t get_true_random_number();
|
||||||
@@ -135,35 +106,37 @@ u64_t hton64(u64_t a);
|
|||||||
bool larger_than_u16(uint16_t a,uint16_t b);
|
bool larger_than_u16(uint16_t a,uint16_t b);
|
||||||
bool larger_than_u32(u32_t a,u32_t b);
|
bool larger_than_u32(u32_t a,u32_t b);
|
||||||
void setnonblocking(int sock);
|
void setnonblocking(int sock);
|
||||||
int set_buf_size(int fd);
|
int set_buf_size(int fd,int socket_buf_size,int force_socket_buf);
|
||||||
|
|
||||||
unsigned short csum(const unsigned short *ptr,int nbytes);
|
|
||||||
|
|
||||||
void signal_handler(int sig);
|
|
||||||
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);
|
|
||||||
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3);
|
|
||||||
|
|
||||||
void myexit(int a);
|
void myexit(int a);
|
||||||
|
|
||||||
int add_iptables_rule(const char *);
|
unsigned short csum(const unsigned short *ptr,int nbytes);
|
||||||
|
|
||||||
int clear_iptables_rule();
|
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);
|
||||||
|
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3);
|
||||||
int 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();
|
|
||||||
|
|
||||||
const int show_none=0;
|
const int show_none=0;
|
||||||
const int show_command=0x1;
|
const int show_command=0x1;
|
||||||
const int show_log=0x2;
|
const int show_log=0x2;
|
||||||
const int show_all=show_command|show_log;
|
const int show_all=show_command|show_log;
|
||||||
|
|
||||||
int run_command(string command,char * &output,int flag=show_all);
|
int run_command(string command,char * &output,int flag=show_all);
|
||||||
//int run_command_no_log(string command,char * &output);
|
//int run_command_no_log(string command,char * &output);
|
||||||
int read_file(const char * file,char * &output);
|
int read_file(const char * file,string &output);
|
||||||
|
|
||||||
vector<string> string_to_vec(const char * s,const char * sp);
|
vector<string> string_to_vec(const char * s,const char * sp);
|
||||||
vector< vector <string> > string_to_vec2(const char * s);
|
vector< vector <string> > string_to_vec2(const char * s);
|
||||||
|
|
||||||
|
string trim(const string& str, char c);
|
||||||
|
|
||||||
|
string trim_conf_line(const string& str);
|
||||||
|
|
||||||
|
vector<string> parse_conf_line(const string& s);
|
||||||
|
|
||||||
|
int hex_to_u32_with_endian(const string & a,u32_t &output);
|
||||||
|
int hex_to_u32(const string & a,u32_t &output);
|
||||||
//extern string iptables_pattern;
|
//extern string iptables_pattern;
|
||||||
|
|
||||||
|
int create_fifo(char * file);
|
||||||
|
|
||||||
#endif /* COMMON_H_ */
|
#endif /* COMMON_H_ */
|
||||||
|
777
connection.cpp
Normal file
@@ -0,0 +1,777 @@
|
|||||||
|
/*
|
||||||
|
* connection.cpp
|
||||||
|
*
|
||||||
|
* Created on: Sep 23, 2017
|
||||||
|
* Author: root
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "connection.h"
|
||||||
|
#include "encrypt.h"
|
||||||
|
#include "fd_manager.h"
|
||||||
|
|
||||||
|
|
||||||
|
int disable_anti_replay=0;//if anti_replay windows is diabled
|
||||||
|
|
||||||
|
const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short.
|
||||||
|
|
||||||
|
const int disable_conn_clear=0;//a raw connection is called conn.
|
||||||
|
|
||||||
|
conn_manager_t conn_manager;
|
||||||
|
|
||||||
|
anti_replay_seq_t anti_replay_t::get_new_seq_for_send()
|
||||||
|
{
|
||||||
|
return anti_replay_seq++;
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
max_packet_received=0;
|
||||||
|
//memset(window,0,sizeof(window));
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
memset(window,0,sizeof(window));
|
||||||
|
window[seq%anti_replay_window_size]=1;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
{
|
||||||
|
window[seq%anti_replay_window_size]=1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0; //for complier check
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void server_clear_function(u64_t u64);
|
||||||
|
|
||||||
|
conv_manager_t::conv_manager_t()
|
||||||
|
{
|
||||||
|
clear_it=conv_last_active_time.begin();
|
||||||
|
long long last_clear_time=0;
|
||||||
|
//clear_function=0;
|
||||||
|
}
|
||||||
|
conv_manager_t::~conv_manager_t()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
int conv_manager_t::get_size()
|
||||||
|
{
|
||||||
|
return conv_to_u64.size();
|
||||||
|
}
|
||||||
|
void conv_manager_t::reserve()
|
||||||
|
{
|
||||||
|
u64_to_conv.reserve(10007);
|
||||||
|
conv_to_u64.reserve(10007);
|
||||||
|
conv_last_active_time.reserve(10007);
|
||||||
|
}
|
||||||
|
void conv_manager_t::clear()
|
||||||
|
{
|
||||||
|
if(disable_conv_clear) return ;
|
||||||
|
|
||||||
|
if(program_mode==server_mode)
|
||||||
|
{
|
||||||
|
for(it=conv_to_u64.begin();it!=conv_to_u64.end();it++)
|
||||||
|
{
|
||||||
|
//int fd=int((it->second<<32u)>>32u);
|
||||||
|
server_clear_function( it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u64_to_conv.clear();
|
||||||
|
conv_to_u64.clear();
|
||||||
|
conv_last_active_time.clear();
|
||||||
|
|
||||||
|
clear_it=conv_last_active_time.begin();
|
||||||
|
|
||||||
|
}
|
||||||
|
u32_t conv_manager_t::get_new_conv()
|
||||||
|
{
|
||||||
|
u32_t conv=get_true_random_number_nz();
|
||||||
|
while(conv_to_u64.find(conv)!=conv_to_u64.end())
|
||||||
|
{
|
||||||
|
conv=get_true_random_number_nz();
|
||||||
|
}
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
int conv_manager_t::is_conv_used(u32_t conv)
|
||||||
|
{
|
||||||
|
return conv_to_u64.find(conv)!=conv_to_u64.end();
|
||||||
|
}
|
||||||
|
int conv_manager_t::is_u64_used(u64_t u64)
|
||||||
|
{
|
||||||
|
return u64_to_conv.find(u64)!=u64_to_conv.end();
|
||||||
|
}
|
||||||
|
u32_t conv_manager_t::find_conv_by_u64(u64_t u64)
|
||||||
|
{
|
||||||
|
return u64_to_conv[u64];
|
||||||
|
}
|
||||||
|
u64_t conv_manager_t::find_u64_by_conv(u32_t conv)
|
||||||
|
{
|
||||||
|
return conv_to_u64[conv];
|
||||||
|
}
|
||||||
|
int conv_manager_t::update_active_time(u32_t conv)
|
||||||
|
{
|
||||||
|
return conv_last_active_time[conv]=get_current_time();
|
||||||
|
}
|
||||||
|
int conv_manager_t::insert_conv(u32_t conv,u64_t u64)
|
||||||
|
{
|
||||||
|
u64_to_conv[u64]=conv;
|
||||||
|
conv_to_u64[conv]=u64;
|
||||||
|
conv_last_active_time[conv]=get_current_time();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int conv_manager_t::erase_conv(u32_t conv)
|
||||||
|
{
|
||||||
|
if(disable_conv_clear) return 0;
|
||||||
|
u64_t u64=conv_to_u64[conv];
|
||||||
|
if(program_mode==server_mode)
|
||||||
|
{
|
||||||
|
server_clear_function(u64);
|
||||||
|
}
|
||||||
|
conv_to_u64.erase(conv);
|
||||||
|
u64_to_conv.erase(u64);
|
||||||
|
conv_last_active_time.erase(conv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int conv_manager_t::clear_inactive(char * ip_port)
|
||||||
|
{
|
||||||
|
if(get_current_time()-last_clear_time>conv_clear_interval)
|
||||||
|
{
|
||||||
|
last_clear_time=get_current_time();
|
||||||
|
return clear_inactive0(ip_port);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int conv_manager_t::clear_inactive0(char * ip_port)
|
||||||
|
{
|
||||||
|
if(disable_conv_clear) return 0;
|
||||||
|
|
||||||
|
|
||||||
|
//map<uint32_t,uint64_t>::iterator it;
|
||||||
|
int cnt=0;
|
||||||
|
it=clear_it;
|
||||||
|
int size=conv_last_active_time.size();
|
||||||
|
int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch
|
||||||
|
|
||||||
|
num_to_clean=min(num_to_clean,size);
|
||||||
|
|
||||||
|
u64_t current_time=get_current_time();
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(cnt>=num_to_clean) break;
|
||||||
|
if(conv_last_active_time.begin()==conv_last_active_time.end()) break;
|
||||||
|
|
||||||
|
if(it==conv_last_active_time.end())
|
||||||
|
{
|
||||||
|
it=conv_last_active_time.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( current_time -it->second >conv_timeout )
|
||||||
|
{
|
||||||
|
//mylog(log_info,"inactive conv %u cleared \n",it->first);
|
||||||
|
old_it=it;
|
||||||
|
it++;
|
||||||
|
u32_t conv= old_it->first;
|
||||||
|
erase_conv(old_it->first);
|
||||||
|
if(ip_port==0)
|
||||||
|
{
|
||||||
|
mylog(log_info,"conv %x cleared\n",conv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mylog(log_info,"[%s]conv %x cleared\n",ip_port,conv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
clear_it=it;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void conn_info_t::recover(const conn_info_t &conn_info)
|
||||||
|
{
|
||||||
|
raw_info=conn_info.raw_info;
|
||||||
|
last_state_time=conn_info.last_state_time;
|
||||||
|
last_hb_recv_time=conn_info.last_hb_recv_time;
|
||||||
|
last_hb_sent_time=conn_info.last_hb_sent_time;
|
||||||
|
my_id=conn_info.my_id;
|
||||||
|
oppsite_id=conn_info.oppsite_id;
|
||||||
|
blob->anti_replay.re_init();
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
//send_packet_info.protocol=g_packet_info_send.protocol;
|
||||||
|
if(program_mode==server_mode)
|
||||||
|
state.server_current_state=server_idle;
|
||||||
|
else
|
||||||
|
state.client_current_state=client_idle;
|
||||||
|
last_state_time=0;
|
||||||
|
oppsite_const_id=0;
|
||||||
|
|
||||||
|
timer_fd64=0;
|
||||||
|
|
||||||
|
my_roller=0;
|
||||||
|
oppsite_roller=0;
|
||||||
|
last_oppsite_roller_time=0;
|
||||||
|
}
|
||||||
|
conn_info_t::conn_info_t()
|
||||||
|
{
|
||||||
|
blob=0;
|
||||||
|
re_init();
|
||||||
|
}
|
||||||
|
void conn_info_t::prepare()
|
||||||
|
{
|
||||||
|
blob=new blob_t;
|
||||||
|
|
||||||
|
}
|
||||||
|
conn_info_t::conn_info_t(const conn_info_t&b)
|
||||||
|
{
|
||||||
|
//mylog(log_error,"called!!!!!!!!!!!!!\n");
|
||||||
|
*this=b;
|
||||||
|
if(blob!=0)
|
||||||
|
{
|
||||||
|
blob=new blob_t(*b.blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
assert(blob==0);
|
||||||
|
assert(oppsite_const_id==0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(timer_fd64==0);
|
||||||
|
//if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function
|
||||||
|
//conn_manager.const_id_mp.erase(oppsite_const_id);
|
||||||
|
if(blob!=0)
|
||||||
|
delete blob;
|
||||||
|
|
||||||
|
//send_packet_info.protocol=g_packet_info_send.protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
conn_manager_t::conn_manager_t()
|
||||||
|
{
|
||||||
|
ready_num=0;
|
||||||
|
mp.reserve(10007);
|
||||||
|
clear_it=mp.begin();
|
||||||
|
// timer_fd_mp.reserve(10007);
|
||||||
|
const_id_mp.reserve(10007);
|
||||||
|
// udp_fd_mp.reserve(100007);
|
||||||
|
last_clear_time=0;
|
||||||
|
//current_ready_ip=0;
|
||||||
|
// current_ready_port=0;
|
||||||
|
}
|
||||||
|
int conn_manager_t::exist(u32_t ip,uint16_t port)
|
||||||
|
{
|
||||||
|
u64_t u64=0;
|
||||||
|
u64=ip;
|
||||||
|
u64<<=32u;
|
||||||
|
u64|=port;
|
||||||
|
if(mp.find(u64)!=mp.end())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int insert(uint32_t ip,uint16_t port)
|
||||||
|
{
|
||||||
|
uint64_t u64=0;
|
||||||
|
u64=ip;
|
||||||
|
u64<<=32u;
|
||||||
|
u64|=port;
|
||||||
|
mp[u64];
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
conn_info_t *& conn_manager_t::find_insert_p(u32_t ip,uint16_t port) //be aware,the adress may change after rehash
|
||||||
|
{
|
||||||
|
u64_t u64=0;
|
||||||
|
u64=ip;
|
||||||
|
u64<<=32u;
|
||||||
|
u64|=port;
|
||||||
|
unordered_map<u64_t,conn_info_t*>::iterator it=mp.find(u64);
|
||||||
|
if(it==mp.end())
|
||||||
|
{
|
||||||
|
mp[u64]=new conn_info_t;
|
||||||
|
}
|
||||||
|
return mp[u64];
|
||||||
|
}
|
||||||
|
conn_info_t & conn_manager_t::find_insert(u32_t ip,uint16_t port) //be aware,the adress may change after rehash
|
||||||
|
{
|
||||||
|
u64_t u64=0;
|
||||||
|
u64=ip;
|
||||||
|
u64<<=32u;
|
||||||
|
u64|=port;
|
||||||
|
unordered_map<u64_t,conn_info_t*>::iterator it=mp.find(u64);
|
||||||
|
if(it==mp.end())
|
||||||
|
{
|
||||||
|
mp[u64]=new conn_info_t;
|
||||||
|
}
|
||||||
|
return *mp[u64];
|
||||||
|
}
|
||||||
|
int conn_manager_t::erase(unordered_map<u64_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);
|
||||||
|
|
||||||
|
assert(erase_it->second->timer_fd64 !=0);
|
||||||
|
|
||||||
|
assert(fd_manager.exist(erase_it->second->timer_fd64));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
fd_manager.fd64_close(erase_it->second->timer_fd64);
|
||||||
|
|
||||||
|
erase_it->second->timer_fd64=0;
|
||||||
|
//timer_fd_mp.erase(erase_it->second->timer_fd);
|
||||||
|
//close(erase_it->second->timer_fd);// close will auto delte it from epoll
|
||||||
|
delete(erase_it->second);
|
||||||
|
mp.erase(erase_it->first);
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
last_clear_time=get_current_time();
|
||||||
|
return clear_inactive0();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int conn_manager_t::clear_inactive0()
|
||||||
|
{
|
||||||
|
unordered_map<u64_t,conn_info_t*>::iterator it;
|
||||||
|
unordered_map<u64_t,conn_info_t*>::iterator old_it;
|
||||||
|
|
||||||
|
if(disable_conn_clear) return 0;
|
||||||
|
|
||||||
|
//map<uint32_t,uint64_t>::iterator it;
|
||||||
|
int cnt=0;
|
||||||
|
it=clear_it;
|
||||||
|
int size=mp.size();
|
||||||
|
int num_to_clean=size/conn_clear_ratio+conn_clear_min; //clear 1/10 each time,to avoid latency glitch
|
||||||
|
|
||||||
|
mylog(log_trace,"mp.size() %d\n", size);
|
||||||
|
|
||||||
|
num_to_clean=min(num_to_clean,(int)mp.size());
|
||||||
|
u64_t current_time=get_current_time();
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(cnt>=num_to_clean) break;
|
||||||
|
if(mp.begin()==mp.end()) break;
|
||||||
|
|
||||||
|
if(it==mp.end())
|
||||||
|
{
|
||||||
|
it=mp.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
else if(it->second->blob!=0&&it->second->blob->conv_manager.get_size() >0)
|
||||||
|
{
|
||||||
|
assert(it->second->state.server_current_state==server_ready);
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mylog(log_info,"[%s:%d]inactive conn cleared \n",my_ntoa(it->second->raw_info.recv_info.src_ip),it->second->raw_info.recv_info.src_port);
|
||||||
|
old_it=it;
|
||||||
|
it++;
|
||||||
|
erase(old_it);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
clear_it=it;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
mylog(log_debug,"input_len <0\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
packet_info_t &send_info=raw_info.send_info;
|
||||||
|
packet_info_t &recv_info=raw_info.recv_info;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
memcpy(send_data_buf,&iv,sizeof(iv));
|
||||||
|
memcpy(send_data_buf+sizeof(iv),&padding,sizeof(padding));
|
||||||
|
|
||||||
|
send_data_buf[sizeof(iv)+sizeof(padding)]='b';
|
||||||
|
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,key)!=0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
send_raw0(raw_info,send_data_buf2,new_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int reserved_parse_bare(const char *input,int input_len,char* & data,int & len) // a sub function used in recv_bare
|
||||||
|
{
|
||||||
|
static char recv_data_buf[buf_len];
|
||||||
|
|
||||||
|
if(input_len<0)
|
||||||
|
{
|
||||||
|
mylog(log_debug,"input_len <0\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(my_decrypt(input,recv_data_buf,input_len,key)!=0)
|
||||||
|
{
|
||||||
|
mylog(log_debug,"decrypt_fail in recv bare\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
mylog(log_debug,"len <0\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int recv_bare(raw_info_t &raw_info,char* & data,int & len)//recv 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
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//printf("recv_raw_fail in recv bare\n");
|
||||||
|
return -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;
|
||||||
|
}
|
||||||
|
return reserved_parse_bare(data,len,data,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_handshake(raw_info_t &raw_info,id_t id1,id_t id2,id_t id3)// a warp for send_bare for sending handshake(this is not tcp handshake) easily
|
||||||
|
{
|
||||||
|
packet_info_t &send_info=raw_info.send_info;
|
||||||
|
packet_info_t &recv_info=raw_info.recv_info;
|
||||||
|
|
||||||
|
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;}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int recv_handshake(packet_info_t &info,id_t &id1,id_t &id2,id_t &id3)
|
||||||
|
{
|
||||||
|
char * data;int len;
|
||||||
|
if(recv_bare(info,data,len)!=0) return -1;
|
||||||
|
|
||||||
|
if(char_to_numbers(data,len,id1,id2,id3)!=0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
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')
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
id_t n_tmp_id=htonl(conn_info.my_id);
|
||||||
|
|
||||||
|
memcpy(send_data_buf,&n_tmp_id,sizeof(n_tmp_id));
|
||||||
|
|
||||||
|
n_tmp_id=htonl(conn_info.oppsite_id);
|
||||||
|
|
||||||
|
memcpy(send_data_buf+sizeof(n_tmp_id),&n_tmp_id,sizeof(n_tmp_id));
|
||||||
|
|
||||||
|
anti_replay_seq_t n_seq=hton64(conn_info.blob->anti_replay.get_new_seq_for_send());
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
memcpy(send_data_buf+2+sizeof(n_tmp_id)*2+sizeof(n_seq),data,len);//data;
|
||||||
|
|
||||||
|
int new_len=len+sizeof(n_seq)+sizeof(n_tmp_id)*2+2;
|
||||||
|
|
||||||
|
if(my_encrypt(send_data_buf,send_data_buf2,new_len,key)!=0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int send_data_safer(conn_info_t &conn_info,const char* data,int len,u32_t conv_num)//a wrap for send_safer for transfer data.
|
||||||
|
{
|
||||||
|
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||||
|
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||||
|
|
||||||
|
char send_data_buf[buf_len];
|
||||||
|
//send_data_buf[0]='d';
|
||||||
|
u32_t n_conv_num=htonl(conv_num);
|
||||||
|
memcpy(send_data_buf,&n_conv_num,sizeof(n_conv_num));
|
||||||
|
|
||||||
|
memcpy(send_data_buf+sizeof(n_conv_num),data,len);
|
||||||
|
int new_len=len+sizeof(n_conv_num);
|
||||||
|
send_safer(conn_info,'d',send_data_buf,new_len);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
int 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,key)!=0)
|
||||||
|
{
|
||||||
|
//printf("decrypt fail\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//char *a=recv_data_buf;
|
||||||
|
//id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) );
|
||||||
|
id_t h_oppsite_id;
|
||||||
|
memcpy(&h_oppsite_id,recv_data_buf,sizeof(h_oppsite_id));
|
||||||
|
h_oppsite_id=ntohl(h_oppsite_id);
|
||||||
|
|
||||||
|
//id_t h_my_id= ntohl ( *((id_t * )(recv_data_buf+sizeof(id_t))) );
|
||||||
|
id_t h_my_id;
|
||||||
|
memcpy(&h_my_id,recv_data_buf+sizeof(id_t),sizeof(h_my_id));
|
||||||
|
h_my_id=ntohl(h_my_id);
|
||||||
|
|
||||||
|
//anti_replay_seq_t h_seq= ntoh64 ( *((anti_replay_seq_t * )(recv_data_buf +sizeof(id_t) *2 )) );
|
||||||
|
anti_replay_seq_t h_seq;
|
||||||
|
memcpy(&h_seq,recv_data_buf +sizeof(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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn_info.blob->anti_replay.is_vaild(h_seq) != 1) {
|
||||||
|
mylog(log_debug,"dropped replay packet\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("recv _len %d\n ",recv_len);
|
||||||
|
data=recv_data_buf+sizeof(anti_replay_seq_t)+sizeof(id_t)*2;
|
||||||
|
len=input_len-(sizeof(anti_replay_seq_t)+sizeof(id_t)*2 );
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
mylog(log_debug,"len <0 ,%d\n",len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if(type=='h')
|
||||||
|
conn_info.my_roller++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(0==1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(after_recv_raw0(conn_info.raw_info)!=0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int recv_safer(conn_info_t &conn_info,char &type,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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return parse_safer(conn_info,recv_data,recv_len,type,data,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
//int fd=int(u64);
|
||||||
|
// int ret;
|
||||||
|
//assert(fd!=0);
|
||||||
|
/*
|
||||||
|
epoll_event ev;
|
||||||
|
|
||||||
|
ev.events = EPOLLIN;
|
||||||
|
ev.data.u64 = u64;
|
||||||
|
|
||||||
|
ret = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev);
|
||||||
|
if (ret!=0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"fd:%d epoll delete failed!!!!\n",fd);
|
||||||
|
myexit(-1); //this shouldnt happen
|
||||||
|
}*/ //no need
|
||||||
|
|
||||||
|
/*ret= close(fd); //closed fd should be auto removed from epoll
|
||||||
|
|
||||||
|
if (ret!=0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"close fd %d failed !!!!\n",fd);
|
||||||
|
myexit(-1); //this shouldnt happen
|
||||||
|
}*/
|
||||||
|
//mylog(log_fatal,"size:%d !!!!\n",conn_manager.udp_fd_mp.size());
|
||||||
|
fd64_t fd64=u64;
|
||||||
|
assert(fd_manager.exist(fd64));
|
||||||
|
fd_manager.fd64_close(fd64);
|
||||||
|
|
||||||
|
//assert(conn_manager.udp_fd_mp.find(fd)!=conn_manager.udp_fd_mp.end());
|
||||||
|
//conn_manager.udp_fd_mp.erase(fd);
|
||||||
|
}
|
165
connection.h
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* connection.h
|
||||||
|
*
|
||||||
|
* Created on: Sep 23, 2017
|
||||||
|
* Author: root
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONNECTION_H_
|
||||||
|
#define CONNECTION_H_
|
||||||
|
|
||||||
|
extern int disable_anti_replay;
|
||||||
|
|
||||||
|
#include "connection.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct anti_replay_t //its for anti replay attack,similar to openvpn/ipsec 's anti replay window
|
||||||
|
{
|
||||||
|
u64_t max_packet_received;
|
||||||
|
char window[anti_replay_window_size];
|
||||||
|
anti_replay_seq_t anti_replay_seq;
|
||||||
|
anti_replay_seq_t get_new_seq_for_send();
|
||||||
|
anti_replay_t();
|
||||||
|
void re_init();
|
||||||
|
|
||||||
|
int is_vaild(u64_t seq);
|
||||||
|
};//anti_replay;
|
||||||
|
|
||||||
|
|
||||||
|
struct conv_manager_t // manage the udp connections
|
||||||
|
{
|
||||||
|
//typedef hash_map map;
|
||||||
|
unordered_map<u64_t,u32_t> u64_to_conv; //conv and u64 are both supposed to be uniq
|
||||||
|
unordered_map<u32_t,u64_t> conv_to_u64;
|
||||||
|
|
||||||
|
unordered_map<u32_t,u64_t> conv_last_active_time;
|
||||||
|
|
||||||
|
unordered_map<u32_t,u64_t>::iterator clear_it;
|
||||||
|
|
||||||
|
unordered_map<u32_t,u64_t>::iterator it;
|
||||||
|
unordered_map<u32_t,u64_t>::iterator old_it;
|
||||||
|
|
||||||
|
//void (*clear_function)(uint64_t u64) ;
|
||||||
|
|
||||||
|
long long last_clear_time;
|
||||||
|
|
||||||
|
conv_manager_t();
|
||||||
|
~conv_manager_t();
|
||||||
|
int get_size();
|
||||||
|
void reserve();
|
||||||
|
void clear();
|
||||||
|
u32_t get_new_conv();
|
||||||
|
int is_conv_used(u32_t conv);
|
||||||
|
int is_u64_used(u64_t u64);
|
||||||
|
u32_t find_conv_by_u64(u64_t u64);
|
||||||
|
u64_t find_u64_by_conv(u32_t conv);
|
||||||
|
int update_active_time(u32_t conv);
|
||||||
|
int insert_conv(u32_t conv,u64_t u64);
|
||||||
|
int erase_conv(u32_t conv);
|
||||||
|
int clear_inactive(char * ip_port=0);
|
||||||
|
int clear_inactive0(char * ip_port);
|
||||||
|
};//g_conv_manager;
|
||||||
|
|
||||||
|
struct blob_t //used in conn_info_t. conv_manager_t and anti_replay_t are costly data structures ,we dont allocate them until its necessary
|
||||||
|
{
|
||||||
|
conv_manager_t conv_manager;
|
||||||
|
anti_replay_t anti_replay;
|
||||||
|
};
|
||||||
|
struct conn_info_t //stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can
|
||||||
|
//handle multiple clients
|
||||||
|
{
|
||||||
|
current_state_t state;
|
||||||
|
|
||||||
|
raw_info_t raw_info;
|
||||||
|
u64_t last_state_time;
|
||||||
|
u64_t last_hb_sent_time; //client re-use this for retry
|
||||||
|
u64_t last_hb_recv_time;
|
||||||
|
//long long last_resent_time;
|
||||||
|
|
||||||
|
id_t my_id;
|
||||||
|
id_t oppsite_id;
|
||||||
|
|
||||||
|
|
||||||
|
fd64_t timer_fd64;
|
||||||
|
|
||||||
|
id_t oppsite_const_id;
|
||||||
|
|
||||||
|
blob_t *blob;
|
||||||
|
|
||||||
|
uint8_t my_roller;
|
||||||
|
uint8_t oppsite_roller;
|
||||||
|
u64_t last_oppsite_roller_time;
|
||||||
|
|
||||||
|
// ip_port_t ip_port;
|
||||||
|
|
||||||
|
/*
|
||||||
|
const uint32_t &ip=raw_info.recv_info.src_ip;
|
||||||
|
const uint16_t &port=raw_info.recv_info.src_port;
|
||||||
|
|
||||||
|
*/
|
||||||
|
void recover(const conn_info_t &conn_info);
|
||||||
|
void re_init();
|
||||||
|
conn_info_t();
|
||||||
|
void prepare();
|
||||||
|
conn_info_t(const conn_info_t&b);
|
||||||
|
conn_info_t& operator=(const conn_info_t& b);
|
||||||
|
~conn_info_t();
|
||||||
|
};//g_conn_info;
|
||||||
|
|
||||||
|
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
|
||||||
|
//unordered_map<int,conn_info_t *> timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy
|
||||||
|
|
||||||
|
unordered_map<id_t,conn_info_t *> const_id_mp;
|
||||||
|
|
||||||
|
unordered_map<u64_t,conn_info_t*> mp; //put it at end so that it de-consturcts first
|
||||||
|
|
||||||
|
unordered_map<u64_t,conn_info_t*>::iterator clear_it;
|
||||||
|
|
||||||
|
long long last_clear_time;
|
||||||
|
|
||||||
|
conn_manager_t();
|
||||||
|
int exist(u32_t ip,uint16_t port);
|
||||||
|
/*
|
||||||
|
int insert(uint32_t ip,uint16_t port)
|
||||||
|
{
|
||||||
|
uint64_t u64=0;
|
||||||
|
u64=ip;
|
||||||
|
u64<<=32u;
|
||||||
|
u64|=port;
|
||||||
|
mp[u64];
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
conn_info_t *& find_insert_p(u32_t ip,uint16_t port); //be aware,the adress may change after rehash
|
||||||
|
conn_info_t & find_insert(u32_t ip,uint16_t port) ; //be aware,the adress may change after rehash
|
||||||
|
|
||||||
|
int erase(unordered_map<u64_t,conn_info_t*>::iterator erase_it);
|
||||||
|
int clear_inactive();
|
||||||
|
int clear_inactive0();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern conn_manager_t conn_manager;
|
||||||
|
|
||||||
|
void server_clear_function(u64_t u64);
|
||||||
|
|
||||||
|
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
|
||||||
|
int reserved_parse_bare(const char *input,int input_len,char* & data,int & len); // a sub function used in recv_bare
|
||||||
|
int recv_bare(raw_info_t &raw_info,char* & data,int & len);//recv 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
|
||||||
|
int send_handshake(raw_info_t &raw_info,id_t id1,id_t id2,id_t id3);// a warp for send_bare for sending handshake(this is not tcp handshake) easily
|
||||||
|
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.
|
||||||
|
int send_data_safer(conn_info_t &conn_info,const char* data,int len,u32_t conv_num);//a wrap for send_safer for transfer data.
|
||||||
|
int 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
|
||||||
|
int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len);///safer transfer function with anti-replay,when mutually verification is done.
|
||||||
|
#endif /* CONNECTION_H_ */
|
@@ -1,25 +1,36 @@
|
|||||||
Udp2raw-tunnel
|
# Udp2raw-tunnel
|
||||||

|

|
||||||
udp2raw tunnel,通过raw socket给UDP包加上TCP或ICMP header,进而绕过UDP屏蔽或QoS,或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速。
|
udp2raw tunnel,通过raw socket给UDP包加上TCP或ICMP header,进而绕过UDP屏蔽或QoS,或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速。
|
||||||
|
|
||||||
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
|
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
|
||||||
|
|
||||||
**欢迎任何形式的转载**
|
|
||||||
|
|
||||||
[English](/README.md)
|
[English](/README.md)
|
||||||
|
|
||||||
[udp2raw+kcptun step_by_step教程](kcptun_step_by_step.md)
|
[udp2raw+kcptun step_by_step教程](kcptun_step_by_step.md)
|
||||||
|
|
||||||
[udp2raw+finalspeed step_by_step教程](finalspeed_step_by_step.md)
|
[udp2raw+finalspeed step_by_step教程](finalspeed_step_by_step.md)
|
||||||
|
|
||||||
如果你需要加速跨国网游、网页浏览,解决方案在另一个repo:
|
**提示:**
|
||||||
|
|
||||||
|
udp2raw不是加速器,只是一个帮助你绕过UDP限制的工具。如果你需要UDP加速器,请看UDPspeeder。
|
||||||
|
|
||||||
|
UDPspeeder的repo:
|
||||||
|
|
||||||
https://github.com/wangyu-/UDPspeeder
|
https://github.com/wangyu-/UDPspeeder
|
||||||
# 支持的平台
|
# 支持的平台
|
||||||
Linux主机,有root权限。可以是PC、android手机/平板、openwrt路由器、树莓派。主机上最好安装了iptables命令(apt/yum很容易安装)。
|
Linux主机,有root权限。可以是PC、android手机/平板、openwrt路由器、树莓派。主机上最好安装了iptables命令(apt/yum很容易安装)。
|
||||||
|
|
||||||
在windows和mac上预装了udp2raw的虚拟机镜像已发布,可以用Vmware或VirtualBox加载,容量4.4mb,已经配置好了自动获取网卡ip,开机即用,稳定,性能很好。
|
Release中提供了`amd64`、`x86`、`arm`、`mips_be`、`mips_le`的预编译binary.
|
||||||
(udp2raw跑在虚拟机里,其他应用照常跑在windows上)(确保虚拟机网卡工作在桥接模式)(Vmware player 75mb,VirtualBox 118mb,很容易安装)。
|
|
||||||
|
##### 对于windows和mac用户:
|
||||||
|
|
||||||
|
在虚拟机中可以稳定使用(udp2raw跑在Linux里,其他应用照常跑在window里;确保虚拟机网卡工作在桥接模式)。可以使用[这个](https://github.com/wangyu-/udp2raw-tunnel/releases/download/20171108.0/lede-17.01.2-x86_virtual_machine_image.zip)虚拟机镜像,大小只有7.5mb,免去在虚拟机里装系统的麻烦;虚拟机自带ssh server,可以scp拷贝文件,可以ssh进去,可以复制粘贴,root密码123456。
|
||||||
|
|
||||||
|
如果你的网络不允许桥接,也是有办法用的,具体方法请看wiki。
|
||||||
|
|
||||||
|
##### 对于ios和游戏主机用户:
|
||||||
|
|
||||||
|
可以把udp2raw运行在局域网的其他机器上。最好的办法是买个能刷OpenWrt/LEDE/梅林的路由器,把udp2raw运行在路由器上。
|
||||||
|
|
||||||
# 功能特性
|
# 功能特性
|
||||||
### 把udp流量伪装成tcp /icmp
|
### 把udp流量伪装成tcp /icmp
|
||||||
@@ -49,9 +60,9 @@ NAT 穿透 ,tcp icmp udp模式都支持nat穿透。
|
|||||||
|
|
||||||
支持Openvz,配合finalspeed使用,可以在openvz上用tcp模式的finalspeed
|
支持Openvz,配合finalspeed使用,可以在openvz上用tcp模式的finalspeed
|
||||||
|
|
||||||
支持Openwrt,没有编译依赖,容易编译到任何平台上。release中提供了ar71xx版本的binary
|
支持Openwrt,没有编译依赖,容易编译到任何平台上。
|
||||||
|
|
||||||
epoll纯异步,高并发,除了回收过期连接外,所有操作的时间复杂度都跟连接数无关。回收过期连接的操做也是柔和进行的,不会因为消耗太多cpu时间造成延迟抖动。
|
epoll实现,高并发,除了回收过期连接外,所有操作的时间复杂度都跟连接数无关。回收过期连接的操做也是柔和进行的,不会因为消耗太多cpu时间造成延迟抖动。
|
||||||
|
|
||||||
### 关键词
|
### 关键词
|
||||||
突破udp qos,突破udp屏蔽,openvpn tcp over tcp problem,openvpn over icmp,udp to icmp tunnel,udp to tcp tunnel,udp via icmp,udp via tcp
|
突破udp qos,突破udp屏蔽,openvpn tcp over tcp problem,openvpn over icmp,udp to icmp tunnel,udp to tcp tunnel,udp via icmp,udp via tcp
|
||||||
@@ -80,15 +91,25 @@ https://github.com/wangyu-/udp2raw-tunnel/releases
|
|||||||
|
|
||||||
现在client和server之间建立起了,tunnel。想要在本地连接44.55.66.77:7777,只需要连接 127.0.0.1:3333。来回的所有的udp流量会被经过tunneling发送。在外界看起来是tcp流量,不会有udp流量暴露到公网。
|
现在client和server之间建立起了,tunnel。想要在本地连接44.55.66.77:7777,只需要连接 127.0.0.1:3333。来回的所有的udp流量会被经过tunneling发送。在外界看起来是tcp流量,不会有udp流量暴露到公网。
|
||||||
|
|
||||||
|
### MTU设置(重要)
|
||||||
|
|
||||||
|
不论你用udp2raw来加速kcptun还是vpn,为了稳定使用,都需要设置合理的MTU(在kcptun/vpn里设置,而不是在udp2raw里),建议把MTU设置成1200。client和server端都要设置。
|
||||||
|
|
||||||
### 提醒
|
### 提醒
|
||||||
如果要在anroid上运行,请看[Android简明教程](/doc/android_guide.md)
|
如果要在anroid上运行,请看[Android简明教程](/doc/android_guide.md)
|
||||||
|
|
||||||
|
如果要在梅林固件的路由器上使用,添加`--lower-level auto` `--keep-rule`
|
||||||
|
|
||||||
|
如果client和server无法连接,或者连接经常断开,请看一下`--seq-mode`的用法,尝试不同的seq-mode。
|
||||||
|
|
||||||
|
udp2raw可以用非root账号运行,这样更安全。具体方法见:[#26](https://github.com/wangyu-/udp2raw-tunnel/issues/26)
|
||||||
|
|
||||||
# 进阶操作说明
|
# 进阶操作说明
|
||||||
|
|
||||||
### 命令选项
|
### 命令选项
|
||||||
```
|
```
|
||||||
udp2raw-tunnel
|
udp2raw-tunnel
|
||||||
version: Aug 18 2017 00:29:11
|
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
|
||||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
@@ -101,13 +122,18 @@ common options,these options must be same on both side:
|
|||||||
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
||||||
--auth-mode <string> avaliable values:md5(default),crc32,simple,none
|
--auth-mode <string> avaliable values:md5(default),crc32,simple,none
|
||||||
-a,--auto-rule auto add (and delete) iptables rule
|
-a,--auto-rule auto add (and delete) iptables rule
|
||||||
-g,--gen-rule generate iptables rule then exit
|
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
||||||
|
add it manually.overrides -a
|
||||||
--disable-anti-replay disable anti-replay,not suggested
|
--disable-anti-replay disable anti-replay,not suggested
|
||||||
client options:
|
client options:
|
||||||
--source-ip <ip> force source-ip for raw socket
|
--source-ip <ip> force source-ip for raw socket
|
||||||
--source-port <port> force source-port for raw socket,tcp/udp only
|
--source-port <port> force source-port for raw socket,tcp/udp only
|
||||||
this option disables port changing while re-connecting
|
this option disables port changing while re-connecting
|
||||||
other options:
|
other options:
|
||||||
|
--conf-file <string> read options from a configuration file instead of command line.
|
||||||
|
check example.conf in repo for format
|
||||||
|
--fifo <string> use a fifo(named pipe) for sending commands to the running program,
|
||||||
|
check readme.md in repository for supported commands.
|
||||||
--log-level <number> 0:never 1:fatal 2:error 3:warn
|
--log-level <number> 0:never 1:fatal 2:error 3:warn
|
||||||
4:info (default) 5:debug 6:trace
|
4:info (default) 5:debug 6:trace
|
||||||
--log-position enable file name,function name,line number in log
|
--log-position enable file name,function name,line number in log
|
||||||
@@ -115,44 +141,97 @@ other options:
|
|||||||
--disable-bpf disable the kernel space filter,most time its not necessary
|
--disable-bpf disable the kernel space filter,most time its not necessary
|
||||||
unless you suspect there is a bug
|
unless you suspect there is a bug
|
||||||
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
||||||
--seqmode <number> seq increase mode for faketcp:
|
--force-sock-buf bypass system limitation while setting sock-buf
|
||||||
0:dont increase
|
--seq-mode <number> seq increase mode for faketcp:
|
||||||
1:increase every packet
|
0:static header,do not increase seq and ack_seq
|
||||||
2:increase randomly, about every 3 packets (default)
|
1:increase seq for every packet,simply ack last seq
|
||||||
--lower-level <string> send packet at OSI level 2, format:'if_name#dest_mac_adress'
|
2:increase seq randomly, about every 3 packets,simply ack last seq
|
||||||
ie:'eth0#00:23:45:67:89:b9'.Beta.
|
3:simulate an almost real seq/ack procedure(default)
|
||||||
|
4:similiar to 3,but do not consider TCP Option Window_Scale,
|
||||||
|
maybe useful when firewall doesnt support TCP Option
|
||||||
|
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
|
||||||
|
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
|
||||||
|
the parameter automatically,specify it manually if 'auto' failed
|
||||||
|
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
|
||||||
|
--keep-rule monitor iptables and auto re-add if necessary.implys -a
|
||||||
|
--clear clear any iptables rules added by this program.overrides everything
|
||||||
-h,--help print this help message
|
-h,--help print this help message
|
||||||
|
|
||||||
```
|
```
|
||||||
### iptables 规则
|
|
||||||
|
### iptables 规则,`-a`和`-g`
|
||||||
用raw收发tcp包本质上绕过了linux内核的tcp协议栈。linux碰到raw socket发来的包会不认识,如果一直收到不认识的包,会回复大量RST,造成不稳定或性能问题。所以强烈建议添加iptables规则屏蔽Linux内核的对指定端口的处理。用-a选项,udp2raw会在启动的时候自动帮你加上Iptables规则,退出的时候再自动删掉。如果长期使用,可以用-g选项来生成相应的Iptables规则再自己手动添加,这样规则不会在udp2raw退出时被删掉,可以避免停掉udp2raw后内核向对端回复RST。
|
用raw收发tcp包本质上绕过了linux内核的tcp协议栈。linux碰到raw socket发来的包会不认识,如果一直收到不认识的包,会回复大量RST,造成不稳定或性能问题。所以强烈建议添加iptables规则屏蔽Linux内核的对指定端口的处理。用-a选项,udp2raw会在启动的时候自动帮你加上Iptables规则,退出的时候再自动删掉。如果长期使用,可以用-g选项来生成相应的Iptables规则再自己手动添加,这样规则不会在udp2raw退出时被删掉,可以避免停掉udp2raw后内核向对端回复RST。
|
||||||
|
|
||||||
用raw收发udp包也类似,只是内核回复的是icmp unreachable。而用raw 收发icmp,内核会自动回复icmp echo。都需要相应的iptables规则。
|
用raw收发udp包也类似,只是内核回复的是icmp unreachable。而用raw 收发icmp,内核会自动回复icmp echo。都需要相应的iptables规则。
|
||||||
### cipher-mode 和 auth-mode
|
### `--cipher-mode` 和 `--auth-mode`
|
||||||
如果要最大的安全性建议用aes128cbc+md5。如果要运行再路由器上,建议xor+simple。但是注意xor+simple只能骗过防火墙的包检测,不能防止真正的攻击者。
|
如果要最大的安全性建议用aes128cbc+md5。如果要运行再路由器上,建议xor+simple。但是注意xor+simple只能骗过防火墙的包检测,不能防止真正的攻击者。
|
||||||
|
|
||||||
### seq-mode
|
### `--seq-mode`
|
||||||
facktcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和真正的tcp流量区分开来(虽然大部分ISP不太可能做这种程度的包检测)。seq-mode可以改变一些seq ack的行为。如果遇到了连接问题,可以尝试更改。在我这边的移动线路用3种模式都没问题。
|
facktcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和真正的tcp流量区分开来(虽然大部分ISP不太可能做这种程度的包检测)。seq-mode可以改变一些seq ack的行为。如果遇到了连接问题,可以尝试更改。在我这边的移动线路用3种模式都没问题。
|
||||||
|
|
||||||
### lower-level
|
### `--keep-rule`
|
||||||
|
定期主动检查iptables,如果udp2raw添加的iptables规则丢了,就重新添加。在一些iptables可能会被其他程序清空的情况下(比如梅林固件和openwrt的路由器)格外有用。
|
||||||
|
|
||||||
|
### `--fifo`
|
||||||
|
指定一个fifo(named pipe)来向运行中的程序发送命令,例如`--fifo fifo.file`:
|
||||||
|
|
||||||
|
在client端,可以用`echo reconnect >fifo.file`来强制client换端口重连(上层不断线).对Server,目前没有效果。
|
||||||
|
|
||||||
|
### `--lower-level`
|
||||||
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效(比如你用的是梅林固件,iptables全是固件自己生成的)。
|
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效(比如你用的是梅林固件,iptables全是固件自己生成的)。
|
||||||
|
|
||||||
##### 格式
|
##### 格式
|
||||||
`if_name#dest_mac_adress`,例如 `eth0#00:23:45:67:89:b9` 。`eth0`换成你的出口网卡名。`00:23:45:67:89:b9`换成网关的mac地址(如果client和server在同一个局域网内,可能不需要网关,这时候直接用对方主机的mac地址,这个属于罕见的应用场景,可以忽略)。
|
`if_name#dest_mac_adress`,例如 `eth0#00:23:45:67:89:b9` 。`eth0`换成你的出口网卡名。`00:23:45:67:89:b9`换成网关的mac地址(如果client和server在同一个局域网内,可能不需要网关,这时候直接用对方主机的mac地址,这个属于罕见的应用场景,可以忽略)。
|
||||||
|
|
||||||
|
可以用`--lower-level auto`自动获取参数,如果获取参数失败,再手动填写。
|
||||||
|
|
||||||
##### client端获得--lower-level参数的办法
|
##### client端获得--lower-level参数的办法
|
||||||
在client 端,运行`traceroute <server_ip>`,记下第一跳的地址,这个就是`网关ip`。再运行`arp -s <网关ip>`,可以同时查到出口网卡名和mac。
|
在client 端,运行`traceroute <server_ip>`,记下第一跳的地址,这个就是`网关ip`。再运行`arp -s <网关ip>`,可以同时查到出口网卡名和mac。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
如果traceroute第一跳结果是`* * *`,说明网关屏蔽了对traceroute的应答。需要用`ip route`或`route`查询网关:
|
||||||
|
|
||||||
|

|
||||||
##### server端获得--lower-level参数的办法
|
##### server端获得--lower-level参数的办法
|
||||||
如果client有公网ip,就`traceroute <client_ip>`。下一步和client端的方法一样。
|
如果client有公网ip,就`traceroute <client_ip>`。下一步和client端的方法一样。
|
||||||
|
|
||||||
如果client没有公网ip,就`traceroute google.com` 或`traceroute baidu.com`。下一步和client端的方法一样。
|
如果client没有公网ip,就`traceroute google.com` 或`traceroute baidu.com`。下一步和client端的方法一样。
|
||||||
|
|
||||||
|
server端也可以用`--lower-level auto` 来尝试自动获得参数,如果无法连接再手动填写。
|
||||||
|
|
||||||
##### 注意
|
##### 注意
|
||||||
如果用了`--lower-level`选项。server虽然还可以bind在0.0.0.0,但是因为你显式指定了网络接口,就只能工作在这一个网络接口了。
|
如果用了`--lower-level`选项。server虽然还可以bind在0.0.0.0,但是因为你显式指定了网络接口,就只能工作在这一个网络接口了。
|
||||||
|
|
||||||
如果`arps -s`命令查询不到,首先再试几次。如果还是查询不到,那么可能是因为你用的是pppoe方式的拨号宽带,查询不到是正常的。这种情况下`if_name`填pppoe产生的虚拟interface,通常名字叫`pppXXXX`,从`ifconfig`命令的输出里找一下;`des_mac_adress`填`00:00:00:00:00:00`,例如`ppp0#00:00:00:00:00:00`
|
如果`arps -s`命令查询不到,首先再试几次。如果还是查询不到,那么可能是因为你用的是pppoe方式的拨号宽带,查询不到是正常的。这种情况下`if_name`填pppoe产生的虚拟interface,通常名字叫`pppXXXX`,从`ifconfig`命令的输出里找一下;`des_mac_adress`填`00:00:00:00:00:00`,例如`ppp0#00:00:00:00:00:00`
|
||||||
|
|
||||||
|
### `--conf-file`
|
||||||
|
|
||||||
|
为了避免将密码等私密信息暴露给`ps`命令,你也可以使用 `配置文件` 来存储参数。
|
||||||
|
|
||||||
|
比如,将以上服务端参数改写成配置文件
|
||||||
|
|
||||||
|
`server.conf`:
|
||||||
|
|
||||||
|
```
|
||||||
|
-s
|
||||||
|
# 你可以像这样添加注释
|
||||||
|
# 注意,只有整行注释才能在配置文件里使用
|
||||||
|
# 注释必须独占一行
|
||||||
|
-l 0.0.0.0:4096
|
||||||
|
-r 127.0.0.1:7777
|
||||||
|
-a
|
||||||
|
-k passwd
|
||||||
|
--raw-mode faketcp
|
||||||
|
```
|
||||||
|
|
||||||
|
注意,当写入配置文件的时候,密码等参数两边的引号必须去除。
|
||||||
|
|
||||||
|
然后就可以使用下面的方式启动服务端
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./udp2raw_amd64 --conf-file server.conf
|
||||||
|
```
|
||||||
|
|
||||||
# 性能测试
|
# 性能测试
|
||||||
iperf3 的UDP模式有BUG,所以,这里用iperf3的tcp模式,配合Openvpn,测试udp2raw的性能。(iperf3 udp issue ,https://github.com/esnet/iperf/issues/296 )
|
iperf3 的UDP模式有BUG,所以,这里用iperf3的tcp模式,配合Openvpn,测试udp2raw的性能。(iperf3 udp issue ,https://github.com/esnet/iperf/issues/296 )
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# How to run udp2raw on a rooted android device(arm cpu)
|
# How to run udp2raw on a rooted android device(arm cpu)
|
||||||
|
|
||||||
There is currently no GUI for udp2raw on android.Make sure you have installed Terminal to run it.
|
There is currently no GUI for udp2raw on android.Make sure you have installed Terminal to run it.Your device has to be rooted,otherwise you cant use raw socket.
|
||||||
|
|
||||||
Download udp2raw_arm from https://github.com/wangyu-/udp2raw-tunnel/releases.
|
Download udp2raw_arm from https://github.com/wangyu-/udp2raw-tunnel/releases.
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
##### 摘要
|
##### 摘要
|
||||||
udp2raw是一个把udp流量通过raw socket包装成tcp流量的工具。通过用udp2raw配合udp模式的 finalspeed一样可以达到在底层发tcp包,绕过QOS的效果。支持openvz,稳定性也好很多。原理上相当于在finalspeed外面再包了一层tunnel。
|
udp2raw是一个把udp流量通过raw socket包装成tcp流量的工具。通过用udp2raw配合udp模式的 finalspeed一样可以达到在底层发tcp包,绕过QOS的效果。支持openvz,稳定性也好很多。原理上相当于在finalspeed外面再包了一层tunnel。
|
||||||
|
|
||||||
本教程会一步一步演示用udp2raw+finalspeed加速http流量的过程。加速任何其他tcp流量也一样,包括ss。本文避免讨论科学上网,所以只演示加速http流量。
|
本教程会一步一步演示用udp2raw+finalspeed加速http流量的过程。加速任何其他tcp流量也一样,包括$\*\*\*。本文避免讨论科学上网,所以只演示加速http流量。
|
||||||
|
|
||||||
udp2raw也支持把udp流量包装成Icmp发送,本教程不做演示。
|
udp2raw也支持把udp流量包装成Icmp发送,本教程不做演示。
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# udp2raw+kcptun 加速tcp流量 Step by Step 教程
|
# udp2raw+kcptun 加速tcp流量 Step by Step 教程
|
||||||

|

|
||||||
|
|
||||||
本教程会一步一步演示用udp2raw+kcptun加速SSH流量的过程。加速任何其他tcp流量也一样,包括ss;本文避免涉及科学上网,所以演示ssh。
|
本教程会一步一步演示用udp2raw+kcptun加速SSH流量的过程。加速任何其他tcp流量也一样,包括$\*\*\*;本文避免涉及科学上网,所以演示ssh。
|
||||||
|
|
||||||
### 环境要求
|
### 环境要求
|
||||||
两边的主机都是linux,有root权限。 可以是openwrt路由器或树莓派,也可以是root了的android。
|
两边的主机都是linux,有root权限。 可以是openwrt路由器或树莓派,也可以是root了的android。
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# udp2raw command
|
# udp2raw command
|
||||||
#### run at server side
|
#### run at server side
|
||||||
```
|
```
|
||||||
@@ -10,9 +11,11 @@
|
|||||||
#### run at client side
|
#### run at client side
|
||||||
assume server ip is 45.66.77.88
|
assume server ip is 45.66.77.88
|
||||||
```
|
```
|
||||||
./udp2raw_amd64 -s -l0.0.0.0:3333 -r 45.66.77.88:8855 -k "passwd" --raw-mode faketcp -a
|
./udp2raw_amd64 -c -l0.0.0.0:3333 -r 45.66.77.88:8855 -k "passwd" --raw-mode faketcp -a
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### hint
|
||||||
|
You can add `--cipher-mode xor` `--auth-mode simple` to **both** sides to obtain maximum performance(but poor security).
|
||||||
|
|
||||||
# openvpn config
|
# openvpn config
|
||||||
|
|
||||||
|
34
encrypt.cpp
@@ -12,10 +12,26 @@
|
|||||||
|
|
||||||
static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data
|
static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data
|
||||||
/****
|
/****
|
||||||
* important!
|
* security of zero_iv + nonce first data block
|
||||||
* why zero iv + nonce first data block is secure?
|
|
||||||
* https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block
|
* https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block
|
||||||
****/
|
****/
|
||||||
|
|
||||||
|
char key[16];//generated from key_string by md5.
|
||||||
|
/*
|
||||||
|
TODO
|
||||||
|
|
||||||
|
Change md5 to HMAC-md5 if necessary.Change padding to PKCS#7 style if necessary.
|
||||||
|
|
||||||
|
Need someone with cryptography knowledge to help review the encryption method.
|
||||||
|
|
||||||
|
Change them if necessary(I can do this by myself,if it turns out to be necessary).
|
||||||
|
|
||||||
|
github issue:
|
||||||
|
|
||||||
|
https://github.com/wangyu-/udp2raw-tunnel/issues/17
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
unordered_map<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}};
|
unordered_map<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}};
|
||||||
unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}};
|
unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}};
|
||||||
|
|
||||||
@@ -192,6 +208,13 @@ int de_padding(const char *data ,int &data_len,int padding_num)
|
|||||||
}
|
}
|
||||||
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;
|
||||||
|
if(aes_key_optimize)
|
||||||
|
{
|
||||||
|
if(first_time==0) key=0;
|
||||||
|
else first_time=0;
|
||||||
|
}
|
||||||
|
|
||||||
char buf[buf_len];
|
char buf[buf_len];
|
||||||
memcpy(buf,data,len);//TODO inefficient code
|
memcpy(buf,data,len);//TODO inefficient code
|
||||||
|
|
||||||
@@ -237,7 +260,12 @@ int cipher_none_encrypt(const char *data,char *output,int &len,char * key)
|
|||||||
}
|
}
|
||||||
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(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(len%16 !=0) {mylog(log_debug,"len%%16!=0\n");return -1;}
|
||||||
//if(len<0) {mylog(log_debug,"len <0\n");return -1;}
|
//if(len<0) {mylog(log_debug,"len <0\n");return -1;}
|
||||||
AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
||||||
|
14
encrypt.h
@@ -1,5 +1,5 @@
|
|||||||
#ifndef _ENCRYPTION_H_
|
#ifndef UDP2RAW_ENCRYPTION_H_
|
||||||
#define _ENCRYPTION_H_
|
#define UDP2RAW_ENCRYPTION_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
//using namespace std;
|
//using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
const int aes_key_optimize=1; //if enabled,once you used a key for aes,you cant change it anymore
|
||||||
|
extern char key[16];
|
||||||
|
|
||||||
int my_encrypt(const char *data,char *output,int &len,char * key);
|
int my_encrypt(const char *data,char *output,int &len,char * key);
|
||||||
int my_decrypt(const char *data,char *output,int &len,char * key);
|
int my_decrypt(const char *data,char *output,int &len,char * key);
|
||||||
|
|
||||||
@@ -32,4 +36,10 @@ extern cipher_mode_t cipher_mode;
|
|||||||
extern unordered_map<int, const char *> auth_mode_tostring;
|
extern unordered_map<int, const char *> auth_mode_tostring;
|
||||||
extern unordered_map<int, const char *> cipher_mode_tostring;
|
extern unordered_map<int, const char *> cipher_mode_tostring;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int cipher_decrypt(const char *data,char *output,int &len,char * key);//internal interface ,exposed for test only
|
||||||
|
int cipher_encrypt(const char *data,char *output,int &len,char * key);//internal interface ,exposed for test only
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
16
example.conf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Basically this file is the equivalent to splitting the command line options into multiple lines
|
||||||
|
# Each line should contain an option
|
||||||
|
|
||||||
|
# This is client
|
||||||
|
-c
|
||||||
|
# Or use -s if you use it on server side
|
||||||
|
# Define local address
|
||||||
|
-l 127.0.0.1:56789
|
||||||
|
# Define remote address
|
||||||
|
-r 45.66.77.88:45678
|
||||||
|
# Password
|
||||||
|
-k my_awesome_password
|
||||||
|
# Mode
|
||||||
|
--raw-mode faketcp
|
||||||
|
# Log Level
|
||||||
|
--log-level 4
|
63
fd_manager.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* fd_manager.cpp
|
||||||
|
*
|
||||||
|
* Created on: Sep 25, 2017
|
||||||
|
* Author: root
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "fd_manager.h"
|
||||||
|
int fd_manager_t::fd_exist(int fd)
|
||||||
|
{
|
||||||
|
return fd_to_fd64_mp.find(fd)!=fd_to_fd64_mp.end();
|
||||||
|
}
|
||||||
|
int fd_manager_t::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)
|
||||||
|
{
|
||||||
|
assert(exist(fd64));
|
||||||
|
return fd64_to_fd_mp[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))
|
||||||
|
{
|
||||||
|
fd_info_mp.erase(fd64);
|
||||||
|
}
|
||||||
|
assert(close(fd)==0);
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
counter=u32_t(-1);
|
||||||
|
counter+=100;
|
||||||
|
reserve(10007);
|
||||||
|
}
|
||||||
|
fd_info_t & fd_manager_t::get_info(fd64_t fd64)
|
||||||
|
{
|
||||||
|
assert(exist(fd64));
|
||||||
|
return fd_info_mp[fd64];
|
||||||
|
}
|
||||||
|
int fd_manager_t::exist_info(fd64_t fd64)
|
||||||
|
{
|
||||||
|
return fd_info_mp.find(fd64)!=fd_info_mp.end();
|
||||||
|
}
|
43
fd_manager.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* fd_manager.h
|
||||||
|
*
|
||||||
|
* Created on: Sep 25, 2017
|
||||||
|
* Author: root
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FD_MANAGER_H_
|
||||||
|
#define FD_MANAGER_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
//#include "packet.h"
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
struct fd_info_t
|
||||||
|
{
|
||||||
|
//ip_port_t ip_port;
|
||||||
|
conn_info_t *p_conn_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create
|
||||||
|
//this class is not strictly necessary,it just makes epoll fd handling easier
|
||||||
|
{
|
||||||
|
fd_info_t & get_info(fd64_t fd64);
|
||||||
|
int exist_info(fd64_t);
|
||||||
|
int exist(fd64_t fd64);
|
||||||
|
int to_fd(fd64_t);
|
||||||
|
void fd64_close(fd64_t fd64);
|
||||||
|
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;
|
||||||
|
unordered_map<fd64_t,int> fd64_to_fd_mp;
|
||||||
|
unordered_map<fd64_t,fd_info_t> fd_info_mp;
|
||||||
|
int fd_exist(int fd);
|
||||||
|
//void remove_fd(int fd);
|
||||||
|
//fd64_t fd_to_fd64(int fd);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern fd_manager_t fd_manager;
|
||||||
|
#endif /* FD_MANAGER_H_ */
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 26 KiB |
BIN
images/route.PNG
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
images/udp2rawopenvpn.PNG
Normal file
After Width: | Height: | Size: 58 KiB |
1
images/wiki/111
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
BIN
images/wiki/mac_nat_vb1.PNG
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
images/wiki/mac_nat_vb2.PNG
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
images/wiki/mac_nat_vb3.PNG
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
images/wiki/mac_nat_vb4.PNG
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
images/wiki/windows_nat.PNG
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
images/wiki/windows_nat_vb1.PNG
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
images/wiki/windows_nat_vb2.PNG
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
images/wiki/windows_nat_vm1.PNG
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
images/wiki/windows_nat_vm2.PNG
Normal file
After Width: | Height: | Size: 29 KiB |
@@ -2,8 +2,8 @@
|
|||||||
* this file comes from https://github.com/kokke/tiny-AES128-C
|
* this file comes from https://github.com/kokke/tiny-AES128-C
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _AES_H_
|
#ifndef UDP2RAW_AES_H_
|
||||||
#define _AES_H_
|
#define UDP2RAW_AES_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@@ -340,30 +340,34 @@ int AES_support_hwaccel(void)
|
|||||||
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||||
{
|
{
|
||||||
uint8_t iv_tmp[16];
|
uint8_t iv_tmp[16];
|
||||||
uint8_t rk[AES_RKSIZE];
|
static uint8_t rk[AES_RKSIZE];
|
||||||
|
|
||||||
if (key == NULL || iv == NULL)
|
if (iv == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
aeshw_init();
|
aeshw_init();
|
||||||
memcpy(iv_tmp, iv, 16);
|
memcpy(iv_tmp, iv, 16);
|
||||||
setkey_enc(rk, key);
|
if(key!= NULL)
|
||||||
|
setkey_enc(rk, key);
|
||||||
encrypt_cbc(rk, length, iv_tmp, input, output);
|
encrypt_cbc(rk, length, iv_tmp, input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||||
{
|
{
|
||||||
uint8_t iv_tmp[16];
|
uint8_t iv_tmp[16];
|
||||||
uint8_t rk[AES_RKSIZE];
|
static uint8_t rk[AES_RKSIZE];
|
||||||
|
|
||||||
if (key == NULL || iv == NULL)
|
if (iv == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
aeshw_init();
|
aeshw_init();
|
||||||
memcpy(iv_tmp, iv, 16);
|
memcpy(iv_tmp, iv, 16);
|
||||||
setkey_dec(rk, key);
|
if(key!= NULL)
|
||||||
|
{
|
||||||
|
setkey_dec(rk, key);
|
||||||
|
}
|
||||||
decrypt_cbc(rk, length, iv_tmp, input, output);
|
decrypt_cbc(rk, length, iv_tmp, input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _AESARM_H_
|
#ifndef UDP2RAW_AESARM_H_
|
||||||
#define _AESARM_H_
|
#define UDP2RAW_AESARM_H_
|
||||||
|
|
||||||
#ifndef AES_ENCRYPT
|
#ifndef AES_ENCRYPT
|
||||||
#define AES_ENCRYPT 1
|
#define AES_ENCRYPT 1
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _AESNI_H_
|
#ifndef UDP2RAW_AESNI_H_
|
||||||
#define _AESNI_H_
|
#define UDP2RAW_AESNI_H_
|
||||||
|
|
||||||
#ifndef AES_ENCRYPT
|
#ifndef AES_ENCRYPT
|
||||||
#define AES_ENCRYPT 1
|
#define AES_ENCRYPT 1
|
||||||
|
4
lib/aes_acc/asm/arm_arch.h
vendored
@@ -7,8 +7,8 @@
|
|||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ARM_ARCH_H__
|
#ifndef UDP2RAW_ARM_ARCH_H_
|
||||||
# define __ARM_ARCH_H__
|
# define UDP2RAW_ARM_ARCH_H_
|
||||||
|
|
||||||
# if !defined(__ARM_ARCH__)
|
# if !defined(__ARM_ARCH__)
|
||||||
# if defined(__CC_ARM)
|
# if defined(__CC_ARM)
|
||||||
|
1459
lib/aes_faster_c/aes.c
Normal file
267
lib/aes_faster_c/aes.h
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/**
|
||||||
|
* \file aes.h
|
||||||
|
*
|
||||||
|
* \brief AES block cipher
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2014, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_AES_H
|
||||||
|
#define POLARSSL_AES_H
|
||||||
|
/*
|
||||||
|
#if !defined(POLARSSL_CONFIG_FILE)
|
||||||
|
#include "config.h"
|
||||||
|
#else
|
||||||
|
#include POLARSSL_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
////////modification begin
|
||||||
|
#define POLARSSL_AES_ROM_TABLES
|
||||||
|
#define POLARSSL_CIPHER_MODE_CBC
|
||||||
|
//#define POLARSSL_SELF_TEST
|
||||||
|
#define polarssl_printf printf
|
||||||
|
///////add end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
|
||||||
|
#include <basetsd.h>
|
||||||
|
typedef UINT32 uint32_t;
|
||||||
|
#else
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* padlock.c and aesni.c rely on these values! */
|
||||||
|
#define AES_ENCRYPT 1
|
||||||
|
#define AES_DECRYPT 0
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||||
|
|
||||||
|
#if !defined(POLARSSL_AES_ALT)
|
||||||
|
// Regular implementation
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES context structure
|
||||||
|
*
|
||||||
|
* \note buf is able to hold 32 extra bytes, which can be used:
|
||||||
|
* - for alignment purposes if VIA padlock is used, and/or
|
||||||
|
* - to simplify key expansion in the 256-bit case by
|
||||||
|
* generating an extra round key
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int nr; /*!< number of rounds */
|
||||||
|
uint32_t *rk; /*!< AES round keys */
|
||||||
|
uint32_t buf[68]; /*!< unaligned data */
|
||||||
|
}
|
||||||
|
aes_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize AES context
|
||||||
|
*
|
||||||
|
* \param ctx AES context to be initialized
|
||||||
|
*/
|
||||||
|
void aes_init( aes_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clear AES context
|
||||||
|
*
|
||||||
|
* \param ctx AES context to be cleared
|
||||||
|
*/
|
||||||
|
void aes_free( aes_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES key schedule (encryption)
|
||||||
|
*
|
||||||
|
* \param ctx AES context to be initialized
|
||||||
|
* \param key encryption key
|
||||||
|
* \param keysize must be 128, 192 or 256
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
*/
|
||||||
|
int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
|
||||||
|
unsigned int keysize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES key schedule (decryption)
|
||||||
|
*
|
||||||
|
* \param ctx AES context to be initialized
|
||||||
|
* \param key decryption key
|
||||||
|
* \param keysize must be 128, 192 or 256
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
*/
|
||||||
|
int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
|
||||||
|
unsigned int keysize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES-ECB block encryption/decryption
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param input 16-byte input block
|
||||||
|
* \param output 16-byte output block
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*/
|
||||||
|
int aes_crypt_ecb( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char input[16],
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
#if defined(POLARSSL_CIPHER_MODE_CBC)
|
||||||
|
/**
|
||||||
|
* \brief AES-CBC buffer encryption/decryption
|
||||||
|
* Length should be a multiple of the block
|
||||||
|
* size (16 bytes)
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||||
|
*/
|
||||||
|
int aes_crypt_cbc( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
size_t length,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
#endif /* POLARSSL_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
|
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||||
|
/**
|
||||||
|
* \brief AES-CFB128 buffer encryption/decryption.
|
||||||
|
*
|
||||||
|
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||||
|
* both encryption and decryption. So a context initialized with
|
||||||
|
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv_off offset in IV (updated after use)
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*/
|
||||||
|
int aes_crypt_cfb128( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
size_t length,
|
||||||
|
size_t *iv_off,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES-CFB8 buffer encryption/decryption.
|
||||||
|
*
|
||||||
|
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||||
|
* both encryption and decryption. So a context initialized with
|
||||||
|
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*/
|
||||||
|
int aes_crypt_cfb8( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
size_t length,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
#endif /*POLARSSL_CIPHER_MODE_CFB */
|
||||||
|
|
||||||
|
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||||
|
/**
|
||||||
|
* \brief AES-CTR buffer encryption/decryption
|
||||||
|
*
|
||||||
|
* Warning: You have to keep the maximum use of your counter in mind!
|
||||||
|
*
|
||||||
|
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||||
|
* both encryption and decryption. So a context initialized with
|
||||||
|
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param length The length of the data
|
||||||
|
* \param nc_off The offset in the current stream_block (for resuming
|
||||||
|
* within current cipher stream). The offset pointer to
|
||||||
|
* should be 0 at the start of a stream.
|
||||||
|
* \param nonce_counter The 128-bit nonce and counter.
|
||||||
|
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||||
|
* by the function.
|
||||||
|
* \param input The input data stream
|
||||||
|
* \param output The output data stream
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*/
|
||||||
|
int aes_crypt_ctr( aes_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
size_t *nc_off,
|
||||||
|
unsigned char nonce_counter[16],
|
||||||
|
unsigned char stream_block[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* POLARSSL_AES_ALT */
|
||||||
|
#include "aes_alt.h"
|
||||||
|
#endif /* POLARSSL_AES_ALT */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*/
|
||||||
|
int aes_self_test( int verbose );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* aes.h */
|
56
lib/aes_faster_c/wrapper.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "aes.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if defined(AES256) && (AES256 == 1)
|
||||||
|
#define AES_KEYSIZE 256
|
||||||
|
#elif defined(AES192) && (AES192 == 1)
|
||||||
|
#define AES_KEYSIZE 192
|
||||||
|
#else
|
||||||
|
#define AES_KEYSIZE 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length)
|
||||||
|
{
|
||||||
|
printf("AES_ECB_encrypt not implemented\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length)
|
||||||
|
{
|
||||||
|
printf("AES_ECB_encrypt not implemented\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||||
|
{
|
||||||
|
static aes_context ctx;
|
||||||
|
static int done=0;
|
||||||
|
if(done==0)
|
||||||
|
{
|
||||||
|
aes_init( &ctx);
|
||||||
|
done=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char tmp_iv[16];
|
||||||
|
if(key!=0) aes_setkey_enc(&ctx,key,AES_KEYSIZE);
|
||||||
|
memcpy(tmp_iv,iv,16);
|
||||||
|
aes_crypt_cbc( &ctx, AES_ENCRYPT, length, (unsigned char* )tmp_iv, (const unsigned char*)input,(unsigned char*) output );
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||||
|
{
|
||||||
|
static aes_context ctx;
|
||||||
|
static int done=0;
|
||||||
|
if(done==0)
|
||||||
|
{
|
||||||
|
aes_init( &ctx);
|
||||||
|
done=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char tmp_iv[16];
|
||||||
|
if(key!=0) aes_setkey_dec(&ctx,key,AES_KEYSIZE);
|
||||||
|
memcpy(tmp_iv,iv,16);
|
||||||
|
aes_crypt_cbc( &ctx,AES_DECRYPT, length, (unsigned char*)tmp_iv, (const unsigned char*)input, (unsigned char*) output );
|
||||||
|
return;
|
||||||
|
}
|
12
lib/md5.c
@@ -302,11 +302,15 @@ void md5_finish( md5_context *ctx, unsigned char output[16] )
|
|||||||
*/
|
*/
|
||||||
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
|
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
|
||||||
{
|
{
|
||||||
md5_context ctx;
|
static md5_context ctx;
|
||||||
|
static int done=0;
|
||||||
md5_init( &ctx );
|
if(done==0)
|
||||||
|
{
|
||||||
|
md5_init( &ctx );
|
||||||
|
done=1;
|
||||||
|
}
|
||||||
md5_starts( &ctx );
|
md5_starts( &ctx );
|
||||||
md5_update( &ctx, input, ilen );
|
md5_update( &ctx, input, ilen );
|
||||||
md5_finish( &ctx, output );
|
md5_finish( &ctx, output );
|
||||||
md5_free( &ctx );
|
//md5_free( &ctx );
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#ifndef _MD5_H_
|
#ifndef UDP2RAW_MD5_H_
|
||||||
#define _MD5_H_
|
#define UDP2RAW_MD5_H_
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
2
log.cpp
@@ -1,11 +1,11 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
int log_level=log_info;
|
int log_level=log_info;
|
||||||
|
|
||||||
int enable_log_position=0;
|
int enable_log_position=0;
|
||||||
int enable_log_color=1;
|
int enable_log_color=1;
|
||||||
|
|
||||||
|
|
||||||
void log0(const char * file,const char * function,int line,int level,const char* str, ...) {
|
void log0(const char * file,const char * function,int line,int level,const char* str, ...) {
|
||||||
|
|
||||||
if(level>log_level) return ;
|
if(level>log_level) return ;
|
||||||
|
53
log.h
@@ -1,57 +1,10 @@
|
|||||||
|
|
||||||
#ifndef _LOG_MYLOG_H_
|
#ifndef UDP2RAW_LOG_MYLOG_H_
|
||||||
#define _LOG_MYLOG_H_
|
#define UDP2RAW_LOG_MYLOG_H_
|
||||||
|
|
||||||
#include<stdio.h>
|
|
||||||
#include<string.h>
|
|
||||||
#include<sys/socket.h>
|
|
||||||
#include<arpa/inet.h>
|
|
||||||
#include<stdlib.h>
|
|
||||||
#include<getopt.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include<errno.h>
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
//#include"aes.h"
|
|
||||||
|
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#include<map>
|
|
||||||
#include<string>
|
|
||||||
#include<vector>
|
|
||||||
|
|
||||||
|
|
||||||
#include <sys/socket.h> //for socket ofcourse
|
#include "common.h"
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdlib.h> //for exit(0);
|
|
||||||
#include <errno.h> //For errno - the error number
|
|
||||||
#include <netinet/tcp.h> //Provides declarations for tcp header
|
|
||||||
#include <netinet/udp.h>
|
|
||||||
#include <netinet/ip.h> //Provides declarations for ip header
|
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <byteswap.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/filter.h>
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <sys/timerfd.h>
|
|
||||||
#include <set>
|
|
||||||
#include "encrypt.h"
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
89
makefile
@@ -1,61 +1,82 @@
|
|||||||
cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||||
cc_local=g++
|
cc_local=g++
|
||||||
cc_ar71xx=/home/wangyu/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
|
#cc_mips34kc=/toolchains/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
|
||||||
cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++
|
cc_mips24kc_be=/toolchains/lede-sdk-17.01.2-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/bin/mips-openwrt-linux-musl-g++
|
||||||
cc_arm=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
cc_mips24kc_le=/toolchains/lede-sdk-17.01.2-ramips-mt7621_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-5.4.0_musl-1.1.16/bin/mipsel-openwrt-linux-musl-g++
|
||||||
|
#cc_arm= /toolchains/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ -march=armv6 -marm
|
||||||
|
cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||||
|
#cc_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
|
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers
|
||||||
|
|
||||||
SOURCES=main.cpp lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -lpthread
|
COMMON=main.cpp lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp -lpthread
|
||||||
SOURCES_AES_ACC=$(filter-out lib/aes.c,$(SOURCES)) $(wildcard lib/aes_acc/aes*.c)
|
SOURCES= $(COMMON) lib/aes_faster_c/aes.c lib/aes_faster_c/wrapper.c
|
||||||
|
SOURCES_TINY_AES= $(COMMON) lib/aes.c
|
||||||
|
SOURCES_AES_ACC=$(COMMON) $(wildcard lib/aes_acc/aes*.c)
|
||||||
|
|
||||||
NAME=udp2raw
|
NAME=udp2raw
|
||||||
TAR=${NAME}_binaries.tar.gz ${NAME}_amd64 ${NAME}_x86 ${NAME}_x86_asm_aes ${NAME}_ar71xx ${NAME}_bcm2708 ${NAME}_arm ${NAME}_amd64_hw_aes ${NAME}_arm_asm_aes ${NAME}_ar71xx_asm_aes
|
TARGETS=amd64 arm amd64_hw_aes arm_asm_aes mips24kc_be mips24kc_be_asm_aes x86 x86_asm_aes mips24kc_le mips24kc_le_asm_aes
|
||||||
|
TAR=${NAME}_binaries.tar.gz `echo ${TARGETS}|sed -r 's/([^ ]+)/udp2raw_\1/g'` version.txt
|
||||||
|
|
||||||
all:
|
all:git_version
|
||||||
rm -f ${NAME}
|
rm -f ${NAME}
|
||||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O3
|
||||||
fast:
|
fast: git_version
|
||||||
rm -f ${NAME}
|
rm -f ${NAME}
|
||||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt
|
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb
|
||||||
debug:
|
debug: git_version
|
||||||
rm -f ${NAME}
|
rm -f ${NAME}
|
||||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
|
${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
|
||||||
|
|
||||||
ar71xx:
|
dynamic: git_version
|
||||||
${cc_ar71xx} -o ${NAME}_ar71xx -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -O3
|
||||||
|
|
||||||
ar71xx_asm_aes:
|
mips24kc_be: git_version
|
||||||
${cc_ar71xx} -o ${NAME}_ar71xx_asm_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips_be.S
|
${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 -O3 lib/aes_acc/asm/mips_be.S
|
||||||
|
|
||||||
bcm2708:
|
mips24kc_le: git_version
|
||||||
${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||||
amd64:
|
mips24kc_le_asm_aes: git_version
|
||||||
${cc_local} -o ${NAME}_amd64 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips.S
|
||||||
amd64_hw_aes:
|
|
||||||
${cc_local} -o ${NAME}_amd64_hw_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/x64.S
|
|
||||||
x86:
|
|
||||||
${cc_local} -o ${NAME}_x86 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
|
|
||||||
x86_asm_aes:
|
|
||||||
${cc_local} -o ${NAME}_x86_asm_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 -m32 lib/aes_acc/asm/x86.S
|
|
||||||
arm:
|
|
||||||
${cc_cross} -o ${NAME}_arm -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
|
||||||
|
|
||||||
arm_asm_aes:
|
#bcm2708:
|
||||||
${cc_cross} -o ${NAME}_arm_asm_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/arm.S
|
# ${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||||
|
amd64:git_version
|
||||||
|
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||||
|
amd64_hw_aes:git_version
|
||||||
|
${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/x64.S
|
||||||
|
x86:git_version
|
||||||
|
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
|
||||||
|
x86_asm_aes:git_version
|
||||||
|
${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 -O3
|
||||||
|
|
||||||
cross:
|
arm_asm_aes:git_version
|
||||||
|
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/arm.S
|
||||||
|
|
||||||
|
cross:git_version
|
||||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
|
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
|
||||||
|
|
||||||
cross2:
|
cross2:git_version
|
||||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
|
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
|
||||||
|
|
||||||
cross3:
|
cross3:git_version
|
||||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||||
|
|
||||||
release: amd64 x86 ar71xx bcm2708 arm amd64_hw_aes arm_asm_aes x86_asm_aes ar71xx_asm_aes
|
release: ${TARGETS}
|
||||||
|
cp git_version.h version.txt
|
||||||
tar -zcvf ${TAR}
|
tar -zcvf ${TAR}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ${TAR}
|
rm -f ${TAR}
|
||||||
rm -f udp2raw udp2raw_cross udp2raw_cmake
|
rm -f udp2raw udp2raw_cross udp2raw_cmake udp2raw_dynamic
|
||||||
|
rm -f git_version.h
|
||||||
|
|
||||||
|
git_version:
|
||||||
|
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > git_version.h
|
||||||
|
|
||||||
|
132
misc.h
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* misc.h
|
||||||
|
*
|
||||||
|
* Created on: Sep 23, 2017
|
||||||
|
* Author: root
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MISC_H_
|
||||||
|
#define MISC_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "network.h"
|
||||||
|
|
||||||
|
extern int hb_mode;
|
||||||
|
extern int hb_len;
|
||||||
|
extern int mtu_warn;
|
||||||
|
|
||||||
|
const u32_t max_handshake_conn_num=10000;
|
||||||
|
const u32_t max_ready_conn_num=1000;
|
||||||
|
const u32_t anti_replay_window_size=4000;
|
||||||
|
const int max_conv_num=10000;
|
||||||
|
|
||||||
|
const u32_t client_handshake_timeout=5000;//unit ms
|
||||||
|
const u32_t client_retry_interval=1000;//ms
|
||||||
|
|
||||||
|
const u32_t server_handshake_timeout=client_handshake_timeout+5000;// this should be longer than clients. client retry initially ,server retry passtively
|
||||||
|
|
||||||
|
const int conv_clear_ratio=30; //conv grabage collecter check 1/30 of all conv one time
|
||||||
|
const int conn_clear_ratio=50;
|
||||||
|
const int conv_clear_min=1;
|
||||||
|
const int conn_clear_min=1;
|
||||||
|
|
||||||
|
const 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
|
||||||
|
|
||||||
|
const u32_t timer_interval=400;//ms. this should be smaller than heartbeat_interval and retry interval;
|
||||||
|
|
||||||
|
const uint32_t conv_timeout=180000; //ms. 120 second
|
||||||
|
//const u32_t conv_timeout=30000; //for test
|
||||||
|
|
||||||
|
const u32_t client_conn_timeout=10000;//ms.
|
||||||
|
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;//ms
|
||||||
|
|
||||||
|
const uint32_t server_conn_timeout=conv_timeout+60000;//ms. this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
|
||||||
|
//const u32_t server_conn_timeout=conv_timeout+10000;//for test
|
||||||
|
|
||||||
|
const u32_t iptables_rule_keep_interval=15;//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 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};
|
||||||
|
|
||||||
|
union current_state_t
|
||||||
|
{
|
||||||
|
server_current_state_t server_current_state;
|
||||||
|
client_current_state_t client_current_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern char local_ip[100], remote_ip[100],source_ip[100];//local_ip is for -l option,remote_ip for -r option,source for --source-ip
|
||||||
|
extern u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line.
|
||||||
|
extern int local_port , remote_port,source_port;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled
|
||||||
|
|
||||||
|
extern int force_source_ip; //if --source-ip is enabled
|
||||||
|
|
||||||
|
extern id_t const_id;//an id used for connection recovery,its generated randomly,it never change since its generated
|
||||||
|
|
||||||
|
extern int udp_fd; //for client only. client use this fd to listen and handle udp connection
|
||||||
|
extern int bind_fd; //bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port
|
||||||
|
extern int epollfd; //fd for epoll
|
||||||
|
extern int timer_fd; //the general timer fd for client and server.for server this is not the only timer find,every connection has a timer fd.
|
||||||
|
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
|
||||||
|
extern int generate_iptables_rule;//if -g is set
|
||||||
|
extern int generate_iptables_rule_add;// if --gen-add is set
|
||||||
|
|
||||||
|
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 program_mode_t program_mode;
|
||||||
|
extern unordered_map<int, const char*> raw_mode_tostring ;
|
||||||
|
|
||||||
|
extern int about_to_exit;
|
||||||
|
|
||||||
|
extern int socket_buf_size;
|
||||||
|
extern int force_socket_buf;
|
||||||
|
|
||||||
|
extern pthread_t keep_thread;
|
||||||
|
extern int keep_thread_running;
|
||||||
|
|
||||||
|
|
||||||
|
int process_lower_level_arg();
|
||||||
|
void print_help();
|
||||||
|
void iptables_rule();
|
||||||
|
void pre_process_arg(int argc, char *argv[]);//mainly for load conf file;
|
||||||
|
int unit_test();
|
||||||
|
int set_timer(int epollfd,int &timer_fd);
|
||||||
|
int set_timer_server(int epollfd,int &timer_fd,fd64_t &fd64);
|
||||||
|
int handle_lower_level(raw_info_t &raw_info);
|
||||||
|
|
||||||
|
int add_iptables_rule(const char *);
|
||||||
|
|
||||||
|
int clear_iptables_rule();
|
||||||
|
|
||||||
|
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_ */
|
495
network.cpp
@@ -7,12 +7,15 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
int raw_recv_fd=-1;
|
int raw_recv_fd=-1;
|
||||||
int raw_send_fd=-1;
|
int raw_send_fd=-1;
|
||||||
u32_t link_level_header_len=0;//set it to 14 if SOCK_RAW is used in socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
u32_t link_level_header_len=0;//set it to 14 if SOCK_RAW is used in socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
||||||
|
|
||||||
int seq_mode=1;
|
int seq_mode=3;
|
||||||
|
int max_seq_mode=4;
|
||||||
|
int random_drop=0;
|
||||||
|
|
||||||
int filter_port=-1;
|
int filter_port=-1;
|
||||||
|
|
||||||
@@ -31,6 +34,10 @@ unsigned char dest_hw_addr[sizeof(sockaddr_ll::sll_addr)]=
|
|||||||
{0xff,0xff,0xff,0xff,0xff,0xff,0,0};
|
{0xff,0xff,0xff,0xff,0xff,0xff,0,0};
|
||||||
//{0x00,0x23,0x45,0x67,0x89,0xb9};
|
//{0x00,0x23,0x45,0x67,0x89,0xb9};
|
||||||
|
|
||||||
|
const u32_t receive_window_lower_bound=40960;
|
||||||
|
const u32_t receive_window_random_range=512;
|
||||||
|
const unsigned char wscale=0x05;
|
||||||
|
|
||||||
struct sock_filter code_tcp_old[] = {
|
struct sock_filter code_tcp_old[] = {
|
||||||
{ 0x28, 0, 0, 0x0000000c },//0
|
{ 0x28, 0, 0, 0x0000000c },//0
|
||||||
{ 0x15, 0, 10, 0x00000800 },//1
|
{ 0x15, 0, 10, 0x00000800 },//1
|
||||||
@@ -146,6 +153,7 @@ packet_info_t::packet_info_t()
|
|||||||
ts_ack=0;
|
ts_ack=0;
|
||||||
syn=0;
|
syn=0;
|
||||||
ack=1;
|
ack=1;
|
||||||
|
ack_seq_counter=0;
|
||||||
|
|
||||||
//mylog(log_info,"<cons ,ts_ack= %u>\n",ts_ack);
|
//mylog(log_info,"<cons ,ts_ack= %u>\n",ts_ack);
|
||||||
}
|
}
|
||||||
@@ -199,11 +207,22 @@ int init_raw_socket()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
if(force_socket_buf)
|
||||||
{
|
{
|
||||||
mylog(log_fatal,"SO_SNDBUFFORCE fail\n");
|
if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
myexit(1);
|
{
|
||||||
}
|
mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -217,11 +236,22 @@ int init_raw_socket()
|
|||||||
myexit(1);
|
myexit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
if(force_socket_buf)
|
||||||
{
|
{
|
||||||
mylog(log_fatal,"SO_RCVBUFFORCE fail\n");
|
if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
myexit(1);
|
{
|
||||||
}
|
mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||||
|
myexit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//IP_HDRINCL to tell the kernel that headers are included in the packet
|
//IP_HDRINCL to tell the kernel that headers are included in the packet
|
||||||
|
|
||||||
@@ -289,7 +319,7 @@ void remove_filter()
|
|||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int init_ifindex(char * if_name)
|
int init_ifindex(const char * if_name,int &index)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
size_t if_name_len=strlen(if_name);
|
size_t if_name_len=strlen(if_name);
|
||||||
@@ -305,10 +335,230 @@ int init_ifindex(char * if_name)
|
|||||||
mylog(log_fatal,"SIOCGIFINDEX fail ,%s\n",strerror(errno));
|
mylog(log_fatal,"SIOCGIFINDEX fail ,%s\n",strerror(errno));
|
||||||
myexit(-1);
|
myexit(-1);
|
||||||
}
|
}
|
||||||
ifindex=ifr.ifr_ifindex;
|
index=ifr.ifr_ifindex;
|
||||||
mylog(log_info,"ifname:%s ifindex:%d\n",if_name,ifindex);
|
mylog(log_info,"ifname:%s ifindex:%d\n",if_name,index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
bool interface_has_arp(const char * interface) {
|
||||||
|
struct ifreq ifr;
|
||||||
|
// int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
|
||||||
|
int sock=raw_send_fd;
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strcpy(ifr.ifr_name, interface);
|
||||||
|
if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
//perror("SIOCGIFFLAGS");
|
||||||
|
mylog(log_fatal,"ioctl(sock, SIOCGIFFLAGS, &ifr) failed for interface %s,errno %s\n",interface,strerror(errno));
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
//close(sock);
|
||||||
|
return !(ifr.ifr_flags & IFF_NOARP);
|
||||||
|
}
|
||||||
|
struct route_info_t
|
||||||
|
{
|
||||||
|
string if_name;
|
||||||
|
u32_t dest;
|
||||||
|
u32_t mask;
|
||||||
|
u32_t gw;
|
||||||
|
u32_t flag;
|
||||||
|
|
||||||
|
};
|
||||||
|
int dest_idx=1;
|
||||||
|
int gw_idx=2;
|
||||||
|
int if_idx=0;
|
||||||
|
int mask_idx=7;
|
||||||
|
int flag_idx=3;
|
||||||
|
vector<int> find_route_entry(const vector<route_info_t> &route_info_vec,u32_t ip)
|
||||||
|
{
|
||||||
|
vector<int> res;
|
||||||
|
for(u32_t i=0;i<=32;i++)
|
||||||
|
{
|
||||||
|
u32_t mask=0xffffffff;
|
||||||
|
//mask >>=i;
|
||||||
|
//if(i==32) mask=0; //why 0xffffffff>>32 equals 0xffffffff??
|
||||||
|
|
||||||
|
mask <<=i;
|
||||||
|
if(i==32) mask=0;
|
||||||
|
log_bare(log_debug,"(mask:%x)",mask);
|
||||||
|
for(u32_t j=0;j<route_info_vec.size();j++)
|
||||||
|
{
|
||||||
|
const route_info_t & info=route_info_vec[j];
|
||||||
|
if(info.mask!=mask)
|
||||||
|
continue;
|
||||||
|
log_bare(log_debug,"<<%d,%d>>",i,j);
|
||||||
|
if((info.dest&mask)==(ip&mask))
|
||||||
|
{
|
||||||
|
log_bare(log_debug,"found!");
|
||||||
|
res.push_back(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(res.size()!=0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int find_direct_dest(const vector<route_info_t> &route_info_vec,u32_t ip,u32_t &dest_ip,string &if_name)
|
||||||
|
{
|
||||||
|
vector<int> res;
|
||||||
|
for(int i=0;i<1000;i++)
|
||||||
|
{
|
||||||
|
res=find_route_entry(route_info_vec,ip);
|
||||||
|
log_bare(log_debug,"<entry:%u>",(u32_t)res.size());
|
||||||
|
if(res.size()==0)
|
||||||
|
{
|
||||||
|
mylog(log_error,"cant find route entry\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(res.size()>1)
|
||||||
|
{
|
||||||
|
mylog(log_error,"found duplicated entries\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if((route_info_vec[res[0]].flag&2)==0)
|
||||||
|
{
|
||||||
|
dest_ip=ip;
|
||||||
|
if_name=route_info_vec[res[0]].if_name;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ip=route_info_vec[res[0]].gw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mylog(log_error,"dead loop in find_direct_dest\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct arp_info_t
|
||||||
|
{
|
||||||
|
u32_t ip;
|
||||||
|
string hw;
|
||||||
|
string if_name;
|
||||||
|
};
|
||||||
|
int arp_ip_idx=0;
|
||||||
|
int arp_hw_idx=3;
|
||||||
|
int arp_if_idx=5;
|
||||||
|
|
||||||
|
|
||||||
|
int find_arp(const vector<arp_info_t> &arp_info_vec,u32_t ip,string if_name,string &hw)
|
||||||
|
{
|
||||||
|
int pos=-1;
|
||||||
|
int count=0;
|
||||||
|
for(u32_t i=0;i<arp_info_vec.size();i++)
|
||||||
|
{
|
||||||
|
const arp_info_t & info=arp_info_vec[i];
|
||||||
|
if(info.if_name!=if_name) continue;
|
||||||
|
if(info.ip==ip)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
pos=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(count==0)
|
||||||
|
{
|
||||||
|
//mylog(log_warn,"cant find arp entry for %s %s,using 00:00:00:00:00:00\n",my_ntoa(ip),if_name.c_str());
|
||||||
|
//hw="00:00:00:00:00:00";
|
||||||
|
mylog(log_error,"cant find arp entry for %s %s\n",my_ntoa(ip),if_name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(count>1)
|
||||||
|
{
|
||||||
|
mylog(log_error,"find multiple arp entry for %s %s\n",my_ntoa(ip),if_name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
hw=arp_info_vec[pos].hw;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw)
|
||||||
|
{
|
||||||
|
ip=htonl(ip);
|
||||||
|
if(ip==htonl(inet_addr("127.0.0.1")))
|
||||||
|
{
|
||||||
|
dest_ip=ntohl(ip);
|
||||||
|
if_name="lo";
|
||||||
|
hw="00:00:00:00:00:00";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
string route_file;
|
||||||
|
if(read_file("/proc/net/route",route_file)!=0) return -1;
|
||||||
|
string arp_file;
|
||||||
|
if(read_file("/proc/net/arp",arp_file)!=0) return -1;
|
||||||
|
|
||||||
|
log_bare(log_debug,"/proc/net/route:<<%s>>\n",route_file.c_str());
|
||||||
|
log_bare(log_debug,"/proc/net/arp:<<%s>>\n",route_file.c_str());
|
||||||
|
|
||||||
|
auto route_vec2=string_to_vec2(route_file.c_str());
|
||||||
|
vector<route_info_t> route_info_vec;
|
||||||
|
for(u32_t i=1;i<route_vec2.size();i++)
|
||||||
|
{
|
||||||
|
log_bare(log_debug,"<size:%u>",(u32_t)route_vec2[i].size());
|
||||||
|
if(route_vec2[i].size()!=11)
|
||||||
|
{
|
||||||
|
mylog(log_error,"route coloum %d !=11 \n",int(route_vec2[i].size()));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
route_info_t tmp;
|
||||||
|
tmp.if_name=route_vec2[i][if_idx];
|
||||||
|
if(hex_to_u32_with_endian(route_vec2[i][dest_idx],tmp.dest)!=0) return -1;
|
||||||
|
if(hex_to_u32_with_endian(route_vec2[i][gw_idx],tmp.gw)!=0) return -1;
|
||||||
|
if(hex_to_u32_with_endian(route_vec2[i][mask_idx],tmp.mask)!=0) return -1;
|
||||||
|
if(hex_to_u32(route_vec2[i][flag_idx],tmp.flag)!=0)return -1;
|
||||||
|
route_info_vec.push_back(tmp);
|
||||||
|
for(u32_t j=0;j<route_vec2[i].size();j++)
|
||||||
|
{
|
||||||
|
log_bare(log_debug,"<%s>",route_vec2[i][j].c_str());
|
||||||
|
}
|
||||||
|
log_bare(log_debug,"%s dest:%x mask:%x gw:%x flag:%x",tmp.if_name.c_str(),tmp.dest,tmp.mask,tmp.gw,tmp.flag);
|
||||||
|
log_bare(log_debug,"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(find_direct_dest(route_info_vec,ip,dest_ip,if_name)!=0)
|
||||||
|
{
|
||||||
|
mylog(log_error,"find_direct_dest failed for ip %s\n",my_ntoa(ntohl(ip)));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log_bare(log_debug,"========\n");
|
||||||
|
auto arp_vec2=string_to_vec2(arp_file.c_str());
|
||||||
|
vector<arp_info_t> arp_info_vec;
|
||||||
|
for(u32_t i=1;i<arp_vec2.size();i++)
|
||||||
|
{
|
||||||
|
log_bare(log_debug,"<<arp_vec2[i].size(): %d>>",(int)arp_vec2[i].size());
|
||||||
|
|
||||||
|
for(u32_t j=0;j<arp_vec2[i].size();j++)
|
||||||
|
{
|
||||||
|
log_bare(log_debug,"<%s>",arp_vec2[i][j].c_str());
|
||||||
|
}
|
||||||
|
if(arp_vec2[i].size()!=6)
|
||||||
|
{
|
||||||
|
mylog(log_error,"arp coloum %d !=11 \n",int(arp_vec2[i].size()));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
arp_info_t tmp;
|
||||||
|
tmp.if_name=arp_vec2[i][arp_if_idx];
|
||||||
|
tmp.hw=arp_vec2[i][arp_hw_idx];
|
||||||
|
tmp.ip=htonl(inet_addr(arp_vec2[i][arp_ip_idx].c_str()));
|
||||||
|
arp_info_vec.push_back(tmp);
|
||||||
|
log_bare(log_debug,"\n");
|
||||||
|
}
|
||||||
|
if(!interface_has_arp(if_name.c_str()))
|
||||||
|
{
|
||||||
|
mylog(log_info,"%s is a noarp interface,using 00:00:00:00:00:00\n",if_name.c_str());
|
||||||
|
hw="00:00:00:00:00:00";
|
||||||
|
}
|
||||||
|
else if(find_arp(arp_info_vec,dest_ip,if_name,hw)!=0)
|
||||||
|
{
|
||||||
|
mylog(log_error,"find_arp failed for dest_ip %s ,if_name %s\n",my_ntoa(ntohl(ip)),if_name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//printf("%s\n",hw.c_str());
|
||||||
|
|
||||||
|
dest_ip=ntohl(dest_ip);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||||
{
|
{
|
||||||
@@ -624,8 +874,8 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
|||||||
|
|
||||||
//mylog(log_debug,"syn %d\n",send_info.syn);
|
//mylog(log_debug,"syn %d\n",send_info.syn);
|
||||||
|
|
||||||
char send_raw_tcp_buf0[buf_len];
|
char send_raw_tcp_buf[buf_len];
|
||||||
char *send_raw_tcp_buf=send_raw_tcp_buf0;
|
//char *send_raw_tcp_buf=send_raw_tcp_buf0;
|
||||||
|
|
||||||
struct tcphdr *tcph = (struct tcphdr *) (send_raw_tcp_buf
|
struct tcphdr *tcph = (struct tcphdr *) (send_raw_tcp_buf
|
||||||
+ sizeof(struct pseudo_header));
|
+ sizeof(struct pseudo_header));
|
||||||
@@ -664,20 +914,26 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
|||||||
send_raw_tcp_buf[i++] = 0x08; //ts i=6
|
send_raw_tcp_buf[i++] = 0x08; //ts i=6
|
||||||
send_raw_tcp_buf[i++] = 0x0a; //i=7
|
send_raw_tcp_buf[i++] = 0x0a; //i=7
|
||||||
|
|
||||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
||||||
(u32_t) get_current_time());
|
// (u32_t) get_current_time());
|
||||||
|
|
||||||
|
u32_t ts=htonl((u32_t) get_current_time());
|
||||||
|
memcpy(&send_raw_tcp_buf[i],&ts,sizeof(ts));
|
||||||
|
|
||||||
i += 4;
|
i += 4;
|
||||||
|
|
||||||
//mylog(log_info,"[syn]<send_info.ts_ack= %u>\n",send_info.ts_ack);
|
//mylog(log_info,"[syn]<send_info.ts_ack= %u>\n",send_info.ts_ack);
|
||||||
|
|
||||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
||||||
|
u32_t ts_ack=htonl(send_info.ts_ack);
|
||||||
|
memcpy(&send_raw_tcp_buf[i],&ts_ack,sizeof(ts_ack));
|
||||||
|
|
||||||
i += 4;
|
i += 4;
|
||||||
|
|
||||||
send_raw_tcp_buf[i++] = 0x01;
|
send_raw_tcp_buf[i++] = 0x01;
|
||||||
send_raw_tcp_buf[i++] = 0x03;
|
send_raw_tcp_buf[i++] = 0x03;
|
||||||
send_raw_tcp_buf[i++] = 0x03;
|
send_raw_tcp_buf[i++] = 0x03;
|
||||||
send_raw_tcp_buf[i++] = 0x05;
|
send_raw_tcp_buf[i++] = wscale;
|
||||||
} else {
|
} else {
|
||||||
tcph->doff = 8;
|
tcph->doff = 8;
|
||||||
int i = sizeof(pseudo_header)+sizeof(tcphdr);
|
int i = sizeof(pseudo_header)+sizeof(tcphdr);
|
||||||
@@ -688,20 +944,25 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
|||||||
send_raw_tcp_buf[i++] = 0x08; //ts //i=2
|
send_raw_tcp_buf[i++] = 0x08; //ts //i=2
|
||||||
send_raw_tcp_buf[i++] = 0x0a; //i=3;
|
send_raw_tcp_buf[i++] = 0x0a; //i=3;
|
||||||
|
|
||||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
||||||
(u32_t) get_current_time());
|
// (u32_t) get_current_time());
|
||||||
|
|
||||||
|
u32_t ts=htonl((u32_t) get_current_time());
|
||||||
|
memcpy(&send_raw_tcp_buf[i],&ts,sizeof(ts));
|
||||||
|
|
||||||
i += 4;
|
i += 4;
|
||||||
|
|
||||||
//mylog(log_info,"<send_info.ts_ack= %u>\n",send_info.ts_ack);
|
//mylog(log_info,"<send_info.ts_ack= %u>\n",send_info.ts_ack);
|
||||||
|
|
||||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
||||||
|
u32_t ts_ack=htonl(send_info.ts_ack);
|
||||||
|
memcpy(&send_raw_tcp_buf[i],&ts_ack,sizeof(ts_ack));
|
||||||
i += 4;
|
i += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcph->urg = 0;
|
tcph->urg = 0;
|
||||||
//tcph->window = htons((uint16_t)(1024));
|
//tcph->window = htons((uint16_t)(1024));
|
||||||
tcph->window = htons((uint16_t) (10240 + random() % 100));
|
tcph->window = htons((uint16_t) (receive_window_lower_bound + random() % receive_window_random_range));
|
||||||
|
|
||||||
tcph->check = 0; //leave checksum 0 now, filled later by pseudo header
|
tcph->check = 0; //leave checksum 0 now, filled later by pseudo header
|
||||||
tcph->urg_ptr = 0;
|
tcph->urg_ptr = 0;
|
||||||
@@ -728,7 +989,7 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
raw_info.last_send_len=payloadlen;
|
raw_info.send_info.data_len=payloadlen;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -1114,8 +1375,14 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
|||||||
if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a)
|
if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a)
|
||||||
{
|
{
|
||||||
recv_info.has_ts=1;
|
recv_info.has_ts=1;
|
||||||
recv_info.ts=ntohl(*(u32_t*)(&tcp_option[8]));
|
//recv_info.ts=ntohl(*(u32_t*)(&tcp_option[8]));
|
||||||
recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[12]));
|
memcpy(&recv_info.ts,&tcp_option[8],sizeof(recv_info.ts));
|
||||||
|
recv_info.ts=ntohl(recv_info.ts);
|
||||||
|
|
||||||
|
//recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[12]));
|
||||||
|
memcpy(&recv_info.ts_ack,&tcp_option[12],sizeof(recv_info.ts_ack));
|
||||||
|
recv_info.ts_ack=ntohl(recv_info.ts_ack);
|
||||||
|
|
||||||
//g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8]));
|
//g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1128,8 +1395,12 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
|||||||
if(tcp_option[2]==0x08 &&tcp_option[3]==0x0a)
|
if(tcp_option[2]==0x08 &&tcp_option[3]==0x0a)
|
||||||
{
|
{
|
||||||
recv_info.has_ts=1;
|
recv_info.has_ts=1;
|
||||||
recv_info.ts=ntohl(*(u32_t*)(&tcp_option[4]));
|
//recv_info.ts=ntohl(*(u32_t*)(&tcp_option[4]));
|
||||||
recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[8]));
|
memcpy(&recv_info.ts,&tcp_option[4],sizeof(recv_info.ts));
|
||||||
|
recv_info.ts=ntohl(recv_info.ts);
|
||||||
|
//recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[8]));
|
||||||
|
memcpy(&recv_info.ts_ack,&tcp_option[8],sizeof(recv_info.ts_ack));
|
||||||
|
recv_info.ts_ack=ntohl(recv_info.ts_ack);
|
||||||
//g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0]));
|
//g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1150,7 +1421,20 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
|||||||
recv_info.dst_port=ntohs(tcph->dest);
|
recv_info.dst_port=ntohs(tcph->dest);
|
||||||
|
|
||||||
recv_info.seq=ntohl(tcph->seq);
|
recv_info.seq=ntohl(tcph->seq);
|
||||||
|
|
||||||
|
// recv_info.last_last_ack_seq=recv_info.last_ack_seq;
|
||||||
|
//recv_info.last_ack_seq=recv_info.ack_seq;
|
||||||
|
u32_t last_ack_seq=recv_info.ack_seq;
|
||||||
recv_info.ack_seq=ntohl(tcph->ack_seq);
|
recv_info.ack_seq=ntohl(tcph->ack_seq);
|
||||||
|
if(recv_info.ack_seq==last_ack_seq)
|
||||||
|
{
|
||||||
|
recv_info.ack_seq_counter++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recv_info.ack_seq_counter=0;
|
||||||
|
}
|
||||||
|
|
||||||
recv_info.psh=tcph->psh;
|
recv_info.psh=tcph->psh;
|
||||||
|
|
||||||
if(tcph->rst==1)
|
if(tcph->rst==1)
|
||||||
@@ -1171,7 +1455,7 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
|||||||
{
|
{
|
||||||
send_info.ack_seq=recv_info.seq;
|
send_info.ack_seq=recv_info.seq;
|
||||||
}*/
|
}*/
|
||||||
raw_info.last_recv_len=payloadlen;
|
raw_info.recv_info.data_len=payloadlen;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -1340,6 +1624,12 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen)
|
|||||||
}*/
|
}*/
|
||||||
int send_raw0(raw_info_t &raw_info,const char * payload,int payloadlen)
|
int send_raw0(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||||
{
|
{
|
||||||
|
if (random_drop != 0) {
|
||||||
|
if (get_true_random_number() % 10000 < (u32_t) random_drop) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packet_info_t &send_info=raw_info.send_info;
|
packet_info_t &send_info=raw_info.send_info;
|
||||||
packet_info_t &recv_info=raw_info.recv_info;
|
packet_info_t &recv_info=raw_info.recv_info;
|
||||||
mylog(log_trace,"send_raw : from %x %d to %x %d\n",send_info.src_ip,send_info.src_port,send_info.dst_ip,send_info.dst_port);
|
mylog(log_trace,"send_raw : from %x %d to %x %d\n",send_info.src_ip,send_info.src_port,send_info.dst_ip,send_info.dst_port);
|
||||||
@@ -1373,18 +1663,47 @@ int after_send_raw0(raw_info_t &raw_info)
|
|||||||
|
|
||||||
if(raw_mode==mode_faketcp)
|
if(raw_mode==mode_faketcp)
|
||||||
{
|
{
|
||||||
if (send_info.syn == 0 && send_info.ack == 1&& raw_info.last_send_len != 0) //only modify send_info when the packet is not part of handshake
|
if (send_info.syn == 0 && send_info.ack == 1&& raw_info.send_info.data_len != 0) //only modify send_info when the packet is not part of handshake
|
||||||
{
|
{
|
||||||
if (seq_mode == 0)
|
if (seq_mode == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
} else if (seq_mode == 1)
|
} else if (seq_mode == 1)
|
||||||
{
|
{
|
||||||
send_info.seq += raw_info.last_send_len; //////////////////modify
|
send_info.seq += raw_info.send_info.data_len; //////////////////modify
|
||||||
} else if (seq_mode == 2)
|
} else if (seq_mode == 2)
|
||||||
{
|
{
|
||||||
if (random() % 5 == 3)
|
if (random() % 5 == 3)
|
||||||
send_info.seq += raw_info.last_send_len; //////////////////modify
|
send_info.seq += raw_info.send_info.data_len; //////////////////modify
|
||||||
|
}
|
||||||
|
else if(seq_mode==3||seq_mode==4)
|
||||||
|
{
|
||||||
|
send_info.seq += raw_info.send_info.data_len;
|
||||||
|
|
||||||
|
u32_t window_size;
|
||||||
|
|
||||||
|
if(seq_mode==3)
|
||||||
|
{
|
||||||
|
window_size=(u32_t)((u32_t)receive_window_lower_bound<<(u32_t)wscale);
|
||||||
|
}
|
||||||
|
else//seq_mode==4
|
||||||
|
{
|
||||||
|
window_size=(u32_t)((u32_t)receive_window_lower_bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(larger_than_u32(send_info.seq+max_data_len,recv_info.ack_seq+window_size))
|
||||||
|
{
|
||||||
|
send_info.seq=raw_info.recv_info.ack_seq;
|
||||||
|
}
|
||||||
|
if(recv_info.ack_seq_counter>=3) //simulate tcp fast re-transmit
|
||||||
|
{
|
||||||
|
recv_info.ack_seq_counter=0;
|
||||||
|
send_info.seq=raw_info.recv_info.ack_seq;
|
||||||
|
}
|
||||||
|
if(larger_than_u32(raw_info.recv_info.ack_seq,send_info.seq)) //for further use,currently no effect.
|
||||||
|
{
|
||||||
|
send_info.seq=raw_info.recv_info.ack_seq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1406,10 +1725,21 @@ int after_recv_raw0(raw_info_t &raw_info)
|
|||||||
{
|
{
|
||||||
if(recv_info.has_ts)
|
if(recv_info.has_ts)
|
||||||
send_info.ts_ack=recv_info.ts;
|
send_info.ts_ack=recv_info.ts;
|
||||||
if (recv_info.syn == 0 && recv_info.ack == 1 && raw_info.last_recv_len != 0) //only modify send_info when the packet is not part of handshake
|
if (recv_info.syn == 0 && recv_info.ack == 1 && raw_info.recv_info.data_len != 0) //only modify send_info when the packet is not part of handshake
|
||||||
{
|
{
|
||||||
if(larger_than_u32(recv_info.seq+raw_info.last_recv_len,send_info.ack_seq))
|
if(seq_mode==0||seq_mode==1||seq_mode==2)
|
||||||
send_info.ack_seq = recv_info.seq+raw_info.last_recv_len;//TODO only update if its larger
|
{
|
||||||
|
if(larger_than_u32(recv_info.seq+raw_info.recv_info.data_len,send_info.ack_seq))
|
||||||
|
send_info.ack_seq = recv_info.seq+raw_info.recv_info.data_len;//TODO only update if its larger
|
||||||
|
}
|
||||||
|
else if(seq_mode==3||seq_mode==4)
|
||||||
|
{
|
||||||
|
if(recv_info.seq==send_info.ack_seq)
|
||||||
|
{
|
||||||
|
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;//currently we dont remembr tcp segments,this is the simplest way
|
||||||
|
//TODO implement tcp segment remembering and SACK.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(raw_mode==mode_icmp)
|
if(raw_mode==mode_icmp)
|
||||||
@@ -1450,3 +1780,96 @@ int recv_raw(raw_info_t &raw_info,char *& payload,int & payloadlen)
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip
|
||||||
|
{
|
||||||
|
struct sockaddr_in remote_addr_in={0};
|
||||||
|
|
||||||
|
socklen_t slen = sizeof(sockaddr_in);
|
||||||
|
//memset(&remote_addr_in, 0, sizeof(remote_addr_in));
|
||||||
|
remote_addr_in.sin_family = AF_INET;
|
||||||
|
remote_addr_in.sin_port = htons(remote_port);
|
||||||
|
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
|
||||||
|
|
||||||
|
|
||||||
|
int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if(new_udp_fd<0)
|
||||||
|
{
|
||||||
|
mylog(log_warn,"create udp_fd error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//set_buf_size(new_udp_fd);
|
||||||
|
|
||||||
|
mylog(log_debug,"created new udp_fd %d\n",new_udp_fd);
|
||||||
|
int ret = connect(new_udp_fd, (struct sockaddr *) &remote_addr_in, slen);
|
||||||
|
if(ret!=0)
|
||||||
|
{
|
||||||
|
mylog(log_warn,"udp fd connect fail\n");
|
||||||
|
close(new_udp_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in my_addr={0};
|
||||||
|
socklen_t len=sizeof(my_addr);
|
||||||
|
|
||||||
|
if(getsockname(new_udp_fd, (struct sockaddr *) &my_addr, &len)!=0) return -1;
|
||||||
|
|
||||||
|
ip=my_addr.sin_addr.s_addr;
|
||||||
|
|
||||||
|
close(new_udp_fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int try_to_list_and_bind(int &fd,u32_t local_ip_uint32,int port) //try to bind to a port,may fail.
|
||||||
|
{
|
||||||
|
int old_bind_fd=fd;
|
||||||
|
|
||||||
|
if(raw_mode==mode_faketcp)
|
||||||
|
{
|
||||||
|
fd=socket(AF_INET,SOCK_STREAM,0);
|
||||||
|
}
|
||||||
|
else if(raw_mode==mode_udp||raw_mode==mode_icmp)
|
||||||
|
{
|
||||||
|
fd=socket(AF_INET,SOCK_DGRAM,0);
|
||||||
|
}
|
||||||
|
if(old_bind_fd!=-1)
|
||||||
|
{
|
||||||
|
close(old_bind_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in temp_bind_addr={0};
|
||||||
|
//bzero(&temp_bind_addr, sizeof(temp_bind_addr));
|
||||||
|
|
||||||
|
temp_bind_addr.sin_family = AF_INET;
|
||||||
|
temp_bind_addr.sin_port = htons(port);
|
||||||
|
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
|
||||||
|
{
|
||||||
|
mylog(log_debug,"bind fail\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(raw_mode==mode_faketcp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (listen(fd, SOMAXCONN) != 0) {
|
||||||
|
mylog(log_warn,"listen fail\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int client_bind_to_a_new_port(int &fd,u32_t local_ip_uint32)//find a free port and bind to it.
|
||||||
|
{
|
||||||
|
int raw_send_port=10000+get_true_random_number()%(65535-10000);
|
||||||
|
for(int i=0;i<1000;i++)//try 1000 times at max,this should be enough
|
||||||
|
{
|
||||||
|
if (try_to_list_and_bind(fd,local_ip_uint32,raw_send_port)==0)
|
||||||
|
{
|
||||||
|
return raw_send_port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mylog(log_fatal,"bind port fail\n");
|
||||||
|
myexit(-1);
|
||||||
|
return -1;////for compiler check
|
||||||
|
}
|
||||||
|
26
network.h
@@ -5,12 +5,13 @@
|
|||||||
* Author: wangyu
|
* Author: wangyu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NETWORK_H_
|
#ifndef UDP2RAW_NETWORK_H_
|
||||||
#define NETWORK_H_
|
#define UDP2RAW_NETWORK_H_
|
||||||
|
|
||||||
extern int raw_recv_fd;
|
extern int raw_recv_fd;
|
||||||
extern int raw_send_fd;
|
extern int raw_send_fd;
|
||||||
extern int seq_mode;
|
extern int seq_mode;
|
||||||
|
extern int max_seq_mode;
|
||||||
extern int filter_port;
|
extern int filter_port;
|
||||||
extern u32_t bind_address_uint32;
|
extern u32_t bind_address_uint32;
|
||||||
extern int disable_bpf_filter;
|
extern int disable_bpf_filter;
|
||||||
@@ -20,6 +21,8 @@ extern int lower_level_manual;
|
|||||||
extern char if_name[100];
|
extern char if_name[100];
|
||||||
extern unsigned char dest_hw_addr[];
|
extern unsigned char dest_hw_addr[];
|
||||||
|
|
||||||
|
extern int random_drop;
|
||||||
|
|
||||||
extern int ifindex;
|
extern int ifindex;
|
||||||
|
|
||||||
struct icmphdr
|
struct icmphdr
|
||||||
@@ -54,6 +57,7 @@ struct packet_info_t //todo change this to union
|
|||||||
|
|
||||||
u32_t seq,ack_seq;
|
u32_t seq,ack_seq;
|
||||||
|
|
||||||
|
u32_t ack_seq_counter;
|
||||||
|
|
||||||
u32_t ts,ts_ack;
|
u32_t ts,ts_ack;
|
||||||
|
|
||||||
@@ -64,6 +68,8 @@ struct packet_info_t //todo change this to union
|
|||||||
|
|
||||||
sockaddr_ll addr_ll;
|
sockaddr_ll addr_ll;
|
||||||
|
|
||||||
|
i32_t data_len;
|
||||||
|
|
||||||
packet_info_t();
|
packet_info_t();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,10 +78,10 @@ struct raw_info_t
|
|||||||
packet_info_t send_info;
|
packet_info_t send_info;
|
||||||
packet_info_t recv_info;
|
packet_info_t recv_info;
|
||||||
|
|
||||||
int last_send_len;
|
//int last_send_len;
|
||||||
int last_recv_len;
|
//int last_recv_len;
|
||||||
|
|
||||||
u32_t reserved_seq;
|
u32_t reserved_send_seq;
|
||||||
//uint32_t first_seq,first_ack_seq;
|
//uint32_t first_seq,first_ack_seq;
|
||||||
|
|
||||||
};//g_raw_info;
|
};//g_raw_info;
|
||||||
@@ -86,8 +92,16 @@ int init_raw_socket();
|
|||||||
void init_filter(int port);
|
void init_filter(int port);
|
||||||
|
|
||||||
void remove_filter();
|
void remove_filter();
|
||||||
int init_ifindex(char * if_name);
|
|
||||||
|
|
||||||
|
int init_ifindex(const char * if_name,int &index);
|
||||||
|
|
||||||
|
int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw);
|
||||||
|
|
||||||
|
int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port); //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip
|
||||||
|
|
||||||
|
int try_to_list_and_bind(int & bind_fd,u32_t local_ip_uint32,int port); //try to bind to a port,may fail.
|
||||||
|
|
||||||
|
int client_bind_to_a_new_port(int & bind_fd,u32_t local_ip_uint32);//find a free port and bind to it.
|
||||||
|
|
||||||
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);
|
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);
|
||||||
|
|
||||||
|