Exemplo n.º 1
0
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
}
Exemplo n.º 2
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
	}
}
Exemplo n.º 3
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
}
Exemplo n.º 4
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
}
Exemplo n.º 5
0
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
}
Exemplo n.º 6
0
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
}
Exemplo n.º 7
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
}
Exemplo n.º 8
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
	}
}
Exemplo n.º 9
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
	}
}
Exemplo n.º 10
0
// Send File over UnixConn
func SendFD(conn *net.UnixConn, file *os.File) (err error) {
	cmsgb := make([]byte, CmsgSpace(unsafe.Sizeof(int(0))))

	cms := (*syscall.Cmsghdr)(unsafe.Pointer(&cmsgb[0]))
	cms.Len = CmsgLen(unsafe.Sizeof(int(0)))
	cms.Level = 1
	cms.Type = 1

	fdnum := file.Fd()
	fdArea := cmsgb[unsafe.Sizeof(syscall.Cmsghdr{}):]
	fdArea[0] = byte(fdnum)
	fdArea[1] = byte(fdnum >> 8)
	fdArea[2] = byte(fdnum >> 16)
	fdArea[3] = byte(fdnum >> 24)

	_, _, err = conn.WriteMsgUnix([]byte{}, cmsgb, nil)
	return
}
Exemplo n.º 11
0
func sendUnix(conn *net.UnixConn, data []byte, fds ...int) error {
	_, _, err := conn.WriteMsgUnix(data, syscall.UnixRights(fds...), nil)
	return err
}