girl 0.58.1 → 0.62.0

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: 3499680dcc958bbb7fe5a1a1774a78d67441c9f4ac3f6a1a3662533814efbdd3
4
- data.tar.gz: 2dc867c3105d9d111e98a8be41ab3bb10a86ed883e35d684a85c5d52b7534953
3
+ metadata.gz: f3597360a30c0ba1226ed9fdeef1faf10687bbfc48ac58c07c063c5e6888dd50
4
+ data.tar.gz: 7d7429c890f3090c53b57c61587a4f03351d4e68775e310acd174baf91adfa74
5
5
  SHA512:
6
- metadata.gz: efb0dde6e8508b3596490230ecc95413c3e2d0154af963106e25fff87c77e1ffbee8e758d3b52593360885ab3a7f9a49349804e64359c817bcb99cc6dcf0508a
7
- data.tar.gz: 36760b372618934b90c09649ff600fcf60935637af90ca16b4fb5b34777b183181717b41dc573b533c76b116aa68077c23ecc2ff216f38b1baad2b6efd2d1623
6
+ metadata.gz: f0e09919d82be7c07a3342199af626487cdde4527e799609ec561fc9bef29929a616a075dbc10ce31656c00c7c5aab4311223edbf7ea45cf70e9798f0bc5f20e
7
+ data.tar.gz: 979e305bb9c5f9e846271ff9d9c1bb01438ca6714e96a95ab7b588493968aa5d25dccfda5ee4d36d288570034e655ac0c113a4e935fcc3410be23d091d74ea56
@@ -99,7 +99,7 @@ module Girl
99
99
  raise "not found direct file #{ direct_path }"
100
100
  end
101
101
 
102
- directs = ( RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map { | line | IPAddr.new( line.strip ) }
102
+ directs = ( [ Addrinfo.ip( proxyd_host ).ip_address ] + RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map { | line | IPAddr.new( line.strip ) }
103
103
  end
104
104
 
105
105
  remotes = []
@@ -163,35 +163,39 @@ module Girl
163
163
  puts "im #{ im }"
164
164
  puts "worker count #{ worker_count }"
165
165
 
166
- $0 = title
167
- workers = []
166
+ if RUBY_PLATFORM.include?( 'linux' )
167
+ $0 = title
168
+ workers = []
168
169
 
169
- worker_count.times do | i |
170
- workers << fork do
171
- $0 = 'girl proxy worker'
172
- worker = Girl::ProxyWorker.new( proxy_port, proxyd_host, proxyd_port, directs, remotes, src_chunk_dir, dst_chunk_dir, tun_chunk_dir, im )
170
+ worker_count.times do | i |
171
+ workers << fork do
172
+ $0 = 'girl proxy worker'
173
+ worker = Girl::ProxyWorker.new( proxy_port, proxyd_host, proxyd_port, directs, remotes, src_chunk_dir, dst_chunk_dir, tun_chunk_dir, im )
173
174
 
174
- Signal.trap( :TERM ) do
175
- puts "w#{ i } exit"
176
- worker.quit!
177
- end
175
+ Signal.trap( :TERM ) do
176
+ puts "w#{ i } exit"
177
+ worker.quit!
178
+ end
178
179
 
179
- worker.looping
180
+ worker.looping
181
+ end
180
182
  end
181
- end
182
183
 
183
- Signal.trap( :TERM ) do
184
- puts 'trap TERM'
185
- workers.each do | pid |
186
- begin
187
- Process.kill( :TERM, pid )
188
- rescue Errno::ESRCH => e
189
- puts e.class
184
+ Signal.trap( :TERM ) do
185
+ puts 'trap TERM'
186
+ workers.each do | pid |
187
+ begin
188
+ Process.kill( :TERM, pid )
189
+ rescue Errno::ESRCH => e
190
+ puts e.class
191
+ end
190
192
  end
191
193
  end
192
- end
193
194
 
194
- Process.waitall
195
+ Process.waitall
196
+ else
197
+ Girl::ProxyWorker.new( proxy_port, proxyd_host, proxyd_port, directs, remotes, src_chunk_dir, dst_chunk_dir, tun_chunk_dir, im ).looping
198
+ end
195
199
  end
196
200
 
197
201
  end
@@ -217,6 +217,12 @@ module Girl
217
217
  # resolve domain
218
218
  #
219
219
  def resolve_domain( src, domain )
220
+ if ( /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ domain ) && domain.split( '.' ).all? { | part | part.to_i < 256 }
221
+ # puts "debug1 #{ domain } is a ip"
222
+ deal_with_destination_ip( src, domain )
223
+ return
224
+ end
225
+
220
226
  if @remotes.any? { | remote | ( domain.size >= remote.size ) && ( domain[ ( remote.size * -1 )..-1 ] == remote ) }
221
227
  # puts "debug1 #{ domain } hit remotes"
222
228
  new_a_src_ext( src )
@@ -238,6 +244,9 @@ module Girl
238
244
  @resolv_caches.delete( domain )
239
245
  end
240
246
 
247
+ src_info = @src_infos[ src ]
248
+ src_info[ :proxy_type ] = :checking
249
+
241
250
  Thread.new do
242
251
  begin
243
252
  ip_info = Addrinfo.ip( domain )
@@ -283,8 +292,12 @@ module Girl
283
292
  def new_a_proxy( proxy_port )
284
293
  proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
285
294
  proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
286
- proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
287
- proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
295
+
296
+ if RUBY_PLATFORM.include?( 'linux' )
297
+ proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
298
+ proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
299
+ end
300
+
288
301
  proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
289
302
  proxy.listen( 511 )
290
303
  puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
@@ -334,7 +347,10 @@ module Girl
334
347
  src_info = @src_infos[ src ]
335
348
  destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], destination_ip )
336
349
  dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
337
- dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
350
+
351
+ if RUBY_PLATFORM.include?( 'linux' )
352
+ dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
353
+ end
338
354
 
339
355
  begin
340
356
  dst.connect_nonblock( destination_addr )
@@ -369,11 +385,11 @@ module Girl
369
385
  datas = src_info[ :rbuffs ]
370
386
 
371
387
  if datas.empty?
372
- # HTTP/1.1 CONNECT
388
+ # CONNECT
373
389
  # puts "debug1 add src wbuff http ok"
374
390
  add_src_wbuff( src, HTTP_OK )
375
391
  else
376
- # HTTP/1.1 not CONNECT
392
+ # not CONNECT
377
393
  # puts "debug1 add src rbuffs to dst wbuff"
378
394
 
379
395
  datas.each do | data |
@@ -434,6 +450,27 @@ module Girl
434
450
  add_src_wbuff( src, data )
435
451
  end
436
452
 
453
+ ##
454
+ # sub http request
455
+ #
456
+ def sub_http_request( data )
457
+ lines = data.split( "\r\n" )
458
+
459
+ if lines.empty?
460
+ return [ data, nil ]
461
+ end
462
+
463
+ method, url, proto = lines.first.split( ' ' )
464
+
465
+ if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://'
466
+ domain_and_port = url.split( '/' )[ 2 ]
467
+ data = data.sub( "http://#{ domain_and_port }", '' )
468
+ # puts "debug1 subed #{ data.inspect } #{ domain_and_port }"
469
+ end
470
+
471
+ [ data, domain_and_port ]
472
+ end
473
+
437
474
  ##
438
475
  # add tun ctlmsg
439
476
  #
@@ -460,7 +497,7 @@ module Girl
460
497
  spring = @tun_info[ :chunks ].size > 0 ? ( @tun_info[ :spring ] + 1 ) : 0
461
498
  filename = "#{ Process.pid }-#{ @tun_info[ :port ] }.#{ spring }"
462
499
  chunk_path = File.join( @tun_chunk_dir, filename )
463
- wbuffs = @tun_info[ :wbuffs ].map{ | _src_addr, _data | [ _src_addr, _data.bytesize.pack( 'n' ), _data ].join }
500
+ wbuffs = @tun_info[ :wbuffs ].map{ | _src_addr, _data | [ _src_addr, [ _data.bytesize ].pack( 'n' ), _data ].join }
464
501
 
465
502
  begin
466
503
  IO.binwrite( chunk_path, wbuffs.join )
@@ -939,8 +976,8 @@ module Girl
939
976
  src_addr = addrinfo.to_sockaddr
940
977
  @src_infos[ src ] = {
941
978
  src_addr: src_addr, # src地址
942
- proxy_proto: :unchecked, # :http / :socks5
943
- proxy_type: :unchecked, # :unchecked / :direct / :tunnel / :negotiation / :udp
979
+ proxy_proto: :uncheck, # :uncheck / :http / :socks5
980
+ proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
944
981
  dst: nil, # :direct的场合,对应的dst
945
982
  destination_domain: nil, # 目的地域名
946
983
  destination_port: nil, # 目的地端口
@@ -977,63 +1014,84 @@ module Girl
977
1014
  proxy_type = src_info[ :proxy_type ]
978
1015
 
979
1016
  case proxy_type
980
- when :unchecked
1017
+ when :uncheck
981
1018
  if data[ 0, 7 ] == 'CONNECT'
982
- # puts "debug1 HTTP/1.1 CONNECT"
1019
+ # puts "debug1 CONNECT"
1020
+ domain_and_port = data.split( "\r\n" )[ 0 ].split( ' ' )[ 1 ]
983
1021
 
984
- connect_to = data.split( "\r\n" )[ 0 ].split( ' ' )[ 1 ]
985
- domain, port = connect_to.split( ':' )
986
- port = port.to_i
987
- else
988
- # https://tools.ietf.org/html/rfc1928
989
- if data[ 0 ].unpack( 'C' ).first == 5
990
- # +----+----------+----------+
991
- # |VER | NMETHODS | METHODS |
992
- # +----+----------+----------+
993
- # | 1 | 1 | 1 to 255 |
994
- # +----+----------+----------+
995
- # puts "debug1 socks5 #{ data.inspect }"
996
- nmethods = data[ 1 ].unpack( 'C' ).first
997
- methods = data[ 2, nmethods ].unpack( 'C*' )
998
-
999
- unless methods.include?( 0 )
1000
- puts "p#{ Process.pid } #{ Time.new } miss method 00"
1001
- set_is_closing( src )
1002
- return
1003
- end
1004
-
1005
- # +----+--------+
1006
- # |VER | METHOD |
1007
- # +----+--------+
1008
- # | 1 | 1 |
1009
- # +----+--------+
1010
- data2 = [ 5, 0 ].pack( 'CC' )
1011
- add_src_wbuff( src, data2 )
1022
+ unless domain_and_port
1023
+ puts "p#{ Process.pid } #{ Time.new } CONNECT miss domain"
1024
+ set_is_closing( src )
1025
+ return
1026
+ end
1027
+ elsif data[ 0 ].unpack( 'C' ).first == 5
1028
+ # puts "debug1 socks5 #{ data.inspect }"
1012
1029
 
1013
- src_info[ :proxy_proto ] = :socks5
1014
- src_info[ :proxy_type ] = :negotiation
1030
+ # https://tools.ietf.org/html/rfc1928
1031
+ #
1032
+ # +----+----------+----------+
1033
+ # |VER | NMETHODS | METHODS |
1034
+ # +----+----------+----------+
1035
+ # | 1 | 1 | 1 to 255 |
1036
+ # +----+----------+----------+
1037
+ nmethods = data[ 1 ].unpack( 'C' ).first
1038
+ methods = data[ 2, nmethods ].unpack( 'C*' )
1039
+
1040
+ unless methods.include?( 0 )
1041
+ puts "p#{ Process.pid } #{ Time.new } miss method 00"
1042
+ set_is_closing( src )
1015
1043
  return
1016
1044
  end
1017
1045
 
1018
- # puts "debug1 HTTP/1.1 not CONNECT"
1019
- line = data.split( "\r\n" ).find { | _line | _line[ 0, 6 ] == 'Host: ' }
1046
+ # +----+--------+
1047
+ # |VER | METHOD |
1048
+ # +----+--------+
1049
+ # | 1 | 1 |
1050
+ # +----+--------+
1051
+ data2 = [ 5, 0 ].pack( 'CC' )
1052
+ add_src_wbuff( src, data2 )
1053
+
1054
+ src_info[ :proxy_proto ] = :socks5
1055
+ src_info[ :proxy_type ] = :negotiation
1056
+
1057
+ return
1058
+ else
1059
+ # puts "debug1 not CONNECT #{ data.inspect }"
1060
+ host_line = data.split( "\r\n" ).find { | _line | _line[ 0, 6 ] == 'Host: ' }
1020
1061
 
1021
- unless line
1022
- # puts "debug1 not found Host #{ data.inspect }"
1062
+ unless host_line
1063
+ # puts "debug1 not found host line"
1023
1064
  set_is_closing( src )
1024
1065
  return
1025
1066
  end
1026
1067
 
1027
- domain, port = line.split( ' ' )[ 1 ].split( ':' )
1028
- port = port ? port.to_i : 80
1068
+ data, domain_and_port = sub_http_request( data )
1069
+
1070
+ unless domain_and_port
1071
+ # puts "debug1 not HTTP"
1072
+ domain_and_port = host_line.split( ' ' )[ 1 ]
1073
+
1074
+ unless domain_and_port
1075
+ puts "p#{ Process.pid } #{ Time.new } Host line miss domain"
1076
+ set_is_closing( src )
1077
+ return
1078
+ end
1079
+ end
1080
+
1029
1081
  src_info[ :rbuffs ] << data
1030
1082
  end
1031
1083
 
1084
+ domain, port = domain_and_port.split( ':' )
1085
+ port = port ? port.to_i : 80
1086
+
1032
1087
  src_info[ :proxy_proto ] = :http
1033
1088
  src_info[ :destination_domain ] = domain
1034
1089
  src_info[ :destination_port ] = port
1035
1090
 
1036
1091
  resolve_domain( src, domain )
1092
+ when :checking
1093
+ # puts "debug1 add src rbuff while checking #{ data.inspect }"
1094
+ src_info[ :rbuffs ] << data
1037
1095
  when :negotiation
1038
1096
  # +----+-----+-------+------+----------+----------+
1039
1097
  # |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
@@ -1068,7 +1126,7 @@ module Girl
1068
1126
  end
1069
1127
  end
1070
1128
  else
1071
- # puts "debug1 cmd #{ cmd } not implement"
1129
+ puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
1072
1130
  end
1073
1131
  when :tunnel
1074
1132
  src_addr = src_info[ :src_addr ]
@@ -1087,6 +1145,10 @@ module Girl
1087
1145
  return
1088
1146
  end
1089
1147
 
1148
+ if src_info[ :rbuffs ].any?
1149
+ data, _ = sub_http_request( data )
1150
+ end
1151
+
1090
1152
  add_tun_wbuff( src_addr, data )
1091
1153
  else
1092
1154
  # puts "debug1 remote dst not ready, save data to src rbuff"
@@ -1102,6 +1164,10 @@ module Girl
1102
1164
  return
1103
1165
  end
1104
1166
 
1167
+ if src_info[ :rbuffs ].any?
1168
+ data, _ = sub_http_request( data )
1169
+ end
1170
+
1105
1171
  add_dst_wbuff( dst, data )
1106
1172
  else
1107
1173
  # puts "debug1 dst not ready, save data to src rbuff"
@@ -1197,11 +1263,11 @@ module Girl
1197
1263
  datas = src_info[ :rbuffs ]
1198
1264
 
1199
1265
  if datas.empty?
1200
- # HTTP/1.1 CONNECT
1266
+ # CONNECT
1201
1267
  # puts "debug1 add src wbuff http ok"
1202
1268
  add_src_wbuff( src, HTTP_OK )
1203
1269
  else
1204
- # HTTP/1.1 not CONNECT
1270
+ # not CONNECT
1205
1271
  # puts "debug1 add src rbuffs to tun wbuffs"
1206
1272
 
1207
1273
  datas.each do | _data |
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.58.1'.freeze
2
+ VERSION = '0.62.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: girl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.58.1
4
+ version: 0.62.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takafan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2020-06-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: while internet is evil, here's a girl.
14
14
  email: