girl 0.55.0 → 0.56.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: 98deb3d9378bcd1eb4477e0a6466c527770b957f627908fd2f6b696da6648083
4
- data.tar.gz: f3bca1da27d757810adccb9bb20d3eddfbfdb7b5ea4e1d0c5130d956d0dbd059
3
+ metadata.gz: 51cd8eb08b9c349052e54ac302dd4ad2fdfac19b93e80636d20507ab21e1d3b5
4
+ data.tar.gz: 05d5de915f020e027d938f410a9a875ba92b39cb668a14ad9a3f523ecf5424dd
5
5
  SHA512:
6
- metadata.gz: 14d229048ad6c27df19295600b0c0817962b667bde195fd26a272a323d29b8f35196f49fc41cfc3b47afaac9f32e5e7d56be8dd890300a6d408e4a1a0fc600b5
7
- data.tar.gz: de9f1a2af41e00056fb0822348276b5fcfd6326fe5b00813cc0f7bba66e2e7b524ad2a3f00d0e93d68723f14e4d4284a5f89f0e10564505c44e0d8a14ceee496
6
+ metadata.gz: 0bf9735b27decf69c11b3c2b9701ec6f77f351a95b5ab0585cffbc0d17df0ed0dce0b94cacc5b2b032b9ebf0e7ca13cb2b8ab49ba6c2d300c3a02a0985bbdd21
7
+ data.tar.gz: a8a5b465ed7ef52108ff56d8ddaf0b5a56e3b10ca1d254f78e069df198d3e3df8d1fe7285ea2e8695e24e9d26d41d72bb803955ad1a90aaa75672c2244aa15e7
@@ -13,45 +13,6 @@ 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
- # p2p flow
17
- # =========
18
- #
19
- # 源地址src发往第二个目的地dst2,iptables会映射一个新的本地端口sport2,用来代理dst2的返程。
20
- # 可在nf_conntrack里找到src1和src2,看到映射前的源地址端口是一样的。
21
- # 若在sport2没有收到返程30秒过期后,src发往第三个目的地dst3,iptables会把dst3的返程依旧映射在sport2上。因此不能根据映射端口建tun-tund对。
22
- #
23
- # tund1接到dst2,看作p2p进来,记tund1为src-dst2发送代理。
24
- # 取接收者tund1.dst2.receiver,由接收者接数据。
25
- # 若接收者为空,据dst2-src找接收者,找到tund2,tund2-tun2传数据,同时tund1发tund2.wmems去dst2。没找到,记tund1.dst2.rbuff。
26
- #
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。
30
- #
31
- # 请求匹配服务器:
32
- #
33
- # redir recv -> src1, dst1, data -> tun1-tund1 data -> set receiver dst1-src: tund1 -> tund1-dst1 data
34
- #
35
- # 匹配服务器返回:
36
- #
37
- # tund1 recv -> dst1, data -> tund1-tun1 data -> redir-src1 data
38
- #
39
- # p1发往p2:
40
- #
41
- # redir recv -> src2, dst2, data -> tun2-tund2 data -> set receiver dst2-src: tund2 -> alias sender not found -> tund2-dst2 data -> save wmem
42
- #
43
- # p2后进来:
44
- #
45
- # tund1 recv -> dst2, data -> set alias sender src-dst2: tund1 -> found receiver tund2 -> tund2-tun2 redir-src2 data -> tund1-dst2 tund2.wmems
46
- #
47
- # p3进来:
48
- #
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
54
- #
55
16
  module Girl
56
17
  class Udp
57
18
 
@@ -83,7 +44,7 @@ module Girl
83
44
  # dst_addr: sockaddr
84
45
  # src_addr: sockaddr
85
46
  # tund_addr: sockaddr
86
- # ctlmsgs: []
47
+ # rbuffs: []
87
48
  # wbuffs: []
88
49
  # last_traff_at: now
89
50
  end
@@ -136,30 +97,51 @@ module Girl
136
97
  def read_redir( redir )
137
98
  data, addrinfo, rflags, *controls = redir.recvmsg
138
99
  src_addr = addrinfo.to_sockaddr
139
-
100
+ is_hit_cache = false
101
+ now = Time.new
140
102
  # puts "debug redir recv #{ data.inspect } from #{ addrinfo.inspect }"
141
- # 2 udp 5 src 7 sport 9 [UNREPLIED] 11 dst 13 dport
142
- # 2 udp 5 src 7 sport 10 dst 12 dport
143
- bin = IO.binread( '/proc/net/nf_conntrack' )
144
- rows = bin.split( "\n" ).map { | line | line.split( ' ' ) }
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 ) ) }
146
103
 
147
- if row
104
+ if @mappings.include?( src_addr )
105
+ orig_src_addr, dst_addr, timeout, read_at = @mappings[ src_addr ]
106
+
107
+ if now - read_at < timeout
108
+ # puts "debug hit cache #{ addrinfo.inspect }"
109
+ is_hit_cache = true
110
+ else
111
+ # puts "debug cache timeout #{ addrinfo.inspect }"
112
+ @mappings.delete( src_addr )
113
+ end
114
+ end
115
+
116
+ unless is_hit_cache
117
+ # 2 udp 4 timeout 5 src 7 sport 9 [UNREPLIED] 11 dst 13 dport
118
+ # 2 udp 4 timeout 5 src 7 sport 10 dst 12 dport
119
+ bin = IO.binread( '/proc/net/nf_conntrack' )
120
+ rows = bin.split( "\n" ).map { | line | line.split( ' ' ) }
121
+ row = rows.find { | _row | _row[ 2 ] == 'udp' && ( ( _row[ 10 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 12 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) || ( _row[ 9 ] == '[UNREPLIED]' && _row[ 11 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 13 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) ) }
122
+
123
+ unless row
124
+ puts "miss conntrack #{ addrinfo.inspect } #{ Time.new }"
125
+ IO.binwrite( '/tmp/nf_conntrack', bin )
126
+ return
127
+ end
128
+
129
+ timeout = row[ 4 ].to_i
148
130
  orig_src_ip = row[ 5 ].split( '=' )[ 1 ]
149
131
  orig_src_port = row[ 7 ].split( '=' )[ 1 ].to_i
150
132
  dst_ip = row[ 6 ].split( '=' )[ 1 ]
151
133
  dst_port = row[ 8 ].split( '=' )[ 1 ].to_i
152
134
  orig_src_addr = Socket.sockaddr_in( orig_src_port, orig_src_ip )
153
135
  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 )
136
+
137
+ if Addrinfo.new( dst_addr ).ipv4_private?
138
+ puts "dst is private? #{ Addrinfo.new( dst_addr ).inspect } #{ Addrinfo.new( src_addr ).inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Time.new }"
139
+ add_redir_wbuff( redir, dst_addr, data )
158
140
  return
159
141
  end
160
142
 
161
- puts "hit mapping #{ addrinfo.inspect }"
162
- orig_src_addr, dst_addr = @mappings[ src_addr ]
143
+ # puts "debug save cache #{ addrinfo.inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect } #{ timeout } #{ now }"
144
+ @mappings[ src_addr ] = [ orig_src_addr, dst_addr, timeout, now ]
163
145
  end
164
146
 
165
147
  tun = @tuns[ [ orig_src_addr, dst_addr ].join ]
@@ -169,12 +151,11 @@ module Girl
169
151
 
170
152
  # puts "debug tun send to udpd #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect }"
171
153
  ctlmsg = [ orig_src_addr, dst_addr ].join
172
- add_ctlmsg( tun, ctlmsg )
173
-
174
- @mappings[ src_addr ] = [ orig_src_addr, dst_addr ]
154
+ add_tun_wbuff( tun, @udpd_addr, ctlmsg )
175
155
  end
176
156
 
177
- add_write( tun, data )
157
+ tun_info = @tun_infos[ tun ]
158
+ add_tun_wbuff( tun, tun_info[ :tund_addr ], data )
178
159
  end
179
160
 
180
161
  def read_tun( tun )
@@ -187,10 +168,15 @@ module Girl
187
168
  tund_port = data[ 0, 2 ].unpack( 'n' ).first
188
169
  tund_addr = Socket.sockaddr_in( tund_port, @udpd_host )
189
170
  tun_info[ :tund_addr ] = tund_addr
190
- add_write( tun )
171
+
172
+ if tun_info[ :rbuffs ].any?
173
+ tun_info[ :wbuffs ] += tun_info[ :rbuffs ].map{ | rbuff | [ tund_addr, rbuff ] }
174
+ tun_info[ :rbuffs ].clear
175
+ add_write( tun )
176
+ end
177
+
191
178
  elsif from_addr == tun_info[ :tund_addr ]
192
- @redir_wbuffs << [ tun_info[ :src_addr ], data ]
193
- add_write( @redir )
179
+ add_redir_wbuff( @redir, tun_info[ :src_addr ], data )
194
180
  end
195
181
  end
196
182
 
@@ -211,34 +197,33 @@ module Girl
211
197
  end
212
198
 
213
199
  tun_info = @tun_infos[ tun ]
214
- ctlmsg = tun_info[ :ctlmsgs ].shift
215
-
216
- if ctlmsg
217
- tun.sendmsg( ctlmsg, 0, @udpd_addr )
218
- return
219
- end
220
200
 
221
- if tun_info[ :tund_addr ].nil? || tun_info[ :wbuffs ].empty?
201
+ if tun_info[ :wbuffs ].empty?
222
202
  @writes.delete( tun )
223
203
  return
224
204
  end
225
205
 
226
- data = tun_info[ :wbuffs ].shift
227
- tun.sendmsg( data, 0, tun_info[ :tund_addr ] )
206
+ to_addr, data = tun_info[ :wbuffs ].shift
207
+ tun.sendmsg( data, 0, to_addr )
228
208
  end
229
209
 
230
- def add_ctlmsg( tun, ctlmsg )
231
- tun_info = @tun_infos[ tun ]
232
- tun_info[ :ctlmsgs ] << ctlmsg
233
- add_write( tun )
210
+ def add_redir_wbuff( redir, to_addr, data )
211
+ @redir_wbuffs << [ to_addr, data ]
212
+ add_write( redir )
234
213
  end
235
214
 
236
- def add_write( sock, data = nil )
237
- if data
238
- tun_info = @tun_infos[ sock ]
239
- tun_info[ :wbuffs ] << data
215
+ def add_tun_wbuff( tun, to_addr, data )
216
+ tun_info = @tun_infos[ tun ]
217
+
218
+ if to_addr
219
+ tun_info[ :wbuffs ] << [ to_addr, data ]
220
+ add_write( tun )
221
+ else
222
+ tun_info[ :rbuffs ] << data
240
223
  end
224
+ end
241
225
 
226
+ def add_write( sock )
242
227
  unless @writes.include?( sock )
243
228
  @writes << sock
244
229
  end
@@ -262,7 +247,7 @@ module Girl
262
247
  @tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
263
248
 
264
249
  if @mappings.include?( tun_info[ :src_addr ] )
265
- orig_src_addr, dst_addr = @mappings[ tun_info[ :src_addr ] ]
250
+ orig_src_addr, dst_addr, timeout, read_at = @mappings[ tun_info[ :src_addr ] ]
266
251
 
267
252
  if orig_src_addr == tun_info[ :orig_src_addr ] && dst_addr == tun_info[ :dst_addr ]
268
253
  @mappings.delete( tun_info[ :src_addr ] )
@@ -280,7 +265,7 @@ module Girl
280
265
  dst_addr: dst_addr,
281
266
  src_addr: src_addr,
282
267
  tund_addr: nil,
283
- ctlmsgs: [],
268
+ rbuffs: [],
284
269
  wbuffs: [],
285
270
  last_traff_at: Time.new
286
271
  }
@@ -295,13 +280,14 @@ module Girl
295
280
  def loop_expire
296
281
  Thread.new do
297
282
  loop do
298
- sleep 60
283
+ sleep 30
299
284
 
300
285
  @mutex.synchronize do
301
286
  now = Time.new
302
287
 
303
288
  @tun_infos.values.each do | tun_info |
304
- if now - tun_info[ :last_traff_at ] > 600
289
+ # net.netfilter.nf_conntrack_udp_timeout_stream
290
+ if now - tun_info[ :last_traff_at ] > 180
305
291
  @ctlw.write( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
306
292
  end
307
293
  end
@@ -22,25 +22,20 @@ module Girl
22
22
  @writes = []
23
23
  @closings = []
24
24
  @roles = {
25
- ctlr => :ctlr, # :ctlr / :udpd / :tund
25
+ ctlr => :ctlr, # :ctlr / :udpd / :tund
26
26
  udpd => :udpd
27
27
  }
28
- @udpd_wbuffs = [] # [ tun_addr ctlmsg ] ...
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
32
- @tund_infos = {} # tund => {}
33
- # port: port
34
- # tun_addr: sockaddr
35
- # tun_ip_addr: sockaddr
36
- # orig_src_addr: sockaddr
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
- # last_traff_at: now
43
- @od_addr_rbuffs = {}
28
+ @udpd_wbuffs = [] # [ tun_addr ctlmsg ] ...
29
+ @tunds = {} # [ tun_ip_addr orig_src_addr ] => tund
30
+ @tund_infos = {} # tund => {}
31
+ # port: port
32
+ # tun_ip_addr: sockaddr
33
+ # orig_src_addr: sockaddr
34
+ # wbuffs: [] # [ to_addr, data ] ...
35
+ # dst_addrs: { tun_addr => dst_addr }
36
+ # tun_addrs: { dst_addr => tun_addr }
37
+ # unpaired_dst_rbuffs: { dst_addr => [] }
38
+ # last_traff_at: now
44
39
  end
45
40
 
46
41
  def looping
@@ -80,8 +75,8 @@ module Girl
80
75
  private
81
76
 
82
77
  def read_ctlr( ctlr )
83
- tun_addr = ctlr.read( 16 )
84
- tund = @tunds[ tun_addr ]
78
+ to_addr = ctlr.read( 32 )
79
+ tund = @tunds[ to_addr ]
85
80
 
86
81
  if tund
87
82
  add_closing( tund )
@@ -97,14 +92,12 @@ module Girl
97
92
  tun_ip_addr = Addrinfo.ip( addrinfo.ip_address ).to_sockaddr
98
93
 
99
94
  return unless Addrinfo.new( orig_src_addr ).ipv4?
100
- return unless Addrinfo.new( dst_addr ).ipv4?
101
95
 
102
- tund = @tunds[ tun_addr ]
103
-
104
- unless tund
105
- tund = new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
106
- end
96
+ dst_addrinfo = Addrinfo.new( dst_addr )
97
+ return unless dst_addrinfo.ipv4?
98
+ return if dst_addrinfo.ipv4_private?
107
99
 
100
+ tund = pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
108
101
  tund_info = @tund_infos[ tund ]
109
102
  tund_port = tund_info[ :port ]
110
103
 
@@ -119,106 +112,42 @@ module Girl
119
112
  from_addr = addrinfo.to_sockaddr
120
113
  tund_info = @tund_infos[ tund ]
121
114
  tund_info[ :last_traff_at ] = Time.new
115
+ to_addr = tund_info[ :dst_addrs ][ from_addr ]
116
+
117
+ if to_addr
118
+ # 来自tun,发给dst。
119
+ # 如果对面没来过流量,且在nat里,nat规则是只对去过的目的地做接收,那么,先过去的流量会撞死。
120
+ # 没关系,撞死的流量通常是打洞数据,撞死在应用掌控之内,打洞数据通常是连发的。
121
+ # puts "debug #{ data.inspect } from #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
122
+ add_tund_wbuff( tund, to_addr, data )
123
+ return
124
+ end
122
125
 
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
126
+ to_addr = tund_info[ :tun_addrs ][ from_addr ]
127
127
 
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
128
+ if to_addr
129
+ # 来自dst,发给tun。
130
+ # 先发暂存
131
+ if tund_info[ :unpaired_dst_rbuffs ].include?( from_addr )
132
+ rbuffs = tund_info[ :unpaired_dst_rbuffs ].delete( from_addr )
133
+ # puts "debug move tund.dst.rbuffs to tund.wbuffs #{ rbuffs.inspect }"
134
+ tund_info[ :wbuffs ] += rbuffs.map{ | rbuff | [ to_addr, rbuff ] }
135
135
  end
136
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 ]
147
-
148
- if sender
149
- sender.sendmsg( data, 0, tund_info[ :dst_addr ] )
150
- tund_info[ :alias_sender ] = sender
151
-
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
158
- add_write( tund )
159
- end
160
- else
161
- tund.sendmsg( data, 0, tund_info[ :dst_addr ] )
162
-
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
167
- end
168
- end
169
- end
170
- when tund_info[ :dst_addr ]
171
- # puts "debug tund-tun #{ data.inspect } from #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
172
- add_write( tund, data )
173
- else
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
182
- end
183
- else
184
- @alias_senders[ tod_addr ] = tund
185
- end
186
-
187
- # 取接收者tund1.dst2.receiver,由接收者接数据。
188
- receiver = tund_info[ :receivers ][ from_addr ]
189
-
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 ]
197
-
198
- if receiver
199
- add_write( receiver, data )
200
-
201
- tund_info[ :receivers ][ from_addr ] = receiver
202
- receiver_info = @tund_infos[ receiver ]
203
-
204
- receiver_info[ :wmems ].each do | wmem |
205
- # puts "debug send wmem #{ wmem.inspect } to #{ addrinfo.inspect }"
206
- tund.sendmsg( wmem, 0, from_addr )
207
- end
137
+ # puts "debug #{ data.inspect } from #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
138
+ add_tund_wbuff( tund, to_addr, data )
139
+ return
140
+ end
208
141
 
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
142
+ # 来自未知的地方,看做是p2p对面先到。
143
+ unless tund_info[ :unpaired_dst_rbuffs ][ from_addr ]
144
+ tund_info[ :unpaired_dst_rbuffs ][ from_addr ] = []
145
+ end
214
146
 
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
220
- end
221
- end
147
+ # 暂存5条(连发打洞数据,不需要存多)。
148
+ if tund_info[ :unpaired_dst_rbuffs ][ from_addr ].size < 5
149
+ # puts "debug save other dst rbuff #{ addrinfo.inspect } #{ data.inspect }"
150
+ tund_info[ :unpaired_dst_rbuffs ][ from_addr ] << data
222
151
  end
223
152
  end
224
153
 
@@ -245,16 +174,18 @@ module Girl
245
174
  return
246
175
  end
247
176
 
248
- data = tund_info[ :wbuffs ].shift
249
- tund.sendmsg( data, 0, tund_info[ :tun_addr ] )
177
+ to_addr, data = tund_info[ :wbuffs ].shift
178
+ tund.sendmsg( data, 0, to_addr )
250
179
  end
251
180
 
252
- def add_write( sock, data = nil )
253
- if data
254
- tund_info = @tund_infos[ sock ]
255
- tund_info[ :wbuffs ] << data
256
- end
181
+ def add_tund_wbuff( tund, to_addr, data )
182
+ tund_info = @tund_infos[ tund ]
183
+ tund_info[ :wbuffs ] << [ to_addr, data ]
184
+
185
+ add_write( tund )
186
+ end
257
187
 
188
+ def add_write( sock )
258
189
  unless @writes.include?( sock )
259
190
  @writes << sock
260
191
  end
@@ -275,44 +206,39 @@ module Girl
275
206
  @closings.delete( tund )
276
207
  @roles.delete( tund )
277
208
  tund_info = @tund_infos.delete( tund )
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
209
+ @tunds.delete( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
291
210
  end
292
211
 
293
- def new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
294
- tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
295
- tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
296
- tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
297
- tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
298
- tund_port = tund.local_address.ip_unpack.last
299
-
300
- @tunds[ tun_addr ] = tund
301
- @tund_infos[ tund ] = {
302
- port: tund_port,
303
- tun_addr: tun_addr,
304
- tun_ip_addr: tun_ip_addr,
305
- orig_src_addr: orig_src_addr,
306
- dst_addr: dst_addr,
307
- wbuffs: [],
308
- wmems: [],
309
- other_dst_rbuffs: {},
310
- receivers: {},
311
- last_traff_at: Time.new
312
- }
212
+ def pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
213
+ from_addr = [ tun_ip_addr, orig_src_addr ].join
214
+ tund = @tunds[ from_addr ]
313
215
 
314
- @roles[ tund ] = :tund
315
- @reads << tund
216
+ if tund
217
+ tund_info = @tund_infos[ tund ]
218
+ tund_info[ :dst_addrs ][ tun_addr ] = dst_addr
219
+ tund_info[ :tun_addrs ][ dst_addr ] = tun_addr
220
+ else
221
+ tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
222
+ tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
223
+ tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
224
+ tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
225
+ tund_port = tund.local_address.ip_unpack.last
226
+
227
+ @tund_infos[ tund ] = {
228
+ port: tund_port,
229
+ tun_ip_addr: tun_ip_addr,
230
+ orig_src_addr: orig_src_addr,
231
+ wbuffs: [],
232
+ dst_addrs: { tun_addr => dst_addr },
233
+ tun_addrs: { dst_addr => tun_addr },
234
+ unpaired_dst_rbuffs: {},
235
+ last_traff_at: Time.new
236
+ }
237
+
238
+ @roles[ tund ] = :tund
239
+ @reads << tund
240
+ @tunds[ from_addr ] = tund
241
+ end
316
242
 
317
243
  tund
318
244
  end
@@ -320,14 +246,15 @@ module Girl
320
246
  def loop_expire
321
247
  Thread.new do
322
248
  loop do
323
- sleep 60
249
+ sleep 30
324
250
 
325
251
  @mutex.synchronize do
326
252
  now = Time.new
327
253
 
328
254
  @tund_infos.values.each do | tund_info |
329
- if now - tund_info[ :last_traff_at ] > 600
330
- @ctlw.write( tund_info[ :tun_addr ] )
255
+ # net.netfilter.nf_conntrack_udp_timeout_stream
256
+ if now - tund_info[ :last_traff_at ] > 180
257
+ @ctlw.write( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
331
258
  end
332
259
  end
333
260
  end
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.55.0'.freeze
2
+ VERSION = '0.56.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.55.0
4
+ version: 0.56.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-06 00:00:00.000000000 Z
11
+ date: 2020-04-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: while internet is evil, here's a girl.
14
14
  email: