diff --git a/.travis.yml b/.travis.yml index 8322e02..1cb5a08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,11 @@ language: go go: - - 1.9.x - 1.10.x - 1.11.x + - 1.12.x before_install: + - sudo apt update + - sudo apt install libpcap-dev - go get github.com/mattn/goveralls - go get golang.org/x/tools/cmd/cover install: diff --git a/Dockerfile b/Dockerfile index 0c2db5d..03bf196 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,11 @@ FROM golang:alpine as builder MAINTAINER xtaci RUN apk update && \ apk upgrade && \ - apk add git + apk add git libpcap-dev RUN go get -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" github.com/xtaci/kcptun/client && go get -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" github.com/xtaci/kcptun/server -FROM alpine:3.9 +FROM alpine:latest COPY --from=builder /go/bin /bin EXPOSE 29900/udp +EXPOSE 29900 EXPOSE 12948 diff --git a/client/config.go b/client/config.go index a5d3ed4..5e01ed3 100644 --- a/client/config.go +++ b/client/config.go @@ -34,6 +34,7 @@ type Config struct { SnmpLog string `json:"snmplog"` SnmpPeriod int `json:"snmpperiod"` Quiet bool `json:"quiet"` + TCP bool `json:"tcp"` } func parseJSONConfig(config *Config, path string) error { diff --git a/client/main.go b/client/main.go index ad3a9a5..89333cc 100644 --- a/client/main.go +++ b/client/main.go @@ -18,6 +18,7 @@ import ( kcp "github.com/xtaci/kcp-go" "github.com/xtaci/kcptun/generic" "github.com/xtaci/smux" + "github.com/xtaci/tcpraw" ) // SALT is use for pbkdf2 key expansion @@ -221,6 +222,10 @@ func main() { Name: "quiet", Usage: "to suppress the 'stream open/close' messages", }, + cli.BoolFlag{ + Name: "tcp", + Usage: "to emulate a TCP connection", + }, cli.StringFlag{ Name: "c", Value: "", // when the value is not empty, the config path must exists @@ -256,6 +261,7 @@ func main() { config.SnmpLog = c.String("snmplog") config.SnmpPeriod = c.Int("snmpperiod") config.Quiet = c.Bool("quiet") + config.TCP = c.Bool("tcp") if c.String("c") != "" { err := parseJSONConfig(&config, c.String("c")) @@ -339,13 +345,26 @@ func main() { log.Println("snmplog:", config.SnmpLog) log.Println("snmpperiod:", config.SnmpPeriod) log.Println("quiet:", config.Quiet) + log.Println("tcp:", config.TCP) smuxConfig := smux.DefaultConfig() smuxConfig.MaxReceiveBuffer = config.SmuxBuf smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second createConn := func() (*smux.Session, error) { - kcpconn, err := kcp.DialWithOptions(config.RemoteAddr, block, config.DataShard, config.ParityShard) + var kcpconn *kcp.UDPSession + if config.TCP { + conn, err := tcpraw.Dial("tcp", config.RemoteAddr) + if err != nil { + return nil, errors.Wrap(err, "tcpraw.Dial()") + } + kcpconn, err = kcp.NewConn(config.RemoteAddr, block, config.DataShard, config.ParityShard, conn) + if err != nil { + return nil, errors.Wrap(err, "createConn()") + } + } + + kcpconn, err = kcp.DialWithOptions(config.RemoteAddr, block, config.DataShard, config.ParityShard) if err != nil { return nil, errors.Wrap(err, "createConn()") } diff --git a/go.mod b/go.mod index 6133ab7..885294e 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,7 @@ module github.com/xtaci/kcptun require ( github.com/golang/snappy v0.0.1 + github.com/google/gopacket v1.1.17 // indirect github.com/klauspost/cpuid v1.2.1 // indirect github.com/klauspost/reedsolomon v1.9.2 // indirect github.com/pkg/errors v0.8.1 @@ -11,9 +12,10 @@ require ( github.com/urfave/cli v1.20.0 github.com/xtaci/kcp-go v5.4.2+incompatible github.com/xtaci/smux v1.3.3 - golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 - golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect - golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae // indirect + github.com/xtaci/tcpraw v1.0.11 + golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 + golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect + golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 // indirect golang.org/x/text v0.3.2 // indirect - golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7 // indirect + golang.org/x/tools v0.0.0-20190625160430-252024b82959 // indirect ) diff --git a/go.sum b/go.sum index 6a60fc7..2f5a73e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= +github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= @@ -91,6 +93,24 @@ github.com/xtaci/smux v1.3.2 h1:8NsGbxBW6oSaeLu5E6V8AmklZm6EhBz7BeCOU3Zdhwc= github.com/xtaci/smux v1.3.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw= github.com/xtaci/smux v1.3.3 h1:+vnzZHTLGHrj+LzUZEkKmvu4KkG7fj4jwMPqhawvErg= github.com/xtaci/smux v1.3.3/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw= +github.com/xtaci/tcpraw v1.0.0 h1:pte2E7y6RbqmjGbbezoH/ZV3cqYATo0yT3iZvColyA4= +github.com/xtaci/tcpraw v1.0.0/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.1/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.2/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.3 h1:JkOedFmlUQ3TwCBS93pCeaN1ENY4Q7bf2C+ytduN/9k= +github.com/xtaci/tcpraw v1.0.3/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.4 h1:tCpmrmpR904XAQxoVe+HJmzh3gR/R1/PsCPNIWlS7kQ= +github.com/xtaci/tcpraw v1.0.4/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.6 h1:A+J3FOHh5twbi2tAvLjyxKz7fHPRM49ibtUTwLZnYJs= +github.com/xtaci/tcpraw v1.0.6/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.7 h1:zfoWxygl8T5MSrAezU0BNw0bBFGTIYIVIGnL9P9k0qk= +github.com/xtaci/tcpraw v1.0.7/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.9 h1:r8NW59RJWOF6hubWOZ+/WqfiqRhg9Gumwz5jY47RvSU= +github.com/xtaci/tcpraw v1.0.9/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.10 h1:AhES6V2LNqL59V8yBt+QGegBJUaw6QwT6pEHYb0Wsk4= +github.com/xtaci/tcpraw v1.0.10/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= +github.com/xtaci/tcpraw v1.0.11 h1:mFWp9qwOwDjQqMgGFie7pBwDaPzJk+Lafq3Vgb85438= +github.com/xtaci/tcpraw v1.0.11/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -115,6 +135,8 @@ golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPl golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -135,6 +157,8 @@ golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR17 golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00= golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -151,6 +175,8 @@ golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -161,3 +187,5 @@ golang.org/x/tools v0.0.0-20190509153222-73554e0f7805/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190511041617-99f201b6807e/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190513233021-7d589f28aaf4/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190625160430-252024b82959/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= diff --git a/server/config.go b/server/config.go index b3c7ea6..5858ccb 100644 --- a/server/config.go +++ b/server/config.go @@ -32,6 +32,7 @@ type Config struct { SnmpPeriod int `json:"snmpperiod"` Pprof bool `json:"pprof"` Quiet bool `json:"quiet"` + TCP bool `json:"tcp"` } func parseJSONConfig(config *Config, path string) error { diff --git a/server/main.go b/server/main.go index f68dfff..ea93d0d 100644 --- a/server/main.go +++ b/server/main.go @@ -19,6 +19,7 @@ import ( kcp "github.com/xtaci/kcp-go" "github.com/xtaci/kcptun/generic" "github.com/xtaci/smux" + "github.com/xtaci/tcpraw" ) // SALT is use for pbkdf2 key expansion @@ -238,6 +239,10 @@ func main() { Name: "quiet", Usage: "to suppress the 'stream open/close' messages", }, + cli.BoolFlag{ + Name: "tcp", + Usage: "to emulate a TCP connection", + }, cli.StringFlag{ Name: "c", Value: "", // when the value is not empty, the config path must exists @@ -271,6 +276,7 @@ func main() { config.SnmpPeriod = c.Int("snmpperiod") config.Pprof = c.Bool("pprof") config.Quiet = c.Bool("quiet") + config.TCP = c.Bool("tcp") if c.String("c") != "" { //Now only support json config file @@ -331,7 +337,15 @@ func main() { block, _ = kcp.NewAESBlockCrypt(pass) } - lis, err := kcp.ListenWithOptions(config.Listen, block, config.DataShard, config.ParityShard) + var lis *kcp.Listener + var err error + if config.TCP { + conn, err := tcpraw.Listen("tcp", config.Listen) + checkError(err) + lis, err = kcp.ServeConn(block, config.DataShard, config.ParityShard, conn) + checkError(err) + } + lis, err = kcp.ListenWithOptions(config.Listen, block, config.DataShard, config.ParityShard) checkError(err) log.Println("listening on:", lis.Addr()) log.Println("target:", config.Target) @@ -350,6 +364,7 @@ func main() { log.Println("snmpperiod:", config.SnmpPeriod) log.Println("pprof:", config.Pprof) log.Println("quiet:", config.Quiet) + log.Println("tcp:", config.TCP) if err := lis.SetDSCP(config.DSCP); err != nil { log.Println("SetDSCP:", err)