2008-09-26 15:11:26 -06:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
package net
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os";
|
|
|
|
"syscall";
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
|
|
|
export func IPv4ToSockaddr(p *[]byte, port int) (sa1 *syscall.Sockaddr, err *os.Error) {
|
2008-10-07 13:31:31 -06:00
|
|
|
p = ToIPv4(p);
|
2008-09-26 15:11:26 -06:00
|
|
|
if p == nil || port < 0 || port > 0xFFFF {
|
|
|
|
return nil, os.EINVAL
|
|
|
|
}
|
|
|
|
sa := new(syscall.SockaddrInet4);
|
|
|
|
sa.family = syscall.AF_INET;
|
|
|
|
sa.port[0] = byte(port>>8);
|
|
|
|
sa.port[1] = byte(port);
|
|
|
|
for i := 0; i < IPv4len; i++ {
|
|
|
|
sa.addr[i] = p[i]
|
|
|
|
}
|
|
|
|
return syscall.SockaddrInet4ToSockaddr(sa), nil
|
|
|
|
}
|
|
|
|
|
2008-09-29 14:37:00 -06:00
|
|
|
var IPv6zero [16]byte;
|
|
|
|
|
2008-09-26 15:11:26 -06:00
|
|
|
export func IPv6ToSockaddr(p *[]byte, port int) (sa1 *syscall.Sockaddr, err *os.Error) {
|
2008-10-07 13:31:31 -06:00
|
|
|
p = ToIPv6(p);
|
2008-09-26 15:11:26 -06:00
|
|
|
if p == nil || port < 0 || port > 0xFFFF {
|
|
|
|
return nil, os.EINVAL
|
|
|
|
}
|
2008-09-29 14:37:00 -06:00
|
|
|
|
|
|
|
// 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 := ToIPv4(p); p4 != nil && p4[0] == 0 && p4[1] == 0 && p4[2] == 0 && p4[3] == 0 {
|
|
|
|
p = &IPv6zero;
|
|
|
|
}
|
|
|
|
|
2008-09-26 15:11:26 -06:00
|
|
|
sa := new(syscall.SockaddrInet6);
|
|
|
|
sa.family = syscall.AF_INET6;
|
|
|
|
sa.port[0] = byte(port>>8);
|
|
|
|
sa.port[1] = byte(port);
|
|
|
|
for i := 0; i < IPv6len; i++ {
|
|
|
|
sa.addr[i] = p[i]
|
|
|
|
}
|
|
|
|
return syscall.SockaddrInet6ToSockaddr(sa), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
export func SockaddrToIP(sa1 *syscall.Sockaddr) (p *[]byte, port int, err *os.Error) {
|
|
|
|
switch sa1.family {
|
|
|
|
case syscall.AF_INET:
|
|
|
|
sa := syscall.SockaddrToSockaddrInet4(sa1);
|
2008-10-07 13:31:31 -06:00
|
|
|
a := ToIPv6(&sa.addr);
|
2008-09-26 15:11:26 -06:00
|
|
|
if a == nil {
|
|
|
|
return nil, 0, os.EINVAL
|
|
|
|
}
|
2008-10-07 13:31:31 -06:00
|
|
|
return a, int(sa.port[0])<<8 + int(sa.port[1]), nil;
|
2008-09-26 15:11:26 -06:00
|
|
|
case syscall.AF_INET6:
|
|
|
|
sa := syscall.SockaddrToSockaddrInet6(sa1);
|
2008-10-07 13:31:31 -06:00
|
|
|
a := ToIPv6(&sa.addr);
|
2008-09-26 15:11:26 -06:00
|
|
|
if a == nil {
|
|
|
|
return nil, 0, os.EINVAL
|
|
|
|
}
|
2008-10-07 13:31:31 -06:00
|
|
|
return a, int(sa.port[0])<<8 + int(sa.port[1]), nil;
|
2008-09-26 15:11:26 -06:00
|
|
|
default:
|
|
|
|
return nil, 0, os.EINVAL
|
|
|
|
}
|
|
|
|
return nil, 0, nil // not reached
|
|
|
|
}
|
|
|
|
|
|
|
|
export func ListenBacklog() int64 {
|
|
|
|
// TODO: Read the limit from /proc/sys/net/core/somaxconn,
|
|
|
|
// to take advantage of kernels that have raised the limit.
|
|
|
|
return syscall.SOMAXCONN
|
|
|
|
}
|
|
|
|
|