func (self *UdpInput) Init(config interface{}) error { self.config = config.(*UdpInputConfig) if len(self.config.Address) > 3 && self.config.Address[:3] == "fd:" { // File descriptor fdStr := self.config.Address[3:] fdInt, err := strconv.ParseUint(fdStr, 0, 0) if err != nil { log.Println(err) return fmt.Errorf("Invalid file descriptor: %s", self.config.Address) } fd := uintptr(fdInt) udpFile := os.NewFile(fd, "udpFile") self.listener, err = net.FileConn(udpFile) if err != nil { return fmt.Errorf("Error accessing UDP fd: %s\n", err.Error()) } } else { // IP address udpAddr, err := net.ResolveUDPAddr("udp", self.config.Address) if err != nil { return fmt.Errorf("ResolveUDPAddr failed: %s\n", err.Error()) } self.listener, err = net.ListenUDP("udp", udpAddr) if err != nil { return fmt.Errorf("ListenUDP failed: %s\n", err.Error()) } } return nil }
func NewUdpGobInput(addrStr string, fd *uintptr) *UdpGobInput { var listener net.Conn if *fd != 0 { udpFile := os.NewFile(*fd, "udpFile") fdConn, err := net.FileConn(udpFile) if err != nil { log.Printf("Error accessing UDP fd: %s\n", err.Error()) return nil } listener = fdConn } else { udpAddr, err := net.ResolveUDPAddr("udp", addrStr) if err != nil { log.Printf("ResolveUDPAddr failed: %s\n", err.Error()) return nil } listener, err = net.ListenUDP("udp", udpAddr) if err != nil { log.Printf("ListenUDP failed: %s\n", err.Error()) return nil } } decoder := gob.NewDecoder(listener) return &UdpGobInput{listener: &listener, decoder: decoder} }
func newFakeVTYServer() (*fakeVTYServer, error) { fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) if err != nil { return nil, err } vtyClientFile := os.NewFile(uintptr(fds[1]), "vty-client") vtyClientConn, err := net.FileConn(vtyClientFile) if err != nil { return nil, err } vtyServerFile := os.NewFile(uintptr(fds[0]), "vty-server") vtyServerConn, err := net.FileConn(vtyServerFile) if err != nil { return nil, err } syscall.SetNonblock(fds[0], false) vs := &fakeVTYServer{ clientConn: vtyClientConn, serverConn: vtyServerConn, clientFile: vtyClientFile, serverFile: vtyServerFile, send: make(chan []byte), received: make(chan []byte), } go vs.read() go vs.write() return vs, nil }
// Attempt to hijack session previously running bot func (irc *IrcCon) HijackSession() bool { unaddr, err := net.ResolveUnixAddr("unix", irc.unixastr) if err != nil { irc.Log(LWarning, "could not resolve unix socket") return false } con, err := net.DialUnix("unix", nil, unaddr) if err != nil { fmt.Println("Couldnt restablish connection, no prior bot.") fmt.Println(err) return false } ncon, err := sendfd.RecvFD(con) if err != nil { panic(err) } netcon, err := net.FileConn(ncon) if err != nil { panic(err) } irc.reconnect = true irc.con = netcon return true }
func (g *graphiteUdpTextServiceManager) Start(file *os.File) error { var ( err error udpAddr *net.UDPAddr ) if g.listenSpec != "" { if file != nil { g.conn, err = net.FileConn(file) } else { udpAddr, err = net.ResolveUDPAddr("udp", processListenSpec(g.listenSpec)) if err == nil { g.conn, err = net.ListenUDP("udp", udpAddr) } } } else { log.Printf("Not starting Graphite UDP protocol because graphite-udp-listen-spec is blank.") return nil } if err != nil { return fmt.Errorf("Error starting Graphite UDP Text Protocol serviceManager: %v", err) } fmt.Printf("Graphite UDP protocol Listening on %s\n", processListenSpec(g.listenSpec)) // for UDP timeout must be 0 go handleGraphiteTextProtocol(g.rcvr, g.conn, 0) return nil }
// dial tcp with tcp fastopen // 第一个包体积不要太大,需要小于一定数量,否则会被吃掉(正确性问题), // 如果过大,此处会在连接时发送前一部分,连接后又发送一部分 func TfoDial(nextAddr string, data []byte) (conn net.Conn, err error) { s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM, 0) if err != nil { return nil, err } defer unix.Close(s) sa, err := kmgUnix.IPv4TcpAddrToUnixSocksAddr(nextAddr) if err != nil { return nil, err } if len(data) <= tfoFirstSize { err = unix.Sendto(s, data, unix.MSG_FASTOPEN, sa) if err != nil { return } } else { err = unix.Sendto(s, data[:tfoFirstSize], unix.MSG_FASTOPEN, sa) if err != nil { return } } f := os.NewFile(uintptr(s), "TFODial") defer f.Close() conn, err = net.FileConn(f) if err != nil { return } if len(data) > tfoFirstSize { _, err = conn.Write(data[tfoFirstSize:]) if err != nil { return nil, err } } return conn, nil }
func (g *statsdUdpTextServiceManager) Start(file *os.File) error { var ( err error udpAddr *net.UDPAddr ) if config.StatsdUdpListenSpec != "" { if file != nil { g.conn, err = net.FileConn(file) } else { udpAddr, err = net.ResolveUDPAddr("udp", config.StatsdUdpListenSpec) if err == nil { g.conn, err = net.ListenUDP("udp", udpAddr) } } } else { log.Printf("Not starting Statsd UDP protocol because statsd-udp-listen-spec is blank.") return nil } if err != nil { return fmt.Errorf("Error starting Statsd UDP Text Protocol serviceManager: %v", err) } fmt.Printf("Statsd UDP protocol Listening on %s\n", config.StatsdTextListenSpec) // for UDP timeout must be 0 go handleStatsdTextProtocol(g.t, g.conn, 0) return nil }
func (o *Object) Connect() (net.Conn, error) { ret, err := o.Send(&Message{Verb: Connect, Ret: RetPipe}) if err != nil { return nil, err } // FIXME: set Att msg, err := ret.Receive(0) if err == io.EOF { return nil, fmt.Errorf("unexpected EOF") } if msg.Verb == Connect { if msg.Att == nil { return nil, fmt.Errorf("missing attachment") } conn, err := net.FileConn(msg.Att) if err != nil { msg.Att.Close() return nil, err } msg.Att.Close() return conn, nil } if msg.Verb == Error { return nil, fmt.Errorf(strings.Join(msg.Args[:1], "")) } return nil, fmt.Errorf("unexpected verb %v", msg.Verb) }
func LessDelayTcpConn(conn *net.TCPConn) (connOut net.Conn, err error) { //err = conn.SetKeepAlive(true) //if err!=nil{ // kmgErr.LogErrorWithStack(err) // return nil,err //} //err = conn.SetKeepAlivePeriod(5*time.Second) //5s太小,耗流量非常凶残. //if err!=nil{ // kmgErr.LogErrorWithStack(err) // return nil,err //} fd, err := conn.File() if err != nil { kmgErr.LogErrorWithStack(err) return } conn1, err := net.FileConn(fd) if err != nil { fd.Close() kmgErr.LogErrorWithStack(err) return } conn.Close() //尝试将连接重新设置回 block 模式,减少cpu占用,此方案不稳定,并且不知道如何解决不稳定的问题. //err = unix.SetNonblock(int(fd.Fd()),true) //if err!=nil{ // fd.Close() // kmgErr.LogErrorWithStack(err) // return nil,err //} //return NewDebugConn(fasterTcpConn{TCPConn: conn, fd: fd},conn.LocalAddr().String()+"_"+conn.RemoteAddr().String()), nil return &fasterTcpConn{TCPConn: conn1.(*net.TCPConn), fd: fd}, nil }
func createAttachment(stream *spdystream.Stream) (*os.File, error) { if stream.IsFinished() { return nil, fmt.Errorf("stream already finished") } socketFds, socketErr := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.FD_CLOEXEC, 0) if socketErr != nil { return nil, socketErr } pipe := os.NewFile(uintptr(socketFds[1]), "") defer pipe.Close() conn, connErr := net.FileConn(pipe) if connErr != nil { return nil, connErr } go func() { io.Copy(conn, stream) conn.Close() }() go func() { io.Copy(stream, conn) }() return os.NewFile(uintptr(socketFds[0]), ""), nil }
// getConn checks if the file descriptor at the given offset is a socket and // returns a net.Conn bound to this file descriptor. func getConn(num int) (conn net.Conn, err error) { fd := listenFdsStart + num f := osm.NewFile(uintptr(fd), "") conn, err = net.FileConn(f) f.Close() return conn, err }
func mount(dir string, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) { // linux mount is never delayed close(ready) fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0) if err != nil { return nil, fmt.Errorf("socketpair error: %v", err) } defer syscall.Close(fds[0]) defer syscall.Close(fds[1]) cmd := exec.Command("fusermount", "--", dir) cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3") writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes") defer writeFile.Close() cmd.ExtraFiles = []*os.File{writeFile} out, err := cmd.CombinedOutput() if len(out) > 0 || err != nil { return nil, fmt.Errorf("fusermount: %q, %v", out, err) } readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads") defer readFile.Close() c, err := net.FileConn(readFile) if err != nil { return nil, fmt.Errorf("FileConn from fusermount socket: %v", err) } defer c.Close() uc, ok := c.(*net.UnixConn) if !ok { return nil, fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c) } buf := make([]byte, 32) // expect 1 byte oob := make([]byte, 32) // expect 24 bytes _, oobn, _, _, err := uc.ReadMsgUnix(buf, oob) scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) if err != nil { return nil, fmt.Errorf("ParseSocketControlMessage: %v", err) } if len(scms) != 1 { return nil, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms) } scm := scms[0] gotFds, err := syscall.ParseUnixRights(&scm) if err != nil { return nil, fmt.Errorf("syscall.ParseUnixRights: %v", err) } if len(gotFds) != 1 { return nil, fmt.Errorf("wanted 1 fd; got %#v", gotFds) } f := os.NewFile(uintptr(gotFds[0]), "/dev/fuse") return f, nil }
func (tl *TCPListener) Accept() (fd int, conn net.Conn, err error) { cpointer, err := tl.Listener.AcceptTCP() if err != nil { return } file, err := cpointer.File() fd = int(file.Fd()) conn, err = net.FileConn(file) return }
func (c *Container) followLogs(log log15.Logger, buffer host.LogBuffer) error { c.l.logStreamMtx.Lock() defer c.l.logStreamMtx.Unlock() if _, ok := c.l.logStreams[c.job.ID]; ok { return nil } log.Info("getting stdout") stdout, stderr, initLog, err := c.Client.GetStreams() if err != nil { log.Error("error getting streams", "err", err) return err } nonblocking := func(file *os.File) (net.Conn, error) { // convert to a net.Conn so we do non-blocking I/O on the fd and Close // will make calls to Read return straight away (using read(2) would // not have this same behaviour, meaning we could potentially read // from the stream after we have closed and returned the buffer). defer file.Close() return net.FileConn(file) } muxConfig := logmux.Config{ AppID: c.job.Metadata["flynn-controller.app"], HostID: c.l.state.id, JobType: c.job.Metadata["flynn-controller.type"], JobID: c.job.ID, } logStreams := make(map[string]*logmux.LogStream, 3) stdoutR, err := nonblocking(stdout) if err != nil { log.Error("error streaming stdout", "err", err) return err } logStreams["stdout"] = c.l.mux.Follow(stdoutR, buffer["stdout"], 1, muxConfig) stderrR, err := nonblocking(stderr) if err != nil { log.Error("error streaming stderr", "err", err) return err } logStreams["stderr"] = c.l.mux.Follow(stderrR, buffer["stderr"], 2, muxConfig) initLogR, err := nonblocking(initLog) if err != nil { log.Error("error streaming initial log", "err", err) return err } logStreams["initLog"] = c.l.mux.Follow(initLogR, buffer["initLog"], 3, muxConfig) c.l.logStreams[c.job.ID] = logStreams return nil }
//Listen advertises a single protocol, proto, in the directory the server //was created with. It will invoke handler in a new goroutine every time //a fd representing a tcp socket is sent down the unix domain socket //created at dir/proto by an instance of etnsrv on dir. // //Warning: if there is an existing file named dir/proto it will be deleted. // //It is safe to call multiple times on same server, with different proto. func (s *Server) Listen(proto string, handler func(*net.TCPConn) error) error { if len(proto) > 255 { return etsn.ErrProtocolIdentifierTooLong } nm := filepath.Join(s.dir, proto) if err := os.Remove(nm); err != nil { pe := err.(*os.PathError) if pe.Err.Error() != "no such file or directory" { return err } } c, err := net.Listen("unix", nm) if err != nil { return err } ul := c.(*net.UnixListener) for { conn, err := ul.AcceptUnix() if err != nil { //BUG(jmf) There are surely many an error that should lead to //us breaking out of the listen loop. For example if another //process deletes our socket s.log(err) continue } fs, err := fd.Get(conn, 1, nil) if err != nil { s.log(err) continue } if len(fs) != 1 { s.log(errors.New("Did not receive exactly one fd")) continue } f := fs[0] ic, err := net.FileConn(f) if err != nil { f.Close() s.log(err) continue } s.log(f.Close()) tcp, ok := ic.(*net.TCPConn) if !ok { s.log(errors.New("Received invalid socket type")) ic.Close() continue } go s.log(handler(tcp)) } }
func (tl *TLSListener) Accept() (fd int, conn net.Conn, err error) { cpointer, err := tl.Listener.AcceptTCP() if err != nil { return } file, err := cpointer.File() fd = int(file.Fd()) fconn, err := net.FileConn(file) conn = tls.Server(fconn, tl.Config) return }
func getAttachment() (io.ReadWriteCloser, *os.File, error) { f1, f2, err := unix.SocketPair() if err != nil { return nil, nil, err } fConn, err := net.FileConn(f1) if err != nil { return nil, nil, err } return fConn, f2, nil }
// bindLookupIP implements the BindToDevice LookupIP case. // To implement socket device binding, the lower-level syscall APIs are used. // The sequence of syscalls in this implementation are taken from: // https://code.google.com/p/go/issues/detail?id=6966 func bindLookupIP(host string, config *DialConfig) (addrs []net.IP, err error) { // When the input host is an IP address, echo it back ipAddr := net.ParseIP(host) if ipAddr != nil { return []net.IP{ipAddr}, nil } socketFd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) if err != nil { return nil, ContextError(err) } defer syscall.Close(socketFd) err = config.DeviceBinder.BindToDevice(socketFd) if err != nil { return nil, ContextError(fmt.Errorf("BindToDevice failed: %s", err)) } // config.DnsServerGetter.GetDnsServer must return an IP address ipAddr = net.ParseIP(config.DnsServerGetter.GetDnsServer()) if ipAddr == nil { return nil, ContextError(errors.New("invalid IP address")) } // TODO: IPv6 support var ip [4]byte copy(ip[:], ipAddr.To4()) sockAddr := syscall.SockaddrInet4{Addr: ip, Port: DNS_PORT} // Note: no timeout or interrupt for this connect, as it's a datagram socket err = syscall.Connect(socketFd, &sockAddr) if err != nil { return nil, ContextError(err) } // Convert the syscall socket to a net.Conn, for use in the dns package file := os.NewFile(uintptr(socketFd), "") defer file.Close() conn, err := net.FileConn(file) if err != nil { return nil, ContextError(err) } // Set DNS query timeouts, using the ConnectTimeout from the overall Dial if config.ConnectTimeout != 0 { conn.SetReadDeadline(time.Now().Add(config.ConnectTimeout)) conn.SetWriteDeadline(time.Now().Add(config.ConnectTimeout)) } // TODO: make conn interruptible? addrs, _, err = ResolveIP(host, conn) return }
func ReadUnixConn(c *net.UnixConn, timeout time.Duration) (*net.UnixConn, error) { file, err := ReadFile(c, timeout) if err != nil { return nil, err } defer checkClose(file) fdConn, err := net.FileConn(file) if err != nil { return nil, err } return fdConn.(*net.UnixConn), nil }
func UdpTProxyConn(listenAddr string) (udp *net.UDPConn, err error) { var c net.Conn s, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0) if err != nil { return nil, err } //Why close here ??? defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_BROADCAST, 1) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.SOL_IP, unix.IP_TRANSPARENT, 1) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.IPPROTO_IP, unix.IP_RECVORIGDSTADDR, 1) if err != nil { return nil, err } sa, err := IPv6TcpAddrToUnixSocksAddr(listenAddr) if err != nil { return nil, err } err = unix.Bind(s, sa) if err != nil { return nil, err } f := os.NewFile(uintptr(s), "TProxy") defer f.Close() c, err = net.FileConn(f) if err != nil { return nil, err } var ok bool if udp, ok = c.(*net.UDPConn); ok { return } else { c.Close() return nil, errors.New("type error") } }
func MakeUnixSocket(f *os.File) (*net.UnixConn, error) { fileConn, err := net.FileConn(f) if err != nil { return nil, err } unixConn, ok := fileConn.(*net.UnixConn) if !ok { return nil, errors.New(fmt.Sprintf("unexpected FileConn type; expected UnixConn, got %T", unixConn)) } return unixConn, nil }
func NewUsockFromFile(f *os.File) (*Usock, error) { fileConn, err := net.FileConn(f) if err != nil { return nil, err } unixConn, ok := fileConn.(*net.UnixConn) if !ok { return nil, errors.New(fmt.Sprintf("unexpected FileConn type; expected UnixConn, got %T", unixConn)) } return NewUsock(unixConn), nil }
func FileConn(f *os.File) (*UnixConn, error) { conn, err := net.FileConn(f) if err != nil { return nil, err } uconn, ok := conn.(*net.UnixConn) if !ok { conn.Close() return nil, fmt.Errorf("%d: not a unix connection", f.Fd()) } return &UnixConn{uconn}, nil }
func createStreamMessage(stream *spdystream.Stream, mode int, streamChans streamChanProvider, ret libchan.Sender) (*libchan.Message, error) { dataString := stream.Headers()["Data"] if len(dataString) != 1 { if len(dataString) == 0 { return nil, fmt.Errorf("Stream(%s) is missing data header", stream) } else { return nil, fmt.Errorf("Stream(%s) has multiple data headers", stream) } } data, decodeErr := base64.URLEncoding.DecodeString(dataString[0]) if decodeErr != nil { return nil, decodeErr } var attach *os.File if !stream.IsFinished() { socketFds, socketErr := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.FD_CLOEXEC, 0) if socketErr != nil { return nil, socketErr } attach = os.NewFile(uintptr(socketFds[0]), "") conn, connErr := net.FileConn(os.NewFile(uintptr(socketFds[1]), "")) if connErr != nil { return nil, connErr } go func() { io.Copy(conn, stream) }() go func() { io.Copy(stream, conn) }() } retSender := ret if retSender == nil || libchan.RetPipe.Equals(retSender) { retSender = &StreamSender{stream: stream, streamChans: streamChans} } if mode&libchan.Ret == 0 { retSender.Close() } return &libchan.Message{ Data: data, Fd: attach, Ret: retSender, }, nil }
func unixPair(typ int) (*net.UnixConn, *net.UnixConn) { fds, err := syscall.Socketpair(syscall.AF_UNIX, typ, 0) if err != nil { panic(os.NewSyscallError("socketpair", err)) } file := os.NewFile(uintptr(fds[0]), "") c0, err := net.FileConn(file) if err != nil { panic(err) } if err := file.Close(); err != nil { panic(err) } file = os.NewFile(uintptr(fds[1]), "") c1, err := net.FileConn(file) if err != nil { panic(err) } if err := file.Close(); err != nil { panic(err) } return c0.(*net.UnixConn), c1.(*net.UnixConn) }
func (u *UdpInput) Init(config interface{}) (err error) { u.config = config.(*UdpInputConfig) if u.config.Net == "unixgram" { if runtime.GOOS == "windows" { return errors.New( "Can't use Unix datagram sockets on Windows.") } unixAddr, err := net.ResolveUnixAddr(u.config.Net, u.config.Address) if err != nil { return fmt.Errorf("Error resolving unixgram address: %s", err) } u.listener, err = net.ListenUnixgram(u.config.Net, unixAddr) if err != nil { return fmt.Errorf("Error listening on unixgram: %s", err) } // Make sure socket file is world writable. if err = os.Chmod(u.config.Address, 0666); err != nil { return fmt.Errorf("Error changing unixgram socket permissions: %s", err) } } else if len(u.config.Address) > 3 && u.config.Address[:3] == "fd:" { // File descriptor fdStr := u.config.Address[3:] fdInt, err := strconv.ParseUint(fdStr, 0, 0) if err != nil { return fmt.Errorf("Error parsing file descriptor '%s': %s", u.config.Address, err) } fd := uintptr(fdInt) udpFile := os.NewFile(fd, "udpFile") u.listener, err = net.FileConn(udpFile) if err != nil { return fmt.Errorf("Error accessing UDP fd: %s\n", err.Error()) } } else { // IP address udpAddr, err := net.ResolveUDPAddr(u.config.Net, u.config.Address) if err != nil { return fmt.Errorf("ResolveUDPAddr failed: %s\n", err.Error()) } u.listener, err = net.ListenUDP(u.config.Net, udpAddr) if err != nil { return fmt.Errorf("ListenUDP failed: %s\n", err.Error()) } } u.stopChan = make(chan struct{}) return }
//Try to UnixConn-ify file proto in Where. func getConn(proto string) (*net.UnixConn, error) { file, err := os.Open(filepath.Join(*Where, proto)) if err != nil { return nil, err } conn, err := net.FileConn(file) if err != nil { return nil, err } uc, ok := conn.(*net.UnixConn) if !ok { return nil, fmt.Errorf("etsnsrv: %s is not a unix domain socket", proto) } return uc, nil }
// FdConn wraps a file descriptor in a standard *net.UnixConn object, or // returns an error if the file descriptor does not point to a unix socket. // This creates a duplicate file descriptor. It's the caller's responsibility // to close both. func FdConn(fd int) (n *net.UnixConn, err error) { { debugCheckpoint("===DEBUG=== FdConn([%d]) = (unknown fd). Hit enter to confirm: ", fd) } f := os.NewFile(uintptr(fd), fmt.Sprintf("%d", fd)) conn, err := net.FileConn(f) if err != nil { return nil, err } uconn, ok := conn.(*net.UnixConn) if !ok { conn.Close() return nil, fmt.Errorf("%d: not a unix connection", fd) } return uconn, nil }
// converts the protected connection specified by // socket fd to a net.Conn func (conn *ProtectedConn) convert() error { conn.mutex.Lock() file := os.NewFile(uintptr(conn.socketFd), "") // dup the fd and return a copy fileConn, err := net.FileConn(file) // closes the original fd file.Close() conn.socketFd = socketError if err != nil { conn.mutex.Unlock() return err } conn.Conn = fileConn conn.mutex.Unlock() return nil }
func testFileConn() { f, err := os.Open("test.dat") if err != nil { fmt.Println(err.Error()) return } defer f.Close() conn, err := net.FileConn(f) //将socket file(不是普通文件)转为Conn对象 if err != nil { fmt.Println(err.Error()) } defer conn.Close() reader := bufio.NewReader(conn) line, _, _ := reader.ReadLine() fmt.Println(string(line)) }