mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-23 03:17:43 +08:00
Note: This commit is technically broken. However, I need to make a bunch of cmds changes to make this work and I'd rather not bundle both changes into a single commit. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>
151 lines
3.2 KiB
Go
151 lines
3.2 KiB
Go
package p2p
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
manet "gx/ipfs/QmX3U3YXCQ6UYBxq2LVWF8dARS1hPUTEYLrSx654Qyxyw6/go-multiaddr-net"
|
|
ma "gx/ipfs/QmXY77cVe7rVRQXZZQRioukUM7aRW3BTcAgJe12MCtb3Ji/go-multiaddr"
|
|
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
|
|
net "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net"
|
|
)
|
|
|
|
// ListenerInfo holds information on a p2p listener.
|
|
type ListenerInfo struct {
|
|
// Application protocol identifier.
|
|
Protocol string
|
|
|
|
// Node identity
|
|
Identity peer.ID
|
|
|
|
// Local protocol stream address.
|
|
Address ma.Multiaddr
|
|
|
|
// Local protocol stream listener.
|
|
Closer io.Closer
|
|
|
|
// Flag indicating whether we're still accepting incoming connections, or
|
|
// whether this application listener has been shutdown.
|
|
Running bool
|
|
|
|
Registry *ListenerRegistry
|
|
}
|
|
|
|
// Close closes the listener. Does not affect child streams
|
|
func (c *ListenerInfo) Close() error {
|
|
c.Closer.Close()
|
|
err := c.Registry.Deregister(c.Protocol)
|
|
return err
|
|
}
|
|
|
|
// ListenerRegistry is a collection of local application protocol listeners.
|
|
type ListenerRegistry struct {
|
|
Listeners []*ListenerInfo
|
|
}
|
|
|
|
// Register registers listenerInfo2 in this registry
|
|
func (c *ListenerRegistry) Register(listenerInfo *ListenerInfo) {
|
|
c.Listeners = append(c.Listeners, listenerInfo)
|
|
}
|
|
|
|
// Deregister removes p2p listener from this registry
|
|
func (c *ListenerRegistry) Deregister(proto string) error {
|
|
foundAt := -1
|
|
for i, a := range c.Listeners {
|
|
if a.Protocol == proto {
|
|
foundAt = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if foundAt != -1 {
|
|
c.Listeners = append(c.Listeners[:foundAt], c.Listeners[foundAt+1:]...)
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("failed to deregister proto %s", proto)
|
|
}
|
|
|
|
// StreamInfo holds information on active incoming and outgoing p2p streams.
|
|
type StreamInfo struct {
|
|
HandlerID uint64
|
|
|
|
Protocol string
|
|
|
|
LocalPeer peer.ID
|
|
LocalAddr ma.Multiaddr
|
|
|
|
RemotePeer peer.ID
|
|
RemoteAddr ma.Multiaddr
|
|
|
|
Local manet.Conn
|
|
Remote net.Stream
|
|
|
|
Registry *StreamRegistry
|
|
}
|
|
|
|
// Close closes stream endpoints and deregisters it
|
|
func (s *StreamInfo) Close() error {
|
|
s.Local.Close()
|
|
s.Remote.Close()
|
|
s.Registry.Deregister(s.HandlerID)
|
|
return nil
|
|
}
|
|
|
|
// Reset closes stream endpoints and deregisters it
|
|
func (s *StreamInfo) Reset() error {
|
|
s.Local.Close()
|
|
s.Remote.Reset()
|
|
s.Registry.Deregister(s.HandlerID)
|
|
return nil
|
|
}
|
|
|
|
func (s *StreamInfo) startStreaming() {
|
|
go func() {
|
|
_, err := io.Copy(s.Local, s.Remote)
|
|
if err != nil {
|
|
s.Reset()
|
|
} else {
|
|
s.Close()
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
_, err := io.Copy(s.Remote, s.Local)
|
|
if err != nil {
|
|
s.Reset()
|
|
} else {
|
|
s.Close()
|
|
}
|
|
}()
|
|
}
|
|
|
|
// StreamRegistry is a collection of active incoming and outgoing protocol app streams.
|
|
type StreamRegistry struct {
|
|
Streams []*StreamInfo
|
|
|
|
nextID uint64
|
|
}
|
|
|
|
// Register registers a stream to the registry
|
|
func (c *StreamRegistry) Register(streamInfo *StreamInfo) {
|
|
streamInfo.HandlerID = c.nextID
|
|
c.Streams = append(c.Streams, streamInfo)
|
|
c.nextID++
|
|
}
|
|
|
|
// Deregister deregisters stream from the registry
|
|
func (c *StreamRegistry) Deregister(handlerID uint64) {
|
|
foundAt := -1
|
|
for i, s := range c.Streams {
|
|
if s.HandlerID == handlerID {
|
|
foundAt = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if foundAt != -1 {
|
|
c.Streams = append(c.Streams[:foundAt], c.Streams[foundAt+1:]...)
|
|
}
|
|
}
|