Collecting network vars and functions in networks structure

This commit is contained in:
Kleissner
2021-10-18 02:12:36 +02:00
parent e2542b3a4d
commit 5d93a74981
10 changed files with 98 additions and 105 deletions

View File

@@ -165,18 +165,18 @@ func bootstrap() {
Filters.LogError("bootstrap", "unable to connect to at least 2 root peers, aborting\n") Filters.LogError("bootstrap", "unable to connect to at least 2 root peers, aborting\n")
} }
func autoMulticastBroadcast() { func (nets *Networks) autoMulticastBroadcast() {
sendMulticastBroadcast := func() { sendMulticastBroadcast := func() {
networksMutex.RLock() nets.RLock()
defer networksMutex.RUnlock() defer nets.RUnlock()
for _, network := range networks6 { for _, network := range nets.networks6 {
if err := network.MulticastIPv6Send(); err != nil { if err := network.MulticastIPv6Send(); err != nil {
Filters.LogError("autoMulticastBroadcast", "multicast from network address '%s': %v\n", network.address.IP.String(), err.Error()) Filters.LogError("autoMulticastBroadcast", "multicast from network address '%s': %v\n", network.address.IP.String(), err.Error())
} }
} }
for _, network := range networks4 { for _, network := range nets.networks4 {
if err := network.BroadcastIPv4Send(); err != nil { if err := network.BroadcastIPv4Send(); err != nil {
Filters.LogError("autoMulticastBroadcast", "broadcast from network address '%s': %v\n", network.address.IP.String(), err.Error()) Filters.LogError("autoMulticastBroadcast", "broadcast from network address '%s': %v\n", network.address.IP.String(), err.Error())
} }
@@ -216,7 +216,7 @@ func contactArbitraryPeer(publicKey *btcec.PublicKey, address *net.UDPAddr, rece
Filters.MessageOutAnnouncement(publicKey, nil, raw, findSelf, nil, nil, nil) Filters.MessageOutAnnouncement(publicKey, nil, raw, findSelf, nil, nil, nil)
sendAllNetworks(publicKey, raw, address, receiverPortInternal, nil, &bootstrapFindSelf{}) networks.sendAllNetworks(publicKey, raw, address, receiverPortInternal, nil, &bootstrapFindSelf{})
return true return true
} }

View File

@@ -351,7 +351,7 @@ func (c *Connection) send(packet *protocol.PacketRaw, receiverPublicKey *btcec.P
func (peer *PeerInfo) send(packet *protocol.PacketRaw) (err error) { func (peer *PeerInfo) send(packet *protocol.PacketRaw) (err error) {
if peer.isVirtual { // special case for peers that were not contacted before if peer.isVirtual { // special case for peers that were not contacted before
for _, address := range peer.targetAddresses { for _, address := range peer.targetAddresses {
sendAllNetworks(peer.PublicKey, packet, &net.UDPAddr{IP: address.IP, Port: int(address.Port)}, address.PortInternal, peer.traversePeer, nil) networks.sendAllNetworks(peer.PublicKey, packet, &net.UDPAddr{IP: address.IP, Port: int(address.Port)}, address.PortInternal, peer.traversePeer, nil)
} }
return return
} }
@@ -407,13 +407,13 @@ func (peer *PeerInfo) sendConnection(packet *protocol.PacketRaw, connection *Con
// sendAllNetworks sends a raw packet via all networks. It assigns a new sequence for each sent packet. // sendAllNetworks sends a raw packet via all networks. It assigns a new sequence for each sent packet.
// receiverPortInternal is important for NAT detection and sending the traverse message. // receiverPortInternal is important for NAT detection and sending the traverse message.
func sendAllNetworks(receiverPublicKey *btcec.PublicKey, packet *protocol.PacketRaw, remote *net.UDPAddr, receiverPortInternal uint16, traversePeer *PeerInfo, sequenceData interface{}) (err error) { func (nets *Networks) sendAllNetworks(receiverPublicKey *btcec.PublicKey, packet *protocol.PacketRaw, remote *net.UDPAddr, receiverPortInternal uint16, traversePeer *PeerInfo, sequenceData interface{}) (err error) {
networksMutex.RLock() nets.RLock()
defer networksMutex.RUnlock() defer nets.RUnlock()
networksTarget := networks4 networksTarget := nets.networks4
if IsIPv6(remote.IP.To16()) { if IsIPv6(remote.IP.To16()) {
networksTarget = networks6 networksTarget = nets.networks6
} }
successCount := 0 successCount := 0
@@ -426,7 +426,7 @@ func sendAllNetworks(receiverPublicKey *btcec.PublicKey, packet *protocol.Packet
} }
if sequenceData != nil { if sequenceData != nil {
packet.Sequence = networks.Sequences.ArbitrarySequence(receiverPublicKey, sequenceData).SequenceNumber packet.Sequence = nets.Sequences.ArbitrarySequence(receiverPublicKey, sequenceData).SequenceNumber
} }
err = (&Connection{Network: network, Address: remote, PortInternal: receiverPortInternal, traversePeer: traversePeer}).send(packet, receiverPublicKey, isFirstPacket) err = (&Connection{Network: network, Address: remote, PortInternal: receiverPortInternal, traversePeer: traversePeer}).send(packet, receiverPublicKey, isFirstPacket)
isFirstPacket = false isFirstPacket = false

View File

@@ -93,7 +93,7 @@ func IsNetworkErrorFatal(err error) bool {
const changeMonitorFrequency = 10 const changeMonitorFrequency = 10
// networkChangeMonitor() monitors for network changes to act accordingly // networkChangeMonitor() monitors for network changes to act accordingly
func networkChangeMonitor() { func (nets *Networks) networkChangeMonitor() {
// If manual IPs are entered, no need for monitoring for any network changes. // If manual IPs are entered, no need for monitoring for any network changes.
if len(config.Listen) > 0 { if len(config.Listen) > 0 {
return return
@@ -119,9 +119,9 @@ func networkChangeMonitor() {
ifacesNew[iface.Name] = addressesNew ifacesNew[iface.Name] = addressesNew
// was the interface added? // was the interface added?
addressesExist, ok := networks.ipListen.ifacesExist[iface.Name] addressesExist, ok := nets.ipListen.ifacesExist[iface.Name]
if !ok { if !ok {
networkChangeInterfaceNew(iface, addressesNew) nets.networkChangeInterfaceNew(iface, addressesNew)
} else { } else {
// new IPs added for this interface? // new IPs added for this interface?
for _, addr := range addressesNew { for _, addr := range addressesNew {
@@ -134,7 +134,7 @@ func networkChangeMonitor() {
} }
if !exists { if !exists {
networkChangeIPNew(iface, addr) nets.networkChangeIPNew(iface, addr)
} }
} }
@@ -149,30 +149,30 @@ func networkChangeMonitor() {
} }
if removed { if removed {
networkChangeIPRemove(iface, exist) nets.networkChangeIPRemove(iface, exist)
} }
} }
} }
} }
// was an existing interface removed? // was an existing interface removed?
for ifaceExist, addressesExist := range networks.ipListen.ifacesExist { for ifaceExist, addressesExist := range nets.ipListen.ifacesExist {
if _, ok := ifacesNew[ifaceExist]; !ok { if _, ok := ifacesNew[ifaceExist]; !ok {
networkChangeInterfaceRemove(ifaceExist, addressesExist) nets.networkChangeInterfaceRemove(ifaceExist, addressesExist)
} }
} }
networks.ipListen.ifacesExist = ifacesNew nets.ipListen.ifacesExist = ifacesNew
} }
} }
// networkChangeInterfaceNew is called when a new interface is detected // networkChangeInterfaceNew is called when a new interface is detected
func networkChangeInterfaceNew(iface net.Interface, addresses []net.Addr) { func (nets *Networks) networkChangeInterfaceNew(iface net.Interface, addresses []net.Addr) {
Filters.LogError("networkChangeInterfaceNew", "new interface '%s' (%d IPs)\n", iface.Name, len(addresses)) Filters.LogError("networkChangeInterfaceNew", "new interface '%s' (%d IPs)\n", iface.Name, len(addresses))
networks := networks.InterfaceStart(iface, addresses) networksNew := nets.InterfaceStart(iface, addresses)
for _, network := range networks { for _, network := range networksNew {
go network.upnpAuto() go network.upnpAuto()
} }
@@ -180,44 +180,44 @@ func networkChangeInterfaceNew(iface net.Interface, addresses []net.Addr) {
} }
// networkChangeInterfaceRemove is called when an existing interface is removed // networkChangeInterfaceRemove is called when an existing interface is removed
func networkChangeInterfaceRemove(iface string, addresses []net.Addr) { func (nets *Networks) networkChangeInterfaceRemove(iface string, addresses []net.Addr) {
networksMutex.RLock() nets.RLock()
defer networksMutex.RUnlock() defer nets.RUnlock()
Filters.LogError("networkChangeInterfaceRemove", "removing interface '%s' (%d IPs)\n", iface, len(addresses)) Filters.LogError("networkChangeInterfaceRemove", "removing interface '%s' (%d IPs)\n", iface, len(addresses))
for n, network := range networks6 { for n, network := range nets.networks6 {
if network.iface != nil && network.iface.Name == iface { if network.iface != nil && network.iface.Name == iface {
network.Terminate() network.Terminate()
// remove from list // remove from list
networksNew := networks6[:n] networksNew := nets.networks6[:n]
if n < len(networks6)-1 { if n < len(nets.networks6)-1 {
networksNew = append(networksNew, networks6[n+1:]...) networksNew = append(networksNew, nets.networks6[n+1:]...)
} }
networks6 = networksNew nets.networks6 = networksNew
} }
} }
for n, network := range networks4 { for n, network := range nets.networks4 {
if network.iface != nil && network.iface.Name == iface { if network.iface != nil && network.iface.Name == iface {
network.Terminate() network.Terminate()
// remove from list // remove from list
networksNew := networks4[:n] networksNew := nets.networks4[:n]
if n < len(networks4)-1 { if n < len(nets.networks4)-1 {
networksNew = append(networksNew, networks4[n+1:]...) networksNew = append(networksNew, nets.networks4[n+1:]...)
} }
networks4 = networksNew nets.networks4 = networksNew
} }
} }
} }
// networkChangeIPNew is called when an existing interface lists a new IP // networkChangeIPNew is called when an existing interface lists a new IP
func networkChangeIPNew(iface net.Interface, address net.Addr) { func (nets *Networks) networkChangeIPNew(iface net.Interface, address net.Addr) {
Filters.LogError("networkChangeIPNew", "new interface '%s' IP %s\n", iface.Name, address.String()) Filters.LogError("networkChangeIPNew", "new interface '%s' IP %s\n", iface.Name, address.String())
networksNew := networks.InterfaceStart(iface, []net.Addr{address}) networksNew := nets.InterfaceStart(iface, []net.Addr{address})
for _, network := range networksNew { for _, network := range networksNew {
go network.upnpAuto() go network.upnpAuto()
@@ -227,35 +227,35 @@ func networkChangeIPNew(iface net.Interface, address net.Addr) {
} }
// networkChangeIPRemove is called when an existing interface removes an IP // networkChangeIPRemove is called when an existing interface removes an IP
func networkChangeIPRemove(iface net.Interface, address net.Addr) { func (nets *Networks) networkChangeIPRemove(iface net.Interface, address net.Addr) {
networksMutex.RLock() nets.RLock()
defer networksMutex.RUnlock() defer nets.RUnlock()
Filters.LogError("networkChangeIPRemove", "remove interface '%s' IP %s\n", iface.Name, address.String()) Filters.LogError("networkChangeIPRemove", "remove interface '%s' IP %s\n", iface.Name, address.String())
for n, network := range networks6 { for n, network := range nets.networks6 {
if network.address.IP.Equal(address.(*net.IPNet).IP) { if network.address.IP.Equal(address.(*net.IPNet).IP) {
network.Terminate() network.Terminate()
// remove from list // remove from list
networksNew := networks6[:n] networksNew := nets.networks6[:n]
if n < len(networks6)-1 { if n < len(nets.networks6)-1 {
networksNew = append(networksNew, networks6[n+1:]...) networksNew = append(networksNew, nets.networks6[n+1:]...)
} }
networks6 = networksNew nets.networks6 = networksNew
} }
} }
for n, network := range networks4 { for n, network := range nets.networks4 {
if network.address.IP.Equal(address.(*net.IPNet).IP) { if network.address.IP.Equal(address.(*net.IPNet).IP) {
network.Terminate() network.Terminate()
// remove from list // remove from list
networksNew := networks4[:n] networksNew := nets.networks4[:n]
if n < len(networks4)-1 { if n < len(nets.networks4)-1 {
networksNew = append(networksNew, networks4[n+1:]...) networksNew = append(networksNew, nets.networks4[n+1:]...)
} }
networks4 = networksNew nets.networks4 = networksNew
} }
} }
} }

View File

@@ -68,7 +68,7 @@ func (network *Network) BroadcastIPv4Listen() {
continue continue
} }
if networks.ipListen.IsAddressSelf(sender.(*net.UDPAddr)) { if network.networkGroup.ipListen.IsAddressSelf(sender.(*net.UDPAddr)) {
continue continue
} }
@@ -85,7 +85,7 @@ func (network *Network) BroadcastIPv4Listen() {
} }
// send the packet to a channel which is processed by multiple workers. // send the packet to a channel which is processed by multiple workers.
rawPacketsIncoming <- networkWire{network: network, sender: sender.(*net.UDPAddr), raw: buffer[:length], receiverPublicKey: ipv4BroadcastPublicKey, unicast: false} network.networkGroup.rawPacketsIncoming <- networkWire{network: network, sender: sender.(*net.UDPAddr), raw: buffer[:length], receiverPublicKey: ipv4BroadcastPublicKey, unicast: false}
} }
} }

View File

@@ -114,7 +114,7 @@ func (network *Network) MulticastIPv6Listen() {
} }
// skip incoming packets that were looped back // skip incoming packets that were looped back
if networks.ipListen.IsAddressSelf(sender.(*net.UDPAddr)) { if network.networkGroup.ipListen.IsAddressSelf(sender.(*net.UDPAddr)) {
continue continue
} }
@@ -131,7 +131,7 @@ func (network *Network) MulticastIPv6Listen() {
} }
// send the packet to a channel which is processed by multiple workers. // send the packet to a channel which is processed by multiple workers.
rawPacketsIncoming <- networkWire{network: network, sender: sender.(*net.UDPAddr), raw: buffer[:length], receiverPublicKey: ipv6MulticastPublicKey, unicast: false} network.networkGroup.rawPacketsIncoming <- networkWire{network: network, sender: sender.(*net.UDPAddr), raw: buffer[:length], receiverPublicKey: ipv6MulticastPublicKey, unicast: false}
} }
} }

View File

@@ -30,20 +30,16 @@ type networkWire struct {
unicast bool // True if the message was sent via unicast. False if sent via IPv4 broadcast or IPv6 multicast. unicast bool // True if the message was sent via unicast. False if sent via IPv4 broadcast or IPv6 multicast.
} }
var (
rawPacketsIncoming chan networkWire // channel for processing incoming decoded packets by workers
)
// initNetwork sets up the network configuration and starts listening. // initNetwork sets up the network configuration and starts listening.
func initNetwork() { func initNetwork() {
rawPacketsIncoming = make(chan networkWire, 1000) // buffer up to 1000 UDP packets before they get buffered by the OS network stack and eventually dropped rand.Seed(time.Now().UnixNano()) // we are not using "crypto/rand" for speed tradeoff
rand.Seed(time.Now().UnixNano()) // we are not using "crypto/rand" for speed tradeoff
// start listen workers
if config.ListenWorkers == 0 { if config.ListenWorkers == 0 {
config.ListenWorkers = 2 config.ListenWorkers = 2
} }
for n := 0; n < config.ListenWorkers; n++ { for n := 0; n < config.ListenWorkers; n++ {
go packetWorker(rawPacketsIncoming) go networks.packetWorker()
} }
// check if user specified where to listen // check if user specified where to listen
@@ -110,7 +106,7 @@ func (nets *Networks) InterfaceStart(iface net.Interface, addresses []net.Addr)
continue continue
} }
networkNew, err := networks.PrepareListen(net1.IP.String(), 0) networkNew, err := nets.PrepareListen(net1.IP.String(), 0)
if err != nil { if err != nil {
// Do not log common errors: // Do not log common errors:
@@ -124,7 +120,7 @@ func (nets *Networks) InterfaceStart(iface net.Interface, addresses []net.Addr)
continue continue
} }
networks.ipListen.Add(networkNew.address) nets.ipListen.Add(networkNew.address)
Filters.LogError("networks.InterfaceStart", "listen on network '%s' UDP %s\n", iface.Name, networkNew.address.String()) Filters.LogError("networks.InterfaceStart", "listen on network '%s' UDP %s\n", iface.Name, networkNew.address.String())
@@ -141,7 +137,7 @@ func (nets *Networks) PrepareListen(ipA string, port int) (network *Network, err
return nil, errors.New("invalid input IP") return nil, errors.New("invalid input IP")
} }
network = new(Network) network = &Network{networkGroup: nets}
network.terminateSignal = make(chan interface{}) network.terminateSignal = make(chan interface{})
// get the network interface that belongs to the IP // get the network interface that belongs to the IP
@@ -157,16 +153,16 @@ func (nets *Networks) PrepareListen(ipA string, port int) (network *Network, err
return nil, err return nil, err
} }
networksMutex.Lock() nets.Lock()
// Success - port is open. Add to the list and start accepting incoming messages. // Success - port is open. Add to the list and start accepting incoming messages.
if IsIPv4(ip) { if IsIPv4(ip) {
networks4 = append(networks4, network) nets.networks4 = append(nets.networks4, network)
networksMutex.Unlock() nets.Unlock()
network.BroadcastIPv4() network.BroadcastIPv4()
} else { } else {
networks6 = append(networks6, network) nets.networks6 = append(nets.networks6, network)
networksMutex.Unlock() nets.Unlock()
network.MulticastIPv6Join() network.MulticastIPv6Join()
} }

View File

@@ -20,7 +20,7 @@ import (
var upnpListInterfaces map[string]struct{} var upnpListInterfaces map[string]struct{}
var upnpMutex sync.RWMutex var upnpMutex sync.RWMutex
func startUPnP() { func (nets *Networks) startUPnP() {
upnpListInterfaces = make(map[string]struct{}) upnpListInterfaces = make(map[string]struct{})
for _, cidr := range []string{ for _, cidr := range []string{
@@ -40,7 +40,7 @@ func startUPnP() {
return return
} }
for _, network := range networks4 { for _, network := range nets.networks4 {
go network.upnpAuto() go network.upnpAuto()
} }
} }

View File

@@ -34,18 +34,9 @@ type Network struct {
isTerminated bool // If true, the network was signaled for termination isTerminated bool // If true, the network was signaled for termination
terminateSignal chan interface{} // gets closed on termination signal, can be used in select via "case _ = <- network.terminateSignal:" terminateSignal chan interface{} // gets closed on termination signal, can be used in select via "case _ = <- network.terminateSignal:"
sync.RWMutex // for sychronized closing sync.RWMutex // for sychronized closing
networkGroup *Networks // Pointer to the pool of networks that this is part of
} }
// networks is a list of all connected networks
var networks4, networks6 []*Network
// single mutex for both network lists. Higher granularity currently not needed.
var networksMutex sync.RWMutex
// countListenX is the number of networks listened to, excluding link-local only listeners. This number might be different than len(networksN).
// This is useful to determine if there are any IPv4 or IPv6 listeners for potential external connections. This can be used to determine IPv4_LISTEN and IPv6_LISTEN.
var countListen4, countListen6 int64
// Default ports to use. This may be randomized in the future to prevent fingerprinting (and subsequent blocking) by corporate and ISP firewalls. // Default ports to use. This may be randomized in the future to prevent fingerprinting (and subsequent blocking) by corporate and ISP firewalls.
const defaultPort = 'p' // 112 const defaultPort = 'p' // 112
@@ -106,9 +97,9 @@ const maxPacketSize = 65536
func (network *Network) Listen() { func (network *Network) Listen() {
if !network.address.IP.IsLinkLocalUnicast() { if !network.address.IP.IsLinkLocalUnicast() {
if IsIPv4(network.address.IP) { if IsIPv4(network.address.IP) {
atomic.AddInt64(&countListen4, 1) atomic.AddInt64(&network.networkGroup.countListen4, 1)
} else { } else {
atomic.AddInt64(&countListen6, 1) atomic.AddInt64(&network.networkGroup.countListen6, 1)
} }
} }
@@ -135,13 +126,13 @@ func (network *Network) Listen() {
} }
// send the packet to a channel which is processed by multiple workers. // send the packet to a channel which is processed by multiple workers.
rawPacketsIncoming <- networkWire{network: network, sender: sender, raw: buffer[:length], receiverPublicKey: peerPublicKey, unicast: true} network.networkGroup.rawPacketsIncoming <- networkWire{network: network, sender: sender, raw: buffer[:length], receiverPublicKey: peerPublicKey, unicast: true}
} }
} }
// packetWorker handles incoming packets. // packetWorker handles incoming packets.
func packetWorker(packets <-chan networkWire) { func (nets *Networks) packetWorker() {
for packet := range packets { for packet := range nets.rawPacketsIncoming {
decoded, senderPublicKey, err := protocol.PacketDecrypt(packet.raw, packet.receiverPublicKey) decoded, senderPublicKey, err := protocol.PacketDecrypt(packet.raw, packet.receiverPublicKey)
if err != nil { if err != nil {
//Filters.LogError("packetWorker", "decrypting packet from '%s': %s\n", packet.sender.String(), err.Error()) // Only log for debug purposes. //Filters.LogError("packetWorker", "decrypting packet from '%s': %s\n", packet.sender.String(), err.Error()) // Only log for debug purposes.
@@ -195,7 +186,7 @@ func packetWorker(packets <-chan networkWire) {
case protocol.CommandResponse: // Response case protocol.CommandResponse: // Response
if response, _ := msgDecodeResponse(raw); response != nil { if response, _ := msgDecodeResponse(raw); response != nil {
// Validate sequence number which prevents unsolicited responses. // Validate sequence number which prevents unsolicited responses.
if valid, rtt := networks.Sequences.ValidateSequence(raw, response.Actions&(1<<ActionSequenceLast) > 0); !valid { if valid, rtt := nets.Sequences.ValidateSequence(raw, response.Actions&(1<<ActionSequenceLast) > 0); !valid {
//Filters.LogError("packetWorker", "message with invalid sequence %d command %d from %s\n", raw.Sequence, raw.Command, raw.connection.Address.String()) // Only log for debug purposes. //Filters.LogError("packetWorker", "message with invalid sequence %d command %d from %s\n", raw.Sequence, raw.Command, raw.connection.Address.String()) // Only log for debug purposes.
continue continue
} else if rtt > 0 { } else if rtt > 0 {
@@ -237,7 +228,7 @@ func packetWorker(packets <-chan networkWire) {
case protocol.CommandPong: // Ping case protocol.CommandPong: // Ping
// Validate sequence number which prevents unsolicited responses. // Validate sequence number which prevents unsolicited responses.
if valid, rtt := networks.Sequences.ValidateSequence(raw, true); !valid { if valid, rtt := nets.Sequences.ValidateSequence(raw, true); !valid {
//Filters.LogError("packetWorker", "message with invalid sequence %d command %d from %s\n", raw.Sequence, raw.Command, raw.connection.Address.String()) // Only log for debug purposes. //Filters.LogError("packetWorker", "message with invalid sequence %d command %d from %s\n", raw.Sequence, raw.Command, raw.connection.Address.String()) // Only log for debug purposes.
continue continue
} else if rtt > 0 { } else if rtt > 0 {
@@ -271,12 +262,12 @@ func packetWorker(packets <-chan networkWire) {
} }
// GetNetworks returns the list of connected networks // GetNetworks returns the list of connected networks
func GetNetworks(networkType int) (networks []*Network) { func GetNetworks(networkType int) (networksConnected []*Network) {
switch networkType { switch networkType {
case 4: case 4:
return networks4 return networks.networks4
case 6: case 6:
return networks6 return networks.networks6
} }
return nil return nil
} }
@@ -305,9 +296,9 @@ func (network *Network) Terminate() {
if !network.address.IP.IsLinkLocalUnicast() { if !network.address.IP.IsLinkLocalUnicast() {
if IsIPv4(network.address.IP) { if IsIPv4(network.address.IP) {
atomic.AddInt64(&countListen4, -1) atomic.AddInt64(&network.networkGroup.countListen4, -1)
} else { } else {
atomic.AddInt64(&countListen6, -1) atomic.AddInt64(&network.networkGroup.countListen6, -1)
} }
} }
@@ -316,7 +307,7 @@ func (network *Network) Terminate() {
close(network.terminateSignal) // safety guaranteed via lock close(network.terminateSignal) // safety guaranteed via lock
network.socket.Close() // Will stop the listener from blocking on network.socket.ReadFromUDP network.socket.Close() // Will stop the listener from blocking on network.socket.ReadFromUDP
networks.ipListen.Remove(network.address) network.networkGroup.ipListen.Remove(network.address)
} }
// SelfReportedPorts returns the internal and external ports as self-reported by the peer to others. // SelfReportedPorts returns the internal and external ports as self-reported by the peer to others.
@@ -341,10 +332,10 @@ func (network *Network) SelfReportedPorts() (portI, portE uint16) {
// FeatureSupport returns supported features by this peer // FeatureSupport returns supported features by this peer
func FeatureSupport() (feature byte) { func FeatureSupport() (feature byte) {
if countListen4 > 0 { if networks.countListen4 > 0 {
feature |= 1 << FeatureIPv4Listen feature |= 1 << FeatureIPv4Listen
} }
if countListen6 > 0 { if networks.countListen6 > 0 {
feature |= 1 << FeatureIPv6Listen feature |= 1 << FeatureIPv6Listen
} }
return feature return feature

View File

@@ -6,18 +6,22 @@ Author: Peter Kleissner
package core package core
import "sync"
// Networks is the collection of all connected networks // Networks is the collection of all connected networks
type Networks struct { type Networks struct {
// networks is a list of all connected networks // networks is a list of all connected networks
//networks4, networks6 []*Network networks4, networks6 []*Network
// Mutex for both network lists. Higher granularity currently not needed. // Mutex for both network lists. Higher granularity currently not needed.
//sync.RWMutex sync.RWMutex
//networksMutex sync.RWMutex
// countListenX is the number of networks listened to, excluding link-local only listeners. This number might be different than len(networksN). // countListenX is the number of networks listened to, excluding link-local only listeners. This number might be different than len(networksN).
// This is useful to determine if there are any IPv4 or IPv6 listeners for potential external connections. This can be used to determine IPv4_LISTEN and IPv6_LISTEN. // This is useful to determine if there are any IPv4 or IPv6 listeners for potential external connections. This can be used to determine IPv4_LISTEN and IPv6_LISTEN.
//countListen4, countListen6 int64 countListen4, countListen6 int64
// channel for processing incoming decoded packets by workers, across all networks
rawPacketsIncoming chan networkWire
// Sequences keeps track of all message sequence number, regardless of the network connection. // Sequences keeps track of all message sequence number, regardless of the network connection.
Sequences *SequenceManager Sequences *SequenceManager
@@ -34,6 +38,8 @@ var networks *Networks
func initMessageSequence() { func initMessageSequence() {
networks = &Networks{} networks = &Networks{}
networks.rawPacketsIncoming = make(chan networkWire, 1000) // buffer up to 1000 UDP packets before they get buffered by the OS network stack and eventually dropped
networks.Sequences = NewSequenceManager(ReplyTimeout) networks.Sequences = NewSequenceManager(ReplyTimeout)
networks.ipListen = NewIPList() networks.ipListen = NewIPList()

View File

@@ -25,9 +25,9 @@ func Init() {
func Connect() { func Connect() {
go bootstrapKademlia() go bootstrapKademlia()
go bootstrap() go bootstrap()
go autoMulticastBroadcast() go networks.autoMulticastBroadcast()
go autoPingAll() go autoPingAll()
go networkChangeMonitor() go networks.networkChangeMonitor()
go networks.startUPnP()
go autoBucketRefresh() go autoBucketRefresh()
go startUPnP()
} }