diff --git a/common/plugin_chain.go b/common/plugin_chain.go index 7c576d7..5b7f598 100644 --- a/common/plugin_chain.go +++ b/common/plugin_chain.go @@ -197,20 +197,19 @@ func (p LuaPluginChain) Close() { p.pool.Shutdown() } - -func PluginFactory(plugins string)(input, output PluginChain){ +func PluginFactory(plugins string) (input, output PluginChain) { var ip PluginChain var op PluginChain - for _, plugin := range strings.Split(plugins, ","){ + for _, plugin := range strings.Split(plugins, ",") { var nextip PluginChain var nextop PluginChain - if plugin[:3] == "cpp"{ + if plugin[:3] == "cpp" { nextip = GetCPluginChain(plugin[4:], DEC) nextop = GetCPluginChain(plugin[4:], ENC) - }else if plugin[:3] == "lua"{ + } else if plugin[:3] == "lua" { nextip = GetLuaPluginChain(plugin[4:], DEC) nextop = GetLuaPluginChain(plugin[4:], ENC) - }else if plugin[:2] == "go" { + } else if plugin[:2] == "go" { nextip = GetGoPluginChain(plugin[3:], DEC) nextop = GetGoPluginChain(plugin[3:], ENC) } @@ -219,10 +218,10 @@ func PluginFactory(plugins string)(input, output PluginChain){ op.AddNextChainLoop(nextop) nextip.AddNextChainLoop(ip) ip = nextip - }else{ + } else { ip = nextip op = nextop } } return ip, op -} \ No newline at end of file +} diff --git a/common/types.go b/common/types.go index f01f2ba..211d510 100644 --- a/common/types.go +++ b/common/types.go @@ -13,13 +13,13 @@ const ( type InterfaceType string const ( - SOCKS_IFACE InterfaceType = "socks" - TCP_IFACE InterfaceType = "tcp" - UDP_IFACE InterfaceType = "udp" - TUN_IFACE InterfaceType = "tun" + SOCKS_IFACE InterfaceType = "socks" + TCP_IFACE InterfaceType = "tcp" + UDP_IFACE InterfaceType = "udp" + TUN_IFACE InterfaceType = "tun" + SERIAL_IFACE InterfaceType = "serial" ) - type PluginMode string const ( diff --git a/interface/serial/serial_client.go b/interface/serial/serial_client.go index 94e59d2..6654220 100644 --- a/interface/serial/serial_client.go +++ b/interface/serial/serial_client.go @@ -1,55 +1,55 @@ package serial import ( + "github.com/jacobsa/go-serial/serial" icommon "gitlab.com/h.bahadorzadeh/stunning/interface/common" tcommon "gitlab.com/h.bahadorzadeh/stunning/tunnel/common" + "io" "log" "net" - "github.com/jacobsa/go-serial/serial" - "io" ) type SerialClient struct { icommon.TunnelInterfaceClient tun_dialer tcommon.TunnelDialer saddress string - port io.ReadWriteCloser + port io.ReadWriteCloser listen net.Listener } func GetTcpClient(saddress, PortName string, BaudRate, DataBits, StopBits, MinimumReadSize uint, tun_dialer tcommon.TunnelDialer) SerialClient { s := SerialClient{} options := serial.OpenOptions{ - PortName: PortName, - BaudRate: BaudRate, - DataBits: DataBits, - StopBits: StopBits, + PortName: PortName, + BaudRate: BaudRate, + DataBits: DataBits, + StopBits: StopBits, MinimumReadSize: MinimumReadSize, } port, err := serial.Open(options) if err != nil { log.Fatalf("serial.Open: %v", err) } - s.port =port - s.saddress =saddress + s.port = port + s.saddress = saddress return s } func (s SerialClient) WaitingForConnection() { - for { - - sconn, serr := s.tun_dialer.Dial(s.tun_dialer.Protocol().String(), s.saddress) - if serr != nil { - log.Fatalln(serr) - continue - } - // Write 4 bytes to the port. - b := []byte{0x00, 0x01, 0x02, 0x03} - n, err := port.Write(b) - if err != nil { - log.Fatalf("port.Write: %v", err) - } - } + //for { + // + // sconn, serr := s.tun_dialer.Dial(s.tun_dialer.Protocol().String(), s.saddress) + // if serr != nil { + // log.Fatalln(serr) + // continue + // } + // // Write 4 bytes to the port. + // b := []byte{0x00, 0x01, 0x02, 0x03} + // n, err := port.Write(b) + // if err != nil { + // log.Fatalf("port.Write: %v", err) + // } + //} } func (s SerialClient) HandleConnection(conn net.Conn, tconn net.Conn) error { @@ -58,8 +58,6 @@ func (s SerialClient) HandleConnection(conn net.Conn, tconn net.Conn) error { return nil } -func (s SerialClient) Close(){ +func (s SerialClient) Close() { s.port.Close() } - - diff --git a/interface/socks/socks_client.go b/interface/socks/socks_client.go index dfa0654..d0c214e 100644 --- a/interface/socks/socks_client.go +++ b/interface/socks/socks_client.go @@ -51,7 +51,6 @@ func (t SocksClient) HandleConnection(conn net.Conn, tconn net.Conn) error { return nil } - func (t SocksClient) Close() { t.listen.Close() } diff --git a/interface/tun/tun_iface.go b/interface/tun/tun_iface.go index c44781b..2eab633 100644 --- a/interface/tun/tun_iface.go +++ b/interface/tun/tun_iface.go @@ -17,16 +17,15 @@ type TunInterface struct { icommon.TunnelInterfaceClient conf TunConfig iface *water.Interface + stopped bool } - type TunInterfaceClient struct { TunInterface address string - dialer tcommon.TunnelDialer + dialer tcommon.TunnelDialer } - type TunConfig struct { DevType water.DeviceType Address string @@ -50,6 +49,7 @@ func GetTunIface(config TunConfig) TunInterface { iface := TunInterface{ iface: ifce, conf: config, + stopped: false, } return iface } @@ -68,8 +68,8 @@ func GetTunIfaceClient(config TunConfig, addr string, d tcommon.TunnelDialer) Tu } iface := TunInterfaceClient{ - address:addr, - dialer: d, + address: addr, + dialer: d, } iface.iface = ifce iface.conf = config @@ -137,15 +137,21 @@ func runIP(args ...string) { } } -func(t TunInterfaceClient)WaitingForConnection(){ +func (t TunInterfaceClient) WaitingForConnection() { conn, err := t.dialer.Dial(t.dialer.Protocol().String(), t.address) if err == nil { t.HandleConnection(conn) } } -func(t TunInterface)WaitingForConnection(){ - for { +func (t TunInterface) WaitingForConnection() { + for !t.stopped{ time.Sleep(time.Second) } +} + + +func (t TunInterface) Close() error { + t.stopped = true + return nil } \ No newline at end of file diff --git a/interface/udp/udp_client.go b/interface/udp/udp_client.go index 667403c..4a7135e 100644 --- a/interface/udp/udp_client.go +++ b/interface/udp/udp_client.go @@ -47,7 +47,7 @@ func GetUdpClient(url string) *udp_client { }() return s } -func (c *udp_client)WaitingForConnection(){ +func (c *udp_client) WaitingForConnection() { } diff --git a/stunning.go b/stunning.go index 0d121f0..8dcc9f5 100644 --- a/stunning.go +++ b/stunning.go @@ -1,62 +1,249 @@ package stunning import ( + "github.com/songgao/water" + "gitlab.com/h.bahadorzadeh/stunning/common" icommon "gitlab.com/h.bahadorzadeh/stunning/interface/common" + socksiface "gitlab.com/h.bahadorzadeh/stunning/interface/socks" + tcpiface "gitlab.com/h.bahadorzadeh/stunning/interface/tcp" + tuniface "gitlab.com/h.bahadorzadeh/stunning/interface/tun" tcommon "gitlab.com/h.bahadorzadeh/stunning/tunnel/common" - tlstun "gitlab.com/h.bahadorzadeh/stunning/tunnel/tls" - tcptun "gitlab.com/h.bahadorzadeh/stunning/tunnel/tcp" - udptun "gitlab.com/h.bahadorzadeh/stunning/tunnel/udp" httptun "gitlab.com/h.bahadorzadeh/stunning/tunnel/http" httpstun "gitlab.com/h.bahadorzadeh/stunning/tunnel/https" - "gitlab.com/h.bahadorzadeh/stunning/common" + tcptun "gitlab.com/h.bahadorzadeh/stunning/tunnel/tcp" + tlstun "gitlab.com/h.bahadorzadeh/stunning/tunnel/tls" + udptun "gitlab.com/h.bahadorzadeh/stunning/tunnel/udp" "log" ) -type Tunnel struct { - tunnelType common.TunnelType - interfaceType common.InterfaceType - tunnelMode common.TunnelMode - inputPluginChain common.PluginChain +type Tunnel interface { + ListenAndServer() +} +type TunnelCommon struct { + Tunnel + tunnelType common.TunnelType + interfaceType common.InterfaceType + tunnelMode common.TunnelMode + inputPluginChain common.PluginChain outputPluginChain common.PluginChain - tunnelClient tcommon.TunnelDialer - tunnelServer tcommon.TunnelServer - interfaceClient icommon.TunnelInterfaceClient +} + +type TunnelServer struct { + TunnelCommon + tunnelServer tcommon.TunnelServer interfaceServer icommon.TunnelInterfaceServer } -func(t Tunnel)GetTunnelType()common.TunnelType{ +type TunnelClient struct { + TunnelCommon + serverAddress string + tunnelClient tcommon.TunnelDialer + interfaceClient icommon.TunnelInterfaceClient +} + +func (t TunnelCommon) GetTunnelType() common.TunnelType { return t.tunnelType } -func(t Tunnel)GetInterfaceType()common.InterfaceType{ +func (t TunnelCommon) GetInterfaceType() common.InterfaceType { return t.interfaceType } -func(t Tunnel)GetTunnelMode()common.TunnelMode{ +func (t TunnelCommon) GetTunnelMode() common.TunnelMode { return t.tunnelMode } - -func(t Tunnel)ListenAndServer(){ - if t.tunnelMode == common.SERVER { - if &t.tunnelServer != nil{ - defer t.tunnelServer.Close() - t.tunnelServer.WaitingForConnection() - }else{ - log.Panic("No tunnel server") - } - }else if t.tunnelMode == common.CLIENT { - if &t.interfaceClient != nil{ - defer t.interfaceClient.Close() - t.tunnelServer.WaitingForConnection() - }else{ - log.Panic("No tunnel Interface") - } +func (t TunnelServer) ListenAndServer() { + if &t.tunnelServer != nil { + defer t.tunnelServer.Close() + t.tunnelServer.WaitingForConnection() + } else { + log.Panic("No tunnel server") } } -func TunnelFactory(conf map[string]string)Tunnel{ - tun := Tunnel{ - +func (t TunnelClient) ListenAndServer() { + if &t.interfaceClient != nil { + defer t.interfaceClient.Close() + t.tunnelClient.Dial("", t.serverAddress) + } else { + log.Panic("No tunnel Interface") } -} \ No newline at end of file +} + +func TunnelFactory(conf map[string]string) TunnelCommon { + var tun TunnelCommon + if sorc, exist := conf["service_mode"]; exist { + if common.TunnelMode(sorc) == common.CLIENT { + ttun := TunnelClient{} + if stype, exist := conf["server_type"]; exist { + switch common.TunnelType(stype) { + case common.HTTP_TUN: + ttun.tunnelClient = httptun.GetHttpDialer() + break + case common.HTTPS_TUN: + ttun.tunnelClient = httpstun.GetHttpsDialer() + break + case common.TCP_TUN: + ttun.tunnelClient = tcptun.GetTcpDialer() + break + case common.UDP_TUN: + ttun.tunnelClient = udptun.GetUdpDialer() + break + case common.TLS_TUN: + ttun.tunnelClient = tlstun.GetTlsDialer() + break + default: + log.Panicf("Invalid server type(%s).", stype) + } + saddr, sexist := conf["connect"] + if !sexist { + log.Panicf("Service connect address not specified.") + } + caddr, cexist := conf["listen"] + if !cexist { + log.Panicf("Service listen address not specified.") + } + + if itype, exist := conf["interface_type"]; exist { + switch common.InterfaceType(itype) { + case common.SOCKS_IFACE: + ttun.interfaceClient = socksiface.GetSocksClient(caddr, saddr, ttun.tunnelClient) + break + case common.TCP_IFACE: + ttun.interfaceClient = tcpiface.GetTcpClient(caddr, saddr, ttun.tunnelClient) + break + case common.TUN_IFACE: + imtu, exist := conf["mtu"] + if !exist { + imtu = "1500" + } + iname, exist := conf["devname"] + if !exist { + iname = "tun" + } + conf := tuniface.TunConfig{ + DevType: water.TUN, + Address: caddr, + Name: iname, + MTU: imtu, + } + tuniface.GetTunIfaceClient(conf, saddr, ttun.tunnelClient) + break + case common.UDP_IFACE: + case common.SERIAL_IFACE: + default: + log.Panicf("Invalid interface type (%s)", itype) + } + } + } + } else if common.TunnelMode(sorc) == common.SERVER { + ttun := TunnelServer{} + if stype, exist := conf["server_type"]; exist { + if saddr, exist := conf["listen"]; exist { + switch common.TunnelType(stype) { + case common.HTTP_TUN: + tServer, err := httptun.StartHttpServer(saddr) + if err != nil { + log.Panicf("Failed to create tunnel server.\n%v", err) + } + ttun.tunnelServer = tServer + break + case common.HTTPS_TUN: + scert, cexist := conf["cert"] + skey, kexist := conf["key"] + if cexist && kexist { + tServer, err := httpstun.StartHttpsServer(scert, skey, saddr) + if err != nil { + log.Panicf("Failed to create tunnel server.\n%v", err) + } + ttun.tunnelServer = tServer + } else { + log.Panicf("Key or Cert not defiend") + } + break + case common.TCP_TUN: + tServer, err := tcptun.StartTcpServer(saddr) + if err != nil { + log.Panicf("Failed to create tunnel server.\n%v", err) + } + ttun.tunnelServer = tServer + break + case common.UDP_TUN: + tServer, err := udptun.StartUdpServer(saddr) + if err != nil { + log.Panicf("Failed to create tunnel server.\n%v", err) + } + ttun.tunnelServer = tServer + break + case common.TLS_TUN: + scert, cexist := conf["cert"] + skey, kexist := conf["key"] + if cexist && kexist { + tServer, err := tlstun.StartTlsServer(scert, skey, saddr) + if err != nil { + log.Panicf("Failed to create tunnel server.\n%v", err) + } + ttun.tunnelServer = tServer + } else { + log.Panicf("Key or Cert not defiend") + } + break + default: + log.Panicf("Invalid server type(%s).", stype) + } + } else { + log.Panicf("Service listen address not specified.") + } + + if itype, exist := conf["interface_type"]; exist { + switch common.InterfaceType(itype) { + case common.SOCKS_IFACE: + ttun.interfaceServer = socksiface.GetSocksServer() + break + case common.TCP_IFACE: + if iaddr, exist := conf["connect"]; exist { + ttun.interfaceServer = tcpiface.GetTcpServer(iaddr) + } else { + log.Panicf("Service connect address not specified.") + } + break + case common.TUN_IFACE: + iaddr, exist := conf["connect"] + if !exist { + log.Panicf("Service connect address not specified.") + } + imtu, exist := conf["mtu"] + if !exist { + imtu = "1500" + } + iname, exist := conf["devname"] + if !exist { + iname = "tun" + } + conf := tuniface.TunConfig{ + DevType: water.TUN, + Address: iaddr, + Name: iname, + MTU: imtu, + } + ttun.interfaceServer = tuniface.GetTunIface(conf) + break + case common.UDP_IFACE: + case common.SERIAL_IFACE: + default: + log.Panicf("Invalid interface type (%s)", itype) + } + } + } else { + log.Panicf("Server type not defined.") + } + } else { + log.Panicf("Invalid service mode(%s).", sorc) + } + } else { + log.Panicf("Service mode not specified.") + } + tun = TunnelCommon{} + return tun +} diff --git a/tunnel/common/tunnel_server.go b/tunnel/common/tunnel_server.go index d3b4936..0230d94 100644 --- a/tunnel/common/tunnel_server.go +++ b/tunnel/common/tunnel_server.go @@ -6,16 +6,24 @@ import ( "net" ) -type TunnelServer struct { +type TunnelServer interface { + SetServer(server icommon.TunnelInterfaceServer) + WaitingForConnection() + Close() error + HandleConnection(conn net.Conn) +} + +type TunnelServerCommon struct { + TunnelServer Server icommon.TunnelInterfaceServer Listener net.Listener } -func (s TunnelServer) SetServer(ss icommon.TunnelInterfaceServer) { +func (s TunnelServerCommon) SetServer(ss icommon.TunnelInterfaceServer) { s.Server = ss } -func (s TunnelServer) WaitingForConnection() { +func (s TunnelServerCommon) WaitingForConnection() { log.Printf("listening for connection on %s\n", s.Listener.Addr().String()) for { conn, err := s.Listener.Accept() @@ -29,12 +37,12 @@ func (s TunnelServer) WaitingForConnection() { log.Printf("Listening on %s stopped\n", s.Listener.Addr().String()) } -func (s TunnelServer) Close() error { +func (s TunnelServerCommon) Close() error { log.Println("Closing connection") return s.Listener.Close() } -func (s TunnelServer) HandleConnection(conn net.Conn) { +func (s TunnelServerCommon) HandleConnection(conn net.Conn) { defer conn.Close() s.Server.HandleConnection(conn) } diff --git a/tunnel/http/http_server.go b/tunnel/http/http_server.go index 7a6e66a..68a53f4 100644 --- a/tunnel/http/http_server.go +++ b/tunnel/http/http_server.go @@ -12,7 +12,7 @@ import ( ) type HttpServer struct { - tcommon.TunnelServer + tcommon.TunnelServerCommon connMap map[string]tcommon.ServerHttpConnection mux sync.Mutex webserver *http.Server @@ -82,8 +82,9 @@ func (s HttpServer) WaitingForConnection() { s.webserver.ListenAndServe() } -func (s HttpServer) Close() { +func (s HttpServer) Close() error { s.webserver.Close() + return nil } func (s HttpServer) HandleConnection(conn net.Conn) { diff --git a/tunnel/https/https_server.go b/tunnel/https/https_server.go index 655b1d2..21fed47 100644 --- a/tunnel/https/https_server.go +++ b/tunnel/https/https_server.go @@ -12,7 +12,7 @@ import ( ) type HttpsServer struct { - tcommon.TunnelServer + tcommon.TunnelServerCommon connMap map[string]tcommon.ServerHttpConnection mux sync.Mutex webserver *http.Server @@ -85,8 +85,9 @@ func (s HttpsServer) WaitingForConnection() { s.webserver.ListenAndServeTLS(s.crt, s.key) } -func (s HttpsServer) Close() { +func (s HttpsServer) Close() error { s.webserver.Close() + return nil } func (s HttpsServer) HandleConnection(conn net.Conn) { diff --git a/tunnel/tcp/tcp_server.go b/tunnel/tcp/tcp_server.go index b16933d..642698c 100644 --- a/tunnel/tcp/tcp_server.go +++ b/tunnel/tcp/tcp_server.go @@ -7,7 +7,7 @@ import ( ) type TcpServer struct { - tcommon.TunnelServer + tcommon.TunnelServerCommon } func StartTcpServer(address string) (TcpServer, error) { diff --git a/tunnel/tls/tls_server.go b/tunnel/tls/tls_server.go index 3a4a8db..f8302ce 100644 --- a/tunnel/tls/tls_server.go +++ b/tunnel/tls/tls_server.go @@ -7,7 +7,7 @@ import ( ) type TlsServer struct { - tcommon.TunnelServer + tcommon.TunnelServerCommon } func StartTlsServer(crt, key, address string) (TlsServer, error) { diff --git a/tunnel/udp/udp_server.go b/tunnel/udp/udp_server.go index 34dbf7a..1b36c07 100644 --- a/tunnel/udp/udp_server.go +++ b/tunnel/udp/udp_server.go @@ -10,7 +10,7 @@ import ( ) type UdpServer struct { - tcommon.TunnelServer + tcommon.TunnelServerCommon conn *net.UDPConn mux *sync.Mutex wch chan tcommon.UdpPacket