Skip to content

Commit

Permalink
New openwrt/lede platform
Browse files Browse the repository at this point in the history
优化目录结构
优化openwrt/lede下内存的消耗
优化命令行的使用体验
  • Loading branch information
AlbertZhan committed Aug 2, 2019
1 parent c32cda5 commit dc8e35e
Show file tree
Hide file tree
Showing 17 changed files with 949 additions and 608 deletions.
7 changes: 7 additions & 0 deletions client/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

type command interface {
addFlags()
printHelp(string)
run(args []string)
}
184 changes: 184 additions & 0 deletions client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package main

import (
"flag"
"fmt"
"net"
"os"
"runtime"
"strings"
"time"
)

var commands map[string]command
var provider command

//与浏览器相关的连接
type browser struct {
conn net.Conn
er chan bool
writ chan bool
recv chan []byte
send chan []byte
}

//读取浏览器发送过来的数据
func (self browser) read() {
for {
var recv=make([]byte,10240)
n, err := self.conn.Read(recv)
if err != nil {
self.writ <- true
self.er <- true
break
}
self.recv <- recv[:n]
}
}

//把数据发送给浏览器
func (self browser) write() {
for {
var send=make([]byte, 10240)
select {
case send = <-self.send:
_, _ = self.conn.Write(send)
case <-self.writ:
break
}
}
}

//与服务端相关的连接
type server struct {
conn net.Conn
er chan bool
writ chan bool
recv chan []byte
send chan []byte
}

//读取服务端发送过来的数据
func (self *server) read() {
//isheart与timeout共同判断是不是自己设定的SetReadDeadline
var isheart=false
//20秒发一次心跳包
_ = self.conn.SetReadDeadline(time.Now().Add(20*time.Second))
for {
var recv=make([]byte,10240)
n, err := self.conn.Read(recv)
if err != nil {
if strings.Contains(err.Error(), "timeout") && !isheart {
_, _ = self.conn.Write([]byte("hh"))
//4秒时间收心跳包
_ = self.conn.SetReadDeadline(time.Now().Add(4*time.Second))
isheart = true
continue
}
//浏览器有可能连接上不发消息就断开,此时就发一个0,为了与服务器一直有一条tcp通道
self.recv <- []byte("0")
self.er <- true
self.writ <- true
break
}
//收到心跳包
if recv[0] == 'h' && recv[1] == 'h' {
_ = self.conn.SetReadDeadline(time.Now().Add(time.Second * 20))
isheart = false
continue
}
self.recv <- recv[:n]
}
}

//把数据发送给服务端
func (self server) write() {
for {
var send=make([]byte, 10240)
select {
case send = <-self.send:
_, _ = self.conn.Write(send)
case <-self.writ:
break
}
}
}

func printUsage() {
fmt.Println("Usage: proxy [command] [parameters], where command is one of:")
fmt.Print(" ")

i := 0
for id := range commands {
fmt.Print(id)

if i < len(commands)-1 {
fmt.Print(", ")
}
i++
}

fmt.Println(" or help")
fmt.Println()

if provider != nil {
provider.printHelp(" ")
} else {
for id, provider := range commands {
fmt.Printf(" %s\n", id)
provider.printHelp(" ")
fmt.Printf(" For more information run \"proxy help %s\"\n", id)
fmt.Println("")
}
}
flag.PrintDefaults()
}

func help() {
printUsage()
os.Exit(2)
}

func loadCommands() {
commands = make(map[string]command)
commands["start"]=&start{}
commands["stop"] = &stop{}
}

func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
loadCommands()
flag.Usage = printUsage

args := os.Args[1:]
if len(args) < 1 {
help()
}

command := args[0]
if command[0] == '-' {
help()
}

if command == "help" {
if len(args) >= 2 {
provider = commands[args[1]]
provider.addFlags()
}
help()
} else if command == "version" {
fmt.Printf("proxy version %s","0.3.3")
}else {
provider = commands[command]
if provider == nil {
fmt.Println("Unsupported command", command)
return
}

provider.addFlags()
if command=="start" {
_ = flag.CommandLine.Parse(args[1:])
}
provider.run(os.Args[2:])
}
}
121 changes: 121 additions & 0 deletions client/start.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package main

import (
"flag"
"fmt"
"io/ioutil"
"net"
"os"
"os/exec"
"runtime"
)

type start struct {
ip string
port string
local string
d bool
}

func (this *start) addFlags() {
flag.StringVar(&this.ip, "h", "", "Server IP.")
flag.StringVar(&this.port, "r", "2001", "Server Port.")
flag.StringVar(&this.local, "l", "127.0.0.1:80", "Local IP and Port.")
flag.BoolVar(&this.d, "d", false, "Open daemon.")
}

func (this *start) printHelp(indent string) {
fmt.Println(indent, "This command is used to open intranet penetration connecting the server.")
fmt.Println(indent, "Command usage: proxy start [parameters]")
}

func (this *start) run(args []string) {
if len(args)==0 || this.ip=="" {
help()
}

if this.d==true {
cmd:=exec.Command(os.Args[0],"-start","-h",this.ip,"-r",this.port,"-l",this.local)
err:=cmd.Start()
if err!=nil {
fmt.Println(err.Error())
os.Exit(2)
}

_ = ioutil.WriteFile("./proxy.pid", []byte(fmt.Sprintf("%d", cmd.Process.Pid)), 0666)
fmt.Println("Start success.")
os.Exit(2)
}else{
this.startServer()
}
}

//开启内网穿透
func (this *start) startServer() {
target := net.JoinHostPort(this.ip,this.port)
for {
//链接端口
serverconn := dail(target)
recv := make(chan []byte)
send := make(chan []byte)
//1个位置是为了防止两个读取线程一个退出后另一个永远卡住
er := make(chan bool, 1)
writ := make(chan bool)
next := make(chan bool)
server := &server{serverconn, er, writ, recv, send}
go server.read()
go server.write()
go handle(this.local,server,next)
<-next
}
}

//链接端口
func dail(hostport string) net.Conn {
conn, err := net.Dial("tcp", hostport)
if err!=nil {
fmt.Printf("出现错误,退出线程: %v\n", err)
runtime.Goexit()
}
return conn
}

//两个socket衔接相关处理
func handle(localPort string,server *server, next chan bool) {
var serverrecv=make([]byte,10240)
//阻塞这里等待服务端传来数据再链接浏览器
fmt.Println("等待server发来消息")
serverrecv = <-server.recv
next <- true
var browse *browser
//服务端发来数据,链接本地80端口
serverconn := dail(localPort)
recv := make(chan []byte)
send := make(chan []byte)
er := make(chan bool, 1)
writ := make(chan bool)
browse = &browser{serverconn, er, writ, recv, send}
go browse.read()
go browse.write()
browse.send <- serverrecv
for {
var serverrecv = make([]byte, 10240)
var browserrecv = make([]byte, 10240)
select {
case serverrecv = <-server.recv:
if serverrecv[0] != '0' {
browse.send <- serverrecv
}
case browserrecv = <-browse.recv:
server.send <- browserrecv
case <-server.er:
_ = server.conn.Close()
_ = browse.conn.Close()
runtime.Goexit()
case <-browse.er:
_ = server.conn.Close()
_ = browse.conn.Close()
runtime.Goexit()
}
}
}
40 changes: 40 additions & 0 deletions client/stop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"runtime"
)

type stop struct {}

func (this *stop) addFlags() {

}

func (this *stop) printHelp(indent string) {
fmt.Println(indent, "This command is used to shut down client intranet penetration.")
fmt.Println(indent, "Command usage: proxy stop")
}

func (this *stop) run(args []string) {
b,_:=ioutil.ReadFile("./proxy.pid")
var command *exec.Cmd
//结束守护进程
if runtime.GOOS=="windows"{
command=exec.Command("taskkill","/F","/PID",string(b))
}else{
command=exec.Command("kill","-9",string(b))
}
err:=command.Start()
if err!=nil {
fmt.Println(err.Error())
os.Exit(2)
}

_ = os.Remove("./proxy.pid")
fmt.Println("Stop success.")
os.Exit(2)
}
2 changes: 1 addition & 1 deletion hosts/conf/conf.go → conf/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,4 @@ func (c Config) Read(node, key string) string {
return ""
}
return v
}
}
7 changes: 7 additions & 0 deletions hosts/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

type command interface {
addFlags()
printHelp(string)
run(args []string)
}
5 changes: 0 additions & 5 deletions hosts/hosts.conf

This file was deleted.

Loading

0 comments on commit dc8e35e

Please sign in to comment.