girl 0.95.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of girl might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/girl.gemspec +0 -2
- data/lib/girl/proxy_worker.rb +312 -313
- data/lib/girl/proxyd_worker.rb +227 -178
- data/lib/girl/version.rb +1 -1
- metadata +2 -4
- data/lib/girl/udp.rb +0 -326
- data/lib/girl/udpd.rb +0 -316
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0c0254d6f9509721f13f14148087071820ae5ad13a3a7a87884d5372e7d93035
         | 
| 4 | 
            +
              data.tar.gz: 2e718e248d7b3967e350a0dd4b6266c2a396a7eb5193a2fcd419222606b9ac19
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: f9546abfd9b420cf80fa128670ba0db60e95bf54ed88466e1309820bb247ced3e7aa552d6afb93db12388a35b3d432d6994dfe2ea9a5f80580c82dce8655ff66
         | 
| 7 | 
            +
              data.tar.gz: 7e3b2c573cd03bb284cc5d51a44b0c4aa882f7c069759f63075216759cf5abdab44f80babe5f3dbe81c126a05d9e1449c9e65bab0d34e3a9f184a417e922d326
         | 
    
        data/girl.gemspec
    CHANGED
    
    
    
        data/lib/girl/proxy_worker.rb
    CHANGED
    
    | @@ -13,6 +13,13 @@ module Girl | |
| 13 13 | 
             
                  @mutex = Mutex.new
         | 
| 14 14 | 
             
                  @reads = []
         | 
| 15 15 | 
             
                  @writes = []
         | 
| 16 | 
            +
                  @closing_srcs = []
         | 
| 17 | 
            +
                  @paused_srcs = []
         | 
| 18 | 
            +
                  @paused_dsts = []
         | 
| 19 | 
            +
                  @paused_streams = []
         | 
| 20 | 
            +
                  @resume_srcs = []
         | 
| 21 | 
            +
                  @resume_dsts = []
         | 
| 22 | 
            +
                  @resume_streams = []
         | 
| 16 23 | 
             
                  @roles = {}         # sock => :dotr / :proxy / :src / :dst / :tun / :stream
         | 
| 17 24 | 
             
                  @src_infos = {}     # src => {}
         | 
| 18 25 | 
             
                  @dst_infos = {}     # dst => {}
         | 
| @@ -37,7 +44,6 @@ module Girl | |
| 37 44 | 
             
                    rs, ws = IO.select( @reads, @writes )
         | 
| 38 45 |  | 
| 39 46 | 
             
                    @mutex.synchronize do
         | 
| 40 | 
            -
                      # 先读,再写,避免打上关闭标记后读到
         | 
| 41 47 | 
             
                      rs.each do | sock |
         | 
| 42 48 | 
             
                        case @roles[ sock ]
         | 
| 43 49 | 
             
                        when :dotr then
         | 
| @@ -90,6 +96,15 @@ module Girl | |
| 90 96 |  | 
| 91 97 | 
             
                private
         | 
| 92 98 |  | 
| 99 | 
            +
                ##
         | 
| 100 | 
            +
                # add closing src
         | 
| 101 | 
            +
                #
         | 
| 102 | 
            +
                def add_closing_src( src )
         | 
| 103 | 
            +
                  return if src.closed? || @closing_srcs.include?( src )
         | 
| 104 | 
            +
                  @closing_srcs << src
         | 
| 105 | 
            +
                  next_tick
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 93 108 | 
             
                ##
         | 
| 94 109 | 
             
                # add ctlmsg
         | 
| 95 110 | 
             
                #
         | 
| @@ -101,14 +116,56 @@ module Girl | |
| 101 116 | 
             
                  if to_addr then
         | 
| 102 117 | 
             
                    @tun_info[ :ctlmsgs ] << [ data, to_addr ]
         | 
| 103 118 | 
             
                    add_write( @tun )
         | 
| 119 | 
            +
                    next_tick
         | 
| 104 120 | 
             
                  end
         | 
| 105 121 | 
             
                end
         | 
| 106 122 |  | 
| 123 | 
            +
                ##
         | 
| 124 | 
            +
                # add dst wbuff
         | 
| 125 | 
            +
                #
         | 
| 126 | 
            +
                def add_dst_wbuff( dst, data )
         | 
| 127 | 
            +
                  dst_info = @dst_infos[ dst ]
         | 
| 128 | 
            +
                  dst_info[ :wbuff ] << data
         | 
| 129 | 
            +
                  add_write( dst )
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                  if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 132 | 
            +
                    puts "p#{ Process.pid } #{ Time.new } pause direct src #{ dst_info[ :domain ] }"
         | 
| 133 | 
            +
                    add_paused_src( dst_info[ :src ] )
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
                end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                ##
         | 
| 138 | 
            +
                # add paused dst
         | 
| 139 | 
            +
                #
         | 
| 140 | 
            +
                def add_paused_dst( dst )
         | 
| 141 | 
            +
                  return if dst.closed? || @paused_dsts.include?( dst )
         | 
| 142 | 
            +
                  @reads.delete( dst )
         | 
| 143 | 
            +
                  @paused_dsts << dst
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                ##
         | 
| 147 | 
            +
                # add paused src
         | 
| 148 | 
            +
                #
         | 
| 149 | 
            +
                def add_paused_src( src )
         | 
| 150 | 
            +
                  return if src.closed? || @paused_srcs.include?( src )
         | 
| 151 | 
            +
                  @reads.delete( src )
         | 
| 152 | 
            +
                  @paused_srcs << src
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                ##
         | 
| 156 | 
            +
                # add paused stream
         | 
| 157 | 
            +
                #
         | 
| 158 | 
            +
                def add_paused_stream( stream )
         | 
| 159 | 
            +
                  return if stream.closed? || @paused_streams.include?( stream )
         | 
| 160 | 
            +
                  @reads.delete( stream )
         | 
| 161 | 
            +
                  @paused_streams << stream
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 107 164 | 
             
                ##
         | 
| 108 165 | 
             
                # add read
         | 
| 109 166 | 
             
                #
         | 
| 110 167 | 
             
                def add_read( sock, role = nil )
         | 
| 111 | 
            -
                   | 
| 168 | 
            +
                  if !sock.closed? && !@reads.include?( sock ) then
         | 
| 112 169 | 
             
                    @reads << sock
         | 
| 113 170 |  | 
| 114 171 | 
             
                    if role then
         | 
| @@ -117,11 +174,51 @@ module Girl | |
| 117 174 | 
             
                  end
         | 
| 118 175 | 
             
                end
         | 
| 119 176 |  | 
| 177 | 
            +
                ##
         | 
| 178 | 
            +
                # add resume dst
         | 
| 179 | 
            +
                #
         | 
| 180 | 
            +
                def add_resume_dst( dst )
         | 
| 181 | 
            +
                  return if @resume_dsts.include?( dst )
         | 
| 182 | 
            +
                  @resume_dsts << dst
         | 
| 183 | 
            +
                  next_tick
         | 
| 184 | 
            +
                end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                ##
         | 
| 187 | 
            +
                # add resume src
         | 
| 188 | 
            +
                #
         | 
| 189 | 
            +
                def add_resume_src( src )
         | 
| 190 | 
            +
                  return if @resume_srcs.include?( src )
         | 
| 191 | 
            +
                  @resume_srcs << src
         | 
| 192 | 
            +
                  next_tick
         | 
| 193 | 
            +
                end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                ##
         | 
| 196 | 
            +
                # add resume stream
         | 
| 197 | 
            +
                #
         | 
| 198 | 
            +
                def add_resume_stream( stream )
         | 
| 199 | 
            +
                  return if @resume_streams.include?( stream )
         | 
| 200 | 
            +
                  @resume_streams << stream
         | 
| 201 | 
            +
                  next_tick
         | 
| 202 | 
            +
                end
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                ##
         | 
| 205 | 
            +
                # add src rbuff
         | 
| 206 | 
            +
                #
         | 
| 207 | 
            +
                def add_src_rbuff( src, data )
         | 
| 208 | 
            +
                  src_info = @src_infos[ src ]
         | 
| 209 | 
            +
                  src_info[ :rbuff ] << data
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                  if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 212 | 
            +
                    # puts "debug1 src.rbuff full"
         | 
| 213 | 
            +
                    add_closing_src( src )
         | 
| 214 | 
            +
                  end
         | 
| 215 | 
            +
                end
         | 
| 216 | 
            +
             | 
| 120 217 | 
             
                ##
         | 
| 121 218 | 
             
                # add src wbuff
         | 
| 122 219 | 
             
                #
         | 
| 123 220 | 
             
                def add_src_wbuff( src, data )
         | 
| 124 | 
            -
                  return if src.closed?
         | 
| 221 | 
            +
                  return if src.closed? || @closing_srcs.include?( src )
         | 
| 125 222 | 
             
                  src_info = @src_infos[ src ]
         | 
| 126 223 | 
             
                  src_info[ :wbuff ] << data
         | 
| 127 224 | 
             
                  src_info[ :last_recv_at ] = Time.new
         | 
| @@ -131,18 +228,14 @@ module Girl | |
| 131 228 | 
             
                    dst = src_info[ :dst ]
         | 
| 132 229 |  | 
| 133 230 | 
             
                    if dst then
         | 
| 134 | 
            -
                       | 
| 135 | 
            -
                       | 
| 136 | 
            -
                      dst_info[ :paused ] = true
         | 
| 137 | 
            -
                      @reads.delete( dst )
         | 
| 231 | 
            +
                      puts "p#{ Process.pid } #{ Time.new } pause dst #{ src_info[ :destination_domain ] }"
         | 
| 232 | 
            +
                      add_paused_dst( dst )
         | 
| 138 233 | 
             
                    else
         | 
| 139 234 | 
             
                      stream = src_info[ :stream ]
         | 
| 140 235 |  | 
| 141 236 | 
             
                      if stream then
         | 
| 142 | 
            -
                         | 
| 143 | 
            -
                         | 
| 144 | 
            -
                        stream_info[ :paused ] = true
         | 
| 145 | 
            -
                        @reads.delete( stream )
         | 
| 237 | 
            +
                        puts "p#{ Process.pid } #{ Time.new } pause stream #{ src_info[ :destination_domain ] }"
         | 
| 238 | 
            +
                        add_paused_stream( stream )
         | 
| 146 239 | 
             
                      end
         | 
| 147 240 | 
             
                    end
         | 
| 148 241 | 
             
                  end
         | 
| @@ -164,34 +257,46 @@ module Girl | |
| 164 257 | 
             
                end
         | 
| 165 258 |  | 
| 166 259 | 
             
                ##
         | 
| 167 | 
            -
                # add  | 
| 260 | 
            +
                # add stream wbuff
         | 
| 168 261 | 
             
                #
         | 
| 169 | 
            -
                def  | 
| 170 | 
            -
                   | 
| 171 | 
            -
             | 
| 262 | 
            +
                def add_stream_wbuff( stream, data )
         | 
| 263 | 
            +
                  stream_info = @stream_infos[ stream ]
         | 
| 264 | 
            +
                  stream_info[ :wbuff ] << data
         | 
| 265 | 
            +
                  add_write( stream )
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                  if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 268 | 
            +
                    puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ stream_info[ :domain ] }"
         | 
| 269 | 
            +
                    add_paused_src( stream_info[ :src ] )
         | 
| 172 270 | 
             
                  end
         | 
| 173 271 | 
             
                end
         | 
| 174 272 |  | 
| 175 273 | 
             
                ##
         | 
| 176 | 
            -
                #  | 
| 274 | 
            +
                # add write
         | 
| 177 275 | 
             
                #
         | 
| 178 | 
            -
                def  | 
| 179 | 
            -
                  sock. | 
| 180 | 
            -
             | 
| 181 | 
            -
                   | 
| 182 | 
            -
                  @roles.delete( sock )
         | 
| 276 | 
            +
                def add_write( sock )
         | 
| 277 | 
            +
                  if !sock.closed? && !@writes.include?( sock ) then
         | 
| 278 | 
            +
                    @writes << sock
         | 
| 279 | 
            +
                  end
         | 
| 183 280 | 
             
                end
         | 
| 184 281 |  | 
| 185 282 | 
             
                ##
         | 
| 186 | 
            -
                # close dst
         | 
| 283 | 
            +
                # close read dst
         | 
| 187 284 | 
             
                #
         | 
| 188 | 
            -
                def  | 
| 189 | 
            -
                   | 
| 190 | 
            -
                   | 
| 191 | 
            -
                   | 
| 192 | 
            -
                   | 
| 193 | 
            -
             | 
| 194 | 
            -
                   | 
| 285 | 
            +
                def close_read_dst( dst )
         | 
| 286 | 
            +
                  return if dst.closed?
         | 
| 287 | 
            +
                  # puts "debug1 close read dst"
         | 
| 288 | 
            +
                  dst.close_read
         | 
| 289 | 
            +
                  @reads.delete( dst )
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                  if dst.closed? then
         | 
| 292 | 
            +
                    # puts "debug1 delete dst info"
         | 
| 293 | 
            +
                    @roles.delete( dst )
         | 
| 294 | 
            +
                    dst_info = @dst_infos.delete( dst )
         | 
| 295 | 
            +
                  else
         | 
| 296 | 
            +
                    dst_info = @dst_infos[ dst ]
         | 
| 297 | 
            +
                  end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                  dst_info
         | 
| 195 300 | 
             
                end
         | 
| 196 301 |  | 
| 197 302 | 
             
                ##
         | 
| @@ -211,30 +316,9 @@ module Girl | |
| 211 316 | 
             
                    src_info = @src_infos[ src ]
         | 
| 212 317 | 
             
                  end
         | 
| 213 318 |  | 
| 214 | 
            -
                  src_info[ :paused ] = false
         | 
| 215 319 | 
             
                  src_info
         | 
| 216 320 | 
             
                end
         | 
| 217 321 |  | 
| 218 | 
            -
                ##
         | 
| 219 | 
            -
                # close read dst
         | 
| 220 | 
            -
                #
         | 
| 221 | 
            -
                def close_read_dst( dst )
         | 
| 222 | 
            -
                  return if dst.closed?
         | 
| 223 | 
            -
                  # puts "debug1 close read dst"
         | 
| 224 | 
            -
                  dst.close_read
         | 
| 225 | 
            -
                  @reads.delete( dst )
         | 
| 226 | 
            -
             | 
| 227 | 
            -
                  if dst.closed? then
         | 
| 228 | 
            -
                    # puts "debug1 delete dst info"
         | 
| 229 | 
            -
                    @roles.delete( dst )
         | 
| 230 | 
            -
                    dst_info = @dst_infos.delete( dst )
         | 
| 231 | 
            -
                  else
         | 
| 232 | 
            -
                    dst_info = @dst_infos[ dst ]
         | 
| 233 | 
            -
                  end
         | 
| 234 | 
            -
             | 
| 235 | 
            -
                  dst_info
         | 
| 236 | 
            -
                end
         | 
| 237 | 
            -
             | 
| 238 322 | 
             
                ##
         | 
| 239 323 | 
             
                # close read stream
         | 
| 240 324 | 
             
                #
         | 
| @@ -255,68 +339,47 @@ module Girl | |
| 255 339 | 
             
                  stream_info
         | 
| 256 340 | 
             
                end
         | 
| 257 341 |  | 
| 342 | 
            +
                ##
         | 
| 343 | 
            +
                # close sock
         | 
| 344 | 
            +
                #
         | 
| 345 | 
            +
                def close_sock( sock )
         | 
| 346 | 
            +
                  sock.close
         | 
| 347 | 
            +
                  @reads.delete( sock )
         | 
| 348 | 
            +
                  @writes.delete( sock )
         | 
| 349 | 
            +
                  @roles.delete( sock )
         | 
| 350 | 
            +
                end
         | 
| 351 | 
            +
             | 
| 258 352 | 
             
                ##
         | 
| 259 353 | 
             
                # close src
         | 
| 260 354 | 
             
                #
         | 
| 261 355 | 
             
                def close_src( src )
         | 
| 356 | 
            +
                  return if src.closed?
         | 
| 262 357 | 
             
                  # puts "debug1 close src"
         | 
| 263 358 | 
             
                  close_sock( src )
         | 
| 264 359 | 
             
                  src_info = del_src_info( src )
         | 
| 265 360 | 
             
                  dst = src_info[ :dst ]
         | 
| 266 361 |  | 
| 267 362 | 
             
                  if dst then
         | 
| 268 | 
            -
                     | 
| 269 | 
            -
                     | 
| 363 | 
            +
                    close_sock( dst )
         | 
| 364 | 
            +
                    @dst_infos.delete( dst )
         | 
| 270 365 | 
             
                  else
         | 
| 271 366 | 
             
                    stream = src_info[ :stream ]
         | 
| 272 367 |  | 
| 273 368 | 
             
                    if stream then
         | 
| 274 | 
            -
                       | 
| 275 | 
            -
                       | 
| 369 | 
            +
                      close_sock( stream )
         | 
| 370 | 
            +
                      @stream_infos.delete( stream )
         | 
| 276 371 | 
             
                    end
         | 
| 277 372 | 
             
                  end
         | 
| 278 373 | 
             
                end
         | 
| 279 374 |  | 
| 280 | 
            -
                ##
         | 
| 281 | 
            -
                # close stream
         | 
| 282 | 
            -
                #
         | 
| 283 | 
            -
                def close_stream( stream )
         | 
| 284 | 
            -
                  # puts "debug1 close stream"
         | 
| 285 | 
            -
                  close_sock( stream )
         | 
| 286 | 
            -
                  stream_info = @stream_infos.delete( stream )
         | 
| 287 | 
            -
                  src = stream_info[ :src ]
         | 
| 288 | 
            -
                  close_read_src( src )
         | 
| 289 | 
            -
                  set_src_closing_write( src )
         | 
| 290 | 
            -
                end
         | 
| 291 | 
            -
             | 
| 292 375 | 
             
                ##
         | 
| 293 376 | 
             
                # close tun
         | 
| 294 377 | 
             
                #
         | 
| 295 378 | 
             
                def close_tun( tun )
         | 
| 296 379 | 
             
                  # puts "debug1 close tun"
         | 
| 297 380 | 
             
                  close_sock( tun )
         | 
| 298 | 
            -
                  @tun_info[ : | 
| 299 | 
            -
             | 
| 300 | 
            -
             | 
| 301 | 
            -
                ##
         | 
| 302 | 
            -
                # close write src
         | 
| 303 | 
            -
                #
         | 
| 304 | 
            -
                def close_write_src( src )
         | 
| 305 | 
            -
                  return if src.closed?
         | 
| 306 | 
            -
                  # puts "debug1 close write src"
         | 
| 307 | 
            -
                  src.close_write
         | 
| 308 | 
            -
                  @writes.delete( src )
         | 
| 309 | 
            -
             | 
| 310 | 
            -
                  if src.closed? then
         | 
| 311 | 
            -
                    # puts "debug1 delete src info"
         | 
| 312 | 
            -
                    @roles.delete( src )
         | 
| 313 | 
            -
                    src_info = del_src_info( src )
         | 
| 314 | 
            -
                  else
         | 
| 315 | 
            -
                    src_info = @src_infos[ src ]
         | 
| 316 | 
            -
                  end
         | 
| 317 | 
            -
             | 
| 318 | 
            -
                  src_info[ :closed_write ] = true
         | 
| 319 | 
            -
                  src_info
         | 
| 381 | 
            +
                  @tun_info[ :ctlmsgs ].clear
         | 
| 382 | 
            +
                  @tun_info[ :srcs ].each{ | _, src | close_src( src ) }
         | 
| 320 383 | 
             
                end
         | 
| 321 384 |  | 
| 322 385 | 
             
                ##
         | 
| @@ -336,10 +399,29 @@ module Girl | |
| 336 399 | 
             
                    dst_info = @dst_infos[ dst ]
         | 
| 337 400 | 
             
                  end
         | 
| 338 401 |  | 
| 339 | 
            -
                  dst_info[ :closed_write ] = true
         | 
| 340 402 | 
             
                  dst_info
         | 
| 341 403 | 
             
                end
         | 
| 342 404 |  | 
| 405 | 
            +
                ##
         | 
| 406 | 
            +
                # close write src
         | 
| 407 | 
            +
                #
         | 
| 408 | 
            +
                def close_write_src( src )
         | 
| 409 | 
            +
                  return if src.closed?
         | 
| 410 | 
            +
                  # puts "debug1 close write src"
         | 
| 411 | 
            +
                  src.close_write
         | 
| 412 | 
            +
                  @writes.delete( src )
         | 
| 413 | 
            +
             | 
| 414 | 
            +
                  if src.closed? then
         | 
| 415 | 
            +
                    # puts "debug1 delete src info"
         | 
| 416 | 
            +
                    @roles.delete( src )
         | 
| 417 | 
            +
                    src_info = del_src_info( src )
         | 
| 418 | 
            +
                  else
         | 
| 419 | 
            +
                    src_info = @src_infos[ src ]
         | 
| 420 | 
            +
                  end
         | 
| 421 | 
            +
             | 
| 422 | 
            +
                  src_info
         | 
| 423 | 
            +
                end
         | 
| 424 | 
            +
             | 
| 343 425 | 
             
                ##
         | 
| 344 426 | 
             
                # close write stream
         | 
| 345 427 | 
             
                #
         | 
| @@ -357,7 +439,6 @@ module Girl | |
| 357 439 | 
             
                    stream_info = @stream_infos[ stream ]
         | 
| 358 440 | 
             
                  end
         | 
| 359 441 |  | 
| 360 | 
            -
                  stream_info[ :closed_write ] = true
         | 
| 361 442 | 
             
                  stream_info
         | 
| 362 443 | 
             
                end
         | 
| 363 444 |  | 
| @@ -384,7 +465,7 @@ module Girl | |
| 384 465 | 
             
                def del_src_info( src )
         | 
| 385 466 | 
             
                  src_info = @src_infos.delete( src )
         | 
| 386 467 |  | 
| 387 | 
            -
                  if ( src_info[ :proxy_type ] == :tunnel ) && @tun  | 
| 468 | 
            +
                  if ( src_info[ :proxy_type ] == :tunnel ) && @tun then
         | 
| 388 469 | 
             
                    @tun_info[ :srcs ].delete( src_info[ :id ] )
         | 
| 389 470 | 
             
                  end
         | 
| 390 471 |  | 
| @@ -400,7 +481,6 @@ module Girl | |
| 400 481 | 
             
                      sleep CHECK_EXPIRE_INTERVAL
         | 
| 401 482 |  | 
| 402 483 | 
             
                      @mutex.synchronize do
         | 
| 403 | 
            -
                        trigger = false
         | 
| 404 484 | 
             
                        now = Time.new
         | 
| 405 485 |  | 
| 406 486 | 
             
                        if @tun && !@tun.closed? then
         | 
| @@ -414,8 +494,6 @@ module Girl | |
| 414 494 | 
             
                            data = [ 0, HEARTBEAT ].pack( 'Q>C' )
         | 
| 415 495 | 
             
                            add_ctlmsg( data )
         | 
| 416 496 | 
             
                          end
         | 
| 417 | 
            -
             | 
| 418 | 
            -
                          trigger = true
         | 
| 419 497 | 
             
                        end
         | 
| 420 498 |  | 
| 421 499 | 
             
                        @src_infos.each do | src, src_info |
         | 
| @@ -424,12 +502,9 @@ module Girl | |
| 424 502 |  | 
| 425 503 | 
             
                          if ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
         | 
| 426 504 | 
             
                            puts "p#{ Process.pid } #{ Time.new } expire src #{ src_info[ :destination_domain ] }"
         | 
| 427 | 
            -
                             | 
| 428 | 
            -
                            trigger = true
         | 
| 505 | 
            +
                            add_closing_src( src )
         | 
| 429 506 | 
             
                          end
         | 
| 430 507 | 
             
                        end
         | 
| 431 | 
            -
             | 
| 432 | 
            -
                        next_tick if trigger
         | 
| 433 508 | 
             
                      end
         | 
| 434 509 | 
             
                    end
         | 
| 435 510 | 
             
                  end
         | 
| @@ -444,56 +519,61 @@ module Girl | |
| 444 519 | 
             
                      sleep CHECK_RESUME_INTERVAL
         | 
| 445 520 |  | 
| 446 521 | 
             
                      @mutex.synchronize do
         | 
| 447 | 
            -
                         | 
| 448 | 
            -
             | 
| 449 | 
            -
             | 
| 450 | 
            -
                          dst = src_info[ :dst ]
         | 
| 451 | 
            -
             | 
| 452 | 
            -
                          if dst then
         | 
| 453 | 
            -
                            dst_info = @dst_infos[ dst ]
         | 
| 454 | 
            -
             | 
| 455 | 
            -
                            if dst_info[ :wbuff ].size < RESUME_BELOW then
         | 
| 456 | 
            -
                              puts "p#{ Process.pid } #{ Time.new } dst.wbuff below #{ RESUME_BELOW }, resume src #{ src_info[ :destination_domain ] }"
         | 
| 457 | 
            -
                              resume_src( src )
         | 
| 458 | 
            -
                              trigger = true
         | 
| 459 | 
            -
                            end
         | 
| 522 | 
            +
                        @paused_srcs.each do | src |
         | 
| 523 | 
            +
                          if src.closed? then
         | 
| 524 | 
            +
                            add_resume_src( src )
         | 
| 460 525 | 
             
                          else
         | 
| 461 | 
            -
                             | 
| 462 | 
            -
                             | 
| 463 | 
            -
             | 
| 464 | 
            -
                            if  | 
| 465 | 
            -
                               | 
| 466 | 
            -
             | 
| 467 | 
            -
                               | 
| 526 | 
            +
                            src_info = @src_infos[ src ]
         | 
| 527 | 
            +
                            dst = src_info[ :dst ]
         | 
| 528 | 
            +
             | 
| 529 | 
            +
                            if dst then
         | 
| 530 | 
            +
                              dst_info = @dst_infos[ dst ]
         | 
| 531 | 
            +
             | 
| 532 | 
            +
                              if dst_info[ :wbuff ].size < RESUME_BELOW then
         | 
| 533 | 
            +
                                puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
         | 
| 534 | 
            +
                                add_resume_src( src )
         | 
| 535 | 
            +
                              end
         | 
| 536 | 
            +
                            else
         | 
| 537 | 
            +
                              stream = src_info[ :stream ]
         | 
| 538 | 
            +
                              stream_info = @stream_infos[ stream ]
         | 
| 539 | 
            +
             | 
| 540 | 
            +
                              if stream_info[ :wbuff ].size < RESUME_BELOW then
         | 
| 541 | 
            +
                                puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
         | 
| 542 | 
            +
                                add_resume_src( src )
         | 
| 543 | 
            +
                              end
         | 
| 468 544 | 
             
                            end
         | 
| 469 545 | 
             
                          end
         | 
| 470 546 | 
             
                        end
         | 
| 471 547 |  | 
| 472 | 
            -
                        @ | 
| 473 | 
            -
                           | 
| 474 | 
            -
             | 
| 548 | 
            +
                        @paused_dsts.each do | dst |
         | 
| 549 | 
            +
                          if dst.closed? then
         | 
| 550 | 
            +
                            add_resume_dst( dst )
         | 
| 551 | 
            +
                          else
         | 
| 552 | 
            +
                            dst_info = @dst_infos[ dst ]
         | 
| 553 | 
            +
                            src = dst_info[ :src ]
         | 
| 554 | 
            +
                            src_info = @src_infos[ src ]
         | 
| 475 555 |  | 
| 476 | 
            -
             | 
| 477 | 
            -
             | 
| 478 | 
            -
             | 
| 479 | 
            -
                             | 
| 480 | 
            -
                            trigger = true
         | 
| 556 | 
            +
                            if src_info[ :wbuff ].size < RESUME_BELOW then
         | 
| 557 | 
            +
                              puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
         | 
| 558 | 
            +
                              add_resume_dst( dst )
         | 
| 559 | 
            +
                            end
         | 
| 481 560 | 
             
                          end
         | 
| 482 561 | 
             
                        end
         | 
| 483 562 |  | 
| 484 | 
            -
                        @ | 
| 485 | 
            -
                           | 
| 486 | 
            -
             | 
| 563 | 
            +
                        @paused_streams.each do | stream |
         | 
| 564 | 
            +
                          if stream.closed? then
         | 
| 565 | 
            +
                            add_resume_stream( stream )
         | 
| 566 | 
            +
                          else
         | 
| 567 | 
            +
                            stream_info = @stream_infos[ stream ]
         | 
| 568 | 
            +
                            src = stream_info[ :src ]
         | 
| 569 | 
            +
                            src_info = @src_infos[ src ]
         | 
| 487 570 |  | 
| 488 | 
            -
             | 
| 489 | 
            -
             | 
| 490 | 
            -
             | 
| 491 | 
            -
                             | 
| 492 | 
            -
                            trigger = true
         | 
| 571 | 
            +
                            if src_info[ :wbuff ].size < RESUME_BELOW then
         | 
| 572 | 
            +
                              puts "p#{ Process.pid } #{ Time.new } resume stream #{ stream_info[ :domain ] }"
         | 
| 573 | 
            +
                              add_resume_stream( stream )
         | 
| 574 | 
            +
                            end
         | 
| 493 575 | 
             
                          end
         | 
| 494 576 | 
             
                        end
         | 
| 495 | 
            -
             | 
| 496 | 
            -
                        next_tick if trigger
         | 
| 497 577 | 
             
                      end
         | 
| 498 578 | 
             
                    end
         | 
| 499 579 | 
             
                  end
         | 
| @@ -513,7 +593,7 @@ module Girl | |
| 513 593 |  | 
| 514 594 | 
             
                    Thread.new do
         | 
| 515 595 | 
             
                      SEND_HELLO_COUNT.times do | i |
         | 
| 516 | 
            -
                        if @tun.nil? || @tun.closed? || src.closed? || src_info[ :stream ] then
         | 
| 596 | 
            +
                        if @tun.nil? || @tun.closed? || @tun_info[ :closing ] || src.closed? || src_info[ :stream ] then
         | 
| 517 597 | 
             
                          # puts "debug1 break loop send a new source #{ src_info[ :dst_port ] }"
         | 
| 518 598 | 
             
                          break
         | 
| 519 599 | 
             
                        end
         | 
| @@ -524,7 +604,6 @@ module Girl | |
| 524 604 | 
             
                          end
         | 
| 525 605 |  | 
| 526 606 | 
             
                          add_ctlmsg( data )
         | 
| 527 | 
            -
                          next_tick
         | 
| 528 607 | 
             
                        end
         | 
| 529 608 |  | 
| 530 609 | 
             
                        sleep SEND_HELLO_INTERVAL
         | 
| @@ -549,21 +628,17 @@ module Girl | |
| 549 628 | 
             
                    # connect nonblock 必抛 wait writable
         | 
| 550 629 | 
             
                  rescue Exception => e
         | 
| 551 630 | 
             
                    puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
         | 
| 552 | 
            -
                     | 
| 631 | 
            +
                    dst.close
         | 
| 632 | 
            +
                    add_closing_src( src )
         | 
| 553 633 | 
             
                    return
         | 
| 554 634 | 
             
                  end
         | 
| 555 635 |  | 
| 556 636 | 
             
                  # puts "debug1 a new dst #{ dst.local_address.inspect }"
         | 
| 557 | 
            -
                  local_port = dst.local_address.ip_port
         | 
| 558 637 | 
             
                  dst_info = {
         | 
| 559 | 
            -
                     | 
| 560 | 
            -
                     | 
| 561 | 
            -
                     | 
| 562 | 
            -
                     | 
| 563 | 
            -
                    paused: false,          # 是否已暂停读
         | 
| 564 | 
            -
                    closing: false,         # 准备关闭
         | 
| 565 | 
            -
                    closing_write: false,   # 准备关闭写
         | 
| 566 | 
            -
                    closed_write: false     # 已关闭写
         | 
| 638 | 
            +
                    src: src,            # 对应src
         | 
| 639 | 
            +
                    domain: domain,      # 目的地
         | 
| 640 | 
            +
                    wbuff: '',           # 写前,从src读到的流量
         | 
| 641 | 
            +
                    closing_write: false # 准备关闭写
         | 
| 567 642 | 
             
                  }
         | 
| 568 643 |  | 
| 569 644 | 
             
                  @dst_infos[ dst ] = dst_info
         | 
| @@ -585,6 +660,25 @@ module Girl | |
| 585 660 | 
             
                  end
         | 
| 586 661 | 
             
                end
         | 
| 587 662 |  | 
| 663 | 
            +
                ##
         | 
| 664 | 
            +
                # new a proxy
         | 
| 665 | 
            +
                #
         | 
| 666 | 
            +
                def new_a_proxy( proxy_port )
         | 
| 667 | 
            +
                  proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
         | 
| 668 | 
            +
                  proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
         | 
| 669 | 
            +
             | 
| 670 | 
            +
                  if RUBY_PLATFORM.include?( 'linux' ) then
         | 
| 671 | 
            +
                    proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
         | 
| 672 | 
            +
                    proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
         | 
| 673 | 
            +
                  end
         | 
| 674 | 
            +
             | 
| 675 | 
            +
                  proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
         | 
| 676 | 
            +
                  proxy.listen( 127 )
         | 
| 677 | 
            +
                  puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
         | 
| 678 | 
            +
                  add_read( proxy, :proxy )
         | 
| 679 | 
            +
                  @proxy_local_address = proxy.local_address
         | 
| 680 | 
            +
                end
         | 
| 681 | 
            +
             | 
| 588 682 | 
             
                ##
         | 
| 589 683 | 
             
                # new a stream
         | 
| 590 684 | 
             
                #
         | 
| @@ -597,7 +691,7 @@ module Girl | |
| 597 691 |  | 
| 598 692 | 
             
                  if dst_id == 0 then
         | 
| 599 693 | 
             
                    puts "p#{ Process.pid } #{ Time.new } remote dst already closed"
         | 
| 600 | 
            -
                     | 
| 694 | 
            +
                    add_closing_src( src )
         | 
| 601 695 | 
             
                    return
         | 
| 602 696 | 
             
                  end
         | 
| 603 697 |  | 
| @@ -609,6 +703,7 @@ module Girl | |
| 609 703 | 
             
                  rescue IO::WaitWritable
         | 
| 610 704 | 
             
                  rescue Exception => e
         | 
| 611 705 | 
             
                    puts "p#{ Process.pid } #{ Time.new } connect tcpd #{ e.class }"
         | 
| 706 | 
            +
                    stream.close
         | 
| 612 707 | 
             
                    return
         | 
| 613 708 | 
             
                  end
         | 
| 614 709 |  | 
| @@ -625,10 +720,7 @@ module Girl | |
| 625 720 | 
             
                    src: src,             # 对应src
         | 
| 626 721 | 
             
                    domain: domain,       # 目的地
         | 
| 627 722 | 
             
                    wbuff: data,          # 写前,写往远端streamd
         | 
| 628 | 
            -
                     | 
| 629 | 
            -
                    closing: false,       # 准备关闭
         | 
| 630 | 
            -
                    closing_write: false, # 准备关闭写
         | 
| 631 | 
            -
                    closed_write: false   # 已关闭写
         | 
| 723 | 
            +
                    closing_write: false  # 准备关闭写
         | 
| 632 724 | 
             
                  }
         | 
| 633 725 |  | 
| 634 726 | 
             
                  src_info[ :dst_id ] = dst_id
         | 
| @@ -646,25 +738,6 @@ module Girl | |
| 646 738 | 
             
                  end
         | 
| 647 739 | 
             
                end
         | 
| 648 740 |  | 
| 649 | 
            -
                ##
         | 
| 650 | 
            -
                # new a proxy
         | 
| 651 | 
            -
                #
         | 
| 652 | 
            -
                def new_a_proxy( proxy_port )
         | 
| 653 | 
            -
                  proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
         | 
| 654 | 
            -
                  proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
         | 
| 655 | 
            -
             | 
| 656 | 
            -
                  if RUBY_PLATFORM.include?( 'linux' ) then
         | 
| 657 | 
            -
                    proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
         | 
| 658 | 
            -
                    proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
         | 
| 659 | 
            -
                  end
         | 
| 660 | 
            -
             | 
| 661 | 
            -
                  proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
         | 
| 662 | 
            -
                  proxy.listen( 127 )
         | 
| 663 | 
            -
                  puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
         | 
| 664 | 
            -
                  add_read( proxy, :proxy )
         | 
| 665 | 
            -
                  @proxy_local_address = proxy.local_address
         | 
| 666 | 
            -
                end
         | 
| 667 | 
            -
             | 
| 668 741 | 
             
                ##
         | 
| 669 742 | 
             
                # new a tun
         | 
| 670 743 | 
             
                #
         | 
| @@ -692,7 +765,7 @@ module Girl | |
| 692 765 |  | 
| 693 766 | 
             
                  Thread.new do
         | 
| 694 767 | 
             
                    SEND_HELLO_COUNT.times do | i |
         | 
| 695 | 
            -
                      if @tun.nil? || @tun.closed? || @tun_info[ :tund_addr ] then
         | 
| 768 | 
            +
                      if @tun.nil? || @tun.closed? || @tun_info[ :closing ] || @tun_info[ :tund_addr ] then
         | 
| 696 769 | 
             
                        # puts "debug1 break loop send hello"
         | 
| 697 770 | 
             
                        break
         | 
| 698 771 | 
             
                      end
         | 
| @@ -703,7 +776,6 @@ module Girl | |
| 703 776 | 
             
                        # puts "debug1 #{ data.inspect }"
         | 
| 704 777 |  | 
| 705 778 | 
             
                        add_ctlmsg( data, @proxyd_addr )
         | 
| 706 | 
            -
                        next_tick
         | 
| 707 779 | 
             
                      end
         | 
| 708 780 |  | 
| 709 781 | 
             
                      sleep SEND_HELLO_INTERVAL
         | 
| @@ -723,7 +795,7 @@ module Girl | |
| 723 795 | 
             
                #
         | 
| 724 796 | 
             
                def resolve_domain( src, domain )
         | 
| 725 797 | 
             
                  if @remotes.any? { | remote | ( domain.size >= remote.size ) && ( domain[ ( remote.size * -1 )..-1 ] == remote ) } then
         | 
| 726 | 
            -
                     | 
| 798 | 
            +
                    puts "p#{ Process.pid } #{ Time.new } #{ domain } hit remotes"
         | 
| 727 799 | 
             
                    set_src_proxy_type_tunnel( src )
         | 
| 728 800 | 
             
                    return
         | 
| 729 801 | 
             
                  end
         | 
| @@ -760,41 +832,15 @@ module Girl | |
| 760 832 | 
             
                        unless src.closed? then
         | 
| 761 833 | 
             
                          puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
         | 
| 762 834 | 
             
                          deal_with_destination_ip( src, ip_info )
         | 
| 835 | 
            +
                          next_tick
         | 
| 763 836 | 
             
                        end
         | 
| 764 837 | 
             
                      else
         | 
| 765 | 
            -
                         | 
| 838 | 
            +
                        add_closing_src( src )
         | 
| 766 839 | 
             
                      end
         | 
| 767 | 
            -
             | 
| 768 | 
            -
                      next_tick
         | 
| 769 840 | 
             
                    end
         | 
| 770 841 | 
             
                  end
         | 
| 771 842 | 
             
                end
         | 
| 772 843 |  | 
| 773 | 
            -
                ##
         | 
| 774 | 
            -
                # resume src
         | 
| 775 | 
            -
                #
         | 
| 776 | 
            -
                def resume_src( src )
         | 
| 777 | 
            -
                  src_info = @src_infos[ src ]
         | 
| 778 | 
            -
                  src_info[ :paused ] = false
         | 
| 779 | 
            -
                  add_read( src )
         | 
| 780 | 
            -
                end
         | 
| 781 | 
            -
             | 
| 782 | 
            -
                ##
         | 
| 783 | 
            -
                # set dst closing
         | 
| 784 | 
            -
                #
         | 
| 785 | 
            -
                def set_dst_closing( dst )
         | 
| 786 | 
            -
                  return if dst.closed?
         | 
| 787 | 
            -
                  dst_info = @dst_infos[ dst ]
         | 
| 788 | 
            -
                  dst_info[ :closing ] = true
         | 
| 789 | 
            -
             | 
| 790 | 
            -
                  if dst_info[ :closed_write ] then
         | 
| 791 | 
            -
                    add_read( dst )
         | 
| 792 | 
            -
                  else
         | 
| 793 | 
            -
                    @reads.delete( dst )
         | 
| 794 | 
            -
                    add_write( dst )
         | 
| 795 | 
            -
                  end
         | 
| 796 | 
            -
                end
         | 
| 797 | 
            -
             | 
| 798 844 | 
             
                ##
         | 
| 799 845 | 
             
                # set dst closing write
         | 
| 800 846 | 
             
                #
         | 
| @@ -802,36 +848,20 @@ module Girl | |
| 802 848 | 
             
                  return if dst.closed?
         | 
| 803 849 |  | 
| 804 850 | 
             
                  dst_info = @dst_infos[ dst ]
         | 
| 805 | 
            -
                  return if dst_info[ : | 
| 851 | 
            +
                  return if dst_info[ :closing_write ]
         | 
| 806 852 |  | 
| 807 853 | 
             
                  dst_info[ :closing_write ] = true
         | 
| 808 854 | 
             
                  add_write( dst )
         | 
| 809 855 | 
             
                end
         | 
| 810 856 |  | 
| 811 | 
            -
                ##
         | 
| 812 | 
            -
                # set src is closing
         | 
| 813 | 
            -
                #
         | 
| 814 | 
            -
                def set_src_closing( src )
         | 
| 815 | 
            -
                  return if src.closed?
         | 
| 816 | 
            -
                  src_info = @src_infos[ src ]
         | 
| 817 | 
            -
                  src_info[ :closing ] = true
         | 
| 818 | 
            -
             | 
| 819 | 
            -
                  if src_info[ :closed_write ] then
         | 
| 820 | 
            -
                    add_read( src )
         | 
| 821 | 
            -
                  else
         | 
| 822 | 
            -
                    @reads.delete( src )
         | 
| 823 | 
            -
                    add_write( src )
         | 
| 824 | 
            -
                  end
         | 
| 825 | 
            -
                end
         | 
| 826 | 
            -
             | 
| 827 857 | 
             
                ##
         | 
| 828 858 | 
             
                # set src closing write
         | 
| 829 859 | 
             
                #
         | 
| 830 860 | 
             
                def set_src_closing_write( src )
         | 
| 831 | 
            -
                  return if src.closed?
         | 
| 861 | 
            +
                  return if src.closed? || @closing_srcs.include?( src )
         | 
| 832 862 |  | 
| 833 863 | 
             
                  src_info = @src_infos[ src ]
         | 
| 834 | 
            -
                  return if src_info[ : | 
| 864 | 
            +
                  return if src_info[ :closing_write ]
         | 
| 835 865 |  | 
| 836 866 | 
             
                  src_info[ :closing_write ] = true
         | 
| 837 867 | 
             
                  add_write( src )
         | 
| @@ -841,10 +871,6 @@ module Girl | |
| 841 871 | 
             
                # set src proxy type tunnel
         | 
| 842 872 | 
             
                #
         | 
| 843 873 | 
             
                def set_src_proxy_type_tunnel( src )
         | 
| 844 | 
            -
                  if @tun.nil? || @tun.closed? then
         | 
| 845 | 
            -
                    new_a_tun
         | 
| 846 | 
            -
                  end
         | 
| 847 | 
            -
             | 
| 848 874 | 
             
                  src_info = @src_infos[ src ]
         | 
| 849 875 | 
             
                  src_info[ :proxy_type ] = :tunnel
         | 
| 850 876 | 
             
                  src_id = src_info[ :id ]
         | 
| @@ -864,7 +890,7 @@ module Girl | |
| 864 890 | 
             
                  return if stream.closed?
         | 
| 865 891 |  | 
| 866 892 | 
             
                  stream_info = @stream_infos[ stream ]
         | 
| 867 | 
            -
                  return if stream_info[ : | 
| 893 | 
            +
                  return if stream_info[ :closing_write ]
         | 
| 868 894 |  | 
| 869 895 | 
             
                  stream_info[ :closing_write ] = true
         | 
| 870 896 | 
             
                  add_write( stream )
         | 
| @@ -874,10 +900,11 @@ module Girl | |
| 874 900 | 
             
                # set tun is closing
         | 
| 875 901 | 
             
                #
         | 
| 876 902 | 
             
                def set_tun_closing
         | 
| 877 | 
            -
                  return if @tun.closed?
         | 
| 903 | 
            +
                  return if @tun.closed? || @tun_info[ :closing ]
         | 
| 878 904 | 
             
                  @tun_info[ :closing ] = true
         | 
| 879 905 | 
             
                  @reads.delete( @tun )
         | 
| 880 | 
            -
                   | 
| 906 | 
            +
                  @writes.delete( @tun )
         | 
| 907 | 
            +
                  next_tick
         | 
| 881 908 | 
             
                end
         | 
| 882 909 |  | 
| 883 910 | 
             
                ##
         | 
| @@ -903,7 +930,43 @@ module Girl | |
| 903 930 | 
             
                # read dotr
         | 
| 904 931 | 
             
                #
         | 
| 905 932 | 
             
                def read_dotr( dotr )
         | 
| 906 | 
            -
                  dotr. | 
| 933 | 
            +
                  dotr.read_nonblock( READ_SIZE )
         | 
| 934 | 
            +
             | 
| 935 | 
            +
                  if @tun && !@tun.closed? && @tun_info[ :closing ] then
         | 
| 936 | 
            +
                    close_tun( @tun )
         | 
| 937 | 
            +
                  end
         | 
| 938 | 
            +
             | 
| 939 | 
            +
                  if @closing_srcs.any? then
         | 
| 940 | 
            +
                    @closing_srcs.each{ | src | close_src( src ) }
         | 
| 941 | 
            +
                    @closing_srcs.clear
         | 
| 942 | 
            +
                  end
         | 
| 943 | 
            +
             | 
| 944 | 
            +
                  if @resume_srcs.any? then
         | 
| 945 | 
            +
                    @resume_srcs.each do | src |
         | 
| 946 | 
            +
                      add_read( src )
         | 
| 947 | 
            +
                      @paused_srcs.delete( src )
         | 
| 948 | 
            +
                    end
         | 
| 949 | 
            +
             | 
| 950 | 
            +
                    @resume_srcs.clear
         | 
| 951 | 
            +
                  end
         | 
| 952 | 
            +
             | 
| 953 | 
            +
                  if @resume_dsts.any? then
         | 
| 954 | 
            +
                    @resume_dsts.each do | dst |
         | 
| 955 | 
            +
                      add_read( dst )
         | 
| 956 | 
            +
                      @paused_dsts.delete( dst )
         | 
| 957 | 
            +
                    end
         | 
| 958 | 
            +
             | 
| 959 | 
            +
                    @resume_dsts.clear
         | 
| 960 | 
            +
                  end
         | 
| 961 | 
            +
             | 
| 962 | 
            +
                  if @resume_streams.any? then
         | 
| 963 | 
            +
                    @resume_streams.each do | stream |
         | 
| 964 | 
            +
                      add_read( stream )
         | 
| 965 | 
            +
                      @paused_streams.delete( stream )
         | 
| 966 | 
            +
                    end
         | 
| 967 | 
            +
             | 
| 968 | 
            +
                    @resume_streams.clear
         | 
| 969 | 
            +
                  end
         | 
| 907 970 | 
             
                end
         | 
| 908 971 |  | 
| 909 972 | 
             
                ##
         | 
| @@ -935,19 +998,23 @@ module Girl | |
| 935 998 | 
             
                    created_at: Time.new,    # 创建时间
         | 
| 936 999 | 
             
                    last_recv_at: nil,       # 上一次收到新流量(由dst收到,或者由stream收到)的时间
         | 
| 937 1000 | 
             
                    last_sent_at: nil,       # 上一次发出流量(由dst发出,或者由stream发出)的时间
         | 
| 938 | 
            -
                     | 
| 939 | 
            -
                    closing: false,          # 准备关闭
         | 
| 940 | 
            -
                    closing_write: false,    # 准备关闭写
         | 
| 941 | 
            -
                    closed_write: false      # 已关闭写
         | 
| 1001 | 
            +
                    closing_write: false     # 准备关闭写
         | 
| 942 1002 | 
             
                  }
         | 
| 943 1003 |  | 
| 944 1004 | 
             
                  add_read( src, :src )
         | 
| 1005 | 
            +
             | 
| 1006 | 
            +
                  # 用到tun,是在解析目的地域名得出是国外ip之后。但解析域名是额外的线程,为避免多线程重复建tun,在accept到src时就建。
         | 
| 1007 | 
            +
                  if @tun.nil? || @tun.closed? then
         | 
| 1008 | 
            +
                    new_a_tun
         | 
| 1009 | 
            +
                  end
         | 
| 945 1010 | 
             
                end
         | 
| 946 1011 |  | 
| 947 1012 | 
             
                ##
         | 
| 948 1013 | 
             
                # read tun
         | 
| 949 1014 | 
             
                #
         | 
| 950 1015 | 
             
                def read_tun( tun )
         | 
| 1016 | 
            +
                  return if tun.closed?
         | 
| 1017 | 
            +
             | 
| 951 1018 | 
             
                  begin
         | 
| 952 1019 | 
             
                    data, addrinfo, rflags, *controls = tun.recvmsg_nonblock
         | 
| 953 1020 | 
             
                  rescue IO::WaitReadable, Errno::EINTR
         | 
| @@ -1028,13 +1095,6 @@ module Girl | |
| 1028 1095 | 
             
                  end
         | 
| 1029 1096 |  | 
| 1030 1097 | 
             
                  src_info = @src_infos[ src ]
         | 
| 1031 | 
            -
             | 
| 1032 | 
            -
                  # 处理关闭
         | 
| 1033 | 
            -
                  if src_info[ :closing ] then
         | 
| 1034 | 
            -
                    close_src( src )
         | 
| 1035 | 
            -
                    return
         | 
| 1036 | 
            -
                  end
         | 
| 1037 | 
            -
             | 
| 1038 1098 | 
             
                  proxy_type = src_info[ :proxy_type ]
         | 
| 1039 1099 |  | 
| 1040 1100 | 
             
                  case proxy_type
         | 
| @@ -1045,7 +1105,7 @@ module Girl | |
| 1045 1105 |  | 
| 1046 1106 | 
             
                      unless domain_port then
         | 
| 1047 1107 | 
             
                        puts "p#{ Process.pid } #{ Time.new } CONNECT miss domain"
         | 
| 1048 | 
            -
                         | 
| 1108 | 
            +
                        add_closing_src( src )
         | 
| 1049 1109 | 
             
                        return
         | 
| 1050 1110 | 
             
                      end
         | 
| 1051 1111 | 
             
                    elsif data[ 0 ].unpack( 'C' ).first == 5 then
         | 
| @@ -1063,7 +1123,7 @@ module Girl | |
| 1063 1123 |  | 
| 1064 1124 | 
             
                      unless methods.include?( 0 ) then
         | 
| 1065 1125 | 
             
                        puts "p#{ Process.pid } #{ Time.new } miss method 00"
         | 
| 1066 | 
            -
                         | 
| 1126 | 
            +
                        add_closing_src( src )
         | 
| 1067 1127 | 
             
                        return
         | 
| 1068 1128 | 
             
                      end
         | 
| 1069 1129 |  | 
| @@ -1083,7 +1143,7 @@ module Girl | |
| 1083 1143 |  | 
| 1084 1144 | 
             
                      unless host_line then
         | 
| 1085 1145 | 
             
                        # puts "debug1 not found host line"
         | 
| 1086 | 
            -
                         | 
| 1146 | 
            +
                        add_closing_src( src )
         | 
| 1087 1147 | 
             
                        return
         | 
| 1088 1148 | 
             
                      end
         | 
| 1089 1149 |  | 
| @@ -1095,7 +1155,7 @@ module Girl | |
| 1095 1155 |  | 
| 1096 1156 | 
             
                        unless domain_port then
         | 
| 1097 1157 | 
             
                          puts "p#{ Process.pid } #{ Time.new } Host line miss domain"
         | 
| 1098 | 
            -
                           | 
| 1158 | 
            +
                          add_closing_src( src )
         | 
| 1099 1159 | 
             
                          return
         | 
| 1100 1160 | 
             
                        end
         | 
| 1101 1161 | 
             
                      end
         | 
| @@ -1160,26 +1220,13 @@ module Girl | |
| 1160 1220 | 
             
                          data, _ = sub_http_request( data )
         | 
| 1161 1221 | 
             
                        end
         | 
| 1162 1222 |  | 
| 1163 | 
            -
                        stream_info = @stream_infos[ stream ]
         | 
| 1164 1223 | 
             
                        data = @custom.encode( data )
         | 
| 1165 1224 | 
             
                        # puts "debug2 add stream.wbuff encoded #{ data.bytesize }"
         | 
| 1166 | 
            -
                         | 
| 1167 | 
            -
                        add_write( stream )
         | 
| 1168 | 
            -
             | 
| 1169 | 
            -
                        if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 1170 | 
            -
                          puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :destination_domain ] }"
         | 
| 1171 | 
            -
                          src_info[ :paused ] = true
         | 
| 1172 | 
            -
                          @reads.delete( src )
         | 
| 1173 | 
            -
                        end
         | 
| 1225 | 
            +
                        add_stream_wbuff( stream, data )
         | 
| 1174 1226 | 
             
                      end
         | 
| 1175 1227 | 
             
                    else
         | 
| 1176 1228 | 
             
                      # puts "debug1 stream not ready, save data to src.rbuff"
         | 
| 1177 | 
            -
                       | 
| 1178 | 
            -
             | 
| 1179 | 
            -
                      if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 1180 | 
            -
                        # puts "debug1 tunnel src.rbuff full"
         | 
| 1181 | 
            -
                        set_src_closing( src )
         | 
| 1182 | 
            -
                      end
         | 
| 1229 | 
            +
                      add_src_rbuff( src, data )
         | 
| 1183 1230 | 
             
                    end
         | 
| 1184 1231 | 
             
                  when :direct then
         | 
| 1185 1232 | 
             
                    dst = src_info[ :dst ]
         | 
| @@ -1190,25 +1237,12 @@ module Girl | |
| 1190 1237 | 
             
                          data, _ = sub_http_request( data )
         | 
| 1191 1238 | 
             
                        end
         | 
| 1192 1239 |  | 
| 1193 | 
            -
                        dst_info = @dst_infos[ dst ]
         | 
| 1194 1240 | 
             
                        # puts "debug2 add dst.wbuff #{ data.bytesize }"
         | 
| 1195 | 
            -
                         | 
| 1196 | 
            -
                        add_write( dst )
         | 
| 1197 | 
            -
             | 
| 1198 | 
            -
                        if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 1199 | 
            -
                          puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :destination_domain ] }"
         | 
| 1200 | 
            -
                          src_info[ :paused ] = true
         | 
| 1201 | 
            -
                          @reads.delete( src )
         | 
| 1202 | 
            -
                        end
         | 
| 1241 | 
            +
                        add_dst_wbuff( dst, data )
         | 
| 1203 1242 | 
             
                      end
         | 
| 1204 1243 | 
             
                    else
         | 
| 1205 1244 | 
             
                      # puts "debug1 dst not ready, save data to src.rbuff"
         | 
| 1206 | 
            -
                       | 
| 1207 | 
            -
             | 
| 1208 | 
            -
                      if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
         | 
| 1209 | 
            -
                        # puts "debug1 direct src.rbuff full"
         | 
| 1210 | 
            -
                        set_src_closing( src )
         | 
| 1211 | 
            -
                      end
         | 
| 1245 | 
            +
                      add_src_rbuff( src, data )
         | 
| 1212 1246 | 
             
                    end
         | 
| 1213 1247 | 
             
                  end
         | 
| 1214 1248 | 
             
                end
         | 
| @@ -1233,13 +1267,6 @@ module Girl | |
| 1233 1267 | 
             
                  end
         | 
| 1234 1268 |  | 
| 1235 1269 | 
             
                  dst_info = @dst_infos[ dst ]
         | 
| 1236 | 
            -
             | 
| 1237 | 
            -
                  # 处理关闭
         | 
| 1238 | 
            -
                  if dst_info[ :closing ] then
         | 
| 1239 | 
            -
                    close_dst( dst )
         | 
| 1240 | 
            -
                    return
         | 
| 1241 | 
            -
                  end
         | 
| 1242 | 
            -
             | 
| 1243 1270 | 
             
                  src = dst_info[ :src ]
         | 
| 1244 1271 | 
             
                  add_src_wbuff( src, data )
         | 
| 1245 1272 | 
             
                end
         | 
| @@ -1274,13 +1301,7 @@ module Girl | |
| 1274 1301 | 
             
                # write tun
         | 
| 1275 1302 | 
             
                #
         | 
| 1276 1303 | 
             
                def write_tun( tun )
         | 
| 1277 | 
            -
                   | 
| 1278 | 
            -
                  if @tun_info[ :closing ] then
         | 
| 1279 | 
            -
                    close_tun( tun )
         | 
| 1280 | 
            -
                    return
         | 
| 1281 | 
            -
                  end
         | 
| 1282 | 
            -
             | 
| 1283 | 
            -
                  now = Time.new
         | 
| 1304 | 
            +
                  return if tun.closed?
         | 
| 1284 1305 |  | 
| 1285 1306 | 
             
                  # 发ctlmsg
         | 
| 1286 1307 | 
             
                  while @tun_info[ :ctlmsgs ].any? do
         | 
| @@ -1292,8 +1313,8 @@ module Girl | |
| 1292 1313 | 
             
                      puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
         | 
| 1293 1314 | 
             
                      return
         | 
| 1294 1315 | 
             
                    rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
         | 
| 1295 | 
            -
                      puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class },  | 
| 1296 | 
            -
                       | 
| 1316 | 
            +
                      puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, set tun closing"
         | 
| 1317 | 
            +
                      set_tun_closing
         | 
| 1297 1318 | 
             
                      return
         | 
| 1298 1319 | 
             
                    end
         | 
| 1299 1320 |  | 
| @@ -1310,14 +1331,6 @@ module Girl | |
| 1310 1331 | 
             
                  return if src.closed?
         | 
| 1311 1332 | 
             
                  src_info = @src_infos[ src ]
         | 
| 1312 1333 | 
             
                  dst = src_info[ :dst ]
         | 
| 1313 | 
            -
             | 
| 1314 | 
            -
                  # 处理关闭
         | 
| 1315 | 
            -
                  if src_info[ :closing ] then
         | 
| 1316 | 
            -
                    close_src( src )
         | 
| 1317 | 
            -
                    return
         | 
| 1318 | 
            -
                  end
         | 
| 1319 | 
            -
             | 
| 1320 | 
            -
                  # 处理wbuff
         | 
| 1321 1334 | 
             
                  data = src_info[ :wbuff ]
         | 
| 1322 1335 |  | 
| 1323 1336 | 
             
                  # 写前为空,处理关闭写
         | 
| @@ -1363,13 +1376,6 @@ module Girl | |
| 1363 1376 | 
             
                  return if dst.closed?
         | 
| 1364 1377 | 
             
                  dst_info = @dst_infos[ dst ]
         | 
| 1365 1378 | 
             
                  src = dst_info[ :src ]
         | 
| 1366 | 
            -
             | 
| 1367 | 
            -
                  # 处理关闭
         | 
| 1368 | 
            -
                  if dst_info[ :closing ] then
         | 
| 1369 | 
            -
                    close_dst( dst )
         | 
| 1370 | 
            -
                    return
         | 
| 1371 | 
            -
                  end
         | 
| 1372 | 
            -
             | 
| 1373 1379 | 
             
                  data = dst_info[ :wbuff ]
         | 
| 1374 1380 |  | 
| 1375 1381 | 
             
                  # 写前为空,处理关闭写
         | 
| @@ -1412,13 +1418,6 @@ module Girl | |
| 1412 1418 | 
             
                  return if stream.closed?
         | 
| 1413 1419 | 
             
                  stream_info = @stream_infos[ stream ]
         | 
| 1414 1420 | 
             
                  src = stream_info[ :src ]
         | 
| 1415 | 
            -
             | 
| 1416 | 
            -
                  # 处理关闭
         | 
| 1417 | 
            -
                  if stream_info[ :closing ] then
         | 
| 1418 | 
            -
                    close_stream( stream )
         | 
| 1419 | 
            -
                    return
         | 
| 1420 | 
            -
                  end
         | 
| 1421 | 
            -
             | 
| 1422 1421 | 
             
                  data = stream_info[ :wbuff ]
         | 
| 1423 1422 |  | 
| 1424 1423 | 
             
                  # 写前为空,处理关闭写
         |