흐름을 따라가보자
func (srv *Server) listenLoop() {
srv.log.Debug("TCP listener up", "addr", srv.listener.Addr())
for {
for {
fd, err = srv.listener.Accept()
break
}
remoteIP := netutil.AddrIP(fd.RemoteAddr())
go func() {
srv.SetupConn(fd, inboundConn, nil)
slots <- struct{}{}
}()
}
}
func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *enode.Node) error {
c := &conn{fd: fd, flags: flags, cont: make(chan error)}
err := srv.setupConn(c, flags, dialDest)
return err
}
- SetupConn에서 srv.setupConn을 호출
func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) error {
if dialDest != nil {
dialPubkey := new(ecdsa.PublicKey)
if err := dialDest.Load((*enode.Secp256k1)(dialPubkey)); err != nil {
err = errors.New("dial destination doesn't have a secp256k1 public key")
srv.log.Trace("Setting up connection failed", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err)
return err
}
}
remotePubkey, err := c.doEncHandshake(srv.PrivateKey)
c.node = dialDest
phs, err := c.doProtoHandshake(srv.ourHandshake)
err = srv.checkpoint(c, srv.checkpointAddPeer)
return nil
}
잠시 ECIES를 알아보자
doEncHandshake에서 실제 handshke 까지 살펴보자
func (t *rlpxTransport) doEncHandshake(prv *ecdsa.PrivateKey) (*ecdsa.PublicKey, error) {
t.conn.SetDeadline(time.Now().Add(handshakeTimeout))
return t.conn.Handshake(prv)
}
func (c *Conn) Handshake(prv *ecdsa.PrivateKey) (*ecdsa.PublicKey, error) {
var (
sec Secrets
err error
h handshakeState
)
sec, err = h.runInitiator(c.conn, prv, c.dialDest)
c.InitWithSecrets(sec)
c.session.rbuf = h.rbuf
c.session.wbuf = h.wbuf
return sec.remote, err
}
func (h *handshakeState) runInitiator(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ecdsa.PublicKey) (s Secrets, err error) {
h.initiator = true
h.remote = ecies.ImportECDSAPublic(remote)
authMsg, err := h.makeAuthMsg(prv)
authPacket, err := h.sealEIP8(authMsg)
if _, err = conn.Write(authPacket); err != nil {
return s, err
}
authRespMsg := new(authRespV4)
authRespPacket, err := h.readMsg(authRespMsg, prv, conn)
if err != nil {
return s, err
}
if err := h.handleAuthResp(authRespMsg); err != nil {
return s, err
}
return h.secrets(authPacket, authRespPacket)
}
- 위의 과정을 거치면 Adding p2p peer