func (fd *Fd) readFrom(c *net.UnixConn) error { var b []byte oob := make([]byte, 16) _, oobn, _, _, err := c.ReadMsgUnix(b, oob) if err != nil { return err } if oobn == 0 { return errors.New("error reading oob") } oob = oob[:oobn] scms, err := syscall.ParseSocketControlMessage(oob) if err != nil { return err } if len(scms) != 1 { return fmt.Errorf("expected 1 SocketControlMessage, got %d", len(scms)) } scm := scms[0] fds, err := syscall.ParseUnixRights(&scm) if err != nil { return nil } if len(fds) != 1 { return fmt.Errorf("expected 1 fd, got %d", len(fds)) } *fd = Fd(fds[0]) return nil }
func (i *instance) connectionHandler(c *net.UnixConn) { defer c.Close() for { req, err := readRequest(c) if err == io.EOF { return // Client closed the connection. } if err != nil { glog.Errorln("Failed to read a message from socket:", err) } f, t := funcMap[req.Type] if t != true { sendError(c, fmt.Errorf("unknown request type")) continue } resp, err := f(i, req) if err != nil { sendError(c, err) continue } err = writeResponse(c, resp) if err != nil { glog.Errorln("Failed to write a message to socket:", err) return } } }
func writeData(conn *net.UnixConn, files []*os.File, pid int, responseErr error) { var errMsg string = "" if responseErr != nil { errMsg = responseErr.Error() } response := &Response{ Pid: pid, ErrMessage: errMsg, } responseJson, _ := json.Marshal(response) // Ignore error args := make([]int, len(files)) for i, f := range files { args[i] = int(f.Fd()) } resp := syscall.UnixRights(args...) conn.WriteMsgUnix(responseJson, resp, nil) // Ignore error // Close the files whose descriptors have been sent to the host to ensure that // a close on the host takes effect in a timely fashion. for _, file := range files { file.Close() // Ignore error } }
func RemoteRecvCredentials(conn *net.UnixConn) (uint32, uint32, error) { err := syscall.SetsockoptInt(sysfd(conn), syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1) if err != nil { return 0, 0, err } oob := make([]byte, len(syscall.UnixCredentials(&syscall.Ucred{}))) _, _, _, _, err = conn.ReadMsgUnix(nil, oob) if err != nil { return 0, 0, err } scm, err := syscall.ParseSocketControlMessage(oob) if err != nil { return 0, 0, err } ucred, err := syscall.ParseUnixCredentials(&scm[0]) if err != nil { return 0, 0, err } return ucred.Uid, ucred.Gid, nil }
func SendRequest(c *net.UnixConn, req *server.Request) error { payload, err := json.Marshal(req) if err != nil { return err } err = binary.Write(c, binary.BigEndian, uint32(len(payload))) if err != nil { return err } n, err := c.Write(payload) if err != nil { return err } else if n != len(payload) { return fmt.Errorf("Failed to write full payload, expected %v, wrote %v", len(payload), n) } if !req.HasFds { return nil } // Send filedescriptors with a 1 byte message. var oob []byte oob = syscall.UnixRights(req.Fds...) payload = make([]byte, 1) n, oobn, err := c.WriteMsgUnix(payload, oob, nil) if err != nil { return err } else if n != len(payload) || oobn != len(oob) { return fmt.Errorf("Error writing to socket, expected n=%v got %v, oob=%v got %v", len(payload), n, len(oob), oobn) } return nil }
func daemonIpcHandleConn(conn *net.UnixConn) { defer cluegetterRecover("daemonIpcHandleConn") defer conn.Close() for { message, err := bufio.NewReader(conn).ReadString('\x00') if err != nil { if message != "" { Log.Info("Got %s on IPC Socket. Ignoring.", err.Error()) } return } kv := strings.SplitN(message, " ", 2) handle := strings.TrimRightFunc(kv[0], func(v rune) bool { return v == '\x00' }) callback := ipcHandlers[handle] v := "" if len(kv) > 1 { v = strings.TrimRightFunc(kv[1], func(v rune) bool { return v == '\x00' }) } if callback == nil { Log.Debug("Received IPC message but no such pattern was registered, ignoring: <%s>%s", handle, v) return } callback(v) } }
// handle the socket connection. When data comes in on the socket write it // to the channel so the serial port can see it. When data comes in over the // channel translate the message and write it to the socket func handleSocket(conn *net.UnixConn, ch chan []byte) { defer conn.Close() readCh := make(chan []byte) go socketRead(conn, readCh) for { select { case s := <-ch: { // map micro -> gui trans := mapMicro.ItemTranslate(string(s)) _, err := conn.Write([]byte(trans)) if err != nil { fmt.Println(err) } } case r := <-readCh: { ch <- r } case <-time.After(timeout): continue } } }
func receiveUnix(conn *net.UnixConn) ([]byte, []int, error) { buf := make([]byte, 4096) oob := make([]byte, 4096) bufn, oobn, _, _, err := conn.ReadMsgUnix(buf, oob) if err != nil { return nil, nil, err } return buf[:bufn], extractFds(oob[:oobn]), nil }
func (a *Array) readFrom(c *net.UnixConn) error { var l uint32 if err := binary.Read(c, HostOrder, l); err != nil { return err } *a = make([]byte, l) _, err := c.Read(*a) return err }
func logPrinter(c *net.UnixConn) { for { var buf [1024]byte nr, err := c.Read(buf[:]) if err != nil { panic(err) } fmt.Printf("%s\n", string(buf[:nr])) } }
func (srv *Server) handleConn(conn *net.UnixConn) { err := srv.doRequest(conn) resp := "Ok\n" if err != nil { resp = err.Error() } conn.Write(([]byte)(resp)) conn.Close() }
func (s String) writeTo(c *net.UnixConn) error { l := s.len() if err := binary.Write(c, HostOrder, l); err != nil { return err } d := make([]byte, l) copy(d, s) _, err := c.Write(d) return err }
func (a Array) writeTo(c *net.UnixConn) error { l := a.size() if err := binary.Write(c, HostOrder, l); err != nil { return err } d := make([]byte, l) copy(d, a) _, err := c.Write(d) return err }
func readRequest(c *net.UnixConn) (*Request, error) { var l uint32 err := binary.Read(c, binary.BigEndian, &l) length := int(l) if err != nil { return nil, err } payload := make([]byte, length) n, err := c.Read(payload) if err != nil { return nil, err } else if n != length { return nil, fmt.Errorf("Payload was %d bytes rather than reported size of %d", n, length) } req := &Request{} err = json.Unmarshal(payload, req) if err != nil { return nil, err } if !req.HasFds { return req, nil } payload = make([]byte, 1) // TODO: does this buffer need to be configurable? oob := make([]byte, 8192) n, oobn, _, _, err := c.ReadMsgUnix(payload, oob) if err != nil && err != io.EOF { return nil, err } if n != 1 { return nil, fmt.Errorf("Error reading OOB filedescriptors") } oob = oob[0:oobn] scm, err := syscall.ParseSocketControlMessage(oob) if err != nil { return nil, fmt.Errorf("Error parsing socket control message: %v", err) } var fds []int for i := 0; i < len(scm); i++ { tfds, err := syscall.ParseUnixRights(&scm[i]) if err == syscall.EINVAL { continue // Wasn't a UnixRights Control Message } else if err != nil { return nil, fmt.Errorf("Error parsing unix rights: %v", err) } fds = append(fds, tfds...) } if len(fds) == 0 { return nil, fmt.Errorf("Failed to receive any FDs on a request with HasFds == true") } req.ReceivedFds = fds return req, nil }
func WriteFile(c *net.UnixConn, file *os.File, timeout time.Duration) error { if timeout > 0 { deadline := time.Now().Add(timeout) if err := c.SetWriteDeadline(deadline); err != nil { return err } } oob := syscall.UnixRights(int(file.Fd())) _, _, err := c.WriteMsgUnix(nil, oob, nil) return err }
func readUnixConn(conn *net.UnixConn, msgs chan []byte) { for { msg := make([]byte, maxPktSize) nread, err := conn.Read(msg) if err != nil { fmt.Fprintf(os.Stderr, "Failed to read from unix socket: %v\n", err) return } msgs <- msg[:nread] } }
func RemoteSendCredentials(conn *net.UnixConn) error { ucred := &syscall.Ucred{ Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid()), } oob := syscall.UnixCredentials(ucred) _, _, err := conn.WriteMsgUnix(nil, oob, nil) return err }
func (fd Fd) writeTo(c *net.UnixConn) error { var b []byte oob := syscall.UnixRights(int(fd)) _, oobn, err := c.WriteMsgUnix(b, oob, nil) if err != nil { return err } if oobn != len(oob) { return fmt.Errorf("expected to write %d oob bytes, wrote %d", len(oob), oobn) } return nil }
func sendResponse(msg *ResponseStruct, conn *net.UnixConn) { jsonMsg, err := json.Marshal(msg) if err != nil { tlog.Warn.Printf("ctlsock: Marshal failed: %v", err) return } // For convenience for the user, add a newline at the end. jsonMsg = append(jsonMsg, '\n') _, err = conn.Write(jsonMsg) if err != nil { tlog.Warn.Printf("ctlsock: Write failed: %v", err) } }
// ServeUnix ... func (service *UnixService) ServeUnix(conn *net.UnixConn) (err error) { if service.readBuffer != nil { if err = conn.SetReadBuffer(service.readBuffer.(int)); err != nil { return err } } if service.writeBuffer != nil { if err = conn.SetWriteBuffer(service.writeBuffer.(int)); err != nil { return err } } return ((*StreamService)(service)).Serve(conn) }
// socket read, we run this in a goroutine so we can block on read // on data read send through the channel func socketRead(conn *net.UnixConn, ch chan []byte) { buf := make([]byte, 512) for { n, err := conn.Read(buf) if nil != err { log.Fatal(err) } if n > 0 { ch <- buf[:n] } } }
func qmpCommander(handler chan QmpInteraction, conn *net.UnixConn, session *QmpSession, feedback chan QmpInteraction) { glog.V(1).Info("Begin process command session") for _, cmd := range session.commands { msg, err := json.Marshal(*cmd) if err != nil { handler <- qmpFail("cannot marshal command", session.respond) return } success := false var qe *QmpError = nil for repeat := 0; !success && repeat < 3; repeat++ { if len(cmd.Scm) > 0 { glog.V(1).Infof("send cmd with scm (%d bytes) (%d) %s", len(cmd.Scm), repeat+1, string(msg)) f, _ := conn.File() fd := f.Fd() syscall.Sendmsg(int(fd), msg, cmd.Scm, nil, 0) } else { glog.V(1).Infof("sending command (%d) %s", repeat+1, string(msg)) conn.Write(msg) } res, ok := <-feedback if !ok { glog.Info("QMP command result chan closed") return } switch res.MessageType() { case QMP_RESULT: success = true break //success case QMP_ERROR: glog.Warning("got one qmp error") qe = res.(*QmpError) time.Sleep(1000 * time.Millisecond) case QMP_INTERNAL_ERROR: glog.Info("QMP quit... commander quit... ") return } } if !success { handler <- qe.Finish(session.respond) return } } handler <- session.Finish() return }
func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) { buf := make([]byte, ReadBufSize) for { n, err := conn.Read(buf) if err == io.EOF { conn.Close() return } else if err != nil { tlog.Warn.Printf("ctlsock: Read error: %#v", err) conn.Close() return } if n == ReadBufSize { tlog.Warn.Printf("ctlsock: request too big (max = %d bytes)", ReadBufSize-1) conn.Close() return } buf = buf[:n] var in RequestStruct err = json.Unmarshal(buf, &in) if err != nil { tlog.Warn.Printf("ctlsock: Unmarshal error: %#v", err) errorMsg := ResponseStruct{ ErrNo: int32(syscall.EINVAL), ErrText: err.Error(), } sendResponse(&errorMsg, conn) } ch.handleRequest(&in, conn) // Restore original size. buf = buf[:cap(buf)] } }
func readAndCompare(conn *net.UnixConn, want string) error { buf := make([]byte, 128) // File system events can take a long time to propagate conn.SetDeadline(time.Now().Add(3 * time.Second)) if _, _, err := conn.ReadFrom(buf); err != nil { return err } if have := string(bytes.Trim(buf, "\x00")); have != want { return fmt.Errorf("expected %q, got %q", want, have) } return nil }
func SendFd(conn *net.UnixConn, file *os.File) error { rights := syscall.UnixRights(int(file.Fd())) dummy := []byte("x") n, oobn, err := conn.WriteMsgUnix(dummy, rights, nil) if err != nil { return fmt.Errorf("sendfd: err %v", err) } if n != len(dummy) { return fmt.Errorf("sendfd: short write %v", conn) } if oobn != len(rights) { return fmt.Errorf("sendfd: short oob write %v", conn) } return nil }
func (s *String) readFrom(c *net.UnixConn) error { var sl, wl uint32 if err := binary.Read(c, HostOrder, &sl); err != nil { return err } wl = sl if r := wl % 4; r != 0 { wl += 4 - r } b := make([]byte, wl) if _, err := c.Read(b); err != nil { return err } *s = String(b[:sl-1]) return nil }
func SendWaylandMessage(conn *net.UnixConn, m *Message) error { header := &bytes.Buffer{} // calculate message total size m.size = uint32(m.data.Len() + 8) binary.Write(header, binary.LittleEndian, m.Id) binary.Write(header, binary.LittleEndian, m.size<<16|m.Opcode&0x0000ffff) d, c, err := conn.WriteMsgUnix(append(header.Bytes(), m.data.Bytes()...), m.control.Bytes(), nil) if err != nil { panic(err.Error()) } if c != m.control.Len() || d != (header.Len()+m.data.Len()) { panic("WriteMsgUnix failed.") } return err }
func writeData(conn *net.UnixConn, response *container_daemon.ResponseMessage) { data, _ := json.Marshal(response) // Ignore error args := make([]int, len(response.Files)) for i, f := range response.Files { args[i] = int(f.Fd()) } oobData := syscall.UnixRights(args...) conn.WriteMsgUnix(data, oobData, nil) // Ignore error // Close the files whose descriptors have been sent to the host to ensure that // a close on the host takes effect in a timely fashion. for _, file := range response.Files { file.Close() // Ignore error } }
func HandleConnection(conn *net.UnixConn) { defer conn.Close() defer fmt.Println("closing...") r := bufio.NewReader(conn) w := bufio.NewWriter(conn) req, err := ReceiveRequest(r) if req != nil { fmt.Println("req.Name =", *req.Name) res := new(Response) res.Name = proto.String("hello hello!") SendResponse(w, res) w.Flush() } else { fmt.Println("Failed to receive a request:", err) } }
// passFDChild is the child process used by TestPassFD. func passFDChild() { defer os.Exit(0) // Look for our fd. It should be fd 3, but we work around an fd leak // bug here (http://golang.org/issue/2603) to let it be elsewhere. var uc *net.UnixConn for fd := uintptr(3); fd <= 10; fd++ { f := os.NewFile(fd, "unix-conn") var ok bool netc, _ := net.FileConn(f) uc, ok = netc.(*net.UnixConn) if ok { break } } if uc == nil { fmt.Println("failed to find unix fd") return } // Make a file f to send to our parent process on uc. // We make it in tempDir, which our parent will clean up. flag.Parse() tempDir := flag.Arg(0) f, err := ioutil.TempFile(tempDir, "") if err != nil { fmt.Printf("TempFile: %v", err) return } f.Write([]byte("Hello from child process!\n")) f.Seek(0, 0) rights := syscall.UnixRights(int(f.Fd())) dummyByte := []byte("x") n, oobn, err := uc.WriteMsgUnix(dummyByte, rights, nil) if err != nil { fmt.Printf("WriteMsgUnix: %v", err) return } if n != 1 || oobn != len(rights) { fmt.Printf("WriteMsgUnix = %d, %d; want 1, %d", n, oobn, len(rights)) return } }