diff --git a/hop/buffer.go b/hop/buffer.go index 6fa1a62..ace9b5f 100644 --- a/hop/buffer.go +++ b/hop/buffer.go @@ -21,25 +21,25 @@ package hop import ( - "sort" "errors" + "sort" "sync" "time" ) const ( - hpBufSize = 384 + hpBufSize = 384 bufferTimeout = 20 * time.Millisecond ) type hopPacketBuffer struct { - buf [hpBufSize]*HopPacket - outQueue []*HopPacket - count int - timer *time.Timer - timeout time.Duration + buf [hpBufSize]*HopPacket + outQueue []*HopPacket + count int + timer *time.Timer + timeout time.Duration flushChan chan *HopPacket - mutex sync.Mutex + mutex sync.Mutex } var bufFull = errors.New("Buffer Full") @@ -47,7 +47,7 @@ var bufFull = errors.New("Buffer Full") func newHopPacketBuffer(flushChan chan *HopPacket, timeout time.Duration) *hopPacketBuffer { hb := new(hopPacketBuffer) hb.count = 0 - hb.timer = time.NewTimer(1000*time.Second) + hb.timer = time.NewTimer(1000 * time.Second) hb.timer.Stop() hb.flushChan = flushChan hb.timeout = timeout @@ -86,7 +86,6 @@ func (hb *hopPacketBuffer) Swap(i, j int) { hb.outQueue[i], hb.outQueue[j] = hb.outQueue[j], hb.outQueue[i] } - func (hb *hopPacketBuffer) Flush() { defer hb.mutex.Unlock() hb.mutex.Lock() @@ -105,7 +104,7 @@ func (hb *hopPacketBuffer) _flushToChan(c chan *HopPacket) { } sort.Sort(hb) - for _, p := range(hb.outQueue) { + for _, p := range hb.outQueue { c <- p } hb.count = 0 diff --git a/hop/cipher.go b/hop/cipher.go index dbeb137..ed1cbc5 100644 --- a/hop/cipher.go +++ b/hop/cipher.go @@ -22,6 +22,7 @@ import ( "bytes" "crypto/aes" _cipher "crypto/cipher" + "crypto/md5" "crypto/rand" ) @@ -33,8 +34,9 @@ const cipherBlockSize = 16 func newHopCipher(key []byte) (*hopCipher, error) { s := new(hopCipher) - key = PKCS5Padding(key, cipherBlockSize) - block, err := aes.NewCipher(key) + // key = PKCS5Padding(key, cipherBlockSize) + key1 := md5.Sum(key) + block, err := aes.NewCipher(key1[:]) if err != nil { return nil, err } @@ -55,7 +57,7 @@ func (s *hopCipher) encrypt(msg []byte) []byte { } func (s *hopCipher) decrypt(iv []byte, ctext []byte) []byte { - defer func(){ + defer func() { if err := recover(); err != nil { logger.Error("%v", err) } diff --git a/hop/client.go b/hop/client.go index c4c1b89..823e6f5 100644 --- a/hop/client.go +++ b/hop/client.go @@ -19,17 +19,17 @@ package hop import ( + "crypto/rand" + "errors" + "fmt" + "github.com/bigeagle/water" + mrand "math/rand" "net" "os" "os/signal" + "sync/atomic" "syscall" "time" - "fmt" - "errors" - "crypto/rand" - mrand "math/rand" - "github.com/bigeagle/water" - "sync/atomic" ) var net_gateway, net_nic string @@ -40,9 +40,9 @@ type route struct { type HopClient struct { // config - cfg HopClientConfig + cfg *HopClientConfig // interface - iface *water.Interface + iface *water.Interface // ip addr ip net.IP @@ -54,12 +54,12 @@ type HopClient struct { // net to interface toIface chan *HopPacket // buffer for packets from net - recvBuf *hopPacketBuffer + recvBuf *hopPacketBuffer // channel to send frames to net toNet chan *HopPacket handshakeDone chan byte - finishAck chan byte + finishAck chan byte // state variable to ensure serverRoute added srvRoute int32 // routes need to be clean in the end @@ -68,8 +68,7 @@ type HopClient struct { seq uint32 } - -func NewClient(cfg HopClientConfig) error { +func NewClient(cfg *HopClientConfig) error { var err error // logger.Debug("%v", cfg) @@ -122,7 +121,6 @@ func NewClient(cfg HopClientConfig) error { go hopClient.handleUDP(server) } - // wait until handshake done res := <-hopClient.handshakeDone if res == 0 { @@ -193,7 +191,7 @@ func (clt *HopClient) handleInterface() { } else { // with traffic morphing packets := hopFrager.Fragmentate(clt, buf[HOP_HDR_LEN:]) - for _, hp := range(packets) { + for _, hp := range packets { clt.toNet <- hp } } @@ -211,7 +209,7 @@ func (clt *HopClient) handleUDP(server string) { pktHandle := map[byte](func(*net.UDPConn, *HopPacket)){ HOP_FLG_HSH | HOP_FLG_ACK: clt.handleHandshakeAck, HOP_FLG_HSH | HOP_FLG_FIN: clt.handleHandshakeError, - HOP_FLG_DAT: clt.handleDataPacket, + HOP_FLG_DAT: clt.handleDataPacket, HOP_FLG_DAT | HOP_FLG_MFR: clt.handleDataPacket, HOP_FLG_FIN | HOP_FLG_ACK: clt.handleFinishAck, } @@ -250,7 +248,6 @@ func (clt *HopClient) handleUDP(server string) { } }() - buf := make([]byte, IFACE_BUFSIZE) for { logger.Debug("waiting for udp packet") @@ -284,7 +281,7 @@ func (clt *HopClient) toServer(u *net.UDPConn, flag byte, payload []byte, noise hp.Seq = clt.Seq() hp.setPayload(payload) if noise { - hp.addNoise(mrand.Intn(MTU-64-len(payload))) + hp.addNoise(mrand.Intn(MTU - 64 - len(payload))) } u.Write(hp.Pack()) } @@ -318,19 +315,12 @@ func (clt *HopClient) finishSession() { clt.toNet <- hp } - // handle handeshake ack func (clt *HopClient) handleHandshakeAck(u *net.UDPConn, hp *HopPacket) { if atomic.LoadInt32(&clt.state) == HOP_STAT_HANDSHAKE { - _ip, _net, _mask := make([]byte, 4), make([]byte, 4), make([]byte, 4) - copy(_ip, hp.payload[:4]) - copy(_net, hp.payload[:4]) - copy(_mask, hp.payload[4:8]) - logger.Debug("%v", hp.payload) - _net[3] = 0 - - ip := net.IP(_ip) - subnet := &net.IPNet{_net, _mask} + by := hp.payload + addrStr := fmt.Sprintf("%d.%d.%d.%d/%d", by[0], by[1], by[2], by[3], by[4]) + ip, subnet, _ := net.ParseCIDR(addrStr) setTunIP(clt.iface, ip, subnet) if clt.cfg.FixMSS { fixMSS(clt.iface.Name(), false) @@ -344,7 +334,7 @@ func (clt *HopClient) handleHandshakeAck(u *net.UDPConn, hp *HopPacket) { } logger.Debug("Handshake Ack to Server") - clt.toServer(u, HOP_FLG_HSH | HOP_FLG_ACK, clt.sid[:], true) + clt.toServer(u, HOP_FLG_HSH|HOP_FLG_ACK, clt.sid[:], true) } // handle handshake fail @@ -352,7 +342,6 @@ func (clt *HopClient) handleHandshakeError(u *net.UDPConn, hp *HopPacket) { clt.handshakeDone <- 0 } - // handle data packet func (clt *HopClient) handleDataPacket(u *net.UDPConn, hp *HopPacket) { // logger.Debug("New HopPacket Seq: %d", packet.Seq) @@ -364,7 +353,6 @@ func (clt *HopClient) handleFinishAck(u *net.UDPConn, hp *HopPacket) { clt.finishAck <- byte(1) } - func (clt *HopClient) cleanUp() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) @@ -379,7 +367,6 @@ func (clt *HopClient) cleanUp() { clearMSS(clt.iface.Name(), false) } - timeout := time.After(3 * time.Second) if clt.state != HOP_STAT_INIT { clt.finishSession() diff --git a/hop/common.go b/hop/common.go index e42f1a0..1e61831 100644 --- a/hop/common.go +++ b/hop/common.go @@ -19,7 +19,7 @@ package hop import ( - "github.com/bigeagle/gohop/logging" + "../logging" ) var logger = logging.GetLogger() diff --git a/hop/config.go b/hop/config.go index fb31a05..eb5cddc 100644 --- a/hop/config.go +++ b/hop/config.go @@ -1,33 +1,44 @@ package hop import ( - "errors" + "bufio" "code.google.com/p/gcfg" + "errors" + "fmt" + "io" + "regexp" + "strconv" + "strings" ) + // Server Config type HopServerConfig struct { - HopStart int - HopEnd int - ListenAddr string - Addr string - MTU int - Key string - FixMSS bool + HopStart int + HopEnd int + ListenAddr string + Addr string + DNS []string + PeerTimeout int + MTU int + Key string + FixMSS bool MorphMethod string + RouteFile string + RouteList map[uint32][][5]byte } // Client Config type HopClientConfig struct { - Server string - HopStart int - HopEnd int - Key string - MTU int - FixMSS bool - Local bool - MorphMethod string + Server string + HopStart int + HopEnd int + Key string + MTU int + FixMSS bool + Local bool + MorphMethod string Redirect_gateway bool - Net_gateway []string + Net_gateway []string } type HopConfig struct { @@ -53,3 +64,38 @@ func ParseHopConfig(filename string) (interface{}, error) { return nil, errors.New("Wrong mode") } } + +func (cfg *HopServerConfig) RouteConfig(r io.Reader) { + + regCM := regexp.MustCompile(`#.*`) + regIP := regexp.MustCompile(`(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)`) + regGM := regexp.MustCompile(`\[\s*(\d+)\s*\]`) + key := uint32(0) + ip := [5]byte{} + cfg.RouteList = make(map[uint32][][5]byte) + + bf := bufio.NewReader(r) + for { + if line, err := bf.ReadString('\n'); err == nil { + if line = regCM.ReplaceAllString(line, ""); len(strings.TrimSpace(line)) < 3 { + continue + } + if ips := regIP.FindStringSubmatch(line); len(ips) == 6 { + for k, ipt := range ips[1:] { + v, _ := strconv.Atoi(ipt) + ip[k] = byte(v) + if k == 5 && uint8(ip[k]) > 32 { + ip[k] = 32 + } + } + cfg.RouteList[key] = append(cfg.RouteList[key], ip) + } else if gms := regGM.FindStringSubmatch(line); len(gms) == 2 { + v, _ := strconv.Atoi(gms[1]) + key = uint32(v) + } + } else { + break + } + } + logger.Debug(fmt.Sprintf("Route list : %v", cfg.RouteList)) +} diff --git a/hop/iface.go b/hop/iface.go index 36110d4..3f70a23 100644 --- a/hop/iface.go +++ b/hop/iface.go @@ -47,8 +47,7 @@ func newTun(name string) (iface *water.Interface, err error) { sargs := fmt.Sprintf("link set dev %s up mtu %d qlen 100", iface.Name(), MTU) args := strings.Split(sargs, " ") - cmd := exec.Command("ip", args...) - logger.Info("ip %s", sargs) + cmd := texec("ip", args...) err = cmd.Run() if err != nil { return nil, err @@ -60,7 +59,7 @@ func newTun(name string) (iface *water.Interface, err error) { func setTunIP(iface *water.Interface, ip net.IP, subnet *net.IPNet) (err error) { ip = ip.To4() logger.Debug("%v", ip) - if ip[3] % 2 == 0 { + if ip[3]%2 == 0 { return invalidAddr } @@ -71,8 +70,7 @@ func setTunIP(iface *water.Interface, ip net.IP, subnet *net.IPNet) (err error) sargs := fmt.Sprintf("addr add dev %s local %s peer %s", iface.Name(), ip, peer) args := strings.Split(sargs, " ") - cmd := exec.Command("ip", args...) - logger.Info("ip %s", sargs) + cmd := texec("ip", args...) err = cmd.Run() if err != nil { return err @@ -80,8 +78,7 @@ func setTunIP(iface *water.Interface, ip net.IP, subnet *net.IPNet) (err error) sargs = fmt.Sprintf("route add %s via %s dev %s", subnet, peer, iface.Name()) args = strings.Split(sargs, " ") - cmd = exec.Command("ip", args...) - logger.Info("ip %s", sargs) + cmd = texec("ip", args...) err = cmd.Run() return err } @@ -142,13 +139,11 @@ func getNetGateway() (gw, dev string, err error) { return "", "", errors.New("No default gateway found") } - // add route func addRoute(dest, nextHop, iface string) { scmd := fmt.Sprintf("ip -4 r a %s via %s dev %s", dest, nextHop, iface) - cmd := exec.Command("bash", "-c", scmd) - logger.Info(scmd) + cmd := texec("bash", "-c", scmd) err := cmd.Run() if err != nil { @@ -161,8 +156,7 @@ func addRoute(dest, nextHop, iface string) { func delRoute(dest string) { sargs := fmt.Sprintf("-4 route del %s", dest) args := strings.Split(sargs, " ") - cmd := exec.Command("ip", args...) - logger.Info("ip %s", sargs) + cmd := texec("ip", args...) err := cmd.Run() if err != nil { @@ -173,12 +167,11 @@ func delRoute(dest string) { // redirect default gateway func redirectGateway(iface, gw string) error { subnets := []string{"0.0.0.0/1", "128.0.0.0/1"} - logger.Info("Redirecting Gateway") + logger.Debug("Redirecting Gateway") for _, subnet := range subnets { sargs := fmt.Sprintf("-4 route add %s via %s dev %s", subnet, gw, iface) args := strings.Split(sargs, " ") - cmd := exec.Command("ip", args...) - logger.Info("ip %s", sargs) + cmd := texec("ip", args...) err := cmd.Run() if err != nil { @@ -188,20 +181,19 @@ func redirectGateway(iface, gw string) error { return nil } - // redirect ports to one func redirectPort(from, to string) error { //iptables -t nat -A PREROUTING -p udp -m udp --dport 40000:41000 -j REDIRECT --to-ports 1234 - logger.Info("Port Redirecting") + logger.Debug("Port Redirecting") sargs := fmt.Sprintf("-t nat -A PREROUTING -p udp -m udp --dport %s -j REDIRECT --to-ports %s", from, to) args := strings.Split(sargs, " ") - cmd := exec.Command("iptables", args...) + cmd := texec("iptables", args...) err := cmd.Run() if err != nil { return err } - cmd = exec.Command("ip6tables", args...) + cmd = texec("ip6tables", args...) err = cmd.Run() if err != nil { @@ -210,20 +202,19 @@ func redirectPort(from, to string) error { return nil } - // undo redirect ports func unredirectPort(from, to string) error { //iptables -t nat -D PREROUTING -p udp -m udp --dport 40000:41000 -j REDIRECT --to-ports 1234 - logger.Info("Clear Port Redirecting") + logger.Debug("Clear Port Redirecting") sargs := fmt.Sprintf("-t nat -D PREROUTING -p udp -m udp --dport %s -j REDIRECT --to-ports %s", from, to) args := strings.Split(sargs, " ") - cmd := exec.Command("iptables", args...) + cmd := texec("iptables", args...) err := cmd.Run() if err != nil { return err } - cmd = exec.Command("ip6tables", args...) + cmd = texec("ip6tables", args...) err = cmd.Run() if err != nil { @@ -234,7 +225,7 @@ func unredirectPort(from, to string) error { func fixMSS(iface string, is_server bool) error { mss := MTU - 40 - logger.Info("Fix MSS with iptables to %d", mss) + logger.Debug("Fix MSS with iptables to %d", mss) io := "o" if is_server { io = "i" @@ -242,7 +233,7 @@ func fixMSS(iface string, is_server bool) error { sargs := fmt.Sprintf("-I FORWARD -%s %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss %d", io, iface, mss) args := strings.Split(sargs, " ") - cmd := exec.Command("iptables", args...) + cmd := texec("iptables", args...) err := cmd.Run() if err != nil { @@ -253,7 +244,7 @@ func fixMSS(iface string, is_server bool) error { func clearMSS(iface string, is_server bool) error { mss := MTU - 40 - logger.Info("Clean MSS fix") + logger.Debug("Clean MSS fix") io := "o" if is_server { @@ -262,7 +253,7 @@ func clearMSS(iface string, is_server bool) error { sargs := fmt.Sprintf("-D FORWARD -%s %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss %d", io, iface, mss) args := strings.Split(sargs, " ") - cmd := exec.Command("iptables", args...) + cmd := texec("iptables", args...) err := cmd.Run() if err != nil { @@ -271,3 +262,12 @@ func clearMSS(iface string, is_server bool) error { return nil } + +func texec(name string, arg ...string) *exec.Cmd { + out := "EXEC:" + name + for _, s := range arg { + out += " " + s + } + logger.Debug(out) + return exec.Command(name, arg...) +} diff --git a/hop/ippool.go b/hop/ippool.go index 971a892..fd2651b 100644 --- a/hop/ippool.go +++ b/hop/ippool.go @@ -1,50 +1,49 @@ package hop import ( - "net" + "encoding/binary" "errors" + "net" "sync/atomic" ) type hopIPPool struct { subnet *net.IPNet - pool [127]int32 + pool []int32 } var poolFull = errors.New("IP Pool Full") func (p *hopIPPool) next() (*net.IPNet, error) { - found := false - var i int - for i = 3; i < 255; i +=2 { - if atomic.CompareAndSwapInt32(&p.pool[i], 0, 1) { - found = true - break - } + if len(p.pool) == 0 { + maskint := binary.BigEndian.Uint32(p.subnet.Mask) + maskint = ^maskint & 0xffff //最长支持 65535 IP + p.pool = make([]int32, maskint) } - if !found { - return nil, poolFull - } - - - ipnet := &net.IPNet{ - make([]byte, 4), - make([]byte, 4), + for i := 3; i < len(p.pool); i++ { + lB := i & 0xff + if lB > 2 && lB < 255 && atomic.CompareAndSwapInt32(&p.pool[i], 0, 1) { + ipint := binary.BigEndian.Uint32(p.subnet.IP.To4()) + uint32(i) + ipnet := &net.IPNet{ + make([]byte, 4), + make([]byte, 4), + } + binary.BigEndian.PutUint32(ipnet.IP, ipint) + copy([]byte(ipnet.Mask), []byte(p.subnet.Mask)) + return ipnet, nil + } } - copy([]byte(ipnet.IP), []byte(p.subnet.IP)) - copy([]byte(ipnet.Mask), []byte(p.subnet.Mask)) - ipnet.IP[3] = byte(i) - return ipnet, nil + return nil, poolFull } func (p *hopIPPool) relase(ip net.IP) { - defer func(){ + defer func() { if err := recover(); err != nil { logger.Error("%v", err) } }() - logger.Debug("releasing ip: %v", ip) - i := ip[3] + + i := binary.BigEndian.Uint32(ip.To4()) & uint32(len(p.pool)) p.pool[i] = 0 } diff --git a/hop/protocol.go b/hop/protocol.go index 93e4d77..a034c69 100644 --- a/hop/protocol.go +++ b/hop/protocol.go @@ -21,15 +21,16 @@ package hop import ( - "net" "bytes" - "encoding/binary" "crypto/rand" - "sync" - "sync/atomic" + "encoding/binary" "errors" "fmt" + "net" "strings" + "sync" + "sync/atomic" + "time" ) const ( @@ -37,49 +38,51 @@ const ( HOP_ACK uint8 = 0xAC HOP_DAT uint8 = 0xDA - HOP_FLG_PSH byte = 0x80 // port knocking and heartbeat - HOP_FLG_HSH byte = 0x40 // handshaking - HOP_FLG_FIN byte = 0x20 // finish session - HOP_FLG_MFR byte = 0x08 // more fragments - HOP_FLG_ACK byte = 0x04 // acknowledge - HOP_FLG_DAT byte = 0x00 // acknowledge + HOP_FLG_PSH byte = 0x80 // port knocking and heartbeat + HOP_FLG_HSH byte = 0x40 // handshaking + HOP_FLG_FIN byte = 0x20 // finish session + HOP_FLG_MFR byte = 0x08 // more fragments + HOP_FLG_ACK byte = 0x04 // acknowledge + HOP_FLG_DAT byte = 0x00 // acknowledge - HOP_STAT_INIT int32 = iota // initing - HOP_STAT_HANDSHAKE // handeshaking - HOP_STAT_WORKING // working - HOP_STAT_FIN // finishing + HOP_STAT_INIT int32 = iota // initing + HOP_STAT_HANDSHAKE // handeshaking + HOP_STAT_WORKING // working + HOP_STAT_FIN // finishing HOP_HDR_LEN int = 16 + + DAT_CIPHER bool = true ) type hopPacketHeader struct { - Flag byte - Seq uint32 - Plen uint16 + Flag byte + Seq uint32 + Plen uint16 FragPrefix uint16 - Frag uint8 - Sid uint32 - Dlen uint16 + Frag uint8 + Sid uint32 + Dlen uint16 } func (p hopPacketHeader) String() string { flag := make([]string, 0, 8) - if (p.Flag ^ HOP_FLG_MFR == 0) || (p.Flag == 0) { + if (p.Flag^HOP_FLG_MFR == 0) || (p.Flag == 0) { flag = append(flag, "DAT") } - if p.Flag & HOP_FLG_PSH != 0 { + if p.Flag&HOP_FLG_PSH != 0 { flag = append(flag, "PSH") } - if p.Flag & HOP_FLG_HSH != 0 { + if p.Flag&HOP_FLG_HSH != 0 { flag = append(flag, "HSH") } - if p.Flag & HOP_FLG_FIN != 0 { + if p.Flag&HOP_FLG_FIN != 0 { flag = append(flag, "FIN") } - if p.Flag & HOP_FLG_ACK != 0 { + if p.Flag&HOP_FLG_ACK != 0 { flag = append(flag, "ACK") } - if p.Flag & HOP_FLG_MFR != 0 { + if p.Flag&HOP_FLG_MFR != 0 { flag = append(flag, "MFR") } @@ -92,12 +95,12 @@ func (p hopPacketHeader) String() string { type HopPacket struct { hopPacketHeader - payload []byte - noise []byte - buf []byte + payload []byte + noise []byte + buf []byte } -var cipher *hopCipher +var cipher *hopCipher = nil func (p *HopPacket) Pack() []byte { p.Dlen = uint16(len(p.payload)) @@ -105,7 +108,9 @@ func (p *HopPacket) Pack() []byte { if p.buf != nil { // reduce memcopy buf = bytes.NewBuffer(p.buf[:0]) + // write packet header to p.buf header binary.Write(buf, binary.BigEndian, p.hopPacketHeader) + } else { buf = bytes.NewBuffer(make([]byte, 0, p.Size())) binary.Write(buf, binary.BigEndian, p.hopPacketHeader) @@ -113,11 +118,16 @@ func (p *HopPacket) Pack() []byte { buf.Write(p.noise) p.buf = buf.Bytes() } - return cipher.encrypt(p.buf) + + if cipher == nil { + return p.buf //暂时不用加密 + } + return cipher.encrypt(p.buf) // 数据加密 + } func (p *HopPacket) Size() int { - return HOP_HDR_LEN+len(p.payload)+len(p.noise) + return HOP_HDR_LEN + len(p.payload) + len(p.noise) } func (p *HopPacket) setPayload(d []byte) { @@ -127,7 +137,7 @@ func (p *HopPacket) setPayload(d []byte) { func (p *HopPacket) addNoise(n int) { if p.buf != nil { - s := HOP_HDR_LEN+len(p.payload) + s := HOP_HDR_LEN + len(p.payload) p.noise = p.buf[s:len(p.buf)] } else { p.noise = make([]byte, n) @@ -147,6 +157,23 @@ func (p *HopPacket) String() string { } func unpackHopPacket(b []byte) (*HopPacket, error) { + + //不加密数据 + if cipher == nil { + logger.Debug("no ciph!") + buf := bytes.NewBuffer(b) + p := new(HopPacket) + err := binary.Read(buf, binary.BigEndian, &p.hopPacketHeader) + if err == nil { + p.payload = make([]byte, p.Dlen) + if _, err = buf.Read(p.payload); err == nil { + return p, nil + } + } + return nil, err + } + + // 加密数据 iv := b[:cipherBlockSize] ctext := b[cipherBlockSize:] if frame := cipher.decrypt(iv, ctext); frame != nil { @@ -163,8 +190,7 @@ func unpackHopPacket(b []byte) (*HopPacket, error) { } - -func udpAddrHash(a *net.UDPAddr) [6]byte{ +func udpAddrHash(a *net.UDPAddr) [6]byte { var b [6]byte copy(b[:4], []byte(a.IP)[:4]) p := uint16(a.Port) @@ -174,7 +200,7 @@ func udpAddrHash(a *net.UDPAddr) [6]byte{ } type hUDPAddr struct { - u *net.UDPAddr + u *net.UDPAddr hash [6]byte } @@ -184,21 +210,28 @@ func newhUDPAddr(a *net.UDPAddr) *hUDPAddr { // gohop Peer is a record of a peer's available UDP addrs type HopPeer struct { - id uint64 - ip net.IP - addrs map[[6]byte]int - _addrs_lst []*hUDPAddr // i know it's ugly! - seq uint32 - state int32 - hsDone chan byte - recvBuffer *hopPacketBuffer - srv *HopServer - _lock sync.RWMutex + id uint64 + gmid uint32 //game id + uid uint32 //user id + lastConnTime time.Time + bytes_up uint32 //user update bytes + bytes_down uint32 //user download bytes + ip net.IP + addrs map[[6]byte]int + _addrs_lst []*hUDPAddr // i know it's ugly! + seq uint32 + state int32 + hsDone chan byte + recvBuffer *hopPacketBuffer + srv *HopServer + _lock sync.RWMutex } func newHopPeer(id uint64, srv *HopServer, addr *net.UDPAddr, idx int) *HopPeer { hp := new(HopPeer) hp.id = id + hp.bytes_up = 0 + hp.bytes_down = 0 hp._addrs_lst = make([]*hUDPAddr, 0) hp.addrs = make(map[[6]byte]int) hp.state = HOP_STAT_INIT @@ -207,7 +240,6 @@ func newHopPeer(id uint64, srv *HopServer, addr *net.UDPAddr, idx int) *HopPeer hp.recvBuffer = newHopPacketBuffer(srv.toIface, bufferTimeout/2) // logger.Debug("%v, %v", hp.recvBuffer, hp.srv) - a := newhUDPAddr(addr) hp._addrs_lst = append(hp._addrs_lst, a) hp.addrs[a.hash] = idx diff --git a/hop/server.go b/hop/server.go index ea0c0fa..ba47674 100644 --- a/hop/server.go +++ b/hop/server.go @@ -19,18 +19,18 @@ package hop import ( - "github.com/bigeagle/water" - "github.com/bigeagle/water/waterutil" - "encoding/binary" "bytes" + "encoding/binary" "fmt" + "github.com/bigeagle/water" + "github.com/bigeagle/water/waterutil" "net" "os" "os/signal" + "sync" + "sync/atomic" "syscall" "time" - "sync/atomic" - "sync" ) // a udpPacket @@ -45,7 +45,7 @@ type udpPacket struct { type HopServer struct { // config - cfg HopServerConfig + cfg *HopServerConfig // interface iface *water.Interface // subnet @@ -60,27 +60,27 @@ type HopServer struct { // channel to put packets to send through udpsocket toNet []chan *udpPacket // channel to put frames read from tun/tap device - fromIface chan []byte - toIface chan *HopPacket - _lock sync.RWMutex + fromIface chan []byte + toIface chan *HopPacket + _lock sync.RWMutex _chanBufSize int } - -func NewServer(cfg HopServerConfig) error { +func NewServer(cfg *HopServerConfig) error { var err error logger.Debug("%v", cfg) - cipher, err = newHopCipher([]byte(cfg.Key)) - if err != nil { - return err + if len(cfg.Key) > 0 { + cipher, err = newHopCipher([]byte(cfg.Key)) + if err != nil { + return err + } } if cfg.MTU != 0 { MTU = cfg.MTU } - hopServer := new(HopServer) hopServer._chanBufSize = 256 hopServer.fromNet = make(chan *udpPacket, hopServer._chanBufSize) @@ -88,7 +88,7 @@ func NewServer(cfg HopServerConfig) error { hopServer.toIface = make(chan *HopPacket, hopServer._chanBufSize) hopServer.peers = make(map[uint64]*HopPeer) hopServer.cfg = cfg - hopServer.toNet = make([]chan *udpPacket, (cfg.HopEnd-cfg.HopStart+1)) + hopServer.toNet = make([]chan *udpPacket, (cfg.HopEnd - cfg.HopStart + 1)) hopServer.ippool = new(hopIPPool) iface, err := newTun("") @@ -118,7 +118,6 @@ func NewServer(cfg HopServerConfig) error { logger.Info("No Traffic Morphing") } - // forward device frames to socket and socket packets to device go hopServer.forwardFrames() @@ -134,8 +133,10 @@ func NewServer(cfg HopServerConfig) error { idx++ } - logger.Debug("Recieving iface frames") + // peer Timeout Watcher + go hopServer.peerTimeoutWatcher() + logger.Info("Recieving iface frames") // handle interface @@ -143,6 +144,7 @@ func NewServer(cfg HopServerConfig) error { for { hp := <-hopServer.toIface // logger.Debug("New Net packet to device") + // logger.Debug("toIface : %v", hp.payload) _, err := iface.Write(hp.payload) // logger.Debug("n: %d, len: %d", n, len(hp.payload)) if err != nil { @@ -192,27 +194,37 @@ func (srv *HopServer) listenAndServe(addr string, port string, idx int) { for { packet := <-toNet // logger.Debug("index: %d, port: %s", idx, port) - // logger.Debug("client addr: %v", packet.addr) - udpConn.WriteTo(packet.data, packet.addr) + // logger.Debug("toClient: %v", packet.data) + _, err := udpConn.WriteTo(packet.data, packet.addr) + if err != nil { + logger.Error("ToNet Err: %v", err) + } } }() for { - var plen int - packet := new(udpPacket) - packet.channel = idx - buf := make([]byte, IFACE_BUFSIZE) - // logger.Debug("Recieving packet %s", port) - plen, packet.addr, err = udpConn.ReadFromUDP(buf) - // logger.Debug("New UDP Packet from: %v", packet.addr) - - packet.data = buf[:plen] - if err != nil { - logger.Error(err.Error()) - return - } + func() { + defer func() { + if _err := recover(); _err != nil { + logger.Error("ReadFromUDP failed: %v", _err) + } + }() + var plen int + packet := new(udpPacket) + packet.channel = idx + buf := make([]byte, IFACE_BUFSIZE) + // logger.Debug("Recieving packet %s", port) + plen, packet.addr, err = udpConn.ReadFromUDP(buf) + // logger.Debug("New UDP Packet from: %v", packet.addr) + + packet.data = buf[:plen] + if err != nil { + logger.Error(err.Error()) + return + } - srv.fromNet <- packet + srv.fromNet <- packet + }() } } @@ -221,12 +233,12 @@ func (srv *HopServer) forwardFrames() { // packet map pktHandle := map[byte](func(*udpPacket, *HopPacket)){ - HOP_FLG_PSH: srv.handleKnock, - HOP_FLG_HSH: srv.handleHandshake, - HOP_FLG_HSH|HOP_FLG_ACK: srv.handleHandshakeAck, - HOP_FLG_DAT: srv.handleDataPacket, - HOP_FLG_DAT|HOP_FLG_MFR: srv.handleDataPacket, - HOP_FLG_FIN: srv.handleFinish, + HOP_FLG_PSH: srv.handleKnock, + HOP_FLG_HSH: srv.handleHandshake, + HOP_FLG_HSH | HOP_FLG_ACK: srv.handleHandshakeAck, + HOP_FLG_DAT: srv.handleDataPacket, + HOP_FLG_DAT | HOP_FLG_MFR: srv.handleDataPacket, + HOP_FLG_FIN: srv.handleFinish, } for { @@ -238,29 +250,43 @@ func (srv *HopServer) forwardFrames() { dest := waterutil.IPv4Destination(frame).To4() mkey := ip4_uint64(dest) - // logger.Debug("ip dest: %v", dest) + // logger.Debug("fromIfc: ip dest: %v, data:%v", dest, frame) if hpeer, found := srv.peers[mkey]; found { srv.bufferToClient(hpeer, pack) } else { - logger.Warning("client peer with key %d not found", mkey) + // logger.Debug("fromIface : client peer with key %d not found", mkey) } case packet := <-srv.fromNet: + packet.handleFunction(pktHandle) + } + } +} - hPack, err := unpackHopPacket(packet.data) - if err == nil { - // logger.Debug("New UDP Packet from: %v", packet.addr) +func (packet *udpPacket) handleFunction(pktHandle map[byte](func(*udpPacket, *HopPacket))) { - if handle_func, ok := pktHandle[hPack.Flag]; ok { - handle_func(packet, hPack) - } else { - logger.Error("Unkown flag: %x", hPack.Flag) - } - } else { - logger.Error(err.Error()) - } + defer func() { + if err := recover(); err != nil { + logger.Error("handleFunction failed: %v, packet addr:%v", err, packet.addr) + } + }() + + // logger.Debug("Receive data[%d]:%v", len(packet.data), packet.data) + + hPack, err := unpackHopPacket(packet.data) //协议包拆包 + if err == nil { + // logger.Debug("fromClient: %v", hPack.String()) + if hPack.Flag != 0 { + logger.Debug("New UDP Packet [%v] from: %v", hPack.Flag, packet.addr) } + if handle_func, ok := pktHandle[hPack.Flag]; ok { + handle_func(packet, hPack) //事件处理 + } else { + logger.Error("Unkown flag: %x", hPack.Flag) + } + } else { + logger.Error(err.Error()) } } @@ -271,11 +297,12 @@ func (srv *HopServer) toClient(peer *HopPeer, flag byte, payload []byte, noise b hp.payload = payload if addr, idx, ok := peer.addr(); ok { - logger.Debug("peer: %v", addr) + // logger.Debug("toClient : peer: %v", addr) upacket := &udpPacket{addr, hp.Pack(), idx} + peer.bytes_down += uint32(len(upacket.data)) srv.toNet[idx] <- upacket } else { - logger.Debug("peer not found") + logger.Debug("toClient : peer not found sid:%d, uid:%d, ip:%d", peer.id>>32, peer.uid, peer.ip) } } @@ -289,16 +316,19 @@ func (srv *HopServer) bufferToClient(peer *HopPeer, buf []byte) { hp.Seq = peer.Seq() if addr, idx, ok := peer.addr(); ok { + // logger.Debug("bufferToClient : peer: %v", addr) upacket := &udpPacket{addr, hp.Pack(), idx} + peer.bytes_down += uint32(len(upacket.data)) srv.toNet[idx] <- upacket } } else { // with traffic morphing frame := buf[HOP_HDR_LEN:] packets := hopFrager.Fragmentate(peer, frame) - for _, hp := range(packets) { + for _, hp := range packets { if addr, idx, ok := peer.addr(); ok { upacket := &udpPacket{addr, hp.Pack(), idx} + peer.bytes_down += uint32(len(upacket.data)) srv.toNet[idx] <- upacket } } @@ -307,64 +337,102 @@ func (srv *HopServer) bufferToClient(peer *HopPeer, buf []byte) { func (srv *HopServer) handleKnock(u *udpPacket, hp *HopPacket) { sid := uint64(binary.BigEndian.Uint32(hp.payload[:4])) - logger.Debug("port knock from client %v, sid: %d", u.addr, sid) sid = (sid << 32) & uint64(0xFFFFFFFF00000000) - hpeer, ok := srv.peers[sid] - if ! ok { + if !ok { hpeer = newHopPeer(sid, srv, u.addr, u.channel) srv.peers[sid] = hpeer } else { hpeer.insertAddr(u.addr, u.channel) + logger.Debug("[knock] from client %v, sid:%d, uid:%d, gid:%d", u.addr, sid>>32, hpeer.uid, hpeer.gmid) + if hpeer.state == HOP_STAT_WORKING { + srv.toClient(hpeer, HOP_FLG_PSH, []byte{0}, true) + } } - + hpeer.bytes_up += uint32(len(u.data)) + hpeer.lastConnTime = time.Now() } func (srv *HopServer) handleHandshake(u *udpPacket, hp *HopPacket) { - sid := uint64(binary.BigEndian.Uint32(hp.payload[:4])) + tms := []uint32{0, 0, 0} + for i := 0; i*4+4 <= int(hp.Dlen); i++ { + tms[i] = binary.BigEndian.Uint32(hp.payload[i*4 : i*4+4]) + } + sid := uint64(tms[0]) + gmid := tms[1] + uid := tms[2] + + logger.Debug("[handshake] from client %v, sid:%d, uid:%d, gmid:%d", u.addr, sid, uid, gmid) sid = (sid << 32) & uint64(0xFFFFFFFF00000000) - logger.Debug("handshake from client %v, sid: %d", u.addr, sid) hpeer, ok := srv.peers[sid] - if ! ok { + if !ok { hpeer = newHopPeer(sid, srv, u.addr, u.channel) srv.peers[sid] = hpeer } else { hpeer.insertAddr(u.addr, u.channel) } + hpeer.gmid = gmid + hpeer.uid = uid + hpeer.bytes_up += uint32(len(u.data)) + hpeer.lastConnTime = time.Now() + cltIP, err := srv.ippool.next() if err != nil { msg := fmt.Sprintf("%s", err.Error()) - srv.toClient(hpeer, HOP_FLG_HSH | HOP_FLG_FIN, []byte(msg), true) + srv.toClient(hpeer, HOP_FLG_HSH|HOP_FLG_FIN, []byte(msg), true) delete(srv.peers, sid) + logger.Error("Have no IP to allocation") } else { hpeer.ip = cltIP.IP.To4() - buf := bytes.NewBuffer(make([]byte, 0, 8)) + buf := bytes.NewBuffer(make([]byte, 0, 5)) + //set client ip buf.Write([]byte(hpeer.ip)) - buf.Write([]byte(cltIP.Mask)) + siz, _ := cltIP.Mask.Size() + // buf.Write([]byte(cltIP.Mask)) + buf.WriteByte(byte(siz)) + + //set client dns + for i := 0; i < 2; i++ { + if ip, _, err := net.ParseCIDR(srv.cfg.DNS[i]); err != nil { + buf.Write([]byte{0, 0, 0, 0, 0}) + } else { + ip = ip.To4() + buf.Write([]byte(ip)) + buf.WriteByte(0) + } + } + + //set client route + routes := srv.routeList(gmid) + for i := 0; i < len(routes) && i <= 256; i++ { + buf.Write(routes[i][:]) + } + key := ip4_uint64(hpeer.ip) - logger.Debug("assign address %s, route key %d", cltIP, key) + logger.Debug("assign address %s route; sid:%d, uid:%d, gid:%d", cltIP, hpeer.id>>32, hpeer.uid, hpeer.gmid) srv.peers[key] = hpeer atomic.StoreInt32(&hpeer.state, HOP_STAT_HANDSHAKE) - srv.toClient(hpeer, HOP_FLG_HSH | HOP_FLG_ACK, buf.Bytes(), true) + srv.toClient(hpeer, HOP_FLG_HSH|HOP_FLG_ACK, buf.Bytes(), true) hpeer.hsDone = make(chan byte) - go func(){ + go func() { for i := 0; i < 5; i++ { select { - case <- hpeer.hsDone: - hpeer.state = HOP_STAT_WORKING + case <-hpeer.hsDone: + logger.Debug("hperr.hsDone; sid:%d, uid:%d, gid:%d", hpeer.id>>32, hpeer.uid, hpeer.gmid) + // hpeer.state = HOP_STAT_WORKING return - case <- time.After(2 * time.Second): - logger.Debug("Client Handshake Timeout") - srv.toClient(hpeer, HOP_FLG_HSH | HOP_FLG_ACK, buf.Bytes(), true) + case <-time.After(2 * time.Second): + logger.Debug("Client Handshake Timeout; sid:%d, uid:%d, gid:%d", hpeer.id>>32, hpeer.uid, hpeer.gmid) + srv.toClient(hpeer, HOP_FLG_HSH|HOP_FLG_ACK, buf.Bytes(), true) } } // timeout, kick - srv.toClient(hpeer, HOP_FLG_HSH | HOP_FLG_FIN, []byte{}, true) - srv.toClient(hpeer, HOP_FLG_HSH | HOP_FLG_FIN, []byte{}, true) - srv.toClient(hpeer, HOP_FLG_HSH | HOP_FLG_FIN, []byte{}, true) + srv.toClient(hpeer, HOP_FLG_HSH|HOP_FLG_FIN, []byte{0}, true) + srv.toClient(hpeer, HOP_FLG_HSH|HOP_FLG_FIN, []byte{0}, true) + srv.toClient(hpeer, HOP_FLG_HSH|HOP_FLG_FIN, []byte{0}, true) srv.ippool.relase(hpeer.ip) delete(srv.peers, sid) @@ -379,41 +447,62 @@ func (srv *HopServer) handleHandshakeAck(u *udpPacket, hp *HopPacket) { sid := uint64(binary.BigEndian.Uint32(hp.payload[:4])) sid = (sid << 32) & uint64(0xFFFFFFFF00000000) hpeer, ok := srv.peers[sid] - if ! ok { + if !ok { return } - logger.Debug("Client Handshake Done") - logger.Info("Client %d Connected", sid) - atomic.StoreInt32(&hpeer.state, HOP_STAT_WORKING) - hpeer.hsDone <- 1 + hpeer.bytes_up += uint32(len(u.data)) + hpeer.lastConnTime = time.Now() + logger.Info("Client sid:%d, uid:%d, gid:%d, ip %v Connected. DHCP:%v", sid>>32, hpeer.uid, hpeer.gmid, u.addr, hpeer.ip) + + if ok = atomic.CompareAndSwapInt32(&hpeer.state, HOP_STAT_HANDSHAKE, HOP_STAT_WORKING); ok { + hpeer.hsDone <- 1 + } } func (srv *HopServer) handleDataPacket(u *udpPacket, hp *HopPacket) { sid := uint64(hp.Sid) sid = (sid << 32) & uint64(0xFFFFFFFF00000000) - if peer, ok := srv.peers[sid]; ok { - // logger.Debug("n peer addrs: %v", len(peer._addrs_lst)) - // peer.insertAddr(u.addr, u.channel) - peer.recvBuffer.Push(hp) + if hpeer, ok := srv.peers[sid]; ok && hpeer.state == HOP_STAT_WORKING { + // logger.Debug("n hpeer addrs: %v", len(hpeer._addrs_lst)) + // hpeer.insertAddr(u.addr, u.channel) + if ok, ip := srv.routeMatch(hpeer, hp); ok { + hpeer.lastConnTime = time.Now() + hpeer.recvBuffer.Push(hp) + } else { + logger.Info("DataPacket not routed to %v", ip) + } + hpeer.bytes_up += uint32(len(u.data)) + } else { + peer := newHopPeer(sid, srv, u.addr, u.channel) + srv.toClient(peer, HOP_FLG_FIN|HOP_FLG_ACK, []byte{0}, false) } + } func (srv *HopServer) handleFinish(u *udpPacket, hp *HopPacket) { sid := uint64(binary.BigEndian.Uint32(hp.payload[:4])) + logger.Info("releasing client %v, sid:%d", u.addr, sid) sid = (sid << 32) & uint64(0xFFFFFFFF00000000) - logger.Info("releasing client %v, sid: %d", u.addr, sid) + srv.deletePeer(sid) +} + +func (srv *HopServer) deletePeer(sid uint64) { hpeer, ok := srv.peers[sid] - if ! ok { + if !ok { return } - + srv.toClient(hpeer, HOP_FLG_FIN|HOP_FLG_ACK, []byte{0}, false) key := ip4_uint64(hpeer.ip) srv.ippool.relase(hpeer.ip) + + // log user info + if sid>>32 > 0 { + logger.Info("UserBytes sid:%d, uid:%d, gid:%d, up:%d, down:%d", hpeer.id>>32, hpeer.uid, hpeer.gmid, hpeer.bytes_up, hpeer.bytes_down) + } delete(srv.peers, sid) delete(srv.peers, key) - srv.toClient(hpeer, HOP_FLG_FIN | HOP_FLG_ACK, []byte{}, false) } func (srv *HopServer) cleanUp() { @@ -424,3 +513,54 @@ func (srv *HopServer) cleanUp() { clearMSS(srv.iface.Name(), true) os.Exit(0) } + +func (srv *HopServer) routeList(gmid uint32) [][5]byte { + var routes [][5]byte = make([][5]byte, 0, 5) + for _, k := range []uint32{1, gmid} { + if list, ok := srv.cfg.RouteList[k]; ok { + routes = append(routes, list...) + } + } + if len(routes) == 0 { + routes = [][5]byte{[5]byte{254, 254, 254, 254, 32}} + } + return routes +} + +func (srv *HopServer) routeMatch(peer *HopPeer, hp *HopPacket) (bool, net.IP) { + ip := waterutil.IPv4Destination(hp.payload).To4() + list := srv.routeList(peer.gmid) + intip := binary.BigEndian.Uint32([]byte(ip)) + for _, l := range list { + routeIp := binary.BigEndian.Uint32(l[:4]) + mask := 32 - l[4] + if intip >= routeIp && (intip>>mask) == (routeIp>>mask) { + return true, ip + } + } + + return false, ip +} + +func (srv *HopServer) peerTimeoutWatcher() { + for { + if srv.cfg.PeerTimeout <= 0 { + return + } + time.Sleep(time.Minute) + count := 0 + timeout := time.Second * time.Duration(srv.cfg.PeerTimeout) + for sid, hpeer := range srv.peers { + // logger.Debug("watch:%v", hpeer.lastConnTime) + if sid>>32 > 0 { + count++ + } + conntime := time.Since(hpeer.lastConnTime) + // logger.Debug("watch:%v %v", conntime.Seconds(), timeout.Seconds()) + if conntime > timeout { + go srv.deletePeer(sid) + } + } + logger.Info("Ulinks:%d", count) + } +} diff --git a/main.go b/main.go index dedfbbe..2040fe0 100644 --- a/main.go +++ b/main.go @@ -19,11 +19,15 @@ package main import ( + "./hop" + "./logging" "flag" "fmt" - "github.com/bigeagle/gohop/hop" - "github.com/bigeagle/gohop/logging" + "io" "os" + "runtime" + "time" + "path/filepath" ) var srvMode, cltMode, debug, getVersion bool @@ -31,10 +35,13 @@ var cfgFile string var VERSION = "0.3.2-dev" -func main() { +func init() { flag.BoolVar(&getVersion, "version", false, "Get Version info") flag.BoolVar(&debug, "debug", false, "Provide debug info") flag.StringVar(&cfgFile, "config", "", "configfile") +} + +func main() { flag.Parse() if getVersion { @@ -60,17 +67,52 @@ func main() { logger.Info("using config file: %v", cfgFile) icfg, err := hop.ParseHopConfig(cfgFile) - logger.Debug("%v", icfg) + //logger.Debug("%v", icfg) checkerr(err) + // 设置可使用的最大核心数 + runtime.GOMAXPROCS(runtime.NumCPU() - 1) + fmt.Printf("/** server start **/\nUse %d/%d CPU cores\n", runtime.GOMAXPROCS(-1), runtime.NumCPU()) + switch cfg := icfg.(type) { case hop.HopServerConfig: - err := hop.NewServer(cfg) + addWatchFile(cfg.RouteFile, cfg.RouteConfig, time.Second*60) + err := hop.NewServer(&cfg) checkerr(err) case hop.HopClientConfig: - err := hop.NewClient(cfg) + err := hop.NewClient(&cfg) checkerr(err) default: logger.Error("Invalid config file") } } + +/* +配置文件监控方法 +不能放到其他包中。避免非启动时调用。 +*/ +func addWatchFile(filename string, callback func(r io.Reader), st time.Duration) { + logger := logging.GetLogger() + modtime := int64(0) + filename, _ = filepath.Abs(filename) + logger.Info("addWatchFile : " + filename) + setF := func() { + if f, err := os.Open(filename); err != nil { + logger.Error("config file " + filename + " error : " + err.Error()) + } else if fi, err := f.Stat(); err != nil { + logger.Error("config file " + filename + " error : " + err.Error()) + } else if mt := fi.ModTime().Unix(); mt != modtime { + logger.Debug("load config file : " + filename + " begin !") + modtime = mt + callback(f) + logger.Debug("load config file : " + filename + " finish !") + } + } + setF() + go func() { + for { + time.Sleep(st) + setF() + } + }() +} diff --git a/route.ini b/route.ini new file mode 100644 index 0000000..6ecf838 --- /dev/null +++ b/route.ini @@ -0,0 +1,31 @@ +# [游戏ID] : 游戏ID为 1 时,使用所有客户端通用规则 请慎用 +# 路由条目 : 如 202.58.246.0/24 +# 文件修改后1分钟生效 + + +[1] #通用规则 +# 220.254.254.254/32 + + + +[1000] #游戏ID为1000时,使用的路由规则 +12.0.0.0/6 +16.0.0.0/4 +32.0.0.0/3 +64.0.0.0/3 +96.0.0.0/4 +112.0.0.0/5 +120.0.0.0/6 +124.0.0.0/7 +132.0.0.0/6 +152.0.0.0/5 +160.0.0.0/5 +168.0.0.0/7 +175.0.0.0/8 +176.0.0.0/4 +202.0.0.0/7 +208.0.0.0/4 + + + + diff --git a/server.ini b/server.ini index bf0cc3f..0ac2404 100644 --- a/server.ini +++ b/server.ini @@ -4,14 +4,23 @@ mode = server [server] # port range to listen -hopstart = 40100 -hopend = 40200 +hopstart = 4000 +hopend = 4000 # server addr -addr = 10.1.1.1/24 +addr = 10.251.0.1/16 +dns = 0.0.0.0/0 +dns = 0.0.0.0/0 +# route file path +routefile = ./route.ini +# peer timeout (second) +peertimeout = 300 # master key mtu = 1400 -key = ilovethebigbrother +key = com_zhf5_tvpn # method of traffic morphing: none or randsize morphmethod = none # Fix MSS for tcp handshake fixmss = true + + + diff --git a/vpn.sh b/vpn.sh new file mode 100755 index 0000000..d0db180 --- /dev/null +++ b/vpn.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +CMD="./tvpn" +PID="./log/PID.txt" +LOG="./log/tvpn.log" +DEBUG="false" + +# --------------------------------------------------- + +function start { + $CMD -debug=$DEBUG server.ini >> $LOG 2>&1 & + tvpnpid=$! + echo $tvpnpid > $PID + echo "start [ok]" +} + +function stop { + kill `cat $PID` + rm $PID + echo "stop [ok]" +} + +# -------------------------------------------------- + + +echo "$CMD $1" + +case "$1" in +start) + sysctl net.ipv4.ip_forward=1 + iptables -t nat -A POSTROUTING -j MASQUERADE + start +;; +start_debug) + sysctl net.ipv4.ip_forward=1 + iptables -t nat -A POSTROUTING -j MASQUERADE + DEBUG="true" + start +;; +restart) + if [ -f $PID ] ; then + stop + sleep 4 + fi + start +;; +stop) + stop + exit 0 +;; +esac + + +for (( c=0 ; ; c++ )) +do + if [ -f $PID ] ; then + tvpnpid=`cat $PID` + cmdex="ps uh -p$tvpnpid" + psrtn=`$cmdex` + if [ -z "$psrtn" ]; then + echo "`date '+%Y/%m/%d %H:%M:%S'` FATALERROR RESTART SERVICE" >> $LOG + start + elif (( $c%20 == 0 )); then + echo "`date '+%Y/%m/%d %H:%M:%S'` PSINFO $psrtn" >> $LOG + c=0 + fi + sleep 3 + else + break + fi +done +