~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/net/lookup_windows.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
import (
8
8
        "os"
9
 
        "sync"
 
9
        "runtime"
10
10
        "syscall"
11
11
        "unsafe"
12
12
)
13
13
 
14
14
var (
15
 
        protoentLock sync.Mutex
16
 
        hostentLock  sync.Mutex
17
 
        serventLock  sync.Mutex
 
15
        lookupPort = oldLookupPort
 
16
        lookupIP   = oldLookupIP
18
17
)
19
18
 
20
 
// lookupProtocol looks up IP protocol name and returns correspondent protocol number.
21
 
func lookupProtocol(name string) (proto int, err error) {
22
 
        protoentLock.Lock()
23
 
        defer protoentLock.Unlock()
 
19
func getprotobyname(name string) (proto int, err error) {
24
20
        p, err := syscall.GetProtoByName(name)
25
21
        if err != nil {
26
22
                return 0, os.NewSyscallError("GetProtoByName", err)
28
24
        return int(p.Proto), nil
29
25
}
30
26
 
 
27
// lookupProtocol looks up IP protocol name and returns correspondent protocol number.
 
28
func lookupProtocol(name string) (proto int, err error) {
 
29
        // GetProtoByName return value is stored in thread local storage.
 
30
        // Start new os thread before the call to prevent races.
 
31
        type result struct {
 
32
                proto int
 
33
                err   error
 
34
        }
 
35
        ch := make(chan result)
 
36
        go func() {
 
37
                runtime.LockOSThread()
 
38
                defer runtime.UnlockOSThread()
 
39
                proto, err := getprotobyname(name)
 
40
                ch <- result{proto: proto, err: err}
 
41
        }()
 
42
        r := <-ch
 
43
        return r.proto, r.err
 
44
}
 
45
 
31
46
func lookupHost(name string) (addrs []string, err error) {
32
47
        ips, err := LookupIP(name)
33
48
        if err != nil {
40
55
        return
41
56
}
42
57
 
43
 
func lookupIP(name string) (addrs []IP, err error) {
44
 
        hostentLock.Lock()
45
 
        defer hostentLock.Unlock()
 
58
func gethostbyname(name string) (addrs []IP, err error) {
46
59
        h, err := syscall.GetHostByName(name)
47
60
        if err != nil {
48
61
                return nil, os.NewSyscallError("GetHostByName", err)
56
69
                }
57
70
                addrs = addrs[0:i]
58
71
        default: // TODO(vcc): Implement non IPv4 address lookups.
59
 
                return nil, os.NewSyscallError("LookupHost", syscall.EWINDOWS)
60
 
        }
61
 
        return addrs, nil
62
 
}
63
 
 
64
 
func lookupPort(network, service string) (port int, err error) {
 
72
                return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
 
73
        }
 
74
        return addrs, nil
 
75
}
 
76
 
 
77
func oldLookupIP(name string) (addrs []IP, err error) {
 
78
        // GetHostByName return value is stored in thread local storage.
 
79
        // Start new os thread before the call to prevent races.
 
80
        type result struct {
 
81
                addrs []IP
 
82
                err   error
 
83
        }
 
84
        ch := make(chan result)
 
85
        go func() {
 
86
                runtime.LockOSThread()
 
87
                defer runtime.UnlockOSThread()
 
88
                addrs, err := gethostbyname(name)
 
89
                ch <- result{addrs: addrs, err: err}
 
90
        }()
 
91
        r := <-ch
 
92
        return r.addrs, r.err
 
93
}
 
94
 
 
95
func newLookupIP(name string) (addrs []IP, err error) {
 
96
        hints := syscall.AddrinfoW{
 
97
                Family:   syscall.AF_UNSPEC,
 
98
                Socktype: syscall.SOCK_STREAM,
 
99
                Protocol: syscall.IPPROTO_IP,
 
100
        }
 
101
        var result *syscall.AddrinfoW
 
102
        e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result)
 
103
        if e != nil {
 
104
                return nil, os.NewSyscallError("GetAddrInfoW", e)
 
105
        }
 
106
        defer syscall.FreeAddrInfoW(result)
 
107
        addrs = make([]IP, 0, 5)
 
108
        for ; result != nil; result = result.Next {
 
109
                addr := unsafe.Pointer(result.Addr)
 
110
                switch result.Family {
 
111
                case syscall.AF_INET:
 
112
                        a := (*syscall.RawSockaddrInet4)(addr).Addr
 
113
                        addrs = append(addrs, IPv4(a[0], a[1], a[2], a[3]))
 
114
                case syscall.AF_INET6:
 
115
                        a := (*syscall.RawSockaddrInet6)(addr).Addr
 
116
                        addrs = append(addrs, IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]})
 
117
                default:
 
118
                        return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
 
119
                }
 
120
        }
 
121
        return addrs, nil
 
122
}
 
123
 
 
124
func getservbyname(network, service string) (port int, err error) {
65
125
        switch network {
66
126
        case "tcp4", "tcp6":
67
127
                network = "tcp"
68
128
        case "udp4", "udp6":
69
129
                network = "udp"
70
130
        }
71
 
        serventLock.Lock()
72
 
        defer serventLock.Unlock()
73
131
        s, err := syscall.GetServByName(service, network)
74
132
        if err != nil {
75
133
                return 0, os.NewSyscallError("GetServByName", err)
77
135
        return int(syscall.Ntohs(s.Port)), nil
78
136
}
79
137
 
 
138
func oldLookupPort(network, service string) (port int, err error) {
 
139
        // GetServByName return value is stored in thread local storage.
 
140
        // Start new os thread before the call to prevent races.
 
141
        type result struct {
 
142
                port int
 
143
                err  error
 
144
        }
 
145
        ch := make(chan result)
 
146
        go func() {
 
147
                runtime.LockOSThread()
 
148
                defer runtime.UnlockOSThread()
 
149
                port, err := getservbyname(network, service)
 
150
                ch <- result{port: port, err: err}
 
151
        }()
 
152
        r := <-ch
 
153
        return r.port, r.err
 
154
}
 
155
 
 
156
func newLookupPort(network, service string) (port int, err error) {
 
157
        var stype int32
 
158
        switch network {
 
159
        case "tcp4", "tcp6":
 
160
                stype = syscall.SOCK_STREAM
 
161
        case "udp4", "udp6":
 
162
                stype = syscall.SOCK_DGRAM
 
163
        }
 
164
        hints := syscall.AddrinfoW{
 
165
                Family:   syscall.AF_UNSPEC,
 
166
                Socktype: stype,
 
167
                Protocol: syscall.IPPROTO_IP,
 
168
        }
 
169
        var result *syscall.AddrinfoW
 
170
        e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
 
171
        if e != nil {
 
172
                return 0, os.NewSyscallError("GetAddrInfoW", e)
 
173
        }
 
174
        defer syscall.FreeAddrInfoW(result)
 
175
        if result == nil {
 
176
                return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
 
177
        }
 
178
        addr := unsafe.Pointer(result.Addr)
 
179
        switch result.Family {
 
180
        case syscall.AF_INET:
 
181
                a := (*syscall.RawSockaddrInet4)(addr)
 
182
                return int(syscall.Ntohs(a.Port)), nil
 
183
        case syscall.AF_INET6:
 
184
                a := (*syscall.RawSockaddrInet6)(addr)
 
185
                return int(syscall.Ntohs(a.Port)), nil
 
186
        }
 
187
        return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
 
188
}
 
189
 
80
190
func lookupCNAME(name string) (cname string, err error) {
81
191
        var r *syscall.DNSRecord
82
192
        e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &r, nil)
129
239
        return mx, nil
130
240
}
131
241
 
 
242
func lookupNS(name string) (ns []*NS, err error) {
 
243
        var r *syscall.DNSRecord
 
244
        e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil)
 
245
        if e != nil {
 
246
                return nil, os.NewSyscallError("LookupNS", e)
 
247
        }
 
248
        defer syscall.DnsRecordListFree(r, 1)
 
249
        ns = make([]*NS, 0, 10)
 
250
        for p := r; p != nil && p.Type == syscall.DNS_TYPE_NS; p = p.Next {
 
251
                v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
 
252
                ns = append(ns, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."})
 
253
        }
 
254
        return ns, nil
 
255
}
 
256
 
132
257
func lookupTXT(name string) (txt []string, err error) {
133
258
        var r *syscall.DNSRecord
134
259
        e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)