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  }