Compare commits

...

2 Commits
v2 ... main

Author SHA1 Message Date
lzf 676aa5bdcb update 2024-10-10 10:53:08 +08:00
lzf 36d32e7222 update 2024-09-30 18:02:16 +08:00
9 changed files with 91 additions and 35 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"git.makemake.in/kzkzzzz/mycommon/mylog" "git.makemake.in/kzkzzzz/mycommon/mylog"
"io" "io"
"log"
"math/rand" "math/rand"
"net" "net"
"time" "time"
@ -61,7 +62,7 @@ func (t *TCP) Forward() error {
//listener, err := lc.Listen(ctx0, "tcp", t.forwardInfo.LocalAddr) //listener, err := lc.Listen(ctx0, "tcp", t.forwardInfo.LocalAddr)
// 启动 TCP 监听 // 启动 TCP 监听
mylog.Infof("[TCP] %s %s -> %s", t.forwardInfo.Name, t.forwardInfo.LocalAddr, t.forwardInfo.TargetAddr) log.Printf("[TCP] [%s] %s -> %s", t.forwardInfo.Name, t.forwardInfo.LocalAddr, t.forwardInfo.TargetAddr)
go func() { go func() {
ctx, cancelCtx := context.WithCancel(context.Background()) ctx, cancelCtx := context.WithCancel(context.Background())

View File

@ -2,6 +2,7 @@ package forward
import ( import (
"git.makemake.in/kzkzzzz/mycommon/mylog" "git.makemake.in/kzkzzzz/mycommon/mylog"
"log"
"math/rand" "math/rand"
"net" "net"
"time" "time"
@ -36,7 +37,7 @@ func (u *UDP) Forward() error {
} }
u.conn = conn u.conn = conn
mylog.Infof("[UDP] %s %s -> %s", u.forwardInfo.Name, u.forwardInfo.LocalAddr, u.forwardInfo.TargetAddr) log.Printf("[UDP] [%s] %s -> %s", u.forwardInfo.Name, u.forwardInfo.LocalAddr, u.forwardInfo.TargetAddr)
go func() { go func() {
err := u.handleConn(conn) err := u.handleConn(conn)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,8 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>端口转发配置</title> <title>端口转发</title>
<script type="module" crossorigin src="./assets/index-lqpwyav5.js"></script> <script type="module" crossorigin src="./assets/index-JzuN2dGn.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-BA8XwqWY.css"> <link rel="stylesheet" crossorigin href="./assets/index-BA8XwqWY.css">
</head> </head>
<body> <body>

View File

@ -12,7 +12,9 @@ import (
enTr "github.com/go-playground/validator/v10/translations/en" enTr "github.com/go-playground/validator/v10/translations/en"
"github.com/spf13/cast" "github.com/spf13/cast"
"gorm.io/gorm" "gorm.io/gorm"
"log"
"net/http" "net/http"
"net/netip"
"proxyport/app/db" "proxyport/app/db"
"proxyport/app/forward" "proxyport/app/forward"
"proxyport/app/model" "proxyport/app/model"
@ -29,6 +31,7 @@ type Cfg struct {
ListenAddr string ListenAddr string
User string User string
Password string Password string
WebName string
} }
func Start(ctx context.Context) { func Start(ctx context.Context) {
@ -48,6 +51,8 @@ func Start(ctx context.Context) {
engine.GET("/", func(ctx *gin.Context) { engine.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "index.html", nil) ctx.HTML(http.StatusOK, "index.html", nil)
}) })
engine.GET("/GetConfig", GetConfig)
engine.GET("/List", List) engine.GET("/List", List)
engine.POST("/Create", Create) engine.POST("/Create", Create)
engine.POST("/Update", Update) engine.POST("/Update", Update)
@ -60,7 +65,7 @@ func Start(ctx context.Context) {
} }
go func() { go func() {
mylog.Infof("http listen on %s", hs.Addr) log.Printf("http listen on %s", hs.Addr)
mylog.Warn(hs.ListenAndServe()) mylog.Warn(hs.ListenAndServe())
}() }()
@ -84,6 +89,12 @@ func cors() gin.HandlerFunc {
} }
} }
func GetConfig(ctx *gin.Context) {
success(ctx, gin.H{
"web_name": Config.WebName,
})
}
func List(ctx *gin.Context) { func List(ctx *gin.Context) {
data := make([]*model.Forward, 0) data := make([]*model.Forward, 0)
@ -269,23 +280,45 @@ func Delete(ctx *gin.Context) {
success(ctx, "ok") success(ctx, "ok")
} }
var addrReg = regexp.MustCompile(`^[^:]+:([0-9]{1,5})$`) var (
hostReg = regexp.MustCompile(`^[a-zA-Z0-9]+[a-zA-Z0-9\-.]*[a-zA-Z]+$`)
letterReg = regexp.MustCompile(`[a-zA-Z\-]`)
emptyReg = regexp.MustCompile(`\s+`)
)
func checkAddr(addr string) error { func checkAddr(addr string) error {
res := addrReg.FindStringSubmatch(addr) addr = strings.TrimSpace(addr)
if len(res) != 2 {
return fmt.Errorf("invalid addr: %s", addr) if emptyReg.MatchString(addr) {
return fmt.Errorf("addr format err: %s", addr)
} }
intPort := cast.ToInt(res[1]) sp := strings.SplitN(addr, ":", 2)
if intPort < 10 || intPort > 65535 {
return fmt.Errorf("port: %d out of range: 10 - 65535", intPort) if len(sp) != 2 {
return fmt.Errorf("addr format err: %s", addr)
} }
//_, err := netip.ParseAddrPort(addr) host := sp[0]
//if err != nil { port := sp[1]
// return err intPort := cast.ToInt(port)
//}
if intPort > 65535 || intPort < 10 {
return fmt.Errorf("port [%s] out of range: 10 - 65535", port)
}
if !letterReg.MatchString(host) {
_, err := netip.ParseAddrPort(addr)
if err != nil {
return fmt.Errorf("ip [%s] format err: %s", host, err)
}
return nil
}
if !hostReg.MatchString(host) {
return fmt.Errorf("host [%s] format err", host)
}
return nil return nil
} }

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>端口转发配置</title> <title>端口转发</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -1,7 +1,9 @@
<template> <template>
<div> <div>
<div> <div>
<h2>端口转发</h2> <h2>
<span>{{ data.title }}</span>
</h2>
</div> </div>
<div style="width: 100%;"> <div style="width: 100%;">
@ -9,15 +11,15 @@
</div> </div>
<div> <div>
<el-table :data="data.list" style="width: 100%"> <el-table :data="data.list" style="width: 100%;" max-height="75vh">
<el-table-column align="center" label="协议"> <el-table-column align="center" label="协议">
<template #default="scope"> <template #default="scope">
<div v-if="scope.row.protocol === 1"> <div v-if="scope.row.protocol === 1">
<el-tag type="success">UDP</el-tag> <el-tag disable-transitions type="success">UDP</el-tag>
</div> </div>
<div v-else> <div v-else>
<el-tag type="primary">TCP</el-tag> <el-tag disable-transitions type="primary">TCP</el-tag>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -35,7 +37,7 @@
<el-table-column align="center" label="远程地址"> <el-table-column align="center" label="远程地址">
<template #default="scope"> <template #default="scope">
<div style="white-space: pre">{{ formatList(scope.row.target_addr) }}</div> <div style="white-space: pre-wrap; word-break: break-all">{{ formatList(scope.row.target_addr) }}</div>
</template> </template>
</el-table-column> </el-table-column>
@ -61,6 +63,8 @@
:title="data.form.id > 0 ? '修改': '添加'" :title="data.form.id > 0 ? '修改': '添加'"
width="600px" width="600px"
align-center align-center
:close-on-click-modal="false"
:show-close="false"
> >
<div> <div>
@ -108,17 +112,31 @@ import {onMounted, reactive} from "vue";
import http from "@/helper/http.js"; import http from "@/helper/http.js";
const data = reactive({ const data = reactive({
title: "端口转发",
list: [], list: [],
dialogVisible: false, dialogVisible: false,
form: { form: {
protocol: 0, protocol: 0,
} },
config: {}
}) })
onMounted(() => { onMounted(() => {
getConfig()
getList() getList()
}) })
const getConfig = async () => {
let res = await http.get("/GetConfig")
data.config = res.data.data
if (data.config.web_name !== "") {
data.title = `端口转发 - ${data.config.web_name}`
}
document.title = data.title
}
const createForward = () => { const createForward = () => {
data.dialogVisible = true data.dialogVisible = true
data.form = { data.form = {
@ -175,7 +193,7 @@ const getList = async () => {
} }
} }
console.log(res) // console.log(res)
} }
const confirmConfig = async () => { const confirmConfig = async () => {

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"flag" "flag"
"git.makemake.in/kzkzzzz/mycommon/mylog" "git.makemake.in/kzkzzzz/mycommon/mylog"
"log"
"os" "os"
"os/signal" "os/signal"
"proxyport/app/db" "proxyport/app/db"
@ -18,10 +19,12 @@ var (
) )
func main() { func main() {
log.SetOutput(os.Stdout)
flag.StringVar(&logLevel, "log_level", "debug", "log level") flag.StringVar(&logLevel, "log_level", "debug", "log level")
flag.StringVar(&web.Config.ListenAddr, "listen_addr", ":28083", "web port") flag.StringVar(&web.Config.ListenAddr, "listen_addr", ":28083", "web port")
flag.StringVar(&web.Config.User, "user", "", "web user") flag.StringVar(&web.Config.User, "user", "", "web user")
flag.StringVar(&web.Config.Password, "password", "", "web password") flag.StringVar(&web.Config.Password, "password", "", "web password")
flag.StringVar(&web.Config.WebName, "web_name", "", "web name")
flag.Parse() flag.Parse()
mylog.SetLogLevel(logLevel) mylog.SetLogLevel(logLevel)