Skip to content

Commit

Permalink
v1.25.0 (#59)
Browse files Browse the repository at this point in the history
* refactor(api/traffic): merge now and traffic

* feat(api): dns statistic

* feat(api): dns statistic

* chore: upgrade dashboard
  • Loading branch information
igoogolx authored Jan 11, 2025
1 parent 78cc120 commit d203c53
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 57 deletions.
61 changes: 61 additions & 0 deletions api/routes/dns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package routes

import (
"bytes"
"encoding/json"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
"github.com/gorilla/websocket"
"github.com/igoogolx/itun2socks/internal/dns"
"net/http"
"time"
)

func dnsRouter() http.Handler {
r := chi.NewRouter()
r.Get("/statistic", getDnsStatistic)
return r
}

type Dns struct {
Success int32 `json:"success"`
Fail int32 `json:"fail"`
}

func getDnsStatistic(w http.ResponseWriter, r *http.Request) {
var wsConn *websocket.Conn
if websocket.IsWebSocketUpgrade(r) {
var err error
wsConn, err = upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
}

if wsConn == nil {
w.Header().Set("Content-Type", "application/json")
render.Status(r, http.StatusOK)
}

tick := time.NewTicker(time.Second)
defer tick.Stop()
buf := &bytes.Buffer{}
var err error
for range tick.C {
buf.Reset()
if err := json.NewEncoder(buf).Encode(dns.GetStatistic()); err != nil {
break
}

if wsConn == nil {
_, err = w.Write(buf.Bytes())
w.(http.Flusher).Flush()
} else {
err = wsConn.WriteMessage(websocket.TextMessage, buf.Bytes())
}

if err != nil {
break
}
}
}
1 change: 1 addition & 0 deletions api/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func Start(addr string, secret string) error {
r.Mount("/manager", managerRouter())
r.Mount("/is-admin", isAdminRouter())
r.Mount("/heartbeat", heartbeatRouter())
r.Mount("/dns", dnsRouter())
})
go FileServer(r)
err := http.ListenAndServe(addr, r)
Expand Down
69 changes: 13 additions & 56 deletions api/routes/traffic.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/igoogolx/itun2socks/internal/constants"
"github.com/igoogolx/itun2socks/internal/tunnel/statistic"
"net/http"
"strconv"
"time"
)

Expand All @@ -23,8 +22,7 @@ var (

func trafficRouter() http.Handler {
r := chi.NewRouter()
r.Get("/now", getNow)
r.Get("/total", getTotal)
r.Get("/", getTraffic)
return r
}

Expand All @@ -33,12 +31,17 @@ type TrafficItem struct {
Down int64 `json:"download"`
}

type Traffic struct {
type Speed struct {
Proxy TrafficItem `json:"proxy"`
Direct TrafficItem `json:"direct"`
}

func getNow(w http.ResponseWriter, r *http.Request) {
type Traffic struct {
Speed Speed `json:"speed"`
Total statistic.Total `json:"total"`
}

func getTraffic(w http.ResponseWriter, r *http.Request) {
var wsConn *websocket.Conn
if websocket.IsWebSocketUpgrade(r) {
var err error
Expand All @@ -63,8 +66,11 @@ func getNow(w http.ResponseWriter, r *http.Request) {
proxyUp, proxyDown := t.Now(constants.PolicyProxy)
directUp, directDown := t.Now(constants.PolicyDirect)
if err := json.NewEncoder(buf).Encode(Traffic{
TrafficItem{proxyUp, proxyDown},
TrafficItem{directUp, directDown},
Speed: Speed{
TrafficItem{proxyUp, proxyDown},
TrafficItem{directUp, directDown},
},
Total: *t.GetTotal(),
}); err != nil {
break
}
Expand All @@ -81,52 +87,3 @@ func getNow(w http.ResponseWriter, r *http.Request) {
}
}
}

func getTotal(w http.ResponseWriter, r *http.Request) {
if !websocket.IsWebSocketUpgrade(r) {
snapshot := statistic.DefaultManager.Connections()
render.JSON(w, r, snapshot)
return
}

conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}

intervalStr := r.URL.Query().Get("interval")
interval := 1000
if intervalStr != "" {
t, err := strconv.Atoi(intervalStr)
if err != nil {
render.Status(r, http.StatusBadRequest)
render.JSON(w, r, ErrBadRequest)
return
}

interval = t
}

buf := &bytes.Buffer{}
sendTotal := func() error {
buf.Reset()
total := statistic.DefaultManager.GetTotal()
if err := json.NewEncoder(buf).Encode(total); err != nil {
return err
}

return conn.WriteMessage(websocket.TextMessage, buf.Bytes())
}

if err := sendTotal(); err != nil {
return
}

tick := time.NewTicker(time.Millisecond * time.Duration(interval))
defer tick.Stop()
for range tick.C {
if err := sendTotal(); err != nil {
break
}
}
}
10 changes: 10 additions & 0 deletions internal/dns/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func Handle(dnsMessage *D.Msg, metadata *constant.Metadata) (*D.Msg, error) {
defer mux.RUnlock()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var err error
start := time.Now()
question, qType, err := getDnsQuestion(dnsMessage)

Expand All @@ -117,6 +118,15 @@ func Handle(dnsMessage *D.Msg, metadata *constant.Metadata) (*D.Msg, error) {
if err != nil {
return nil, fmt.Errorf("fail to get dns resolver, err: %v, question: %v", err, question)
}

defer func() {
if err != nil {
countFailQuery(dnsRule.GetPolicy())
} else {
countSuccessQuery(dnsRule.GetPolicy())
}
}()

res, err := dnsMap[dnsRule.GetPolicy()].ExchangeContext(ctx, dnsMessage)
if err != nil {
return nil, fmt.Errorf("fail to exchange dns message, err: %v, question: %v", err, question)
Expand Down
47 changes: 47 additions & 0 deletions internal/dns/statistic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dns

import (
"github.com/igoogolx/itun2socks/internal/constants"
"go.uber.org/atomic"
)

type StatisticItem struct {
Success *atomic.Int32 `json:"success"`
Fail *atomic.Int32 `json:"fail"`
}

type Statistic struct {
Proxy StatisticItem `json:"proxy"`
Direct StatisticItem `json:"direct"`
}

var static = Statistic{
Proxy: StatisticItem{
Success: atomic.NewInt32(0),
Fail: atomic.NewInt32(0),
},
Direct: StatisticItem{
Success: atomic.NewInt32(0),
Fail: atomic.NewInt32(0),
},
}

func countSuccessQuery(policy constants.Policy) {
if policy == constants.PolicyDirect {
static.Direct.Success.Inc()
} else if policy == constants.PolicyProxy {
static.Proxy.Success.Inc()
}
}

func countFailQuery(policy constants.Policy) {
if policy == constants.PolicyDirect {
static.Direct.Fail.Inc()
} else if policy == constants.PolicyProxy {
static.Proxy.Fail.Inc()
}
}

func GetStatistic() Statistic {
return static
}
2 changes: 1 addition & 1 deletion scripts/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

func main() {
download("https://github.com/igoogolx/lux-rules/releases/download/v2.4.0/rules.tar.gz", filepath.Join("internal", "cfg", "distribution", "ruleEngine", "rules.tar.gz"))
download("https://github.com/igoogolx/lux-client/releases/download/v1.11.0/dist-ui.tar.gz", filepath.Join("api", "routes", "dist.tar.gz"))
download("https://github.com/igoogolx/lux-client/releases/download/v1.11.2/dist-ui.tar.gz", filepath.Join("api", "routes", "dist.tar.gz"))
}

func download(url string, outputPath string) {
Expand Down

0 comments on commit d203c53

Please sign in to comment.