1
1
package websocket
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
"crypto/ecdsa"
6
7
"crypto/elliptic"
@@ -15,10 +16,12 @@ import (
15
16
"math/big"
16
17
"net"
17
18
"net/http"
19
+ "net/url"
18
20
"strings"
19
21
"testing"
20
22
"time"
21
23
24
+ gws "github.com/gorilla/websocket"
22
25
"github.com/libp2p/go-libp2p/core/crypto"
23
26
"github.com/libp2p/go-libp2p/core/network"
24
27
"github.com/libp2p/go-libp2p/core/peer"
@@ -548,3 +551,75 @@ func TestResolveMultiaddr(t *testing.T) {
548
551
})
549
552
}
550
553
}
554
+
555
+ func TestSocksProxy (t * testing.T ) {
556
+ testCases := []string {
557
+ "/ip4/1.2.3.4/tcp/1/ws" , // No TLS
558
+ "/ip4/1.2.3.4/tcp/1/tls/ws" , // TLS no SNI
559
+ "/ip4/1.2.3.4/tcp/1/tls/sni/example.com/ws" , // TLS with an SNI
560
+ }
561
+
562
+ for _ , tc := range testCases {
563
+ t .Run (tc , func (t * testing.T ) {
564
+ proxyServer , err := net .Listen ("tcp" , "127.0.0.1:0" )
565
+ require .NoError (t , err )
566
+ proxyServerErr := make (chan error , 1 )
567
+
568
+ go func () {
569
+ defer proxyServer .Close ()
570
+ c , err := proxyServer .Accept ()
571
+ if err != nil {
572
+ proxyServerErr <- err
573
+ return
574
+ }
575
+ defer c .Close ()
576
+
577
+ req := [32 ]byte {}
578
+ _ , err = io .ReadFull (c , req [:3 ])
579
+ if err != nil {
580
+ proxyServerErr <- err
581
+ return
582
+ }
583
+
584
+ // Handshake a SOCKS5 client: https://www.rfc-editor.org/rfc/rfc1928.html#section-3
585
+ if ! bytes .Equal ([]byte {0x05 , 0x01 , 0x00 }, req [:3 ]) {
586
+ t .Log ("expected SOCKS5 connect request" )
587
+ proxyServerErr <- err
588
+ return
589
+ }
590
+ _ , err = c .Write ([]byte {0x05 , 0x00 })
591
+ if err != nil {
592
+ proxyServerErr <- err
593
+ return
594
+ }
595
+
596
+ proxyServerErr <- nil
597
+ }()
598
+
599
+ orig := gws .DefaultDialer .Proxy
600
+ defer func () { gws .DefaultDialer .Proxy = orig }()
601
+
602
+ proxyUrl , err := url .Parse ("socks5://" + proxyServer .Addr ().String ())
603
+ require .NoError (t , err )
604
+ gws .DefaultDialer .Proxy = http .ProxyURL (proxyUrl )
605
+
606
+ tlsConfig := & tls.Config {InsecureSkipVerify : true } // Our test server doesn't have a cert signed by a CA
607
+ _ , u := newSecureUpgrader (t )
608
+ tpt , err := New (u , & network.NullResourceManager {}, nil , WithTLSClientConfig (tlsConfig ))
609
+ require .NoError (t , err )
610
+
611
+ // This can be any wss address. We aren't actually going to dial it.
612
+ maToDial := ma .StringCast (tc )
613
+ _ , err = tpt .Dial (context .Background (), maToDial , "" )
614
+ require .ErrorContains (t , err , "failed to read connect reply from SOCKS5 proxy" , "This should error as we don't have a real socks server" )
615
+
616
+ select {
617
+ case <- time .After (1 * time .Second ):
618
+ case err := <- proxyServerErr :
619
+ if err != nil {
620
+ t .Fatal (err )
621
+ }
622
+ }
623
+ })
624
+ }
625
+ }
0 commit comments