-
-
Save warriorpaw/5371951 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- openvpn-2.2.2.orig/options.c 2011-12-14 00:58:56.000000000 +0800 | |
+++ openvpn-2.2.2/options.c 2012-12-21 10:44:57.683130505 +0800 | |
@@ -54,6 +54,10 @@ | |
#include "memdbg.h" | |
+extern char* _socket_obfs_salt; | |
+extern int _socket_obfs_salt_len; | |
+extern int _socket_obfs_padlen; | |
+ | |
const char title_string[] = | |
PACKAGE_STRING | |
" " TARGET_ALIAS | |
@@ -6008,6 +6012,20 @@ | |
options->persist_mode = 1; | |
} | |
#endif | |
+ else if (streq (p[0], "obfs-salt") && p[1]) | |
+ { | |
+ VERIFY_PERMISSION (OPT_P_GENERAL); | |
+ srand((unsigned)time(NULL)); | |
+ _socket_obfs_salt = p[1]; | |
+ _socket_obfs_salt_len = strlen(_socket_obfs_salt); | |
+ } | |
+ else if (streq (p[0], "obfs-padlen") && p[1]) | |
+ { | |
+ VERIFY_PERMISSION (OPT_P_GENERAL); | |
+ _socket_obfs_padlen = atoi(p[1]); | |
+ if (_socket_obfs_padlen < 0) | |
+ msg(M_ERR, "--obfs-padlen must be positive"); | |
+ } | |
else | |
{ | |
if (file) | |
--- openvpn-2.2.2.orig/socket.c 2011-12-14 00:58:56.000000000 +0800 | |
+++ openvpn-2.2.2/socket.c 2012-12-21 10:44:57.707131191 +0800 | |
@@ -35,6 +35,10 @@ | |
#include "memdbg.h" | |
+const char* _socket_obfs_salt = NULL; | |
+int _socket_obfs_salt_len = 0; | |
+int _socket_obfs_padlen = 0; | |
+ | |
const int proto_overhead[] = { /* indexed by PROTO_x */ | |
IPv4_UDP_HEADER_SIZE, | |
IPv4_TCP_HEADER_SIZE, | |
@@ -42,6 +46,50 @@ | |
IPv4_TCP_HEADER_SIZE | |
}; | |
+/** | |
+ * @return int The length of the random string that should be padding to the packet | |
+ */ | |
+int obfs_padlen(const void* rand) { | |
+ int pad_len; | |
+ unsigned char md[MD5_DIGEST_LENGTH]; | |
+ unsigned char iv[4 + _socket_obfs_salt_len]; | |
+ memcpy(iv, rand, 4); | |
+ memcpy(iv + 4, _socket_obfs_salt, _socket_obfs_salt_len); | |
+ MD5(iv, 4 + _socket_obfs_salt_len, md); | |
+ if (_socket_obfs_padlen <= 0) | |
+ pad_len = 0; | |
+ else | |
+ pad_len = md[9] % _socket_obfs_padlen; | |
+ pad_len++; | |
+ return pad_len; | |
+} | |
+ | |
+void obfs_buffer(const struct buffer* buf, const void* rand) { | |
+ unsigned char md[SHA_DIGEST_LENGTH]; | |
+ unsigned char iv[4 + _socket_obfs_salt_len + SHA_DIGEST_LENGTH]; | |
+ unsigned char *c; | |
+ int i, len; | |
+ | |
+ memcpy(iv, rand, 4); | |
+ memcpy(iv + 4, _socket_obfs_salt, _socket_obfs_salt_len); | |
+ | |
+ SHA1(iv, 4 + _socket_obfs_salt_len, md); | |
+ | |
+ /* Obsfucation data */ | |
+ len = BLEN(buf); | |
+ | |
+ for (i = 0, c = BPTR(buf); i < len; i++, c++) | |
+ { | |
+ *c ^= md[i % SHA_DIGEST_LENGTH]; | |
+ | |
+ if (i % SHA_DIGEST_LENGTH == SHA_DIGEST_LENGTH - 1) | |
+ { | |
+ memcpy(iv, md, SHA_DIGEST_LENGTH); | |
+ SHA1(iv, SHA_DIGEST_LENGTH, md); | |
+ } | |
+ } | |
+} | |
+ | |
/* | |
* Convert sockflags/getaddr_flags into getaddr_flags | |
*/ | |
--- openvpn-2.2.2.orig/socket.h 2011-12-14 00:58:56.000000000 +0800 | |
+++ openvpn-2.2.2/socket.h 2013-01-24 10:48:37.559033278 +0800 | |
@@ -36,6 +36,11 @@ | |
#include "socks.h" | |
#include "misc.h" | |
+extern int _socket_obfs_salt_len; | |
+extern int _socket_obfs_padlen; | |
+ | |
+void obfs_buffer(const struct buffer* buf, const void* rand); | |
+int obfs_padlen(const void* rand); | |
/* | |
* OpenVPN's default port number as assigned by IANA. | |
*/ | |
@@ -740,28 +745,60 @@ | |
int maxsize, | |
struct link_socket_actual *from) | |
{ | |
+ int res; | |
+ | |
+ struct buffer tbuf; | |
+ | |
+ | |
if (sock->info.proto == PROTO_UDPv4) | |
{ | |
- int res; | |
- | |
#ifdef WIN32 | |
res = link_socket_read_udp_win32 (sock, buf, from); | |
#else | |
res = link_socket_read_udp_posix (sock, buf, maxsize, from); | |
#endif | |
- return res; | |
} | |
else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) | |
{ | |
/* from address was returned by accept */ | |
from->dest.sa = sock->info.lsa->actual.dest.sa; | |
- return link_socket_read_tcp (sock, buf); | |
+ res = link_socket_read_tcp (sock, buf); | |
} | |
else | |
{ | |
ASSERT (0); | |
return -1; /* NOTREACHED */ | |
} | |
+ | |
+ /* Decode obsfucated traffic */ | |
+ if (_socket_obfs_salt_len > 0 && BLEN(buf) > 4) | |
+ { | |
+ int r; | |
+ int pad_len = 0; | |
+ | |
+ memcpy((void*)&r, BPTR(buf)+BLEN(buf)-4, 4); | |
+ r ^= 0x5f3759df; | |
+ msg(M_DEBUG, "1, read buflen=%d rand=%d", BLEN(buf),r); | |
+ | |
+ pad_len = obfs_padlen(&r); | |
+ tbuf = alloc_buf(BLEN(buf) - 4); | |
+ buf_copy_range(&tbuf, 0, buf, 0, BLEN(buf) - 4); | |
+ obfs_buffer(&tbuf, &r); | |
+ /* Remove padding random string */ | |
+ buf_clear(buf); | |
+ buf_prepend(buf, BLEN(&tbuf) - pad_len); | |
+ buf_copy_range(buf, 0, &tbuf, pad_len, BLEN(&tbuf) - pad_len); | |
+ | |
+ msg(M_DEBUG, "1, read buflen=%d, padlen=%d", BLEN(buf), pad_len); | |
+ | |
+ free_buf(&tbuf); | |
+ | |
+ res -= 4; | |
+ res -= pad_len; | |
+ | |
+ } | |
+ | |
+ return res; | |
} | |
/* | |
@@ -846,6 +883,37 @@ | |
struct buffer *buf, | |
struct link_socket_actual *to) | |
{ | |
+ struct buffer tbuf; | |
+ | |
+ /* Obsfucate traffic */ | |
+ if (_socket_obfs_salt_len > 0) | |
+ { | |
+ int pad_len, i; | |
+ int r = rand(),tmp; | |
+ | |
+ msg(M_DEBUG, "1, write buflen=%d rand=%d", BLEN(buf),r); | |
+ pad_len = obfs_padlen(&r); | |
+ | |
+ tbuf = alloc_buf(BLEN(buf) + 4 + pad_len); | |
+ for (i = 0; i < pad_len; i++) | |
+ { | |
+ if (unlikely(i % 4 == 0)) | |
+ tmp = rand(); | |
+ | |
+ buf_write(&tbuf, (void*)&tmp + i % 4, 1); | |
+ } | |
+ buf_copy_range(&tbuf, pad_len, buf, 0, BLEN(buf)); | |
+ obfs_buffer(&tbuf, &r); | |
+ r ^= 0x5f3759df; | |
+ buf_write(&tbuf, (void*)&r, 4); | |
+ buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf)); | |
+ | |
+ msg(M_DEBUG, "2, write buflen=%d padlen=%d", BLEN(buf),pad_len); | |
+ | |
+ free_buf(&tbuf); | |
+ } | |
+ | |
+ | |
if (sock->info.proto == PROTO_UDPv4) | |
{ | |
return link_socket_write_udp (sock, buf, to); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
您好,我试了您这个,但是UDP模式下连接还是会断流,断一会又恢复了,恢复完又断流了,有什么解决办法么?