func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) error { var err error var lsa syscall.Sockaddr if laddr != nil { if lsa, err = laddr.sockaddr(fd.family); err != nil { return err } else if lsa != nil { if err := syscall.Bind(fd.sysfd, lsa); err != nil { return os.NewSyscallError("bind", err) } } } var rsa syscall.Sockaddr if raddr != nil { if rsa, err = raddr.sockaddr(fd.family); err != nil { return err } if err := fd.connect(lsa, rsa, deadline); err != nil { return err } fd.isConnected = true } else { if err := fd.init(); err != nil { return err } } lsa, _ = syscall.Getsockname(fd.sysfd) if rsa, _ = syscall.Getpeername(fd.sysfd); rsa != nil { fd.setAddr(toAddr(lsa), toAddr(rsa)) } else { fd.setAddr(toAddr(lsa), raddr) } return nil }
func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { file, err := conn.File() if err != nil { return nil, err } return syscall.Getsockname(int(file.Fd())) }
func (fd *netFD) dial(ctx context.Context, laddr, raddr sockaddr) error { var err error var lsa syscall.Sockaddr if laddr != nil { if lsa, err = laddr.sockaddr(fd.family); err != nil { return err } else if lsa != nil { if err := syscall.Bind(fd.sysfd, lsa); err != nil { return os.NewSyscallError("bind", err) } } } var rsa syscall.Sockaddr if raddr != nil { if rsa, err = raddr.sockaddr(fd.family); err != nil { return err } if err := fd.connect(ctx, lsa, rsa); err != nil { return err } fd.isConnected = true } else { if err := fd.init(); err != nil { return err } } lsa, _ = syscall.Getsockname(fd.sysfd) if rsa, _ = syscall.Getpeername(fd.sysfd); rsa != nil { fd.setAddr(fd.addrFunc()(lsa), fd.addrFunc()(rsa)) } else { fd.setAddr(fd.addrFunc()(lsa), raddr) } return nil }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) { if err := fd.incref(false); err != nil { return nil, err } defer fd.decref() var s int var rsa syscall.Sockaddr for { s, rsa, err = accept(fd.sysfd) if err != nil { if err == syscall.EAGAIN { if err = fd.pollServer.WaitRead(fd); err == nil { continue } } else if err == syscall.ECONNABORTED { // This means that a socket on the listen queue was closed // before we Accept()ed it; it's a silly error, so try again. continue } return nil, &OpError{"accept", fd.net, fd.laddr, err} } break } if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil { closesocket(s) return nil, err } lsa, _ := syscall.Getsockname(netfd.sysfd) netfd.setAddr(toAddr(lsa), toAddr(rsa)) return netfd, nil }
func BenchmarkListenSock(b *testing.B) { aConn := listenUDP(udpAddr) bConn := listenUDP(udpAddr) aFile := getFile(aConn) bFile := getFile(bConn) aSockaddr, err := syscall.Getsockname(int(aFile.Fd())) if err != nil { log.Fatal(err) } src := make([]byte, bytesNum) io.ReadFull(rand.Reader, src) b.ResetTimer() for i := 0; i < b.N; i++ { err = syscall.Sendto(int(bFile.Fd()), src, 0, aSockaddr) if err != nil { b.Fatal(err) } } b.SetBytes(bytesNum) }
func localSockname(fd *netFD, toAddr func(syscall.Sockaddr) Addr) Addr { sa, _ := syscall.Getsockname(fd.sysfd) if sa == nil { return nullProtocolAddr(fd.family, fd.sotype) } return toAddr(sa) }
// GetOriginalDst returns original destination of Conn func GetOriginalDst(c net.Conn) (string, error) { tcp, ok := c.(*net.TCPConn) if !ok { return "", errors.New("socket is not tcp") } file, err := tcp.File() if err != nil { return "", err } defer file.Close() sa, err := syscall.Getsockname(int(file.Fd())) if err != nil { return "", err } var addr net.TCPAddr if v, ok := sa.(*syscall.SockaddrInet4); ok { addr = net.TCPAddr{IP: v.Addr[0:], Port: v.Port} } else if v, ok := sa.(*syscall.SockaddrInet6); ok { addr = net.TCPAddr{IP: v.Addr[0:], Port: v.Port, Zone: zoneToString(int(v.ZoneId))} } else { return "", errors.New("socket is not ipv4") } return addr.String(), nil }
// Generic socket creation. func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { // See ../syscall/exec_unix.go for description of ForkLock. syscall.ForkLock.RLock() s, err := syscall.Socket(f, t, p) if err != nil { syscall.ForkLock.RUnlock() return nil, err } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() if err = setDefaultSockopts(s, f, t, ipv6only); err != nil { closesocket(s) return nil, err } if ulsa != nil { // We provide a socket that listens to a wildcard // address with reusable UDP port when the given ulsa // is an appropriate UDP multicast address prefix. // This makes it possible for a single UDP listener // to join multiple different group addresses, for // multiple UDP listeners that listen on the same UDP // port to join the same group address. if ulsa, err = listenerSockaddr(s, f, ulsa, toAddr); err != nil { closesocket(s) return nil, err } if err = syscall.Bind(s, ulsa); err != nil { closesocket(s) return nil, err } } if fd, err = newFD(s, f, t, net); err != nil { closesocket(s) return nil, err } if ursa != nil { if !deadline.IsZero() { fd.wdeadline = deadline.UnixNano() } if err = fd.connect(ursa); err != nil { closesocket(s) fd.Close() return nil, err } fd.isConnected = true fd.wdeadline = 0 } lsa, _ := syscall.Getsockname(s) laddr := toAddr(lsa) rsa, _ := syscall.Getpeername(s) raddr := toAddr(rsa) fd.setAddr(laddr, raddr) return fd, nil }
// Sends a signal to kernel to check if Audit is enabled func AuditIsEnabled(s *NetlinkSocket) error { wb := newNetlinkAuditRequest(uint16(AUDIT_GET), syscall.AF_NETLINK, 0) if err := s.Send(wb); err != nil { return err } done: for { //Make the rb byte bigger because of large messages from Kernel doesn't fit in 4096 msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, syscall.MSG_DONTWAIT) if err != nil { return err } for _, m := range msgs { lsa, er := syscall.Getsockname(s.fd) if er != nil { return nil } switch v := lsa.(type) { case *syscall.SockaddrNetlink: if m.Header.Seq != uint32(wb.Header.Seq) { return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq) } if m.Header.Pid != v.Pid { return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, v.Pid) } default: return syscall.EINVAL } if m.Header.Type == syscall.NLMSG_DONE { log.Println("Done") break done } if m.Header.Type == syscall.NLMSG_ERROR { log.Println("NLMSG_ERROR Received..") } if m.Header.Type == uint16(AUDIT_GET) { //Convert the data part written to AuditStatus struct b := m.Data[:] // h := (*AuditStatus)(unsafe.Pointer(&b[0])) Unsafe Method avoided buf := bytes.NewBuffer(b) var dumm AuditStatus err = binary.Read(buf, nativeEndian(), &dumm) if err != nil { log.Println("binary.Read failed:", err) return err } ParsedResult = dumm break done } } } return nil }
// Generic POSIX socket creation. func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { s, err := sysSocket(f, t, p) if err != nil { return nil, err } if err = setDefaultSockopts(s, f, t, ipv6only); err != nil { closesocket(s) return nil, err } if ulsa != nil { // We provide a socket that listens to a wildcard // address with reusable UDP port when the given ulsa // is an appropriate UDP multicast address prefix. // This makes it possible for a single UDP listener // to join multiple different group addresses, for // multiple UDP listeners that listen on the same UDP // port to join the same group address. if ulsa, err = listenerSockaddr(s, f, ulsa, toAddr); err != nil { closesocket(s) return nil, err } if err = syscall.Bind(s, ulsa); err != nil { closesocket(s) return nil, err } } if fd, err = newFD(s, f, t, net); err != nil { closesocket(s) return nil, err } if ursa != nil { if !deadline.IsZero() { setWriteDeadline(fd, deadline) } if err = fd.connect(ursa); err != nil { closesocket(s) return nil, err } fd.isConnected = true if !deadline.IsZero() { setWriteDeadline(fd, time.Time{}) } } lsa, _ := syscall.Getsockname(s) laddr := toAddr(lsa) rsa, _ := syscall.Getpeername(s) raddr := toAddr(rsa) fd.setAddr(laddr, raddr) if fd.raddr == nil { fd.raddr = toAddr(ursa) } return fd, nil }
func newFileFD(f *os.File) (*netFD, error) { syscall.ForkLock.RLock() fd, err := syscall.Dup(int(f.Fd())) if err != nil { syscall.ForkLock.RUnlock() return nil, os.NewSyscallError("dup", err) } syscall.CloseOnExec(fd) syscall.ForkLock.RUnlock() sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE) if err != nil { closesocket(fd) return nil, os.NewSyscallError("getsockopt", err) } family := syscall.AF_UNSPEC toAddr := sockaddrToTCP sa, _ := syscall.Getsockname(fd) switch sa.(type) { default: closesocket(fd) return nil, syscall.EINVAL case *syscall.SockaddrInet4: family = syscall.AF_INET if sotype == syscall.SOCK_DGRAM { toAddr = sockaddrToUDP } else if sotype == syscall.SOCK_RAW { toAddr = sockaddrToIP } case *syscall.SockaddrInet6: family = syscall.AF_INET6 if sotype == syscall.SOCK_DGRAM { toAddr = sockaddrToUDP } else if sotype == syscall.SOCK_RAW { toAddr = sockaddrToIP } case *syscall.SockaddrUnix: family = syscall.AF_UNIX toAddr = sockaddrToUnix if sotype == syscall.SOCK_DGRAM { toAddr = sockaddrToUnixgram } else if sotype == syscall.SOCK_SEQPACKET { toAddr = sockaddrToUnixpacket } } laddr := toAddr(sa) sa, _ = syscall.Getpeername(fd) raddr := toAddr(sa) netfd, err := newFD(fd, family, sotype, laddr.Network()) if err != nil { closesocket(fd) return nil, err } netfd.setAddr(laddr, raddr) return netfd, nil }
// Generic socket creation. func socket(net string, f, t, p int, ipv6only bool, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { // See ../syscall/exec.go for description of ForkLock. syscall.ForkLock.RLock() s, err := syscall.Socket(f, t, p) if err != nil { syscall.ForkLock.RUnlock() return nil, err } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() err = setDefaultSockopts(s, f, t, ipv6only) if err != nil { closesocket(s) return nil, err } var bla syscall.Sockaddr if la != nil { bla, err = listenerSockaddr(s, f, la, toAddr) if err != nil { closesocket(s) return nil, err } err = syscall.Bind(s, bla) if err != nil { closesocket(s) return nil, err } } if fd, err = newFD(s, f, t, net); err != nil { closesocket(s) return nil, err } if ra != nil { if err = fd.connect(ra); err != nil { closesocket(s) fd.Close() return nil, err } fd.isConnected = true } sa, _ := syscall.Getsockname(s) var laddr Addr if la != nil && bla != la { laddr = toAddr(la) } else { laddr = toAddr(sa) } sa, _ = syscall.Getpeername(s) raddr := toAddr(sa) fd.setAddr(laddr, raddr) return fd, nil }
// DeleteAllRules deletes all previous audit rules listed in the kernel func DeleteAllRules(s *NetlinkConnection) error { wb := newNetlinkAuditRequest(uint16(AUDIT_LIST_RULES), syscall.AF_NETLINK, 0) if err := s.Send(wb); err != nil { return errors.Wrap(err, "DeleteAllRules failed") } done: for { // Avoid DONTWAIT due to implications on systems with low resources // msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, syscall.MSG_DONTWAIT) msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, 0) if err != nil { return errors.Wrap(err, "DeleteAllRules failed") } for _, m := range msgs { address, err := syscall.Getsockname(s.fd) if err != nil { return errors.Wrap(err, "DeleteAllRules: Getsockname failed") } switch v := address.(type) { case *syscall.SockaddrNetlink: if m.Header.Seq != uint32(wb.Header.Seq) { return fmt.Errorf("DeleteAllRules: Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq) } if m.Header.Pid != v.Pid { return fmt.Errorf("DeleteAllRules: Wrong PID %d, expected %d", m.Header.Pid, v.Pid) } default: return errors.Wrap(syscall.EINVAL, "DeleteAllRules: socket type unexpected") } if m.Header.Type == syscall.NLMSG_DONE { break done } if m.Header.Type == syscall.NLMSG_ERROR { e := int32(nativeEndian().Uint32(m.Data[0:4])) if e != 0 { return fmt.Errorf("DeleteAllRules: error receiving rules -%d", e) } } if m.Header.Type == uint16(AUDIT_LIST_RULES) { b := m.Data[:] //Avoid conversion to auditRuleData, we just need to pass the recvd rule //as a Buffer in a newly packed rule to delete it // rules := (*auditRuleData)(unsafe.Pointer(&b[0])) newwb := newNetlinkAuditRequest(uint16(AUDIT_DEL_RULE), syscall.AF_NETLINK, len(b) /*+int(rule.Buflen)*/) newwb.Data = append(newwb.Data[:], b[:]...) if err := s.Send(newwb); err != nil { return errors.Wrap(err, "DeleteAllRules failed") } } } } return nil }
func newFileFD(f *os.File, sa SocketAddr) (*netFD, error) { s, err := dupSocket(f) if err != nil { return nil, err } var laddr, raddr Addr var fd *netFD if sa != nil { lsa := make([]byte, syscall.SizeofSockaddrAny) if err := unix.Getsockname(s, lsa); err != nil { lsa = nil } rsa := make([]byte, syscall.SizeofSockaddrAny) if err := unix.Getpeername(s, rsa); err != nil { rsa = nil } laddr = sa.Addr(lsa) raddr = sa.Addr(rsa) fd, err = newFD(s, -1, -1, laddr.Network()) } else { family := syscall.AF_UNSPEC var sotype int sotype, err = syscall.GetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_TYPE) if err != nil { closeFunc(s) return nil, os.NewSyscallError("getsockopt", err) } lsa, _ := syscall.Getsockname(s) rsa, _ := syscall.Getpeername(s) switch lsa.(type) { case *syscall.SockaddrInet4: family = syscall.AF_INET case *syscall.SockaddrInet6: family = syscall.AF_INET6 case *syscall.SockaddrUnix: family = syscall.AF_UNIX default: closeFunc(s) return nil, syscall.EPROTONOSUPPORT } fd, err = newFD(s, family, sotype, "") laddr = fd.addrFunc()(lsa) raddr = fd.addrFunc()(rsa) fd.net = laddr.Network() } if err != nil { closeFunc(s) return nil, err } if err := fd.init(); err != nil { fd.Close() return nil, err } fd.setAddr(laddr, raddr) return fd, nil }
// Generic socket creation. func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) { // See ../syscall/exec.go for description of ForkLock. syscall.ForkLock.RLock() s, e := syscall.Socket(f, p, t) if e != 0 { syscall.ForkLock.RUnlock() return nil, os.Errno(e) } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() // Allow reuse of recently-used addresses. syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) // Allow broadcast. syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) if f == syscall.AF_INET6 { // using ip, tcp, udp, etc. // allow both protocols even if the OS default is otherwise. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0) } if la != nil { e = syscall.Bind(s, la) if e != 0 { closesocket(s) return nil, os.Errno(e) } } if ra != nil { e = syscall.Connect(s, ra) for e == syscall.EINTR { e = syscall.Connect(s, ra) } if e != 0 { closesocket(s) return nil, os.Errno(e) } } sa, _ := syscall.Getsockname(s) laddr := toAddr(sa) sa, _ = syscall.Getpeername(s) raddr := toAddr(sa) fd, err = newFD(s, f, p, net, laddr, raddr) if err != nil { closesocket(s) return nil, err } return fd, nil }
func (s *NetlinkSocket) GetPid() (uint32, error) { lsa, err := syscall.Getsockname(s.fd) if err != nil { return 0, err } switch v := lsa.(type) { case *syscall.SockaddrNetlink: return v.Pid, nil } return 0, ErrWrongSockType }
func TestNetlinkConnection(t *testing.T) { s, err := NewNetlinkConnection() if err != nil { t.Errorf("NewNetlinkConnection failed %v", err) } defer s.Close() wb := newNetlinkAuditRequest(uint16(AUDIT_GET), syscall.AF_NETLINK, 0) if err = s.Send(wb); err != nil { t.Errorf("TestNetlinkConnection: sending failed %v", err) } done: for { msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, 0) if err != nil { t.Errorf("TestNetlinkConnection: recv failed %v", err) } for _, m := range msgs { address, err := syscall.Getsockname(s.fd) if err != nil { t.Errorf("TestNetlinkConnection: unable to get sockname %v", err) } switch v := address.(type) { case *syscall.SockaddrNetlink: if m.Header.Seq != uint32(wb.Header.Seq) { t.Errorf("TestNetlinkConnection: Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq) } if m.Header.Pid != v.Pid { t.Errorf("TestNetlinkConnection: Wrong PID %d, expected %d", m.Header.Pid, v.Pid) } default: t.Errorf("TestNetlinkConnection: socket type unexpected") } if m.Header.Type == syscall.NLMSG_DONE { break done } else if m.Header.Type == syscall.NLMSG_ERROR { e := int32(nativeEndian().Uint32(m.Data[0:4])) if e == 0 { // request ack from kernel continue } break done } if m.Header.Type == uint16(AUDIT_GET) { break done } } } }
func newFileFD(f *os.File) (nfd *netFD, err error) { fd, errno := syscall.Dup(f.Fd()) if errno != 0 { return nil, os.NewSyscallError("dup", errno) } proto, errno := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE) if errno != 0 { return nil, os.NewSyscallError("getsockopt", errno) } family := syscall.AF_UNSPEC toAddr := sockaddrToTCP sa, _ := syscall.Getsockname(fd) switch sa.(type) { default: closesocket(fd) return nil, os.EINVAL case *syscall.SockaddrInet4: family = syscall.AF_INET if proto == syscall.SOCK_DGRAM { toAddr = sockaddrToUDP } else if proto == syscall.SOCK_RAW { toAddr = sockaddrToIP } case *syscall.SockaddrInet6: family = syscall.AF_INET6 if proto == syscall.SOCK_DGRAM { toAddr = sockaddrToUDP } else if proto == syscall.SOCK_RAW { toAddr = sockaddrToIP } case *syscall.SockaddrUnix: family = syscall.AF_UNIX toAddr = sockaddrToUnix if proto == syscall.SOCK_DGRAM { toAddr = sockaddrToUnixgram } else if proto == syscall.SOCK_SEQPACKET { toAddr = sockaddrToUnixpacket } } laddr := toAddr(sa) sa, _ = syscall.Getpeername(fd) raddr := toAddr(sa) if nfd, err = newFD(fd, family, proto, laddr.Network()); err != nil { return nil, err } nfd.setAddr(laddr, raddr) return nfd, nil }
func OpenNetlinkSocket(protocol int) (*NetlinkSocket, error) { fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol) if err != nil { return nil, err } success := false defer func() { if !success { syscall.Close(fd) } }() // It's fairly easy to provoke ENOBUFS from a netlink socket // receiving miss upcalls when every packet misses. The // default socket buffer size is relatively small at 200KB, // and the default of /proc/sys/net/core/rmem_max means we // can't easily increase it. if err := syscall.SetsockoptInt(fd, SOL_NETLINK, syscall.NETLINK_NO_ENOBUFS, 1); err != nil { return nil, err } addr := syscall.SockaddrNetlink{Family: syscall.AF_NETLINK} if err := syscall.Bind(fd, &addr); err != nil { return nil, err } localaddr, err := syscall.Getsockname(fd) if err != nil { return nil, err } nladdr, ok := localaddr.(*syscall.SockaddrNetlink) if !ok { return nil, fmt.Errorf("Expected netlink sockaddr, got %s", reflect.TypeOf(localaddr)) } success = true return &NetlinkSocket{ fd: fd, addr: nladdr, // netlink messages can be bigger than this, but it // seems unlikely in practice, and this is similar to // the limit that the OVS userspace imposes. buf: make([]byte, 65536), }, nil }
func (fd *netFD) accept() (netfd *netFD, err error) { if err := fd.readLock(); err != nil { return nil, err } defer fd.readUnlock() var s int var rsa syscall.Sockaddr if err = fd.pd.prepareRead(); err != nil { return nil, err } for { s, rsa, err = accept(fd.sysfd) if err != nil { nerr, ok := err.(*os.SyscallError) if !ok { return nil, err } switch nerr.Err { case syscall.EAGAIN: if err = fd.pd.waitRead(); err == nil { continue } case syscall.ECONNABORTED: // This means that a socket on the // listen queue was closed before we // Accept()ed it; it's a silly error, // so try again. continue } return nil, err } break } if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil { closeFunc(s) return nil, err } if err = netfd.init(); err != nil { fd.Close() return nil, err } lsa, _ := syscall.Getsockname(netfd.sysfd) netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa)) return netfd, nil }
//HandleAck ? func AuditGetReply(s *NetlinkSocket, bytesize, block int, seq uint32) error { done: for { msgs, err := s.Receive(bytesize, block) //ParseAuditNetlinkMessage(rb) if err != nil { return err } for _, m := range msgs { lsa, err := syscall.Getsockname(s.fd) if err != nil { return err } switch v := lsa.(type) { case *syscall.SockaddrNetlink: if m.Header.Seq != seq { return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, seq) } if m.Header.Pid != v.Pid { return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, v.Pid) } default: return syscall.EINVAL } if m.Header.Type == syscall.NLMSG_DONE { break done } if m.Header.Type == syscall.NLMSG_ERROR { error := int32(nativeEndian().Uint32(m.Data[0:4])) if error == 0 { log.Println("Acknowledged!!") break done } else { log.Println("NLMSG_ERROR Received..") } break done } if m.Header.Type == uint16(AUDIT_GET) { log.Println("AUDIT_GET") break done } } } return nil }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err error) { if fd == nil || fd.sysfile == nil { return nil, os.EINVAL } fd.incref() defer fd.decref() if fd.rdeadline_delta > 0 { fd.rdeadline = pollserver.Now() + fd.rdeadline_delta } else { fd.rdeadline = 0 } // See ../syscall/exec.go for description of ForkLock. // It is okay to hold the lock across syscall.Accept // because we have put fd.sysfd into non-blocking mode. syscall.ForkLock.RLock() var s, e int var rsa syscall.Sockaddr for { if fd.closing { syscall.ForkLock.RUnlock() return nil, os.EINVAL } s, rsa, e = syscall.Accept(fd.sysfd) if e != syscall.EAGAIN || fd.rdeadline < 0 { break } syscall.ForkLock.RUnlock() pollserver.WaitRead(fd) syscall.ForkLock.RLock() } if e != 0 { syscall.ForkLock.RUnlock() return nil, &OpError{"accept", fd.net, fd.laddr, os.Errno(e)} } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() if nfd, err = newFD(s, fd.family, fd.proto, fd.net); err != nil { syscall.Close(s) return nil, err } lsa, _ := syscall.Getsockname(nfd.sysfd) nfd.setAddr(toAddr(lsa), toAddr(rsa)) return nfd, nil }
// Generic socket creation. func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) { // See ../syscall/exec.go for description of ForkLock. syscall.ForkLock.RLock() s, e := syscall.Socket(f, p, t) if e != 0 { syscall.ForkLock.RUnlock() return nil, os.Errno(e) } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() // Allow reuse of recently-used addresses. syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) // Allow broadcast. syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) if la != nil { e = syscall.Bind(s, la) if e != 0 { syscall.Close(s) return nil, os.Errno(e) } } if ra != nil { e = syscall.Connect(s, ra) if e != 0 { syscall.Close(s) return nil, os.Errno(e) } } sa, _ := syscall.Getsockname(s) laddr := toAddr(sa) sa, _ = syscall.Getpeername(s) raddr := toAddr(sa) fd, err = newFD(s, f, p, net, laddr, raddr) if err != nil { syscall.Close(s) return nil, err } return fd, nil }
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, sa.Port, true case *syscall.SockaddrInet6: return &sa.Addr, sa.Port, true } return }
// auditGetReply connects to kernel to recieve a reply func auditGetReply(s *NetlinkConnection, bytesize, block int, seq uint32) error { done: for { msgs, err := s.Receive(bytesize, block) //parseAuditNetlinkMessage(rb) if err != nil { return errors.Wrap(err, "auditGetReply failed") } for _, m := range msgs { address, err := syscall.Getsockname(s.fd) if err != nil { return errors.Wrap(err, "auditGetReply: Getsockname failed") } switch v := address.(type) { case *syscall.SockaddrNetlink: if m.Header.Seq != seq { return fmt.Errorf("auditGetReply: Wrong Seq nr %d, expected %d", m.Header.Seq, seq) } if m.Header.Pid != v.Pid { return fmt.Errorf("auditGetReply: Wrong pid %d, expected %d", m.Header.Pid, v.Pid) } default: return errors.Wrap(syscall.EINVAL, "auditGetReply: socket type unexpected") } if m.Header.Type == syscall.NLMSG_DONE { break done } if m.Header.Type == syscall.NLMSG_ERROR { e := int32(nativeEndian().Uint32(m.Data[0:4])) if e == 0 { break done } else { return fmt.Errorf("auditGetReply: error while recieving reply -%d", e) } } // acknowledge AUDIT_GET replies from kernel if m.Header.Type == uint16(AUDIT_GET) { break done } } } return nil }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) { if err := fd.incref(false); err != nil { return nil, err } defer fd.decref() // See ../syscall/exec_unix.go for description of ForkLock. // It is okay to hold the lock across syscall.Accept // because we have put fd.sysfd into non-blocking mode. var s int var rsa syscall.Sockaddr for { syscall.ForkLock.RLock() s, rsa, err = syscall.Accept(fd.sysfd) if err != nil { syscall.ForkLock.RUnlock() if err == syscall.EAGAIN { err = errTimeout if fd.rdeadline >= 0 { if err = fd.pollServer.WaitRead(fd); err == nil { continue } } } else if err == syscall.ECONNABORTED { // This means that a socket on the listen queue was closed // before we Accept()ed it; it's a silly error, so try again. continue } return nil, &OpError{"accept", fd.net, fd.laddr, err} } break } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil { closesocket(s) return nil, err } lsa, _ := syscall.Getsockname(netfd.sysfd) netfd.setAddr(toAddr(lsa), toAddr(rsa)) return netfd, nil }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) { if fd == nil || fd.sysfile == nil { return nil, os.EINVAL } fd.incref() defer fd.decref() // See ../syscall/exec.go for description of ForkLock. // It is okay to hold the lock across syscall.Accept // because we have put fd.sysfd into non-blocking mode. var s int var rsa syscall.Sockaddr for { if fd.closing { return nil, os.EINVAL } syscall.ForkLock.RLock() s, rsa, err = syscall.Accept(fd.sysfd) if err != nil { syscall.ForkLock.RUnlock() if err == syscall.EAGAIN { if fd.rdeadline >= 0 { pollserver.WaitRead(fd) continue } err = errTimeout } return nil, &OpError{"accept", fd.net, fd.laddr, err} } break } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil { syscall.Close(s) return nil, err } lsa, _ := syscall.Getsockname(netfd.sysfd) netfd.setAddr(toAddr(lsa), toAddr(rsa)) return netfd, nil }
// Generic socket creation. func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) { // See ../syscall/exec.go for description of ForkLock. syscall.ForkLock.RLock() s, e := syscall.Socket(f, p, t) if e != 0 { syscall.ForkLock.RUnlock() return nil, os.Errno(e) } syscall.CloseOnExec(s) syscall.ForkLock.RUnlock() setKernelSpecificSockopt(s, f) if la != nil { e = syscall.Bind(s, la) if e != 0 { closesocket(s) return nil, os.Errno(e) } } if fd, err = newFD(s, f, p, net); err != nil { closesocket(s) return nil, err } if ra != nil { if err = fd.connect(ra); err != nil { fd.sysfd = -1 closesocket(s) return nil, err } } sa, _ := syscall.Getsockname(s) laddr := toAddr(sa) sa, _ = syscall.Getpeername(s) raddr := toAddr(sa) fd.setAddr(laddr, raddr) return fd, nil }
func OpenNetlinkSocket(protocol int) (*NetlinkSocket, error) { fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol) if err != nil { return nil, err } success := false defer func() { if !success { syscall.Close(fd) } }() // It's fairly easy to provoke ENOBUFS from a netlink socket // receiving miss upcalls when every packet misses. The // default socket buffer size is relatively small at 200KB, // and the default of /proc/sys/net/core/rmem_max means we // can't easily increase it. if err := syscall.SetsockoptInt(fd, SOL_NETLINK, syscall.NETLINK_NO_ENOBUFS, 1); err != nil { return nil, err } addr := syscall.SockaddrNetlink{Family: syscall.AF_NETLINK} if err := syscall.Bind(fd, &addr); err != nil { return nil, err } localaddr, err := syscall.Getsockname(fd) if err != nil { return nil, err } switch nladdr := localaddr.(type) { case *syscall.SockaddrNetlink: success = true return &NetlinkSocket{fd: fd, addr: nladdr}, nil default: return nil, fmt.Errorf("Expected netlink sockaddr, got %s", reflect.TypeOf(localaddr)) } }
func (fd *netFD) listenStream(laddr sockaddr, backlog int) error { if err := setDefaultListenerSockopts(fd.sysfd); err != nil { return err } if lsa, err := laddr.sockaddr(fd.family); err != nil { return err } else if lsa != nil { if err := syscall.Bind(fd.sysfd, lsa); err != nil { return os.NewSyscallError("bind", err) } } if err := listenFunc(fd.sysfd, backlog); err != nil { return os.NewSyscallError("listen", err) } if err := fd.init(); err != nil { return err } lsa, _ := syscall.Getsockname(fd.sysfd) fd.setAddr(fd.addrFunc()(lsa), nil) return nil }