func (l *ListenerService) process(c net.Conn) error { handshakeMsg, errHandshake := protocol.ReadDecodeHandshake(c) if errHandshake != nil { return errHandshake } l.logger.Debug("processing hansdhake...") if !protocol.IsMagicValid(handshakeMsg.Bytes()) { return fmt.Errorf("invalid magic bytes") } l.logger.Debug("maginc is correct, replying...") if err := protocol.WriteEncodeOk(c); err != nil { return err } if err := protocol.WriteEncodePeerInfo(c, l.localNode.State().PrivateIP); err != nil { return err } peerInfo, errPeerInfo := protocol.ReadDecodePeerInfo(c) if errPeerInfo != nil { return errPeerInfo } l.logger.Debug("processing peer info...") rn := NewRemoteNode(c, handshakeMsg.SessionKey(), peerInfo.PrivateIP()) l.logger.Debug("adding remote node...") l.localNode.NetTable().AddRemoteNode(rn) return nil }
func TryConnect(h string, networkSecret *secure.NetworkSecret, ln *LocalNode) (*RemoteNode, error) { host, portStr, errSplit := net.SplitHostPort(h) if errSplit != nil { return nil, errSplit } port, errConvert := strconv.Atoi(portStr) if errConvert != nil { return nil, errConvert } rn := new(RemoteNode) rn.lastHeartbeat = time.Now() rn.publicAddress = fmt.Sprintf("%s:%d", host, port+1) rn.logger = log.L(fmt.Sprintf("public %s", rn.publicAddress)) rn.logger.Debug("trying to connect...") s, errSocket := utp.NewSocket("udp4", ":0") if errSocket != nil { rn.logger.Error("unable to crete a socket, %v", errSocket) return nil, errSocket } conn, errDial := s.DialTimeout(rn.publicAddress, 10*time.Second) if errDial != nil { rn.logger.Error("unable to dial, %s", errDial) return nil, errDial } rn.conn = conn rn.sessionKey = RandomBytes(16) if err := protocol.WriteEncodeHandshake(rn.conn, rn.sessionKey, networkSecret); err != nil { return nil, err } if _, okError := protocol.ReadDecodeOk(rn.conn); okError != nil { return nil, okError } peerInfo, errPeerInfo := protocol.ReadDecodePeerInfo(rn.conn) if errPeerInfo != nil { return nil, errPeerInfo } rn.privateIP = peerInfo.PrivateIP() // create new logger log.RemoveLogger(rn.logger.Name()) rn.logger = log.L(fmt.Sprintf(rnLoggerFormat, rn.privateIP.String())) if err := protocol.WriteEncodePeerInfo(rn.conn, ln.State().PrivateIP); err != nil { return nil, err } rn.logger.Info("connected, with public address %q", rn.publicAddress) return rn, nil }