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