From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libgo/go/net/ipsock.go | 236 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 libgo/go/net/ipsock.go (limited to 'libgo/go/net/ipsock.go') diff --git a/libgo/go/net/ipsock.go b/libgo/go/net/ipsock.go new file mode 100644 index 000000000..4ba6a55b9 --- /dev/null +++ b/libgo/go/net/ipsock.go @@ -0,0 +1,236 @@ +// Copyright 2009 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. + +// IP sockets + +package net + +import ( + "os" + "syscall" +) + +// Should we try to use the IPv4 socket interface if we're +// only dealing with IPv4 sockets? As long as the host system +// understands IPv6, it's okay to pass IPv4 addresses to the IPv6 +// interface. That simplifies our code and is most general. +// Unfortunately, we need to run on kernels built without IPv6 support too. +// So probe the kernel to figure it out. +func kernelSupportsIPv6() bool { + // FreeBSD does not support this sort of interface. + if syscall.OS == "freebsd" { + return false + } + fd, e := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP) + if fd >= 0 { + closesocket(fd) + } + return e == 0 +} + +var preferIPv4 = !kernelSupportsIPv6() + +// TODO(rsc): if syscall.OS == "linux", we're supposd to read +// /proc/sys/net/core/somaxconn, +// to take advantage of kernels that have raised the limit. +func listenBacklog() int { return syscall.SOMAXCONN } + +// Internet sockets (TCP, UDP) + +// A sockaddr represents a TCP or UDP network address that can +// be converted into a syscall.Sockaddr. +type sockaddr interface { + Addr + sockaddr(family int) (syscall.Sockaddr, os.Error) + family() int +} + +func internetSocket(net string, laddr, raddr sockaddr, socktype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) { + // Figure out IP version. + // If network has a suffix like "tcp4", obey it. + var oserr os.Error + family := syscall.AF_INET6 + switch net[len(net)-1] { + case '4': + family = syscall.AF_INET + case '6': + // nothing to do + default: + // Otherwise, guess. + // If the addresses are IPv4 and we prefer IPv4, use 4; else 6. + if preferIPv4 && + (laddr == nil || laddr.family() == syscall.AF_INET) && + (raddr == nil || raddr.family() == syscall.AF_INET) { + family = syscall.AF_INET + } + } + + var la, ra syscall.Sockaddr + if laddr != nil { + if la, oserr = laddr.sockaddr(family); oserr != nil { + goto Error + } + } + if raddr != nil { + if ra, oserr = raddr.sockaddr(family); oserr != nil { + goto Error + } + } + fd, oserr = socket(net, family, socktype, proto, la, ra, toAddr) + if oserr != nil { + goto Error + } + return fd, nil + +Error: + addr := raddr + if mode == "listen" { + addr = laddr + } + return nil, &OpError{mode, net, addr, oserr} +} + +func getip(fd int, remote bool) (ip []byte, port int, ok bool) { + // No attempt at error reporting because + // there are no possible errors, and the + // caller won't report them anyway. + var sa syscall.Sockaddr + if remote { + sa, _ = syscall.Getpeername(fd) + } else { + sa, _ = syscall.Getsockname(fd) + } + switch sa := sa.(type) { + case *syscall.SockaddrInet4: + return sa.Addr[0:], sa.Port, true + case *syscall.SockaddrInet6: + return sa.Addr[0:], sa.Port, true + } + return +} + +type InvalidAddrError string + +func (e InvalidAddrError) String() string { return string(e) } +func (e InvalidAddrError) Timeout() bool { return false } +func (e InvalidAddrError) Temporary() bool { return false } + + +func ipToSockaddr(family int, ip IP, port int) (syscall.Sockaddr, os.Error) { + switch family { + case syscall.AF_INET: + if len(ip) == 0 { + ip = IPv4zero + } + if ip = ip.To4(); ip == nil { + return nil, InvalidAddrError("non-IPv4 address") + } + s := new(syscall.SockaddrInet4) + for i := 0; i < IPv4len; i++ { + s.Addr[i] = ip[i] + } + s.Port = port + return s, nil + case syscall.AF_INET6: + if len(ip) == 0 { + ip = IPzero + } + // IPv4 callers use 0.0.0.0 to mean "announce on any available address". + // In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0", + // which it refuses to do. Rewrite to the IPv6 all zeros. + if p4 := ip.To4(); p4 != nil && p4[0] == 0 && p4[1] == 0 && p4[2] == 0 && p4[3] == 0 { + ip = IPzero + } + if ip = ip.To16(); ip == nil { + return nil, InvalidAddrError("non-IPv6 address") + } + s := new(syscall.SockaddrInet6) + for i := 0; i < IPv6len; i++ { + s.Addr[i] = ip[i] + } + s.Port = port + return s, nil + } + return nil, InvalidAddrError("unexpected socket family") +} + +// Split "host:port" into "host" and "port". +// Host cannot contain colons unless it is bracketed. +func splitHostPort(hostport string) (host, port string, err os.Error) { + // The port starts after the last colon. + i := last(hostport, ':') + if i < 0 { + err = &AddrError{"missing port in address", hostport} + return + } + + host, port = hostport[0:i], hostport[i+1:] + + // Can put brackets around host ... + if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' { + host = host[1 : len(host)-1] + } else { + // ... but if there are no brackets, no colons. + if byteIndex(host, ':') >= 0 { + err = &AddrError{"too many colons in address", hostport} + return + } + } + return +} + +// Join "host" and "port" into "host:port". +// If host contains colons, will join into "[host]:port". +func joinHostPort(host, port string) string { + // If host has colons, have to bracket it. + if byteIndex(host, ':') >= 0 { + return "[" + host + "]:" + port + } + return host + ":" + port +} + +// Convert "host:port" into IP address and port. +func hostPortToIP(net, hostport string) (ip IP, iport int, err os.Error) { + host, port, err := splitHostPort(hostport) + if err != nil { + goto Error + } + + var addr IP + if host != "" { + // Try as an IP address. + addr = ParseIP(host) + if addr == nil { + // Not an IP address. Try as a DNS name. + _, addrs, err1 := LookupHost(host) + if err1 != nil { + err = err1 + goto Error + } + addr = ParseIP(addrs[0]) + if addr == nil { + // should not happen + err = &AddrError{"LookupHost returned invalid address", addrs[0]} + goto Error + } + } + } + + p, i, ok := dtoi(port, 0) + if !ok || i != len(port) { + p, err = LookupPort(net, port) + if err != nil { + goto Error + } + } + if p < 0 || p > 0xFFFF { + err = &AddrError{"invalid port", port} + goto Error + } + + return addr, p, nil + +Error: + return nil, 0, err +} -- cgit v1.2.3