Пример #1
1
// ListenAX25 announces on the local port axPort using mycall as the local address.
func ListenAX25(axPort, mycall string) (net.Listener, error) {
	if _, err := loadPorts(); err != nil {
		return nil, err
	}

	// Setup local address (via callsign of supplied axPort)
	localAddr := newAX25Addr(mycall)
	if err := localAddr.setPort(axPort); err != nil {
		return nil, err
	}

	// Create file descriptor
	var socket fd
	if f, err := syscall.Socket(syscall.AF_AX25, syscall.SOCK_SEQPACKET, 0); err != nil {
		return nil, err
	} else {
		socket = fd(f)
	}

	if err := socket.bind(localAddr); err != nil {
		return nil, err
	}
	if err := syscall.Listen(int(socket), syscall.SOMAXCONN); err != nil {
		return nil, err
	}

	return ax25Listener{
		sock:      fd(socket),
		localAddr: AX25Addr{localAddr},
	}, nil
}
Пример #2
1
func listenStream(netw, addr string) (l net.Listener, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if l, err = net.FileListener(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		l.Close()
		return nil, err
	}

	return l, err
}
Пример #3
0
// Listen wraps syscall.Listen.
func (sw *Switch) Listen(s syscall.Handle, backlog int) (err error) {
	so := sw.sockso(s)
	if so == nil {
		return syscall.Listen(s, backlog)
	}
	sw.fmu.RLock()
	f, _ := sw.fltab[FilterListen]
	sw.fmu.RUnlock()

	af, err := f.apply(so)
	if err != nil {
		return err
	}
	so.Err = syscall.Listen(s, backlog)
	if err = af.apply(so); err != nil {
		return err
	}

	sw.smu.Lock()
	defer sw.smu.Unlock()
	if so.Err != nil {
		sw.stats.getLocked(so.Cookie).ListenFailed++
		return so.Err
	}
	sw.stats.getLocked(so.Cookie).Listened++
	return nil
}
Пример #4
0
func so_listen(fd int, queue int) error {
	if queue < 1 {
		return os.NewSyscallError("so_listen", syscall.Listen(fd, syscall.SOMAXCONN))
	}

	return os.NewSyscallError("so_listen", syscall.Listen(fd, queue))

}
Пример #5
0
// Create a tcp socket, setting the TCP_FASTOPEN socket option.
func (s *TFOServer) Bind() (err error) {

	s.fd, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)
	if err != nil {
		if err == syscall.ENOPROTOOPT {
			err = errors.New("TCP Fast Open server support is unavailable (unsupported kernel).")
		}
		return
	}

	err = syscall.SetsockoptInt(s.fd, syscall.SOL_TCP, TCP_FASTOPEN, 1)
	if err != nil {
		err = errors.New(fmt.Sprintf("Failed to set necessary TCP_FASTOPEN socket option: %s", err))
		return
	}

	sa := &syscall.SockaddrInet4{Addr: s.ServerAddr, Port: s.ServerPort}

	err = syscall.Bind(s.fd, sa)
	if err != nil {
		err = errors.New(fmt.Sprintf("Failed to bind to Addr: %v, Port: %d, Reason: %s", s.ServerAddr, s.ServerPort, err))
		return
	}

	log.Printf("Server: Bound to addr: %v, port: %d\n", s.ServerAddr, s.ServerPort)

	err = syscall.Listen(s.fd, LISTEN_BACKLOG)
	if err != nil {
		err = errors.New(fmt.Sprintf("Failed to listen: %s", err))
		return
	}

	return

}
Пример #6
0
func main() {
	acceptingFd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)
	check(err)

	addr := &syscall.SockaddrInet4{Port: 3000, Addr: [4]byte{0, 0, 0, 0}}
	err = syscall.Bind(acceptingFd, addr)
	check(err)

	err = syscall.Listen(acceptingFd, 100)
	check(err)

	for {
		connectionFd, _, err := syscall.Accept(acceptingFd)
		check(err)
		fmt.Println("Accepted new connectrion")

		data := make([]byte, 1024)
		_, err = syscall.Read(connectionFd, data)
		check(err)
		fmt.Printf("Received: %s\n", string(data))

		_, err = syscall.Write(connectionFd, data)
		check(err)

		err = syscall.Close(connectionFd)
		check(err)
	}
}
Пример #7
0
func (io *NetIOManager) ProxyNetListen(sa syscall.Sockaddr) error {
	serverfd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM,
		syscall.IPPROTO_TCP)
	if err != nil {
		goto Error
	}

	err = syscall.Bind(serverfd, sa)
	if err != nil {
		goto Cleanup
	}

	err = syscall.Listen(serverfd, io.max_backlog)
	if err != nil {
		goto Cleanup
	}

	err = syscall.EpollCtl(io.epoll_fd, syscall.EPOLL_CTL_ADD, serverfd,
		&syscall.EpollEvent{Events: syscall.EPOLLIN, Fd: int32(serverfd)})
	if err != nil {
		goto Cleanup
	}

	io.proxy_server_fd = serverfd
	return nil

Cleanup:
	syscall.Close(serverfd)
Error:
	return err
}
Пример #8
0
func CreateTCPSocket(proto, addr string) (net.Listener, error) {
	var err error
	var laddr *net.TCPAddr

	laddr, err = net.ResolveTCPAddr(proto, addr)
	if err != nil {
		return nil, err
	}

	family, ipv6only := favoriteTCPAddrFamily(proto, laddr, "listen")

	var socketAddr syscall.Sockaddr
	if socketAddr, err = ipToSockaddr(family, laddr.IP, laddr.Port, laddr.Zone); err != nil {
		panic(err)
		return nil, err
	}

	var s int
	if s, err = sysSocket(family, syscall.SOCK_STREAM, 0); err != nil {
		return nil, err
	}

	if err = setDefaultSockopts(s, family, syscall.SOCK_STREAM, ipv6only); err != nil {
		closesocket(s)
		return nil, err
	}

	if err = setDefaultListenerSockopts(s); err != nil {
		closesocket(s)
		return nil, err
	}

	if err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, SO_REUSEPORT, 1); err != nil {
		closesocket(s)
		panic(err)
		return nil, err
	}

	if err = syscall.Bind(s, socketAddr); err != nil {
		closesocket(s)
		return nil, err
	}

	if err = syscall.Listen(s, maxListenerBacklog()); err != nil {
		closesocket(s)
		return nil, err
	}

	file := os.NewFile(uintptr(s), "listener-"+laddr.String())
	defer file.Close()

	var socketListener net.Listener
	if socketListener, err = net.FileListener(file); err != nil {
		return nil, err
	}

	return socketListener, nil

}
Пример #9
0
// Listen returns TCP listener with SO_REUSEPORT option set.
//
// Only tcp4 network is supported.
//
// ErrNoReusePort error is returned if the system doesn't support SO_REUSEPORT.
func Listen(network, addr string) (l net.Listener, err error) {
	var (
		soType, fd int
		file       *os.File
		sockaddr   syscall.Sockaddr
	)

	if sockaddr, soType, err = getSockaddr(network, addr); err != nil {
		return nil, err
	}

	syscall.ForkLock.RLock()
	fd, err = syscall.Socket(soType, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
	if err == nil {
		syscall.CloseOnExec(fd)
	}
	syscall.ForkLock.RUnlock()
	if err != nil {
		return nil, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReusePort, 1); err != nil {
		syscall.Close(fd)
		return nil, &ErrNoReusePort{err}
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	name := fmt.Sprintf("reuseport.%d.%s.%s", os.Getpid(), network, addr)
	file = os.NewFile(uintptr(fd), name)
	if l, err = net.FileListener(file); err != nil {
		file.Close()
		return nil, err
	}

	if err = file.Close(); err != nil {
		l.Close()
		return nil, err
	}

	return l, err
}
Пример #10
0
func listen2(path string) int {
	_, err := os.Stat(path)
	if err == nil {
		os.Remove(path)
	}
	fd, _ := syscall.Socket(syscall.AF_LOCAL,
		syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
	addr := &syscall.SockaddrUnix{Name: path}
	syscall.Bind(fd, addr)
	syscall.Listen(fd, 1)
	return fd
}
Пример #11
0
// NewReusablePortListener returns net.FileListener that created from
// a file discriptor for a socket with SO_REUSEPORT option.
func NewReusablePortListener(proto, addr string) (l net.Listener, err error) {
	var (
		soType, fd int
		file       *os.File
		sockaddr   syscall.Sockaddr
	)

	if sockaddr, soType, err = getSockaddr(proto, addr); err != nil {
		return nil, err
	}

	syscall.ForkLock.RLock()
	if fd, err = syscall.Socket(soType, syscall.SOCK_STREAM, syscall.IPPROTO_TCP); err != nil {
		return nil, err
	}
	syscall.ForkLock.RUnlock()

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, reusePort, 1); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, listenerBacklogMaxSize); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	file = os.NewFile(uintptr(fd), getSocketFileName(proto, addr))
	if l, err = net.FileListener(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	return l, err
}
Пример #12
0
// TuneAndListenTCP announces on the TCP address laddr and returns a TCP
// listener. The configuration config indicates additional socket options
// set on the listener socket.
func TuneAndListenTCP(net string, laddr *TCPAddr, tuners ...Tuner) (Listener, error) {
	var err error
	family, ipv6only := favoriteTCPAddrFamily(net, laddr, "listen")

	var socketAddr syscall.Sockaddr
	if socketAddr, err = ipToSockaddr(family, laddr.IP, laddr.Port, laddr.Zone); err != nil {
		return nil, err
	}

	var s int
	if s, err = sysSocket(family, syscall.SOCK_STREAM, 0); err != nil {
		return nil, err
	}

	if err = setDefaultSockopts(s, family, syscall.SOCK_STREAM, ipv6only); err != nil {
		closesocket(s)
		return nil, err
	}

	if err = setDefaultListenerSockopts(s); err != nil {
		closesocket(s)
		return nil, err
	}

	for _, tuner := range tuners {
		if err := tuner(s); err != nil {
			return nil, err
		}
	}

	if err = syscall.Bind(s, socketAddr); err != nil {
		closesocket(s)
		return nil, err
	}

	if err = syscall.Listen(s, maxListenerBacklog()); err != nil {
		closesocket(s)
		return nil, err
	}

	file := os.NewFile(uintptr(s), "listener-"+laddr.String())
	defer file.Close()

	var socketListener Listener
	if socketListener, err = FileListener(file); err != nil {
		return nil, err
	}

	return socketListener, nil
}
Пример #13
0
// NewReusablePortListener returns net.FileListener that created from a file discriptor for a socket with SO_REUSEPORT option.
func NewReusablePortListener(proto, addr string) (l net.Listener, err error) {
	var (
		soType, fd int
		file       *os.File
		sockaddr   syscall.Sockaddr
	)

	if sockaddr, soType, err = getSockaddr(proto, addr); err != nil {
		return nil, err
	}

	if fd, err = syscall.Socket(soType, syscall.SOCK_STREAM, syscall.IPPROTO_TCP); err != nil {
		return nil, err
	}

	defer func() {
		if err != nil {
			syscall.Close(fd)
		}
	}()

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		return nil, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, reusePort, 1); err != nil {
		return nil, err
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, listenerBacklog); err != nil {
		return nil, err
	}

	// File Name get be nil
	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if l, err = net.FileListener(file); err != nil {
		return nil, err
	}

	if err = file.Close(); err != nil {
		return nil, err
	}

	return l, err
}
Пример #14
0
// ListenTCP announces on the TCP address laddr and returns a TCP listener.
// Net must be "tcp", "tcp4", or "tcp6".
// If laddr has a port of 0, it means to listen on some available port.
// The caller can use l.Addr() to retrieve the chosen address.
func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
	fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
	if err != nil {
		return nil, err
	}
	err = syscall.Listen(fd.sysfd, listenerBacklog)
	if err != nil {
		closesocket(fd.sysfd)
		return nil, &OpError{"listen", net, laddr, err}
	}
	l := new(TCPListener)
	l.fd = fd
	return l, nil
}
Пример #15
0
// ListenTCP announces on the TCP address laddr and returns a TCP listener.
// Net must be "tcp", "tcp4", or "tcp6".
// If laddr has a port of 0, it means to listen on some available port.
// The caller can use l.Addr() to retrieve the chosen address.
func ListenTCP(net string, laddr *TCPAddr) (l *TCPListener, err os.Error) {
	fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_STREAM, "listen", sockaddrToTCP)
	if err != nil {
		return nil, err
	}
	errno := syscall.Listen(fd.sysfd, listenBacklog())
	if errno != 0 {
		syscall.Close(fd.sysfd)
		return nil, &OpError{"listen", "tcp", laddr, os.Errno(errno)}
	}
	l = new(TCPListener)
	l.fd = fd
	return l, nil
}
Пример #16
0
/*-----------------------------------------------------------------------------
-- FUNCTION:    manageConnections
--
-- DATE:        February 7, 2016
--
-- REVISIONS:	  February 11, 2016 Modified for EPoll
--
--
-- DESIGNER:		Marc Vouve
--
-- PROGRAMMER:	Marc Vouve
--
-- INTERFACE:   func manageConnections(srvInfo serverInfo, osSignals chan os.Signal)
--	 srvInfo:   information about the server (IPC and listening port)
-- osSignals:	  listens for signals from the OS that should stop the server from running
--
-- RETURNS:     void
--
-- NOTES:			This server will loop until inturupted by an OS Signal on soSignals.
------------------------------------------------------------------------------*/
func newServerInfo() serverInfo {
	srvInfo := serverInfo{serverConnection: make(chan int, 100), connectInfo: make(chan connectionInfo, 100)}
	fd, err := syscall.Socket(syscall.AF_INET, syscall.O_NONBLOCK|syscall.SOCK_STREAM, 0)
	if err != nil {
		log.Println(err)
	}
	syscall.SetNonblock(fd, true)
	// TODO: make port vairable
	addr := getAddr()
	syscall.Bind(fd, &addr)
	syscall.Listen(fd, backlog)
	srvInfo.listener = fd

	return srvInfo
}
Пример #17
0
// ListenUnix announces on the Unix domain socket laddr and returns a Unix listener.
// Net must be "unix" (stream sockets).
func ListenUnix(net string, laddr *UnixAddr) (l *UnixListener, err error) {
	if net != "unix" && net != "unixgram" && net != "unixpacket" {
		return nil, UnknownNetworkError(net)
	}
	if laddr != nil {
		laddr = &UnixAddr{laddr.Name, net} // make our own copy
	}
	fd, err := unixSocket(net, laddr, nil, "listen")
	if err != nil {
		return nil, err
	}
	e1 := syscall.Listen(fd.sysfd, 8) // listenBacklog());
	if e1 != 0 {
		closesocket(fd.sysfd)
		return nil, &OpError{Op: "listen", Net: "unix", Addr: laddr, Err: os.Errno(e1)}
	}
	return &UnixListener{fd, laddr.Name}, nil
}
Пример #18
0
// ListenUnix announces on the Unix domain socket laddr and returns a Unix listener.
// Net must be "unix" (stream sockets).
func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
	if net != "unix" && net != "unixgram" && net != "unixpacket" {
		return nil, UnknownNetworkError(net)
	}
	if laddr != nil {
		laddr = &UnixAddr{laddr.Name, net} // make our own copy
	}
	fd, err := unixSocket(net, laddr, nil, "listen")
	if err != nil {
		return nil, err
	}
	err = syscall.Listen(fd.sysfd, listenerBacklog)
	if err != nil {
		closesocket(fd.sysfd)
		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
	}
	return &UnixListener{fd, laddr.Name}, nil
}
Пример #19
0
func main() {
	fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC|syscall.SOCK_NONBLOCK, syscall.IPPROTO_TCP)
	if err != nil {
		log.Fatalln("Cannot create socket:", err)
	}

	err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
	if err != nil {
		log.Fatalln("Cannot setsockopt:", err)
	}

	sa := &syscall.SockaddrInet4{
		Port: 12345,     // Listen on this port number
		Addr: [4]byte{}, // Listen to all IPs
	}

	err = syscall.Bind(fd, sa)
	if err != nil {
		log.Fatalln("Cannot bind to socket:", err)
	}

	err = syscall.Listen(fd, 10)
	if err != nil {
		log.Fatalln("Cannot listen to socket:", err)
	}

	// TODO select

	/*
		go func() {
			x, raddr, err := syscall.Accept(fd)
			if err != nil {
				log.Fatalln("Cannot listen to socket:", err)
			}

			log.Printf("received:")
			log.Printf("%#v", raddr)
			log.Printf("%#v", x)
		}()
	*/

}
Пример #20
0
// ListenUnix announces on the Unix domain socket laddr and returns a
// Unix listener.  The network net must be "unix", "unixgram" or
// "unixpacket".
func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
	switch net {
	case "unix", "unixgram", "unixpacket":
	default:
		return nil, UnknownNetworkError(net)
	}
	if laddr == nil {
		return nil, &OpError{"listen", net, nil, errMissingAddress}
	}
	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
	if err != nil {
		return nil, err
	}
	err = syscall.Listen(fd.sysfd, listenerBacklog)
	if err != nil {
		closesocket(fd.sysfd)
		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
	}
	return &UnixListener{fd, laddr.Name}, nil
}
Пример #21
0
// ListenTCP announces on the TCP address laddr and returns a TCP listener.
// Net must be "tcp", "tcp4", or "tcp6".
// If laddr has a port of 0, it means to listen on some available port.
// The caller can use l.Addr() to retrieve the chosen address.
func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
	switch net {
	case "tcp", "tcp4", "tcp6":
	default:
		return nil, UnknownNetworkError(net)
	}
	if laddr == nil {
		laddr = &TCPAddr{}
	}
	fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
	if err != nil {
		return nil, err
	}
	err = syscall.Listen(fd.sysfd, listenerBacklog)
	if err != nil {
		closesocket(fd.sysfd)
		return nil, &OpError{"listen", net, laddr, err}
	}
	return &TCPListener{fd}, nil
}
Пример #22
0
func main() {
	check(os.MkdirAll(FOLDER, 0777))

	// Initialisation des variables serveur
	lastUpdate = time.Date(1994, time.April, 2, 2, 0, 0, 0, time.UTC)
	dat, err := ioutil.ReadFile(LASTUPFOLDER)
	if err == nil {
		err = json.Unmarshal(dat, &lastUpdate)
		check(err)
	}

	envoi = &sync.Mutex{}
	err = util.ScanDir(FOLDER, &mainFolder)
	check(err)

	// création du socket d'écoute
	fd, err := s.Socket(s.AF_INET, s.SOCK_STREAM, 0)
	if err != nil {
		check(err)
	}
	defer s.Close(fd)
	if err := s.Bind(fd, &s.SockaddrInet4{Port: PORT, Addr: [4]byte{0, 0, 0, 0}}); err != nil {
		check(err)
	}

	if err := s.Listen(fd, 5); err != nil {
		check(err)
	}

	// Lancement de l'écoute du serveur
	fmt.Println("Serveur lancé !")
	for {
		nfd, sa, err := s.Accept(fd)
		if err != nil {
			check(err)
		}
		envoi.Lock()
		go app(nfd, sa)
		envoi.Unlock()
	}
}
Пример #23
0
func (fd *netFD) listenStream(laddr sockaddr, backlog int, toAddr func(syscall.Sockaddr) Addr) 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 := syscall.Listen(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(toAddr(lsa), nil)
	return nil
}
Пример #24
0
// ListenUnix announces on the Unix domain socket laddr and returns a Unix listener.
// Net must be "unix" (stream sockets).
func ListenUnix(net string, laddr *UnixAddr) (l *UnixListener, err os.Error) {
	if net != "unix" && net != "unixgram" {
		return nil, UnknownNetworkError(net)
	}
	if laddr != nil {
		laddr = &UnixAddr{laddr.Name, net == "unixgram"} // make our own copy
	}
	fd, e := unixSocket(net, laddr, nil, "listen")
	if e != nil {
		if pe, ok := e.(*os.PathError); ok {
			e = pe.Error
		}
		return nil, e
	}
	e1 := syscall.Listen(fd.sysfd, 8) // listenBacklog());
	if e1 != 0 {
		syscall.Close(fd.sysfd)
		return nil, &OpError{"listen", "unix", laddr, os.Errno(e1)}
	}
	return &UnixListener{fd, laddr.Name}, nil
}
Пример #25
0
// ReusableListen returns a TCP listener with SO_REUSEPORT and keepalives
// enabled.
func ReusableListen(proto, addr string) (net.Listener, error) {
	backlogOnce.Do(func() {
		backlog = maxListenerBacklog()
	})

	saddr, typ, err := sockaddr(proto, addr)
	if err != nil {
		return nil, err
	}

	fd, err := syscall.Socket(typ, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
	if err != nil {
		return nil, err
	}

	if err := setSockopt(fd); err != nil {
		return nil, err
	}

	if err := syscall.Bind(fd, saddr); err != nil {
		return nil, err
	}

	if err := syscall.Listen(fd, backlog); err != nil {
		return nil, err
	}

	f := os.NewFile(uintptr(fd), proto+":"+addr)
	l, err := net.FileListener(f)
	if err != nil {
		return nil, err
	}

	if err := f.Close(); err != nil {
		l.Close()
		return nil, err
	}

	return l, nil
}
Пример #26
0
// NewReusablePortListener returns net.FileListener that created from a file discriptor for a socket with SO_REUSEPORT option.
func newSocket(proto, addr string) (file *os.File, err error) {
	var (
		soType, fd int
		sockaddr   syscall.Sockaddr
	)

	if sockaddr, soType, err = getSockaddr(proto, addr); err != nil {
		return nil, err
	}

	if proto == "tcp" || proto == "tcp4" || proto == "tcp6" {
		if fd, err = syscall.Socket(soType, syscall.SOCK_STREAM, syscall.IPPROTO_TCP); err != nil {
			return nil, err
		}
	} else {
		if fd, err = syscall.Socket(soType, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP); err != nil {
			return nil, err
		}
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, reusePort, 1); err != nil {
		return nil, err
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		return nil, err
	}

	if proto == "tcp" || proto == "tcp4" || proto == "tcp6" {
		// Set backlog size to the maximum
		if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
			return nil, err
		}
	}

	// File Name get be nil
	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	return file, err
}
Пример #27
0
// dialExec will ForkExec a new process, and returns a wsConn that connects to its stdin
func dialExec(binpath string) (rwc io.ReadWriteCloser, err os.Error) {
	listenBacklog := 1024
	dir, file := path.Split(binpath)
	socketPath := "/tmp/" + file + ".sock"
	socketIndex := 0 // if the first socket is really in use (we are launching this same process more than once)
	// then the socketIndex will start incrementing so we assign .sock-1 to the second process, etc
	for {
		err := os.Remove(socketPath)
		// if the socket file is stale, but not in use, the Remove succeeds with no error
		if err == nil {
			goto haveSocket // success, found a stale socket we can re-use
		}
		// otherwise we have to check what the error was
		switch err.String() {
		case "remove " + socketPath + ": no such file or directory":
			goto haveSocket // success, we have found an unused socket.
		default:
			// if its really in use, we start incrementing socketIndex
			socketIndex += 1
			socketPath = "/tmp/" + file + ".sock-" + strconv.Itoa(socketIndex)
			Log("Socket was in use, trying:", socketPath)
		}
	}
haveSocket:
	var fd, cfd, errno int
	var sa syscall.Sockaddr
	// we can almost use UnixListener to do this except it doesn't expose the fd it's listening on
	// create a new socket
	if fd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 {
		Log("Creating first new socket failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("Creating first new socket failed:", syscall.Errstr(errno)))
	}
	// bind the new socket to socketPath
	if errno = syscall.Bind(fd, &syscall.SockaddrUnix{Name: socketPath}); errno != 0 {
		Log("Bind failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("Bind failed:", syscall.Errstr(errno)))
	}
	// start to listen on that socket
	if errno = syscall.Listen(fd, listenBacklog); errno != 0 {
		Log("Listen failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("Listen failed:", syscall.Errstr(errno)))
	}
	// then ForkExec a new process, and give this listening socket to them as stdin
	// DEBUG: for now, give the new process our stdout, and stderr, but the spec says these should be closed
	// in reality, we should redirect, capture, and possibly log separately
	if _, errno = syscall.ForkExec(file, []string{}, []string{}, dir, []int{fd, 1, 2}); errno != 0 {
		Log("ForkExec failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("ForkExec failed:", syscall.Errstr(errno)))
	}
	// now create a socket for the client-side of the connection
	if cfd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 {
		Log("Creating new socket on webserver failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("Creating new socket on webserver failed:", syscall.Errstr(errno)))
	}
	// find the address of the socket we gave the new process
	if sa, errno = syscall.Getsockname(fd); errno != 0 {
		Log("Getsockname failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("Getsockname failed:", syscall.Errstr(errno)))
	}
	// connect our client side to the remote address
	if errno = syscall.Connect(cfd, sa); errno != 0 {
		Log("Connect failed:", syscall.Errstr(errno))
		return nil, os.NewError(fmt.Sprint("Connect failed:", syscall.Errstr(errno)))
	}
	// return a wrapper around the client side of this connection
	rwc = os.NewFile(cfd, "exec://"+binpath)
	return rwc, nil
}
Пример #28
0
// dialExec will ForkExec a new process, and returns a wsConn that connects to its
// stdin
func dialExec(binpath string) (io.ReadWriteCloser, os.Error) {
	listenBacklog := 1024
	dir, file := path.Split(binpath)
	socketPath := "/tmp/" + file + ".sock"
	// if the first socket is really in use (we are launching this same process more
	// than once) then the socketIndex will start incrementing so we assign .sock-1
	// to the second process, etc
	socketIndex := 0
	err := os.Remove(socketPath)
	// if the socket file is stale but not in use,
	// Remove succeeds with no error
	for err != nil {
		pe, ok := err.(*os.PathError)
		if ok && pe.Error == os.ENOENT {
			// success, found a stale socket we can re-use
			break
		}
		// if it's really in use, we start incrementing socketIndex
		socketIndex++
		socketPath = "/tmp/" + file + ".sock-" + strconv.Itoa(socketIndex)
		Log("Socket was in use, trying:", socketPath)
		err = os.Remove(socketPath)
	}

	var fd, cfd, errno int
	var sa syscall.Sockaddr
	// we can almost use UnixListener to do this except it doesn't expose the fd
	// it's listening on
	// create a new socket
	if fd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 {
		msg := "Creating first new socket failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// bind the new socket to socketPath
	if errno = syscall.Bind(fd, &syscall.SockaddrUnix{Name: socketPath}); errno != 0 {
		msg := "Bind failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// start to listen on that socket
	if errno = syscall.Listen(fd, listenBacklog); errno != 0 {
		msg := "Listen failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// then ForkExec a new process, and give this listening socket to them as stdin
	// DEBUG: for now, give the new process our stdout, and stderr, but the spec
	// says these should be closed
	// in reality, we should redirect, capture, and possibly log separately
	if _, errno = syscall.ForkExec(file, []string{}, []string{}, dir, []int{fd, 1, 2}); errno != 0 {
		msg := "ForkExec failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// now create a socket for the client-side of the connection
	if cfd, errno = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0); errno != 0 {
		msg := "Creating new socket on webserved failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// find the address of the socket we gave the new process
	if sa, errno = syscall.Getsockname(fd); errno != 0 {
		msg := "Getsockname failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// connect our client side to the remote address
	if errno = syscall.Connect(cfd, sa); errno != 0 {
		msg := "Connected failed: " + syscall.Errstr(errno)
		Log(msg)
		return nil, os.NewError(msg)
	}
	// return a wrapper around the client side of this connection
	rwc := os.NewFile(cfd, "exec://"+binpath)
	return rwc, nil
}
Пример #29
0
func Listen(rendezvousAddr string, key string) (net.Listener, error) {
	raddr, err := net.ResolveTCPAddr("tcp", rendezvousAddr)
	if err != nil {
		return nil, err
	}

	rsockaddr, domain, err := tcpaddrToSockaddr(raddr)
	if err != nil {
		return nil, err
	}

	sendSock, err := syscall.Socket(domain, syscall.SOCK_STREAM, 0)
	if err != nil {
		return nil, err
	}

	if err := syscall.SetsockoptInt(
		sendSock, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1,
	); err != nil {
		return nil, err
	}

	if err := syscall.Connect(sendSock, rsockaddr); err != nil {
		return nil, err
	}

	lsockaddr, err := syscall.Getsockname(sendSock)
	if err != nil {
		return nil, err
	}

	listenSock, err := syscall.Socket(domain, syscall.SOCK_STREAM, 0)
	if err != nil {
		return nil, err
	}

	if err := syscall.SetsockoptInt(
		listenSock, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1,
	); err != nil {
		return nil, err
	}

	if err := syscall.Bind(listenSock, lsockaddr); err != nil {
		return nil, err
	}

	if err := syscall.Listen(listenSock, 1000); err != nil {
		return nil, err
	}

	sendFile := os.NewFile(uintptr(sendSock), "rendezvous-send")
	listenFile := os.NewFile(uintptr(listenSock), "rendezvous-listen")

	rendezvousConn, err := net.FileConn(sendFile)
	if err != nil {
		return nil, err
	}

	encoder := json.NewEncoder(rendezvousConn)

	message := map[string]string{
		"action": "listen",
		"key":    key,
	}

	if err := encoder.Encode(&message); err != nil {
		return nil, err
	}

	return net.FileListener(listenFile)
}
Пример #30
0
var initStep = [...]InitStep{
	{
		ErrFmt: "Create epoll fd error [%s]\n",
		Action: func(t *Tunnel) (err error) {
			t.LFd, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
			return err
		}},
	{
		ErrFmt: "Bind epoll fd error [%s]\n",
		Action: func(t *Tunnel) error {
			return syscall.Bind(t.LFd, &syscall.SockaddrInet4{Port: int(t.EPort), Addr: [4]byte{0, 0, 0, 0}})
		}},
	{
		ErrFmt: "Listen fd error [%s]\n",
		Action: func(t *Tunnel) error {
			return syscall.Listen(t.LFd, 10)
		}},
	{
		ErrFmt: "Add fd to epoll error [%s]\n",
		Action: func(t *Tunnel) error {
			return syscall.EpollCtl(epollFd, syscall.EPOLL_CTL_ADD, t.LFd, &syscall.EpollEvent{Events: syscall.EPOLLIN, Fd: int32(t.LFd)})
		}},
}

var pathAddStep = [...]TunnelStep{
	{
		ErrFmt: "Port [%d] accept error [%s]",
		Action: func(tc *TunnelConn) (err error) {
			tc.EFd, _, err = syscall.Accept(tc.RelTunnel.LFd)
			return
		}},