summaryrefslogtreecommitdiff
path: root/src/lib/net/socket_linux.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2008-09-16 13:42:47 -0700
committerRuss Cox <rsc@golang.org>2008-09-16 13:42:47 -0700
commit015a709e5efffab4183acf1a6d5146d99ba574cd (patch)
tree9f656df558356b50f93329d1697852b7a3feb2ef /src/lib/net/socket_linux.go
parent4e3a56356778e5628364e4995e1a12d93aece84e (diff)
downloadgolang-015a709e5efffab4183acf1a6d5146d99ba574cd.tar.gz
preliminary network - just Dial for now
R=r,presotto OCL=15393 CL=15399
Diffstat (limited to 'src/lib/net/socket_linux.go')
-rw-r--r--src/lib/net/socket_linux.go247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/lib/net/socket_linux.go b/src/lib/net/socket_linux.go
new file mode 100644
index 000000000..5dacaf58e
--- /dev/null
+++ b/src/lib/net/socket_linux.go
@@ -0,0 +1,247 @@
+// 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.
+
+// Low-level socket interface.
+// Only for implementing net package.
+// DO NOT USE DIRECTLY.
+
+package socket
+
+import (
+ "os";
+ "ip";
+ "syscall"
+)
+
+export const (
+ SOCKET = 41;
+ CONNECT = 42;
+ ACCEPT = 43;
+ SETSOCKOPT = 54;
+ GETSOCKOPT = 55;
+ BIND = 49;
+ LISTEN = 50;
+
+ AF_UNIX = 1;
+ AF_INET = 2;
+ AF_INET6 = 10;
+
+ SOCK_STREAM = 1;
+ SOCK_DGRAM = 2;
+ SOCK_RAW = 3;
+ SOCK_RDM = 4;
+ SOCK_SEQPACKET = 5;
+
+ SOL_SOCKET = 1;
+
+ SO_DEBUG = 1;
+ SO_REUSEADDR = 2;
+ SO_TYPE = 3;
+ SO_ERROR = 4;
+ SO_DONTROUTE = 5;
+ SO_BROADCAST = 6;
+ SO_SNDBUF = 7;
+ SO_RCVBUF = 8;
+ SO_SNDBUFFORCE = 32;
+ SO_RCVBUFFORCE = 33;
+ SO_KEEPALIVE = 9;
+ SO_OOBINLINE = 10;
+ SO_NO_CHECK = 11;
+ SO_PRIORITY = 12;
+ SO_LINGER = 13;
+ SO_BSDCOMPAT = 14;
+ SO_PASSCRED = 16;
+ SO_PEERCRED = 17;
+ SO_RCVLOWAT = 18;
+ SO_SNDLOWAT = 19;
+ SO_RCVTIMEO = 20;
+ SO_SNDTIMEO = 21;
+ SO_BINDTODEVICE = 25;
+
+ IPPROTO_TCP = 6;
+ IPPROTO_UDP = 17;
+
+ TCP_NODELAY = 0x01;
+)
+
+export type SockaddrUnix struct {
+ family uint16;
+ path [108]byte
+}
+export const SizeofSockaddrUnix = 110
+
+export type SockaddrInet4 struct {
+ family uint16;
+ port [2]byte;
+ addr [4]byte;
+ zero [8]byte
+}
+export const SizeofSockaddrInet4 = 16
+
+export type SockaddrInet6 struct {
+ family uint16;
+ port [2]byte;
+ flowinfo [4]byte;
+ addr [16]byte;
+ scopeid [4]byte;
+}
+export const SizeofSockaddrInet6 = 28
+
+export type Sockaddr struct {
+ family uint16;
+ opaque [126]byte
+}
+export const SizeofSockaddr = 128
+
+export type Timeval struct {
+ sec int32;
+ usec int32;
+}
+export type Linger struct {
+ yes int32;
+ sec int32;
+}
+
+func (s *Sockaddr) Len() int64 {
+ switch s.family {
+ case AF_UNIX:
+ return SizeofSockaddrUnix
+ case AF_INET:
+ return SizeofSockaddrInet4
+ case AF_INET6:
+ return SizeofSockaddrInet6
+ }
+ return 0
+}
+
+func SockaddrToSockaddrInet4(s *Sockaddr) *SockaddrInet4;
+func SockaddrToSockaddrInet6(s *Sockaddr) *SockaddrInet6;
+func SockaddrInet4ToSockaddr(s *SockaddrInet4) *Sockaddr;
+func SockaddrInet6ToSockaddr(s *SockaddrInet6) *Sockaddr;
+func SockaddrPtr(s *Sockaddr) int64;
+func Int32Ptr(ip *int32) int64;
+func TimevalPtr(tv *Timeval) int64;
+func LingerPtr(l *Linger) int64;
+
+export func socket(domain, proto, typ int64) (ret int64, err *os.Error) {
+ r1, r2, e := syscall.Syscall(SOCKET, domain, proto, typ);
+ return r1, os.ErrnoToError(e)
+}
+
+export func connect(fd int64, sa *Sockaddr) (ret int64, err *os.Error) {
+ r1, r2, e := syscall.Syscall(CONNECT, fd, SockaddrPtr(sa), sa.Len());
+ return r1, os.ErrnoToError(e)
+}
+
+export func bind(fd int64, sa *Sockaddr) (ret int64, err *os.Error) {
+ r1, r2, e := syscall.Syscall(BIND, fd, SockaddrPtr(sa), sa.Len());
+ return r1, os.ErrnoToError(e)
+}
+
+export func listen(fd, n int64) (ret int64, err *os.Error) {
+ r1, r2, e := syscall.Syscall(LISTEN, fd, n, 0);
+ return r1, os.ErrnoToError(e)
+}
+
+export func accept(fd int64, sa *Sockaddr) (ret int64, err *os.Error) {
+ n := int32(sa.Len());
+ r1, r2, e := syscall.Syscall(ACCEPT, fd, SockaddrPtr(sa), Int32Ptr(&n));
+ return r1, os.ErrnoToError(e)
+}
+
+export func setsockopt(fd, level, opt, valueptr, length int64) (ret int64, err *os.Error) {
+ if fd < 0 {
+ return -1, os.EINVAL
+ }
+ r1, r2, e := syscall.Syscall6(SETSOCKOPT, fd, level, opt, valueptr, length, 0);
+ return r1, os.ErrnoToError(e)
+}
+
+export func setsockopt_int(fd, level, opt int64, value int) *os.Error {
+ n := int32(opt);
+ r1, e := setsockopt(fd, level, opt, Int32Ptr(&n), 4)
+ return e
+}
+
+export func setsockopt_tv(fd, level, opt, nsec int64) *os.Error {
+ var tv Timeval;
+ nsec += 999;
+ tv.sec = int32(nsec/1000000000);
+ tv.usec = int32(nsec%1000000000);
+ r1, e := setsockopt(fd, level, opt, TimevalPtr(&tv), 4)
+ return e
+}
+
+export func setsockopt_linger(fd, level, opt int64, sec int) *os.Error {
+ var l Linger;
+ if sec != 0 {
+ l.yes = 1;
+ l.sec = sec
+ } else {
+ l.yes = 0;
+ l.sec = 0
+ }
+ r1, err := setsockopt(fd, level, opt, LingerPtr(&l), 8)
+ return err
+}
+
+/*
+export func getsockopt(fd, level, opt, valueptr, lenptr int64) (ret int64, errno int64) {
+ r1, r2, err := syscall.Syscall6(GETSOCKOPT, fd, level, opt, valueptr, lenptr, 0);
+ return r1, err;
+}
+*/
+
+export func IPv4ToSockaddr(p *[]byte, port int) (sa1 *Sockaddr, err *os.Error) {
+ p = ip.ToIPv4(p)
+ if p == nil || port < 0 || port > 0xFFFF {
+ return nil, os.EINVAL
+ }
+ sa := new(SockaddrInet4);
+ sa.family = AF_INET;
+ sa.port[0] = byte(port>>8);
+ sa.port[1] = byte(port);
+ for i := 0; i < ip.IPv4len; i++ {
+ sa.addr[i] = p[i]
+ }
+ return SockaddrInet4ToSockaddr(sa), nil
+}
+
+export func IPv6ToSockaddr(p *[]byte, port int) (sa1 *Sockaddr, err *os.Error) {
+ p = ip.ToIPv6(p)
+ if p == nil || port < 0 || port > 0xFFFF {
+ return nil, os.EINVAL
+ }
+ sa := new(SockaddrInet6);
+ sa.family = AF_INET6;
+ sa.port[0] = byte(port>>8);
+ sa.port[1] = byte(port);
+ for i := 0; i < ip.IPv6len; i++ {
+ sa.addr[i] = p[i]
+ }
+ return SockaddrInet6ToSockaddr(sa), nil
+}
+
+export func SockaddrToIP(sa1 *Sockaddr) (p *[]byte, port int, err *os.Error) {
+ switch sa1.family {
+ case AF_INET:
+ sa := SockaddrToSockaddrInet4(sa1);
+ a := ip.ToIPv6(&sa.addr)
+ if a == nil {
+ return nil, 0, os.EINVAL
+ }
+ return a, int(sa.port[0])<<8 + int(sa.port[1]), nil
+ case AF_INET6:
+ sa := SockaddrToSockaddrInet6(sa1);
+ a := ip.ToIPv6(&sa.addr)
+ if a == nil {
+ return nil, 0, os.EINVAL
+ }
+ return a, int(sa.port[0])<<8 + int(sa.port[1]), nil
+ default:
+ return nil, 0, os.EINVAL
+ }
+ return nil, 0, nil // not reached
+}
+