mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-16 18:37:51 +01:00
Termination of networks upon removal of their network adapter.
This commit is contained in:
@@ -170,22 +170,41 @@ func networkChangeMonitor() {
|
||||
|
||||
// networkChangeInterfaceNew is called when a new interface is detected
|
||||
func networkChangeInterfaceNew(iface net.Interface, addresses []net.Addr) {
|
||||
fmt.Printf("Interface new: %s\n", iface.Name)
|
||||
log.Printf("networkChangeInterfaceNew new interface '%s' (%d IPs)\n", iface.Name, len(addresses))
|
||||
|
||||
for _, addr := range addresses {
|
||||
fmt.Printf(" IP: %s\n", addr.String())
|
||||
}
|
||||
}
|
||||
|
||||
// networkChangeInterfaceRemove is called when an existing interface is removed
|
||||
func networkChangeInterfaceRemove(iface string, addresses []net.Addr) {
|
||||
//networksMutex.RLock()
|
||||
//defer networksMutex.RUnlock()
|
||||
networksMutex.RLock()
|
||||
defer networksMutex.RUnlock()
|
||||
|
||||
fmt.Printf("Interface removed: %s\n", iface)
|
||||
log.Printf("networkChangeInterfaceRemove removing interface '%s' (%d IPs)\n", iface, len(addresses))
|
||||
|
||||
for _, addr := range addresses {
|
||||
fmt.Printf(" IP: %s\n", addr.String())
|
||||
for n, network := range networks6 {
|
||||
if network.iface != nil && network.iface.Name == iface {
|
||||
network.Terminate()
|
||||
|
||||
// remove from list
|
||||
networksNew := networks6[:n]
|
||||
if n < len(networks6)-1 {
|
||||
networksNew = append(networksNew, networks6[n+1:]...)
|
||||
}
|
||||
networks6 = networksNew
|
||||
}
|
||||
}
|
||||
|
||||
for n, network := range networks4 {
|
||||
if network.iface != nil && network.iface.Name == iface {
|
||||
network.Terminate()
|
||||
|
||||
// remove from list
|
||||
networksNew := networks4[:n]
|
||||
if n < len(networks4)-1 {
|
||||
networksNew = append(networksNew, networks4[n+1:]...)
|
||||
}
|
||||
networks4 = networksNew
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ func networkPrepareListen(ipA string, port int) (network *Network, err error) {
|
||||
}
|
||||
|
||||
network = new(Network)
|
||||
network.terminateSignal = make(chan interface{})
|
||||
|
||||
// get the network interface that belongs to the IP
|
||||
if ipA != "0.0.0.0" && ipA != "::" {
|
||||
|
||||
41
Network.go
41
Network.go
@@ -18,14 +18,17 @@ import (
|
||||
// Network is a connection adapter through one network interface (adapter).
|
||||
// Note that for each IP on the same adapter separate network entries are created.
|
||||
type Network struct {
|
||||
iface *net.Interface // Network interface belonging to the IP. May not be set.
|
||||
ipnet *net.IPNet // IP network the listening address belongs to. May not be set.
|
||||
address *net.UDPAddr // IP:Port where the server listens
|
||||
socket *net.UDPConn // active socket for send/receive
|
||||
multicastIP net.IP // Multicast IP, IPv6 only.
|
||||
multicastSocket net.PacketConn // Multicast socket, IPv6 only.
|
||||
broadcastSocket net.PacketConn // Broadcast socket, IPv4 only.
|
||||
broadcastIPv4 []net.IP // Broadcast IPs, IPv4 only.
|
||||
iface *net.Interface // Network interface belonging to the IP. May not be set.
|
||||
ipnet *net.IPNet // IP network the listening address belongs to. May not be set.
|
||||
address *net.UDPAddr // IP:Port where the server listens
|
||||
socket *net.UDPConn // active socket for send/receive
|
||||
multicastIP net.IP // Multicast IP, IPv6 only.
|
||||
multicastSocket net.PacketConn // Multicast socket, IPv6 only.
|
||||
broadcastSocket net.PacketConn // Broadcast socket, IPv4 only.
|
||||
broadcastIPv4 []net.IP // Broadcast IPs, IPv4 only.
|
||||
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:"
|
||||
sync.RWMutex // for sychronized closing
|
||||
}
|
||||
|
||||
// networks is a list of all connected networks
|
||||
@@ -92,13 +95,18 @@ const maxPacketSize = 4096
|
||||
|
||||
// Listen starts listening for incoming packets on the given UDP connection
|
||||
func (network *Network) Listen() {
|
||||
for {
|
||||
for !network.isTerminated {
|
||||
// Buffer: Must be created for each packet as it is passed as pointer.
|
||||
// If the buffer is too small, ReadFromUDP only reads until its length and returns this error: "wsarecvfrom: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself."
|
||||
buffer := make([]byte, maxPacketSize)
|
||||
length, sender, err := network.socket.ReadFromUDP(buffer)
|
||||
|
||||
if err != nil {
|
||||
// Exit on closed socket. Error will be "use of closed network connection".
|
||||
if network.isTerminated {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Listen Error receiving UDP message: %v\n", err) // Only log for debug purposes.
|
||||
time.Sleep(time.Millisecond * 50) // In case of endless errors, prevent ddos of CPU.
|
||||
continue
|
||||
@@ -193,3 +201,18 @@ func (network *Network) GetAdapterName() string {
|
||||
}
|
||||
return "[unknown adapter]"
|
||||
}
|
||||
|
||||
// Terminate sends the termination signal to all workers. It is safe to call Terminate multiple times.
|
||||
func (network *Network) Terminate() {
|
||||
network.Lock()
|
||||
defer network.Unlock()
|
||||
|
||||
if network.isTerminated {
|
||||
return
|
||||
}
|
||||
|
||||
// set the termination signal
|
||||
network.isTerminated = true
|
||||
close(network.terminateSignal) // safety guaranteed via lock
|
||||
network.socket.Close() // Will stop the listener from blocking on network.socket.ReadFromUDP
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user