func JoinSession(invitation protocol.SessionInvitation) (net.Conn, error) { addr := net.JoinHostPort(net.IP(invitation.Address).String(), strconv.Itoa(int(invitation.Port))) conn, err := net.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 sessionConnectionHandler(conn net.Conn) { if err := conn.SetDeadline(time.Now().Add(messageTimeout)); err != nil { if debug { log.Println("Weird error setting deadline:", err, "on", conn.RemoteAddr()) } return } message, err := protocol.ReadMessage(conn) if err != nil { return } switch msg := message.(type) { case protocol.JoinSessionRequest: ses := findSession(string(msg.Key)) if debug { log.Println(conn.RemoteAddr(), "session lookup", ses) } if ses == nil { protocol.WriteMessage(conn, protocol.ResponseNotFound) conn.Close() return } if !ses.AddConnection(conn) { if debug { log.Println("Failed to add", conn.RemoteAddr(), "to session", ses) } protocol.WriteMessage(conn, protocol.ResponseAlreadyConnected) conn.Close() return } if err := protocol.WriteMessage(conn, protocol.ResponseSuccess); err != nil { if debug { log.Println("Failed to send session join response to ", conn.RemoteAddr(), "for", ses) } return } if err := conn.SetDeadline(time.Time{}); err != nil { if debug { log.Println("Weird error setting deadline:", err, "on", conn.RemoteAddr()) } conn.Close() return } default: if debug { log.Println("Unexpected message from", conn.RemoteAddr(), message) } protocol.WriteMessage(conn, protocol.ResponseUnexpectedMessage) conn.Close() } }
func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) { for { msg, err := protocol.ReadMessage(conn) if err != nil { errors <- err return } messages <- msg } }
func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) { atomic.AddInt64(&numConnections, 1) defer atomic.AddInt64(&numConnections, -1) for { msg, err := protocol.ReadMessage(conn) if err != nil { errors <- err return } messages <- msg } }
func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs []tls.Certificate) (protocol.SessionInvitation, error) { if uri.Scheme != "relay" { return protocol.SessionInvitation{}, fmt.Errorf("Unsupported relay scheme:", uri.Scheme) } conn, err := tls.Dial("tcp", uri.Host, configForCerts(certs)) if err != nil { return protocol.SessionInvitation{}, err } conn.SetDeadline(time.Now().Add(10 * time.Second)) if err := performHandshakeAndValidation(conn, uri); err != nil { return protocol.SessionInvitation{}, err } defer conn.Close() request := protocol.ConnectRequest{ ID: id[:], } if err := protocol.WriteMessage(conn, request); err != nil { return protocol.SessionInvitation{}, err } message, err := protocol.ReadMessage(conn) if err != nil { return protocol.SessionInvitation{}, err } switch msg := message.(type) { case protocol.Response: return protocol.SessionInvitation{}, fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message) case protocol.SessionInvitation: if debug { l.Debugln("Received invitation", msg, "via", conn.LocalAddr()) } ip := net.IP(msg.Address) if len(ip) == 0 || ip.IsUnspecified() { msg.Address = conn.RemoteAddr().(*net.TCPAddr).IP[:] } return msg, nil default: return protocol.SessionInvitation{}, fmt.Errorf("protocol error: unexpected message %v", msg) } }
func (c *ProtocolClient) join() error { if err := protocol.WriteMessage(c.conn, protocol.JoinRelayRequest{}); err != nil { return err } message, err := protocol.ReadMessage(c.conn) if err != nil { return err } switch msg := message.(type) { case protocol.Response: if msg.Code != 0 { return fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message) } default: return fmt.Errorf("protocol error: expecting response got %v", msg) } return nil }