func (s *Session) handleBind(stream conn.Conn, bind *proto.Bind) (err error) { stream.Debug("Binding new tunnel: %v", bind) respond := func(resp *proto.BindResp) { if err = proto.WriteMsg(stream, resp); err != nil { err = stream.Error("Failed to send bind response: %v", err) } } if err = s.hooks.OnBind(s, bind); err != nil { return } t, err := newTunnel(bind, s, s.binders, s.tunnelHooks) if err != nil { respond(&proto.BindResp{Error: err.Error()}) return } t.Info("Registered new tunnel on session %s", s.id) // add it to the list of tunnels s.addTunnel(t) // acknowledge success respond(&proto.BindResp{Url: t.url}) return }
func (t *Tunnel) handlePublic(publicConn conn.Conn) { defer publicConn.Close() defer t.recoverPanic("Tunnel.handlePublic") publicConn.Info("New connection from %v", publicConn.RemoteAddr()) // connection hook if err := t.hooks.OnConnectionOpen(t, publicConn); err != nil { t.Error("OnConnectionOpen hook failed: %v", err) return } startTime := time.Now() // open a proxy stream proxyConn, err := t.sess.openProxy(publicConn.RemoteAddr().String(), t.url) if err != nil { t.Error("Failed to open proxy connection: %v", err) return } defer proxyConn.Close() // join the public and proxy connections bytesIn, bytesOut := conn.Join(publicConn, proxyConn) if err = t.hooks.OnConnectionClose(t, publicConn, time.Now().Sub(startTime), bytesIn, bytesOut); err != nil { t.Error("OnConnectionClose hook failed: %v", err) return } }
func (s *Session) handleStream(stream conn.Conn) { defer s.recoverPanic("Session.handleStream") defer stream.Close() // make sure we only process streams while we're not shutting down if err := s.guard.Enter(); err != nil { stream.Error("Failing stream, session is shutting down") return } defer s.guard.Exit() raw, err := proto.ReadMsg(stream) if err != nil { stream.Error("Failed to read message: %v") go s.Shutdown() return } switch msg := raw.(type) { case *proto.Bind: err = s.handleBind(stream, msg) case *proto.Unbind: err = s.handleUnbind(stream, msg) default: err = fmt.Errorf("Unknown message type: %v", reflect.TypeOf(raw)) } if err != nil { stream.Error("Error on stream: %v", err) go s.Shutdown() return } return }
func WriteMsg(c conn.Conn, msg interface{}) (err error) { buffer, err := Pack(msg) if err != nil { return } c.Debug("Writing message: %s", string(buffer)) if err = binary.Write(c, binary.LittleEndian, int64(len(buffer))); err != nil { return } if _, err = c.Write(buffer); err != nil { return } return }
func readMsgShared(c conn.Conn) (buffer []byte, err error) { c.Debug("Waiting to read message") var sz int64 err = binary.Read(c, binary.LittleEndian, &sz) if err != nil { return } c.Debug("Reading message with length: %d", sz) buffer = make([]byte, sz) if _, err = io.ReadFull(c, buffer); err != nil { return } c.Debug("Read message %s", buffer) return }