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 }
// 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 (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 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) } }
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 writeResponse(c *net.UnixConn, resp *Response) error { payload, err := json.Marshal(resp) 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) } return nil }
func waitTtyMessage(ctx *VmContext, conn *net.UnixConn) { for { msg, ok := <-ctx.ptys.channel if !ok { glog.V(1).Info("tty chan closed, quit sent goroutine") break } glog.V(3).Infof("trying to write to session %d", msg.Session) if _, ok := ctx.ptys.ttys[msg.Session]; ok { _, err := conn.Write(msg.ToBuffer()) if err != nil { glog.V(1).Info("Cannot write to tty socket: ", err.Error()) return } } } }
func waitCmdToInit(ctx *VmContext, init *net.UnixConn) { looping := true cmds := []*DecodedMessage{} var data []byte var timeout bool = false var index int = 0 var got int = 0 var pingTimer *time.Timer = nil var pongTimer *time.Timer = nil go waitInitAck(ctx, init) for looping { cmd, ok := <-ctx.vm if !ok { glog.Info("vm channel closed, quit") break } glog.Infof("got cmd:%d", cmd.Code) if cmd.Code == INIT_ACK || cmd.Code == INIT_ERROR { if len(cmds) > 0 { if cmds[0].Code == INIT_DESTROYPOD { glog.Info("got response of shutdown command, last round of command to init") looping = false } if cmd.Code == INIT_ACK { if cmds[0].Code != INIT_PING { ctx.Hub <- &CommandAck{ reply: cmds[0], msg: cmd.Message, } } } else { ctx.Hub <- &CommandError{ reply: cmds[0], msg: cmd.Message, } } cmds = cmds[1:] if pongTimer != nil { glog.V(1).Info("ack got, clear pong timer") pongTimer.Stop() pongTimer = nil } if pingTimer == nil { pingTimer = time.AfterFunc(30*time.Second, func() { defer func() { recover() }() glog.V(1).Info("Send ping message to init") ctx.vm <- &DecodedMessage{ Code: INIT_PING, Message: []byte{}, } pingTimer = nil }) } else { pingTimer.Reset(30 * time.Second) } } else { glog.Error("got ack but no command in queue") } } else if cmd.Code == INIT_FINISHPOD { num := len(cmd.Message) / 4 results := make([]uint32, num) for i := 0; i < num; i++ { results[i] = binary.BigEndian.Uint32(cmd.Message[i*4 : i*4+4]) } for _, c := range cmds { if c.Code == INIT_DESTROYPOD { glog.Info("got pod finish message after having send destroy message") looping = false ctx.Hub <- &CommandAck{ reply: c, } break } } glog.V(1).Infof("Pod finished, returned %d values", num) ctx.Hub <- &PodFinished{ result: results, } } else { if cmd.Code == INIT_NEXT { glog.V(1).Infof("get command NEXT") got += int(binary.BigEndian.Uint32(cmd.Message[0:4])) glog.V(1).Infof("send %d, receive %d", index, got) timeout = false if index == got { /* received the sent out message */ tmp := data[index:] data = tmp index = 0 got = 0 } } else { glog.V(1).Infof("send command %d to init, payload: '%s'.", cmd.Code, string(cmd.Message)) cmds = append(cmds, cmd) data = append(data, NewVmMessage(cmd)...) timeout = true } if index == 0 && len(data) != 0 { var end int = len(data) if end > 512 { end = 512 } wrote, _ := init.Write(data[:end]) glog.V(1).Infof("write %d to init, payload: '%s'.", wrote, data[:end]) index += wrote } if timeout && pongTimer == nil { glog.V(1).Info("message sent, set pong timer") pongTimer = time.AfterFunc(30*time.Second, func() { if !ctx.Paused { ctx.Hub <- &Interrupted{Reason: "init not reply ping mesg"} } }) } } } if pingTimer != nil { pingTimer.Stop() } if pongTimer != nil { pongTimer.Stop() } }
func waitCmdToInit(ctx *VmContext, init *net.UnixConn) { looping := true cmds := []*hyperstartCmd{} var data []byte var timeout bool = false var index int = 0 var got int = 0 var pingTimer *time.Timer = nil var pongTimer *time.Timer = nil go waitInitAck(ctx, init) for looping { cmd, ok := <-ctx.vm if !ok { glog.Info("vm channel closed, quit") break } if cmd.result == nil { cmd.result = defaultHyperstartResultChan(ctx, cmd) } glog.Infof("got cmd:%d", cmd.Code) if cmd.Code == hyperstartapi.INIT_ACK || cmd.Code == hyperstartapi.INIT_ERROR { if len(cmds) > 0 { if cmds[0].Code == hyperstartapi.INIT_DESTROYPOD { glog.Info("got response of shutdown command, last round of command to init") looping = false } if cmd.Code == hyperstartapi.INIT_ACK { if cmds[0].Code != hyperstartapi.INIT_PING { cmds[0].retMsg = cmd.retMsg cmds[0].result <- nil } } else { cmds[0].retMsg = cmd.retMsg cmds[0].result <- fmt.Errorf("Error: %s", string(cmd.retMsg)) } cmds = cmds[1:] if pongTimer != nil { glog.V(1).Info("ack got, clear pong timer") pongTimer.Stop() pongTimer = nil } if pingTimer == nil { pingTimer = time.AfterFunc(30*time.Second, func() { defer func() { recover() }() glog.V(1).Info("Send ping message to init") ctx.vm <- &hyperstartCmd{ Code: hyperstartapi.INIT_PING, } pingTimer = nil }) } else { pingTimer.Reset(30 * time.Second) } } else { glog.Error("got ack but no command in queue") } } else { if cmd.Code == hyperstartapi.INIT_NEXT { glog.V(1).Infof("get command NEXT") got += int(binary.BigEndian.Uint32(cmd.retMsg[0:4])) glog.V(1).Infof("send %d, receive %d", index, got) timeout = false if index == got { /* received the sent out message */ tmp := data[index:] data = tmp index = 0 got = 0 } } else { var message []byte if message1, ok := cmd.Message.([]byte); ok { message = message1 } else if message2, err := json.Marshal(cmd.Message); err == nil { message = message2 } else { glog.Infof("marshal command %d failed. object: %v", cmd.Code, cmd.Message) cmd.result <- fmt.Errorf("marshal command %d failed", cmd.Code) continue } msg := &hyperstartapi.DecodedMessage{ Code: cmd.Code, Message: message, } glog.V(1).Infof("send command %d to init, payload: '%s'.", cmd.Code, string(msg.Message)) cmds = append(cmds, cmd) data = append(data, NewVmMessage(msg)...) timeout = true } if index == 0 && len(data) != 0 { var end int = len(data) if end > 512 { end = 512 } wrote, _ := init.Write(data[:end]) glog.V(1).Infof("write %d to init, payload: '%s'.", wrote, data[:end]) index += wrote } if timeout && pongTimer == nil { glog.V(1).Info("message sent, set pong timer") pongTimer = time.AfterFunc(30*time.Second, func() { if ctx.PauseState == PauseStateUnpaused { ctx.Hub <- &Interrupted{Reason: "init not reply ping mesg"} } }) } } } if pingTimer != nil { pingTimer.Stop() } if pongTimer != nil { pongTimer.Stop() } }
func waitCmdToInit(ctx *VmContext, init *net.UnixConn) { looping := true cmds := []*DecodedMessage{} var pingTimer *time.Timer = nil var pongTimer *time.Timer = nil go waitInitAck(ctx, init) for looping { cmd, ok := <-ctx.vm if !ok { glog.Info("vm channel closed, quit") break } if cmd.code == INIT_ACK || cmd.code == INIT_ERROR { if len(cmds) > 0 { if cmds[0].code == INIT_DESTROYPOD { glog.Info("got response of shutdown command, last round of command to init") looping = false } if cmd.code == INIT_ACK { if cmds[0].code != INIT_PING { ctx.Hub <- &CommandAck{ reply: cmds[0].code, msg: cmd.message, } } } else { ctx.Hub <- &CommandError{ context: cmds[0], msg: cmd.message, } } cmds = cmds[1:] if pongTimer != nil { glog.V(1).Info("ack got, clear pong timer") pongTimer.Stop() pongTimer = nil } if pingTimer == nil { pingTimer = time.AfterFunc(30*time.Second, func() { defer func() { recover() }() glog.V(1).Info("Send ping message to init") ctx.vm <- &DecodedMessage{ code: INIT_PING, message: []byte{}, } pingTimer = nil }) } else { pingTimer.Reset(30 * time.Second) } } else { glog.Error("got ack but no command in queue") } } else if cmd.code == INIT_FINISHPOD { num := len(cmd.message) / 4 results := make([]uint32, num) for i := 0; i < num; i++ { results[i] = binary.BigEndian.Uint32(cmd.message[i*4 : i*4+4]) } for _, c := range cmds { if c.code == INIT_DESTROYPOD { glog.Info("got pod finish message after having send destroy message") looping = false ctx.Hub <- &CommandAck{ reply: c.code, } break } } glog.V(1).Infof("Pod finished, returned %d values", num) ctx.Hub <- &PodFinished{ result: results, } } else { if glog.V(1) { glog.Infof("send command %d to init, payload: '%s'.", cmd.code, string(cmd.message)) } init.Write(newVmMessage(cmd)) cmds = append(cmds, cmd) if pongTimer == nil { glog.V(1).Info("message sent, set pong timer") pongTimer = time.AfterFunc(30*time.Second, func() { ctx.Hub <- &Interrupted{Reason: "init not reply ping mesg"} }) } } } if pingTimer != nil { pingTimer.Stop() } if pongTimer != nil { pongTimer.Stop() } }