예제 #1
0
// Dispatch processes the connection.
func (d *dispatcher) Dispatch(g grim.GrimReaper, conn net.Conn) {

	// Create buffer and read connection type
	buf := make([]byte, 1)
	if _, err := conn.Read(buf); err != nil {
		d.logger.Warn("error reading StreamType",
			"remote", conn.RemoteAddr().String, "err", err)
		conn.Close()
		return
	}

	// Dispatch connection based on first byte
	ctype := StreamType(buf[0])
	if handler, ok := d.handlers[ctype]; ok {
		g.SpawnFunc(func(c context.Context) {
			handler.Handle(c, conn)
		})
		return
	}

	// Process unknown streams if there is an unknown stream handler
	if d.unknown != nil {
		g.SpawnFunc(func(c context.Context) {
			d.unknown.Handle(c, conn)
		})
		return
	}

	// If there is not an unknown stream handler, close the stream.
	d.logger.Warn("closing connection: unknown stream type",
		"type", ctype, "remote", conn.RemoteAddr().String())
	conn.Close()
}
예제 #2
0
func processStreams(g grim.GrimReaper, conn net.Conn, streamCh chan net.Conn, dispatcher Dispatcher) grim.TaskFunc {
	return func(ctx context.Context) {
		defer conn.Close()
		for {
			select {
			case <-ctx.Done():
				return
			case stream, ok := <-streamCh:
				if !ok {
					return
				}
				dispatcher.Dispatch(g.New(), stream)
			}
		}
	}
}
예제 #3
0
func (y *yamuxer) handleConn(g grim.GrimReaper, conn net.Conn) {
	defer g.Wait()

	conf := yamux.DefaultConfig()
	conf.LogOutput = y.logOutput
	session, _ := yamux.Server(conn, conf)

	streamCh := make(chan net.Conn)
	g.SpawnFunc(processStreams(g.New(), conn, streamCh, y.dispatcher))
	g.SpawnFunc(acceptStreams(y.logger, session, streamCh))
}