Changes for unit test

This commit is contained in:
wweir
2019-04-04 10:57:25 +08:00
parent aed2afbe6d
commit a57f85ab1b
17 changed files with 208 additions and 110 deletions
+11 -6
View File
@@ -24,15 +24,20 @@ kill:
sudo pkill -9 sower || true
client: build kill
sudo $(PWD)/sower
sudo $(PWD)/sower -f '' -s 127.0.0.1:5533 -H "127.0.0.1:8080"
server: build kill
$(PWD)/sower -n TCP -v 1
server: build
$(PWD)/sower -f ''
run: build kill
$(PWD)/sower -n TCP -v 1 &
sudo $(PWD)/sower &
$(PWD)/sower -f '' &
sudo $(PWD)/sower -f '' -s 127.0.0.1:5533 -H "127.0.0.1:8080" &
@sleep 1
curl localhost
HTTP_PROXY=http://127.0.0.1:8080 curl http://baidu.com || true
@echo
HTTPS_PROXY=http://127.0.0.1:8080 curl https://baidu.com || true
@echo
@sleep 1
@sudo pkill -9 sower || true
+2 -2
View File
@@ -23,11 +23,11 @@ func initArgs() {
flag.StringVar(&Conf.Cipher, "C", "AES_128_GCM", "cipher type: "+strings.Join(shadow.ListCiphers(), ","))
flag.StringVar(&Conf.Password, "p", "12345678", "password")
flag.StringVar(&Conf.ServerPort, "P", "5533", "server mode listen port")
flag.StringVar(&Conf.ServerAddr, "s", "", "server IP (run in CLIENT MODE if set)")
flag.StringVar(&Conf.ServerAddr, "s", "", "server IP (run in CLIENT mode if set)")
flag.StringVar(&Conf.HTTPProxy, "H", "", "http proxy listen addr")
flag.StringVar(&Conf.DNSServer, "d", "114.114.114.114", "client dns server")
flag.StringVar(&Conf.ClientIP, "c", "127.0.0.1", "client dns service redirect IP")
flag.StringVar(&Conf.SuggestLevel, "S", "SPEEDUP", "suggest level setting: "+strings.Join(dns.ListSuggestLevels(), ","))
flag.StringVar(&Conf.SuggestLevel, "l", "SPEEDUP", "suggest level setting: "+strings.Join(dns.ListSuggestLevels(), ","))
flag.BoolVar(&Conf.VersionOnly, "V", false, "print sower version")
if !flag.Parsed() {
+11 -2
View File
@@ -1,9 +1,18 @@
package dns
import "testing"
import (
"runtime"
"testing"
)
func TestGetDefaultDNSServer(t *testing.T) {
t.Skip("skip for some enviroment not support dhcp and permission")
switch runtime.GOOS {
case "windows":
case "darwin":
default:
t.Skip("skip for some enviroment not support dhcp and permission set")
return
}
if got, err := GetDefaultDNSServer(); err != nil {
t.Errorf("GetDefaultDNSServer() return error: %s", err)
+27 -38
View File
@@ -10,14 +10,15 @@ import (
"github.com/golang/glog"
"github.com/miekg/dns"
mem "github.com/wweir/mem-go"
"github.com/wweir/sower/util"
)
const colon = byte(':')
func StartDNS(dnsServer, listenIP string, suggestCh chan<- string, suggestLevel string) {
func StartDNS(dnsServer, listenIP string, suggestCh chan<- string, level string) {
ip := net.ParseIP(listenIP)
suggest := &intelliSuggest{suggestCh, parseSuggestLevel(suggestLevel), listenIP, time.Second}
suggest := &intelliSuggest{suggestCh, parseSuggestLevel(level), listenIP, time.Second}
mem.DefaultCache = mem.New(time.Hour)
dhcpCh := make(chan struct{})
@@ -93,18 +94,7 @@ func matchAndServe(w dns.ResponseWriter, r *dns.Msg, domain, listenIP, dnsServer
return
}
if !inWriteList {
go func() {
ip, err := net.LookupIP(domain)
if err != nil || len(ip) == 0 {
glog.V(1).Infoln(ip, err)
return
}
mem.Remember(suggest, addr{domain, ip[0].String()})
}()
}
go mem.Remember(suggest, domain)
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
@@ -127,40 +117,39 @@ func matchAndServe(w dns.ResponseWriter, r *dns.Msg, domain, listenIP, dnsServer
}
type intelliSuggest struct {
suggestCh chan<- string
suggestLevel suggestLevel
listenIP string
timeout time.Duration
}
type addr struct {
domain string
ip string
suggestCh chan<- string
level level
listenIP string
timeout time.Duration
}
func (i *intelliSuggest) GetOne(key interface{}) (iface interface{}, e error) {
iface, e = struct{}{}, nil
if i.suggestLevel == DISABLE {
if i.level == DISABLE {
return
}
domain := key.(addr).domain
ip := key.(addr).ip
// kill deadloop, for ugly wildcard setting dns setting
domain = strings.TrimSuffix(domain, ".")
domain := strings.TrimSuffix(key.(string), ".")
if strings.Count(domain, ".") > 10 {
return
}
ip, err := net.LookupIP(domain)
if err != nil || len(ip) == 0 {
glog.V(1).Infoln(domain, ip, err)
return
}
var (
pings = [...]struct {
viaAddr string
port Port
port util.Port
}{
{ip, HTTP},
{i.listenIP, HTTP},
{ip, HTTPS},
{i.listenIP, HTTPS},
{ip[0].String(), util.HTTP},
{i.listenIP, util.HTTP},
{ip[0].String(), util.HTTPS},
{i.listenIP, util.HTTPS},
}
protos = [...]*int32{
new(int32), /*HTTP*/
@@ -170,19 +159,19 @@ func (i *intelliSuggest) GetOne(key interface{}) (iface interface{}, e error) {
)
for idx := range pings {
go func(idx int) {
if err := HTTPPing(pings[idx].viaAddr, domain, pings[idx].port, i.timeout); err != nil {
if err := util.HTTPPing(pings[idx].viaAddr, domain, pings[idx].port, i.timeout); err != nil {
// local ping fail
if pings[idx].viaAddr == ip {
atomic.AddInt32(score, 1)
glog.V(1).Infof("local ping %s fail", domain)
} else {
if pings[idx].viaAddr == i.listenIP {
atomic.AddInt32(score, -1)
glog.V(1).Infof("remote ping %s fail", domain)
} else {
atomic.AddInt32(score, 1)
glog.V(1).Infof("local ping %s fail", domain)
}
// remote ping faster
} else if pings[idx].viaAddr == i.listenIP {
if atomic.CompareAndSwapInt32(protos[idx/2], 0, 1) && i.suggestLevel == SPEEDUP {
if atomic.CompareAndSwapInt32(protos[idx/2], 0, 1) && i.level == SPEEDUP {
atomic.AddInt32(score, 1)
}
glog.V(1).Infof("remote ping %s faster", domain)
+16
View File
@@ -0,0 +1,16 @@
// Code generated by "stringer -type=level util.go"; DO NOT EDIT.
package dns
import "strconv"
const _level_name = "DISABLEBLOCKSPEEDUPlevelEnd"
var _level_index = [...]uint8{0, 7, 12, 19, 27}
func (i level) String() string {
if i < 0 || i >= level(len(_level_index)-1) {
return "level(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _level_name[_level_index[i]:_level_index[i+1]]
}
-16
View File
@@ -1,16 +0,0 @@
// Code generated by "stringer -type=suggestLevel util.go"; DO NOT EDIT.
package dns
import "strconv"
const _suggestLevel_name = "DISABLEBLOCKSPEEDUPlevelEnd"
var _suggestLevel_index = [...]uint8{0, 7, 12, 19, 27}
func (i suggestLevel) String() string {
if i < 0 || i >= suggestLevel(len(_suggestLevel_index)-1) {
return "suggestLevel(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _suggestLevel_name[_suggestLevel_index[i]:_suggestLevel_index[i+1]]
}
+8 -8
View File
@@ -46,11 +46,11 @@ func localA(r *dns.Msg, domain string, localIP net.IP) *dns.Msg {
return m
}
//go:generate stringer -type=suggestLevel $GOFILE
type suggestLevel int32
//go:generate stringer -type=level $GOFILE
type level int32
const (
DISABLE suggestLevel = iota
DISABLE level = iota
BLOCK
SPEEDUP
levelEnd
@@ -58,19 +58,19 @@ const (
func ListSuggestLevels() []string {
list := make([]string, 0, int(levelEnd))
for i := suggestLevel(0); i < levelEnd; i++ {
for i := level(0); i < levelEnd; i++ {
list = append(list, i.String())
}
return list
}
func parseSuggestLevel(level string) suggestLevel {
for i := suggestLevel(0); i < levelEnd; i++ {
if level == i.String() {
func parseSuggestLevel(suggestLevel string) level {
for i := level(0); i < levelEnd; i++ {
if suggestLevel == i.String() {
return i
}
}
glog.Exitln("invalid suggest level: " + level)
glog.Exitln("invalid suggest level: " + suggestLevel)
return levelEnd
}
+2 -2
View File
@@ -62,11 +62,11 @@ func StartClient(tran transport.Transport, isSocks5 bool, server, cipher, passwo
case !isSocks5 && isHttp:
rc = shadow.Shadow(rc, cipher, password)
rc = parser.NewHttpProtocol(rc)
rc = parser.NewHttpConn(rc)
case !isSocks5 && !isHttp:
rc = shadow.Shadow(rc, cipher, password)
rc = parser.NewHttpsProtocol(rc, "443")
rc = parser.NewHttpsConn(rc, "443")
}
go relay(conn, rc)
+3 -3
View File
@@ -58,8 +58,8 @@ func httpProxy(w http.ResponseWriter, r *http.Request,
return nil, err
}
conn = parser.NewHttpProtocol(conn)
return shadow.Shadow(conn, cipher, password), nil
conn = shadow.Shadow(conn, cipher, password)
return parser.NewHttpConn(conn), nil
}
}
@@ -120,7 +120,7 @@ func httpsProxy(w http.ResponseWriter, r *http.Request,
} else {
rc = shadow.Shadow(rc, cipher, password)
rc = parser.NewHttpsProtocol(rc, port)
rc = parser.NewHttpsConn(rc, port)
}
relay(rc, conn)
+68
View File
@@ -0,0 +1,68 @@
package parser
import (
"bufio"
"bytes"
"io/ioutil"
"net"
"net/http"
"testing"
"github.com/wweir/sower/util"
)
func TestParseAddr1(t *testing.T) {
c1, c2 := net.Pipe()
go func() {
c1 = NewHttpConn(c1)
req, _ := http.NewRequest("GET", "http://wweir.cc", bytes.NewReader([]byte{1, 2, 3}))
req.Write(c1)
}()
c2, host, port, err := ParseAddr(c2)
if err != nil || host != "wweir.cc" || port != "80" {
t.Error(err, host, port)
}
req, err := http.ReadRequest(bufio.NewReader(c2))
if err != nil {
t.Error(err)
}
data, err := ioutil.ReadAll(req.Body)
if err != nil || len(data) != 3 || data[0] != 1 {
t.Error(err, data)
}
}
func TestParseAddr2(t *testing.T) {
c1, c2 := net.Pipe()
go func() {
c1 = NewHttpsConn(c1, "443")
c1.Write(util.HTTPS.PingMsg("wweir.cc"))
}()
_, host, port, err := ParseAddr(c2)
if err != nil || host != "wweir.cc" || port != "443" {
t.Error(err, host, port)
}
}
func TestParseAddr3(t *testing.T) {
c1, c2 := net.Pipe()
go func() {
c1 = NewOtherConn(c1, "wweir.cc", "1080")
c1.Write(util.HTTPS.PingMsg("wweir.cc"))
}()
_, host, port, err := ParseAddr(c2)
if err != nil || host != "wweir.cc" || port != "1080" {
t.Error(err, host, port)
}
}
+4 -6
View File
@@ -14,7 +14,7 @@ func StartServer(tran transport.Transport, port, cipher, password string) {
if port == "" {
glog.Fatalln("port must set")
}
if !strings.Contains(port, ":") {
if !strings.HasPrefix(port, ":") {
port = ":" + port
}
@@ -25,14 +25,12 @@ func StartServer(tran transport.Transport, port, cipher, password string) {
glog.Infoln("Server started.")
for {
conn := <-connCh
conn = shadow.Shadow(conn, cipher, password)
go handle(conn)
go handle(<-connCh, cipher, password)
}
}
func handle(conn net.Conn) {
func handle(conn net.Conn, cipher, password string) {
conn = shadow.Shadow(conn, cipher, password)
conn, host, port, err := parser.ParseAddr(conn)
if err != nil {
conn.Close()
+7 -7
View File
@@ -8,11 +8,11 @@ import (
"golang.org/x/crypto/chacha20poly1305"
)
//go:generate stringer -type=cipherType $GOFILE
type cipherType int
//go:generate stringer -type=typ $GOFILE
type typ int
const (
AES_128_GCM cipherType = iota
AES_128_GCM typ = iota
AES_192_GCM
AES_256_GCM
CHACHA20_IETF_POLY1305
@@ -22,15 +22,15 @@ const (
func ListCiphers() []string {
list := make([]string, 0, int(cipherEnd))
for i := cipherType(0); i < cipherEnd; i++ {
for i := typ(0); i < cipherEnd; i++ {
list = append(list, i.String())
}
return list
}
func pickCipher(cipherType, password string) (cipher.AEAD, error) {
func pickCipher(typ, password string) (cipher.AEAD, error) {
var blockSize int
switch cipherType {
switch typ {
case AES_128_GCM.String():
blockSize = 16
case AES_192_GCM.String():
@@ -44,7 +44,7 @@ func pickCipher(cipherType, password string) (cipher.AEAD, error) {
return chacha20poly1305.NewX(genKey(password, 256))
default:
return nil, errors.New("do not support cipher type: " + cipherType)
return nil, errors.New("do not support cipher type: " + typ)
}
// aes gcm
-16
View File
@@ -1,16 +0,0 @@
// Code generated by "stringer -type=cipherType cipher.go"; DO NOT EDIT.
package shadow
import "strconv"
const _cipherType_name = "AES_128_GCMAES_192_GCMAES_256_GCMCHACHA20_IETF_POLY1305XCHACHA20_IETF_POLY1305cipherEnd"
var _cipherType_index = [...]uint8{0, 11, 22, 33, 55, 78, 87}
func (i cipherType) String() string {
if i < 0 || i >= cipherType(len(_cipherType_index)-1) {
return "cipherType(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _cipherType_name[_cipherType_index[i]:_cipherType_index[i+1]]
}
+22
View File
@@ -0,0 +1,22 @@
package shadow
import (
"net"
"testing"
)
func TestShadow(t *testing.T) {
c1, c2 := net.Pipe()
go func() {
conn := Shadow(c1, "AES_128_GCM", "12345678")
conn.Write([]byte{1, 2})
}()
conn := Shadow(c2, "AES_128_GCM", "12345678")
buf := make([]byte, 3)
n, _ := conn.Read(buf)
if n!=2|| buf[0] != 1 || buf[1] != 2 {
t.Error(buf)
}
}
+16
View File
@@ -0,0 +1,16 @@
// Code generated by "stringer -type=typ cipher.go"; DO NOT EDIT.
package shadow
import "strconv"
const _typ_name = "AES_128_GCMAES_192_GCMAES_256_GCMCHACHA20_IETF_POLY1305XCHACHA20_IETF_POLY1305cipherEnd"
var _typ_index = [...]uint8{0, 11, 22, 33, 55, 78, 87}
func (i typ) String() string {
if i < 0 || i >= typ(len(_typ_index)-1) {
return "typ(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _typ_name[_typ_index[i]:_typ_index[i+1]]
}
+3 -3
View File
@@ -1,4 +1,4 @@
package dns
package util
import (
"bytes"
@@ -18,7 +18,7 @@ func HTTPPing(viaHost, domain string, port Port, timeout time.Duration) (err err
defer conn.Close()
conn.SetDeadline(time.Now().Add(timeout))
if _, err = conn.Write(port.pingMsg(domain)); err != nil {
if _, err = conn.Write(port.PingMsg(domain)); err != nil {
return err
}
@@ -51,7 +51,7 @@ func (p Port) JoinAddr(addr string) string {
}
}
func (p Port) pingMsg(domain string) []byte {
func (p Port) PingMsg(domain string) []byte {
switch p {
case HTTP:
return []byte("TRACE / HTTP/1.1\r\nHost: " + domain + "\r\n\r\n")
+8 -1
View File
@@ -1,11 +1,18 @@
package util
import (
"runtime"
"testing"
)
func TestPickInterface(t *testing.T) {
t.Skip("skip for some enviroment not have net interface")
switch runtime.GOOS {
case "windows":
case "darwin":
default:
t.Skip("skip for some enviroment not have net interface")
return
}
got, err := PickInterface()
if err != nil {