Пример #1
0
// returns the two endpoints of a TCP connection over lo0
func getTCPConnectionPair() (net.Conn, net.Conn, error) {
	lst, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, nil, err
	}

	// We run the Accept in the background since it's blocking, and we use
	// the channel to make the race thingies happy about writing vs reading
	// conn0 and err0.
	var conn0 net.Conn
	var err0 error
	done := make(chan struct{})
	go func() {
		conn0, err0 = lst.Accept()
		close(done)
	}()

	// Dial the connection
	conn1, err := net.Dial("tcp", lst.Addr().String())
	if err != nil {
		return nil, nil, err
	}

	// Check any error from accept
	<-done
	if err0 != nil {
		return nil, nil, err0
	}

	// Set the buffer sizes etc as usual
	dialer.SetTCPOptions(conn0)
	dialer.SetTCPOptions(conn1)

	return conn0, conn1, nil
}
Пример #2
0
func (d *tcpDialer) Dial(id protocol.DeviceID, uri *url.URL) (internalConn, error) {
	uri = fixupPort(uri)

	conn, err := dialer.DialTimeout(uri.Scheme, uri.Host, 10*time.Second)
	if err != nil {
		l.Debugln(err)
		return internalConn{}, err
	}

	err = dialer.SetTCPOptions(conn)
	if err != nil {
		l.Infoln(err)
	}

	err = dialer.SetTrafficClass(conn, d.cfg.Options().TrafficClass)
	if err != nil {
		l.Debugf("failed to set traffic class: %s", err)
	}

	tc := tls.Client(conn, d.tlsCfg)
	err = tlsTimedHandshake(tc)
	if err != nil {
		tc.Close()
		return internalConn{}, err
	}

	return internalConn{tc, connTypeTCPClient, tcpPriority}, nil
}
Пример #3
0
func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConnection, error) {
	inv, err := client.GetInvitationFromRelay(uri, id, d.tlsCfg.Certificates, 10*time.Second)
	if err != nil {
		return IntermediateConnection{}, err
	}

	conn, err := client.JoinSession(inv)
	if err != nil {
		return IntermediateConnection{}, err
	}

	err = dialer.SetTCPOptions(conn)
	if err != nil {
		conn.Close()
		return IntermediateConnection{}, err
	}

	var tc *tls.Conn
	if inv.ServerSocket {
		tc = tls.Server(conn, d.tlsCfg)
	} else {
		tc = tls.Client(conn, d.tlsCfg)
	}

	err = tc.Handshake()
	if err != nil {
		tc.Close()
		return IntermediateConnection{}, err
	}

	return IntermediateConnection{tc, "Relay (Client)", relayPriority}, nil
}
Пример #4
0
func makeTCPListener(network string) ListenerFactory {
	return func(uri *url.URL, tlsCfg *tls.Config, conns chan<- model.IntermediateConnection) {
		tcaddr, err := net.ResolveTCPAddr(network, uri.Host)
		if err != nil {
			l.Fatalln("listen (BEP/tcp):", err)
			return
		}
		listener, err := net.ListenTCP(network, tcaddr)
		if err != nil {
			l.Fatalln("listen (BEP/tcp):", err)
			return
		}

		for {
			conn, err := listener.Accept()
			if err != nil {
				l.Warnln("Accepting connection (BEP/tcp):", err)
				continue
			}

			l.Debugln("connect from", conn.RemoteAddr())

			err = dialer.SetTCPOptions(conn.(*net.TCPConn))
			if err != nil {
				l.Infoln(err)
			}

			tc := tls.Server(conn, tlsCfg)
			err = tc.Handshake()
			if err != nil {
				l.Infoln("TLS handshake (BEP/tcp):", err)
				tc.Close()
				continue
			}

			conns <- model.IntermediateConnection{
				Conn: tc,
				Type: model.ConnectionTypeDirectAccept,
			}
		}
	}
}
Пример #5
0
func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (internalConn, error) {
	inv, err := client.GetInvitationFromRelay(uri, id, d.tlsCfg.Certificates, 10*time.Second)
	if err != nil {
		return internalConn{}, err
	}

	conn, err := client.JoinSession(inv)
	if err != nil {
		return internalConn{}, err
	}

	err = dialer.SetTCPOptions(conn)
	if err != nil {
		conn.Close()
		return internalConn{}, err
	}

	err = dialer.SetTrafficClass(conn, d.cfg.Options().TrafficClass)
	if err != nil {
		l.Debugf("failed to set traffic class: %s", err)
	}

	var tc *tls.Conn
	if inv.ServerSocket {
		tc = tls.Server(conn, d.tlsCfg)
	} else {
		tc = tls.Client(conn, d.tlsCfg)
	}

	err = tlsTimedHandshake(tc)
	if err != nil {
		tc.Close()
		return internalConn{}, err
	}

	return internalConn{tc, connTypeRelayClient, relayPriority}, nil
}
Пример #6
0
func (t *relayListener) Serve() {
	t.mut.Lock()
	t.err = nil
	t.mut.Unlock()

	clnt, err := client.NewClient(t.uri, t.tlsCfg.Certificates, nil, 10*time.Second)
	if err != nil {
		t.mut.Lock()
		t.err = err
		t.mut.Unlock()
		l.Warnln("listen (BEP/relay):", err)
		return
	}

	go clnt.Serve()

	t.mut.Lock()
	t.client = clnt
	t.mut.Unlock()

	oldURI := clnt.URI()

	for {
		select {
		case inv, ok := <-t.client.Invitations():
			if !ok {
				return
			}

			conn, err := client.JoinSession(inv)
			if err != nil {
				l.Warnln("Joining relay session (BEP/relay):", err)
				continue
			}

			err = dialer.SetTCPOptions(conn.(*net.TCPConn))
			if err != nil {
				l.Infoln(err)
			}

			var tc *tls.Conn
			if inv.ServerSocket {
				tc = tls.Server(conn, t.tlsCfg)
			} else {
				tc = tls.Client(conn, t.tlsCfg)
			}

			err = tc.Handshake()
			if err != nil {
				tc.Close()
				l.Infoln("TLS handshake (BEP/relay):", err)
				continue
			}

			t.conns <- IntermediateConnection{tc, "Relay (Server)", relayPriority}

		// Poor mans notifier that informs the connection service that the
		// relay URI has changed. This can only happen when we connect to a
		// relay via dynamic+http(s) pool, which upon a relay failing/dropping
		// us, would pick a different one.
		case <-time.After(10 * time.Second):
			currentURI := clnt.URI()
			if currentURI != oldURI {
				oldURI = currentURI
				t.notifyAddressesChanged(t)
			}
		}
	}
}
Пример #7
0
func (t *tcpListener) Serve() {
	t.mut.Lock()
	t.err = nil
	t.mut.Unlock()

	tcaddr, err := net.ResolveTCPAddr(t.uri.Scheme, t.uri.Host)
	if err != nil {
		t.mut.Lock()
		t.err = err
		t.mut.Unlock()
		l.Infoln("listen (BEP/tcp):", err)
		return
	}

	listener, err := net.ListenTCP(t.uri.Scheme, tcaddr)
	if err != nil {
		t.mut.Lock()
		t.err = err
		t.mut.Unlock()
		l.Infoln("listen (BEP/tcp):", err)
		return
	}
	defer listener.Close()

	l.Infof("TCP listener (%v) starting", listener.Addr())
	defer l.Infof("TCP listener (%v) shutting down", listener.Addr())

	mapping := t.natService.NewMapping(nat.TCP, tcaddr.IP, tcaddr.Port)
	mapping.OnChanged(func(_ *nat.Mapping, _, _ []nat.Address) {
		t.notifyAddressesChanged(t)
	})
	defer t.natService.RemoveMapping(mapping)

	t.mut.Lock()
	t.mapping = mapping
	t.mut.Unlock()

	for {
		listener.SetDeadline(time.Now().Add(time.Second))
		conn, err := listener.Accept()
		select {
		case <-t.stop:
			if err == nil {
				conn.Close()
			}
			t.mut.Lock()
			t.mapping = nil
			t.mut.Unlock()
			return
		default:
		}
		if err != nil {
			if err, ok := err.(*net.OpError); !ok || !err.Timeout() {
				l.Warnln("Accepting connection (BEP/tcp):", err)
			}
			continue
		}

		l.Debugln("connect from", conn.RemoteAddr())

		err = dialer.SetTCPOptions(conn)
		if err != nil {
			l.Infoln(err)
		}

		tc := tls.Server(conn, t.tlsCfg)
		err = tc.Handshake()
		if err != nil {
			l.Infoln("TLS handshake (BEP/tcp):", err)
			tc.Close()
			continue
		}

		t.conns <- IntermediateConnection{tc, "TCP (Server)", tcpPriority}
	}
}