mirror of
https://github.com/ditatompel/xmr-remote-nodes.git
synced 2024-11-16 17:07:36 +00:00
feat: Check IP-stack info everytime prober send report #84
This commit add IsIPv6Only function inside `internal/ip` package and moving `geo` package from `internal/geo` to `internal/ip/geo`. Although it increases server resource usage, checking hostname to IP is required every time the prober sends a report so that the `ipv6_only` record in the database is not up-to-date. Previously, this feature did not exist.
This commit is contained in:
parent
518d4b4335
commit
c3f837e122
7 changed files with 84 additions and 17 deletions
|
@ -38,14 +38,14 @@ To build the executable binaries, you need:
|
||||||
|
|
||||||
- MySQL/MariaDB
|
- MySQL/MariaDB
|
||||||
- [GeoIP Database][geoip_doc] (optional). Place it to `./assets/geoip`,
|
- [GeoIP Database][geoip_doc] (optional). Place it to `./assets/geoip`,
|
||||||
see [./internal/geo/ip.go](./internal/geo/ip.go).
|
see [./internal/ip/geo/geoip.go](./internal/ip/geo/geoip.go).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### For initial server setup:
|
### For initial server setup:
|
||||||
|
|
||||||
1. Download [GeoIP Database][geoip_doc] and place it to `./assets/geoip`.
|
1. Download [GeoIP Database][geoip_doc] and place it to `./assets/geoip`.
|
||||||
(see [./internal/geo/ip.go](./internal/geo/ip.go)).
|
(see [./internal/ip/geo/geoip.go](./internal/ip/geo/geoip.go)).
|
||||||
2. Pepare your MySQL/MariaDB.
|
2. Pepare your MySQL/MariaDB.
|
||||||
3. Copy `.env.example` to `.env` and edit it to match with server environment.
|
3. Copy `.env.example` to `.env` and edit it to match with server environment.
|
||||||
4. Build the binary with `make server` (or `make build` to build both
|
4. Build the binary with `make server` (or `make build` to build both
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ditatompel/xmr-remote-nodes/internal/config"
|
"github.com/ditatompel/xmr-remote-nodes/internal/config"
|
||||||
|
"github.com/ditatompel/xmr-remote-nodes/internal/ip"
|
||||||
"github.com/ditatompel/xmr-remote-nodes/internal/monero"
|
"github.com/ditatompel/xmr-remote-nodes/internal/monero"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -334,6 +335,12 @@ func (p *proberClient) fetchFee(client http.Client, endpoint string) (uint, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proberClient) reportResult(node monero.Node, tookTime float64) error {
|
func (p *proberClient) reportResult(node monero.Node, tookTime float64) error {
|
||||||
|
if !node.IsTor {
|
||||||
|
if hostIps, err := net.LookupIP(node.Hostname); err == nil {
|
||||||
|
node.IPv6Only = ip.IsIPv6Only(hostIps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jsonData, err := json.Marshal(monero.ProbeReport{
|
jsonData, err := json.Marshal(monero.ProbeReport{
|
||||||
TookTime: tookTime,
|
TookTime: tookTime,
|
||||||
Message: p.message,
|
Message: p.message,
|
||||||
|
|
16
internal/ip/ip.go
Normal file
16
internal/ip/ip.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Package ip provides IP address related functions
|
||||||
|
package ip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsIPv6Only returns true if all given IPs are IPv6
|
||||||
|
func IsIPv6Only(ips []net.IP) bool {
|
||||||
|
for _, ip := range ips {
|
||||||
|
if ip.To4() != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
46
internal/ip/ip_test.go
Normal file
46
internal/ip/ip_test.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package ip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Single test: go test ./internal/ip -bench TestIsIPv6Only -benchmem -run=^$ -v
|
||||||
|
func TestIsIPv6Only(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ips []net.IP
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "IPv4",
|
||||||
|
ips: []net.IP{
|
||||||
|
net.ParseIP("1.1.1.1"),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6",
|
||||||
|
ips: []net.IP{
|
||||||
|
net.ParseIP("2606:4700::6810:85e5"),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6 and IPv4",
|
||||||
|
ips: []net.IP{
|
||||||
|
net.ParseIP("1.1.1.1"),
|
||||||
|
net.ParseIP("2606:4700::6810:84e5"),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := IsIPv6Only(tt.ips); got != tt.want {
|
||||||
|
t.Errorf("IsIPv6Only() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ditatompel/xmr-remote-nodes/internal/database"
|
"github.com/ditatompel/xmr-remote-nodes/internal/database"
|
||||||
|
"github.com/ditatompel/xmr-remote-nodes/internal/ip"
|
||||||
"github.com/jmoiron/sqlx/types"
|
"github.com/jmoiron/sqlx/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -196,9 +196,9 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
if strings.HasSuffix(hostname, ".onion") {
|
if strings.HasSuffix(hostname, ".onion") {
|
||||||
is_tor = true
|
is_tor = true
|
||||||
}
|
}
|
||||||
ip := ""
|
|
||||||
|
|
||||||
ipv6_only := true
|
ipAddr := ""
|
||||||
|
ipv6_only := false
|
||||||
|
|
||||||
if !is_tor {
|
if !is_tor {
|
||||||
hostIps, err := net.LookupIP(hostname)
|
hostIps, err := net.LookupIP(hostname)
|
||||||
|
@ -206,12 +206,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hostIp := range hostIps {
|
ipv6_only = ip.IsIPv6Only(hostIps)
|
||||||
if hostIp.To4() != nil {
|
|
||||||
ipv6_only = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hostIp := hostIps[0]
|
hostIp := hostIps[0]
|
||||||
if hostIp.IsPrivate() {
|
if hostIp.IsPrivate() {
|
||||||
|
@ -221,7 +216,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
return errors.New("IP address is loopback address")
|
return errors.New("IP address is loopback address")
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = hostIp.String()
|
ipAddr = hostIp.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
row, err := r.db.Query(`
|
row, err := r.db.Query(`
|
||||||
|
@ -276,7 +271,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
port,
|
port,
|
||||||
is_tor,
|
is_tor,
|
||||||
"",
|
"",
|
||||||
ip,
|
ipAddr,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
time.Now().Unix(),
|
time.Now().Unix(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ditatompel/xmr-remote-nodes/internal/geo"
|
"github.com/ditatompel/xmr-remote-nodes/internal/ip/geo"
|
||||||
)
|
)
|
||||||
|
|
||||||
type QueryLogs struct {
|
type QueryLogs struct {
|
||||||
|
@ -308,7 +308,8 @@ func (r *moneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
city = ?,
|
city = ?,
|
||||||
last_checked = ?,
|
last_checked = ?,
|
||||||
last_check_status = ?,
|
last_check_status = ?,
|
||||||
cors_capable = ?
|
cors_capable = ?,
|
||||||
|
ipv6_only = ?
|
||||||
WHERE
|
WHERE
|
||||||
id = ?`
|
id = ?`
|
||||||
_, err := r.db.Exec(update,
|
_, err := r.db.Exec(update,
|
||||||
|
@ -330,6 +331,7 @@ func (r *moneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
now.Unix(),
|
now.Unix(),
|
||||||
statuses,
|
statuses,
|
||||||
report.Node.CORSCapable,
|
report.Node.CORSCapable,
|
||||||
|
report.Node.IPv6Only,
|
||||||
report.Node.ID)
|
report.Node.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Warn(err.Error())
|
slog.Warn(err.Error())
|
||||||
|
@ -341,10 +343,11 @@ func (r *moneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
is_available = ?,
|
is_available = ?,
|
||||||
uptime = ?,
|
uptime = ?,
|
||||||
last_checked = ?,
|
last_checked = ?,
|
||||||
last_check_status = ?
|
last_check_status = ?,
|
||||||
|
ipv6_only = ?
|
||||||
WHERE
|
WHERE
|
||||||
id = ?`
|
id = ?`
|
||||||
if _, err := r.db.Exec(u, 0, report.Node.Uptime, now.Unix(), statuses, report.Node.ID); err != nil {
|
if _, err := r.db.Exec(u, 0, report.Node.Uptime, now.Unix(), statuses, report.Node.IPv6Only, report.Node.ID); err != nil {
|
||||||
slog.Warn(err.Error())
|
slog.Warn(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue