From a383e31ed72ab14382deb49690473fabda8bdb4e Mon Sep 17 00:00:00 2001 From: David Cook Date: Mon, 28 Dec 2015 22:40:39 -0600 Subject: [PATCH 1/2] Add binary to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d9568ca..590d5de 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *swp +sniff From 3966e4403ad29c6fda472d79f9eda4b2eb79932c Mon Sep 17 00:00:00 2001 From: David Cook Date: Mon, 28 Dec 2015 22:52:02 -0600 Subject: [PATCH 2/2] Add option to specify regexp for hostname --- README.md | 7 +++++ config.go | 1 + server.go | 75 +++++++++++++++++++++++++++++++++++++++--------------- sniff.json | 1 + 4 files changed, 63 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 5fad727..5c86d64 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ sniff config "servers": [ { "default": false, + "regexp": false, "host": "97.107.130.79", "names": [ "pault.ag", @@ -35,6 +36,12 @@ nothing matches this, the socket will be closed. Changing default to true would send any unmatched hosts (or TLS / SSL connections without SNI) to that host. +By default, the requested domain name is compared literally with the strings +inside `names`. If `regexp` is true, then the names are interpreted as regular +expressions. Each server and name will be checked in the order they appear in +the file, stopping with the first match. If there is no match, then the +request is sent to the first server with `default` set. + using the parser ---------------- diff --git a/config.go b/config.go index e6c7358..232ba55 100644 --- a/config.go +++ b/config.go @@ -37,6 +37,7 @@ type Bind struct { type Server struct { Default bool + Regexp bool Host string Names []string Port int diff --git a/server.go b/server.go index 828e961..4146e7b 100644 --- a/server.go +++ b/server.go @@ -25,36 +25,55 @@ import ( "io" "log" "net" + "regexp" "pault.ag/go/sniff/parser" ) +type ServerAndRegexp struct { + Server *Server + Regexp *regexp.Regexp +} + type Proxy struct { - ServerMap map[string]Server - Default *Server + ServerList []ServerAndRegexp + Default *Server } func (c *Proxy) Get(host string) *Server { - if server, ok := c.ServerMap[host]; ok { - return &server + for _, tuple := range c.ServerList { + if tuple.Regexp.MatchString(host) { + return tuple.Server + } } return c.Default } -func (c *Config) CreateProxy() Proxy { - ret := Proxy{ServerMap: map[string]Server{}} - for _, server := range c.Servers { +func (c *Config) CreateProxy() (Proxy, error) { + var ret Proxy + for i, server := range c.Servers { for _, hostname := range server.Names { - ret.ServerMap[hostname] = server + var host_regexp *regexp.Regexp + var err error + if server.Regexp { + host_regexp, err = regexp.Compile(hostname) + } else { + host_regexp, err = regexp.Compile("^\\Q" + hostname + "\\E$") + } + if err != nil { + return Proxy{}, err + } + tuple := ServerAndRegexp{&c.Servers[i], host_regexp} + ret.ServerList = append(ret.ServerList, tuple) } } - for _, server := range c.Servers { + for i, server := range c.Servers { if server.Default { - ret.Default = &server + ret.Default = &c.Servers[i] break } } - return ret + return ret, nil } func (c *Config) Serve() error { @@ -65,7 +84,10 @@ func (c *Config) Serve() error { return err } - server := c.CreateProxy() + server, err := c.CreateProxy() + if err != nil { + return err + } for { conn, err := listener.Accept() @@ -84,16 +106,27 @@ func (s *Proxy) Handle(conn net.Conn) { log.Printf("Error: %s", err) } - hostname, _ := parser.GetHostname(data[:]) - /* So, a failure in parsing just means we default it through */ - proxy := s.Get(hostname) - if proxy == nil { - log.Printf("No default proxy") - conn.Close() - return - } + var proxy *Server + hostname, hostname_err := parser.GetHostname(data[:]) + if hostname_err == nil { + log.Printf("Parsed hostname: %s\n", hostname) - log.Printf("Parsed Hostname: %s\n", hostname) + proxy = s.Get(hostname) + if proxy == nil { + log.Printf("No proxy matched %s", hostname) + conn.Close() + return + } + } else { + log.Printf("Parsed request without hostname") + + proxy = s.Default + if proxy == nil { + log.Printf("No default proxy") + conn.Close() + return + } + } clientConn, err := net.Dial("tcp", fmt.Sprintf( "%s:%d", proxy.Host, proxy.Port, diff --git a/sniff.json b/sniff.json index 8bc33cc..4077b56 100644 --- a/sniff.json +++ b/sniff.json @@ -6,6 +6,7 @@ "servers": [ { "default": false, + "regexp": false, "host": "97.107.130.79", "names": [ "pault.ag",