mirror of
https://github.com/ditatompel/xmr-remote-nodes.git
synced 2024-11-16 17:07:36 +00:00
feat: Record node ip addresses #84
For future use investigations about "suspicious" nodes. #105
This commit is contained in:
parent
0e3dc04af8
commit
f6b048b017
6 changed files with 69 additions and 4 deletions
|
@ -338,6 +338,7 @@ func (p *proberClient) reportResult(node monero.Node, tookTime float64) error {
|
||||||
if !node.IsTor {
|
if !node.IsTor {
|
||||||
if hostIps, err := net.LookupIP(node.Hostname); err == nil {
|
if hostIps, err := net.LookupIP(node.Hostname); err == nil {
|
||||||
node.IPv6Only = ip.IsIPv6Only(hostIps)
|
node.IPv6Only = ip.IsIPv6Only(hostIps)
|
||||||
|
node.IPAddresses = ip.SliceToString(hostIps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -261,11 +261,14 @@ func v3(db *DB) error {
|
||||||
slog.Debug("[DB] Migrating database schema version 3")
|
slog.Debug("[DB] Migrating database schema version 3")
|
||||||
|
|
||||||
// table: tbl_node
|
// table: tbl_node
|
||||||
slog.Debug("[DB] Adding ipv6_only column to tbl_node")
|
// TODO: Remove IF NOT EXISTS SQL statement below after merging to main
|
||||||
|
// branch. The statement only to accomodate commit 518d4b4 so future main
|
||||||
|
// branch keep on schema version 3.
|
||||||
|
slog.Debug("[DB] Adding additional columns to tbl_node")
|
||||||
_, err := db.Exec(`
|
_, err := db.Exec(`
|
||||||
ALTER TABLE tbl_node
|
ALTER TABLE tbl_node
|
||||||
ADD ipv6_only TINYINT(1) UNSIGNED NOT NULL DEFAULT '0'
|
ADD COLUMN IF NOT EXISTS ipv6_only TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER cors_capable,
|
||||||
AFTER cors_capable;`)
|
ADD COLUMN ip_addresses TEXT NOT NULL DEFAULT '' AFTER cors_capable;`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ip
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsIPv6Only returns true if all given IPs are IPv6
|
// IsIPv6Only returns true if all given IPs are IPv6
|
||||||
|
@ -14,3 +15,14 @@ func IsIPv6Only(ips []net.IP) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceToString converts []net.IP to a string separated by comma.
|
||||||
|
// If the separator is empty, it defaults to ",".
|
||||||
|
func SliceToString(ips []net.IP) string {
|
||||||
|
r := make([]string, len(ips))
|
||||||
|
for i, j := range ips {
|
||||||
|
r[i] = j.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(r, ",")
|
||||||
|
}
|
||||||
|
|
|
@ -44,3 +44,43 @@ func TestIsIPv6Only(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Single test: go test ./internal/ip -bench TestSliceToString -benchmem -run=^$ -v
|
||||||
|
func TestSliceToString(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ips []net.IP
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "IPv4",
|
||||||
|
ips: []net.IP{
|
||||||
|
net.ParseIP("1.1.1.1"),
|
||||||
|
},
|
||||||
|
want: "1.1.1.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6",
|
||||||
|
ips: []net.IP{
|
||||||
|
net.ParseIP("2606:4700::6810:85e5"),
|
||||||
|
},
|
||||||
|
want: "2606:4700::6810:85e5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6 and IPv4",
|
||||||
|
ips: []net.IP{
|
||||||
|
net.ParseIP("1.1.1.1"),
|
||||||
|
net.ParseIP("2606:4700::6810:85e5"),
|
||||||
|
},
|
||||||
|
want: "1.1.1.1,2606:4700::6810:85e5",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := SliceToString(tt.ips); got != tt.want {
|
||||||
|
t.Errorf("SliceToString() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ type Node struct {
|
||||||
LastCheckStatus types.JSONText `json:"last_check_statuses" db:"last_check_status"`
|
LastCheckStatus types.JSONText `json:"last_check_statuses" db:"last_check_status"`
|
||||||
CORSCapable bool `json:"cors" db:"cors_capable"`
|
CORSCapable bool `json:"cors" db:"cors_capable"`
|
||||||
IPv6Only bool `json:"ipv6_only" db:"ipv6_only"`
|
IPv6Only bool `json:"ipv6_only" db:"ipv6_only"`
|
||||||
|
IPAddresses string `json:"ip_addresses" db:"ip_addresses"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get node from database by id
|
// Get node from database by id
|
||||||
|
@ -198,6 +199,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ipAddr := ""
|
ipAddr := ""
|
||||||
|
ips := ""
|
||||||
ipv6_only := false
|
ipv6_only := false
|
||||||
|
|
||||||
if !is_tor {
|
if !is_tor {
|
||||||
|
@ -217,6 +219,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ipAddr = hostIp.String()
|
ipAddr = hostIp.String()
|
||||||
|
ips = ip.SliceToString(hostIps)
|
||||||
}
|
}
|
||||||
|
|
||||||
row, err := r.db.Query(`
|
row, err := r.db.Query(`
|
||||||
|
@ -251,6 +254,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
date_entered,
|
date_entered,
|
||||||
last_checked,
|
last_checked,
|
||||||
last_check_status,
|
last_check_status,
|
||||||
|
ip_addresses,
|
||||||
ipv6_only
|
ipv6_only
|
||||||
) VALUES (
|
) VALUES (
|
||||||
?,
|
?,
|
||||||
|
@ -264,6 +268,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
?,
|
?,
|
||||||
?,
|
?,
|
||||||
?,
|
?,
|
||||||
|
?,
|
||||||
?
|
?
|
||||||
)`,
|
)`,
|
||||||
protocol,
|
protocol,
|
||||||
|
@ -277,6 +282,7 @@ func (r *moneroRepo) Add(protocol string, hostname string, port uint) error {
|
||||||
time.Now().Unix(),
|
time.Now().Unix(),
|
||||||
0,
|
0,
|
||||||
string(statusDb),
|
string(statusDb),
|
||||||
|
ips,
|
||||||
ipv6_only)
|
ipv6_only)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -309,6 +309,7 @@ func (r *moneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
last_checked = ?,
|
last_checked = ?,
|
||||||
last_check_status = ?,
|
last_check_status = ?,
|
||||||
cors_capable = ?,
|
cors_capable = ?,
|
||||||
|
ip_addresses = ?,
|
||||||
ipv6_only = ?
|
ipv6_only = ?
|
||||||
WHERE
|
WHERE
|
||||||
id = ?`
|
id = ?`
|
||||||
|
@ -331,6 +332,7 @@ func (r *moneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
now.Unix(),
|
now.Unix(),
|
||||||
statuses,
|
statuses,
|
||||||
report.Node.CORSCapable,
|
report.Node.CORSCapable,
|
||||||
|
report.Node.IPAddresses,
|
||||||
report.Node.IPv6Only,
|
report.Node.IPv6Only,
|
||||||
report.Node.ID)
|
report.Node.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -344,10 +346,11 @@ func (r *moneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
uptime = ?,
|
uptime = ?,
|
||||||
last_checked = ?,
|
last_checked = ?,
|
||||||
last_check_status = ?,
|
last_check_status = ?,
|
||||||
|
ip_addresses = ?,
|
||||||
ipv6_only = ?
|
ipv6_only = ?
|
||||||
WHERE
|
WHERE
|
||||||
id = ?`
|
id = ?`
|
||||||
if _, err := r.db.Exec(u, 0, report.Node.Uptime, now.Unix(), statuses, report.Node.IPv6Only, report.Node.ID); err != nil {
|
if _, err := r.db.Exec(u, 0, report.Node.Uptime, now.Unix(), statuses, report.Node.IPAddresses, report.Node.IPv6Only, report.Node.ID); err != nil {
|
||||||
slog.Warn(err.Error())
|
slog.Warn(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue