<commit_before>package basichost

import (
	"context"
	"io"
	"time"

	logging "github.com/ipfs/go-log"
	goprocess "github.com/jbenet/goprocess"
	goprocessctx "github.com/jbenet/goprocess/context"
	ifconnmgr "github.com/libp2p/go-libp2p-interface-connmgr"
	inet "github.com/libp2p/go-libp2p-net"
	peer "github.com/libp2p/go-libp2p-peer"
	pstore "github.com/libp2p/go-libp2p-peerstore"
	protocol "github.com/libp2p/go-libp2p-protocol"
	identify "github.com/libp2p/go-libp2p/p2p/protocol/identify"
	ma "github.com/multiformats/go-multiaddr"
	madns "github.com/multiformats/go-multiaddr-dns"
	msmux "github.com/multiformats/go-multistream"
)

var log = logging.Logger("basichost")

var (
	// DefaultNegotiationTimeout is the default value for HostOpts.NegotiationTimeout.
	DefaultNegotiationTimeout = time.Second * 60

	// DefaultAddrsFactory is the default value for HostOpts.AddrsFactory.
	DefaultAddrsFactory = func(addrs []ma.Multiaddr) []ma.Multiaddr { return addrs }
)

// AddrsFactory functions can be passed to New in order to override
// addresses returned by Addrs.
type AddrsFactory func([]ma.Multiaddr) []ma.Multiaddr

// Option is a type used to pass in options to the host.
//
// Deprecated in favor of HostOpts and NewHost.
type Option int

// NATPortMap makes the host attempt to open port-mapping in NAT devices
// for all its listeners. Pass in this option in the constructor to
// asynchronously a) find a gateway, b) open port mappings, c) republish
// port mappings periodically. The NATed addresses are included in the
// Host's Addrs() list.
//
// This option is deprecated in favor of HostOpts and NewHost.
const NATPortMap Option = iota

// BasicHost is the basic implementation of the host.Host interface. This
// particular host implementation:
//  * uses a protocol muxer to mux per-protocol streams
//  * uses an identity service to send + receive node information
//  * uses a nat service to establish NAT port mappings
type BasicHost struct {
	network    inet.Network
	mux        *msmux.MultistreamMuxer
	ids        *identify.IDService
	natmgr     NATManager
	addrs      AddrsFactory
	maResolver *madns.Resolver
	cmgr       ifconnmgr.ConnManager

	negtimeout time.Duration

	proc goprocess.Process
}

// HostOpts holds options that can be passed to NewHost in order to
// customize construction of the *BasicHost.
type HostOpts struct {

	// MultistreamMuxer is essential for the *BasicHost and will use a sensible default value if omitted.
	MultistreamMuxer *msmux.MultistreamMuxer

	// NegotiationTimeout determines the read and write timeouts on streams.
	// If 0 or omitted, it will use DefaultNegotiationTimeout.
	// If below 0, timeouts on streams will be deactivated.
	NegotiationTimeout time.Duration

	// IdentifyService holds an implementation of the /ipfs/id/ protocol.
	// If omitted, a new *identify.IDService will be used.
	IdentifyService *identify.IDService

	// AddrsFactory holds a function which can be used to override or filter the result of Addrs.
	// If omitted, there's no override or filtering, and the results of Addrs and AllAddrs are the same.
	AddrsFactory AddrsFactory

	// MultiaddrResolves holds the go-multiaddr-dns.Resolver used for resolving
	// /dns4, /dns6, and /dnsaddr addresses before trying to connect to a peer.
	MultiaddrResolver *madns.Resolver

	// NATManager takes care of setting NAT port mappings, and discovering external addresses.
	// If omitted, this will simply be disabled.
	NATManager func(inet.Network) NATManager

	// ConnManager is a libp2p connection manager
	ConnManager ifconnmgr.ConnManager
}

// NewHost constructs a new *BasicHost and activates it by attaching its stream and connection handlers to the given inet.Network.
func NewHost(ctx context.Context, net inet.Network, opts *HostOpts) (*BasicHost, error) {
	h := &BasicHost{
		network:    net,
		mux:        msmux.NewMultistreamMuxer(),
		negtimeout: DefaultNegotiationTimeout,
		addrs:      DefaultAddrsFactory,
		maResolver: madns.DefaultResolver,
	}

	h.proc = goprocessctx.WithContextAndTeardown(ctx, func() error {
		if h.natmgr != nil {
			h.natmgr.Close()
		}
		return h.Network().Close()
	})

	if opts.MultistreamMuxer != nil {
		h.mux = opts.MultistreamMuxer
	}

	if opts.IdentifyService != nil {
		h.ids = opts.IdentifyService
	} else {
		// we can't set this as a default above because it depends on the *BasicHost.
		h.ids = identify.NewIDService(h)
	}

	if uint64(opts.NegotiationTimeout) != 0 {
		h.negtimeout = opts.NegotiationTimeout
	}

	if opts.AddrsFactory != nil {
		h.addrs = opts.AddrsFactory
	}

	if opts.NATManager != nil {
		h.natmgr = opts.NATManager(net)
	}

	if opts.MultiaddrResolver != nil {
		h.maResolver = opts.MultiaddrResolver
	}

	if opts.ConnManager == nil {
		h.cmgr = &ifconnmgr.NullConnMgr{}
	} else {
		h.cmgr = opts.ConnManager
		net.Notify(h.cmgr.Notifee())
	}

	net.SetConnHandler(h.newConnHandler)
	net.SetStreamHandler(h.newStreamHandler)
	return h, nil
}

// New constructs and sets up a new *BasicHost with given Network and options.
// The following options can be passed:
// * NATPortMap
// * AddrsFactory
// * ifconnmgr.ConnManager<commit_msg>ping service in basic host<commit_after>package basichost

import (
	"context"
	"io"
	"time"

	logging "github.com/ipfs/go-log"
	goprocess "github.com/jbenet/goprocess"
	goprocessctx "github.com/jbenet/goprocess/context"
	ifconnmgr "github.com/libp2p/go-libp2p-interface-connmgr"
	inet "github.com/libp2p/go-libp2p-net"
	peer "github.com/libp2p/go-libp2p-peer"
	pstore "github.com/libp2p/go-libp2p-peerstore"
	protocol "github.com/libp2p/go-libp2p-protocol"
	identify "github.com/libp2p/go-libp2p/p2p/protocol/identify"
	ping "github.com/libp2p/go-libp2p/p2p/protocol/ping"
	ma "github.com/multiformats/go-multiaddr"
	madns "github.com/multiformats/go-multiaddr-dns"
	msmux "github.com/multiformats/go-multistream"
)

var log = logging.Logger("basichost")

var (
	// DefaultNegotiationTimeout is the default value for HostOpts.NegotiationTimeout.
	DefaultNegotiationTimeout = time.Second * 60

	// DefaultAddrsFactory is the default value for HostOpts.AddrsFactory.
	DefaultAddrsFactory = func(addrs []ma.Multiaddr) []ma.Multiaddr { return addrs }
)

// AddrsFactory functions can be passed to New in order to override
// addresses returned by Addrs.
type AddrsFactory func([]ma.Multiaddr) []ma.Multiaddr

// Option is a type used to pass in options to the host.
//
// Deprecated in favor of HostOpts and NewHost.
type Option int

// NATPortMap makes the host attempt to open port-mapping in NAT devices
// for all its listeners. Pass in this option in the constructor to
// asynchronously a) find a gateway, b) open port mappings, c) republish
// port mappings periodically. The NATed addresses are included in the
// Host's Addrs() list.
//
// This option is deprecated in favor of HostOpts and NewHost.
const NATPortMap Option = iota

// BasicHost is the basic implementation of the host.Host interface. This
// particular host implementation:
//  * uses a protocol muxer to mux per-protocol streams
//  * uses an identity service to send + receive node information
//  * uses a nat service to establish NAT port mappings
type BasicHost struct {
	network    inet.Network
	mux        *msmux.MultistreamMuxer
	ids        *identify.IDService
	pings      *ping.PingService
	natmgr     NATManager
	addrs      AddrsFactory
	maResolver *madns.Resolver
	cmgr       ifconnmgr.ConnManager

	negtimeout time.Duration

	proc goprocess.Process
}

// HostOpts holds options that can be passed to NewHost in order to
// customize construction of the *BasicHost.
type HostOpts struct {

	// MultistreamMuxer is essential for the *BasicHost and will use a sensible default value if omitted.
	MultistreamMuxer *msmux.MultistreamMuxer

	// NegotiationTimeout determines the read and write timeouts on streams.
	// If 0 or omitted, it will use DefaultNegotiationTimeout.
	// If below 0, timeouts on streams will be deactivated.
	NegotiationTimeout time.Duration

	// IdentifyService holds an implementation of the /ipfs/id/ protocol.
	// If omitted, a new *identify.IDService will be used.
	IdentifyService *identify.IDService

	// AddrsFactory holds a function which can be used to override or filter the result of Addrs.
	// If omitted, there's no override or filtering, and the results of Addrs and AllAddrs are the same.
	AddrsFactory AddrsFactory

	// MultiaddrResolves holds the go-multiaddr-dns.Resolver used for resolving
	// /dns4, /dns6, and /dnsaddr addresses before trying to connect to a peer.
	MultiaddrResolver *madns.Resolver

	// NATManager takes care of setting NAT port mappings, and discovering external addresses.
	// If omitted, this will simply be disabled.
	NATManager func(inet.Network) NATManager

	// ConnManager is a libp2p connection manager
	ConnManager ifconnmgr.ConnManager

	// EnablePing indicates whether to instantiate the ping service
	EnablePing bool
}

// NewHost constructs a new *BasicHost and activates it by attaching its stream and connection handlers to the given inet.Network.
func NewHost(ctx context.Context, net inet.Network, opts *HostOpts) (*BasicHost, error) {
	h := &BasicHost{
		network:    net,
		mux:        msmux.NewMultistreamMuxer(),
		negtimeout: DefaultNegotiationTimeout,
		addrs:      DefaultAddrsFactory,
		maResolver: madns.DefaultResolver,
	}

	h.proc = goprocessctx.WithContextAndTeardown(ctx, func() error {
		if h.natmgr != nil {
			h.natmgr.Close()
		}
		return h.Network().Close()
	})

	if opts.MultistreamMuxer != nil {
		h.mux = opts.MultistreamMuxer
	}

	if opts.IdentifyService != nil {
		h.ids = opts.IdentifyService
	} else {
		// we can't set this as a default above because it depends on the *BasicHost.
		h.ids = identify.NewIDService(h)
	}

	if uint64(opts.NegotiationTimeout) != 0 {
		h.negtimeout = opts.NegotiationTimeout
	}

	if opts.AddrsFactory != nil {
		h.addrs = opts.AddrsFactory
	}

	if opts.NATManager != nil {
		h.natmgr = opts.NATManager(net)
	}

	if opts.MultiaddrResolver != nil {
		h.maResolver = opts.MultiaddrResolver
	}

	if opts.ConnManager == nil {
		h.cmgr = &ifconnmgr.NullConnMgr{}
	} else {
		h.cmgr = opts.ConnManager
		net.Notify(h.cmgr.Notifee())
	}

	if opts.EnablePing {
		h.pings = ping.NewPingService(h)
	}

	net.SetConnHandler(h.newConnHandler)
	net.SetStreamHandler(h.newStreamHandler)
	return h, nil
}

// New constructs and sets up a new *BasicHost with given Network and options.
// The following options can be passed:
// * NATPortMap
// * AddrsFactory
// * ifconnmgr.ConnManager
{'fraction_non_alphanumeric': 0.08828280908486173, 'fraction_numerical': 0.004656466787037917, 'mean_word_length': 3.8297384121156495, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4795884', 'n_tokens_mistral': 3518, 'n_tokens_neox': 3379, 'n_words': 1063}