Compare commits

..

261 Commits

Author SHA1 Message Date
Darien Raymond
fc81b0aae2 config for inbound tag routing 2016-11-13 21:23:34 +01:00
Darien Raymond
b49f76cd1c fix tcp reading 2016-11-13 21:05:40 +01:00
Darien Raymond
9471b5b066 refine dispatcher 2016-11-13 14:33:00 +01:00
Darien Raymond
5dc05d6352 allow outbound to be proxied 2016-11-10 23:41:28 +01:00
Darien Raymond
e30f466424 update deploy key 2016-11-09 21:58:49 +01:00
Darien Raymond
2e0d54fd4c fix routing config on source IP 2016-11-09 10:56:15 +01:00
Darien Raymond
d343cb1ee6 proxy connection 2016-11-09 00:17:09 +01:00
Darien Raymond
7a09fcdc2f increase kcp ack frequency 2016-11-08 00:35:14 +01:00
Darien Raymond
b0d009664a Fix HTTP serialization 2016-11-07 10:47:30 +01:00
Darien Raymond
3d2431d21c update test data 2016-11-07 10:38:43 +01:00
Darien Raymond
d04e145442 Update version 2016-11-06 21:05:19 +01:00
Darien Raymond
d75cb28413 fix tcp encoding 2016-11-06 21:04:56 +01:00
Darien Raymond
9f68062d48 refine http header parsing 2016-11-06 15:48:25 +01:00
Darien Raymond
d70b997d84 test case for shadowsocks UDP 2016-11-06 14:32:04 +01:00
Darien Raymond
dc0cbce6e1 optimize pickString 2016-11-06 14:04:44 +01:00
Darien Raymond
edc5bbbb72 add more default headers 2016-11-06 13:55:06 +01:00
Darien Raymond
66e8090d3a update http header 2016-11-06 13:38:32 +01:00
Darien Raymond
805bbe5fe4 default user agent strings 2016-11-06 00:42:54 +01:00
Darien Raymond
31be091a55 simplify http header parsing 2016-11-05 15:14:55 +01:00
Darien Raymond
f108633e2e ssr compatibility 2016-11-05 01:50:51 +01:00
Darien Raymond
d2263a452d update http header json config 2016-11-05 01:28:15 +01:00
Darien Raymond
dfc03ff939 support noop connection auth 2016-11-05 01:15:32 +01:00
Darien Raymond
13dde1799d comments 2016-11-05 01:01:46 +01:00
Darien Raymond
c84629c374 add shadowsocks in json config 2016-11-05 01:01:30 +01:00
Darien Raymond
817cc8d82e fix shadowsocks conf 2016-11-05 01:01:07 +01:00
Darien Raymond
13ab2622c5 shadowsocks test 2016-11-05 01:00:54 +01:00
Darien Raymond
0727aa0da9 simplify imports 2016-11-05 01:00:20 +01:00
Darien Raymond
3a15f799c2 prevent deadlock in shadowsocks 2016-11-05 01:00:09 +01:00
Darien Raymond
bae0de7d95 test case for http auth 2016-11-04 21:59:19 +01:00
Darien Raymond
80312627c4 fix typo 2016-11-04 10:49:43 +01:00
Darien Raymond
3d167a6855 json config for http header 2016-11-04 10:49:18 +01:00
Darien Raymond
010f34c76c allow single side auth 2016-11-03 23:14:27 +01:00
Darien Raymond
0747203132 refine http header 2016-11-02 22:26:21 +01:00
Darien Raymond
1600a59254 enable tcp for shadowsocks server 2016-11-02 22:19:01 +01:00
Darien Raymond
c5a92e00ef dont reuse shadowsock connections 2016-11-02 22:18:25 +01:00
Darien Raymond
68b85cce60 remove unused code 2016-11-02 16:42:02 +01:00
Darien Raymond
9d2407f4e4 fix test break 2016-11-02 16:41:02 +01:00
Darien Raymond
cdb0debcb0 register shadowsocks client factory 2016-11-02 16:38:09 +01:00
Darien Raymond
5f3f173b5e shadowsocks client factory 2016-11-02 16:33:04 +01:00
Darien Raymond
35aa16d40d refine shadowsocks user 2016-11-02 16:22:29 +01:00
Darien Raymond
de4836c720 refine ota settings in conf 2016-11-02 16:21:20 +01:00
Darien Raymond
63d3c9fa30 typo 2016-11-02 16:18:29 +01:00
Darien Raymond
687e008c9a refine shadowsocks ota settings 2016-11-02 16:17:57 +01:00
Darien Raymond
43dacc3936 remove small buffer pool 2016-11-01 12:37:35 +01:00
Darien Raymond
aabb9137e1 remove unused code 2016-11-01 12:34:07 +01:00
Darien Raymond
33d2513e3c reduce memory allocation in kcp 2016-11-01 12:07:20 +01:00
Darien Raymond
5b58066345 use local buffer in UDP hub 2016-11-01 11:46:34 +01:00
Darien Raymond
d3f323e24b response factory 2016-11-01 00:42:55 +01:00
Darien Raymond
187688cacb fix type def 2016-11-01 00:42:44 +01:00
Darien Raymond
72339a3509 fix TCP conn reuse with tls 2016-11-01 00:41:46 +01:00
Darien Raymond
ac3b91a877 http authenticator 2016-10-31 22:26:46 +01:00
Darien Raymond
5e1c6fe816 bug fix 2016-10-31 16:46:47 +01:00
Darien Raymond
a54c39b4ac config for shadowsocks 2016-10-31 16:46:15 +01:00
Darien Raymond
c221802963 shadowsocks client 2016-10-31 16:35:18 +01:00
Darien Raymond
be4f3d0772 refine shadowsocks server 2016-10-31 15:24:28 +01:00
Darien Raymond
fbb44e7e02 fix string checking logic 2016-10-24 16:59:43 +02:00
Darien Raymond
369256c82f include user when dispatch requests in VMess. 2016-10-24 16:57:16 +02:00
Darien Raymond
531be77a59 remove test case depending on external resources 2016-10-24 16:49:41 +02:00
Darien Raymond
97dc7b30de remove test cases depending on external resources 2016-10-24 16:48:16 +02:00
Darien Raymond
360c222c1c try again to skip coverage on release 2016-10-24 16:45:02 +02:00
Darien Raymond
1fb9a911cd workaround travis issue 2016-10-24 16:42:28 +02:00
Darien Raymond
6006fd9ca7 Update version 2016-10-24 15:09:24 +02:00
Darien Raymond
59fa064cae default log settings 2016-10-24 15:08:06 +02:00
Darien Raymond
3373e62193 Merge branch 'master' of https://github.com/v2ray/v2ray-core 2016-10-24 15:04:23 +02:00
Darien Raymond
2c2c569c77 Update to Go 1.7.3 2016-10-24 14:13:21 +02:00
Darien Raymond
687ae6c50e chunk writer 2016-10-21 00:33:23 +02:00
Darien Raymond
35ba8710e0 fix ip check in ipnet 2016-10-19 15:38:31 +02:00
Darien Raymond
a7ef82ffbc fix test break 2016-10-19 12:01:11 +02:00
Darien Raymond
ca980f5718 json conf for source session in router 2016-10-18 23:14:48 +02:00
Darien Raymond
aae99a8e98 use session in router 2016-10-18 23:01:39 +02:00
Darien Raymond
f37b04a690 per connection stream settings 2016-10-18 21:57:40 +02:00
Darien Raymond
e13c97d162 rename IP to CIDR in router 2016-10-18 16:42:22 +02:00
Darien Raymond
2af4b16913 remove string list 2016-10-18 16:10:50 +02:00
Darien Raymond
2320bc3304 remove unused code 2016-10-18 15:31:48 +02:00
Darien Raymond
751a105324 comments 2016-10-18 15:31:39 +02:00
Darien Raymond
b3bbd80674 fix json parser for IPv6 routing 2016-10-18 11:36:45 +02:00
Darien Raymond
4e80ed05d9 comments 2016-10-18 10:31:39 +02:00
Darien Raymond
426a58707f skip coverage for releases 2016-10-18 10:28:37 +02:00
Darien Raymond
9b4d9cf0e7 nil pointer 2016-10-18 10:04:15 +02:00
Darien Raymond
f049b3cc2b comments 2016-10-18 00:12:09 +02:00
Darien Raymond
b81d091fb8 comments 2016-10-18 00:09:49 +02:00
Darien Raymond
9bd8822668 unused proto 2016-10-18 00:09:41 +02:00
Darien Raymond
ad59e56925 default send through value 2016-10-18 00:02:41 +02:00
Darien Raymond
4a67587873 fix geoip 2016-10-17 16:35:18 +02:00
Darien Raymond
8b936bc816 fix release binary 2016-10-17 15:52:07 +02:00
Darien Raymond
9ae4611eac fix file name for openbsd 2016-10-17 15:23:45 +02:00
Darien Raymond
14996da74a Update version 2016-10-17 14:55:58 +02:00
Darien Raymond
7a14f646ee gofmt 2016-10-17 14:44:06 +02:00
Darien Raymond
67d597af95 openbsd release 2016-10-17 14:41:54 +02:00
Darien Raymond
5a311cbe08 json config parser 2016-10-17 14:35:13 +02:00
Darien Raymond
e866ff24a4 refine app settings in v2ray config 2016-10-16 16:04:30 +02:00
Darien Raymond
e33b7df34c remove use of any 2016-10-16 14:22:21 +02:00
Darien Raymond
5d9e6b0799 json reference 2016-10-16 00:46:30 +02:00
Darien Raymond
39939b00f0 outbound config 2016-10-16 00:46:08 +02:00
Darien Raymond
be4cfdf61c add tls 2016-10-16 00:45:35 +02:00
Darien Raymond
be026870f7 protogen update 2016-10-16 00:23:27 +02:00
Darien Raymond
348893a02a register protobuf config loader 2016-10-14 23:42:14 +02:00
Darien Raymond
35a0ed6fb4 config loader 2016-10-14 23:41:41 +02:00
Darien Raymond
84f660bbbc update main code 2016-10-14 23:41:17 +02:00
Darien Raymond
8ad04f911d all references 2016-10-14 23:41:06 +02:00
Darien Raymond
0a32345af9 protobuf for v2ray config 2016-10-14 22:21:45 +02:00
Darien Raymond
f87d7f36f5 check nil settings 2016-10-14 21:19:45 +02:00
Darien Raymond
f488a63d97 check nil config 2016-10-14 21:19:26 +02:00
Darien Raymond
b060bb3b94 refactor proxy config cache 2016-10-13 11:14:24 +02:00
Darien Raymond
d26ee5441e fix authenticator config 2016-10-12 22:43:17 +02:00
Darien Raymond
fc6a706166 refactor protos 2016-10-12 18:43:55 +02:00
Darien Raymond
c1f91567ad refactor shell 2016-10-12 16:46:02 +02:00
Darien Raymond
22ef12a456 simplify router 2016-10-12 16:11:13 +02:00
Darien Raymond
63f3108737 protobuf for router 2016-10-11 23:02:44 +02:00
Darien Raymond
ab3173039b increase ping interval 2016-10-11 21:21:06 +02:00
Darien Raymond
b5910dccae simplify fast resend 2016-10-11 13:17:57 +02:00
Darien Raymond
f8ad1f4a3e update predicate syntax 2016-10-11 12:44:17 +02:00
Darien Raymond
da9f1a8013 predicate.Not 2016-10-11 12:30:53 +02:00
Darien Raymond
f3a83c57ab optimize ping and updater logic 2016-10-11 12:24:19 +02:00
Darien Raymond
78f87c4f60 test case for cmd only segment 2016-10-11 11:44:30 +02:00
Darien Raymond
e023859ef0 stop data updating thread when there is no data 2016-10-10 16:50:54 +02:00
Darien Raymond
5f920a9e94 protobuf for log config 2016-10-03 22:07:28 +02:00
Darien Raymond
bd9b7c586e remove unnecessary code in main 2016-10-03 21:37:09 +02:00
Darien Raymond
67793eb3e0 fix config creator cache 2016-10-03 12:25:36 +02:00
Darien Raymond
fd50e8e12b allow stdin as input source 2016-10-03 11:18:24 +02:00
Darien Raymond
1ee76d31fa Update version 2016-10-03 10:54:27 +02:00
Darien Raymond
1d13f47f9c protobuf for stream settings 2016-10-02 23:43:58 +02:00
Darien Raymond
5ec948f690 integrate tls settings in ws 2016-09-30 16:53:40 +02:00
Darien Raymond
af6abfa3e3 update proto generated code 2016-09-26 15:14:39 +02:00
Darien Raymond
91f2a40dae refine proto package names 2016-09-26 15:14:16 +02:00
Darien Raymond
922e761bef rename server spec user 2016-09-25 22:57:27 +02:00
Darien Raymond
c5f09c64a2 refine socks config 2016-09-25 22:54:18 +02:00
Darien Raymond
c6a7389817 refine cipher settings 2016-09-25 22:19:49 +02:00
Darien Raymond
ce5bc72f0c refine shadowsocks proto 2016-09-25 22:07:32 +02:00
Darien Raymond
5e9017720e check nil 2016-09-24 23:36:26 +02:00
Darien Raymond
24e575f2cd protobuf for vmess 2016-09-24 23:11:58 +02:00
Darien Raymond
60f4292882 protobuf for dokodemo config 2016-09-22 16:49:20 +02:00
Darien Raymond
88ae8248a5 protobuf for network list 2016-09-22 12:14:50 +02:00
Darien Raymond
dc6b7e2e75 protobuf for blackhole config 2016-09-22 12:01:36 +02:00
Darien Raymond
6317768cab use golang 1.7.1 2016-09-21 21:08:22 +02:00
Darien Raymond
b28d718b79 optional field in kcp config 2016-09-21 21:08:05 +02:00
Darien Raymond
1a3f51ade7 protobuf for kcp config 2016-09-21 14:39:07 +02:00
Darien Raymond
8f6a972970 refactor config cache 2016-09-21 13:52:16 +02:00
Darien Raymond
d38e62932d proto for dns config 2016-09-20 16:05:35 +02:00
Darien Raymond
7de7588ec2 proto for destination 2016-09-20 11:53:05 +02:00
Darien Raymond
c518726910 network proto 2016-09-20 10:44:44 +02:00
Darien Raymond
fbdb1e09d7 remove incorrect check on config name 2016-09-19 23:54:48 +02:00
Darien Raymond
9ade07db03 remove IsTCP() and IsUDP() 2016-09-19 16:39:11 +02:00
Darien Raymond
5291624165 format log 2016-09-19 14:41:58 +02:00
Darien Raymond
5f5d28009f fix typo in utp def 2016-09-19 14:41:54 +02:00
Darien Raymond
28432cfd4c Update version 2016-09-19 11:52:48 +02:00
Darien Raymond
9ad96949b0 Update version 2016-09-19 11:23:03 +02:00
Darien Raymond
8b37edd02d format log 2016-09-18 00:46:16 +02:00
Darien Raymond
d08cba000f accounts in protobuf 2016-09-18 00:41:21 +02:00
Darien Raymond
3423adaea4 fix test break 2016-08-29 12:25:16 +02:00
Darien Raymond
7a31e7a0c2 fix test break 2016-08-29 12:23:17 +02:00
Darien Raymond
7f2ba0d106 remove unnecessary code 2016-08-28 23:47:39 +02:00
Darien Raymond
948f04921d update socks code for server config 2016-08-28 23:46:50 +02:00
Darien Raymond
ea2c491ade global proto gen 2016-08-28 23:41:51 +02:00
Darien Raymond
11e310298c proto for socks server 2016-08-28 23:41:45 +02:00
Darien Raymond
0f74c618de close input stream early 2016-08-28 12:01:37 +02:00
Darien Raymond
9b72d3cbd7 simplify socks transport 2016-08-28 11:59:03 +02:00
Darien Raymond
bd4ca7b37f remote protobuf code from coverage 2016-08-27 12:00:51 +02:00
Darien Raymond
cdb4c56546 protobuf for net 2016-08-27 00:04:35 +02:00
Darien Raymond
64e38ba851 update chinaip 2016-08-25 22:17:57 +02:00
Darien Raymond
bbca180dba try protobuf 2016-08-25 21:55:49 +02:00
Darien Raymond
04d956462c fix test without -json tag 2016-08-25 13:25:59 +02:00
Darien Raymond
3fd66ad795 remove PingNecessary() 2016-08-25 12:00:31 +02:00
Darien Raymond
e49fb2f50d no compacting buffers 2016-08-25 11:41:05 +02:00
Darien Raymond
59125f665b allow env speicified buffer size 2016-08-25 11:21:32 +02:00
Darien Raymond
fcad4aa212 adjust receiving buffer size 2016-08-25 09:45:56 +02:00
Darien Raymond
0da987ec43 refine buffer size 2016-08-25 00:04:54 +02:00
Darien Raymond
2ae8e5d033 rename buffer size 2016-08-24 23:54:39 +02:00
Darien Raymond
2839ce7a88 simplify receiving worker 2016-08-24 23:51:53 +02:00
Darien Raymond
5d20e3f70b remove sending queue 2016-08-24 15:47:14 +02:00
Darien Raymond
e6e0419958 format private annotation 2016-08-24 11:17:42 +02:00
Darien Raymond
a9da266bf9 update default in-fligh size 2016-08-24 07:50:33 +02:00
Darien Raymond
98025e1457 change default kcp.tti to 50 2016-08-23 23:32:36 +02:00
Darien Raymond
85c5171d8d update deploy key 2016-08-22 23:09:25 +02:00
Darien Raymond
e7bf0c2e49 fix install script 2016-08-21 18:02:12 +02:00
Darien Raymond
8eab746c96 doc 2016-08-21 09:06:15 +02:00
Darien Raymond
fdeb8b4f89 update file paths 2016-08-20 21:03:50 +02:00
v2ray
07a86f549b unified import path 2016-08-20 20:55:45 +02:00
v2ray
6a878432dc Update version 2016-08-20 20:40:24 +02:00
v2ray
d08ffedf48 reduce ping frequency 2016-08-20 11:33:22 +02:00
v2ray
0a34ec0be6 prepare for 2.0 2016-08-20 09:37:08 +02:00
v2ray
7a1bdfcf00 test case for passive connection 2016-08-20 09:12:44 +02:00
v2ray
2268f3d1bc remove import path restriction 2016-08-19 17:05:15 +02:00
v2ray
d83a0ce5d2 Apply new read function to UDP hub. 2016-08-19 13:00:55 +02:00
v2ray
55e5268ce8 Fix UDP reading on Windows 2016-08-19 12:58:26 +02:00
v2ray
ad1353ac2f merge similar error definitions 2016-08-18 08:34:21 +02:00
v2ray
786775ea80 fix build break 2016-08-18 08:24:47 +02:00
v2ray
39737f6fc1 merge bad configuration error 2016-08-18 08:21:20 +02:00
v2ray
933e244d92 value receiver for StringList.Len() 2016-08-18 07:56:31 +02:00
v2ray
89a876a6d4 rename proxy/internal to proxy/registry 2016-08-17 23:30:15 +02:00
v2ray
d9884b4010 format import 2016-08-17 23:14:13 +02:00
v2ray
8ecec9b49d format log 2016-08-17 23:12:10 +02:00
v2ray
bb3ceb3d7b simplify case 2016-08-17 23:05:47 +02:00
v2ray
49056d9942 Merge branch 'master' of https://github.com/v2ray/v2ray-core 2016-08-17 15:25:40 +02:00
Darien Raymond
8951c4da71 comment 2016-08-17 10:05:53 +00:00
v2ray
99a63f1633 reset timer before benchmark 2016-08-17 10:28:30 +02:00
v2ray
99821dc2fb change to wait group 2016-08-16 17:00:04 +02:00
v2ray
125ef8372c actually follow redirect of UDP 2016-08-16 13:04:07 +02:00
v2ray
41d89e6d1e skip test requires root permission 2016-08-16 09:01:58 +02:00
v2ray
9876844296 fix test break 2016-08-16 08:37:38 +02:00
v2ray
a83009afc4 update to 1.7 2016-08-16 08:37:18 +02:00
v2ray
7bc94d55c6 need sudo permission 2016-08-15 23:11:48 +02:00
v2ray
6417adb56d correctly get sys fd from udp conn 2016-08-15 23:11:01 +02:00
v2ray
d025b8d48f fix test break 2016-08-15 23:02:03 +02:00
v2ray
0bca6e8657 fix kcp listener 2016-08-15 22:20:16 +02:00
v2ray
a5a70afdb8 remove port testing 2016-08-15 22:12:11 +02:00
v2ray
338dc1ebb6 remove unused deps 2016-08-15 21:51:51 +02:00
v2ray
c7871a3ab2 test case for socket opt 2016-08-15 21:33:32 +02:00
v2ray
2a778762b1 rename udp.go to hub.go 2016-08-15 21:33:21 +02:00
Darien Raymond
667b71aad0 Merge pull request #238 from xiaokangwang/websocket
Websocket transport support for v2ray
2016-08-15 17:45:25 +02:00
v2ray
210a32dc12 support udp redirection 2016-08-15 17:44:46 +02:00
Shelikhoo
22519353c3 Check Read 2016-08-15 21:55:43 +08:00
Shelikhoo
32e8deb6e8 Simplify Design 2016-08-15 21:36:37 +08:00
Shelikhoo
45d801b922 WsTest:more case 2016-08-15 21:29:15 +08:00
Shelikhoo
6c8b4f5db3 Fix 2016-08-15 21:21:09 +08:00
Shelikhoo
d7440bb1d6 Test:listen tls 2016-08-15 21:19:53 +08:00
Shelikhoo
856f2a2dd3 Fix assert fail 2016-08-15 21:19:15 +08:00
Shelikhoo
4b9e506dba Added Testing Cert 2016-08-15 21:18:48 +08:00
Shelikhoo
f7ce9d3be6 Add Developer Insecure Skip Verify for testing 2016-08-15 20:42:38 +08:00
v2ray
956b47f6ae release connection after all data read in freedom 2016-08-15 14:31:46 +02:00
Shelikhoo
02e3c17c97 test:listen 2016-08-15 20:20:47 +08:00
Shelikhoo
40ec84e222 Dial test 2016-08-15 20:15:12 +08:00
Shelikhoo
2209294dfc Set reuse limit 2016-08-15 20:14:45 +08:00
Shelikhoo
0a49628555 Bettering ping method 2016-08-15 19:13:18 +08:00
Shelikhoo
e382eaa59f typo 2016-08-15 18:59:50 +08:00
Shelikhoo
4c093a2107 Apply coding style 2016-08-15 18:59:14 +08:00
Shelikhoo
a5ae6a0f4e Remove workaround 2016-08-15 18:57:39 +08:00
Shelikhoo
bfb4e0d9b0 Apply coding style 2016-08-15 18:56:33 +08:00
Shelikhoo
273c8f6c57 Support Stop listener 2016-08-15 18:47:44 +08:00
Shelikhoo
062d05fdcf Added Stoppable listener for TLS listener 2016-08-15 18:43:17 +08:00
v2ray
66bb7879e0 handle empty payload in freedom and outbound 2016-08-15 12:23:35 +02:00
Shelikhoo
c8cd1320c7 Use stopable listener for HTTP 2016-08-15 18:17:29 +08:00
Shelikhoo
a36582b294 Added stopable listener 2016-08-15 18:16:54 +08:00
Shelikhoo
863237b518 Justify lock use 2016-08-15 17:53:11 +08:00
Shelikhoo
4853a1a6d3 Increase ping time 2016-08-15 17:48:30 +08:00
Shelikhoo
de28198234 Guess protocol 2016-08-15 17:47:15 +08:00
Shelikhoo
7b3cf631c2 Removed inaccessable doc 2016-08-15 17:40:56 +08:00
Shelikhoo
ee22082fb4 Fix host bug 2016-08-15 14:30:38 +08:00
Shelikhoo
00aeb29e46 typo 2016-08-15 12:31:55 +08:00
Shelikhoo
2bf9edfe7d Prevent unnesessary log 2016-08-15 12:23:15 +08:00
Shelikhoo
d250013c99 Increase conn keep-alive time 2016-08-15 11:07:29 +08:00
Shelikhoo
d06c75f926 Doc sync to code change 2016-08-15 10:25:20 +08:00
Shelikhoo
7259b3363b Merge branch 'master' into websockwt 2016-08-15 10:17:22 +08:00
Shelikhoo
fed2933043 fix crash 2016-08-14 20:41:26 +08:00
Shelikhoo
5e576e11bb fix crash 2016-08-14 20:40:59 +08:00
Shelikhoo
49441a5050 Docs 2016-08-14 14:11:51 +08:00
Shelikhoo
a0fda39274 Fix crash 2016-08-14 11:06:39 +08:00
Shelikhoo
3e9e9b520e Remove useless test 2016-08-14 09:23:24 +08:00
Shelikhoo
1fe090dbfd Verfiy Domain correctly 2016-08-13 22:50:24 +08:00
Shelikhoo
427bed5ddb typo~ 2016-08-13 22:07:47 +08:00
Shelikhoo
16b529093d Support Listen WebSocket with TLS 2016-08-13 21:56:51 +08:00
Shelikhoo
fecf9cc5b8 Added WebSocket transport 2016-08-13 21:44:36 +08:00
Shelikhoo
7ef66c57dc Support Listen WebSocket Connection 2016-08-13 21:43:46 +08:00
Shelikhoo
29f69d63c4 Support Dial WebSocket Connection 2016-08-13 21:42:56 +08:00
Shelikhoo
20f16309e6 Load Websocket Streamtype from json 2016-08-13 21:42:18 +08:00
Shelikhoo
0d60d2449a Add Websocket Stream type 2016-08-13 21:41:13 +08:00
Shelikhoo
2eced2bd6c Load Configure from json 2016-08-13 21:39:34 +08:00
Shelikhoo
8c4a6d94f9 WS Conf structure 2016-08-13 21:37:17 +08:00
Shelikhoo
8c96b1961b load ws transport on init 2016-08-13 21:35:31 +08:00
Shelikhoo
508f79f95f Advertise WS cap 2016-08-13 21:33:34 +08:00
Shelikhoo
cb1356be75 Register ws network 2016-08-13 21:32:47 +08:00
407 changed files with 12596 additions and 13306 deletions

View File

@@ -1,37 +1,34 @@
language: go
go:
- 1.6.3
- 1.7.3
go_import_path: v2ray.com/core
git:
depth: 5
script:
- go test -tags json github.com/v2ray/v2ray-core/...
- go test -tags json v2ray.com/core/...
after_success:
- ./testing/coverage/coverall
- ./testing/coverage/coverall
before_deploy:
- rvm 1.9.3 do gem install mime-types -v 2.6.2
- "./tools/release/release-ci.sh"
- ./tools/release/release-ci.sh
- gem install octokit -v 4.3.0
deploy:
provider: releases
api_key:
secure: "Nbno1ibFpq0DC6y0mkN6NFTbDQinRAEQo2Jl5lvsbiaX9m4CK59xG8XOcmZ3mqqdeioj6m9X5BVe2UtCZjmXmnyPq0FYNFHAPTfd2VrcOpi0fWLD9ndTYAsqjxrqPGK62XVjPbG8U2pGdq2yCOb0qQ9DlahDhVIMzQ/GYuRDps25fPGftepdPwlrwOfYCIvAHoi3GEozuS67WNEx/YtmZTce/2Qebdmwf44hUNaQibeXEspu9wQcp9M/i7aTuX/tUbn7rVCQ4TfoIJU1C1qKedUw0QYMjqP08Wn6UjwwhbblsJKFv8Kc0nx+i2K9CvvLyaBBIVY2Ggxj4Niy+X4VbyWWzdKx+0FXlmKh3U/hJdMZU3OrnwliBns2X3tCHSq7/+7ynLs3UZ4wCkCl7rQYucJ2mlvGquohQV6MX2vjl73y+pYljf+PKYbSDBb7iUOjllisRD+HmDmGQl81BvdEpN/K/BlfsTwHoHxsALSTjRljSngH51SUvjnaVbi/JolJ3lomTr1vCHl4WUiQVLnh7O2Cg7QLNMNieoblnh9yDQG9wC4xuzOJ/AaxRd/pRZMeIooQ1zsHOe+47C1YAep88b+9xtRqVMozAjk/XgNzWjuT2R8G7lZDq0mL9VajD/NUjM3Yrswoft9A3DRmR+lIFJR+fJb8tNf+k1OczE4lesg="
api_key:
secure: h7P6y7jHe0yALKgXb9HyPAlE6JPOB/BiScMlqsG6MUF0G29JrEjcDXh/jZm8HB82OfUG3zPBtr5m0P3LUoM60EQQ96/yE9KKrhEBeyF+E9CAOUHx7Ar4XDR7dG7/Wv+q3ZRFl+4CB5f7xbt9qlobqXkeffngeu9RNWngqVvbyTWIZclx7NYl5haf/hhqGcX2OPKQQfjvOsnP+uLmqiRJBbaYQMzPmvjaQJ9cB6Z11ctJqunk3bN89nV86uaHLqmz8nfk3/J7RjdeT0mqgRYVwfMavZifGPISlgsZd7N0PqiiWB7gZqzjbiSCur+PtnVScYfTlfNoRP+XJtVx3OFnepffSvyE6zOP20MEINAMOgME68Zzkaab8JnDVwj0eTsPNEDpK+E+RUZ1IkaAvVZ19L0qNYwO6bP8koUI4cFDI45srcx0o5xC7Hzz1eaSm5ZJZ3iwwzFZE2vFm83pcQilopG0E7gTYyB+fk0x6sca5MY1PhHAByvBbvYhsCBV4x4o0N1lD1V3QXhvljJL4qieFybwg8g0hdUNeSrm2+NxPqKpEHUQWQFGsl0OGMy2Ji6u/NG5tSvfWKUUsXpkueyutvfTb9D94Xk4s1eNGMG+BHFIGHRTZzX6XXB7/j3zObWApD3h8SIbXjfL0mLaKaBeMyLwf2tlsKTgzwEjvIzcNfQ=
file:
- "$GOPATH/bin/v2ray-macos.zip"
- "$GOPATH/bin/v2ray-windows-64.zip"
- "$GOPATH/bin/v2ray-windows-32.zip"
- "$GOPATH/bin/v2ray-linux-64.zip"
- "$GOPATH/bin/v2ray-linux-32.zip"
- "$GOPATH/bin/v2ray-linux-arm.zip"
- "$GOPATH/bin/v2ray-linux-arm64.zip"
- "$GOPATH/bin/v2ray-linux-mips64.zip"
- "$GOPATH/bin/v2ray-freebsd-64.zip"
- "$GOPATH/bin/v2ray-freebsd-32.zip"
- "$GOPATH/bin/metadata.txt"
- $GOPATH/bin/v2ray-macos.zip
- $GOPATH/bin/v2ray-windows-64.zip
- $GOPATH/bin/v2ray-windows-32.zip
- $GOPATH/bin/v2ray-linux-64.zip
- $GOPATH/bin/v2ray-linux-32.zip
- $GOPATH/bin/v2ray-linux-arm.zip
- $GOPATH/bin/v2ray-linux-arm64.zip
- $GOPATH/bin/v2ray-linux-mips64.zip
- $GOPATH/bin/v2ray-freebsd-64.zip
- $GOPATH/bin/v2ray-freebsd-32.zip
- $GOPATH/bin/v2ray-openbsd-64.zip
- $GOPATH/bin/v2ray-openbsd-32.zip
- $GOPATH/bin/metadata.txt
skip_cleanup: true
on:
tags: true

View File

@@ -2,5 +2,12 @@
{
"editor.tabSize": 2,
"go.buildTags": "json"
"go.buildTags": "json",
"protoc": {
"options": [
"--proto_path=$GOPATH/src/",
"--proto_path=$GOPATH/src/github.com/google/protobuf/src"
]
}
}

4
.vscode/tasks.json vendored
View File

@@ -6,7 +6,7 @@
"tasks": [
{
"taskName": "build",
"args": ["-tags", "json", "github.com/v2ray/v2ray-core/..."],
"args": ["-tags", "json", "v2ray.com/core/..."],
"isBuildCommand": true,
"problemMatcher": {
"owner": "go",
@@ -21,7 +21,7 @@
},
{
"taskName": "test",
"args": ["-tags", "json", "github.com/v2ray/v2ray-core/..."],
"args": ["-tags", "json", "v2ray.com/core/..."],
"isBuildCommand": false
}
]

View File

@@ -5,10 +5,10 @@
[2]: https://travis-ci.org/v2ray/v2ray-core "Travis-CI Build Status"
[3]: https://codecov.io/github/v2ray/v2ray-core/coverage.svg?branch=master "Coverage badge"
[4]: https://codecov.io/github/v2ray/v2ray-core?branch=master "Codecov Status"
[5]: https://goreportcard.com/badge/github.com/v2ray/v2ray-core "Go Report badge"
[6]: https://goreportcard.com/report/github.com/v2ray/v2ray-core "Go Report"
[7]: https://godoc.org/github.com/v2ray/v2ray-core?status.svg "GoDoc badge"
[8]: https://godoc.org/github.com/v2ray/v2ray-core "GoDoc"
[5]: https://goreportcard.com/badge/v2ray.com/core "Go Report badge"
[6]: https://goreportcard.com/report/v2ray.com/core "Go Report"
[7]: https://godoc.org/v2ray.com/core?status.svg "GoDoc badge"
[8]: https://godoc.org/v2ray.com/core "GoDoc"
[9]: https://codebeat.co/badges/f2354ca8-3e24-463d-a2e3-159af73b2477 "Codebeat badge"
[10]: https://codebeat.co/projects/github-com-v2ray-v2ray-core "Codebeat"

28
all.go Normal file
View File

@@ -0,0 +1,28 @@
package core
import (
// The following are necessary as they register handlers in their init functions.
_ "v2ray.com/core/app/dns"
_ "v2ray.com/core/app/proxy"
_ "v2ray.com/core/app/router"
_ "v2ray.com/core/proxy/blackhole"
_ "v2ray.com/core/proxy/dokodemo"
_ "v2ray.com/core/proxy/freedom"
_ "v2ray.com/core/proxy/http"
_ "v2ray.com/core/proxy/shadowsocks"
_ "v2ray.com/core/proxy/socks"
_ "v2ray.com/core/proxy/vmess/inbound"
_ "v2ray.com/core/proxy/vmess/outbound"
_ "v2ray.com/core/transport/internet/kcp"
_ "v2ray.com/core/transport/internet/tcp"
_ "v2ray.com/core/transport/internet/tls"
_ "v2ray.com/core/transport/internet/udp"
_ "v2ray.com/core/transport/internet/ws"
_ "v2ray.com/core/transport/internet/authenticators/http"
_ "v2ray.com/core/transport/internet/authenticators/noop"
_ "v2ray.com/core/transport/internet/authenticators/srtp"
_ "v2ray.com/core/transport/internet/authenticators/utp"
)

View File

@@ -1,7 +1,7 @@
package api
import (
"github.com/v2ray/v2ray-core/app"
"v2ray.com/core/app"
)
const (

View File

@@ -1,7 +1,7 @@
package api
import (
v2net "github.com/v2ray/v2ray-core/common/net"
v2net "v2ray.com/core/common/net"
)
type Config struct {

View File

@@ -1,9 +1,9 @@
package dispatcher
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/transport/ray"
"v2ray.com/core/app"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
const (
@@ -12,5 +12,5 @@ const (
// PacketDispatcher dispatch a packet and possibly further network payload to its destination.
type PacketDispatcher interface {
DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay
DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay
}

View File

@@ -1,19 +1,19 @@
package impl
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/proxyman"
"github.com/v2ray/v2ray-core/app/router"
"github.com/v2ray/v2ray-core/common/alloc"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/transport/ray"
"v2ray.com/core/app"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/router"
"v2ray.com/core/common/alloc"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
type DefaultDispatcher struct {
ohm proxyman.OutboundHandlerManager
router router.Router
router *router.Router
}
func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
@@ -24,7 +24,7 @@ func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
return d
}
// @Private
// Private: Used by app.Space only.
func (this *DefaultDispatcher) Initialize(space app.Space) error {
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
log.Error("DefaultDispatcher: OutboundHandlerManager is not found in the space.")
@@ -33,7 +33,7 @@ func (this *DefaultDispatcher) Initialize(space app.Space) error {
this.ohm = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
if space.HasApp(router.APP_ID) {
this.router = space.GetApp(router.APP_ID).(router.Router)
this.router = space.GetApp(router.APP_ID).(*router.Router)
}
return nil
@@ -43,13 +43,13 @@ func (this *DefaultDispatcher) Release() {
}
func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay {
func (this *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
direct := ray.NewRay()
dispatcher := this.ohm.GetDefaultHandler()
destination := session.Destination
if this.router != nil {
if tag, err := this.router.TakeDetour(destination); err == nil {
if tag, err := this.router.TakeDetour(session); err == nil {
if handler := this.ohm.GetHandler(tag); handler != nil {
log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
dispatcher = handler
@@ -61,7 +61,7 @@ func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta
}
}
if meta.AllowPassiveConnection {
if session.Inbound != nil && session.Inbound.AllowPassiveConnection {
go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct)
} else {
go this.FilterPacketAndDispatch(destination, direct, dispatcher)
@@ -70,7 +70,7 @@ func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta
return direct
}
// @Private
// Private: Visible for testing.
func (this *DefaultDispatcher) FilterPacketAndDispatch(destination v2net.Destination, link ray.OutboundRay, dispatcher proxy.OutboundHandler) {
payload, err := link.OutboundInput().Read()
if err != nil {

View File

@@ -1,9 +1,9 @@
package testing
import (
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/transport/ray"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
type TestPacketDispatcher struct {
@@ -30,7 +30,7 @@ func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic
}
}
func (this *TestPacketDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay {
func (this *TestPacketDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
traffic := ray.NewRay()
this.Destination <- session.Destination
go this.Handler(session.Destination, traffic)

View File

@@ -3,10 +3,18 @@ package dns
import (
"net"
v2net "github.com/v2ray/v2ray-core/common/net"
"v2ray.com/core/common/log"
)
type Config struct {
Hosts map[string]net.IP
NameServers []v2net.Destination
func (this *Config) GetInternalHosts() map[string]net.IP {
hosts := make(map[string]net.IP)
for domain, ipOrDomain := range this.GetHosts() {
address := ipOrDomain.AsAddress()
if address.Family().IsDomain() {
log.Warning("DNS: Ignoring domain address in static hosts: ", address.Domain())
continue
}
hosts[domain] = address.IP()
}
return hosts
}

85
app/dns/config.pb.go Normal file
View File

@@ -0,0 +1,85 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/dns/config.proto
// DO NOT EDIT!
/*
Package dns is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/dns/config.proto
It has these top-level messages:
Config
*/
package dns
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import v2ray_core_common_net "v2ray.com/core/common/net"
import v2ray_core_common_net2 "v2ray.com/core/common/net"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Config struct {
// Nameservers used by this DNS. Only traditional UDP servers are support at the moment.
// A special value 'localhost' as a domain address can be set to use DNS on local system.
NameServers []*v2ray_core_common_net2.Endpoint `protobuf:"bytes,1,rep,name=NameServers" json:"NameServers,omitempty"`
// Static hosts. Domain to IP.
Hosts map[string]*v2ray_core_common_net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Config) GetNameServers() []*v2ray_core_common_net2.Endpoint {
if m != nil {
return m.NameServers
}
return nil
}
func (m *Config) GetHosts() map[string]*v2ray_core_common_net.IPOrDomain {
if m != nil {
return m.Hosts
}
return nil
}
func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.app.dns.Config")
}
func init() { proto.RegisterFile("v2ray.com/core/app/dns/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 272 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x90, 0x31, 0x4b, 0xc4, 0x30,
0x14, 0x80, 0x49, 0xcb, 0x1d, 0x98, 0x2e, 0x92, 0x41, 0x4a, 0x17, 0xab, 0x22, 0x16, 0x85, 0x04,
0xea, 0xa0, 0xe8, 0xe4, 0xe9, 0x81, 0x2e, 0x7a, 0xd4, 0x4d, 0xa7, 0xd8, 0x44, 0x29, 0x9a, 0xf7,
0x42, 0x12, 0x0b, 0xfd, 0xc1, 0xfe, 0x0f, 0xb9, 0x06, 0xf1, 0xd0, 0xbb, 0x2d, 0x84, 0xef, 0xcb,
0xfb, 0xf2, 0xe8, 0x41, 0x5f, 0x3b, 0x39, 0xf0, 0x16, 0x8d, 0x68, 0xd1, 0x69, 0x21, 0xad, 0x15,
0x0a, 0xbc, 0x68, 0x11, 0x5e, 0xbb, 0x37, 0x6e, 0x1d, 0x06, 0x64, 0xec, 0x07, 0x72, 0x9a, 0x4b,
0x6b, 0xb9, 0x02, 0x5f, 0x1c, 0xfd, 0x11, 0x5b, 0x34, 0x06, 0x41, 0x80, 0x0e, 0x42, 0x2a, 0xe5,
0xb4, 0xf7, 0x51, 0x2e, 0x4e, 0x36, 0x83, 0x4a, 0xfb, 0xd0, 0x81, 0x0c, 0x1d, 0x42, 0x84, 0xf7,
0xbf, 0x08, 0x9d, 0x5e, 0x8f, 0xa3, 0xd9, 0x15, 0xcd, 0xee, 0xa5, 0xd1, 0x8f, 0xda, 0xf5, 0xda,
0xf9, 0x9c, 0x94, 0x69, 0x95, 0xd5, 0xbb, 0x7c, 0x25, 0x25, 0xbe, 0xc4, 0x41, 0x07, 0x3e, 0x07,
0x65, 0xb1, 0x83, 0xd0, 0xac, 0x3a, 0xec, 0x92, 0x4e, 0x6e, 0xd1, 0x07, 0x9f, 0x27, 0xa3, 0x7c,
0xc8, 0xff, 0xff, 0x83, 0xc7, 0x69, 0x7c, 0xe4, 0xe6, 0x10, 0xdc, 0xd0, 0x44, 0xa7, 0x78, 0xa6,
0xf4, 0xf7, 0x92, 0x6d, 0xd3, 0xf4, 0x5d, 0x0f, 0x39, 0x29, 0x49, 0xb5, 0xd5, 0x2c, 0x8f, 0xec,
0x8c, 0x4e, 0x7a, 0xf9, 0xf1, 0xa9, 0xf3, 0xa4, 0x24, 0x55, 0x56, 0xef, 0x6d, 0x28, 0xbb, 0x5b,
0x3c, 0xb8, 0x1b, 0x34, 0xb2, 0x83, 0x26, 0xf2, 0x17, 0xc9, 0x39, 0x99, 0x1d, 0xd3, 0x9d, 0x16,
0xcd, 0x9a, 0x9e, 0x59, 0x16, 0x83, 0x16, 0xcb, 0x75, 0x3c, 0xa5, 0x0a, 0xfc, 0xcb, 0x74, 0x5c,
0xcd, 0xe9, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x43, 0x85, 0xa5, 0x73, 0xab, 0x01, 0x00, 0x00,
}

18
app/dns/config.proto Normal file
View File

@@ -0,0 +1,18 @@
syntax = "proto3";
package v2ray.core.app.dns;
option go_package = "dns";
option java_package = "com.v2ray.core.app.dns";
option java_outer_classname = "ConfigProto";
import "v2ray.com/core/common/net/address.proto";
import "v2ray.com/core/common/net/destination.proto";
message Config {
// Nameservers used by this DNS. Only traditional UDP servers are support at the moment.
// A special value 'localhost' as a domain address can be set to use DNS on local system.
repeated v2ray.core.common.net.Endpoint NameServers = 1;
// Static hosts. Domain to IP.
map<string, v2ray.core.common.net.IPOrDomain> Hosts = 2;
}

View File

@@ -1,38 +0,0 @@
// +build json
package dns
import (
"encoding/json"
"errors"
"net"
v2net "github.com/v2ray/v2ray-core/common/net"
)
func (this *Config) UnmarshalJSON(data []byte) error {
type JsonConfig struct {
Servers []v2net.AddressJson `json:"servers"`
Hosts map[string]v2net.AddressJson `json:"hosts"`
}
jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return err
}
this.NameServers = make([]v2net.Destination, len(jsonConfig.Servers))
for idx, server := range jsonConfig.Servers {
this.NameServers[idx] = v2net.UDPDestination(server.Address, v2net.Port(53))
}
if jsonConfig.Hosts != nil {
this.Hosts = make(map[string]net.IP)
for domain, ip := range jsonConfig.Hosts {
if ip.Address.Family().IsDomain() {
return errors.New(ip.Address.String() + " is not an IP.")
}
this.Hosts[domain] = ip.Address.IP()
}
}
return nil
}

View File

@@ -1,28 +0,0 @@
// +build json
package dns_test
import (
"encoding/json"
"testing"
. "github.com/v2ray/v2ray-core/app/dns"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestConfigParsing(t *testing.T) {
assert := assert.On(t)
rawJson := `{
"servers": ["8.8.8.8"]
}`
config := new(Config)
err := json.Unmarshal([]byte(rawJson), config)
assert.Error(err).IsNil()
assert.Int(len(config.NameServers)).Equals(1)
assert.Destination(config.NameServers[0]).IsUDP()
assert.Address(config.NameServers[0].Address()).Equals(v2net.IPAddress([]byte{8, 8, 8, 8}))
assert.Port(config.NameServers[0].Port()).Equals(v2net.Port(53))
}

View File

@@ -3,7 +3,7 @@ package dns
import (
"net"
"github.com/v2ray/v2ray-core/app"
"v2ray.com/core/app"
)
const (

View File

@@ -5,13 +5,13 @@ import (
"sync"
"time"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/alloc"
"github.com/v2ray/v2ray-core/common/dice"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/transport/internet/udp"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/common/alloc"
"v2ray.com/core/common/dice"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/internet/udp"
"github.com/miekg/dns"
)
@@ -50,16 +50,14 @@ type UDPNameServer struct {
func NewUDPNameServer(address v2net.Destination, dispatcher dispatcher.PacketDispatcher) *UDPNameServer {
s := &UDPNameServer{
address: address,
requests: make(map[uint16]*PendingRequest),
udpServer: udp.NewUDPServer(&proxy.InboundHandlerMeta{
AllowPassiveConnection: false,
}, dispatcher),
address: address,
requests: make(map[uint16]*PendingRequest),
udpServer: udp.NewUDPServer(dispatcher),
}
return s
}
// @Private
// Private: Visible for testing.
func (this *UDPNameServer) Cleanup() {
expiredRequests := make([]uint16, 0, 16)
now := time.Now()
@@ -77,7 +75,7 @@ func (this *UDPNameServer) Cleanup() {
expiredRequests = nil
}
// @Private
// Private: Visible for testing.
func (this *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
var id uint16
this.Lock()
@@ -102,7 +100,7 @@ func (this *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
return id
}
// @Private
// Private: Visible for testing.
func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc.Buffer) {
msg := new(dns.Msg)
err := msg.Unpack(payload.Value)

View File

@@ -5,9 +5,11 @@ import (
"sync"
"time"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/log"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/common/loader"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
"github.com/miekg/dns"
)
@@ -32,7 +34,7 @@ func NewCacheServer(space app.Space, config *Config) *CacheServer {
server := &CacheServer{
records: make(map[string]*DomainRecord),
servers: make([]NameServer, len(config.NameServers)),
hosts: config.Hosts,
hosts: config.GetInternalHosts(),
}
space.InitializeApplication(func() error {
if !space.HasApp(dispatcher.APP_ID) {
@@ -41,11 +43,18 @@ func NewCacheServer(space app.Space, config *Config) *CacheServer {
}
dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
for idx, ns := range config.NameServers {
if ns.Address().Family().IsDomain() && ns.Address().Domain() == "localhost" {
for idx, destPB := range config.NameServers {
address := destPB.Address.AsAddress()
if address.Family().IsDomain() && address.Domain() == "localhost" {
server.servers[idx] = &LocalNameServer{}
} else {
server.servers[idx] = NewUDPNameServer(ns, dispatcher)
dest := destPB.AsDestination()
if dest.Network == v2net.Network_Unknown {
dest.Network = v2net.Network_UDP
}
if dest.Network == v2net.Network_UDP {
server.servers[idx] = NewUDPNameServer(dest, dispatcher)
}
}
}
if len(config.NameServers) == 0 {
@@ -60,7 +69,7 @@ func (this *CacheServer) Release() {
}
//@Private
// Private: Visible for testing.
func (this *CacheServer) GetCached(domain string) []net.IP {
this.RLock()
defer this.RUnlock()
@@ -103,3 +112,18 @@ func (this *CacheServer) Get(domain string) []net.IP {
log.Debug("DNS: Returning nil for domain ", domain)
return nil
}
type CacheServerFactory struct{}
func (this CacheServerFactory) Create(space app.Space, config interface{}) (app.Application, error) {
server := NewCacheServer(space, config.(*Config))
return server, nil
}
func (this CacheServerFactory) AppId() app.ID {
return APP_ID
}
func init() {
app.RegisterApplicationFactory(loader.GetType(new(Config)), CacheServerFactory{})
}

View File

@@ -1,50 +0,0 @@
package dns_test
import (
"net"
"testing"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
dispatchers "github.com/v2ray/v2ray-core/app/dispatcher/impl"
. "github.com/v2ray/v2ray-core/app/dns"
"github.com/v2ray/v2ray-core/app/proxyman"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/proxy/freedom"
"github.com/v2ray/v2ray-core/testing/assert"
"github.com/v2ray/v2ray-core/transport/internet"
)
func TestDnsAdd(t *testing.T) {
assert := assert.On(t)
space := app.NewSpace()
outboundHandlerManager := proxyman.NewDefaultOutboundHandlerManager()
outboundHandlerManager.SetDefaultHandler(
freedom.NewFreedomConnection(
&freedom.Config{},
space,
&proxy.OutboundHandlerMeta{
Address: v2net.AnyIP,
StreamSettings: &internet.StreamSettings{
Type: internet.StreamConnectionTypeRawTCP,
},
}))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager)
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
domain := "local.v2ray.com"
server := NewCacheServer(space, &Config{
NameServers: []v2net.Destination{
v2net.UDPDestination(v2net.IPAddress([]byte{8, 8, 8, 8}), v2net.Port(53)),
},
})
space.BindApp(APP_ID, server)
space.Initialize()
ips := server.Get(domain)
assert.Int(len(ips)).Equals(1)
assert.IP(ips[0].To4()).Equals(net.IP([]byte{127, 0, 0, 1}))
}

133
app/proxy/proxy.go Normal file
View File

@@ -0,0 +1,133 @@
package proxy
import (
"errors"
"io"
"net"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common/alloc"
v2io "v2ray.com/core/common/io"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/transport/internet"
"v2ray.com/core/transport/ray"
)
const (
APP_ID = 7
)
type OutboundProxy struct {
outboundManager proxyman.OutboundHandlerManager
}
func NewOutboundProxy(space app.Space) *OutboundProxy {
proxy := new(OutboundProxy)
space.InitializeApplication(func() error {
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
return errors.New("Proxy: Outbound handler manager not found.")
}
proxy.outboundManager = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
return nil
})
return proxy
}
func (this *OutboundProxy) RegisterDialer() {
internet.ProxyDialer = this.Dial
}
func (this *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
handler := this.outboundManager.GetHandler(options.Proxy.Tag)
if handler == nil {
log.Warning("Proxy: Failed to get outbound handler with tag: ", options.Proxy.Tag)
return internet.Dial(src, dest, internet.DialerOptions{
Stream: options.Stream,
})
}
stream := ray.NewRay()
go handler.Dispatch(dest, alloc.NewLocalBuffer(32).Clear(), stream)
return NewProxyConnection(src, dest, stream), nil
}
func (this *OutboundProxy) Release() {
}
type ProxyConnection struct {
stream ray.Ray
closed bool
localAddr net.Addr
remoteAddr net.Addr
reader *v2io.ChanReader
writer *v2io.ChainWriter
}
func NewProxyConnection(src v2net.Address, dest v2net.Destination, stream ray.Ray) *ProxyConnection {
return &ProxyConnection{
stream: stream,
localAddr: &net.TCPAddr{
IP: []byte{0, 0, 0, 0},
Port: 0,
},
remoteAddr: &net.TCPAddr{
IP: []byte{0, 0, 0, 0},
Port: 0,
},
reader: v2io.NewChanReader(stream.InboundOutput()),
writer: v2io.NewChainWriter(stream.InboundInput()),
}
}
func (this *ProxyConnection) Read(b []byte) (int, error) {
if this.closed {
return 0, io.EOF
}
return this.reader.Read(b)
}
func (this *ProxyConnection) Write(b []byte) (int, error) {
if this.closed {
return 0, io.EOF
}
return this.writer.Write(b)
}
func (this *ProxyConnection) Close() error {
this.closed = true
this.stream.InboundInput().Close()
this.stream.InboundOutput().Release()
return nil
}
func (this *ProxyConnection) LocalAddr() net.Addr {
return this.localAddr
}
func (this *ProxyConnection) RemoteAddr() net.Addr {
return this.remoteAddr
}
func (this *ProxyConnection) SetDeadline(t time.Time) error {
return nil
}
func (this *ProxyConnection) SetReadDeadline(t time.Time) error {
return nil
}
func (this *ProxyConnection) SetWriteDeadline(t time.Time) error {
return nil
}
func (this *ProxyConnection) Reusable() bool {
return false
}
func (this *ProxyConnection) SetReusable(bool) {
}

68
app/proxy/proxy_test.go Normal file
View File

@@ -0,0 +1,68 @@
package proxy_test
import (
"testing"
"v2ray.com/core/app"
. "v2ray.com/core/app/proxy"
"v2ray.com/core/app/proxyman"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/proxy/freedom"
"v2ray.com/core/testing/assert"
"v2ray.com/core/testing/servers/tcp"
"v2ray.com/core/transport/internet"
)
func TestProxyDial(t *testing.T) {
assert := assert.On(t)
space := app.NewSpace()
outboundManager := proxyman.NewDefaultOutboundHandlerManager()
outboundManager.SetHandler("tag", freedom.NewFreedomConnection(&freedom.Config{}, space, &proxy.OutboundHandlerMeta{
Tag: "tag",
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
},
}))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundManager)
proxy := NewOutboundProxy(space)
space.BindApp(APP_ID, proxy)
assert.Error(space.Initialize()).IsNil()
xor := func(b []byte) []byte {
for idx, x := range b {
b[idx] = x ^ 'c'
}
return b
}
tcpServer := &tcp.Server{
MsgProcessor: xor,
}
dest, err := tcpServer.Start()
assert.Error(err).IsNil()
conn, err := proxy.Dial(v2net.LocalHostIP, dest, internet.DialerOptions{
Stream: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
},
Proxy: &internet.ProxyConfig{
Tag: "tag",
},
})
assert.Error(err).IsNil()
_, err = conn.Write([]byte{'a', 'b', 'c', 'd'})
assert.Error(err).IsNil()
b := make([]byte, 10)
nBytes, err := conn.Read(b)
assert.Error(err).IsNil()
assert.Bytes(xor(b[:nBytes])).Equals([]byte{'a', 'b', 'c', 'd'})
conn.Close()
tcpServer.Close()
}

View File

@@ -3,8 +3,8 @@ package proxyman
import (
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/proxy"
"v2ray.com/core/app"
"v2ray.com/core/proxy"
)
const (

229
app/router/condition.go Normal file
View File

@@ -0,0 +1,229 @@
package router
import (
"net"
"regexp"
"strings"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
)
type Condition interface {
Apply(session *proxy.SessionInfo) bool
}
type ConditionChan []Condition
func NewConditionChan() *ConditionChan {
var condChan ConditionChan = make([]Condition, 0, 8)
return &condChan
}
func (this *ConditionChan) Add(cond Condition) *ConditionChan {
*this = append(*this, cond)
return this
}
func (this *ConditionChan) Apply(session *proxy.SessionInfo) bool {
for _, cond := range *this {
if !cond.Apply(session) {
return false
}
}
return true
}
func (this *ConditionChan) Len() int {
return len(*this)
}
type AnyCondition []Condition
func NewAnyCondition() *AnyCondition {
var anyCond AnyCondition = make([]Condition, 0, 8)
return &anyCond
}
func (this *AnyCondition) Add(cond Condition) *AnyCondition {
*this = append(*this, cond)
return this
}
func (this *AnyCondition) Apply(session *proxy.SessionInfo) bool {
for _, cond := range *this {
if cond.Apply(session) {
return true
}
}
return false
}
func (this *AnyCondition) Len() int {
return len(*this)
}
type PlainDomainMatcher struct {
pattern string
}
func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
return &PlainDomainMatcher{
pattern: pattern,
}
}
func (this *PlainDomainMatcher) Apply(session *proxy.SessionInfo) bool {
dest := session.Destination
if !dest.Address.Family().IsDomain() {
return false
}
domain := dest.Address.Domain()
return strings.Contains(domain, this.pattern)
}
type RegexpDomainMatcher struct {
pattern *regexp.Regexp
}
func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
r, err := regexp.Compile(pattern)
if err != nil {
return nil, err
}
return &RegexpDomainMatcher{
pattern: r,
}, nil
}
func (this *RegexpDomainMatcher) Apply(session *proxy.SessionInfo) bool {
dest := session.Destination
if !dest.Address.Family().IsDomain() {
return false
}
domain := dest.Address.Domain()
return this.pattern.MatchString(strings.ToLower(domain))
}
type CIDRMatcher struct {
cidr *net.IPNet
onSource bool
}
func NewCIDRMatcher(ip []byte, mask uint32, onSource bool) (*CIDRMatcher, error) {
cidr := &net.IPNet{
IP: net.IP(ip),
Mask: net.CIDRMask(int(mask), len(ip)),
}
return &CIDRMatcher{
cidr: cidr,
onSource: onSource,
}, nil
}
func (this *CIDRMatcher) Apply(session *proxy.SessionInfo) bool {
dest := session.Destination
if this.onSource {
dest = session.Source
}
if !dest.Address.Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
return false
}
return this.cidr.Contains(dest.Address.IP())
}
type IPv4Matcher struct {
ipv4net *v2net.IPNet
onSource bool
}
func NewIPv4Matcher(ipnet *v2net.IPNet, onSource bool) *IPv4Matcher {
return &IPv4Matcher{
ipv4net: ipnet,
onSource: onSource,
}
}
func (this *IPv4Matcher) Apply(session *proxy.SessionInfo) bool {
dest := session.Destination
if this.onSource {
dest = session.Source
}
if !dest.Address.Family().Either(v2net.AddressFamilyIPv4) {
return false
}
return this.ipv4net.Contains(dest.Address.IP())
}
type PortMatcher struct {
port v2net.PortRange
}
func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
return &PortMatcher{
port: portRange,
}
}
func (this *PortMatcher) Apply(session *proxy.SessionInfo) bool {
return this.port.Contains(session.Destination.Port)
}
type NetworkMatcher struct {
network *v2net.NetworkList
}
func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
return &NetworkMatcher{
network: network,
}
}
func (this *NetworkMatcher) Apply(session *proxy.SessionInfo) bool {
return this.network.HasNetwork(session.Destination.Network)
}
type UserMatcher struct {
user []string
}
func NewUserMatcher(users []string) *UserMatcher {
return &UserMatcher{
user: users,
}
}
func (this *UserMatcher) Apply(session *proxy.SessionInfo) bool {
if session.User == nil {
return false
}
for _, u := range this.user {
if u == session.User.Email {
return true
}
}
return false
}
type InboundTagMatcher struct {
tags []string
}
func NewInboundTagMatcher(tags []string) *InboundTagMatcher {
return &InboundTagMatcher{
tags: tags,
}
}
func (this *InboundTagMatcher) Apply(session *proxy.SessionInfo) bool {
if session.Inbound == nil || len(session.Inbound.Tag) == 0 {
return false
}
for _, t := range this.tags {
if t == session.Inbound.Tag {
return true
}
}
return false
}

View File

@@ -1,6 +1,126 @@
package router
type Config struct {
Strategy string
Settings interface{}
import (
"errors"
"net"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
)
type Rule struct {
Tag string
Condition Condition
}
func (this *Rule) Apply(session *proxy.SessionInfo) bool {
return this.Condition.Apply(session)
}
func (this *RoutingRule) BuildCondition() (Condition, error) {
conds := NewConditionChan()
if len(this.Domain) > 0 {
anyCond := NewAnyCondition()
for _, domain := range this.Domain {
if domain.Type == Domain_Plain {
anyCond.Add(NewPlainDomainMatcher(domain.Value))
} else {
matcher, err := NewRegexpDomainMatcher(domain.Value)
if err != nil {
return nil, err
}
anyCond.Add(matcher)
}
}
conds.Add(anyCond)
}
if len(this.Cidr) > 0 {
ipv4Net := v2net.NewIPNet()
ipv6Cond := NewAnyCondition()
hasIpv6 := false
for _, ip := range this.Cidr {
switch len(ip.Ip) {
case net.IPv4len:
ipv4Net.AddIP(ip.Ip, byte(ip.Prefix))
case net.IPv6len:
hasIpv6 = true
matcher, err := NewCIDRMatcher(ip.Ip, ip.Prefix, false)
if err != nil {
return nil, err
}
ipv6Cond.Add(matcher)
default:
return nil, errors.New("Router: Invalid IP length.")
}
}
if !ipv4Net.IsEmpty() && hasIpv6 {
cond := NewAnyCondition()
cond.Add(NewIPv4Matcher(ipv4Net, false))
cond.Add(ipv6Cond)
conds.Add(cond)
} else if !ipv4Net.IsEmpty() {
conds.Add(NewIPv4Matcher(ipv4Net, false))
} else if hasIpv6 {
conds.Add(ipv6Cond)
}
}
if this.PortRange != nil {
conds.Add(NewPortMatcher(*this.PortRange))
}
if this.NetworkList != nil {
conds.Add(NewNetworkMatcher(this.NetworkList))
}
if len(this.SourceCidr) > 0 {
ipv4Net := v2net.NewIPNet()
ipv6Cond := NewAnyCondition()
hasIpv6 := false
for _, ip := range this.SourceCidr {
switch len(ip.Ip) {
case net.IPv4len:
ipv4Net.AddIP(ip.Ip, byte(ip.Prefix))
case net.IPv6len:
hasIpv6 = true
matcher, err := NewCIDRMatcher(ip.Ip, ip.Prefix, true)
if err != nil {
return nil, err
}
ipv6Cond.Add(matcher)
default:
return nil, errors.New("Router: Invalid IP length.")
}
}
if !ipv4Net.IsEmpty() && hasIpv6 {
cond := NewAnyCondition()
cond.Add(NewIPv4Matcher(ipv4Net, true))
cond.Add(ipv6Cond)
conds.Add(cond)
} else if !ipv4Net.IsEmpty() {
conds.Add(NewIPv4Matcher(ipv4Net, true))
} else if hasIpv6 {
conds.Add(ipv6Cond)
}
}
if len(this.UserEmail) > 0 {
conds.Add(NewUserMatcher(this.UserEmail))
}
if len(this.InboundTag) > 0 {
conds.Add(NewInboundTagMatcher(this.InboundTag))
}
if conds.Len() == 0 {
return nil, errors.New("Router: This rule has no effective fields.")
}
return conds, nil
}

227
app/router/config.pb.go Normal file
View File

@@ -0,0 +1,227 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/router/config.proto
// DO NOT EDIT!
/*
Package router is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/router/config.proto
It has these top-level messages:
Domain
CIDR
RoutingRule
Config
*/
package router
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import v2ray_core_common_net "v2ray.com/core/common/net"
import v2ray_core_common_net1 "v2ray.com/core/common/net"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Type of domain value.
type Domain_Type int32
const (
// The value is used as is.
Domain_Plain Domain_Type = 0
// The value is used as a regular expression.
Domain_Regex Domain_Type = 1
)
var Domain_Type_name = map[int32]string{
0: "Plain",
1: "Regex",
}
var Domain_Type_value = map[string]int32{
"Plain": 0,
"Regex": 1,
}
func (x Domain_Type) String() string {
return proto.EnumName(Domain_Type_name, int32(x))
}
func (Domain_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
type Config_DomainStrategy int32
const (
// Use domain as is.
Config_AsIs Config_DomainStrategy = 0
// Always resolve IP for domains.
Config_UseIp Config_DomainStrategy = 1
// Resolve to IP if the domain doesn't match any rules.
Config_IpIfNonMatch Config_DomainStrategy = 2
)
var Config_DomainStrategy_name = map[int32]string{
0: "AsIs",
1: "UseIp",
2: "IpIfNonMatch",
}
var Config_DomainStrategy_value = map[string]int32{
"AsIs": 0,
"UseIp": 1,
"IpIfNonMatch": 2,
}
func (x Config_DomainStrategy) String() string {
return proto.EnumName(Config_DomainStrategy_name, int32(x))
}
func (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3, 0} }
// Domain for routing decision.
type Domain struct {
// Domain matching type.
Type Domain_Type `protobuf:"varint,1,opt,name=type,enum=v2ray.core.app.router.Domain_Type" json:"type,omitempty"`
// Domain value.
Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
}
func (m *Domain) Reset() { *m = Domain{} }
func (m *Domain) String() string { return proto.CompactTextString(m) }
func (*Domain) ProtoMessage() {}
func (*Domain) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
// IP for routing decision, in CIDR form.
type CIDR struct {
// IP address, should be either 4 or 16 bytes.
Ip []byte `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"`
// Number of leading ones in the network mask.
Prefix uint32 `protobuf:"varint,2,opt,name=prefix" json:"prefix,omitempty"`
}
func (m *CIDR) Reset() { *m = CIDR{} }
func (m *CIDR) String() string { return proto.CompactTextString(m) }
func (*CIDR) ProtoMessage() {}
func (*CIDR) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type RoutingRule struct {
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
Domain []*Domain `protobuf:"bytes,2,rep,name=domain" json:"domain,omitempty"`
Cidr []*CIDR `protobuf:"bytes,3,rep,name=cidr" json:"cidr,omitempty"`
PortRange *v2ray_core_common_net.PortRange `protobuf:"bytes,4,opt,name=port_range,json=portRange" json:"port_range,omitempty"`
NetworkList *v2ray_core_common_net1.NetworkList `protobuf:"bytes,5,opt,name=network_list,json=networkList" json:"network_list,omitempty"`
SourceCidr []*CIDR `protobuf:"bytes,6,rep,name=source_cidr,json=sourceCidr" json:"source_cidr,omitempty"`
UserEmail []string `protobuf:"bytes,7,rep,name=user_email,json=userEmail" json:"user_email,omitempty"`
InboundTag []string `protobuf:"bytes,8,rep,name=inbound_tag,json=inboundTag" json:"inbound_tag,omitempty"`
}
func (m *RoutingRule) Reset() { *m = RoutingRule{} }
func (m *RoutingRule) String() string { return proto.CompactTextString(m) }
func (*RoutingRule) ProtoMessage() {}
func (*RoutingRule) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *RoutingRule) GetDomain() []*Domain {
if m != nil {
return m.Domain
}
return nil
}
func (m *RoutingRule) GetCidr() []*CIDR {
if m != nil {
return m.Cidr
}
return nil
}
func (m *RoutingRule) GetPortRange() *v2ray_core_common_net.PortRange {
if m != nil {
return m.PortRange
}
return nil
}
func (m *RoutingRule) GetNetworkList() *v2ray_core_common_net1.NetworkList {
if m != nil {
return m.NetworkList
}
return nil
}
func (m *RoutingRule) GetSourceCidr() []*CIDR {
if m != nil {
return m.SourceCidr
}
return nil
}
type Config struct {
DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,enum=v2ray.core.app.router.Config_DomainStrategy" json:"domain_strategy,omitempty"`
Rule []*RoutingRule `protobuf:"bytes,2,rep,name=rule" json:"rule,omitempty"`
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *Config) GetRule() []*RoutingRule {
if m != nil {
return m.Rule
}
return nil
}
func init() {
proto.RegisterType((*Domain)(nil), "v2ray.core.app.router.Domain")
proto.RegisterType((*CIDR)(nil), "v2ray.core.app.router.CIDR")
proto.RegisterType((*RoutingRule)(nil), "v2ray.core.app.router.RoutingRule")
proto.RegisterType((*Config)(nil), "v2ray.core.app.router.Config")
proto.RegisterEnum("v2ray.core.app.router.Domain_Type", Domain_Type_name, Domain_Type_value)
proto.RegisterEnum("v2ray.core.app.router.Config_DomainStrategy", Config_DomainStrategy_name, Config_DomainStrategy_value)
}
func init() { proto.RegisterFile("v2ray.com/core/app/router/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 520 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x93, 0xd1, 0x6e, 0xd3, 0x3e,
0x14, 0xc6, 0xff, 0x69, 0xb3, 0xfc, 0x97, 0x93, 0x51, 0x22, 0x0b, 0x50, 0x18, 0x4c, 0x44, 0x11,
0x82, 0x5e, 0xa0, 0x04, 0x15, 0x01, 0x37, 0x48, 0x88, 0x75, 0xbb, 0xa8, 0x04, 0x53, 0x65, 0xb6,
0x1b, 0x6e, 0x22, 0x2f, 0x75, 0x83, 0x45, 0x62, 0x5b, 0x8e, 0x33, 0xd6, 0x87, 0xe0, 0xdd, 0x78,
0x24, 0x64, 0x3b, 0x13, 0x1b, 0x5a, 0xe1, 0xce, 0xe7, 0xf4, 0xf7, 0x1d, 0x7f, 0x3d, 0xfe, 0x02,
0xcf, 0x2e, 0x66, 0x8a, 0x6c, 0xf2, 0x4a, 0xb4, 0x45, 0x25, 0x14, 0x2d, 0x88, 0x94, 0x85, 0x12,
0xbd, 0xa6, 0xaa, 0xa8, 0x04, 0x5f, 0xb3, 0x3a, 0x97, 0x4a, 0x68, 0x81, 0xee, 0x5f, 0x71, 0x8a,
0xe6, 0x44, 0xca, 0xdc, 0x31, 0xfb, 0x4f, 0xff, 0x90, 0x57, 0xa2, 0x6d, 0x05, 0x2f, 0x38, 0xd5,
0x85, 0x14, 0x4a, 0x3b, 0xf1, 0xfe, 0xf3, 0xed, 0x14, 0xa7, 0xfa, 0xbb, 0x50, 0xdf, 0x1c, 0x98,
0x69, 0x08, 0x8e, 0x44, 0x4b, 0x18, 0x47, 0x6f, 0xc0, 0xd7, 0x1b, 0x49, 0x13, 0x2f, 0xf5, 0xa6,
0x93, 0x59, 0x96, 0xdf, 0x7a, 0x7d, 0xee, 0xe0, 0xfc, 0x74, 0x23, 0x29, 0xb6, 0x3c, 0xba, 0x07,
0x3b, 0x17, 0xa4, 0xe9, 0x69, 0x32, 0x4a, 0xbd, 0x69, 0x88, 0x5d, 0x91, 0x3d, 0x06, 0xdf, 0x30,
0x28, 0x84, 0x9d, 0x65, 0x43, 0x18, 0x8f, 0xff, 0x33, 0x47, 0x4c, 0x6b, 0x7a, 0x19, 0x7b, 0x59,
0x0e, 0xfe, 0x7c, 0x71, 0x84, 0xd1, 0x04, 0x46, 0x4c, 0xda, 0x1b, 0xf7, 0xf0, 0x88, 0x49, 0xf4,
0x00, 0x02, 0xa9, 0xe8, 0x9a, 0x5d, 0xda, 0x61, 0x77, 0xf0, 0x50, 0x65, 0x3f, 0xc6, 0x10, 0x61,
0xd1, 0x6b, 0xc6, 0x6b, 0xdc, 0x37, 0x14, 0xc5, 0x30, 0xd6, 0xa4, 0xb6, 0xc2, 0x10, 0x9b, 0x23,
0x7a, 0x0d, 0xc1, 0xca, 0x5a, 0x4b, 0x46, 0xe9, 0x78, 0x1a, 0xcd, 0x0e, 0xfe, 0xea, 0x1f, 0x0f,
0x30, 0x2a, 0xc0, 0xaf, 0xd8, 0x4a, 0x25, 0x63, 0x2b, 0x7a, 0xb4, 0x45, 0x64, 0xbc, 0x62, 0x0b,
0xa2, 0xf7, 0x00, 0x66, 0xcd, 0xa5, 0x22, 0xbc, 0xa6, 0x89, 0x9f, 0x7a, 0xd3, 0x68, 0x96, 0x5e,
0x97, 0xb9, 0x4d, 0xe7, 0x9c, 0xea, 0x7c, 0x29, 0x94, 0xc6, 0x86, 0xc3, 0xa1, 0xbc, 0x3a, 0xa2,
0x63, 0xd8, 0x1b, 0x5e, 0xa0, 0x6c, 0x58, 0xa7, 0x93, 0x1d, 0x3b, 0x22, 0xdb, 0x32, 0xe2, 0xc4,
0xa1, 0x1f, 0x59, 0xa7, 0x71, 0xc4, 0x7f, 0x17, 0xe8, 0x1d, 0x44, 0x9d, 0xe8, 0x55, 0x45, 0x4b,
0xeb, 0x3f, 0xf8, 0xb7, 0x7f, 0x70, 0xfc, 0xdc, 0xfc, 0x8b, 0x03, 0x80, 0xbe, 0xa3, 0xaa, 0xa4,
0x2d, 0x61, 0x4d, 0xf2, 0x7f, 0x3a, 0x9e, 0x86, 0x38, 0x34, 0x9d, 0x63, 0xd3, 0x40, 0x4f, 0x20,
0x62, 0xfc, 0x5c, 0xf4, 0x7c, 0x55, 0x9a, 0x35, 0xef, 0xda, 0xdf, 0x61, 0x68, 0x9d, 0x92, 0x3a,
0xfb, 0xe9, 0x41, 0x30, 0xb7, 0x61, 0x45, 0x67, 0x70, 0xd7, 0xed, 0xb2, 0xec, 0xb4, 0x22, 0x9a,
0xd6, 0x9b, 0x21, 0x41, 0x2f, 0xb6, 0x99, 0x71, 0x21, 0x77, 0x0f, 0xf1, 0x79, 0xd0, 0xe0, 0xc9,
0xea, 0x46, 0x6d, 0xd2, 0xa8, 0xfa, 0x86, 0x0e, 0xaf, 0xb9, 0x2d, 0x8d, 0xd7, 0x32, 0x81, 0x2d,
0x9f, 0xbd, 0x85, 0xc9, 0xcd, 0xc9, 0x68, 0x17, 0xfc, 0x0f, 0xdd, 0xa2, 0x73, 0x01, 0x3c, 0xeb,
0xe8, 0x42, 0xc6, 0x1e, 0x8a, 0x61, 0x6f, 0x21, 0x17, 0xeb, 0x13, 0xc1, 0x3f, 0x11, 0x5d, 0x7d,
0x8d, 0x47, 0x87, 0x2f, 0xe1, 0x61, 0x25, 0xda, 0xdb, 0xef, 0x39, 0x8c, 0x9c, 0xe9, 0xa5, 0xf9,
0x64, 0xbe, 0x04, 0xae, 0x79, 0x1e, 0xd8, 0x2f, 0xe8, 0xd5, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff,
0xe4, 0x89, 0x6f, 0xa7, 0xd1, 0x03, 0x00, 0x00,
}

61
app/router/config.proto Normal file
View File

@@ -0,0 +1,61 @@
syntax = "proto3";
package v2ray.core.app.router;
option go_package = "router";
option java_package = "com.v2ray.core.app.router";
option java_outer_classname = "ConfigProto";
import "v2ray.com/core/common/net/port.proto";
import "v2ray.com/core/common/net/network.proto";
// Domain for routing decision.
message Domain {
// Type of domain value.
enum Type {
// The value is used as is.
Plain = 0;
// The value is used as a regular expression.
Regex = 1;
}
// Domain matching type.
Type type = 1;
// Domain value.
string value = 2;
}
// IP for routing decision, in CIDR form.
message CIDR {
// IP address, should be either 4 or 16 bytes.
bytes ip = 1;
// Number of leading ones in the network mask.
uint32 prefix = 2;
}
message RoutingRule {
string tag = 1;
repeated Domain domain = 2;
repeated CIDR cidr = 3;
v2ray.core.common.net.PortRange port_range = 4;
v2ray.core.common.net.NetworkList network_list = 5;
repeated CIDR source_cidr = 6;
repeated string user_email = 7;
repeated string inbound_tag = 8;
}
message Config {
enum DomainStrategy {
// Use domain as is.
AsIs = 0;
// Always resolve IP for domains.
UseIp = 1;
// Resolve to IP if the domain doesn't match any rules.
IpIfNonMatch = 2;
}
DomainStrategy domain_strategy = 1;
repeated RoutingRule rule = 2;
}

View File

@@ -1,31 +0,0 @@
package router
import (
"errors"
)
type ConfigObjectCreator func([]byte) (interface{}, error)
var (
configCache map[string]ConfigObjectCreator
ErrRouterNotFound = errors.New("Router not found.")
)
func RegisterRouterConfig(strategy string, creator ConfigObjectCreator) error {
// TODO: check strategy
configCache[strategy] = creator
return nil
}
func CreateRouterConfig(strategy string, data []byte) (interface{}, error) {
creator, found := configCache[strategy]
if !found {
return nil, ErrRouterNotFound
}
return creator(data)
}
func init() {
configCache = make(map[string]ConfigObjectCreator)
}

View File

@@ -1,28 +0,0 @@
// +build json
package router
import (
"encoding/json"
"github.com/v2ray/v2ray-core/common/log"
)
func (this *Config) UnmarshalJSON(data []byte) error {
type JsonConfig struct {
Strategy string `json:"strategy"`
Settings json.RawMessage `json:"settings"`
}
jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return err
}
settings, err := CreateRouterConfig(jsonConfig.Strategy, []byte(jsonConfig.Settings))
if err != nil {
log.Error("Router: Failed to load router settings: ", err)
return err
}
this.Strategy = jsonConfig.Strategy
this.Settings = settings
return nil
}

View File

@@ -1,37 +1,131 @@
package router
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/common"
v2net "github.com/v2ray/v2ray-core/common/net"
"errors"
"v2ray.com/core/app"
"v2ray.com/core/app/dns"
"v2ray.com/core/common/loader"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
)
const (
APP_ID = app.ID(3)
)
type Router interface {
common.Releasable
TakeDetour(v2net.Destination) (string, error)
}
type RouterFactory interface {
Create(rawConfig interface{}, space app.Space) (Router, error)
}
var (
routerCache = make(map[string]RouterFactory)
ErrInvalidRule = errors.New("Invalid Rule")
ErrNoRuleApplicable = errors.New("No rule applicable")
)
func RegisterRouter(name string, factory RouterFactory) error {
// TODO: check name
routerCache[name] = factory
return nil
type Router struct {
domainStrategy Config_DomainStrategy
rules []Rule
// cache *RoutingTable
dnsServer dns.Server
}
func CreateRouter(name string, rawConfig interface{}, space app.Space) (Router, error) {
if factory, found := routerCache[name]; found {
return factory.Create(rawConfig, space)
func NewRouter(config *Config, space app.Space) *Router {
r := &Router{
domainStrategy: config.DomainStrategy,
//cache: NewRoutingTable(),
rules: make([]Rule, len(config.Rule)),
}
return nil, ErrRouterNotFound
space.InitializeApplication(func() error {
for idx, rule := range config.Rule {
r.rules[idx].Tag = rule.Tag
cond, err := rule.BuildCondition()
if err != nil {
return err
}
r.rules[idx].Condition = cond
}
if !space.HasApp(dns.APP_ID) {
log.Error("Router: DNS is not found in the space.")
return app.ErrMissingApplication
}
r.dnsServer = space.GetApp(dns.APP_ID).(dns.Server)
return nil
})
return r
}
func (this *Router) Release() {
}
// Private: Visible for testing.
func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
ips := this.dnsServer.Get(dest.Address.Domain())
if len(ips) == 0 {
return nil
}
dests := make([]v2net.Destination, len(ips))
for idx, ip := range ips {
if dest.Network == v2net.Network_TCP {
dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port)
} else {
dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port)
}
}
return dests
}
func (this *Router) takeDetourWithoutCache(session *proxy.SessionInfo) (string, error) {
for _, rule := range this.rules {
if rule.Apply(session) {
return rule.Tag, nil
}
}
dest := session.Destination
if this.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
log.Info("Router: Looking up IP for ", dest)
ipDests := this.ResolveIP(dest)
if ipDests != nil {
for _, ipDest := range ipDests {
log.Info("Router: Trying IP ", ipDest)
for _, rule := range this.rules {
if rule.Apply(&proxy.SessionInfo{
Source: session.Source,
Destination: ipDest,
User: session.User,
}) {
return rule.Tag, nil
}
}
}
}
}
return "", ErrNoRuleApplicable
}
func (this *Router) TakeDetour(session *proxy.SessionInfo) (string, error) {
//destStr := dest.String()
//found, tag, err := this.cache.Get(destStr)
//if !found {
tag, err := this.takeDetourWithoutCache(session)
//this.cache.Set(destStr, tag, err)
return tag, err
//}
//return tag, err
}
type RouterFactory struct{}
func (RouterFactory) Create(space app.Space, config interface{}) (app.Application, error) {
router := NewRouter(config.(*Config), space)
return router, nil
}
func (RouterFactory) AppId() app.ID {
return APP_ID
}
func init() {
app.RegisterApplicationFactory(loader.GetType(new(Config)), RouterFactory{})
}

42
app/router/router_test.go Normal file
View File

@@ -0,0 +1,42 @@
package router_test
import (
"testing"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
dispatchers "v2ray.com/core/app/dispatcher/impl"
"v2ray.com/core/app/dns"
"v2ray.com/core/app/proxyman"
. "v2ray.com/core/app/router"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/testing/assert"
)
func TestSimpleRouter(t *testing.T) {
assert := assert.On(t)
config := &Config{
Rule: []*RoutingRule{
{
Tag: "test",
NetworkList: &v2net.NetworkList{
Network: []v2net.Network{v2net.Network_TCP},
},
},
},
}
space := app.NewSpace()
space.BindApp(dns.APP_ID, dns.NewCacheServer(space, &dns.Config{}))
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, proxyman.NewDefaultOutboundHandlerManager())
r := NewRouter(config, space)
space.BindApp(APP_ID, r)
assert.Error(space.Initialize()).IsNil()
tag, err := r.TakeDetour(&proxy.SessionInfo{Destination: v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80)})
assert.Error(err).IsNil()
assert.String(tag).Equals("test")
}

View File

@@ -1,4 +1,4 @@
package rules
package router
import (
"sync"

View File

@@ -1,10 +0,0 @@
package rules
//go:generate go run chinaip_gen.go
func NewChinaIPRule(tag string) *Rule {
return &Rule{
Tag: tag,
Condition: NewIPv4Matcher(chinaIPNet),
}
}

View File

@@ -1,83 +0,0 @@
// +build generate
package main
import (
"bufio"
"fmt"
"log"
"math"
"net"
"net/http"
"os"
"strconv"
"strings"
v2net "github.com/v2ray/v2ray-core/common/net"
)
const (
apnicFile = "http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest"
)
func main() {
resp, err := http.Get(apnicFile)
if err != nil {
panic(err)
}
if resp.StatusCode != 200 {
panic(fmt.Errorf("Unexpected status %d", resp.StatusCode))
}
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
ipNet := v2net.NewIPNet()
for scanner.Scan() {
line := scanner.Text()
line = strings.TrimSpace(line)
parts := strings.Split(line, "|")
if len(parts) < 5 {
continue
}
if strings.ToLower(parts[1]) != "cn" || strings.ToLower(parts[2]) != "ipv4" {
continue
}
ip := parts[3]
count, err := strconv.Atoi(parts[4])
if err != nil {
continue
}
mask := 32 - int(math.Floor(math.Log2(float64(count))+0.5))
cidr := fmt.Sprintf("%s/%d", ip, mask)
_, t, err := net.ParseCIDR(cidr)
if err != nil {
panic(err)
}
ipNet.Add(t)
}
dump := ipNet.Serialize()
file, err := os.OpenFile("chinaip_init.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
log.Fatalf("Failed to generate chinaip_init.go: %v", err)
}
defer file.Close()
fmt.Fprintln(file, "package rules")
fmt.Fprintln(file, "import (")
fmt.Fprintln(file, "v2net \"github.com/v2ray/v2ray-core/common/net\"")
fmt.Fprintln(file, ")")
fmt.Fprintln(file, "var (")
fmt.Fprintln(file, "chinaIPNet *v2net.IPNet")
fmt.Fprintln(file, ")")
fmt.Fprintln(file, "func init() {")
fmt.Fprintln(file, "chinaIPNet = v2net.NewIPNetInitialValue(map[uint32]byte {")
for i := 0; i < len(dump); i += 2 {
fmt.Fprintln(file, dump[i], ": ", dump[i+1], ",")
}
fmt.Fprintln(file, "})")
fmt.Fprintln(file, "}")
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +0,0 @@
// +build json
package rules
import (
"encoding/json"
"github.com/v2ray/v2ray-core/common/log"
)
func parseChinaIPRule(data []byte) (*Rule, error) {
rawRule := new(JsonRule)
err := json.Unmarshal(data, rawRule)
if err != nil {
log.Error("Router: Invalid router rule: ", err)
return nil, err
}
return NewChinaIPRule(rawRule.OutboundTag), nil
}

View File

@@ -1,26 +0,0 @@
// +build json
package rules_test
import (
"testing"
. "github.com/v2ray/v2ray-core/app/router/rules"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestChinaIPJson(t *testing.T) {
assert := assert.On(t)
rule := ParseRule([]byte(`{
"type": "chinaip",
"outboundTag": "x"
}`))
assert.String(rule.Tag).Equals("x")
assert.Bool(rule.Apply(makeDestination("121.14.1.189"))).IsTrue() // sina.com.cn
assert.Bool(rule.Apply(makeDestination("101.226.103.106"))).IsTrue() // qq.com
assert.Bool(rule.Apply(makeDestination("115.239.210.36"))).IsTrue() // image.baidu.com
assert.Bool(rule.Apply(makeDestination("120.135.126.1"))).IsTrue()
assert.Bool(rule.Apply(makeDestination("8.8.8.8"))).IsFalse()
}

View File

@@ -1,27 +0,0 @@
package rules_test
import (
"net"
"testing"
. "github.com/v2ray/v2ray-core/app/router/rules"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func makeDestination(ip string) v2net.Destination {
return v2net.TCPDestination(v2net.IPAddress(net.ParseIP(ip)), 80)
}
func TestChinaIP(t *testing.T) {
assert := assert.On(t)
rule := NewChinaIPRule("tag")
assert.Bool(rule.Apply(makeDestination("121.14.1.189"))).IsTrue() // sina.com.cn
assert.Bool(rule.Apply(makeDestination("101.226.103.106"))).IsTrue() // qq.com
assert.Bool(rule.Apply(makeDestination("115.239.210.36"))).IsTrue() // image.baidu.com
assert.Bool(rule.Apply(makeDestination("120.135.126.1"))).IsTrue()
assert.Bool(rule.Apply(makeDestination("101.201.173.126"))).IsTrue()
assert.Bool(rule.Apply(makeDestination("8.8.8.8"))).IsFalse()
}

View File

@@ -1,21 +0,0 @@
// +build json
package rules
import (
"encoding/json"
"github.com/v2ray/v2ray-core/common/log"
)
func parseChinaSitesRule(data []byte) (*Rule, error) {
rawRule := new(JsonRule)
err := json.Unmarshal(data, rawRule)
if err != nil {
log.Error("Router: Invalid router rule: ", err)
return nil, err
}
return &Rule{
Tag: rawRule.OutboundTag,
Condition: chinaSitesConds,
}, nil
}

View File

@@ -1,26 +0,0 @@
// +build json
package rules_test
import (
"testing"
. "github.com/v2ray/v2ray-core/app/router/rules"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestChinaSitesJson(t *testing.T) {
assert := assert.On(t)
rule := ParseRule([]byte(`{
"type": "chinasites",
"outboundTag": "y"
}`))
assert.String(rule.Tag).Equals("y")
assert.Bool(rule.Apply(makeDomainDestination("v.qq.com"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("www.163.com"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("ngacn.cc"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("12306.cn"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("v2ray.com"))).IsFalse()
}

View File

@@ -1,25 +0,0 @@
package rules_test
import (
"testing"
. "github.com/v2ray/v2ray-core/app/router/rules"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func makeDomainDestination(domain string) v2net.Destination {
return v2net.TCPDestination(v2net.DomainAddress(domain), 80)
}
func TestChinaSites(t *testing.T) {
assert := assert.On(t)
rule := NewChinaSitesRule("tag")
assert.Bool(rule.Apply(makeDomainDestination("v.qq.com"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("www.163.com"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("ngacn.cc"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("12306.cn"))).IsTrue()
assert.Bool(rule.Apply(makeDomainDestination("v2ray.com"))).IsFalse()
}

View File

@@ -1,169 +0,0 @@
package rules
import (
"net"
"regexp"
"strings"
v2net "github.com/v2ray/v2ray-core/common/net"
)
type Condition interface {
Apply(dest v2net.Destination) bool
}
type ConditionChan []Condition
func NewConditionChan() *ConditionChan {
var condChan ConditionChan = make([]Condition, 0, 8)
return &condChan
}
func (this *ConditionChan) Add(cond Condition) *ConditionChan {
*this = append(*this, cond)
return this
}
func (this *ConditionChan) Apply(dest v2net.Destination) bool {
for _, cond := range *this {
if !cond.Apply(dest) {
return false
}
}
return true
}
func (this *ConditionChan) Len() int {
return len(*this)
}
type AnyCondition []Condition
func NewAnyCondition() *AnyCondition {
var anyCond AnyCondition = make([]Condition, 0, 8)
return &anyCond
}
func (this *AnyCondition) Add(cond Condition) *AnyCondition {
*this = append(*this, cond)
return this
}
func (this *AnyCondition) Apply(dest v2net.Destination) bool {
for _, cond := range *this {
if cond.Apply(dest) {
return true
}
}
return false
}
func (this *AnyCondition) Len() int {
return len(*this)
}
type PlainDomainMatcher struct {
pattern string
}
func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
return &PlainDomainMatcher{
pattern: pattern,
}
}
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
if !dest.Address().Family().IsDomain() {
return false
}
domain := dest.Address().Domain()
return strings.Contains(domain, this.pattern)
}
type RegexpDomainMatcher struct {
pattern *regexp.Regexp
}
func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
r, err := regexp.Compile(pattern)
if err != nil {
return nil, err
}
return &RegexpDomainMatcher{
pattern: r,
}, nil
}
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
if !dest.Address().Family().IsDomain() {
return false
}
domain := dest.Address().Domain()
return this.pattern.MatchString(strings.ToLower(domain))
}
type CIDRMatcher struct {
cidr *net.IPNet
}
func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {
_, cidr, err := net.ParseCIDR(ipnet)
if err != nil {
return nil, err
}
return &CIDRMatcher{
cidr: cidr,
}, nil
}
func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
if !dest.Address().Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
return false
}
return this.cidr.Contains(dest.Address().IP())
}
type IPv4Matcher struct {
ipv4net *v2net.IPNet
}
func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {
return &IPv4Matcher{
ipv4net: ipnet,
}
}
func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
if !dest.Address().Family().Either(v2net.AddressFamilyIPv4) {
return false
}
return this.ipv4net.Contains(dest.Address().IP())
}
type PortMatcher struct {
port v2net.PortRange
}
func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
return &PortMatcher{
port: portRange,
}
}
func (this *PortMatcher) Apply(dest v2net.Destination) bool {
return this.port.Contains(dest.Port())
}
type NetworkMatcher struct {
network *v2net.NetworkList
}
func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
return &NetworkMatcher{
network: network,
}
}
func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {
return this.network.HasNetwork(dest.Network())
}

View File

@@ -1,27 +0,0 @@
package rules
import (
v2net "github.com/v2ray/v2ray-core/common/net"
)
type Rule struct {
Tag string
Condition Condition
}
func (this *Rule) Apply(dest v2net.Destination) bool {
return this.Condition.Apply(dest)
}
type DomainStrategy int
var (
DomainAsIs = DomainStrategy(0)
AlwaysUseIP = DomainStrategy(1)
UseIPIfNonMatch = DomainStrategy(2)
)
type RouterRuleConfig struct {
Rules []*Rule
DomainStrategy DomainStrategy
}

View File

@@ -1,143 +0,0 @@
// +build json
package rules
import (
"encoding/json"
"errors"
"strings"
router "github.com/v2ray/v2ray-core/app/router"
"github.com/v2ray/v2ray-core/common/collect"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
)
type JsonRule struct {
Type string `json:"type"`
OutboundTag string `json:"outboundTag"`
}
func parseFieldRule(msg json.RawMessage) (*Rule, error) {
type RawFieldRule struct {
JsonRule
Domain *collect.StringList `json:"domain"`
IP *collect.StringList `json:"ip"`
Port *v2net.PortRange `json:"port"`
Network *v2net.NetworkList `json:"network"`
}
rawFieldRule := new(RawFieldRule)
err := json.Unmarshal(msg, rawFieldRule)
if err != nil {
return nil, err
}
conds := NewConditionChan()
if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 {
anyCond := NewAnyCondition()
for _, rawDomain := range *(rawFieldRule.Domain) {
var matcher Condition
if strings.HasPrefix(rawDomain, "regexp:") {
rawMatcher, err := NewRegexpDomainMatcher(rawDomain[7:])
if err != nil {
return nil, err
}
matcher = rawMatcher
} else {
matcher = NewPlainDomainMatcher(rawDomain)
}
anyCond.Add(matcher)
}
conds.Add(anyCond)
}
if rawFieldRule.IP != nil && rawFieldRule.IP.Len() > 0 {
anyCond := NewAnyCondition()
for _, ipStr := range *(rawFieldRule.IP) {
cidrMatcher, err := NewCIDRMatcher(ipStr)
if err != nil {
log.Error("Router: Invalid IP range in router rule: ", err)
return nil, err
}
anyCond.Add(cidrMatcher)
}
conds.Add(anyCond)
}
if rawFieldRule.Port != nil {
conds.Add(NewPortMatcher(*rawFieldRule.Port))
}
if rawFieldRule.Network != nil {
conds.Add(NewNetworkMatcher(rawFieldRule.Network))
}
if conds.Len() == 0 {
return nil, errors.New("Router: This rule has no effective fields.")
}
return &Rule{
Tag: rawFieldRule.OutboundTag,
Condition: conds,
}, nil
}
func ParseRule(msg json.RawMessage) *Rule {
rawRule := new(JsonRule)
err := json.Unmarshal(msg, rawRule)
if err != nil {
log.Error("Router: Invalid router rule: ", err)
return nil
}
if rawRule.Type == "field" {
fieldrule, err := parseFieldRule(msg)
if err != nil {
log.Error("Invalid field rule: ", err)
return nil
}
return fieldrule
}
if rawRule.Type == "chinaip" {
chinaiprule, err := parseChinaIPRule(msg)
if err != nil {
log.Error("Router: Invalid chinaip rule: ", err)
return nil
}
return chinaiprule
}
if rawRule.Type == "chinasites" {
chinasitesrule, err := parseChinaSitesRule(msg)
if err != nil {
log.Error("Invalid chinasites rule: ", err)
return nil
}
return chinasitesrule
}
log.Error("Unknown router rule type: ", rawRule.Type)
return nil
}
func init() {
router.RegisterRouterConfig("rules", func(data []byte) (interface{}, error) {
type JsonConfig struct {
RuleList []json.RawMessage `json:"rules"`
DomainStrategy string `json:"domainStrategy"`
}
jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return nil, err
}
config := &RouterRuleConfig{
Rules: make([]*Rule, len(jsonConfig.RuleList)),
DomainStrategy: DomainAsIs,
}
domainStrategy := strings.ToLower(jsonConfig.DomainStrategy)
if domainStrategy == "alwaysip" {
config.DomainStrategy = AlwaysUseIP
} else if domainStrategy == "ipifnonmatch" {
config.DomainStrategy = UseIPIfNonMatch
}
for idx, rawRule := range jsonConfig.RuleList {
rule := ParseRule(rawRule)
config.Rules[idx] = rule
}
return config, nil
})
}

View File

@@ -1,51 +0,0 @@
// +build json
package rules_test
import (
"testing"
. "github.com/v2ray/v2ray-core/app/router/rules"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestDomainRule(t *testing.T) {
assert := assert.On(t)
rule := ParseRule([]byte(`{
"type": "field",
"domain": [
"ooxx.com",
"oxox.com",
"regexp:\\.cn$"
],
"network": "tcp",
"outboundTag": "direct"
}`))
assert.Pointer(rule).IsNotNil()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.ooxx.com"), 80))).IsTrue()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.aabb.com"), 80))).IsFalse()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80))).IsFalse()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.12306.cn"), 80))).IsTrue()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.acn.com"), 80))).IsFalse()
}
func TestIPRule(t *testing.T) {
assert := assert.On(t)
rule := ParseRule([]byte(`{
"type": "field",
"ip": [
"10.0.0.0/8",
"192.0.0.0/24"
],
"network": "tcp",
"outboundTag": "direct"
}`))
assert.Pointer(rule).IsNotNil()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.ooxx.com"), 80))).IsFalse()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80))).IsTrue()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80))).IsFalse()
assert.Bool(rule.Apply(v2net.TCPDestination(v2net.IPAddress([]byte{192, 0, 0, 1}), 80))).IsTrue()
}

View File

@@ -1,105 +0,0 @@
package rules
import (
"errors"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dns"
"github.com/v2ray/v2ray-core/app/router"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
)
var (
ErrInvalidRule = errors.New("Invalid Rule")
ErrNoRuleApplicable = errors.New("No rule applicable")
)
type Router struct {
config *RouterRuleConfig
cache *RoutingTable
dnsServer dns.Server
}
func NewRouter(config *RouterRuleConfig, space app.Space) *Router {
r := &Router{
config: config,
cache: NewRoutingTable(),
}
space.InitializeApplication(func() error {
if !space.HasApp(dns.APP_ID) {
log.Error("DNS: Router is not found in the space.")
return app.ErrMissingApplication
}
r.dnsServer = space.GetApp(dns.APP_ID).(dns.Server)
return nil
})
return r
}
func (this *Router) Release() {
}
// @Private
func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
ips := this.dnsServer.Get(dest.Address().Domain())
if len(ips) == 0 {
return nil
}
dests := make([]v2net.Destination, len(ips))
for idx, ip := range ips {
if dest.IsTCP() {
dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port())
} else {
dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port())
}
}
return dests
}
func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
for _, rule := range this.config.Rules {
if rule.Apply(dest) {
return rule.Tag, nil
}
}
if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().Family().IsDomain() {
log.Info("Router: Looking up IP for ", dest)
ipDests := this.ResolveIP(dest)
if ipDests != nil {
for _, ipDest := range ipDests {
log.Info("Router: Trying IP ", ipDest)
for _, rule := range this.config.Rules {
if rule.Apply(ipDest) {
return rule.Tag, nil
}
}
}
}
}
return "", ErrNoRuleApplicable
}
func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
destStr := dest.String()
found, tag, err := this.cache.Get(destStr)
if !found {
tag, err := this.takeDetourWithoutCache(dest)
this.cache.Set(destStr, tag, err)
return tag, err
}
return tag, err
}
type RouterFactory struct {
}
func (this *RouterFactory) Create(rawConfig interface{}, space app.Space) (router.Router, error) {
return NewRouter(rawConfig.(*RouterRuleConfig), space), nil
}
func init() {
router.RegisterRouter("rules", &RouterFactory{})
}

View File

@@ -1,40 +0,0 @@
package rules_test
import (
"testing"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
dispatchers "github.com/v2ray/v2ray-core/app/dispatcher/impl"
"github.com/v2ray/v2ray-core/app/dns"
"github.com/v2ray/v2ray-core/app/proxyman"
"github.com/v2ray/v2ray-core/app/router"
. "github.com/v2ray/v2ray-core/app/router/rules"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestSimpleRouter(t *testing.T) {
assert := assert.On(t)
config := &RouterRuleConfig{
Rules: []*Rule{
{
Tag: "test",
Condition: NewNetworkMatcher(v2net.Network("tcp").AsList()),
},
},
}
space := app.NewSpace()
space.BindApp(dns.APP_ID, dns.NewCacheServer(space, &dns.Config{}))
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, proxyman.NewDefaultOutboundHandlerManager())
r := NewRouter(config, space)
space.BindApp(router.APP_ID, r)
assert.Error(space.Initialize()).IsNil()
tag, err := r.TakeDetour(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80))
assert.Error(err).IsNil()
assert.String(tag).Equals("test")
}

View File

@@ -3,7 +3,7 @@ package app
import (
"errors"
"github.com/v2ray/v2ray-core/common"
"v2ray.com/core/common"
)
var (
@@ -26,6 +26,19 @@ type Application interface {
}
type ApplicationInitializer func() error
type ApplicationFactory interface {
Create(space Space, config interface{}) (Application, error)
AppId() ID
}
var (
applicationFactoryCache = make(map[string]ApplicationFactory)
)
func RegisterApplicationFactory(name string, factory ApplicationFactory) error {
applicationFactoryCache[name] = factory
return nil
}
// A Space contains all apps that may be available in a V2Ray runtime.
// Caller must check the availability of an app by calling HasXXX before getting its instance.
@@ -36,6 +49,7 @@ type Space interface {
HasApp(ID) bool
GetApp(ID) Application
BindApp(ID, Application)
BindFromConfig(name string, config interface{}) error
}
type spaceImpl struct {
@@ -80,3 +94,16 @@ func (this *spaceImpl) GetApp(id ID) Application {
func (this *spaceImpl) BindApp(id ID, application Application) {
this.cache[id] = application
}
func (this *spaceImpl) BindFromConfig(name string, config interface{}) error {
factory, found := applicationFactoryCache[name]
if !found {
return errors.New("Space: app not registered: " + name)
}
app, err := factory.Create(this, config)
if err != nil {
return err
}
this.BindApp(factory.AppId(), app)
return nil
}

View File

@@ -5,7 +5,7 @@ import (
"hash"
"io"
"github.com/v2ray/v2ray-core/common/serial"
"v2ray.com/core/common/serial"
)
const (
@@ -52,6 +52,7 @@ func (b *Buffer) Clear() *Buffer {
return b
}
// Reset resets this Buffer into its original state.
func (b *Buffer) Reset() *Buffer {
b.offset = defaultOffset
b.Value = b.head
@@ -199,11 +200,6 @@ func (b *Buffer) String() string {
return string(b.Value)
}
// NewSmallBuffer creates a Buffer with 1K bytes of arbitrary content.
func NewSmallBuffer() *Buffer {
return smallPool.Allocate()
}
// NewBuffer creates a Buffer with 8K bytes of arbitrary content.
func NewBuffer() *Buffer {
return mediumPool.Allocate()
@@ -215,10 +211,6 @@ func NewLargeBuffer() *Buffer {
}
func NewBufferWithSize(size int) *Buffer {
if size <= SmallBufferSize {
return NewSmallBuffer()
}
if size <= BufferSize {
return NewBuffer()
}

View File

@@ -1,6 +1,8 @@
package alloc
import (
"os"
"strconv"
"sync"
)
@@ -14,14 +16,14 @@ type BufferPool struct {
allocator *sync.Pool
}
func NewBufferPool(bufferSize, poolSize int) *BufferPool {
func NewBufferPool(bufferSize, poolSize uint32) *BufferPool {
pool := &BufferPool{
chain: make(chan []byte, poolSize),
allocator: &sync.Pool{
New: func() interface{} { return make([]byte, bufferSize) },
},
}
for i := 0; i < poolSize; i++ {
for i := uint32(0); i < poolSize; i++ {
pool.chain <- make([]byte, bufferSize)
}
return pool
@@ -50,11 +52,30 @@ func (p *BufferPool) Free(buffer *Buffer) {
}
const (
SmallBufferSize = 1600 - defaultOffset
BufferSize = 8*1024 - defaultOffset
LargeBufferSize = 64*1024 - defaultOffset
mediumBufferByteSize = 8 * 1024
BufferSize = mediumBufferByteSize - defaultOffset
largeBufferByteSize = 64 * 1024
LargeBufferSize = largeBufferByteSize - defaultOffset
PoolSizeEnvKey = "v2ray.buffer.size"
)
var smallPool = NewBufferPool(1600, 256)
var mediumPool = NewBufferPool(8*1024, 1024)
var largePool = NewBufferPool(64*1024, 32)
var (
mediumPool *BufferPool
largePool *BufferPool
)
func init() {
var size uint32 = 20
sizeStr := os.Getenv(PoolSizeEnvKey)
if len(sizeStr) > 0 {
customSize, err := strconv.ParseUint(sizeStr, 10, 32)
if err == nil {
size = uint32(customSize)
}
}
totalByteSize := size * 1024 * 1024
mediumPool = NewBufferPool(mediumBufferByteSize, totalByteSize/4*3/mediumBufferByteSize)
largePool = NewBufferPool(largeBufferByteSize, totalByteSize/4/largeBufferByteSize)
}

View File

@@ -3,8 +3,8 @@ package alloc_test
import (
"testing"
. "github.com/v2ray/v2ray-core/common/alloc"
"github.com/v2ray/v2ray-core/testing/assert"
. "v2ray.com/core/common/alloc"
"v2ray.com/core/testing/assert"
)
func TestBufferClear(t *testing.T) {

View File

@@ -1,12 +0,0 @@
package collect
type StringList []string
func NewStringList(raw []string) *StringList {
list := StringList(raw)
return &list
}
func (this *StringList) Len() int {
return len(*this)
}

View File

@@ -1,25 +0,0 @@
// +build json
package collect
import (
"encoding/json"
"errors"
"strings"
)
func (this *StringList) UnmarshalJSON(data []byte) error {
var strarray []string
if err := json.Unmarshal(data, &strarray); err == nil {
*this = *NewStringList(strarray)
return nil
}
var rawstr string
if err := json.Unmarshal(data, &rawstr); err == nil {
strlist := strings.Split(rawstr, ",")
*this = *NewStringList(strlist)
return nil
}
return errors.New("Unknown format of a string list: " + string(data))
}

View File

@@ -1,20 +0,0 @@
// +build json
package collect_test
import (
"encoding/json"
"testing"
. "github.com/v2ray/v2ray-core/common/collect"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestStringListUnmarshalError(t *testing.T) {
assert := assert.On(t)
rawJson := `1234`
list := new(StringList)
err := json.Unmarshal([]byte(rawJson), list)
assert.Error(err).IsNotNil()
}

View File

@@ -9,6 +9,8 @@ import (
var (
ErrObjectReleased = errors.New("Object already released.")
ErrBadConfiguration = errors.New("Bad configuration.")
ErrObjectNotFound = errors.New("Object not found.")
ErrDuplicatedName = errors.New("Duplicated name.")
)
// Releasable interface is for those types that can release its members.

View File

@@ -4,7 +4,7 @@ import (
"crypto/cipher"
"testing"
. "github.com/v2ray/v2ray-core/common/crypto"
. "v2ray.com/core/common/crypto"
)
const benchSize = 1024 * 1024
@@ -13,6 +13,7 @@ func benchmarkStream(b *testing.B, c cipher.Stream) {
b.SetBytes(benchSize)
input := make([]byte, benchSize)
output := make([]byte, benchSize)
b.ResetTimer()
for i := 0; i < b.N; i++ {
c.XORKeyStream(output, input)
}

View File

@@ -3,7 +3,7 @@ package crypto
import (
"crypto/cipher"
"github.com/v2ray/v2ray-core/common/crypto/internal"
"v2ray.com/core/common/crypto/internal"
)
// NewChaCha20Stream creates a new Chacha20 encryption/descryption stream based on give key and IV.

View File

@@ -5,8 +5,8 @@ import (
"encoding/hex"
"testing"
. "github.com/v2ray/v2ray-core/common/crypto"
"github.com/v2ray/v2ray-core/testing/assert"
. "v2ray.com/core/common/crypto"
"v2ray.com/core/testing/assert"
)
func mustDecodeHex(s string) []byte {

3
common/crypto/crypto.go Normal file
View File

@@ -0,0 +1,3 @@
// Provides common crypto libraries for V2Ray.
package crypto

View File

@@ -4,7 +4,7 @@ import (
"crypto/cipher"
"io"
"github.com/v2ray/v2ray-core/common"
"v2ray.com/core/common"
)
type CryptionReader struct {

View File

@@ -4,7 +4,7 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/common/alloc"
"v2ray.com/core/common/alloc"
)
type BufferedReader struct {

View File

@@ -3,9 +3,9 @@ package io_test
import (
"testing"
"github.com/v2ray/v2ray-core/common/alloc"
. "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/testing/assert"
"v2ray.com/core/common/alloc"
. "v2ray.com/core/common/io"
"v2ray.com/core/testing/assert"
)
func TestBufferedReader(t *testing.T) {

View File

@@ -4,7 +4,7 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/common/alloc"
"v2ray.com/core/common/alloc"
)
type BufferedWriter struct {

View File

@@ -3,9 +3,9 @@ package io_test
import (
"testing"
"github.com/v2ray/v2ray-core/common/alloc"
. "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/testing/assert"
"v2ray.com/core/common/alloc"
. "v2ray.com/core/common/io"
"v2ray.com/core/testing/assert"
)
func TestBufferedWriter(t *testing.T) {

View File

@@ -4,7 +4,7 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/common/alloc"
"v2ray.com/core/common/alloc"
)
type ChainWriter struct {

View File

@@ -4,7 +4,7 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/common/alloc"
"v2ray.com/core/common/alloc"
)
type ChanReader struct {
@@ -15,14 +15,12 @@ type ChanReader struct {
}
func NewChanReader(stream Reader) *ChanReader {
this := &ChanReader{
return &ChanReader{
stream: stream,
}
this.Fill()
return this
}
// @Private
// Private: Visible for testing.
func (this *ChanReader) Fill() {
b, err := this.stream.Read()
this.current = b

View File

@@ -1,10 +1,10 @@
package io // import "github.com/v2ray/v2ray-core/common/io"
package io
import (
"io"
"github.com/v2ray/v2ray-core/common"
"github.com/v2ray/v2ray-core/common/alloc"
"v2ray.com/core/common"
"v2ray.com/core/common/alloc"
)
// Reader extends io.Reader with alloc.Buffer.

View File

@@ -4,9 +4,9 @@ import (
"bytes"
"testing"
"github.com/v2ray/v2ray-core/common/alloc"
. "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/testing/assert"
"v2ray.com/core/common/alloc"
. "v2ray.com/core/common/io"
"v2ray.com/core/testing/assert"
)
func TestAdaptiveReader(t *testing.T) {

View File

@@ -1,7 +1,7 @@
package io
import (
"github.com/v2ray/v2ray-core/common/log"
"v2ray.com/core/common/log"
)
func Pipe(reader Reader, writer Writer) error {

View File

@@ -3,8 +3,8 @@ package io
import (
"io"
"github.com/v2ray/v2ray-core/common"
"github.com/v2ray/v2ray-core/common/alloc"
"v2ray.com/core/common"
"v2ray.com/core/common/alloc"
)
// Writer extends io.Writer with alloc.Buffer.

View File

@@ -5,9 +5,9 @@ import (
"crypto/rand"
"testing"
"github.com/v2ray/v2ray-core/common/alloc"
. "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/testing/assert"
"v2ray.com/core/common/alloc"
. "v2ray.com/core/common/io"
"v2ray.com/core/testing/assert"
)
func TestAdaptiveWriter(t *testing.T) {

View File

@@ -1,47 +0,0 @@
package loader
import (
"errors"
)
var (
ErrConfigIDKeyNotFound = errors.New("Config ID key is not found.")
ErrConfigIDExists = errors.New("Config ID already exists.")
ErrUnknownConfigID = errors.New("Unknown config ID.")
)
type ConfigCreator func() interface{}
type ConfigLoader interface {
RegisterCreator(string, ConfigCreator) error
CreateConfig(string) (interface{}, error)
Load([]byte) (interface{}, string, error)
LoadWithID([]byte, string) (interface{}, error)
}
type BaseConfigLoader struct {
creators map[string]ConfigCreator
}
func NewBaseConfigLoader() *BaseConfigLoader {
return &BaseConfigLoader{
creators: make(map[string]ConfigCreator),
}
}
func (this *BaseConfigLoader) RegisterCreator(id string, creator ConfigCreator) error {
if _, found := this.creators[id]; found {
return ErrConfigIDExists
}
this.creators[id] = creator
return nil
}
func (this *BaseConfigLoader) CreateConfig(id string) (interface{}, error) {
creator, found := this.creators[id]
if !found {
return nil, ErrUnknownConfigID
}
return creator(), nil
}

50
common/loader/type.go Normal file
View File

@@ -0,0 +1,50 @@
package loader
import (
"errors"
"reflect"
"github.com/golang/protobuf/proto"
)
func NewTypedSettings(message proto.Message) *TypedSettings {
if message == nil {
return nil
}
settings, _ := proto.Marshal(message)
return &TypedSettings{
Type: GetType(message),
Settings: settings,
}
}
func GetType(message proto.Message) string {
return proto.MessageName(message)
}
func GetInstance(messageType string) (interface{}, error) {
mType := proto.MessageType(messageType).Elem()
if mType == nil {
return nil, errors.New("Unknown type: " + messageType)
}
return reflect.New(mType).Interface(), nil
}
func (this *TypedSettings) Load(message proto.Message) error {
targetType := GetType(message)
if targetType != this.Type {
return errors.New("Have type " + this.Type + ", but retrieved for " + targetType)
}
return proto.Unmarshal(this.Settings, message)
}
func (this *TypedSettings) GetInstance() (interface{}, error) {
instance, err := GetInstance(this.Type)
if err != nil {
return nil, err
}
if err := proto.Unmarshal(this.Settings, instance.(proto.Message)); err != nil {
return nil, err
}
return instance, nil
}

62
common/loader/type.pb.go Normal file
View File

@@ -0,0 +1,62 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/loader/type.proto
// DO NOT EDIT!
/*
Package loader is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/loader/type.proto
It has these top-level messages:
TypedSettings
*/
package loader
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Serialized proto message along with its type name.
type TypedSettings struct {
// The name of the message type, retrieved from protobuf API.
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
// Serialized proto message.
Settings []byte `protobuf:"bytes,2,opt,name=settings,proto3" json:"settings,omitempty"`
}
func (m *TypedSettings) Reset() { *m = TypedSettings{} }
func (m *TypedSettings) String() string { return proto.CompactTextString(m) }
func (*TypedSettings) ProtoMessage() {}
func (*TypedSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterType((*TypedSettings)(nil), "v2ray.core.common.loader.TypedSettings")
}
func init() { proto.RegisterFile("v2ray.com/core/common/loader/type.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 151 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2f, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd,
0xcf, 0xd3, 0xcf, 0xc9, 0x4f, 0x4c, 0x49, 0x2d, 0xd2, 0x2f, 0xa9, 0x2c, 0x48, 0xd5, 0x2b, 0x28,
0xca, 0x2f, 0xc9, 0x17, 0x92, 0x80, 0x29, 0x2c, 0x4a, 0xd5, 0x83, 0x28, 0xd2, 0x83, 0x28, 0x52,
0xb2, 0xe7, 0xe2, 0x0d, 0xa9, 0x2c, 0x48, 0x4d, 0x09, 0x4e, 0x2d, 0x29, 0xc9, 0xcc, 0x4b, 0x2f,
0x16, 0x12, 0xe2, 0x62, 0x01, 0x69, 0x94, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85,
0xa4, 0xb8, 0x38, 0x8a, 0xa1, 0xf2, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, 0x70, 0xbe, 0x93,
0x21, 0x97, 0x4c, 0x72, 0x7e, 0xae, 0x1e, 0x2e, 0x0b, 0x9c, 0x38, 0x41, 0xc6, 0x07, 0x80, 0x5c,
0x11, 0xc5, 0x06, 0x11, 0x4a, 0x62, 0x03, 0x3b, 0xca, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x24,
0xa2, 0x4d, 0x76, 0xbf, 0x00, 0x00, 0x00,
}

14
common/loader/type.proto Normal file
View File

@@ -0,0 +1,14 @@
syntax = "proto3";
package v2ray.core.common.loader;
option go_package = "loader";
option java_package = "com.v2ray.core.common.loader";
option java_outer_classname = "TypeProto";
// Serialized proto message along with its type name.
message TypedSettings {
// The name of the message type, retrieved from protobuf API.
string type = 1;
// Serialized proto message.
bytes settings = 2;
}

View File

@@ -1,7 +1,7 @@
package log
import (
"github.com/v2ray/v2ray-core/common/log/internal"
"v2ray.com/core/common/log/internal"
)
// AccessStatus is the status of an access request from clients.

25
common/log/config.go Normal file
View File

@@ -0,0 +1,25 @@
package log
func (this *Config) Apply() error {
if this == nil {
return nil
}
if this.AccessLogType == LogType_File {
if err := InitAccessLogger(this.AccessLogPath); err != nil {
return err
}
}
if this.ErrorLogType == LogType_None {
SetLogLevel(LogLevel_Disabled)
} else {
if this.ErrorLogType == LogType_File {
if err := InitErrorLogger(this.ErrorLogPath); err != nil {
return err
}
}
SetLogLevel(this.ErrorLogLevel)
}
return nil
}

132
common/log/config.pb.go Normal file
View File

@@ -0,0 +1,132 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/log/config.proto
// DO NOT EDIT!
/*
Package log is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/log/config.proto
It has these top-level messages:
Config
*/
package log
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type LogType int32
const (
LogType_None LogType = 0
LogType_Console LogType = 1
LogType_File LogType = 2
LogType_Event LogType = 3
)
var LogType_name = map[int32]string{
0: "None",
1: "Console",
2: "File",
3: "Event",
}
var LogType_value = map[string]int32{
"None": 0,
"Console": 1,
"File": 2,
"Event": 3,
}
func (x LogType) String() string {
return proto.EnumName(LogType_name, int32(x))
}
func (LogType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type LogLevel int32
const (
LogLevel_Disabled LogLevel = 0
LogLevel_Error LogLevel = 1
LogLevel_Warning LogLevel = 2
LogLevel_Info LogLevel = 3
LogLevel_Debug LogLevel = 4
)
var LogLevel_name = map[int32]string{
0: "Disabled",
1: "Error",
2: "Warning",
3: "Info",
4: "Debug",
}
var LogLevel_value = map[string]int32{
"Disabled": 0,
"Error": 1,
"Warning": 2,
"Info": 3,
"Debug": 4,
}
func (x LogLevel) String() string {
return proto.EnumName(LogLevel_name, int32(x))
}
func (LogLevel) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type Config struct {
ErrorLogType LogType `protobuf:"varint,1,opt,name=error_log_type,json=errorLogType,enum=v2ray.core.common.log.LogType" json:"error_log_type,omitempty"`
ErrorLogLevel LogLevel `protobuf:"varint,2,opt,name=error_log_level,json=errorLogLevel,enum=v2ray.core.common.log.LogLevel" json:"error_log_level,omitempty"`
ErrorLogPath string `protobuf:"bytes,3,opt,name=error_log_path,json=errorLogPath" json:"error_log_path,omitempty"`
AccessLogType LogType `protobuf:"varint,4,opt,name=access_log_type,json=accessLogType,enum=v2ray.core.common.log.LogType" json:"access_log_type,omitempty"`
AccessLogPath string `protobuf:"bytes,5,opt,name=access_log_path,json=accessLogPath" json:"access_log_path,omitempty"`
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.common.log.Config")
proto.RegisterEnum("v2ray.core.common.log.LogType", LogType_name, LogType_value)
proto.RegisterEnum("v2ray.core.common.log.LogLevel", LogLevel_name, LogLevel_value)
}
func init() { proto.RegisterFile("v2ray.com/core/common/log/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 322 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x91, 0x6d, 0x4b, 0xf3, 0x30,
0x14, 0x86, 0xd7, 0x76, 0xaf, 0xd9, 0x5b, 0x08, 0x3c, 0xb0, 0xe7, 0x8b, 0x0e, 0x91, 0x31, 0x06,
0xb6, 0x30, 0xf1, 0x0f, 0xec, 0x4d, 0x84, 0x21, 0x63, 0x08, 0x82, 0x5f, 0x46, 0x17, 0xcf, 0xb2,
0x42, 0x9a, 0x53, 0xd2, 0x3a, 0xd8, 0x8f, 0xf2, 0x3f, 0x4a, 0x32, 0x6b, 0x15, 0x26, 0xf8, 0x31,
0xe1, 0x3a, 0xd7, 0x7d, 0x1f, 0x0e, 0x19, 0x1c, 0xc6, 0x3a, 0x3c, 0xfa, 0x1c, 0xe3, 0x80, 0xa3,
0x86, 0x80, 0x63, 0x1c, 0xa3, 0x0a, 0x24, 0x8a, 0x80, 0xa3, 0xda, 0x45, 0xc2, 0x4f, 0x34, 0x66,
0xc8, 0xfe, 0xe5, 0x9c, 0x06, 0xff, 0xc4, 0xf8, 0x12, 0xc5, 0xd5, 0xbb, 0x4b, 0xaa, 0x53, 0xcb,
0xb1, 0x19, 0xe9, 0x80, 0xd6, 0xa8, 0x37, 0x12, 0xc5, 0x26, 0x3b, 0x26, 0xd0, 0x73, 0xfa, 0xce,
0xb0, 0x33, 0xbe, 0xf0, 0xcf, 0x8e, 0xfa, 0x4b, 0x14, 0x4f, 0xc7, 0x04, 0xd6, 0x2d, 0x3b, 0xf5,
0xf9, 0x62, 0xf7, 0xa4, 0x5b, 0x58, 0x24, 0x1c, 0x40, 0xf6, 0x5c, 0xab, 0xb9, 0xfc, 0x5d, 0xb3,
0x34, 0xd8, 0xba, 0x9d, 0x7b, 0xec, 0x93, 0x5d, 0x7f, 0xaf, 0x93, 0x84, 0xd9, 0xbe, 0xe7, 0xf5,
0x9d, 0x61, 0xa3, 0x88, 0x5b, 0x85, 0xd9, 0x9e, 0x2d, 0x48, 0x37, 0xe4, 0x1c, 0xd2, 0xb4, 0x68,
0x5d, 0xfe, 0x53, 0xeb, 0xf6, 0x69, 0x2c, 0xaf, 0x3d, 0xf8, 0xe1, 0xb1, 0x71, 0x15, 0x1b, 0x57,
0x70, 0x26, 0x6f, 0x74, 0x47, 0x6a, 0xf9, 0x48, 0x9d, 0x94, 0x1f, 0x51, 0x01, 0x2d, 0xb1, 0x26,
0xa9, 0x4d, 0x51, 0xa5, 0x28, 0x81, 0x3a, 0xe6, 0x7b, 0x11, 0x49, 0xa0, 0x2e, 0x6b, 0x90, 0xca,
0xfc, 0x00, 0x2a, 0xa3, 0xde, 0x68, 0x4e, 0xea, 0x5f, 0x8b, 0xb5, 0x48, 0x7d, 0x16, 0xa5, 0xe1,
0x56, 0xc2, 0x2b, 0x2d, 0x59, 0xc8, 0x2c, 0x44, 0x1d, 0xa3, 0x79, 0x0e, 0xb5, 0x8a, 0x94, 0xa0,
0xae, 0xd1, 0x3c, 0xa8, 0x1d, 0x52, 0xcf, 0x10, 0x33, 0xd8, 0xbe, 0x09, 0x5a, 0x9e, 0xdc, 0x90,
0xff, 0x1c, 0xe3, 0xf3, 0x9b, 0x4d, 0x9a, 0xa7, 0x3b, 0xae, 0xcc, 0xb9, 0x5f, 0x3c, 0x89, 0x62,
0x5b, 0xb5, 0xa7, 0xbf, 0xfd, 0x08, 0x00, 0x00, 0xff, 0xff, 0x11, 0x55, 0x7e, 0x04, 0x24, 0x02,
0x00, 0x00,
}

30
common/log/config.proto Normal file
View File

@@ -0,0 +1,30 @@
syntax = "proto3";
package v2ray.core.common.log;
option go_package = "log";
option java_package = "com.v2ray.core.common.log";
option java_outer_classname = "ConfigProto";
enum LogType {
None = 0;
Console = 1;
File = 2;
Event = 3;
}
enum LogLevel {
Disabled = 0;
Error = 1;
Warning = 2;
Info = 3;
Debug = 4;
}
message Config {
LogType error_log_type = 1;
LogLevel error_log_level = 2;
string error_log_path = 3;
LogType access_log_type = 4;
string access_log_path = 5;
}

View File

@@ -4,8 +4,8 @@ import (
"fmt"
"strings"
"github.com/v2ray/v2ray-core/common"
"github.com/v2ray/v2ray-core/common/serial"
"v2ray.com/core/common"
"v2ray.com/core/common/serial"
)
func InterfaceToString(value interface{}) string {

View File

@@ -3,8 +3,8 @@ package internal_test
import (
"testing"
. "github.com/v2ray/v2ray-core/common/log/internal"
"github.com/v2ray/v2ray-core/testing/assert"
. "v2ray.com/core/common/log/internal"
"v2ray.com/core/testing/assert"
)
func TestAccessLog(t *testing.T) {

View File

@@ -5,8 +5,8 @@ import (
"os"
"time"
"github.com/v2ray/v2ray-core/common/platform"
"github.com/v2ray/v2ray-core/common/signal"
"v2ray.com/core/common/platform"
"v2ray.com/core/common/signal"
)
type LogWriter interface {

View File

@@ -1,17 +1,7 @@
package log
import (
"github.com/v2ray/v2ray-core/common/log/internal"
)
type LogLevel int
const (
DebugLevel = LogLevel(0)
InfoLevel = LogLevel(1)
WarningLevel = LogLevel(2)
ErrorLevel = LogLevel(3)
NoneLevel = LogLevel(999)
"v2ray.com/core/common/log/internal"
)
var (
@@ -25,28 +15,24 @@ var (
func SetLogLevel(level LogLevel) {
debugLogger = new(internal.NoOpLogWriter)
if level <= DebugLevel {
if level >= LogLevel_Debug {
debugLogger = streamLoggerInstance
}
infoLogger = new(internal.NoOpLogWriter)
if level <= InfoLevel {
if level >= LogLevel_Info {
infoLogger = streamLoggerInstance
}
warningLogger = new(internal.NoOpLogWriter)
if level <= WarningLevel {
if level >= LogLevel_Warning {
warningLogger = streamLoggerInstance
}
errorLogger = new(internal.NoOpLogWriter)
if level <= ErrorLevel {
if level >= LogLevel_Error {
errorLogger = streamLoggerInstance
}
if level == NoneLevel {
accessLoggerInstance = new(internal.NoOpLogWriter)
}
}
func InitErrorLogger(file string) error {

View File

@@ -3,8 +3,8 @@ package net
import (
"net"
"github.com/v2ray/v2ray-core/common/log"
"github.com/v2ray/v2ray-core/common/predicate"
"v2ray.com/core/common/log"
"v2ray.com/core/common/predicate"
)
var (
@@ -186,3 +186,16 @@ func (this *domainAddress) Equals(another Address) bool {
}
return this.Domain() == anotherDomain.Domain()
}
func (this *IPOrDomain) AsAddress() Address {
if this == nil {
return nil
}
switch addr := this.Address.(type) {
case *IPOrDomain_Ip:
return IPAddress(addr.Ip)
case *IPOrDomain_Domain:
return DomainAddress(addr.Domain)
}
panic("Common|Net: Invalid address.")
}

169
common/net/address.pb.go Normal file
View File

@@ -0,0 +1,169 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/address.proto
// DO NOT EDIT!
/*
Package net is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/net/address.proto
v2ray.com/core/common/net/destination.proto
v2ray.com/core/common/net/network.proto
v2ray.com/core/common/net/port.proto
It has these top-level messages:
IPOrDomain
Endpoint
NetworkList
PortRange
*/
package net
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type IPOrDomain struct {
// Types that are valid to be assigned to Address:
// *IPOrDomain_Ip
// *IPOrDomain_Domain
Address isIPOrDomain_Address `protobuf_oneof:"address"`
}
func (m *IPOrDomain) Reset() { *m = IPOrDomain{} }
func (m *IPOrDomain) String() string { return proto.CompactTextString(m) }
func (*IPOrDomain) ProtoMessage() {}
func (*IPOrDomain) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type isIPOrDomain_Address interface {
isIPOrDomain_Address()
}
type IPOrDomain_Ip struct {
Ip []byte `protobuf:"bytes,1,opt,name=ip,proto3,oneof"`
}
type IPOrDomain_Domain struct {
Domain string `protobuf:"bytes,2,opt,name=domain,oneof"`
}
func (*IPOrDomain_Ip) isIPOrDomain_Address() {}
func (*IPOrDomain_Domain) isIPOrDomain_Address() {}
func (m *IPOrDomain) GetAddress() isIPOrDomain_Address {
if m != nil {
return m.Address
}
return nil
}
func (m *IPOrDomain) GetIp() []byte {
if x, ok := m.GetAddress().(*IPOrDomain_Ip); ok {
return x.Ip
}
return nil
}
func (m *IPOrDomain) GetDomain() string {
if x, ok := m.GetAddress().(*IPOrDomain_Domain); ok {
return x.Domain
}
return ""
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*IPOrDomain) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _IPOrDomain_OneofMarshaler, _IPOrDomain_OneofUnmarshaler, _IPOrDomain_OneofSizer, []interface{}{
(*IPOrDomain_Ip)(nil),
(*IPOrDomain_Domain)(nil),
}
}
func _IPOrDomain_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*IPOrDomain)
// address
switch x := m.Address.(type) {
case *IPOrDomain_Ip:
b.EncodeVarint(1<<3 | proto.WireBytes)
b.EncodeRawBytes(x.Ip)
case *IPOrDomain_Domain:
b.EncodeVarint(2<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Domain)
case nil:
default:
return fmt.Errorf("IPOrDomain.Address has unexpected type %T", x)
}
return nil
}
func _IPOrDomain_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*IPOrDomain)
switch tag {
case 1: // address.ip
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeRawBytes(true)
m.Address = &IPOrDomain_Ip{x}
return true, err
case 2: // address.domain
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Address = &IPOrDomain_Domain{x}
return true, err
default:
return false, nil
}
}
func _IPOrDomain_OneofSizer(msg proto.Message) (n int) {
m := msg.(*IPOrDomain)
// address
switch x := m.Address.(type) {
case *IPOrDomain_Ip:
n += proto.SizeVarint(1<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Ip)))
n += len(x.Ip)
case *IPOrDomain_Domain:
n += proto.SizeVarint(2<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Domain)))
n += len(x.Domain)
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
func init() {
proto.RegisterType((*IPOrDomain)(nil), "v2ray.core.common.net.IPOrDomain")
}
func init() { proto.RegisterFile("v2ray.com/core/common/net/address.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 163 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2f, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd,
0xcf, 0xd3, 0xcf, 0x4b, 0x2d, 0xd1, 0x4f, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0xd6, 0x2b, 0x28,
0xca, 0x2f, 0xc9, 0x17, 0x12, 0x85, 0x29, 0x2c, 0x4a, 0xd5, 0x83, 0x28, 0xd2, 0xcb, 0x4b, 0x2d,
0x51, 0x72, 0xe6, 0xe2, 0xf2, 0x0c, 0xf0, 0x2f, 0x72, 0xc9, 0xcf, 0x4d, 0xcc, 0xcc, 0x13, 0x12,
0xe0, 0x62, 0xca, 0x2c, 0x90, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0xf1, 0x60, 0x08, 0x62, 0xca, 0x2c,
0x10, 0x92, 0xe0, 0x62, 0x4b, 0x01, 0xcb, 0x49, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x7a, 0x30, 0x04,
0x41, 0xf9, 0x4e, 0x9c, 0x5c, 0xec, 0x50, 0x1b, 0x9c, 0xf4, 0xb8, 0x24, 0x93, 0xf3, 0x73, 0xf5,
0xb0, 0xda, 0xe0, 0xc4, 0xe3, 0x08, 0x51, 0x15, 0x00, 0x72, 0x46, 0x14, 0x73, 0x5e, 0x6a, 0x49,
0x12, 0x1b, 0xd8, 0x49, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x40, 0xbb, 0x8c, 0xbd,
0x00, 0x00, 0x00,
}

16
common/net/address.proto Normal file
View File

@@ -0,0 +1,16 @@
syntax = "proto3";
package v2ray.core.common.net;
option go_package = "net";
option java_package = "com.v2ray.core.common.net";
option java_outer_classname = "AddressProto";
message IPOrDomain {
oneof address {
// IP address. Must by either 4 or 16 bytes.
bytes ip = 1;
// Domain address.
string domain = 2;
}
}

View File

@@ -1,20 +0,0 @@
// +build json
package net
import (
"encoding/json"
)
type AddressJson struct {
Address Address
}
func (this *AddressJson) UnmarshalJSON(data []byte) error {
var rawStr string
if err := json.Unmarshal(data, &rawStr); err != nil {
return err
}
this.Address = ParseAddress(rawStr)
return nil
}

View File

@@ -1,45 +0,0 @@
// +build json
package net_test
import (
"encoding/json"
"net"
"testing"
. "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestIPParsing(t *testing.T) {
assert := assert.On(t)
rawJson := "\"8.8.8.8\""
var address AddressJson
err := json.Unmarshal([]byte(rawJson), &address)
assert.Error(err).IsNil()
assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsTrue()
assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsFalse()
assert.Bool(address.Address.IP().Equal(net.ParseIP("8.8.8.8"))).IsTrue()
}
func TestDomainParsing(t *testing.T) {
assert := assert.On(t)
rawJson := "\"v2ray.com\""
var address AddressJson
err := json.Unmarshal([]byte(rawJson), &address)
assert.Error(err).IsNil()
assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsFalse()
assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsTrue()
assert.String(address.Address.Domain()).Equals("v2ray.com")
}
func TestInvalidAddressJson(t *testing.T) {
assert := assert.On(t)
rawJson := "1234"
var address AddressJson
err := json.Unmarshal([]byte(rawJson), &address)
assert.Error(err).IsNotNil()
}

View File

@@ -4,8 +4,8 @@ import (
"net"
"testing"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/testing/assert"
)
func TestIPv4Address(t *testing.T) {

View File

@@ -5,16 +5,10 @@ import (
)
// Destination represents a network destination including address and protocol (tcp / udp).
type Destination interface {
Network() Network // Protocol of communication (tcp / udp)
Address() Address // Address of destination
Port() Port
String() string // String representation of the destination
NetAddr() string
Equals(Destination) bool
IsTCP() bool // True if destination is reachable via TCP
IsUDP() bool // True if destination is reachable via UDP
type Destination struct {
Network Network
Address Address
Port Port
}
func DestinationFromAddr(addr net.Addr) Destination {
@@ -30,102 +24,38 @@ func DestinationFromAddr(addr net.Addr) Destination {
// TCPDestination creates a TCP destination with given address
func TCPDestination(address Address, port Port) Destination {
return &tcpDestination{address: address, port: port}
return Destination{
Network: Network_TCP,
Address: address,
Port: port,
}
}
// UDPDestination creates a UDP destination with given address
func UDPDestination(address Address, port Port) Destination {
return &udpDestination{address: address, port: port}
}
type tcpDestination struct {
address Address
port Port
}
func (dest *tcpDestination) Network() Network {
return TCPNetwork
}
func (dest *tcpDestination) Address() Address {
return dest.address
}
func (dest *tcpDestination) NetAddr() string {
return dest.address.String() + ":" + dest.port.String()
}
func (dest *tcpDestination) String() string {
return "tcp:" + dest.NetAddr()
}
func (dest *tcpDestination) IsTCP() bool {
return true
}
func (dest *tcpDestination) IsUDP() bool {
return false
}
func (dest *tcpDestination) Port() Port {
return dest.port
}
func (dest *tcpDestination) Equals(another Destination) bool {
if dest == nil && another == nil {
return true
return Destination{
Network: Network_UDP,
Address: address,
Port: port,
}
if dest == nil || another == nil {
return false
}
func (this Destination) NetAddr() string {
return this.Address.String() + ":" + this.Port.String()
}
func (this Destination) String() string {
return this.Network.UrlPrefix() + ":" + this.NetAddr()
}
func (this Destination) Equals(another Destination) bool {
return this.Network == another.Network && this.Port == another.Port && this.Address.Equals(another.Address)
}
func (this *Endpoint) AsDestination() Destination {
return Destination{
Network: this.Network,
Address: this.Address.AsAddress(),
Port: Port(this.Port),
}
if !another.IsTCP() {
return false
}
return dest.Port() == another.Port() && dest.Address().Equals(another.Address())
}
type udpDestination struct {
address Address
port Port
}
func (dest *udpDestination) Network() Network {
return UDPNetwork
}
func (dest *udpDestination) Address() Address {
return dest.address
}
func (dest *udpDestination) NetAddr() string {
return dest.address.String() + ":" + dest.port.String()
}
func (dest *udpDestination) String() string {
return "udp:" + dest.NetAddr()
}
func (dest *udpDestination) IsTCP() bool {
return false
}
func (dest *udpDestination) IsUDP() bool {
return true
}
func (dest *udpDestination) Port() Port {
return dest.port
}
func (dest *udpDestination) Equals(another Destination) bool {
if dest == nil && another == nil {
return true
}
if dest == nil || another == nil {
return false
}
if !another.IsUDP() {
return false
}
return dest.Port() == another.Port() && dest.Address().Equals(another.Address())
}

View File

@@ -0,0 +1,56 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/destination.proto
// DO NOT EDIT!
package net
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type Endpoint struct {
Network Network `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
Address *IPOrDomain `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
Port uint32 `protobuf:"varint,3,opt,name=port" json:"port,omitempty"`
}
func (m *Endpoint) Reset() { *m = Endpoint{} }
func (m *Endpoint) String() string { return proto.CompactTextString(m) }
func (*Endpoint) ProtoMessage() {}
func (*Endpoint) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
func (m *Endpoint) GetAddress() *IPOrDomain {
if m != nil {
return m.Address
}
return nil
}
func init() {
proto.RegisterType((*Endpoint)(nil), "v2ray.core.common.net.Endpoint")
}
func init() { proto.RegisterFile("v2ray.com/core/common/net/destination.proto", fileDescriptor1) }
var fileDescriptor1 = []byte{
// 219 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x90, 0x31, 0x4b, 0x04, 0x31,
0x10, 0x46, 0x89, 0x27, 0x9e, 0x44, 0x14, 0x09, 0x08, 0xab, 0x85, 0xac, 0x36, 0x2e, 0x08, 0x09,
0xc4, 0x46, 0xb0, 0x3b, 0xce, 0xc2, 0x46, 0x8f, 0x2d, 0xed, 0x62, 0x32, 0x45, 0x90, 0xcc, 0x2c,
0xb3, 0x83, 0xe2, 0x0f, 0xf1, 0xff, 0x8a, 0x97, 0x5b, 0x6c, 0xee, 0xec, 0x52, 0xbc, 0xf7, 0xc8,
0x37, 0xfa, 0xf6, 0xc3, 0x73, 0xf8, 0xb2, 0x91, 0x8a, 0x8b, 0xc4, 0xe0, 0x22, 0x95, 0x42, 0xe8,
0x10, 0xc4, 0x25, 0x18, 0x25, 0x63, 0x90, 0x4c, 0x68, 0x07, 0x26, 0x21, 0x73, 0x36, 0xc1, 0x0c,
0xb6, 0x82, 0x16, 0x41, 0x2e, 0x6e, 0x76, 0x37, 0x10, 0xe4, 0x93, 0xf8, 0xbd, 0xfa, 0xff, 0x81,
0x21, 0x25, 0x86, 0x71, 0xac, 0xe0, 0xf5, 0xb7, 0xd2, 0x87, 0x8f, 0x98, 0x06, 0xca, 0x28, 0xe6,
0x5e, 0xcf, 0x37, 0x99, 0x46, 0xb5, 0xaa, 0x3b, 0xf1, 0x97, 0x76, 0xeb, 0x3f, 0xec, 0x73, 0xa5,
0xfa, 0x09, 0x37, 0x0f, 0x7a, 0xbe, 0xe9, 0x36, 0x7b, 0xad, 0xea, 0x8e, 0xfc, 0xd5, 0x0e, 0xf3,
0x69, 0xf5, 0xc2, 0x4b, 0x2a, 0x21, 0x63, 0x3f, 0x19, 0xc6, 0xe8, 0xfd, 0x81, 0x58, 0x9a, 0x59,
0xab, 0xba, 0xe3, 0x7e, 0xfd, 0x5e, 0x78, 0x7d, 0x1e, 0xa9, 0x6c, 0x8f, 0x2c, 0x4e, 0x97, 0x7f,
0x07, 0x5b, 0xfd, 0xce, 0x78, 0x9d, 0x21, 0xc8, 0xdb, 0xc1, 0x7a, 0xd2, 0xdd, 0x4f, 0x00, 0x00,
0x00, 0xff, 0xff, 0x97, 0xbf, 0x9f, 0x8e, 0x6a, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,15 @@
syntax = "proto3";
package v2ray.core.common.net;
option go_package = "net";
option java_package = "com.v2ray.core.common.net";
option java_outer_classname = "DestinationProto";
import "v2ray.com/core/common/net/network.proto";
import "v2ray.com/core/common/net/address.proto";
message Endpoint {
Network network = 1;
IPOrDomain address = 2;
uint32 port = 3;
}

View File

@@ -3,8 +3,8 @@ package net_test
import (
"testing"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/testing/assert"
)
func TestTCPDestination(t *testing.T) {
@@ -29,7 +29,7 @@ func TestTCPDestinationEquals(t *testing.T) {
assert := assert.On(t)
dest := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
assert.Bool(dest.Equals(nil)).IsFalse()
assert.Bool(dest.Equals(v2net.Destination{})).IsFalse()
dest2 := v2net.TCPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
assert.Bool(dest.Equals(dest2)).IsTrue()
@@ -45,7 +45,7 @@ func TestUDPDestinationEquals(t *testing.T) {
assert := assert.On(t)
dest := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
assert.Bool(dest.Equals(nil)).IsFalse()
assert.Bool(dest.Equals(v2net.Destination{})).IsFalse()
dest2 := v2net.UDPDestination(v2net.IPAddress([]byte{1, 2, 3, 4}), 80)
assert.Bool(dest.Equals(dest2)).IsTrue()

View File

@@ -13,12 +13,8 @@ type IPNet struct {
}
func NewIPNet() *IPNet {
return NewIPNetInitialValue(make(map[uint32]byte, 1024))
}
func NewIPNetInitialValue(data map[uint32]byte) *IPNet {
return &IPNet{
cache: data,
cache: make(map[uint32]byte, 1024),
}
}
@@ -45,11 +41,15 @@ func (this *IPNet) Add(ipNet *net.IPNet) {
// For now, we don't support IPv6
return
}
value := ipToUint32(ipv4)
mask := ipMaskToByte(ipNet.Mask)
existing, found := this.cache[value]
this.AddIP(ipv4, mask)
}
func (this *IPNet) AddIP(ip []byte, mask byte) {
k := ipToUint32(ip)
existing, found := this.cache[k]
if !found || existing > mask {
this.cache[value] = mask
this.cache[k] = mask
}
}
@@ -61,7 +61,7 @@ func (this *IPNet) Contains(ip net.IP) bool {
originalValue := ipToUint32(ipv4)
if entry, found := this.cache[originalValue]; found {
if entry == 0 {
if entry == 32 {
return true
}
}
@@ -80,12 +80,8 @@ func (this *IPNet) Contains(ip net.IP) bool {
return false
}
func (this *IPNet) Serialize() []uint32 {
content := make([]uint32, 0, 2*len(this.cache))
for key, value := range this.cache {
content = append(content, uint32(key), uint32(value))
}
return content
func (this *IPNet) IsEmpty() bool {
return len(this.cache) == 0
}
func init() {

View File

@@ -4,8 +4,8 @@ import (
"net"
"testing"
. "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
. "v2ray.com/core/common/net"
"v2ray.com/core/testing/assert"
)
func parseCIDR(str string) *net.IPNet {

View File

@@ -1,2 +1,2 @@
// Package net contains common network utilities.
package net // import "github.com/v2ray/v2ray-core/common/net"
package net

View File

@@ -2,51 +2,68 @@ package net
import (
"strings"
"github.com/v2ray/v2ray-core/common/collect"
)
const (
// TCPNetwork represents the TCP network.
TCPNetwork = Network("tcp")
// UDPNetwork represents the UDP network.
UDPNetwork = Network("udp")
// KCPNetwork represents the KCP network.
KCPNetwork = Network("kcp")
)
// Network represents a communication network on internet.
type Network string
func ParseNetwork(nwStr string) Network {
if network, found := Network_value[nwStr]; found {
return Network(network)
}
switch strings.ToLower(nwStr) {
case "tcp":
return Network_TCP
case "udp":
return Network_UDP
case "kcp":
return Network_KCP
case "ws":
return Network_WebSocket
default:
return Network_Unknown
}
}
func (this Network) AsList() *NetworkList {
list := NetworkList([]Network{this})
return &list
}
func (this Network) String() string {
return string(this)
}
// NetworkList is a list of Networks.
type NetworkList []Network
// NewNetworkList construsts a NetWorklist from the given StringListeralList.
func NewNetworkList(networks collect.StringList) NetworkList {
list := NetworkList(make([]Network, networks.Len()))
for idx, network := range networks {
list[idx] = Network(strings.ToLower(strings.TrimSpace(network)))
return &NetworkList{
Network: []Network{this},
}
}
func (this Network) SystemString() string {
switch this {
case Network_TCP, Network_RawTCP:
return "tcp"
case Network_UDP, Network_KCP:
return "udp"
default:
return "unknown"
}
}
func (this Network) UrlPrefix() string {
switch this {
case Network_TCP, Network_RawTCP:
return "tcp"
case Network_UDP:
return "udp"
case Network_KCP:
return "kcp"
case Network_WebSocket:
return "ws"
default:
return "unknown"
}
return list
}
// HashNetwork returns true if the given network is in this NetworkList.
func (this *NetworkList) HasNetwork(network Network) bool {
for _, value := range *this {
func (this NetworkList) HasNetwork(network Network) bool {
for _, value := range this.Network {
if string(value) == string(network) {
return true
}
}
return false
}
func (this NetworkList) Get(idx int) Network {
return this.Network[idx]
}

82
common/net/network.pb.go Normal file
View File

@@ -0,0 +1,82 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/network.proto
// DO NOT EDIT!
package net
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type Network int32
const (
Network_Unknown Network = 0
// Native TCP provided by system.
Network_RawTCP Network = 1
// V2Ray specific TCP.
Network_TCP Network = 2
Network_UDP Network = 3
Network_KCP Network = 4
Network_WebSocket Network = 5
)
var Network_name = map[int32]string{
0: "Unknown",
1: "RawTCP",
2: "TCP",
3: "UDP",
4: "KCP",
5: "WebSocket",
}
var Network_value = map[string]int32{
"Unknown": 0,
"RawTCP": 1,
"TCP": 2,
"UDP": 3,
"KCP": 4,
"WebSocket": 5,
}
func (x Network) String() string {
return proto.EnumName(Network_name, int32(x))
}
func (Network) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
type NetworkList struct {
Network []Network `protobuf:"varint,1,rep,packed,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
}
func (m *NetworkList) Reset() { *m = NetworkList{} }
func (m *NetworkList) String() string { return proto.CompactTextString(m) }
func (*NetworkList) ProtoMessage() {}
func (*NetworkList) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func init() {
proto.RegisterType((*NetworkList)(nil), "v2ray.core.common.net.NetworkList")
proto.RegisterEnum("v2ray.core.common.net.Network", Network_name, Network_value)
}
func init() { proto.RegisterFile("v2ray.com/core/common/net/network.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{
// 203 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2f, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd,
0xcf, 0xd3, 0xcf, 0x4b, 0x2d, 0x01, 0xe1, 0xf2, 0xfc, 0xa2, 0x6c, 0xbd, 0x82, 0xa2, 0xfc, 0x92,
0x7c, 0x21, 0x51, 0x98, 0xc2, 0xa2, 0x54, 0x3d, 0x88, 0x22, 0xbd, 0xbc, 0xd4, 0x12, 0x25, 0x77,
0x2e, 0x6e, 0x3f, 0x88, 0x3a, 0x9f, 0xcc, 0xe2, 0x12, 0x21, 0x0b, 0x2e, 0x76, 0xa8, 0x36, 0x09,
0x46, 0x05, 0x66, 0x0d, 0x3e, 0x23, 0x39, 0x3d, 0xac, 0xfa, 0xf4, 0xa0, 0x9a, 0x82, 0x60, 0xca,
0xb5, 0x7c, 0xb8, 0xd8, 0xa1, 0x62, 0x42, 0xdc, 0x5c, 0xec, 0xa1, 0x79, 0xd9, 0x79, 0xf9, 0xe5,
0x79, 0x02, 0x0c, 0x42, 0x5c, 0x5c, 0x6c, 0x41, 0x89, 0xe5, 0x21, 0xce, 0x01, 0x02, 0x8c, 0x42,
0xec, 0x5c, 0xcc, 0x20, 0x06, 0x13, 0x88, 0x11, 0xea, 0x12, 0x20, 0xc0, 0x0c, 0x62, 0x78, 0x3b,
0x07, 0x08, 0xb0, 0x08, 0xf1, 0x72, 0x71, 0x86, 0xa7, 0x26, 0x05, 0xe7, 0x27, 0x67, 0xa7, 0x96,
0x08, 0xb0, 0x3a, 0xe9, 0x71, 0x49, 0x26, 0xe7, 0xe7, 0x62, 0xb7, 0xdb, 0x89, 0x07, 0x6a, 0x51,
0x00, 0xc8, 0x63, 0x51, 0xcc, 0x79, 0xa9, 0x25, 0x49, 0x6c, 0x60, 0x4f, 0x1a, 0x03, 0x02, 0x00,
0x00, 0xff, 0xff, 0x6e, 0x52, 0xf1, 0x92, 0x0f, 0x01, 0x00, 0x00,
}

26
common/net/network.proto Normal file
View File

@@ -0,0 +1,26 @@
syntax = "proto3";
package v2ray.core.common.net;
option go_package = "net";
option java_package = "com.v2ray.core.common.net";
option java_outer_classname = "NetworkProto";
enum Network {
Unknown = 0;
// Native TCP provided by system.
RawTCP = 1;
// V2Ray specific TCP.
TCP = 2;
UDP = 3;
KCP = 4;
WebSocket = 5;
}
message NetworkList {
repeated Network network = 1;
}

View File

@@ -1,18 +0,0 @@
// +build json
package net
import (
"encoding/json"
"github.com/v2ray/v2ray-core/common/collect"
)
func (this *NetworkList) UnmarshalJSON(data []byte) error {
var strlist collect.StringList
if err := json.Unmarshal(data, &strlist); err != nil {
return err
}
*this = NewNetworkList(strlist)
return nil
}

View File

@@ -1,39 +0,0 @@
// +build json
package net_test
import (
"encoding/json"
"testing"
. "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/testing/assert"
)
func TestArrayNetworkList(t *testing.T) {
assert := assert.On(t)
var list NetworkList
err := json.Unmarshal([]byte("[\"Tcp\"]"), &list)
assert.Error(err).IsNil()
assert.Bool(list.HasNetwork(Network("tcp"))).IsTrue()
assert.Bool(list.HasNetwork(Network("udp"))).IsFalse()
}
func TestStringNetworkList(t *testing.T) {
assert := assert.On(t)
var list NetworkList
err := json.Unmarshal([]byte("\"TCP, ip\""), &list)
assert.Error(err).IsNil()
assert.Bool(list.HasNetwork(Network("tcp"))).IsTrue()
assert.Bool(list.HasNetwork(Network("udp"))).IsFalse()
}
func TestInvalidNetworkJson(t *testing.T) {
assert := assert.On(t)
var list NetworkList
err := json.Unmarshal([]byte("0"), &list)
assert.Error(err).IsNotNil()
}

Some files were not shown because too many files have changed in this diff Show More