ipfs, libp2p, private network

Private Network

1. PNet provides extra encrypt/decrypt to a swarm connection:

Initialization here:

func PrivateNetwork(prot pnet.Protector) Option {
	return func(cfg *Config) error {
		if cfg.Protector != nil {
			return fmt.Errorf("cannot specify multiple private network options")
		}

		cfg.Protector = prot
		return nil
	}
}

2. When creating a host, a PNet option has to be provided:

protec, err := pnet.NewProtector(bytes.NewReader(swarmkey))

opts := []libp2p.Option{
	libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", listenPort)),
	libp2p.Identity(priv),
	libp2p.Transport(q),
	libp2p.DefaultTransports,
	libp2p.DefaultMuxers,
	libp2p.DefaultSecurity,
	libp2p.NATPortMap(),
	libp2p.PrivateNetwork(protec),
}

3. Setup PNet connection

func (u *Upgrader) upgrade(ctx context.Context, t transport.Transport, maconn manet.Conn, p peer.ID) (transport.CapableConn, error) {
	if u.Filters != nil && u.Filters.AddrBlocked(maconn.RemoteMultiaddr()) {
		log.Debugf("blocked connection from %s", maconn.RemoteMultiaddr())
		maconn.Close()
		return nil, fmt.Errorf("blocked connection from %s", maconn.RemoteMultiaddr())
	}

	var conn net.Conn = maconn
	if u.Protector != nil {
		pconn, err := u.Protector.Protect(conn)
		if err != nil {
			conn.Close()
			return nil, fmt.Errorf("failed to setup private network protector: %s", err)
		}
		conn = pconn
		...

Protect will call newPSKConn to generate pskConn

func newPSKConn(psk *[32]byte, insecure net.Conn) (net.Conn, error) {
	if insecure == nil {
		return nil, errInsecureNil
	}
	if psk == nil {
		return nil, errPSKNil
	}
	return &pskConn{
		Conn: insecure,
		psk:  psk,
	}, nil
}

type pskConn struct {
	net.Conn
	psk *[32]byte

	writeS20 cipher.Stream
	readS20  cipher.Stream
}

conn will be replaced by pconn(pskConn) when Protector is out there

4. CipherStream when reading or writing. salsa20 will be used

func (c *pskConn) Read(out []byte) (int, error) {
	if c.readS20 == nil {
		nonce := make([]byte, 24)
		_, err := io.ReadFull(c.Conn, nonce)
		if err != nil {
			return 0, errShortNonce
		}
		c.readS20 = salsa20.New(c.psk, nonce)
	}

	n, err := c.Conn.Read(out) // read to in
	if n > 0 {
		c.readS20.XORKeyStream(out[:n], out[:n]) // decrypt to out buffer
	}
	return n, err
}

发布了11 篇原创文章 · 获赞 4 · 访问量 560

猜你喜欢

转载自blog.csdn.net/m0_37889044/article/details/104424332