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 (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 }