Beispiel #1
0
func (tt *TunnelTest) addClient(ident string, cfg *tunnel.ClientConfig) error {
	if _, ok := tt.Clients[ident]; ok {
		return fmt.Errorf("tunnel %q is already being served", ident)
	}

	c, err := tunnel.NewClient(cfg)
	if err != nil {
		return err
	}

	done := make(chan struct{})

	tt.Server.OnConnect(ident, func() error {
		close(done)
		return nil
	})

	go c.Start()
	<-c.StartNotify()

	select {
	case <-time.After(10 * time.Second):
		return errors.New("timed out after 10s waiting on client to establish control conn")
	case <-done:
	}

	tt.Clients[ident] = c
	return nil
}
Beispiel #2
0
// NewClient gives new, unstarted tunnel client for the given options.
func NewClient(opts *ClientOptions) (*Client, error) {
	optsCopy := *opts

	if optsCopy.Log == nil {
		optsCopy.Log = logging.NewCustom("tunnelclient", optsCopy.Debug)
	}

	// TODO(rjeczalik): fix production to use WebSocket by default
	//
	// BUG(rjeczalik): starting a kite that is not registered to
	// kontrol will prevent the kite from updating it's keypair,
	// when it changes in kontrol - the only fix is to restart
	// kite process.
	k := kite.New("tunnelclient", "0.0.1")
	k.Config = optsCopy.Kite.Config.Copy()
	k.Config.Transport = config.WebSocket

	c := &Client{
		kite:          k,
		opts:          &optsCopy,
		tunnelKiteURL: optsCopy.tunnelKiteURL(),
		stateChanges:  make(chan *tunnel.ClientStateChange, 128),
		regserv:       make(chan map[string]*Tunnel, 1),
		services:      make(Services),
		routes:        make(map[int]string),
	}

	// If VirtualHost was configured, try to connect to it first.
	if c.opts.LastVirtualHost != "" {
		c.tunnelKiteURL = fmt.Sprintf("http://%s/kite", c.opts.LastVirtualHost)
		c.connected = &RegisterResult{
			VirtualHost: c.opts.LastVirtualHost,
			ServerAddr:  c.opts.LastVirtualHost,
		}
	}

	c.kite.ClientFunc = httputil.ClientFunc(opts.Debug)

	cfg := &tunnel.ClientConfig{
		FetchIdentifier: c.fetchIdent,
		FetchServerAddr: c.fetchServerAddr,
		FetchLocalAddr:  c.fetchLocalAddr,
		LocalAddr:       c.opts.LocalAddr,
		Debug:           c.opts.Debug,
		Log:             c.opts.Log.New("transport"),
		StateChanges:    c.stateChanges,
	}

	client, err := tunnel.NewClient(cfg)
	if err != nil {
		return nil, err
	}

	c.client = client

	return c, nil
}
Beispiel #3
0
func TestNoHost(t *testing.T) {
	tt, err := tunneltest.Serve(singleHTTP(handlerEchoHTTP))
	if err != nil {
		t.Fatal(err)
	}
	defer tt.Close()

	noBackoff := backoff.NewConstantBackOff(time.Duration(-1))

	unknown, err := tunnel.NewClient(&tunnel.ClientConfig{
		Identifier: "unknown",
		ServerAddr: tt.ServerAddr().String(),
		Backoff:    noBackoff,
		Debug:      testing.Verbose(),
	})
	if err != nil {
		t.Fatalf("client error: %s", err)
	}
	unknown.Start()
	defer unknown.Close()

	if err := tt.ServerStateRecorder.WaitTransition(
		tunnel.ClientUnknown,
		tunnel.ClientClosed,
	); err != nil {
		t.Fatal(err)
	}

	unknown.Start()
	if err := tt.ServerStateRecorder.WaitTransition(
		tunnel.ClientClosed,
		tunnel.ClientClosed,
	); err != nil {
		t.Fatal(err)
	}
}