diff --git a/unum/vendor/golang.org/x/net/internal/socket/sys_posix.go b/unum/vendor/golang.org/x/net/internal/socket/sys_posix.go
new file mode 100644
index 0000000..9a0dbcf
--- /dev/null
+++ b/unum/vendor/golang.org/x/net/internal/socket/sys_posix.go
@@ -0,0 +1,168 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.9
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package socket
+
+import (
+	"encoding/binary"
+	"errors"
+	"net"
+	"runtime"
+	"strconv"
+	"sync"
+	"time"
+)
+
+func marshalInetAddr(a net.Addr) []byte {
+	switch a := a.(type) {
+	case *net.TCPAddr:
+		return marshalSockaddr(a.IP, a.Port, a.Zone)
+	case *net.UDPAddr:
+		return marshalSockaddr(a.IP, a.Port, a.Zone)
+	case *net.IPAddr:
+		return marshalSockaddr(a.IP, 0, a.Zone)
+	default:
+		return nil
+	}
+}
+
+func marshalSockaddr(ip net.IP, port int, zone string) []byte {
+	if ip4 := ip.To4(); ip4 != nil {
+		b := make([]byte, sizeofSockaddrInet)
+		switch runtime.GOOS {
+		case "linux", "solaris", "windows":
+			NativeEndian.PutUint16(b[:2], uint16(sysAF_INET))
+		default:
+			b[0] = sizeofSockaddrInet
+			b[1] = sysAF_INET
+		}
+		binary.BigEndian.PutUint16(b[2:4], uint16(port))
+		copy(b[4:8], ip4)
+		return b
+	}
+	if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
+		b := make([]byte, sizeofSockaddrInet6)
+		switch runtime.GOOS {
+		case "linux", "solaris", "windows":
+			NativeEndian.PutUint16(b[:2], uint16(sysAF_INET6))
+		default:
+			b[0] = sizeofSockaddrInet6
+			b[1] = sysAF_INET6
+		}
+		binary.BigEndian.PutUint16(b[2:4], uint16(port))
+		copy(b[8:24], ip6)
+		if zone != "" {
+			NativeEndian.PutUint32(b[24:28], uint32(zoneCache.index(zone)))
+		}
+		return b
+	}
+	return nil
+}
+
+func parseInetAddr(b []byte, network string) (net.Addr, error) {
+	if len(b) < 2 {
+		return nil, errors.New("invalid address")
+	}
+	var af int
+	switch runtime.GOOS {
+	case "linux", "solaris", "windows":
+		af = int(NativeEndian.Uint16(b[:2]))
+	default:
+		af = int(b[1])
+	}
+	var ip net.IP
+	var zone string
+	if af == sysAF_INET {
+		if len(b) < sizeofSockaddrInet {
+			return nil, errors.New("short address")
+		}
+		ip = make(net.IP, net.IPv4len)
+		copy(ip, b[4:8])
+	}
+	if af == sysAF_INET6 {
+		if len(b) < sizeofSockaddrInet6 {
+			return nil, errors.New("short address")
+		}
+		ip = make(net.IP, net.IPv6len)
+		copy(ip, b[8:24])
+		if id := int(NativeEndian.Uint32(b[24:28])); id > 0 {
+			zone = zoneCache.name(id)
+		}
+	}
+	switch network {
+	case "tcp", "tcp4", "tcp6":
+		return &net.TCPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil
+	case "udp", "udp4", "udp6":
+		return &net.UDPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil
+	default:
+		return &net.IPAddr{IP: ip, Zone: zone}, nil
+	}
+}
+
+// An ipv6ZoneCache represents a cache holding partial network
+// interface information. It is used for reducing the cost of IPv6
+// addressing scope zone resolution.
+//
+// Multiple names sharing the index are managed by first-come
+// first-served basis for consistency.
+type ipv6ZoneCache struct {
+	sync.RWMutex                // guard the following
+	lastFetched  time.Time      // last time routing information was fetched
+	toIndex      map[string]int // interface name to its index
+	toName       map[int]string // interface index to its name
+}
+
+var zoneCache = ipv6ZoneCache{
+	toIndex: make(map[string]int),
+	toName:  make(map[int]string),
+}
+
+func (zc *ipv6ZoneCache) update(ift []net.Interface) {
+	zc.Lock()
+	defer zc.Unlock()
+	now := time.Now()
+	if zc.lastFetched.After(now.Add(-60 * time.Second)) {
+		return
+	}
+	zc.lastFetched = now
+	if len(ift) == 0 {
+		var err error
+		if ift, err = net.Interfaces(); err != nil {
+			return
+		}
+	}
+	zc.toIndex = make(map[string]int, len(ift))
+	zc.toName = make(map[int]string, len(ift))
+	for _, ifi := range ift {
+		zc.toIndex[ifi.Name] = ifi.Index
+		if _, ok := zc.toName[ifi.Index]; !ok {
+			zc.toName[ifi.Index] = ifi.Name
+		}
+	}
+}
+
+func (zc *ipv6ZoneCache) name(zone int) string {
+	zoneCache.update(nil)
+	zoneCache.RLock()
+	defer zoneCache.RUnlock()
+	name, ok := zoneCache.toName[zone]
+	if !ok {
+		name = strconv.Itoa(zone)
+	}
+	return name
+}
+
+func (zc *ipv6ZoneCache) index(zone string) int {
+	zoneCache.update(nil)
+	zoneCache.RLock()
+	defer zoneCache.RUnlock()
+	index, ok := zoneCache.toIndex[zone]
+	if !ok {
+		index, _ = strconv.Atoi(zone)
+	}
+	return index
+}
