OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / github.com / grandcat / zeroconf / connection.go
diff --git a/vendor/github.com/grandcat/zeroconf/connection.go b/vendor/github.com/grandcat/zeroconf/connection.go
new file mode 100644 (file)
index 0000000..598dbb9
--- /dev/null
@@ -0,0 +1,115 @@
+package zeroconf
+
+import (
+       "fmt"
+       "net"
+
+       "golang.org/x/net/ipv4"
+       "golang.org/x/net/ipv6"
+)
+
+var (
+       // Multicast groups used by mDNS
+       mdnsGroupIPv4 = net.IPv4(224, 0, 0, 251)
+       mdnsGroupIPv6 = net.ParseIP("ff02::fb")
+
+       // mDNS wildcard addresses
+       mdnsWildcardAddrIPv4 = &net.UDPAddr{
+               IP:   net.ParseIP("224.0.0.0"),
+               Port: 5353,
+       }
+       mdnsWildcardAddrIPv6 = &net.UDPAddr{
+               IP: net.ParseIP("ff02::"),
+               // IP:   net.ParseIP("fd00::12d3:26e7:48db:e7d"),
+               Port: 5353,
+       }
+
+       // mDNS endpoint addresses
+       ipv4Addr = &net.UDPAddr{
+               IP:   mdnsGroupIPv4,
+               Port: 5353,
+       }
+       ipv6Addr = &net.UDPAddr{
+               IP:   mdnsGroupIPv6,
+               Port: 5353,
+       }
+)
+
+func joinUdp6Multicast(interfaces []net.Interface) (*ipv6.PacketConn, error) {
+       udpConn, err := net.ListenUDP("udp6", mdnsWildcardAddrIPv6)
+       if err != nil {
+               return nil, err
+       }
+
+       // Join multicast groups to receive announcements
+       pkConn := ipv6.NewPacketConn(udpConn)
+       pkConn.SetControlMessage(ipv6.FlagInterface, true)
+
+       if len(interfaces) == 0 {
+               interfaces = listMulticastInterfaces()
+       }
+       // log.Println("Using multicast interfaces: ", interfaces)
+
+       var failedJoins int
+       for _, iface := range interfaces {
+               if err := pkConn.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv6}); err != nil {
+                       // log.Println("Udp6 JoinGroup failed for iface ", iface)
+                       failedJoins++
+               }
+       }
+       if failedJoins == len(interfaces) {
+               pkConn.Close()
+               return nil, fmt.Errorf("udp6: failed to join any of these interfaces: %v", interfaces)
+       }
+
+       return pkConn, nil
+}
+
+func joinUdp4Multicast(interfaces []net.Interface) (*ipv4.PacketConn, error) {
+       udpConn, err := net.ListenUDP("udp4", mdnsWildcardAddrIPv4)
+       if err != nil {
+               // log.Printf("[ERR] bonjour: Failed to bind to udp4 mutlicast: %v", err)
+               return nil, err
+       }
+
+       // Join multicast groups to receive announcements
+       pkConn := ipv4.NewPacketConn(udpConn)
+       pkConn.SetControlMessage(ipv4.FlagInterface, true)
+
+       if len(interfaces) == 0 {
+               interfaces = listMulticastInterfaces()
+       }
+       // log.Println("Using multicast interfaces: ", interfaces)
+
+       var failedJoins int
+       for _, iface := range interfaces {
+               if err := pkConn.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv4}); err != nil {
+                       // log.Println("Udp4 JoinGroup failed for iface ", iface)
+                       failedJoins++
+               }
+       }
+       if failedJoins == len(interfaces) {
+               pkConn.Close()
+               return nil, fmt.Errorf("udp4: failed to join any of these interfaces: %v", interfaces)
+       }
+
+       return pkConn, nil
+}
+
+func listMulticastInterfaces() []net.Interface {
+       var interfaces []net.Interface
+       ifaces, err := net.Interfaces()
+       if err != nil {
+               return nil
+       }
+       for _, ifi := range ifaces {
+               if (ifi.Flags & net.FlagUp) == 0 {
+                       continue
+               }
+               if (ifi.Flags & net.FlagMulticast) > 0 {
+                       interfaces = append(interfaces, ifi)
+               }
+       }
+
+       return interfaces
+}