github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/cmd/geph-client/methods.go (about) 1 package main 2 3 import ( 4 "errors" 5 "net" 6 "sync" 7 "time" 8 9 "github.com/ethereum/go-ethereum/rlp" 10 "github.com/geph-official/geph2/libs/bdclient" 11 "github.com/geph-official/geph2/libs/warpfront" 12 log "github.com/sirupsen/logrus" 13 ) 14 15 func connThroughBridge(bridgeConn net.Conn) (exitConn net.Conn, err error) { 16 bridgeConn.SetDeadline(time.Now().Add(time.Second * 30)) 17 rlp.Encode(bridgeConn, "conn/feedback") 18 rlp.Encode(bridgeConn, exitName) 19 _, err = bridgeConn.Read(make([]byte, 1)) 20 if err != nil { 21 bridgeConn.Close() 22 //log.Debugln("conn in", bi.Host, "failed!", err) 23 return 24 } 25 bridgeConn.SetDeadline(time.Time{}) 26 exitConn = bridgeConn 27 return 28 } 29 30 func getSingleTCP(bridges []bdclient.BridgeInfo) (conn net.Conn, err error) { 31 bridgeRace := make(chan net.Conn) 32 bridgeDeadWait := new(sync.WaitGroup) 33 bridgeDeadWait.Add(len(bridges)) 34 go func() { 35 bridgeDeadWait.Wait() 36 close(bridgeRace) 37 }() 38 syncer := make(chan bool) 39 go func() { 40 time.Sleep(time.Second * 3) 41 close(syncer) 42 }() 43 for _, bi := range bridges { 44 bi := bi 45 go func() { 46 defer bridgeDeadWait.Done() 47 bridgeConn, err := dialBridge(bi.Host, bi.Cookie) 48 if err != nil { 49 log.Debugln("dialing to", bi.Host, "failed!", err) 50 return 51 } 52 <-syncer 53 realConn, err := connThroughBridge(bridgeConn) 54 if err != nil { 55 bridgeConn.Close() 56 log.Debugln("conn in", bi.Host, "failed!", err) 57 return 58 } 59 select { 60 case bridgeRace <- realConn: 61 default: 62 bridgeConn.Close() 63 } 64 }() 65 } 66 zz, ok := <-bridgeRace 67 if !ok { 68 err = errors.New("singlepath timed out") 69 return 70 } 71 conn = zz 72 return 73 } 74 75 func getWarpfront(host2front map[string]string) (conn net.Conn, err error) { 76 for host, front := range host2front { 77 log.Println("> WF", host, front) 78 rc, e := warpfront.Connect(cleanHTTPClient, front, host) 79 if e != nil { 80 err = e 81 log.Debugf("WF failed 1/2 %v", e) 82 continue 83 } 84 c, e := connThroughBridge(rc) 85 if e != nil { 86 log.Debugf("WF failed 2/2 %v", e) 87 err = e 88 continue 89 } 90 conn = c 91 return 92 } 93 return 94 }