예제 #1
0
파일: types.go 프로젝트: vasiliyl/playwand
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
}
예제 #2
0
파일: server.go 프로젝트: akramer/lateral
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
		}
	}
}
예제 #3
0
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
	}
}
예제 #4
0
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
}
예제 #5
0
파일: client.go 프로젝트: akramer/lateral
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
}
예제 #6
0
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)
	}
}
예제 #7
0
파일: sio.go 프로젝트: jmore-reachtech/io
// 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
		}
	}
}
예제 #8
0
파일: unix.go 프로젝트: ChaosCloud/docker
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
}
예제 #9
0
파일: types.go 프로젝트: vasiliyl/playwand
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
}
예제 #10
0
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]))
	}
}
예제 #11
0
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()
}
예제 #12
0
파일: types.go 프로젝트: vasiliyl/playwand
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
}
예제 #13
0
파일: types.go 프로젝트: vasiliyl/playwand
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
}
예제 #14
0
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
}
예제 #15
0
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
}
예제 #16
0
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]
	}
}
예제 #17
0
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
}
예제 #18
0
파일: types.go 프로젝트: vasiliyl/playwand
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
}
예제 #19
0
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)
	}
}
예제 #20
0
// 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)
}
예제 #21
0
파일: sio.go 프로젝트: jmore-reachtech/io
// 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]
		}
	}
}
예제 #22
0
파일: qmp_handler.go 프로젝트: ZJU-SEL/runv
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
}
예제 #23
0
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)]
	}
}
예제 #24
0
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
}
예제 #25
0
파일: fdpass.go 프로젝트: kingpro/vitess
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
}
예제 #26
0
파일: types.go 프로젝트: vasiliyl/playwand
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
}
예제 #27
0
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
}
예제 #28
0
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
	}
}
예제 #29
0
파일: server.go 프로젝트: yunabe/codelab
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)
	}
}
예제 #30
0
// 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
	}
}