OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [cgo_unix.go] - Blame information for rev 748

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// +build darwin freebsd linux
6
 
7
package net
8
 
9
/*
10
#include 
11
#include 
12
#include 
13
#include 
14
#include 
15
#include 
16
#include 
17
*/
18
 
19
import (
20
        "syscall"
21
        "unsafe"
22
)
23
 
24
//extern getaddrinfo
25
func libc_getaddrinfo(node *byte, service *byte, hints *syscall.Addrinfo, res **syscall.Addrinfo) int
26
 
27
//extern freeaddrinfo
28
func libc_freeaddrinfo(res *syscall.Addrinfo)
29
 
30
//extern gai_strerror
31
func libc_gai_strerror(errcode int) *byte
32
 
33
// bytePtrToString takes a NUL-terminated array of bytes and convert
34
// it to a Go string.
35
func bytePtrToString(p *byte) string {
36
        a := (*[10000]byte)(unsafe.Pointer(p))
37
        i := 0
38
        for a[i] != 0 {
39
                i++
40
        }
41
        return string(a[:i])
42
}
43
 
44
func cgoLookupHost(name string) (addrs []string, err error, completed bool) {
45
        ip, err, completed := cgoLookupIP(name)
46
        for _, p := range ip {
47
                addrs = append(addrs, p.String())
48
        }
49
        return
50
}
51
 
52
func cgoLookupPort(net, service string) (port int, err error, completed bool) {
53
        var res *syscall.Addrinfo
54
        var hints syscall.Addrinfo
55
 
56
        switch net {
57
        case "":
58
                // no hints
59
        case "tcp", "tcp4", "tcp6":
60
                hints.Ai_socktype = syscall.SOCK_STREAM
61
                hints.Ai_protocol = syscall.IPPROTO_TCP
62
        case "udp", "udp4", "udp6":
63
                hints.Ai_socktype = syscall.SOCK_DGRAM
64
                hints.Ai_protocol = syscall.IPPROTO_UDP
65
        default:
66
                return 0, UnknownNetworkError(net), true
67
        }
68
        if len(net) >= 4 {
69
                switch net[3] {
70
                case '4':
71
                        hints.Ai_family = syscall.AF_INET
72
                case '6':
73
                        hints.Ai_family = syscall.AF_INET6
74
                }
75
        }
76
 
77
        s := syscall.StringBytePtr(service)
78
        if libc_getaddrinfo(nil, s, &hints, &res) == 0 {
79
                defer libc_freeaddrinfo(res)
80
                for r := res; r != nil; r = r.Ai_next {
81
                        switch r.Ai_family {
82
                        default:
83
                                continue
84
                        case syscall.AF_INET:
85
                                sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.Ai_addr))
86
                                p := (*[2]byte)(unsafe.Pointer(&sa.Port))
87
                                return int(p[0])<<8 | int(p[1]), nil, true
88
                        case syscall.AF_INET6:
89
                                sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.Ai_addr))
90
                                p := (*[2]byte)(unsafe.Pointer(&sa.Port))
91
                                return int(p[0])<<8 | int(p[1]), nil, true
92
                        }
93
                }
94
        }
95
        return 0, &AddrError{"unknown port", net + "/" + service}, true
96
}
97
 
98
func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err error, completed bool) {
99
        var res *syscall.Addrinfo
100
        var hints syscall.Addrinfo
101
 
102
        // NOTE(rsc): In theory there are approximately balanced
103
        // arguments for and against including AI_ADDRCONFIG
104
        // in the flags (it includes IPv4 results only on IPv4 systems,
105
        // and similarly for IPv6), but in practice setting it causes
106
        // getaddrinfo to return the wrong canonical name on Linux.
107
        // So definitely leave it out.
108
        hints.Ai_flags = int32((syscall.AI_ALL | syscall.AI_V4MAPPED | syscall.AI_CANONNAME) & cgoAddrInfoMask())
109
 
110
        h := syscall.StringBytePtr(name)
111
        gerrno := libc_getaddrinfo(h, nil, &hints, &res)
112
        if gerrno != 0 {
113
                var str string
114
                if gerrno == syscall.EAI_NONAME {
115
                        str = noSuchHost
116
                } else if gerrno == syscall.EAI_SYSTEM {
117
                        str = syscall.GetErrno().Error()
118
                } else {
119
                        str = bytePtrToString(libc_gai_strerror(gerrno))
120
                }
121
                return nil, "", &DNSError{Err: str, Name: name}, true
122
        }
123
        defer libc_freeaddrinfo(res)
124
        if res != nil {
125
                cname = bytePtrToString((*byte)(unsafe.Pointer(res.Ai_canonname)))
126
                if cname == "" {
127
                        cname = name
128
                }
129
                if len(cname) > 0 && cname[len(cname)-1] != '.' {
130
                        cname += "."
131
                }
132
        }
133
        for r := res; r != nil; r = r.Ai_next {
134
                // Everything comes back twice, once for UDP and once for TCP.
135
                if r.Ai_socktype != syscall.SOCK_STREAM {
136
                        continue
137
                }
138
                switch r.Ai_family {
139
                default:
140
                        continue
141
                case syscall.AF_INET:
142
                        sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.Ai_addr))
143
                        addrs = append(addrs, copyIP(sa.Addr[:]))
144
                case syscall.AF_INET6:
145
                        sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.Ai_addr))
146
                        addrs = append(addrs, copyIP(sa.Addr[:]))
147
                }
148
        }
149
        return addrs, cname, nil, true
150
}
151
 
152
func cgoLookupIP(name string) (addrs []IP, err error, completed bool) {
153
        addrs, _, err, completed = cgoLookupIPCNAME(name)
154
        return
155
}
156
 
157
func cgoLookupCNAME(name string) (cname string, err error, completed bool) {
158
        _, cname, err, completed = cgoLookupIPCNAME(name)
159
        return
160
}
161
 
162
func copyIP(x IP) IP {
163
        y := make(IP, len(x))
164
        copy(y, x)
165
        return y
166
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.