feat: add port

master
ZGGSONG 2 years ago
parent fd17706a84
commit 2edebee087

@ -1,16 +1,10 @@
package main package main
import ( import (
"encoding/binary"
"errors"
"fmt"
"io"
"log" "log"
"net"
"os" "os"
"os/signal" "os/signal"
"proxy_socks5/ui" "proxy_socks5/ui"
"sync"
"syscall" "syscall"
"time" "time"
) )
@ -18,7 +12,6 @@ import (
const ( const (
name = "Socks5" name = "Socks5"
version = "v1.0.0" version = "v1.0.0"
port = "1080"
) )
func main() { func main() {
@ -27,16 +20,12 @@ func main() {
log.Printf("panic: %v\n", p) log.Printf("panic: %v\n", p)
} }
}() }()
exitCh := make(chan os.Signal, 10) exitCh := make(chan os.Signal, 10)
signal.Notify(exitCh, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) //syscall.SIGUSR1, syscall.SIGUSR2) signal.Notify(exitCh, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) //syscall.SIGUSR1, syscall.SIGUSR2)
go run()
gui := ui.New( gui := ui.New(
ui.Version(version), ui.Version(version),
ui.Name(name), ui.Name(name),
ui.Port(port),
ui.OnClose(func() { ui.OnClose(func() {
log.Printf("gui OnClose callback") log.Printf("gui OnClose callback")
}), }),
@ -45,167 +34,7 @@ func main() {
os.Exit(func() (code int) { os.Exit(func() (code int) {
code = gui.Run(exitCh) code = gui.Run(exitCh)
log.Printf("exit code: %v", code) log.Printf("exit code: %v", code)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Millisecond)
return return
}()) }())
} }
func run() {
server, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Printf("Listen failed: %v\n", err)
return
}
for {
client, err := server.Accept()
if err != nil {
log.Printf("Accept failed: %v", err)
continue
}
go process(client)
}
}
func process(client net.Conn) {
if err := Socks5Auth(client); err != nil {
log.Println("auth error:", err)
client.Close()
return
}
target, err := Socks5Connect(client)
if err != nil {
log.Println("connect error:", err)
client.Close()
return
}
Socks5Forward(client, target)
}
func Socks5Auth(client net.Conn) (err error) {
buf := make([]byte, 256)
// 读取 VER 和 NMETHODS
n, err := io.ReadFull(client, buf[:2])
if n != 2 {
return errors.New("reading header: " + err.Error())
}
ver, nMethods := int(buf[0]), int(buf[1])
if ver != 5 {
return errors.New("invalid version")
}
// 读取 METHODS 列表
n, err = io.ReadFull(client, buf[:nMethods])
if n != nMethods {
return errors.New("reading methods: " + err.Error())
}
//无需认证
n, err = client.Write([]byte{0x05, 0x00})
if n != 2 || err != nil {
return errors.New("write rsp: " + err.Error())
}
return nil
}
func Socks5Connect(client net.Conn) (net.Conn, error) {
buf := make([]byte, 256)
n, err := io.ReadFull(client, buf[:4])
if n != 4 {
return nil, errors.New("read header: " + err.Error())
}
ver, cmd, _, atyp := buf[0], buf[1], buf[2], buf[3]
if ver != 5 || cmd != 1 {
return nil, errors.New("invalid ver/cmd")
}
addr := ""
switch atyp {
case 1:
n, err = io.ReadFull(client, buf[:4])
if n != 4 {
return nil, errors.New("invalid IPv4: " + err.Error())
}
addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])
case 3:
n, err = io.ReadFull(client, buf[:1])
if n != 1 {
return nil, errors.New("invalid hostname: " + err.Error())
}
addrLen := int(buf[0])
n, err = io.ReadFull(client, buf[:addrLen])
if n != addrLen {
return nil, errors.New("invalid hostname: " + err.Error())
}
addr = string(buf[:addrLen])
case 4:
return nil, errors.New("IPv6: no supported yet")
default:
return nil, errors.New("invalid atyp")
}
n, err = io.ReadFull(client, buf[:2])
if n != 2 {
return nil, errors.New("read port: " + err.Error())
}
port := binary.BigEndian.Uint16(buf[:2])
destAddrPort := fmt.Sprintf("%s:%d", addr, port)
dest, err := net.Dial("tcp", destAddrPort)
if err != nil {
return nil, errors.New("dial dst: " + err.Error())
}
_, err = client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})
if err != nil {
dest.Close()
return nil, errors.New("write rsp: " + err.Error())
}
return dest, nil
}
// func Socks5Forward(client, target net.Conn) {
// forward := func(src, dest net.Conn) {
// defer src.Close()
// defer dest.Close()
// io.Copy(src, dest)
// }
// go forward(client, target)
// go forward(target, client)
// }
func Socks5Forward(left, right net.Conn) error {
var err, err1 error
var wg sync.WaitGroup
var wait = 5 * time.Second
wg.Add(1)
go func() {
defer wg.Done()
_, err1 = io.Copy(right, left)
right.SetReadDeadline(time.Now().Add(wait))
}()
_, err = io.Copy(left, right)
left.SetReadDeadline(time.Now().Add(wait))
wg.Wait()
if err != nil && !errors.Is(err, os.ErrDeadlineExceeded) {
return err
}
if err1 != nil && !errors.Is(err1, os.ErrDeadlineExceeded) {
return err1
}
return nil
}

@ -0,0 +1,173 @@
package service
import (
"encoding/binary"
"errors"
"fmt"
"io"
"log"
"net"
"os"
"sync"
"time"
)
func RunServe(port string) {
server, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Printf("Listen failed: %v\n", err)
return
}
for {
client, err := server.Accept()
if err != nil {
log.Printf("Accept failed: %v", err)
continue
}
go process(client)
}
}
func process(client net.Conn) {
if err := Socks5Auth(client); err != nil {
log.Println("auth error:", err)
client.Close()
return
}
target, err := Socks5Connect(client)
if err != nil {
log.Println("connect error:", err)
client.Close()
return
}
Socks5Forward(client, target)
}
func Socks5Auth(client net.Conn) (err error) {
buf := make([]byte, 256)
// 读取 VER 和 NMETHODS
n, err := io.ReadFull(client, buf[:2])
if n != 2 {
return errors.New("reading header: " + err.Error())
}
ver, nMethods := int(buf[0]), int(buf[1])
if ver != 5 {
return errors.New("invalid version")
}
// 读取 METHODS 列表
n, err = io.ReadFull(client, buf[:nMethods])
if n != nMethods {
return errors.New("reading methods: " + err.Error())
}
//无需认证
n, err = client.Write([]byte{0x05, 0x00})
if n != 2 || err != nil {
return errors.New("write rsp: " + err.Error())
}
return nil
}
func Socks5Connect(client net.Conn) (net.Conn, error) {
buf := make([]byte, 256)
n, err := io.ReadFull(client, buf[:4])
if n != 4 {
return nil, errors.New("read header: " + err.Error())
}
ver, cmd, _, atyp := buf[0], buf[1], buf[2], buf[3]
if ver != 5 || cmd != 1 {
return nil, errors.New("invalid ver/cmd")
}
addr := ""
switch atyp {
case 1:
n, err = io.ReadFull(client, buf[:4])
if n != 4 {
return nil, errors.New("invalid IPv4: " + err.Error())
}
addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])
case 3:
n, err = io.ReadFull(client, buf[:1])
if n != 1 {
return nil, errors.New("invalid hostname: " + err.Error())
}
addrLen := int(buf[0])
n, err = io.ReadFull(client, buf[:addrLen])
if n != addrLen {
return nil, errors.New("invalid hostname: " + err.Error())
}
addr = string(buf[:addrLen])
case 4:
return nil, errors.New("IPv6: no supported yet")
default:
return nil, errors.New("invalid atyp")
}
n, err = io.ReadFull(client, buf[:2])
if n != 2 {
return nil, errors.New("read port: " + err.Error())
}
port := binary.BigEndian.Uint16(buf[:2])
destAddrPort := fmt.Sprintf("%s:%d", addr, port)
dest, err := net.Dial("tcp", destAddrPort)
if err != nil {
return nil, errors.New("dial dst: " + err.Error())
}
_, err = client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})
if err != nil {
dest.Close()
return nil, errors.New("write rsp: " + err.Error())
}
return dest, nil
}
// func Socks5Forward(client, target net.Conn) {
// forward := func(src, dest net.Conn) {
// defer src.Close()
// defer dest.Close()
// io.Copy(src, dest)
// }
// go forward(client, target)
// go forward(target, client)
// }
func Socks5Forward(left, right net.Conn) error {
var err, err1 error
var wg sync.WaitGroup
var wait = 5 * time.Second
wg.Add(1)
go func() {
defer wg.Done()
_, err1 = io.Copy(right, left)
right.SetReadDeadline(time.Now().Add(wait))
}()
_, err = io.Copy(left, right)
left.SetReadDeadline(time.Now().Add(wait))
wg.Wait()
if err != nil && !errors.Is(err, os.ErrDeadlineExceeded) {
return err
}
if err1 != nil && !errors.Is(err1, os.ErrDeadlineExceeded) {
return err1
}
return nil
}

@ -8,7 +8,6 @@ import (
type Options struct { type Options struct {
Name string Name string
Version string Version string
Port string
OnClose func() OnClose func()
} }
@ -41,11 +40,6 @@ func Name(n string) Option {
o.Name = n o.Name = n
} }
} }
func Port(p string) Option {
return func(o *Options) {
o.Port = p
}
}
// OnClose 关闭窗口事件 // OnClose 关闭窗口事件
func OnClose(f func()) Option { func OnClose(f func()) Option {

@ -3,6 +3,9 @@ package ui
import ( import (
"fmt" "fmt"
"os" "os"
"proxy_socks5/service"
"regexp"
"strconv"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/app" "fyne.io/fyne/v2/app"
@ -10,6 +13,8 @@ import (
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
) )
const reg = "^[0-9]*[1-9][0-9]*$"
type UI struct { type UI struct {
Options *Options Options *Options
mw *fyne.Window mw *fyne.Window
@ -28,13 +33,34 @@ func New(op ...Option) GUIApp {
a := app.New() a := app.New()
w := a.NewWindow(fmt.Sprintf("%v %v", opts.Name, opts.Version)) w := a.NewWindow(fmt.Sprintf("%v %v", opts.Name, opts.Version))
lable1 := widget.NewLabel(fmt.Sprintf("Listening at %v", opts.Port)) var port string
lable2 := widget.NewLabel("Running") label := widget.NewLabel("")
label.Hidden = true
input := widget.NewEntry()
input.SetPlaceHolder("Please Input The Port...")
w.SetContent(container.NewVBox( w.SetContent(container.NewVBox(
lable1, label,
lable2, input,
widget.NewButton("Listen", func() {
port = input.Text
r, _ := regexp.Compile(reg)
if r.MatchString(port) { //是数字
i, _ := strconv.ParseInt(port, 10, 64)
if 1 < 0 || i > 65535 {
port = "1080"
}
} else { //否则
port = "1080"
}
input.Hidden = true
label.Hidden = false
label.TextStyle.Bold = true
label.SetText(fmt.Sprintf("Listening at %v Succeed!!!", port))
service.RunServe(port)
}),
)) ))
w.Resize(fyne.NewSize(240, 120))
w.Resize(fyne.NewSize(240, 100))
return &UI{ return &UI{
Options: opts, Options: opts,

Loading…
Cancel
Save