// mux routes incoming messages from the server based on message type func mux() { // start piping data to minitunnel and trunking it over the ron local, remote := net.Pipe() defer local.Close() defer remote.Close() go func() { if err := minitunnel.ListenAndServe(local); err != nil { log.Error("ListenAndServe: %v", err) } }() go ron.Trunk(remote, Client.UUID, sendMessage) // Read messages from gob, mux message to the correct place var err error log.Debug("starting mux") for err == nil { var m ron.Message if err = Client.dec.Decode(&m); err == io.EOF { // server disconnected... try to reconnect err = dial() continue } else if err != nil { break } log.Debug("new message: %v", m.Type) switch m.Type { case ron.MESSAGE_COMMAND: updateClient(&m) Client.commandChan <- m.Commands case ron.MESSAGE_FILE: Client.fileChan <- &m case ron.MESSAGE_TUNNEL: _, err = remote.Write(m.Tunnel) default: err = fmt.Errorf("unknown message type: %v", m.Type) } } log.Info("mux exit: %v", err) }
// tunnel transport handler func (c *Client) handleTunnel(server bool, stop chan bool) { log.Debug("handleTunnel: %v", server) a, b := net.Pipe() c.tunnelData = make(chan []byte, 1024) go func() { if server { var err error c.tunnel, err = minitunnel.Dial(a) if err != nil { log.Errorln("Dial: %v", err) a.Close() b.Close() } } else { go func() { err := minitunnel.ListenAndServe(a) if err != nil { log.Fatalln("ListenAndServe: %v", err) } }() } }() go func() { for { var buf = make([]byte, BUFFER_SIZE) n, err := b.Read(buf) if err != nil { if err != io.ErrClosedPipe { log.Errorln(err) } a.Close() b.Close() return } // push it up in a message m := &Message{ Type: MESSAGE_TUNNEL, UUID: c.UUID, Tunnel: buf[:n], } c.out <- m } }() go func() { for { data := <-c.tunnelData if data == nil { return } _, err := b.Write(data) if err != nil { log.Errorln(err) a.Close() b.Close() return } } }() <-stop log.Debug("ron client tunnel close: %v", c.UUID) a.Close() b.Close() close(c.tunnelData) }