girl 0.50.0 → 0.50.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of girl might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87247b5b83a9944f6f88ebdf162352bceb23bea3b4f4e9c2abc8dd1222fe3500
4
- data.tar.gz: '085096f65188b90f9d2fd88610c9b662ba33826a98e7071f9aef7de239d000a3'
3
+ metadata.gz: 22404c18134e089d770eb9a3bfb48a2fcec0d8d03020deb67ddb7d4002899fa7
4
+ data.tar.gz: 9966cb611a97bfbd96256c35cdf819aeb5e963e03cfe4a438112ac1f6cad9be4
5
5
  SHA512:
6
- metadata.gz: 700f061521d68f61ca29053e5fc5bc9c8c0a78d4bd58b80e333ed6c425c65b653381486aef2c860e44268947d94a3cc337e0af2f7be75b6cb62367c12b2a684b
7
- data.tar.gz: f3916e5e99a2c13c9b5b4d3c21b5b1a3825951f7dc0d78843df7b1419da205b255ba2cf3c6b2483472f9e61b133f18644f231d26b1b4abd99f9a6640b8e78540
6
+ metadata.gz: bce25c7de3d0b3ed2db61fe0a187c1c557d924c7923909f7b3d07a23ed33773cb3bfef9c0c92f1c56e4ef31550450b89bdf06a0ff33e26957737da5487ee44d2
7
+ data.tar.gz: b75cd4e997e4e525f4e0095548c5c852f0b5070f1ff3391401654c48c7df8841ee7daf15d35c9bdcc29e84eff2028c54eee46f8d0b7f112f7039d1e65e4c6387
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['qqtakafan@gmail.com']
11
11
 
12
12
  spec.summary = %q{妹子}
13
- spec.description = %q{while internet is evil, here's a patch.}
13
+ spec.description = %q{while internet is evil, here's a girl.}
14
14
  spec.homepage = 'https://github.com/takafan/girl'
15
15
  spec.license = 'MIT'
16
16
 
@@ -1,27 +1,27 @@
1
- module Girl
2
- PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(source/dest id) - 8(pack id) = 1328
3
- CHUNK_SIZE = PACK_SIZE * 1000 # 块大小
4
- WBUFFS_LIMIT = 1000 # 写前上限,超过上限结一个块
5
- WMEMS_LIMIT = 100_000 # 写后上限,达到上限暂停写
6
- RESUME_BELOW = 50_000 # 降到多少以下恢复写
7
- EXPIRE_AFTER = 1800 # 多久过期
8
- HEARTBEAT_INTERVAL = 3 # 心跳间隔
9
- STATUS_INTERVAL = 0.3 # 发送状态间隔
10
- SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
11
- BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
12
- TUND_PORT = 1
13
- HEARTBEAT = 2
14
- A_NEW_SOURCE = 3
15
- PAIRED = 4
16
- DEST_STATUS = 5
17
- SOURCE_STATUS = 6
18
- MISS = 7
19
- FIN1 = 8
20
- GOT_FIN1 = 9
21
- FIN2 = 10
22
- GOT_FIN2 = 11
23
- TUND_FIN = 12
24
- TUN_FIN = 13
25
- CTL_CLOSE = 1
26
- CTL_RESUME = 2
27
- end
1
+ module Girl
2
+ PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(source/dest id) - 8(pack id) = 1328
3
+ CHUNK_SIZE = PACK_SIZE * 1000 # 块大小
4
+ WBUFFS_LIMIT = 1000 # 写前上限,超过上限结一个块
5
+ WMEMS_LIMIT = 100_000 # 写后上限,达到上限暂停写
6
+ RESUME_BELOW = 50_000 # 降到多少以下恢复写
7
+ EXPIRE_AFTER = 1800 # 多久过期
8
+ HEARTBEAT_INTERVAL = 3 # 心跳间隔
9
+ STATUS_INTERVAL = 0.3 # 发送状态间隔
10
+ SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
11
+ BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
12
+ TUND_PORT = 1
13
+ HEARTBEAT = 2
14
+ A_NEW_SOURCE = 3
15
+ PAIRED = 4
16
+ DEST_STATUS = 5
17
+ SOURCE_STATUS = 6
18
+ MISS = 7
19
+ FIN1 = 8
20
+ GOT_FIN1 = 9
21
+ FIN2 = 10
22
+ GOT_FIN2 = 11
23
+ TUND_FIN = 12
24
+ TUN_FIN = 13
25
+ CTL_CLOSE = 1
26
+ CTL_RESUME = 2
27
+ end
@@ -1,200 +1,200 @@
1
- require 'girl/hex'
2
- require 'girl/version'
3
- require 'socket'
4
-
5
- ##
6
- # Girl::Resolv - dns查询得到正确的ip。近端。
7
- #
8
- # usage
9
- # =====
10
- #
11
- # Girl::Resolvd.new( 7070 ).looping # 远端
12
- #
13
- # Girl::Resolv.new( 1717, [ '114.114.114.114' ], 'your.server.ip', 7070, [ 'google.com' ] ).looping # 近端
14
- #
15
- # dig google.com @127.0.0.1 -p1717
16
- #
17
- module Girl
18
- class Resolv
19
-
20
- def initialize( port = 1717, nameservers = [], resolvd_host = nil, resolvd_port = nil, custom_domains = [] )
21
- @hex = Girl::Hex.new
22
- @mutex = Mutex.new
23
- @reads = []
24
- @writes = []
25
- @roles = {} # sock => :ctlr / :redir / :resolv / :pub
26
- @infos = {} # redir => {}
27
- @socks = {} # sock => sock_id
28
- @sock_ids = {} # sock_id => sock
29
-
30
- redir = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
31
- redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
32
- redir.bind( Socket.sockaddr_in( port, '0.0.0.0' ) )
33
- puts "redir bound on #{ port } #{ Time.new }"
34
-
35
- nameservers = nameservers.select{ | ns | Addrinfo.udp( ns, 53 ).ipv4? }
36
-
37
- if nameservers.empty?
38
- nameservers = %w[ 114.114.114.114 114.114.115.115 ]
39
- end
40
-
41
- redir_info = {
42
- src_addrs: {}, # src_addr => resolv_or_pub
43
- socks: {}, # resolv_or_pub => src_addr
44
- last_recv_ats: {}, # resolv_or_pub => now
45
- pubd_addrs: nameservers.map{ | ns | Socket.sockaddr_in( 53, ns ) },
46
- resolvd_addr: ( resolvd_host && resolvd_port ) ? Socket.sockaddr_in( resolvd_port, resolvd_host ) : nil,
47
- custom_qnames: custom_domains.map{ | dom | dom.split( '.' ).map{ | sub | [ sub.size ].pack( 'C' ) + sub }.join }
48
- }
49
-
50
- @redir = redir
51
- @redir_info = redir_info
52
- @roles[ redir ] = :redir
53
- @infos[ redir ] = redir_info
54
- @reads << redir
55
-
56
- ctlr, ctlw = IO.pipe
57
- @ctlw = ctlw
58
- @roles[ ctlr ] = :ctlr
59
- @reads << ctlr
60
- end
61
-
62
- def looping
63
- loop_expire
64
-
65
- loop do
66
- rs, ws = IO.select( @reads, @writes )
67
-
68
- @mutex.synchronize do
69
- rs.each do | sock |
70
- case @roles[ sock ]
71
- when :ctlr
72
- read_ctlr( sock )
73
- when :redir
74
- read_redir( sock )
75
- when :resolv, :pub
76
- read_sock( sock )
77
- end
78
- end
79
-
80
- ws.each do | sock |
81
- close_sock( sock )
82
- end
83
- end
84
- end
85
- end
86
-
87
- def quit!
88
- exit
89
- end
90
-
91
- private
92
-
93
- def read_ctlr( ctlr )
94
- sock_id = ctlr.read( 8 ).unpack( 'Q>' ).first
95
- sock = @sock_ids[ sock_id ]
96
-
97
- if sock
98
- # puts "debug expire #{ @roles[ sock ] } #{ sock_id } #{ Time.new }"
99
-
100
- unless @writes.include?( sock )
101
- @writes << sock
102
- end
103
- end
104
- end
105
-
106
- def read_redir( redir )
107
- # https://tools.ietf.org/html/rfc1035#page-26
108
- data, addrinfo, rflags, *controls = redir.recvmsg
109
- return if data.size <= 12
110
-
111
- id = data[ 0, 2 ]
112
- qname_len = data[ 12..-1 ].index( [ 0 ].pack( 'C' ) )
113
- return unless qname_len
114
-
115
- now = Time.new
116
- info = @infos[ redir ]
117
- src_addr = addrinfo.to_sockaddr
118
- sock = info[ :src_addrs ][ src_addr ]
119
-
120
- unless sock
121
- sock = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
122
- sock.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
123
- sock.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
124
-
125
- sock_id = @hex.gen_random_num
126
- @socks[ sock ] = sock_id
127
- @sock_ids[ sock_id ] = sock
128
- qname = data[ 12, qname_len ]
129
-
130
- if info[ :resolvd_addr ] && ( info[ :custom_qnames ].any? { | custom | qname.include?( custom ) } )
131
- @roles[ sock ] = :resolv
132
- else
133
- @roles[ sock ] = :pub
134
- end
135
-
136
- # puts "debug a new #{ @roles[ sock ] } bound on #{ sock.local_address.ip_unpack.last } #{ Time.new }"
137
-
138
- @reads << sock
139
- info[ :src_addrs ][ src_addr ] = sock
140
- info[ :socks ][ sock ] = src_addr
141
- info[ :last_recv_ats ][ sock ] = now
142
- end
143
-
144
- if @roles[ sock ] == :resolv
145
- data = @hex.encode( data )
146
- sock.sendmsg( data, 0, info[ :resolvd_addr ] )
147
- else
148
- info[ :pubd_addrs ].each { | pubd_addr | sock.sendmsg( data, 0, pubd_addr ) }
149
- end
150
- end
151
-
152
- def read_sock( sock )
153
- data, addrinfo, rflags, *controls = sock.recvmsg
154
- return if data.size <= 12
155
-
156
- if @roles[ sock ] == :resolv
157
- data = @hex.decode( data )
158
- end
159
-
160
- src_addr = @redir_info[ :socks ][ sock ]
161
- return unless src_addr
162
-
163
- @redir_info[ :last_recv_ats ][ sock ] = Time.new
164
- @redir.sendmsg( data, 0, src_addr )
165
- end
166
-
167
- def close_sock( sock )
168
- sock.close
169
- @reads.delete( sock )
170
- @writes.delete( sock )
171
- @roles.delete( sock )
172
- sock_id = @socks.delete( sock )
173
- @sock_ids.delete( sock_id )
174
- @redir_info[ :last_recv_ats ].delete( sock )
175
- src_addr = @redir_info[ :socks ].delete( sock )
176
- @redir_info[ :src_addrs ].delete( src_addr )
177
- end
178
-
179
- def loop_expire
180
- Thread.new do
181
- loop do
182
- sleep 60
183
-
184
- @mutex.synchronize do
185
- now = Time.new
186
- socks = @redir_info[ :socks ].keys
187
-
188
- socks.each do | sock |
189
- if now - @redir_info[ :last_recv_ats ][ sock ] > 5
190
- sock_id = @socks[ sock ]
191
- @ctlw.write( [ sock_id ].pack( 'Q>' ) )
192
- end
193
- end
194
- end
195
- end
196
- end
197
- end
198
-
199
- end
200
- end
1
+ require 'girl/hex'
2
+ require 'girl/version'
3
+ require 'socket'
4
+
5
+ ##
6
+ # Girl::Resolv - dns查询得到正确的ip。近端。
7
+ #
8
+ # usage
9
+ # =====
10
+ #
11
+ # Girl::Resolvd.new( 7070 ).looping # 远端
12
+ #
13
+ # Girl::Resolv.new( 1717, [ '114.114.114.114' ], 'your.server.ip', 7070, [ 'google.com' ] ).looping # 近端
14
+ #
15
+ # dig google.com @127.0.0.1 -p1717
16
+ #
17
+ module Girl
18
+ class Resolv
19
+
20
+ def initialize( port = 1717, nameservers = [], resolvd_host = nil, resolvd_port = nil, custom_domains = [] )
21
+ @hex = Girl::Hex.new
22
+ @mutex = Mutex.new
23
+ @reads = []
24
+ @writes = []
25
+ @roles = {} # sock => :ctlr / :redir / :resolv / :pub
26
+ @infos = {} # redir => {}
27
+ @socks = {} # sock => sock_id
28
+ @sock_ids = {} # sock_id => sock
29
+
30
+ redir = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
31
+ redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
32
+ redir.bind( Socket.sockaddr_in( port, '0.0.0.0' ) )
33
+ puts "redir bound on #{ port } #{ Time.new }"
34
+
35
+ nameservers = nameservers.select{ | ns | Addrinfo.udp( ns, 53 ).ipv4? }
36
+
37
+ if nameservers.empty?
38
+ nameservers = %w[ 114.114.114.114 114.114.115.115 ]
39
+ end
40
+
41
+ redir_info = {
42
+ src_addrs: {}, # src_addr => resolv_or_pub
43
+ socks: {}, # resolv_or_pub => src_addr
44
+ last_recv_ats: {}, # resolv_or_pub => now
45
+ pubd_addrs: nameservers.map{ | ns | Socket.sockaddr_in( 53, ns ) },
46
+ resolvd_addr: ( resolvd_host && resolvd_port ) ? Socket.sockaddr_in( resolvd_port, resolvd_host ) : nil,
47
+ custom_qnames: custom_domains.map{ | dom | dom.split( '.' ).map{ | sub | [ sub.size ].pack( 'C' ) + sub }.join }
48
+ }
49
+
50
+ @redir = redir
51
+ @redir_info = redir_info
52
+ @roles[ redir ] = :redir
53
+ @infos[ redir ] = redir_info
54
+ @reads << redir
55
+
56
+ ctlr, ctlw = IO.pipe
57
+ @ctlw = ctlw
58
+ @roles[ ctlr ] = :ctlr
59
+ @reads << ctlr
60
+ end
61
+
62
+ def looping
63
+ loop_expire
64
+
65
+ loop do
66
+ rs, ws = IO.select( @reads, @writes )
67
+
68
+ @mutex.synchronize do
69
+ rs.each do | sock |
70
+ case @roles[ sock ]
71
+ when :ctlr
72
+ read_ctlr( sock )
73
+ when :redir
74
+ read_redir( sock )
75
+ when :resolv, :pub
76
+ read_sock( sock )
77
+ end
78
+ end
79
+
80
+ ws.each do | sock |
81
+ close_sock( sock )
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def quit!
88
+ exit
89
+ end
90
+
91
+ private
92
+
93
+ def read_ctlr( ctlr )
94
+ sock_id = ctlr.read( 8 ).unpack( 'Q>' ).first
95
+ sock = @sock_ids[ sock_id ]
96
+
97
+ if sock
98
+ # puts "debug expire #{ @roles[ sock ] } #{ sock_id } #{ Time.new }"
99
+
100
+ unless @writes.include?( sock )
101
+ @writes << sock
102
+ end
103
+ end
104
+ end
105
+
106
+ def read_redir( redir )
107
+ # https://tools.ietf.org/html/rfc1035#page-26
108
+ data, addrinfo, rflags, *controls = redir.recvmsg
109
+ return if data.size <= 12
110
+
111
+ id = data[ 0, 2 ]
112
+ qname_len = data[ 12..-1 ].index( [ 0 ].pack( 'C' ) )
113
+ return unless qname_len
114
+
115
+ now = Time.new
116
+ info = @infos[ redir ]
117
+ src_addr = addrinfo.to_sockaddr
118
+ sock = info[ :src_addrs ][ src_addr ]
119
+
120
+ unless sock
121
+ sock = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
122
+ sock.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
123
+ sock.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
124
+
125
+ sock_id = @hex.gen_random_num
126
+ @socks[ sock ] = sock_id
127
+ @sock_ids[ sock_id ] = sock
128
+ qname = data[ 12, qname_len ]
129
+
130
+ if info[ :resolvd_addr ] && ( info[ :custom_qnames ].any? { | custom | qname.include?( custom ) } )
131
+ @roles[ sock ] = :resolv
132
+ else
133
+ @roles[ sock ] = :pub
134
+ end
135
+
136
+ # puts "debug a new #{ @roles[ sock ] } bound on #{ sock.local_address.ip_unpack.last } #{ Time.new }"
137
+
138
+ @reads << sock
139
+ info[ :src_addrs ][ src_addr ] = sock
140
+ info[ :socks ][ sock ] = src_addr
141
+ info[ :last_recv_ats ][ sock ] = now
142
+ end
143
+
144
+ if @roles[ sock ] == :resolv
145
+ data = @hex.encode( data )
146
+ sock.sendmsg( data, 0, info[ :resolvd_addr ] )
147
+ else
148
+ info[ :pubd_addrs ].each { | pubd_addr | sock.sendmsg( data, 0, pubd_addr ) }
149
+ end
150
+ end
151
+
152
+ def read_sock( sock )
153
+ data, addrinfo, rflags, *controls = sock.recvmsg
154
+ return if data.size <= 12
155
+
156
+ if @roles[ sock ] == :resolv
157
+ data = @hex.decode( data )
158
+ end
159
+
160
+ src_addr = @redir_info[ :socks ][ sock ]
161
+ return unless src_addr
162
+
163
+ @redir_info[ :last_recv_ats ][ sock ] = Time.new
164
+ @redir.sendmsg( data, 0, src_addr )
165
+ end
166
+
167
+ def close_sock( sock )
168
+ sock.close
169
+ @reads.delete( sock )
170
+ @writes.delete( sock )
171
+ @roles.delete( sock )
172
+ sock_id = @socks.delete( sock )
173
+ @sock_ids.delete( sock_id )
174
+ @redir_info[ :last_recv_ats ].delete( sock )
175
+ src_addr = @redir_info[ :socks ].delete( sock )
176
+ @redir_info[ :src_addrs ].delete( src_addr )
177
+ end
178
+
179
+ def loop_expire
180
+ Thread.new do
181
+ loop do
182
+ sleep 60
183
+
184
+ @mutex.synchronize do
185
+ now = Time.new
186
+ socks = @redir_info[ :socks ].keys
187
+
188
+ socks.each do | sock |
189
+ if now - @redir_info[ :last_recv_ats ][ sock ] > 5
190
+ sock_id = @socks[ sock ]
191
+ @ctlw.write( [ sock_id ].pack( 'Q>' ) )
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ end
200
+ end