diff --git a/cmd/hvpn-node/hvpn-node.go b/cmd/hvpn-node/hvpn-node.go index 5ac9083..ccf6643 100644 --- a/cmd/hvpn-node/hvpn-node.go +++ b/cmd/hvpn-node/hvpn-node.go @@ -16,6 +16,7 @@ import ( "github.com/urfave/cli/v2" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "github.com/biter777/countries" hvpnnode3 "gitea.hbanafa.com/HeshamTB/hvpn-node3" ) @@ -33,6 +34,8 @@ var InterfaceName string var WgPort int var wgLink *hvpnnode3.WGLink +var Country countries.CountryCode + var httpPort int var TLS_ENABLED bool var tlsConfig *tls.Config @@ -57,6 +60,7 @@ func run(ctx *cli.Context) { wgLink.StartedAT = time.Now().UTC() slog.Info(fmt.Sprintf("Started at %s", wgLink.StartedAT)) + slog.Info(fmt.Sprintf("Country set to %s (%s)", Country.Alpha2(), Country.String())) hvpnnode3.StartMonitor(wgLink, *slog.Default()) apiMux := http.NewServeMux() @@ -68,6 +72,7 @@ func run(ctx *cli.Context) { apiMux.HandleFunc("GET /peer", hvpnnode3.HandleGetCreatePeer(wgLink)) var handler http.Handler = apiMux + handler = hvpnnode3.WithCountryCtx(handler, Country) handler = hvpnnode3.HttpAuthToken(handler, ctx.String("http-api-key")) handler = hvpnnode3.HttpLogHandler2(handler) @@ -197,6 +202,22 @@ func createCliApp() *cli.App { } app.Flags = append(app.Flags, &apiSecret) + countryFlag := cli.StringFlag{ + Name: "country", + Usage: "The contry code for this VPN instance. Accepts ISO 3166 codes", + Value: "SA", + Action: func(ctx *cli.Context, s string) error { + c := countries.ByName(s) + if c == countries.Unknown { + return errors.New(fmt.Sprintf("Country code %s is unknown", s)) + } + Country = c + return nil + }, + EnvVars: []string{ "HVPN_COUNTRY" }, + } + app.Flags = append(app.Flags, &countryFlag) + /* TLS Flags */ diff --git a/go.mod b/go.mod index e9fc852..dbd2360 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gitea.hbanafa.com/HeshamTB/hvpn-node3 go 1.22.0 require ( + github.com/biter777/countries v1.7.4 github.com/felixge/httpsnoop v1.0.4 github.com/google/uuid v1.6.0 github.com/urfave/cli/v2 v2.27.1 diff --git a/go.sum b/go.sum index 09e5313..ac0a02d 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/biter777/countries v1.7.4 h1:590JZkxrv+/JBTAw2GHULx9l7vUZxz2HWMZ9HkruiOc= +github.com/biter777/countries v1.7.4/go.mod h1:1HSpZ526mYqKJcpT5Ti1kcGQ0L0SrXWIaptUWjFfv2E= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= diff --git a/handlers.go b/handlers.go index e226767..b370ca2 100644 --- a/handlers.go +++ b/handlers.go @@ -11,6 +11,7 @@ import ( "text/template" "time" + "github.com/biter777/countries" "github.com/felixge/httpsnoop" "github.com/google/uuid" @@ -20,6 +21,7 @@ import ( type CtxKey string const CtxReqID CtxKey = "request_id" +const CtxCountryCode CtxKey = "country" func HandleGetNodeInfo(wgLink *WGLink) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -31,10 +33,13 @@ func HandleGetNodeInfo(wgLink *WGLink) http.HandlerFunc { return } + c := r.Context().Value(CtxCountryCode).(countries.CountryCode) json.NewEncoder(w).Encode( proto.NodePublicInfo{ PublicKey: dev.PublicKey.String(), UDPPort: dev.ListenPort, + Country: c.String(), + CountryCode: c.Alpha2(), Endpoint: wgLink.Endpoint, Type: dev.Type.String(), StartedAt: wgLink.StartedAT, @@ -236,6 +241,14 @@ func HttpAuthToken(h http.Handler, token string) http.Handler { return http.HandlerFunc(fn) } +func WithCountryCtx(h http.Handler, country countries.CountryCode) http.Handler { + fn := func(w http.ResponseWriter, r* http.Request) { + rr := r.WithContext(context.WithValue(r.Context(), CtxCountryCode, country)) + h.ServeHTTP(w, rr) + } + return http.HandlerFunc(fn) +} + func debugf(format string, reqID uuid.UUID, args ...any) { format = format + " " + reqID.String() slog.Debug(fmt.Sprintf(format, args...)) diff --git a/proto/node.go b/proto/node.go index 7c745a5..44488e5 100644 --- a/proto/node.go +++ b/proto/node.go @@ -6,7 +6,9 @@ type NodePublicInfo struct { PublicKey string `json:"public_key"` UDPPort int `json:"udp_port"` Endpoint string `json:"endpoint"` + Country string `json:"country"` + CountryCode string `json:"country_code"` Type string `json:"type"` StartedAt time.Time `json:"started_at"` - Uptime time.Duration `json:"uptime"` + Uptime time.Duration `json:"uptime_ns"` }