WIP
This commit is contained in:
@@ -16,13 +16,11 @@ type TX interface {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type Config struct {
|
||||
ConfigID int64
|
||||
HubAddress string
|
||||
VPNNetwork []byte
|
||||
Password []byte
|
||||
ConfigID int64
|
||||
Password []byte
|
||||
}
|
||||
|
||||
const Config_SelectQuery = "SELECT ConfigID,HubAddress,VPNNetwork,Password FROM config"
|
||||
const Config_SelectQuery = "SELECT ConfigID,Password FROM config"
|
||||
|
||||
func Config_Insert(
|
||||
tx TX,
|
||||
@@ -33,7 +31,7 @@ func Config_Insert(
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("INSERT INTO config(ConfigID,HubAddress,VPNNetwork,Password) VALUES(?,?,?,?)", row.ConfigID, row.HubAddress, row.VPNNetwork, row.Password)
|
||||
_, err = tx.Exec("INSERT INTO config(ConfigID,Password) VALUES(?,?)", row.ConfigID, row.Password)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -46,7 +44,7 @@ func Config_Update(
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := tx.Exec("UPDATE config SET HubAddress=?,VPNNetwork=? WHERE ConfigID=?", row.HubAddress, row.VPNNetwork, row.ConfigID)
|
||||
result, err := tx.Exec("UPDATE config SET Password=? WHERE ConfigID=?", row.Password, row.ConfigID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -74,7 +72,7 @@ func Config_UpdateFull(
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := tx.Exec("UPDATE config SET HubAddress=?,VPNNetwork=?,Password=? WHERE ConfigID=?", row.HubAddress, row.VPNNetwork, row.Password, row.ConfigID)
|
||||
result, err := tx.Exec("UPDATE config SET Password=? WHERE ConfigID=?", row.Password, row.ConfigID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -124,8 +122,8 @@ func Config_Get(
|
||||
err error,
|
||||
) {
|
||||
row = &Config{}
|
||||
r := tx.QueryRow("SELECT ConfigID,HubAddress,VPNNetwork,Password FROM config WHERE ConfigID=?", ConfigID)
|
||||
err = r.Scan(&row.ConfigID, &row.HubAddress, &row.VPNNetwork, &row.Password)
|
||||
r := tx.QueryRow("SELECT ConfigID,Password FROM config WHERE ConfigID=?", ConfigID)
|
||||
err = r.Scan(&row.ConfigID, &row.Password)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -139,7 +137,7 @@ func Config_GetWhere(
|
||||
) {
|
||||
row = &Config{}
|
||||
r := tx.QueryRow(query, args...)
|
||||
err = r.Scan(&row.ConfigID, &row.HubAddress, &row.VPNNetwork, &row.Password)
|
||||
err = r.Scan(&row.ConfigID, &row.Password)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -159,7 +157,7 @@ func Config_Iterate(
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
row := &Config{}
|
||||
err := rows.Scan(&row.ConfigID, &row.HubAddress, &row.VPNNetwork, &row.Password)
|
||||
err := rows.Scan(&row.ConfigID, &row.Password)
|
||||
if !yield(row, err) {
|
||||
return
|
||||
}
|
||||
@@ -302,11 +300,156 @@ func Session_List(
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Table: networks
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type Network struct {
|
||||
NetworkID int64
|
||||
Name string
|
||||
Network []byte
|
||||
}
|
||||
|
||||
const Network_SelectQuery = "SELECT NetworkID,Name,Network FROM networks"
|
||||
|
||||
func Network_Insert(
|
||||
tx TX,
|
||||
row *Network,
|
||||
) (err error) {
|
||||
Network_Sanitize(row)
|
||||
if err = Network_Validate(row); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("INSERT INTO networks(NetworkID,Name,Network) VALUES(?,?,?)", row.NetworkID, row.Name, row.Network)
|
||||
return err
|
||||
}
|
||||
|
||||
func Network_UpdateFull(
|
||||
tx TX,
|
||||
row *Network,
|
||||
) (err error) {
|
||||
Network_Sanitize(row)
|
||||
if err = Network_Validate(row); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := tx.Exec("UPDATE networks SET Name=?,Network=? WHERE NetworkID=?", row.Name, row.Network, row.NetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
switch n {
|
||||
case 0:
|
||||
return sql.ErrNoRows
|
||||
case 1:
|
||||
return nil
|
||||
default:
|
||||
panic("multiple rows updated")
|
||||
}
|
||||
}
|
||||
|
||||
func Network_Delete(
|
||||
tx TX,
|
||||
NetworkID int64,
|
||||
) (err error) {
|
||||
result, err := tx.Exec("DELETE FROM networks WHERE NetworkID=?", NetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
switch n {
|
||||
case 0:
|
||||
return sql.ErrNoRows
|
||||
case 1:
|
||||
return nil
|
||||
default:
|
||||
panic("multiple rows deleted")
|
||||
}
|
||||
}
|
||||
|
||||
func Network_Get(
|
||||
tx TX,
|
||||
NetworkID int64,
|
||||
) (
|
||||
row *Network,
|
||||
err error,
|
||||
) {
|
||||
row = &Network{}
|
||||
r := tx.QueryRow("SELECT NetworkID,Name,Network FROM networks WHERE NetworkID=?", NetworkID)
|
||||
err = r.Scan(&row.NetworkID, &row.Name, &row.Network)
|
||||
return
|
||||
}
|
||||
|
||||
func Network_GetWhere(
|
||||
tx TX,
|
||||
query string,
|
||||
args ...any,
|
||||
) (
|
||||
row *Network,
|
||||
err error,
|
||||
) {
|
||||
row = &Network{}
|
||||
r := tx.QueryRow(query, args...)
|
||||
err = r.Scan(&row.NetworkID, &row.Name, &row.Network)
|
||||
return
|
||||
}
|
||||
|
||||
func Network_Iterate(
|
||||
tx TX,
|
||||
query string,
|
||||
args ...any,
|
||||
) iter.Seq2[*Network, error] {
|
||||
rows, err := tx.Query(query, args...)
|
||||
if err != nil {
|
||||
return func(yield func(*Network, error) bool) {
|
||||
yield(nil, err)
|
||||
}
|
||||
}
|
||||
|
||||
return func(yield func(*Network, error) bool) {
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
row := &Network{}
|
||||
err := rows.Scan(&row.NetworkID, &row.Name, &row.Network)
|
||||
if !yield(row, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Network_List(
|
||||
tx TX,
|
||||
query string,
|
||||
args ...any,
|
||||
) (
|
||||
l []*Network,
|
||||
err error,
|
||||
) {
|
||||
for row, err := range Network_Iterate(tx, query, args...) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l = append(l, row)
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Table: peers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type Peer struct {
|
||||
NetworkID int64
|
||||
PeerIP byte
|
||||
Version int64
|
||||
APIKey string
|
||||
@@ -318,7 +461,7 @@ type Peer struct {
|
||||
PubSignKey []byte
|
||||
}
|
||||
|
||||
const Peer_SelectQuery = "SELECT PeerIP,Version,APIKey,Name,PublicIP,Port,Relay,PubKey,PubSignKey FROM peers"
|
||||
const Peer_SelectQuery = "SELECT NetworkID,PeerIP,Version,APIKey,Name,PublicIP,Port,Relay,PubKey,PubSignKey FROM peers"
|
||||
|
||||
func Peer_Insert(
|
||||
tx TX,
|
||||
@@ -329,7 +472,7 @@ func Peer_Insert(
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("INSERT INTO peers(PeerIP,Version,APIKey,Name,PublicIP,Port,Relay,PubKey,PubSignKey) VALUES(?,?,?,?,?,?,?,?,?)", row.PeerIP, row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Relay, row.PubKey, row.PubSignKey)
|
||||
_, err = tx.Exec("INSERT INTO peers(NetworkID,PeerIP,Version,APIKey,Name,PublicIP,Port,Relay,PubKey,PubSignKey) VALUES(?,?,?,?,?,?,?,?,?,?)", row.NetworkID, row.PeerIP, row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Relay, row.PubKey, row.PubSignKey)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -342,7 +485,7 @@ func Peer_Update(
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := tx.Exec("UPDATE peers SET Version=?,Name=?,PublicIP=?,Port=?,Relay=? WHERE PeerIP=?", row.Version, row.Name, row.PublicIP, row.Port, row.Relay, row.PeerIP)
|
||||
result, err := tx.Exec("UPDATE peers SET Version=?,Name=?,PublicIP=?,Port=?,Relay=? WHERE NetworkID=? AND PeerIP=?", row.Version, row.Name, row.PublicIP, row.Port, row.Relay, row.NetworkID, row.PeerIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -370,7 +513,7 @@ func Peer_UpdateFull(
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := tx.Exec("UPDATE peers SET Version=?,APIKey=?,Name=?,PublicIP=?,Port=?,Relay=?,PubKey=?,PubSignKey=? WHERE PeerIP=?", row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Relay, row.PubKey, row.PubSignKey, row.PeerIP)
|
||||
result, err := tx.Exec("UPDATE peers SET Version=?,APIKey=?,Name=?,PublicIP=?,Port=?,Relay=?,PubKey=?,PubSignKey=? WHERE NetworkID=? AND PeerIP=?", row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Relay, row.PubKey, row.PubSignKey, row.NetworkID, row.PeerIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -391,9 +534,10 @@ func Peer_UpdateFull(
|
||||
|
||||
func Peer_Delete(
|
||||
tx TX,
|
||||
NetworkID int64,
|
||||
PeerIP byte,
|
||||
) (err error) {
|
||||
result, err := tx.Exec("DELETE FROM peers WHERE PeerIP=?", PeerIP)
|
||||
result, err := tx.Exec("DELETE FROM peers WHERE NetworkID=? AND PeerIP=?", NetworkID, PeerIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -414,14 +558,15 @@ func Peer_Delete(
|
||||
|
||||
func Peer_Get(
|
||||
tx TX,
|
||||
NetworkID int64,
|
||||
PeerIP byte,
|
||||
) (
|
||||
row *Peer,
|
||||
err error,
|
||||
) {
|
||||
row = &Peer{}
|
||||
r := tx.QueryRow("SELECT PeerIP,Version,APIKey,Name,PublicIP,Port,Relay,PubKey,PubSignKey FROM peers WHERE PeerIP=?", PeerIP)
|
||||
err = r.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Relay, &row.PubKey, &row.PubSignKey)
|
||||
r := tx.QueryRow("SELECT NetworkID,PeerIP,Version,APIKey,Name,PublicIP,Port,Relay,PubKey,PubSignKey FROM peers WHERE NetworkID=? AND PeerIP=?", NetworkID, PeerIP)
|
||||
err = r.Scan(&row.NetworkID, &row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Relay, &row.PubKey, &row.PubSignKey)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -435,7 +580,7 @@ func Peer_GetWhere(
|
||||
) {
|
||||
row = &Peer{}
|
||||
r := tx.QueryRow(query, args...)
|
||||
err = r.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Relay, &row.PubKey, &row.PubSignKey)
|
||||
err = r.Scan(&row.NetworkID, &row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Relay, &row.PubKey, &row.PubSignKey)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -455,7 +600,7 @@ func Peer_Iterate(
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
row := &Peer{}
|
||||
err := rows.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Relay, &row.PubKey, &row.PubSignKey)
|
||||
err := rows.Scan(&row.NetworkID, &row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Relay, &row.PubKey, &row.PubSignKey)
|
||||
if !yield(row, err) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,35 +3,21 @@ package db
|
||||
import (
|
||||
"errors"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidIP = errors.New("invalid IP")
|
||||
ErrInvalidPort = errors.New("invalid port")
|
||||
ErrInvalidIP = errors.New("invalid IP")
|
||||
ErrNonPrivateIP = errors.New("non-private IP")
|
||||
ErrInvalidPort = errors.New("invalid port")
|
||||
ErrInvalidNetName = errors.New("invalid network name")
|
||||
ErrInvalidPeerName = errors.New("invalid peer name")
|
||||
)
|
||||
|
||||
func Config_Sanitize(c *Config) {
|
||||
if u, err := url.Parse(c.HubAddress); err == nil {
|
||||
c.HubAddress = u.String()
|
||||
}
|
||||
|
||||
if addr, ok := netip.AddrFromSlice(c.VPNNetwork); ok {
|
||||
c.VPNNetwork = addr.AsSlice()
|
||||
}
|
||||
}
|
||||
|
||||
func Config_Validate(c *Config) error {
|
||||
if _, err := url.Parse(c.HubAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, ok := netip.AddrFromSlice(c.VPNNetwork)
|
||||
if !ok || !addr.Is4() || addr.As4()[3] != 0 || addr.As4()[0] == 0 {
|
||||
return ErrInvalidIP
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -42,6 +28,42 @@ func Session_Validate(s *Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Network_Sanitize(n *Network) {
|
||||
n.Name = strings.TrimSpace(n.Name)
|
||||
|
||||
if addr, ok := netip.AddrFromSlice(n.Network); ok {
|
||||
n.Network = addr.AsSlice()
|
||||
}
|
||||
}
|
||||
|
||||
func Network_Validate(c *Network) error {
|
||||
// 16 bytes is linux limit for network interface names.
|
||||
if len(c.Name) == 0 || len(c.Name) > 16 {
|
||||
return ErrInvalidNetName
|
||||
}
|
||||
|
||||
for _, c := range c.Name {
|
||||
if c >= 'a' && c <= 'z' {
|
||||
continue
|
||||
}
|
||||
if c >= '0' && c <= '9' {
|
||||
continue
|
||||
}
|
||||
return ErrInvalidNetName
|
||||
}
|
||||
|
||||
addr, ok := netip.AddrFromSlice(c.Network)
|
||||
if !ok || !addr.Is4() || addr.As4()[3] != 0 || addr.As4()[0] == 0 {
|
||||
return ErrInvalidIP
|
||||
}
|
||||
|
||||
if !addr.IsPrivate() {
|
||||
return ErrNonPrivateIP
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Peer_Sanitize(p *Peer) {
|
||||
p.Name = strings.TrimSpace(p.Name)
|
||||
if len(p.PublicIP) != 0 {
|
||||
@@ -65,5 +87,20 @@ func Peer_Validate(p *Peer) error {
|
||||
if p.Port == 0 {
|
||||
return ErrInvalidPort
|
||||
}
|
||||
|
||||
for _, c := range p.Name {
|
||||
if c >= 'a' && c <= 'z' {
|
||||
continue
|
||||
}
|
||||
if c >= '0' && c <= '9' {
|
||||
continue
|
||||
}
|
||||
if c == '.' || c == '-' || c == '_' {
|
||||
continue
|
||||
}
|
||||
|
||||
return ErrInvalidPeerName
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
TABLE config OF Config (
|
||||
ConfigID int64 PK,
|
||||
HubAddress string,
|
||||
VPNNetwork []byte,
|
||||
Password []byte NoUpdate
|
||||
Password []byte
|
||||
);
|
||||
|
||||
TABLE sessions OF Session NoUpdate (
|
||||
@@ -13,7 +11,14 @@ TABLE sessions OF Session NoUpdate (
|
||||
LastSeenAt int64
|
||||
);
|
||||
|
||||
TABLE networks OF Network (
|
||||
NetworkID int64 PK,
|
||||
Name string NoUpdate,
|
||||
Network []byte NoUpdate
|
||||
);
|
||||
|
||||
TABLE peers OF Peer (
|
||||
NetworkID int64 PK,
|
||||
PeerIP byte PK,
|
||||
Version int64,
|
||||
APIKey string NoUpdate,
|
||||
|
||||
@@ -26,16 +26,9 @@ func Session_DeleteBefore(
|
||||
return err
|
||||
}
|
||||
|
||||
func Config_UpdatePassword(
|
||||
tx TX,
|
||||
pwdHash []byte,
|
||||
) (err error) {
|
||||
_, err = tx.Exec("UPDATE config SET Password=? WHERE ConfigID=1", pwdHash)
|
||||
return err
|
||||
}
|
||||
|
||||
func Peer_ListAll(tx TX) ([]*Peer, error) {
|
||||
return Peer_List(tx, Peer_SelectQuery)
|
||||
func Peer_ListAll(tx TX, networkID int64) ([]*Peer, error) {
|
||||
const query = Peer_SelectQuery + ` WHERE NetworkID=? ORDER BY PeerIP ASC`
|
||||
return Peer_List(tx, query, networkID)
|
||||
}
|
||||
|
||||
func Peer_GetByAPIKey(tx TX, apiKey string) (*Peer, error) {
|
||||
@@ -45,7 +38,8 @@ func Peer_GetByAPIKey(tx TX, apiKey string) (*Peer, error) {
|
||||
apiKey)
|
||||
}
|
||||
|
||||
func Peer_Exists(tx TX, ip byte) (exists bool, err error) {
|
||||
err = tx.QueryRow(`SELECT EXISTS(SELECT 1 FROM peers WHERE PeerIP=?)`, ip).Scan(&exists)
|
||||
func Peer_Exists(tx TX, networkID int64, ip byte) (exists bool, err error) {
|
||||
const query = `SELECT EXISTS(SELECT 1 FROM peers WHERE NetworkID=? AND PeerIP=?)`
|
||||
err = tx.QueryRow(query, networkID, ip).Scan(&exists)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user