telebit/mplexer/routemux.go

93 lines
2.2 KiB
Go
Raw Normal View History

2020-05-22 10:41:24 +00:00
package telebit
2020-05-21 10:29:05 +00:00
import (
2020-05-22 10:07:35 +00:00
"fmt"
"net"
2020-05-21 10:29:05 +00:00
"time"
)
// A RouteMux is a net.Conn multiplexer.
//
// It matches the port, domain, or connection type of a connection
// and selects the matching handler.
type RouteMux struct {
defaultTimeout time.Duration
2020-05-27 08:53:26 +00:00
routes []meta
2020-05-21 10:29:05 +00:00
}
type meta struct {
2020-05-22 10:07:35 +00:00
addr string
handler Handler
terminate bool
2020-05-21 10:29:05 +00:00
}
// NewRouteMux allocates and returns a new RouteMux.
func NewRouteMux() *RouteMux {
mux := &RouteMux{
defaultTimeout: 45 * time.Second,
}
return mux
}
// Serve dispatches the connection to the handler whose selectors matches the attributes.
2020-05-22 10:07:35 +00:00
func (m *RouteMux) Serve(client net.Conn) error {
wconn := &ConnWrap{Conn: client}
servername := wconn.Servername()
2020-05-21 10:29:05 +00:00
2020-05-27 08:53:26 +00:00
for _, meta := range m.routes {
2020-05-22 10:07:35 +00:00
if servername == meta.addr || "*" == meta.addr {
//fmt.Println("[debug] test of route:", meta)
2020-05-21 10:29:05 +00:00
if err := meta.handler.Serve(client); nil != err {
2020-05-22 10:07:35 +00:00
// error should be EOF if successful
2020-05-21 10:29:05 +00:00
return err
}
2020-05-22 10:07:35 +00:00
// nil err means skipped
2020-05-21 10:29:05 +00:00
}
}
2020-05-22 10:07:35 +00:00
fmt.Println("No match found for", wconn.Scheme(), wconn.Servername())
2020-05-21 10:29:05 +00:00
return client.Close()
}
// ForwardTCP creates and returns a connection to a local handler target.
func (m *RouteMux) ForwardTCP(servername string, target string, timeout time.Duration) error {
// TODO check servername
2020-05-27 08:53:26 +00:00
m.routes = append(m.routes, meta{
2020-05-22 10:07:35 +00:00
addr: servername,
terminate: false,
handler: NewForwarder(target, timeout),
2020-05-21 10:29:05 +00:00
})
return nil
}
// HandleTCP creates and returns a connection to a local handler target.
func (m *RouteMux) HandleTCP(servername string, handler Handler) error {
// TODO check servername
2020-05-27 08:53:26 +00:00
m.routes = append(m.routes, meta{
2020-05-22 10:07:35 +00:00
addr: servername,
terminate: false,
handler: handler,
2020-05-21 10:29:05 +00:00
})
return nil
}
// HandleTLS creates and returns a connection to a local handler target.
2020-05-22 10:07:35 +00:00
func (m *RouteMux) HandleTLS(servername string, acme *ACME, handler Handler) error {
// TODO check servername
2020-05-27 08:53:26 +00:00
m.routes = append(m.routes, meta{
2020-05-22 10:07:35 +00:00
addr: servername,
terminate: true,
handler: HandlerFunc(func(client net.Conn) error {
wrap := &ConnWrap{Conn: client}
if wrap.isTerminated() {
// nil to skip
return nil
}
//NewTerminator(acme, handler)(client)
//return handler.Serve(client)
return handler.Serve(TerminateTLS(client, acme))
}),
})
return nil
2020-05-21 10:29:05 +00:00
}