github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/container_daemon/unix_socket/connector.go (about) 1 package unix_socket 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net" 8 "os" 9 "syscall" 10 11 "github.com/cloudfoundry-incubator/garden-linux/container_daemon" 12 ) 13 14 type Connector struct { 15 SocketPath string 16 } 17 18 func (c *Connector) Connect(msg *container_daemon.RequestMessage) (*container_daemon.ResponseMessage, error) { 19 conn, err := net.Dial("unix", c.SocketPath) 20 if err != nil { 21 return nil, fmt.Errorf("unix_socket: connect to server socket: %s", err) 22 } 23 defer conn.Close() // Ignore error 24 25 msgJson, err := json.Marshal(msg) 26 if err != nil { 27 return nil, fmt.Errorf("unix_socket: failed to marshal json message: %s", err) 28 } 29 30 _, err = conn.Write(msgJson) 31 if err != nil { 32 return nil, fmt.Errorf("unix_socket: failed to write to connection: %s", err) 33 } 34 35 return readData(conn) 36 } 37 38 func readData(conn net.Conn) (*container_daemon.ResponseMessage, error) { 39 var b [2048]byte 40 var oob [2048]byte 41 var response container_daemon.ResponseMessage 42 43 n, oobn, _, _, err := conn.(*net.UnixConn).ReadMsgUnix(b[:], oob[:]) 44 if err != nil { 45 return nil, fmt.Errorf("unix_socket: failed to read unix msg: %s (read: %d, %d)", err, n, oobn) 46 } 47 48 if n > 0 { 49 err := json.Unmarshal(b[:n], &response) 50 if err != nil { 51 return nil, fmt.Errorf("unix_socket: Unmarshal failed: %s", err) 52 } 53 if response.ErrMessage != "" { 54 return nil, errors.New(response.ErrMessage) 55 } 56 } else { 57 return nil, errors.New("unix_socket: No response received") 58 } 59 60 scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) 61 if err != nil { 62 return nil, fmt.Errorf("unix_socket: failed to parse socket control message: %s", err) 63 } 64 65 if len(scms) > 0 { 66 scm := scms[0] 67 fds, err := syscall.ParseUnixRights(&scm) 68 if err != nil { 69 return nil, fmt.Errorf("unix_socket: failed to parse unix rights: %s", err) 70 } 71 72 response.Files = make([]container_daemon.StreamingFile, len(fds)) 73 for i, fd := range fds { 74 response.Files[i] = os.NewFile(uintptr(fd), fmt.Sprintf("/dev/fake-fd-%d", i)) 75 } 76 } 77 78 return &response, nil 79 }