@@ -435,106 +435,118 @@ private bool HandleSocks5(Socket socket, IChannelDirectTcpip channel, TimeSpan t
435
435
return false ;
436
436
}
437
437
438
- IPAddress ipAddress ;
439
- byte [ ] addressBuffer ;
438
+ var host = GetSocks5Host ( addressType , socket , timeout ) ;
439
+ if ( host == null )
440
+ {
441
+ // SOCKS client closed connection
442
+ return false ;
443
+ }
444
+
445
+ var portBuffer = new byte [ 2 ] ;
446
+ if ( SocketAbstraction . Read ( socket , portBuffer , 0 , portBuffer . Length , timeout ) == 0 )
447
+ {
448
+ // SOCKS client closed connection
449
+ return false ;
450
+ }
451
+
452
+ var port = ( uint ) ( portBuffer [ 0 ] * 256 + portBuffer [ 1 ] ) ;
453
+
454
+ RaiseRequestReceived ( host , port ) ;
455
+
456
+ channel . Open ( host , port , this , socket ) ;
457
+
458
+ var socksReply = CreateSocks5Reply ( channel . IsOpen ) ;
459
+
460
+ SocketAbstraction . Send ( socket , socksReply , 0 , socksReply . Length ) ;
461
+
462
+ return true ;
463
+ }
464
+
465
+ private static string GetSocks5Host ( int addressType , Socket socket , TimeSpan timeout )
466
+ {
440
467
switch ( addressType )
441
468
{
442
- case 0x01 :
469
+ case 0x01 : // IPv4
443
470
{
444
- addressBuffer = new byte [ 4 ] ;
471
+ var addressBuffer = new byte [ 4 ] ;
445
472
if ( SocketAbstraction . Read ( socket , addressBuffer , 0 , 4 , timeout ) == 0 )
446
473
{
447
474
// SOCKS client closed connection
448
- return false ;
475
+ return null ;
449
476
}
450
477
451
- ipAddress = new IPAddress ( addressBuffer ) ;
478
+ var ipv4 = new IPAddress ( addressBuffer ) ;
479
+ return ipv4 . ToString ( ) ;
452
480
}
453
- break ;
454
- case 0x03 :
481
+ case 0x03 : // Domain name
455
482
{
456
483
var length = SocketAbstraction . ReadByte ( socket , timeout ) ;
457
484
if ( length == - 1 )
458
485
{
459
486
// SOCKS client closed connection
460
- return false ;
487
+ return null ;
461
488
}
462
- addressBuffer = new byte [ length ] ;
489
+ var addressBuffer = new byte [ length ] ;
463
490
if ( SocketAbstraction . Read ( socket , addressBuffer , 0 , addressBuffer . Length , timeout ) == 0 )
464
491
{
465
492
// SOCKS client closed connection
466
- return false ;
493
+ return null ;
467
494
}
468
495
469
- ipAddress = IPAddress . Parse ( SshData . Ascii . GetString ( addressBuffer , 0 , addressBuffer . Length ) ) ;
470
-
471
- //var hostName = new Common.ASCIIEncoding().GetString(addressBuffer);
472
-
473
- //ipAddress = Dns.GetHostEntry(hostName).AddressList[0];
496
+ var hostName = SshData . Ascii . GetString ( addressBuffer ) ;
497
+ return hostName ;
474
498
}
475
- break ;
476
- case 0x04 :
499
+ case 0x04 : // IPv6
477
500
{
478
- addressBuffer = new byte [ 16 ] ;
501
+ var addressBuffer = new byte [ 16 ] ;
479
502
if ( SocketAbstraction . Read ( socket , addressBuffer , 0 , 16 , timeout ) == 0 )
480
503
{
481
504
// SOCKS client closed connection
482
- return false ;
505
+ return null ;
483
506
}
484
507
485
- ipAddress = new IPAddress ( addressBuffer ) ;
508
+ var ipv6 = new IPAddress ( addressBuffer ) ;
509
+ return ipv6 . ToString ( ) ;
486
510
}
487
- break ;
488
511
default :
489
512
throw new ProxyException ( string . Format ( "SOCKS5: Address type '{0}' is not supported." , addressType ) ) ;
490
513
}
514
+ }
491
515
492
- var portBuffer = new byte [ 2 ] ;
493
- if ( SocketAbstraction . Read ( socket , portBuffer , 0 , portBuffer . Length , timeout ) == 0 )
494
- {
495
- // SOCKS client closed connection
496
- return false ;
497
- }
498
-
499
- var port = ( uint ) ( portBuffer [ 0 ] * 256 + portBuffer [ 1 ] ) ;
500
- var host = ipAddress . ToString ( ) ;
501
-
502
- RaiseRequestReceived ( host , port ) ;
503
-
504
- channel . Open ( host , port , this , socket ) ;
505
-
506
- SocketAbstraction . SendByte ( socket , 0x05 ) ;
507
-
508
- if ( channel . IsOpen )
509
- {
510
- SocketAbstraction . SendByte ( socket , 0x00 ) ;
516
+ private static byte [ ] CreateSocks5Reply ( bool channelOpen )
517
+ {
518
+ var socksReply = new byte [
519
+ // SOCKS version
520
+ 1 +
521
+ // Reply field
522
+ 1 +
523
+ // Reserved; fixed: 0x00
524
+ 1 +
525
+ // Address type; fixed: 0x01
526
+ 1 +
527
+ // IPv4 server bound address; fixed: {0x00, 0x00, 0x00, 0x00}
528
+ 4 +
529
+ // server bound port; fixed: {0x00, 0x00}
530
+ 2 ] ;
531
+
532
+ socksReply [ 0 ] = 0x05 ;
533
+
534
+ if ( channelOpen )
535
+ {
536
+ socksReply [ 1 ] = 0x00 ; // succeeded
511
537
}
512
538
else
513
539
{
514
- SocketAbstraction . SendByte ( socket , 0x01 ) ;
540
+ socksReply [ 1 ] = 0x01 ; // general SOCKS server failure
515
541
}
516
542
517
543
// reserved
518
- SocketAbstraction . SendByte ( socket , 0x00 ) ;
519
-
520
- if ( ipAddress . AddressFamily == AddressFamily . InterNetwork )
521
- {
522
- SocketAbstraction . SendByte ( socket , 0x01 ) ;
523
- }
524
- else if ( ipAddress . AddressFamily == AddressFamily . InterNetworkV6 )
525
- {
526
- SocketAbstraction . SendByte ( socket , 0x04 ) ;
527
- }
528
- else
529
- {
530
- throw new NotSupportedException ( "Not supported address family." ) ;
531
- }
544
+ socksReply [ 2 ] = 0x00 ;
532
545
533
- var addressBytes = ipAddress . GetAddressBytes ( ) ;
534
- SocketAbstraction . Send ( socket , addressBytes , 0 , addressBytes . Length ) ;
535
- SocketAbstraction . Send ( socket , portBuffer , 0 , portBuffer . Length ) ;
546
+ // IPv4 address type
547
+ socksReply [ 3 ] = 0x01 ;
536
548
537
- return true ;
549
+ return socksReply ;
538
550
}
539
551
540
552
/// <summary>
0 commit comments