disco: Peermap to Server

This commit is contained in:
rkonfj
2024-11-25 21:19:38 +08:00
parent 307e441fa1
commit b01e7cd34e
6 changed files with 30 additions and 54 deletions

View File

@@ -278,11 +278,7 @@ func (v *P2PVPN) listenPacketConn(ctx context.Context) (c *p2p.PacketConn, err e
if err != nil {
return
}
peermapURL, err := url.Parse(v.Config.Server)
if err != nil {
return
}
peermap, err := disco.NewPeermap(peermapURL, secretStore)
peermap, err := disco.NewServer(v.Config.Server, secretStore)
if err != nil {
return
}

View File

@@ -10,43 +10,29 @@ import (
"time"
)
type Peermap struct {
store SecretStore
server *url.URL
type Server struct {
Secret SecretStore
URL string
}
func NewPeermap(server *url.URL, store SecretStore) (*Peermap, error) {
func NewServer(serverURL string, store SecretStore) (*Server, error) {
if store == nil {
return nil, errors.New("secret store is required")
}
if server == nil {
return nil, errors.New("peermap server is required")
server, err := url.Parse(serverURL)
if err != nil {
return nil, err
}
if !slices.Contains([]string{"https", "wss", "http", "ws"}, server.Scheme) {
return nil, fmt.Errorf("invalid peermap server %s", server.String())
return nil, fmt.Errorf("unsupport server protocol: %s", server.String())
}
return &Peermap{
store: store,
server: server,
return &Server{
Secret: store,
URL: serverURL,
}, nil
}
func NewPeermapURL(serverURL string, store SecretStore) (*Peermap, error) {
sURL, err := url.Parse(serverURL)
if err != nil {
return nil, fmt.Errorf("invalid peermap url: %w", err)
}
return NewPeermap(sURL, store)
}
func (s *Peermap) SecretStore() SecretStore {
return s.store
}
func (s *Peermap) String() string {
return s.server.String()
}
type SecretStore interface {
NetworkSecret() (NetworkSecret, error)
UpdateNetworkSecret(NetworkSecret) error

View File

@@ -1,6 +1,7 @@
package ws
import (
"cmp"
"context"
"encoding/base64"
"encoding/json"
@@ -29,7 +30,7 @@ var (
type WSConn struct {
rawConn atomic.Pointer[websocket.Conn]
server *disco.Peermap
server *disco.Server
connectedServer string
peerID disco.PeerID
metadata url.Values
@@ -197,7 +198,7 @@ func (c *WSConn) Unregister(ctr disco.Controller) {
}
func (c *WSConn) dial(ctx context.Context, server string) error {
networkSecret, err := c.server.SecretStore().NetworkSecret()
networkSecret, err := cmp.Or[disco.SecretStore](c.server.Secret, &disco.NetworkSecret{}).NetworkSecret()
if err != nil {
return fmt.Errorf("get network secret failed: %w", err)
}
@@ -207,7 +208,7 @@ func (c *WSConn) dial(ctx context.Context, server string) error {
handshake.Set("X-Nonce", disco.NewNonce())
handshake.Set("X-Metadata", c.metadata.Encode())
if server == "" {
server = c.server.String()
server = c.server.URL
}
peermap, err := url.Parse(server)
if err != nil {
@@ -474,7 +475,7 @@ func (c *WSConn) writeWS(messageType int, data []byte) error {
func (c *WSConn) updateNetworkSecret(secret disco.NetworkSecret) {
for i := 0; i < 5; i++ {
if err := c.server.SecretStore().UpdateNetworkSecret(secret); err != nil {
if err := c.server.Secret.UpdateNetworkSecret(secret); err != nil {
slog.Error("[WS] NetworkSecretUpdate", "err", err)
time.Sleep(time.Second)
continue
@@ -484,7 +485,7 @@ func (c *WSConn) updateNetworkSecret(secret disco.NetworkSecret) {
slog.Error("[WS] NetworkSecretUpdate give up", "secret", secret)
}
func DialPeermap(ctx context.Context, server *disco.Peermap, peerID disco.PeerID, metadata url.Values) (*WSConn, error) {
func DialPeermap(ctx context.Context, server *disco.Server, peerID disco.PeerID, metadata url.Values) (*WSConn, error) {
wsConn := &WSConn{
server: server,
peerID: peerID,

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"net"
"net/url"
"github.com/sigcn/pg/disco"
"github.com/sigcn/pg/p2p"
@@ -18,12 +17,8 @@ type PublicNetwork struct {
}
func (pn *PublicNetwork) ListenPacket(udpPort int) (net.PacketConn, error) {
pmapURL, err := url.Parse(pn.Server)
if err != nil {
return nil, fmt.Errorf("invalid peermap URL: %w", err)
}
network := cmp.Or(pn.Name, "pubnet")
pmap, err := disco.NewPeermap(pmapURL, &disco.NetworkSecret{Network: network, Secret: network})
pmap, err := disco.NewServer(pn.Server, &disco.NetworkSecret{Network: network, Secret: network})
if err != nil {
return nil, fmt.Errorf("create peermap failed: %w", err)
}

View File

@@ -1,9 +1,11 @@
# p2p library
### Example
### Peer1 (act as echo server)
```go
peermapURL := "wss://synf.in/pg"
serverURL := "wss://synf.in/pg"
intent, err := network.JoinOIDC(oidc.ProviderGoogle, peermapURL)
if err != nil {
@@ -15,19 +17,14 @@ if err != nil {
panic(err)
}
pmServer, err := peer.NewPeermapURL(peermapURL, networkSecret)
if err != nil {
panic(err)
}
// peerID is a unique string (less than 256bytes)
packetConn, err := p2p.ListenPacket(pmServer, p2p.ListenPeerID("uniqueString"))
packetConn, err := p2p.ListenPacket(disco.NewServer(serverURL, networkSecret), p2p.ListenPeerID("uniqueString"))
if err != nil {
panic(err)
}
// unreliability echo server
buf := make([]byte, 1024)
buf := make([]byte, 1024)
for {
n, peerID, err := packetConn.ReadFrom(buf)
if err != nil {
@@ -41,11 +38,12 @@ for {
}
```
### Peer2
### Peer2
```go
...
packetConn, err := p2p.ListenPacket(pmServer)
packetConn, err := p2p.ListenPacket(disco.NewServer(serverURL, networkSecret))
if err != nil {
panic(err)
}

View File

@@ -388,12 +388,12 @@ func (c *PacketConn) runControlEventLoop() {
}
// ListenPacket same as ListenPacketContext, but no context required
func ListenPacket(peermap *disco.Peermap, opts ...Option) (*PacketConn, error) {
func ListenPacket(peermap *disco.Server, opts ...Option) (*PacketConn, error) {
return ListenPacketContext(context.Background(), peermap, opts...)
}
// ListenPacketContext listen the p2p network for read/write packets
func ListenPacketContext(ctx context.Context, peermap *disco.Peermap, opts ...Option) (*PacketConn, error) {
func ListenPacketContext(ctx context.Context, peermap *disco.Server, opts ...Option) (*PacketConn, error) {
id := make([]byte, 16)
rand.Read(id)
cfg := Config{