girl 0.54.0 → 0.55.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: 19acd0601b223880d31ac0294928830d0a683e419bce6da31712914bebc7b65d
4
- data.tar.gz: 8b112d1eec1f6a83851e8b12e546217c8aeb59f9c743e56d600a23c2f5fc333e
3
+ metadata.gz: 98deb3d9378bcd1eb4477e0a6466c527770b957f627908fd2f6b696da6648083
4
+ data.tar.gz: f3bca1da27d757810adccb9bb20d3eddfbfdb7b5ea4e1d0c5130d956d0dbd059
5
5
  SHA512:
6
- metadata.gz: d9bc77923d0a6e1637cd3b29c2f15aca7d882bf7b6b7501c51cf0fac529244e63e2ce4f8ca47594886d598479eaf3f545801a9f5fdb5fd00075a520cd69db86f
7
- data.tar.gz: e57bdec56fb691207a9f4c1d47622c0f64ef9d4d3b703afba745281e41c50ae84825809af59fc84b1740eceb525a063b8ed3be130295af3725751518c9c44b3e
6
+ metadata.gz: 14d229048ad6c27df19295600b0c0817962b667bde195fd26a272a323d29b8f35196f49fc41cfc3b47afaac9f32e5e7d56be8dd890300a6d408e4a1a0fc600b5
7
+ data.tar.gz: de9f1a2af41e00056fb0822348276b5fcfd6326fe5b00813cc0f7bba66e2e7b524ad2a3f00d0e93d68723f14e4d4284a5f89f0e10564505c44e0d8a14ceee496
@@ -13,42 +13,44 @@ require 'socket'
13
13
  #
14
14
  # iptables -t nat -A PREROUTING -p udp -d game.server.ip -j REDIRECT --to-ports 1313
15
15
  #
16
- # control message
17
- # ================
16
+ # p2p flow
17
+ # =========
18
18
  #
19
- # C: 1 (tun > udpd: req a tund) -> orig_src_addr -> dest_addr
20
- # C: 2 (udpd > tun: tund port) -> n: tund_port -> tun_addr
21
- # C: 3 (udpd > tun: req a chain tun) -> new_dest_addr -> root_dest_addr
22
- # C: 4 (tun > udpd: req a chain tund) -> orig_src_addr -> dest_addr -> root_dest_addr
23
- # C: 5 (tun > tund: hello)
19
+ # 源地址src发往第二个目的地dst2,iptables会映射一个新的本地端口sport2,用来代理dst2的返程。
20
+ # 可在nf_conntrack里找到src1和src2,看到映射前的源地址端口是一样的。
21
+ # 若在sport2没有收到返程30秒过期后,src发往第三个目的地dst3,iptables会把dst3的返程依旧映射在sport2上。因此不能根据映射端口建tun-tund对。
24
22
  #
25
- # flow
26
- # =====
23
+ # tund1接到dst2,看作p2p进来,记tund1为src-dst2发送代理。
24
+ # 取接收者tund1.dst2.receiver,由接收者接数据。
25
+ # 若接收者为空,据dst2-src找接收者,找到tund2,tund2-tun2传数据,同时tund1发tund2.wmems去dst2。没找到,记tund1.dst2.rbuff。
27
26
  #
28
- # src从本机端口发出,发往两个目的地:
27
+ # src经tun2-tund2发往dst2,记tund2为dst2-src接收者。
28
+ # 取发送代理tund2.alias_sender,由发送代理发数据。
29
+ # 若发送代理为空,据src-dst2找发送代理,找到tund1,tund1发数据给dst2,同时tund2转tund1.dst2.rbuffs给tun2。没找到,tund2-dst2,记tund2.wmem。
29
30
  #
30
- # src1=redir.recv -> new tun1 -> ctlmsg.1 -> udpd.recv -> new tund1 -> tund1.recv -> dst1
31
- # src2=redir.recv -> new tun2 -> ctlmsg.1 -> udpd.recv -> new tund2 -> tund2.recv -> dst2
31
+ # 请求匹配服务器:
32
32
  #
33
- # src发往dst2,iptables会映射一个新的端口src2用来代理dst2的返程。可以在nf_conntrack里找到转换前的原端口,看到src2和src1是一样的。
33
+ # redir recv -> src1, dst1, data -> tun1-tund1 data -> set receiver dst1-src: tund1 -> tund1-dst1 data
34
34
  #
35
- # p2p对面先到:
35
+ # 匹配服务器返回:
36
36
  #
37
- # dst3=tund1.recv -> ctlmsg.3 -> tun1.recv -> new tun3 -> ctlmsg.4 -> udpd.recv -> new tund3 -> tun3.recv -> tun3.dest_rbuffs
38
- # -> src3=redir.recv -> tun3=tuns.find([:orig_src dst3]) -> redir.wbuffs.append(tun3.dest_rbuffs) -> redir.send_to(src3)
37
+ # tund1 recv -> dst1, data -> tund1-tun1 data -> redir-src1 data
39
38
  #
40
- # p2p对面先到的情况,准备好tun3-tund3,一边redir接到src3,根据[转换前地址 目的地],匹中tun3。
39
+ # p1发往p2:
41
40
  #
42
- # 来自对面的数据,先存在tund1身上,再移给tun3,src3匹中tun3后,移给redir写入src3。
41
+ # redir recv -> src2, dst2, data -> tun2-tund2 data -> set receiver dst2-src: tund2 -> alias sender not found -> tund2-dst2 data -> save wmem
43
42
  #
44
- # p2p自己先出去:
43
+ # p2后进来:
45
44
  #
46
- # src2=redir.recv -> new tun2 -> ctlmsg.1 -> udpd.recv -> new tund2 -> tund2.recv -> tund2.send_to(dst2) -> 撞死
47
- # -> dst2=tund1.recv -> tund2=tunds.find(tun1_ip-orig_src-dst2) -> tun2.recv -> redir.send_to(src2)
45
+ # tund1 recv -> dst2, data -> set alias sender src-dst2: tund1 -> found receiver tund2 -> tund2-tun2 redir-src2 data -> tund1-dst2 tund2.wmems
48
46
  #
49
- # p2p自己先出去的情况,包会撞死,并且这时还不知道tun2-tund2转发的是p2p流量。不用知道,先把发出的包缓存一下(存最后一个就行,一般是连发打洞的数据)。
47
+ # p3进来:
50
48
  #
51
- # 一边tund1接到dst2,根据[:tun_ip :orig_src dst2],匹中tund2。这时知道了tund2是p2p,由tund1代之和dst2通信(先把缓存的最后一个包发过去)。
49
+ # tund1 recv -> dst3, data -> set alias sender src-dst3: tund1 -> receiver not found -> save data to tund1.dst3.rbuffs
50
+ #
51
+ # p1后发往p3:
52
+ #
53
+ # redir recv -> src3, dst3, data -> tun3-tund3 data -> set receiver dst3-src: tund3 -> found alias sender tund1 -> tund1-dst3 data -> tund3-tun3 redir-src tund1.dst3.rbuffs
52
54
  #
53
55
  module Girl
54
56
  class Udp
@@ -74,16 +76,15 @@ module Girl
74
76
  redir => :redir
75
77
  }
76
78
  @redir_wbuffs = [] # [ src_addr data ] ...
77
- @tuns = {} # [ orig_src_addr dest_addr ] => tun
79
+ @tuns = {} # [ orig_src_addr dst_addr ]=> tun
80
+ @mappings = {} # src_addr => [ orig_src_addr dst_addr ]
78
81
  @tun_infos = {} # tun => {}
79
82
  # orig_src_addr: sockaddr
80
- # dest_addr: sockaddr
83
+ # dst_addr: sockaddr
81
84
  # src_addr: sockaddr
82
- # tun_addr: sockaddr
83
85
  # tund_addr: sockaddr
84
86
  # ctlmsgs: []
85
87
  # wbuffs: []
86
- # dest_rbuffs: []
87
88
  # last_traff_at: now
88
89
  end
89
90
 
@@ -143,41 +144,34 @@ module Girl
143
144
  rows = bin.split( "\n" ).map { | line | line.split( ' ' ) }
144
145
  row = rows.find { | _row | _row[ 2 ] == 'udp' && ( ( _row[ 9 ] == '[UNREPLIED]' && _row[ 11 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 13 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) || ( _row[ 10 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 12 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) ) }
145
146
 
146
- unless row
147
- puts "miss conntrack #{ addrinfo.inspect } #{ Time.new }"
148
- IO.binwrite( '/tmp/nf_conntrack', bin )
149
- return
150
- end
151
-
152
- orig_src_ip = row[ 5 ].split( '=' )[ 1 ]
153
- orig_src_port = row[ 7 ].split( '=' )[ 1 ].to_i
154
- dest_ip = row[ 6 ].split( '=' )[ 1 ]
155
- dest_port = row[ 8 ].split( '=' )[ 1 ].to_i
156
- orig_src_addr = Socket.sockaddr_in( orig_src_port, orig_src_ip )
157
- dest_addr = Socket.sockaddr_in( dest_port, dest_ip )
158
- tun = @tuns[ [ orig_src_addr, dest_addr ].join ]
147
+ if row
148
+ orig_src_ip = row[ 5 ].split( '=' )[ 1 ]
149
+ orig_src_port = row[ 7 ].split( '=' )[ 1 ].to_i
150
+ dst_ip = row[ 6 ].split( '=' )[ 1 ]
151
+ dst_port = row[ 8 ].split( '=' )[ 1 ].to_i
152
+ orig_src_addr = Socket.sockaddr_in( orig_src_port, orig_src_ip )
153
+ dst_addr = Socket.sockaddr_in( dst_port, dst_ip )
154
+ else
155
+ unless @mappings.include?( src_addr )
156
+ puts "miss conntrack #{ addrinfo.inspect } #{ Time.new }"
157
+ IO.binwrite( '/tmp/nf_conntrack', bin )
158
+ return
159
+ end
159
160
 
160
- if tun
161
- tun_info = @tun_infos[ tun ]
161
+ puts "hit mapping #{ addrinfo.inspect }"
162
+ orig_src_addr, dst_addr = @mappings[ src_addr ]
163
+ end
162
164
 
163
- unless tun_info[ :src_addr ]
164
- # p2p paired
165
- tun_info[ :src_addr ] = src_addr
165
+ tun = @tuns[ [ orig_src_addr, dst_addr ].join ]
166
166
 
167
- if tun_info[ :dest_rbuffs ].any?
168
- # puts "debug move dest_rbuff to redir #{ Addrinfo.new( tun_info[ :dest_addr ] ).inspect } #{ Addrinfo.new( tun_info[ :orig_src_addr ] ).inspect }"
169
- @redir_wbuffs += tun_info[ :dest_rbuffs ].map{ | buff | [ src_addr, buff ] }
170
- tun_info[ :dest_rbuffs ].clear
171
- add_redir_write( redir )
172
- end
173
- end
174
- else
175
- tun = new_a_tun( orig_src_addr, dest_addr, src_addr )
176
- tun_info = @tun_infos[ tun ]
167
+ unless tun
168
+ tun = new_a_tun( orig_src_addr, dst_addr, src_addr )
177
169
 
178
- # puts "debug send C: 1 (tun > udpd: req a tund) -> orig_src_addr dest_addr #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dest_addr ).inspect }"
179
- ctlmsg = [ [ 1 ].pack( 'C' ), orig_src_addr, dest_addr ].join
170
+ # puts "debug tun send to udpd #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect }"
171
+ ctlmsg = [ orig_src_addr, dst_addr ].join
180
172
  add_ctlmsg( tun, ctlmsg )
173
+
174
+ @mappings[ src_addr ] = [ orig_src_addr, dst_addr ]
181
175
  end
182
176
 
183
177
  add_write( tun, data )
@@ -190,46 +184,13 @@ module Girl
190
184
  tun_info[ :last_traff_at ] = Time.new
191
185
 
192
186
  if from_addr == @udpd_addr
193
- ctl_num = data[ 0 ].unpack( 'C' ).first
194
-
195
- case ctl_num
196
- when 2 # C: 2 (udpd > tun: tund port) -> n: tund_port -> tun_addr
197
- return if tun_info[ :tund_addr ]
198
-
199
- tund_port = data[ 1, 2 ].unpack( 'n' ).first
200
- tun_addr = data[ 3, 16 ]
201
- tund_addr = Socket.sockaddr_in( tund_port, @udpd_host )
202
- tun_info[ :tun_addr ] = tun_addr
203
- tun_info[ :tund_addr ] = tund_addr
204
-
205
- # flush wbuffs to tund, if empty, just send a cross nat msg (5: hello), tund should ignore hello
206
- if tun_info[ :wbuffs ].empty?
207
- tun_info[ :wbuffs ] << [ 5 ].pack( 'C' )
208
- end
209
-
210
- add_write( tun )
211
- when 3 # C: 3 (udpd > tun: req a chain tun) -> new_dest_addr -> root_dest_addr
212
- new_dest_addr = data[ 1, 16 ]
213
- root_dest_addr = data[ 17, 16 ]
214
- orig_src_addr = tun_info[ :orig_src_addr ]
215
- chain_tun = @tuns[ [ orig_src_addr, new_dest_addr ].join ]
216
-
217
- unless chain_tun
218
- chain_tun = new_a_tun( orig_src_addr, new_dest_addr )
219
- end
220
-
221
- # puts "debug send C: 4 (tun > udpd: req a chain tund) -> orig_src_addr -> dest_addr -> root_dest_addr #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( new_dest_addr ).inspect } #{ Addrinfo.new( root_dest_addr ).inspect }"
222
- ctlmsg = [ [ 4 ].pack( 'C' ), orig_src_addr, new_dest_addr, root_dest_addr ].join
223
- add_ctlmsg( chain_tun, ctlmsg )
224
- end
187
+ tund_port = data[ 0, 2 ].unpack( 'n' ).first
188
+ tund_addr = Socket.sockaddr_in( tund_port, @udpd_host )
189
+ tun_info[ :tund_addr ] = tund_addr
190
+ add_write( tun )
225
191
  elsif from_addr == tun_info[ :tund_addr ]
226
- if tun_info[ :src_addr ]
227
- @redir_wbuffs << [ tun_info[ :src_addr ], data ]
228
- add_redir_write( @redir )
229
- else
230
- # puts "debug save to tun.dest_rbuffs #{ data.inspect }"
231
- tun_info[ :dest_rbuffs ] << data
232
- end
192
+ @redir_wbuffs << [ tun_info[ :src_addr ], data ]
193
+ add_write( @redir )
233
194
  end
234
195
  end
235
196
 
@@ -269,27 +230,17 @@ module Girl
269
230
  def add_ctlmsg( tun, ctlmsg )
270
231
  tun_info = @tun_infos[ tun ]
271
232
  tun_info[ :ctlmsgs ] << ctlmsg
272
-
273
- unless @writes.include?( tun )
274
- @writes << tun
275
- end
233
+ add_write( tun )
276
234
  end
277
235
 
278
- def add_write( tun, data = nil )
279
- tun_info = @tun_infos[ tun ]
280
-
236
+ def add_write( sock, data = nil )
281
237
  if data
238
+ tun_info = @tun_infos[ sock ]
282
239
  tun_info[ :wbuffs ] << data
283
240
  end
284
241
 
285
- unless @writes.include?( tun )
286
- @writes << tun
287
- end
288
- end
289
-
290
- def add_redir_write( redir )
291
- unless @writes.include?( redir )
292
- @writes << redir
242
+ unless @writes.include?( sock )
243
+ @writes << sock
293
244
  end
294
245
  end
295
246
 
@@ -308,27 +259,33 @@ module Girl
308
259
  @closings.delete( tun )
309
260
  @roles.delete( tun )
310
261
  tun_info = @tun_infos.delete( tun )
311
- @tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dest_addr ] ].join )
262
+ @tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
263
+
264
+ if @mappings.include?( tun_info[ :src_addr ] )
265
+ orig_src_addr, dst_addr = @mappings[ tun_info[ :src_addr ] ]
266
+
267
+ if orig_src_addr == tun_info[ :orig_src_addr ] && dst_addr == tun_info[ :dst_addr ]
268
+ @mappings.delete( tun_info[ :src_addr ] )
269
+ end
270
+ end
312
271
  end
313
272
 
314
- def new_a_tun( orig_src_addr, dest_addr, src_addr = nil )
273
+ def new_a_tun( orig_src_addr, dst_addr, src_addr )
315
274
  tun = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
316
275
  tun.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
317
276
  tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
318
277
 
319
- @tuns[ [ orig_src_addr, dest_addr ].join ] = tun
320
278
  @tun_infos[ tun ] = {
321
279
  orig_src_addr: orig_src_addr,
322
- dest_addr: dest_addr,
280
+ dst_addr: dst_addr,
323
281
  src_addr: src_addr,
324
- tun_addr: nil,
325
282
  tund_addr: nil,
326
283
  ctlmsgs: [],
327
284
  wbuffs: [],
328
- dest_rbuffs: [],
329
285
  last_traff_at: Time.new
330
286
  }
331
287
 
288
+ @tuns[ [ orig_src_addr, dst_addr ].join ] = tun
332
289
  @roles[ tun ] = :tun
333
290
  @reads << tun
334
291
 
@@ -344,8 +301,8 @@ module Girl
344
301
  now = Time.new
345
302
 
346
303
  @tun_infos.values.each do | tun_info |
347
- if now - tun_info[ :last_traff_at ] > 1800
348
- @ctlw.write( [ tun_info[ :orig_src_addr ], tun_info[ :dest_addr ] ].join )
304
+ if now - tun_info[ :last_traff_at ] > 600
305
+ @ctlw.write( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
349
306
  end
350
307
  end
351
308
  end
@@ -26,19 +26,19 @@ module Girl
26
26
  udpd => :udpd
27
27
  }
28
28
  @udpd_wbuffs = [] # [ tun_addr ctlmsg ] ...
29
- @tunds = {} # [ tun_ip_addr orig_src_addr dest_addr ] => tund
29
+ @tunds = {} # tun_addr => tund
30
+ @alias_senders = {} # [ tun_ip_addr orig_src_addr dst_addr ] => tund # alias senders to dst
31
+ @receivers = {} # [ dst_addr tun_ip_addr orig_src_addr ] => tund # receivers from dst
30
32
  @tund_infos = {} # tund => {}
31
33
  # port: port
32
- # is_tunneled: false
33
34
  # tun_addr: sockaddr
34
35
  # tun_ip_addr: sockaddr
35
36
  # orig_src_addr: sockaddr
36
- # dest_addr: sockaddr
37
- # root_tund: tund1
38
- # wbuffs: []
39
- # is_dest_responsed: false
40
- # dest_wmemos: []
41
- # new_dest_rbuffs: { new_dest_addr => [] }
37
+ # dst_addr: sockaddr
38
+ # wbuffs: [] # 写往tun的写前缓存
39
+ # wmems: [] # 写往dst的写后缓存
40
+ # other_dst_rbuffs: { new_dst_addr => [] }
41
+ # receivers: { other_dst_addr => other_tund }
42
42
  # last_traff_at: now
43
43
  @od_addr_rbuffs = {}
44
44
  end
@@ -80,8 +80,8 @@ module Girl
80
80
  private
81
81
 
82
82
  def read_ctlr( ctlr )
83
- tod_addr = ctlr.read( 48 )
84
- tund = @tunds[ tod_addr ]
83
+ tun_addr = ctlr.read( 16 )
84
+ tund = @tunds[ tun_addr ]
85
85
 
86
86
  if tund
87
87
  add_closing( tund )
@@ -89,54 +89,29 @@ module Girl
89
89
  end
90
90
 
91
91
  def read_udpd( udpd )
92
- # C: 1 (tun > udpd: req a tund) -> orig_src_addr -> dest_addr
93
- # C: 4 (tun > udpd: req a chain tund) -> orig_src_addr -> dest_addr -> root_dest_addr
94
92
  data, addrinfo, rflags, *controls = udpd.recvmsg
95
93
  # puts "debug udpd recv #{ data.inspect } from #{ addrinfo.inspect }"
96
- ctl_num = data[ 0 ].unpack( 'C' ).first
97
- orig_src_addr = data[ 1, 16 ]
98
- dest_addr = data[ 17, 16 ]
94
+ orig_src_addr = data[ 0, 16 ]
95
+ dst_addr = data[ 16, 16 ]
99
96
  tun_addr = addrinfo.to_sockaddr
100
97
  tun_ip_addr = Addrinfo.ip( addrinfo.ip_address ).to_sockaddr
101
98
 
102
- return unless [ 1, 4 ].include?( ctl_num )
103
99
  return unless Addrinfo.new( orig_src_addr ).ipv4?
104
- return unless Addrinfo.new( dest_addr ).ipv4?
100
+ return unless Addrinfo.new( dst_addr ).ipv4?
105
101
 
106
- tund = @tunds[ [ tun_ip_addr, orig_src_addr, dest_addr ].join ]
102
+ tund = @tunds[ tun_addr ]
107
103
 
108
- if ctl_num == 1
109
- unless tund
110
- tund = new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dest_addr )
111
- end
112
- elsif ctl_num == 4
113
- root_dest_addr = data[ 33, 16 ]
114
- return unless Addrinfo.new( root_dest_addr ).ipv4?
115
-
116
- root_tund = @tunds[ [ tun_ip_addr, orig_src_addr, root_dest_addr ].join ]
117
-
118
- unless root_tund
119
- puts "miss root tund? #{ Addrinfo.new( tun_ip_addr ).inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( root_dest_addr ).inspect }"
120
- return
121
- end
122
-
123
- if tund
124
- tund_info = @tund_infos[ tund ]
125
- tund_info[ :root_tund ] = root_tund
126
- else
127
- tund = new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dest_addr, root_tund )
128
- end
104
+ unless tund
105
+ tund = new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
129
106
  end
130
107
 
131
108
  tund_info = @tund_infos[ tund ]
132
109
  tund_port = tund_info[ :port ]
133
110
 
134
- # puts "debug send C: 2 (udpd > tun: tund port) -> n: tund_port -> tun_addr #{ tund_port } #{ addrinfo.inspect }"
135
- @udpd_wbuffs << [ tun_addr, [ [ 2, tund_port ].pack( 'Cn' ), tun_addr ].join ]
136
-
137
- unless @writes.include?( udpd )
138
- @writes << udpd
139
- end
111
+ # puts "debug udpd send to tun #{ tund_port } #{ addrinfo.inspect }"
112
+ ctlmsg = [ tund_port ].pack( 'n' )
113
+ @udpd_wbuffs << [ tun_addr, ctlmsg ]
114
+ add_write( udpd )
140
115
  end
141
116
 
142
117
  def read_tund( tund )
@@ -145,78 +120,105 @@ module Girl
145
120
  tund_info = @tund_infos[ tund ]
146
121
  tund_info[ :last_traff_at ] = Time.new
147
122
 
148
- if from_addr == tund_info[ :tun_addr ]
149
- root_tund = tund_info[ :root_tund ]
123
+ case from_addr
124
+ when tund_info[ :tun_addr ]
125
+ # src经tun2-tund2发往dst2,记tund2为dst2-src接收者。
126
+ dto_addr = [ tund_info[ :dst_addr ], tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join
150
127
 
151
- if !tund_info[ :is_tunneled ]
152
- tund_info[ :is_tunneled ] = true
128
+ if @receivers[ dto_addr ]
129
+ if @receivers[ dto_addr ] != tund
130
+ puts "receiver not unique? #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect } #{ Addrinfo.new( tund_info[ :tun_ip_addr ] ).inspect } #{ Addrinfo.new( tund_info[ :orig_src_addr ] ).inspect }"
131
+ return
132
+ end
133
+ else
134
+ @receivers[ dto_addr ] = tund
135
+ end
136
+
137
+ # 取发送代理tund2.alias_sender,由发送代理发数据。
138
+ sender = tund_info[ :alias_sender ]
139
+
140
+ if sender
141
+ # puts "debug alias sender send #{ data.inspect } to #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
142
+ sender.sendmsg( data, 0, tund_info[ :dst_addr ] )
143
+ else
144
+ # 若发送代理为空,据src-dst2找发送代理,找到tund1,tund1发数据给dst2,同时tund2转tund1.dst2.rbuffs给tun2。没找到,tund2-dst2,记tund2.wmem。
145
+ tod_addr = [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], tund_info[ :dst_addr ] ].join
146
+ sender = @alias_senders[ tod_addr ]
153
147
 
154
- if root_tund
155
- # p2p tunnel paired
156
- root_tund_info = @tund_infos[ root_tund ]
157
- dest_rbuffs = root_tund_info[ :new_dest_rbuffs ].delete( tund_info[ :dest_addr ] )
148
+ if sender
149
+ sender.sendmsg( data, 0, tund_info[ :dst_addr ] )
150
+ tund_info[ :alias_sender ] = sender
158
151
 
159
- if dest_rbuffs
160
- # puts "debug #{ Addrinfo.new( tund_info[ :dest_addr ] ).inspect } dest_rbuffs #{ dest_rbuffs.inspect }"
161
- tund_info[ :wbuffs ] = dest_rbuffs
152
+ sender_info = @tund_infos[ sender ]
153
+ rbuffs = sender_info[ :other_dst_rbuffs ].delete( tund_info[ :dst_addr ] )
154
+
155
+ if rbuffs
156
+ # puts "debug move tund1.dst2.rbuffs to tund2.wbuffs #{ rbuffs.inspect }"
157
+ tund_info[ :wbuffs ] += rbuffs
162
158
  add_write( tund )
163
159
  end
160
+ else
161
+ tund.sendmsg( data, 0, tund_info[ :dst_addr ] )
164
162
 
165
- if data.size == 1 && data[ 0 ].unpack( 'C' ).first == 5
166
- puts "ignore C: 5 (hello) #{ Time.new }"
167
- return
163
+ # 缓存写后,可能是p2p自己先出去,撞死的流量,之后对面进来匹配成对,由发送代理重发。超过5条看做非p2p。
164
+ if tund_info[ :wmems ].size < 5
165
+ # puts "debug save wmem #{ data.inspect } #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
166
+ tund_info[ :wmems ] << data
168
167
  end
169
168
  end
170
169
  end
171
-
172
- sender = root_tund || tund
173
- sender.sendmsg( data, 0, tund_info[ :dest_addr ] )
174
-
175
- if root_tund.nil? && !tund_info[ :is_dest_responsed ]
176
- if tund_info[ :dest_wmemos ].size >= 10
177
- tund_info[ :dest_wmemos ].clear
178
- end
179
-
180
- tund_info[ :dest_wmemos ] << data
181
- end
182
- elsif from_addr == tund_info[ :dest_addr ]
183
- tund_info[ :is_dest_responsed ] = true
170
+ when tund_info[ :dst_addr ]
171
+ # puts "debug tund-tun #{ data.inspect } from #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
184
172
  add_write( tund, data )
185
173
  else
186
- # p2p input
187
- # puts "debug tund recv #{ data.inspect } from #{ Addrinfo.new( from_addr ).inspect }"
188
- chain_tund = @tunds[ [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], from_addr ].join ]
189
-
190
- unless chain_tund
191
- unless tund_info[ :new_dest_rbuffs ].include?( from_addr )
192
- tund_info[ :new_dest_rbuffs ][ from_addr ] = []
174
+ # tund1接到dst2,看作p2p进来,记tund1为src-dst2发送代理。
175
+ # puts "debug tund recv #{ data.inspect } from #{ addrinfo.inspect }"
176
+ tod_addr = [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], from_addr ].join
177
+
178
+ if @alias_senders[ tod_addr ]
179
+ if @alias_senders[ tod_addr ] != tund
180
+ puts "alias sender not unique? #{ Addrinfo.new( tund_info[ :tun_ip_addr ] ).inspect } #{ Addrinfo.new( tund_info[ :orig_src_addr ] ).inspect } #{ addrinfo.inspect }"
181
+ return
193
182
  end
183
+ else
184
+ @alias_senders[ tod_addr ] = tund
185
+ end
194
186
 
195
- tund_info[ :new_dest_rbuffs ][ from_addr ] << data
187
+ # 取接收者tund1.dst2.receiver,由接收者接数据。
188
+ receiver = tund_info[ :receivers ][ from_addr ]
196
189
 
197
- # puts "debug send C: 3 (udpd > tun: req a chain tun) -> new_dest_addr -> root_dest_addr #{ Addrinfo.new( from_addr ).inspect } #{ Addrinfo.new( tund_info[ :dest_addr ] ).inspect }"
198
- msg = [ [ 3 ].pack( 'C' ), from_addr, tund_info[ :dest_addr ] ].join
199
- @udpd.sendmsg( msg, 0, tund_info[ :tun_addr ] )
200
- return
201
- end
190
+ if receiver
191
+ receiver_info = @tund_infos[ receiver ]
192
+ add_write( receiver, data )
193
+ else
194
+ # 若接收者为空,据dst2-src找接收者,找到tund2,tund2-tun2传数据,同时tund1转tund2.wmems给dst2。没找到,记tund1.dst2.rbuff。
195
+ dto_addr = [ from_addr, tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join
196
+ receiver = @receivers[ dto_addr ]
202
197
 
203
- chain_tund_info = @tund_infos[ chain_tund ]
198
+ if receiver
199
+ add_write( receiver, data )
204
200
 
205
- unless chain_tund_info[ :root_tund ]
206
- # p2p paired
207
- chain_tund_info[ :root_tund ] = tund
201
+ tund_info[ :receivers ][ from_addr ] = receiver
202
+ receiver_info = @tund_infos[ receiver ]
208
203
 
209
- if chain_tund_info[ :dest_wmemos ].size > 0
210
- chain_tund_info[ :dest_wmemos ].each do | wmemo |
211
- # puts "debug send wmemo #{ wmemo.inspect } to #{ Addrinfo.new( from_addr ).inspect }"
212
- tund.sendmsg( wmemo, 0, from_addr )
204
+ receiver_info[ :wmems ].each do | wmem |
205
+ # puts "debug send wmem #{ wmem.inspect } to #{ addrinfo.inspect }"
206
+ tund.sendmsg( wmem, 0, from_addr )
213
207
  end
214
208
 
215
- chain_tund_info[ :dest_wmemos ].clear
209
+ receiver_info[ :wmems ].clear
210
+ else
211
+ unless tund_info[ :other_dst_rbuffs ][ from_addr ]
212
+ tund_info[ :other_dst_rbuffs ][ from_addr ] = []
213
+ end
214
+
215
+ # 暂存对面先到的p2p流量。超过5条看做意外数据忽略。
216
+ if tund_info[ :other_dst_rbuffs ][ from_addr ].size < 5
217
+ # puts "debug save other dst rbuff #{ addrinfo.inspect } #{ data.inspect }"
218
+ tund_info[ :other_dst_rbuffs ][ from_addr ] << data
219
+ end
216
220
  end
217
221
  end
218
-
219
- add_write( chain_tund, data )
220
222
  end
221
223
  end
222
224
 
@@ -247,15 +249,14 @@ module Girl
247
249
  tund.sendmsg( data, 0, tund_info[ :tun_addr ] )
248
250
  end
249
251
 
250
- def add_write( tund, data = nil )
251
- tund_info = @tund_infos[ tund ]
252
-
252
+ def add_write( sock, data = nil )
253
253
  if data
254
+ tund_info = @tund_infos[ sock ]
254
255
  tund_info[ :wbuffs ] << data
255
256
  end
256
257
 
257
- if tund_info[ :tun_addr ] && !@writes.include?( tund )
258
- @writes << tund
258
+ unless @writes.include?( sock )
259
+ @writes << sock
259
260
  end
260
261
  end
261
262
 
@@ -274,28 +275,39 @@ module Girl
274
275
  @closings.delete( tund )
275
276
  @roles.delete( tund )
276
277
  tund_info = @tund_infos.delete( tund )
277
- @tunds.delete( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], tund_info[ :dest_addr ] ].join )
278
+ @tunds.delete( tund_info[ :tun_addr ] )
279
+
280
+ tod_addr = [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], tund_info[ :dst_addr ] ].join
281
+
282
+ if @alias_senders[ tod_addr ] && @alias_senders[ tod_addr ] == tund
283
+ @alias_senders.delete( tod_addr )
284
+ end
285
+
286
+ dto_addr = [ tund_info[ :dst_addr ], tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join
287
+
288
+ if @receivers[ dto_addr ] && @receivers[ dto_addr ] == tund
289
+ @receivers.delete( dto_addr )
290
+ end
278
291
  end
279
292
 
280
- def new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dest_addr, root_tund = nil )
293
+ def new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
281
294
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
282
295
  tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
296
+ tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
283
297
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
284
298
  tund_port = tund.local_address.ip_unpack.last
285
299
 
286
- @tunds[ [ tun_ip_addr, orig_src_addr, dest_addr ].join ] = tund
300
+ @tunds[ tun_addr ] = tund
287
301
  @tund_infos[ tund ] = {
288
302
  port: tund_port,
289
- is_tunneled: false,
290
303
  tun_addr: tun_addr,
291
304
  tun_ip_addr: tun_ip_addr,
292
305
  orig_src_addr: orig_src_addr,
293
- dest_addr: dest_addr,
294
- root_tund: root_tund,
306
+ dst_addr: dst_addr,
295
307
  wbuffs: [],
296
- is_dest_responsed: root_tund ? true : false,
297
- dest_wmemos: [],
298
- new_dest_rbuffs: {},
308
+ wmems: [],
309
+ other_dst_rbuffs: {},
310
+ receivers: {},
299
311
  last_traff_at: Time.new
300
312
  }
301
313
 
@@ -314,8 +326,8 @@ module Girl
314
326
  now = Time.new
315
327
 
316
328
  @tund_infos.values.each do | tund_info |
317
- if now - tund_info[ :last_traff_at ] > 1800
318
- @ctlw.write( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], tund_info[ :dest_addr ] ].join )
329
+ if now - tund_info[ :last_traff_at ] > 600
330
+ @ctlw.write( tund_info[ :tun_addr ] )
319
331
  end
320
332
  end
321
333
  end
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.54.0'.freeze
2
+ VERSION = '0.55.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.54.0
4
+ version: 0.55.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-04-02 00:00:00.000000000 Z
11
+ date: 2020-04-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: while internet is evil, here's a girl.
14
14
  email: