func JoinSession(invitation protocol.SessionInvitation) (net.Conn, error) { addr := net.JoinHostPort(net.IP(invitation.Address).String(), strconv.Itoa(int(invitation.Port))) conn, err := dialer.Dial("tcp", addr) if err != nil { return nil, err } request := protocol.JoinSessionRequest{ Key: invitation.Key, } conn.SetDeadline(time.Now().Add(10 * time.Second)) err = protocol.WriteMessage(conn, request) if err != nil { return nil, err } message, err := protocol.ReadMessage(conn) if err != nil { return nil, err } conn.SetDeadline(time.Time{}) switch msg := message.(type) { case protocol.Response: if msg.Code != 0 { return nil, fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message) } return conn, nil default: return nil, fmt.Errorf("protocol error: expecting response got %v", msg) } }
func tcpDialer(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) { // Check that there is a port number in uri.Host, otherwise add one. host, port, err := net.SplitHostPort(uri.Host) if err != nil && strings.HasPrefix(err.Error(), "missing port") { // addr is on the form "1.2.3.4" uri.Host = net.JoinHostPort(uri.Host, "22000") } else if err == nil && port == "" { // addr is on the form "1.2.3.4:" uri.Host = net.JoinHostPort(host, "22000") } // Don't try to resolve the address before dialing. The dialer may be a // proxy, and we should let the proxy do the resolving in that case. conn, err := dialer.Dial("tcp", uri.Host) if err != nil { l.Debugln(err) return nil, err } tc := tls.Client(conn, tlsCfg) err = tc.Handshake() if err != nil { tc.Close() return nil, err } return tc, nil }
func localIP(url *url.URL) (string, error) { conn, err := dialer.Dial("tcp", url.Host) if err != nil { return "", err } defer conn.Close() localIPAddress, _, err := net.SplitHostPort(conn.LocalAddr().String()) if err != nil { return "", err } return localIPAddress, nil }