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 (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 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 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] } }
// 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 (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 ReceiveResponse(c *net.UnixConn) (*server.Response, 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 && err != io.EOF { return nil, err } else if n != length { return nil, fmt.Errorf("Read %d bytes and expected %d bytes", n, length) } var resp server.Response err = json.Unmarshal(payload, &resp) if err != nil { return nil, err } return &resp, nil }
func ReadWaylandMessage(conn *net.UnixConn) (*Message, error) { var buf [8]byte msg := Message{} control := make([]byte, 24) n, oobn, _, _, err := conn.ReadMsgUnix(buf[:], control) if err != nil { return nil, err } if n != 8 { return nil, errors.New("Unable to read message header.") } if oobn > 0 { if oobn > len(control) { panic("Unsufficient control msg buffer") } msg.control_msgs, err = syscall.ParseSocketControlMessage(control) if err != nil { panic(fmt.Sprintf("Control message parse error: %s", err.Error())) } } msg.Id = ProxyId(binary.LittleEndian.Uint32(buf[0:4])) msg.Opcode = uint32(binary.LittleEndian.Uint16(buf[4:6])) msg.size = uint32(binary.LittleEndian.Uint16(buf[6:8])) // subtract 8 bytes from header data := make([]byte, msg.size-8) n, err = conn.Read(data) if err != nil { return nil, err } if n != int(msg.size)-8 { return nil, errors.New("Invalid message size.") } msg.data = bytes.NewBuffer(data) return &msg, nil }
func readTtyMessage(conn *net.UnixConn) (*hyperstartapi.TtyMessage, error) { needRead := 12 length := 0 read := 0 buf := make([]byte, 512) res := []byte{} for read < needRead { want := needRead - read if want > 512 { want = 512 } glog.V(1).Infof("tty: trying to read %d bytes", want) nr, err := conn.Read(buf[:want]) if err != nil { glog.Error("read tty data failed") return nil, err } res = append(res, buf[:nr]...) read = read + nr glog.V(1).Infof("tty: read %d/%d [length = %d]", read, needRead, length) if length == 0 && read >= 12 { length = int(binary.BigEndian.Uint32(res[8:12])) glog.V(1).Infof("data length is %d", length) if length > 12 { needRead = length } } } return &hyperstartapi.TtyMessage{ Session: binary.BigEndian.Uint64(res[:8]), Message: res[12:], }, nil }
func ReadVmMessage(conn *net.UnixConn) (*DecodedMessage, error) { needRead := 8 length := 0 read := 0 buf := make([]byte, 512) res := []byte{} for read < needRead { want := needRead - read if want > 512 { want = 512 } glog.V(1).Infof("trying to read %d bytes", want) nr, err := conn.Read(buf[:want]) if err != nil { glog.Error("read init data failed") return nil, err } res = append(res, buf[:nr]...) read = read + nr glog.V(1).Infof("read %d/%d [length = %d]", read, needRead, length) if length == 0 && read >= 8 { length = int(binary.BigEndian.Uint32(res[4:8])) glog.V(1).Infof("data length is %d", length) if length > 8 { needRead = length } } } return &DecodedMessage{ Code: binary.BigEndian.Uint32(res[:4]), Message: res[8:], }, nil }
// read command response/output func readResp(c *net.UnixConn) *response { buf := make([]byte, 1024) var output []byte var read int var ret uint16 n, err := c.Read(buf[:4]) if err != nil { return &response{err: err} } // start read if n != 4 { return &response{err: fmt.Errorf("invalid response data: %s", buf[0:n])} } // length of output toRead := int(binary.BigEndian.Uint32(buf[0:n])) for read < toRead { min := min(toRead-read, 1024) n, err := c.Read(buf[:min]) if err != nil { return &response{err: err} } output = append(output, buf[0:n]...) read += n } n, err = c.Read(buf[:2]) if err != nil { return &response{err: err} } if n != 2 { return &response{err: fmt.Errorf("invalid response data: %s", buf[0:n])} } ret = binary.BigEndian.Uint16(buf[0:n]) return &response{output: string(output), ret: ret} }