mirror of
https://github.com/xtaci/kcptun.git
synced 2024-04-21 12:32:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76c88158c8 | ||
|
|
af3185d2e9 | ||
|
|
76f62b0dd1 | ||
|
|
9f5d2a278a | ||
|
|
af88878dd9 | ||
|
|
ec9ace1de0 | ||
|
|
e93a1908c1 | ||
|
|
e7c6eb17d2 | ||
|
|
26f6688da3 | ||
|
|
dbaefc35a7 | ||
|
|
5da363682e | ||
|
|
116c1e7668 | ||
|
|
86cc46f437 | ||
|
|
e54a648576 | ||
|
|
49f701be26 | ||
|
|
6e0b2077ea | ||
|
|
873351361a | ||
|
|
f33e913f73 |
@@ -375,3 +375,33 @@ via WeChat
|
||||
<img src="wechat_donate.jpg" alt="kcptun" height="120px" />
|
||||
|
||||
(注意:我没有任何社交网站的账号,请小心骗子。)
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute.
|
||||
<a href="https://github.com/xtaci/kcptun/graphs/contributors"><img src="https://opencollective.com/kcptun/contributors.svg?width=890&button=false" /></a>
|
||||
|
||||
|
||||
## Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/kcptun#backer)]
|
||||
|
||||
<a href="https://opencollective.com/kcptun#backers" target="_blank"><img src="https://opencollective.com/kcptun/backers.svg?width=890"></a>
|
||||
|
||||
|
||||
## Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/kcptun#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/kcptun/sponsor/0/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/1/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/2/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/3/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/4/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/5/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/6/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/7/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/8/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/kcptun/sponsor/9/website" target="_blank"><img src="https://opencollective.com/kcptun/sponsor/9/avatar.svg"></a>
|
||||
|
||||
|
||||
|
||||
+22
-91
@@ -2,8 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
@@ -14,13 +12,11 @@ import (
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli"
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
"github.com/xtaci/kcptun/generic"
|
||||
"github.com/xtaci/smux"
|
||||
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
@@ -32,63 +28,32 @@ var VERSION = "SELFBUILD"
|
||||
// A pool for stream copying
|
||||
var xmitBuf sync.Pool
|
||||
|
||||
type compStream struct {
|
||||
conn net.Conn
|
||||
w *snappy.Writer
|
||||
r *snappy.Reader
|
||||
}
|
||||
|
||||
func (c *compStream) Read(p []byte) (n int, err error) {
|
||||
return c.r.Read(p)
|
||||
}
|
||||
|
||||
func (c *compStream) Write(p []byte) (n int, err error) {
|
||||
n, err = c.w.Write(p)
|
||||
err = c.w.Flush()
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *compStream) Close() error {
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
func newCompStream(conn net.Conn) *compStream {
|
||||
c := new(compStream)
|
||||
c.conn = conn
|
||||
c.w = snappy.NewBufferedWriter(conn)
|
||||
c.r = snappy.NewReader(conn)
|
||||
return c
|
||||
}
|
||||
|
||||
func handleClient(sess *smux.Session, p1 io.ReadWriteCloser, quiet bool) {
|
||||
if !quiet {
|
||||
log.Println("stream opened")
|
||||
defer log.Println("stream closed")
|
||||
logln := func(v ...interface{}) {
|
||||
if !quiet {
|
||||
log.Println(v...)
|
||||
}
|
||||
}
|
||||
|
||||
defer p1.Close()
|
||||
p2, err := sess.OpenStream()
|
||||
if err != nil {
|
||||
logln(err)
|
||||
return
|
||||
}
|
||||
|
||||
defer p2.Close()
|
||||
|
||||
logln("stream opened", p2.ID())
|
||||
defer logln("stream closed", p2.ID())
|
||||
|
||||
// start tunnel & wait for tunnel termination
|
||||
streamCopy := func(dst io.Writer, src io.Reader) chan struct{} {
|
||||
streamCopy := func(dst io.Writer, src io.ReadCloser) chan struct{} {
|
||||
die := make(chan struct{})
|
||||
go func() {
|
||||
if wt, ok := src.(io.WriterTo); ok {
|
||||
wt.WriteTo(dst)
|
||||
close(die)
|
||||
} else if rt, ok := dst.(io.ReaderFrom); ok {
|
||||
rt.ReadFrom(src)
|
||||
close(die)
|
||||
} else {
|
||||
buf := xmitBuf.Get().([]byte)
|
||||
io.CopyBuffer(dst, src, buf)
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}
|
||||
buf := xmitBuf.Get().([]byte)
|
||||
generic.CopyBuffer(dst, src, buf)
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}()
|
||||
return die
|
||||
}
|
||||
@@ -113,7 +78,7 @@ func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
xmitBuf.New = func() interface{} {
|
||||
return make([]byte, 65535)
|
||||
return make([]byte, 32768)
|
||||
}
|
||||
|
||||
myApp := cli.NewApp()
|
||||
@@ -405,7 +370,7 @@ func main() {
|
||||
if config.NoComp {
|
||||
session, err = smux.Client(kcpconn, smuxConfig)
|
||||
} else {
|
||||
session, err = smux.Client(newCompStream(kcpconn), smuxConfig)
|
||||
session, err = smux.Client(generic.NewCompStream(kcpconn), smuxConfig)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "createConn()")
|
||||
@@ -439,12 +404,12 @@ func main() {
|
||||
|
||||
chScavenger := make(chan *smux.Session, 128)
|
||||
go scavenger(chScavenger, config.ScavengeTTL)
|
||||
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
|
||||
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
|
||||
rr := uint16(0)
|
||||
for {
|
||||
p1, err := listener.AcceptTCP()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
log.Fatalf("%+v", err)
|
||||
}
|
||||
checkError(err)
|
||||
idx := rr % numconn
|
||||
@@ -476,16 +441,16 @@ func scavenger(ch chan *smux.Session, ttl int) {
|
||||
select {
|
||||
case sess := <-ch:
|
||||
sessionList = append(sessionList, scavengeSession{sess, time.Now()})
|
||||
log.Println("session marked as expired")
|
||||
log.Println("session marked as expired", sess.RemoteAddr())
|
||||
case <-ticker.C:
|
||||
var newList []scavengeSession
|
||||
for k := range sessionList {
|
||||
s := sessionList[k]
|
||||
if s.session.NumStreams() == 0 || s.session.IsClosed() {
|
||||
log.Println("session normally closed")
|
||||
log.Println("session normally closed", s.session.RemoteAddr())
|
||||
s.session.Close()
|
||||
} else if ttl >= 0 && time.Since(s.ts) >= time.Duration(ttl)*time.Second {
|
||||
log.Println("session reached scavenge ttl")
|
||||
log.Println("session reached scavenge ttl", s.session.RemoteAddr())
|
||||
s.session.Close()
|
||||
} else {
|
||||
newList = append(newList, sessionList[k])
|
||||
@@ -495,37 +460,3 @@ func scavenger(ch chan *smux.Session, ttl int) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func snmpLogger(path string, interval int) {
|
||||
if path == "" || interval == 0 {
|
||||
return
|
||||
}
|
||||
ticker := time.NewTicker(time.Duration(interval) * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
// split path into dirname and filename
|
||||
logdir, logfile := filepath.Split(path)
|
||||
// only format logfile
|
||||
f, err := os.OpenFile(logdir+time.Now().Format(logfile), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
w := csv.NewWriter(f)
|
||||
// write header in empty file
|
||||
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
|
||||
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
kcp.DefaultSnmp.Reset()
|
||||
w.Flush()
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type CompStream struct {
|
||||
conn net.Conn
|
||||
w *snappy.Writer
|
||||
r *snappy.Reader
|
||||
}
|
||||
|
||||
func (c *CompStream) Read(p []byte) (n int, err error) {
|
||||
return c.r.Read(p)
|
||||
}
|
||||
|
||||
func (c *CompStream) Write(p []byte) (n int, err error) {
|
||||
if _, err := c.w.Write(p); err != nil {
|
||||
return 0, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := c.w.Flush(); err != nil {
|
||||
return 0, errors.WithStack(err)
|
||||
}
|
||||
return len(p), err
|
||||
}
|
||||
|
||||
func (c *CompStream) Close() error {
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
func NewCompStream(conn net.Conn) *CompStream {
|
||||
c := new(CompStream)
|
||||
c.conn = conn
|
||||
c.w = snappy.NewBufferedWriter(conn)
|
||||
c.r = snappy.NewReader(conn)
|
||||
return c
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package generic
|
||||
|
||||
import "io"
|
||||
|
||||
// io.CopyBuffer has extra tests for interface like io.ReaderFrom and io.WriterTo
|
||||
// which is not efficient in memory management from tests
|
||||
func CopyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) {
|
||||
if buf != nil && len(buf) == 0 {
|
||||
panic("empty buffer in copyBuffer")
|
||||
}
|
||||
|
||||
for {
|
||||
nr, er := src.Read(buf)
|
||||
if nr > 0 {
|
||||
nw, ew := dst.Write(buf[0:nr])
|
||||
if nw > 0 {
|
||||
written += int64(nw)
|
||||
}
|
||||
if ew != nil {
|
||||
err = ew
|
||||
break
|
||||
}
|
||||
if nr != nw {
|
||||
err = io.ErrShortWrite
|
||||
break
|
||||
}
|
||||
}
|
||||
if er != nil {
|
||||
if er != io.EOF {
|
||||
err = er
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return written, err
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/xtaci/kcp-go"
|
||||
)
|
||||
|
||||
func SnmpLogger(path string, interval int) {
|
||||
if path == "" || interval == 0 {
|
||||
return
|
||||
}
|
||||
ticker := time.NewTicker(time.Duration(interval) * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
// split path into dirname and filename
|
||||
logdir, logfile := filepath.Split(path)
|
||||
// only format logfile
|
||||
f, err := os.OpenFile(logdir+time.Now().Format(logfile), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
w := csv.NewWriter(f)
|
||||
// write header in empty file
|
||||
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
|
||||
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
kcp.DefaultSnmp.Reset()
|
||||
w.Flush()
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,11 @@ require (
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
|
||||
github.com/tjfoc/gmsm v1.0.1 // indirect
|
||||
github.com/urfave/cli v1.20.0
|
||||
github.com/xtaci/kcp-go v5.2.8+incompatible
|
||||
github.com/xtaci/smux v1.2.10
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
|
||||
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 // indirect
|
||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae // indirect
|
||||
github.com/xtaci/kcp-go v5.3.8+incompatible
|
||||
github.com/xtaci/smux v1.3.2
|
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f
|
||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
golang.org/x/tools v0.0.0-20190428024724-550556f78a90 // indirect
|
||||
golang.org/x/tools v0.0.0-20190513233021-7d589f28aaf4 // indirect
|
||||
)
|
||||
|
||||
@@ -36,7 +36,22 @@ github.com/xtaci/kcp-go v5.2.6+incompatible h1:WokjD7IJJopwivFVIleBjmuHYlhGTlR/J
|
||||
github.com/xtaci/kcp-go v5.2.6+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.2.7+incompatible h1:NkJrwfMj3K6lRHfppR8H+oayahPS6GkGGF4BKiRAiFg=
|
||||
github.com/xtaci/kcp-go v5.2.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.2.8+incompatible h1:WRlKHMAWdB08NEmWW0cpdEQcJsOYRdFwP7lA62AhpWo=
|
||||
github.com/xtaci/kcp-go v5.2.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.2+incompatible h1:sWzdr6Wcs/ZlRY0U8PeeMgpmtimIutFNfrxgQTPoA9U=
|
||||
github.com/xtaci/kcp-go v5.3.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.3+incompatible h1:zlvskph4pBYpt5C8Y22GO2EL3saYpE/2WSZRUEKZXbE=
|
||||
github.com/xtaci/kcp-go v5.3.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.4+incompatible h1:vHlrCvUC4nDSGQQxbgzwwF35sup3mKAxr5Wj3Yzg4c4=
|
||||
github.com/xtaci/kcp-go v5.3.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.5+incompatible h1:PD0cqKLJDAMKgX2qzWfK98fbcrVPYDEdstlY0SN0q20=
|
||||
github.com/xtaci/kcp-go v5.3.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.6+incompatible h1:g3/sc8dtbFG6td3W7BTyJNr/5Sb0zMNBFgEtqnSuxmw=
|
||||
github.com/xtaci/kcp-go v5.3.6+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.7+incompatible h1:iWiEoXj7BnFNR1XUPAQssR8DJGw9E7BE0l1rqFCAi3Y=
|
||||
github.com/xtaci/kcp-go v5.3.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.3.8+incompatible h1:1f9hBNbkoMfLryf0P82GzrMkSkqBLUztOmmqKqh7XxM=
|
||||
github.com/xtaci/kcp-go v5.3.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/smux v1.1.1 h1:ZyIo9XHuHkAeENzHR8yGWC+6xUSCTeP2tPTRE8mnLvc=
|
||||
github.com/xtaci/smux v1.1.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
github.com/xtaci/smux v1.1.2 h1:AeAzHKqvDeFEcicL9Q06LTjIVW2I55iooUbpDRGHth4=
|
||||
@@ -59,6 +74,14 @@ github.com/xtaci/smux v1.2.9 h1:aLBpFdORtDMzFJnrktW5hhe6UScbiS9inicP01KWR7M=
|
||||
github.com/xtaci/smux v1.2.9/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
github.com/xtaci/smux v1.2.10 h1:DQiH08XfO+33X7l5XOGV5urQHrgK8PRFWYxT/z9Hrnw=
|
||||
github.com/xtaci/smux v1.2.10/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
github.com/xtaci/smux v1.2.11 h1:QI4M2HgkkpsVU3Bfcmyx10qURBEeHfKi7xDhGEORfu0=
|
||||
github.com/xtaci/smux v1.2.11/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
github.com/xtaci/smux v1.2.12 h1:POGYLDuR61+XZlVzKUdI4fTLtJnyVba++XS4Q6T5e3M=
|
||||
github.com/xtaci/smux v1.2.12/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
github.com/xtaci/smux v1.3.1 h1:qMkK+dTu8ozfYz13UaX5q9GRIx0Qwux3FvcjtKZmDF8=
|
||||
github.com/xtaci/smux v1.3.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
github.com/xtaci/smux v1.3.2 h1:8NsGbxBW6oSaeLu5E6V8AmklZm6EhBz7BeCOU3Zdhwc=
|
||||
github.com/xtaci/smux v1.3.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
|
||||
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=
|
||||
@@ -73,7 +96,14 @@ golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h
|
||||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd h1:sMHc2rZHuzQmrbVoSpt9HgerkXPyIeCSO6k0zUMGfFk=
|
||||
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 h1:rlLehGeYg6jfoyz/eDqDU1iRXLKfR42nnNh57ytKEWo=
|
||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
|
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/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=
|
||||
@@ -90,6 +120,8 @@ golang.org/x/net v0.0.0-20190424024845-afe8014c977f h1:uALRiwYevCJtciRa4mKKFkrs5
|
||||
golang.org/x/net v0.0.0-20190424024845-afe8014c977f/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 h1:FP8hkuE6yUEaJnK7O2eTuejKWwW+Rhfj80dQ2JcKxCU=
|
||||
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
|
||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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=
|
||||
@@ -103,9 +135,13 @@ golang.org/x/sys v0.0.0-20190416152802-12500544f89f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/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=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190424031103-cb2dda6eabdf/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190428024724-550556f78a90/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190509153222-73554e0f7805/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
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=
|
||||
|
||||
+19
-88
@@ -2,8 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
@@ -16,11 +14,9 @@ import (
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
"github.com/urfave/cli"
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
"github.com/xtaci/kcptun/generic"
|
||||
"github.com/xtaci/smux"
|
||||
)
|
||||
|
||||
@@ -33,34 +29,6 @@ var VERSION = "SELFBUILD"
|
||||
// A pool for stream copying
|
||||
var xmitBuf sync.Pool
|
||||
|
||||
type compStream struct {
|
||||
conn net.Conn
|
||||
w *snappy.Writer
|
||||
r *snappy.Reader
|
||||
}
|
||||
|
||||
func (c *compStream) Read(p []byte) (n int, err error) {
|
||||
return c.r.Read(p)
|
||||
}
|
||||
|
||||
func (c *compStream) Write(p []byte) (n int, err error) {
|
||||
n, err = c.w.Write(p)
|
||||
err = c.w.Flush()
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *compStream) Close() error {
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
func newCompStream(conn net.Conn) *compStream {
|
||||
c := new(compStream)
|
||||
c.conn = conn
|
||||
c.w = snappy.NewBufferedWriter(conn)
|
||||
c.r = snappy.NewReader(conn)
|
||||
return c
|
||||
}
|
||||
|
||||
// handle multiplex-ed connection
|
||||
func handleMux(conn io.ReadWriteCloser, config *Config) {
|
||||
// stream multiplex
|
||||
@@ -84,8 +52,8 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
|
||||
go func(p1 *smux.Stream) {
|
||||
p2, err := net.Dial("tcp", config.Target)
|
||||
if err != nil {
|
||||
p1.Close()
|
||||
log.Println(err)
|
||||
p1.Close()
|
||||
return
|
||||
}
|
||||
handleClient(p1, p2, config.Quiet)
|
||||
@@ -93,30 +61,27 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleClient(p1, p2 io.ReadWriteCloser, quiet bool) {
|
||||
if !quiet {
|
||||
log.Println("stream opened")
|
||||
defer log.Println("stream closed")
|
||||
func handleClient(p1 *smux.Stream, p2 io.ReadWriteCloser, quiet bool) {
|
||||
logln := func(v ...interface{}) {
|
||||
if !quiet {
|
||||
log.Println(v...)
|
||||
}
|
||||
}
|
||||
|
||||
defer p1.Close()
|
||||
defer p2.Close()
|
||||
|
||||
logln("stream opened", p1.ID())
|
||||
defer logln("stream closed", p1.ID())
|
||||
|
||||
// start tunnel & wait for tunnel termination
|
||||
streamCopy := func(dst io.Writer, src io.Reader) chan struct{} {
|
||||
streamCopy := func(dst io.Writer, src io.ReadCloser) chan struct{} {
|
||||
die := make(chan struct{})
|
||||
go func() {
|
||||
if wt, ok := src.(io.WriterTo); ok {
|
||||
wt.WriteTo(dst)
|
||||
close(die)
|
||||
} else if rt, ok := dst.(io.ReaderFrom); ok {
|
||||
rt.ReadFrom(src)
|
||||
close(die)
|
||||
} else {
|
||||
buf := xmitBuf.Get().([]byte)
|
||||
io.CopyBuffer(dst, src, buf)
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}
|
||||
buf := xmitBuf.Get().([]byte)
|
||||
generic.CopyBuffer(dst, src, buf)
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}()
|
||||
return die
|
||||
}
|
||||
@@ -141,7 +106,7 @@ func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
xmitBuf.New = func() interface{} {
|
||||
return make([]byte, 65535)
|
||||
return make([]byte, 32768)
|
||||
}
|
||||
|
||||
myApp := cli.NewApp()
|
||||
@@ -395,7 +360,7 @@ func main() {
|
||||
log.Println("SetWriteBuffer:", err)
|
||||
}
|
||||
|
||||
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
|
||||
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
|
||||
if config.Pprof {
|
||||
go http.ListenAndServe(":6060", nil)
|
||||
}
|
||||
@@ -413,7 +378,7 @@ func main() {
|
||||
if config.NoComp {
|
||||
go handleMux(conn, &config)
|
||||
} else {
|
||||
go handleMux(newCompStream(conn), &config)
|
||||
go handleMux(generic.NewCompStream(conn), &config)
|
||||
}
|
||||
} else {
|
||||
log.Printf("%+v", err)
|
||||
@@ -422,37 +387,3 @@ func main() {
|
||||
}
|
||||
myApp.Run(os.Args)
|
||||
}
|
||||
|
||||
func snmpLogger(path string, interval int) {
|
||||
if path == "" || interval == 0 {
|
||||
return
|
||||
}
|
||||
ticker := time.NewTicker(time.Duration(interval) * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
// split path into dirname and filename
|
||||
logdir, logfile := filepath.Split(path)
|
||||
// only format logfile
|
||||
f, err := os.OpenFile(logdir+time.Now().Format(logfile), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
w := csv.NewWriter(f)
|
||||
// write header in empty file
|
||||
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
|
||||
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
kcp.DefaultSnmp.Reset()
|
||||
w.Flush()
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user