testing client with unix sockets.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"git-indra.lan/indra-labs/indra/pkg/interrupt"
|
||||
log2 "git-indra.lan/indra-labs/indra/pkg/proc/log"
|
||||
"git-indra.lan/indra-labs/indra/pkg/rpc"
|
||||
"git-indra.lan/indra-labs/indra/pkg/rpc/client"
|
||||
"git-indra.lan/indra-labs/indra/pkg/seed"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -85,6 +86,8 @@ var seedCmd = &cobra.Command{
|
||||
log.I.Ln("rpc server is ready")
|
||||
}
|
||||
|
||||
client.Run(ctx)
|
||||
|
||||
//
|
||||
// P2P
|
||||
//
|
||||
|
||||
@@ -2,101 +2,64 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git-indra.lan/indra-labs/indra/pkg/rpc"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/tutorialedge/go-grpc-tutorial/chat"
|
||||
"golang.zx2c4.com/wireguard/conn"
|
||||
"golang.zx2c4.com/wireguard/device"
|
||||
"golang.zx2c4.com/wireguard/tun"
|
||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultClientIPAddr = netip.MustParseAddr("192.168.37.2")
|
||||
DefaultServerIPAddr = netip.MustParseAddr("192.168.37.1")
|
||||
)
|
||||
|
||||
type Peer struct {
|
||||
Endpoint multiaddr.Multiaddr
|
||||
PublicKey *rpc.RPCPublicKey
|
||||
PreSharedKey rpc.RPCPrivateKey
|
||||
KeepAliveInterval uint8
|
||||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
Key rpc.RPCPrivateKey
|
||||
Peer *Peer
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultClientConfig = &ClientConfig{
|
||||
Key: rpc.DecodePrivateKey("Aj9CfbE1pXEVxPfjSaTwdY3B4kYHbwsTSyT3nrc34ATN"),
|
||||
Peer: &Peer{
|
||||
Endpoint: multiaddr.StringCast("/ip4/127.0.0.1/udp/18222"),
|
||||
PublicKey: rpc.DecodePublicKey("G52UmsQpUmN2zFMkJaP9rwCvqQJzi1yHKA9RTrLJTk9f"),
|
||||
KeepAliveInterval: 5,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type RPCClient struct {
|
||||
device *device.Device
|
||||
tunnel tun.Device
|
||||
network *netstack.Net
|
||||
}
|
||||
dev *device.Device
|
||||
)
|
||||
|
||||
func (r *RPCClient) Start() {
|
||||
r.device.Up()
|
||||
}
|
||||
func getNetworkInstance(options *dialOptions) (err error) {
|
||||
|
||||
func (rpc *RPCClient) Stop() {
|
||||
rpc.device.Close()
|
||||
}
|
||||
|
||||
func NewClient(config *ClientConfig) (*RPCClient, error) {
|
||||
|
||||
var err error
|
||||
var r RPCClient
|
||||
|
||||
var tunnel tun.Device
|
||||
|
||||
if tunnel, r.network, err = netstack.CreateNetTUN([]netip.Addr{DefaultClientIPAddr}, []netip.Addr{}, 1420); check(err) {
|
||||
return nil, err
|
||||
if tunnel, network, err = netstack.CreateNetTUN([]netip.Addr{netip.MustParseAddr(options.peerRPCIP)}, []netip.Addr{}, 1420); check(err) {
|
||||
return
|
||||
}
|
||||
|
||||
r.device = device.NewDevice(tunnel, conn.NewDefaultBind(), device.NewLogger(device.LogLevelError, "client "))
|
||||
dev = device.NewDevice(tunnel, conn.NewDefaultBind(), device.NewLogger(device.LogLevelVerbose, "client "))
|
||||
|
||||
r.device.SetPrivateKey(config.Key.AsDeviceKey())
|
||||
dev.SetPrivateKey(options.key.AsDeviceKey())
|
||||
|
||||
deviceConf := "" +
|
||||
"public_key=" + config.Peer.PublicKey.HexString() + "\n" +
|
||||
"public_key=" + options.peerPubKey.HexString() + "\n" +
|
||||
"endpoint=0.0.0.0:18222" + "\n" +
|
||||
"allowed_ip=" + DefaultServerIPAddr.String() + "/32\n" +
|
||||
"persistent_keepalive_interval=" + strconv.Itoa(int(config.Peer.KeepAliveInterval)) + "\n"
|
||||
"allowed_ip=" + options.peerRPCIP + "/32\n" +
|
||||
"persistent_keepalive_interval=" + strconv.Itoa(options.keepAliveInterval) + "\n"
|
||||
|
||||
if err = r.device.IpcSet(deviceConf); check(err) {
|
||||
return nil, err
|
||||
if err = dev.IpcSet(deviceConf); check(err) {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Run(ctx context.Context) {
|
||||
|
||||
var err error
|
||||
var conn *grpc.ClientConn
|
||||
|
||||
//conn, err = grpc.Dial(
|
||||
// "unix:///tmp/indra.sock",
|
||||
// grpc.WithBlock(),
|
||||
// grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
conn, err = Dial("unix:///tmp/indra.sock")
|
||||
|
||||
//conn, err = DialContext(ctx,
|
||||
// "noise://0.0.0.0:18222",
|
||||
// WithPrivateKey("Aj9CfbE1pXEVxPfjSaTwdY3B4kYHbwsTSyT3nrc34ATN"),
|
||||
// WithPeer("G52UmsQpUmN2zFMkJaP9rwCvqQJzi1yHKA9RTrLJTk9f"),
|
||||
// WithKeepAliveInterval(5),
|
||||
//)
|
||||
|
||||
conn, err = grpc.DialContext(context.Background(),
|
||||
DefaultServerIPAddr.String()+":80",
|
||||
grpc.WithBlock(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithContextDialer(func(ctx context.Context, address string) (net.Conn, error) {
|
||||
return r.network.DialContext(ctx, "tcp4", address)
|
||||
}))
|
||||
if err != nil {
|
||||
check(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
c := chat.NewChatServiceClient(conn)
|
||||
|
||||
@@ -107,6 +70,4 @@ func NewClient(config *ClientConfig) (*RPCClient, error) {
|
||||
}
|
||||
|
||||
log.I.F(response.Body)
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
65
pkg/rpc/client/dailer_options.go
Normal file
65
pkg/rpc/client/dailer_options.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package client
|
||||
|
||||
import "git-indra.lan/indra-labs/indra/pkg/rpc"
|
||||
|
||||
// dialOptions configure a Dial call. dialOptions are set by the DialOption
|
||||
// values passed to Dial.
|
||||
type dialOptions struct {
|
||||
key rpc.RPCPrivateKey
|
||||
peerPubKey rpc.RPCPublicKey
|
||||
peerRPCIP string
|
||||
keepAliveInterval int
|
||||
}
|
||||
|
||||
// DialOption configures how we set up the connection.
|
||||
type DialOption interface {
|
||||
apply(*dialOptions)
|
||||
}
|
||||
|
||||
// funcDialOption wraps a function that modifies dialOptions into an
|
||||
// implementation of the DialOption interface.
|
||||
type funcDialOption struct {
|
||||
f func(*dialOptions)
|
||||
}
|
||||
|
||||
func (fdo *funcDialOption) apply(do *dialOptions) {
|
||||
fdo.f(do)
|
||||
}
|
||||
|
||||
func newFuncDialOption(f func(*dialOptions)) *funcDialOption {
|
||||
return &funcDialOption{
|
||||
f: f,
|
||||
}
|
||||
}
|
||||
|
||||
type joinDialOption struct {
|
||||
opts []DialOption
|
||||
}
|
||||
|
||||
func (jdo *joinDialOption) apply(do *dialOptions) {
|
||||
for _, opt := range jdo.opts {
|
||||
opt.apply(do)
|
||||
}
|
||||
}
|
||||
|
||||
func newJoinDialOption(opts ...DialOption) DialOption {
|
||||
return &joinDialOption{opts: opts}
|
||||
}
|
||||
|
||||
func WithKeepAliveInterval(seconds int) DialOption {
|
||||
return newFuncDialOption(func(o *dialOptions) {
|
||||
o.keepAliveInterval = seconds
|
||||
})
|
||||
}
|
||||
|
||||
func WithPeer(pubKey string) DialOption {
|
||||
return newFuncDialOption(func(o *dialOptions) {
|
||||
o.peerPubKey = rpc.DecodePublicKey(pubKey)
|
||||
})
|
||||
}
|
||||
|
||||
func WithPrivateKey(key string) DialOption {
|
||||
return newFuncDialOption(func(o *dialOptions) {
|
||||
o.key = rpc.DecodePrivateKey(key)
|
||||
})
|
||||
}
|
||||
47
pkg/rpc/client/dialer.go
Normal file
47
pkg/rpc/client/dialer.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
rpcEndpoint string = "192.168.37.1:80"
|
||||
)
|
||||
|
||||
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *grpc.ClientConn, err error) {
|
||||
|
||||
if strings.HasPrefix(target, "unix://") {
|
||||
return grpc.Dial(
|
||||
target,
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(target, "noise://") {
|
||||
return nil, errors.New("Unsupported protocol. Only unix:// or noise://")
|
||||
}
|
||||
|
||||
dialOpts := &dialOptions{peerRPCIP: "192.168.37.2"}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt.apply(dialOpts)
|
||||
}
|
||||
|
||||
getNetworkInstance(dialOpts)
|
||||
|
||||
return grpc.DialContext(ctx,
|
||||
rpcEndpoint,
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithContextDialer(func(ctx context.Context, address string) (net.Conn, error) {
|
||||
return network.DialContext(ctx, "tcp4", address)
|
||||
}))
|
||||
}
|
||||
|
||||
func Dial(target string, opts ...DialOption) (conn *grpc.ClientConn, err error) {
|
||||
return DialContext(context.Background(), target, opts...)
|
||||
}
|
||||
@@ -58,12 +58,17 @@ func configureTunnelKey() {
|
||||
func configureTunnelPort() {
|
||||
|
||||
if viper.GetUint16(tunPortFlag) != NullPort {
|
||||
|
||||
tunnelPort = int(viper.GetUint16(tunPortFlag))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
log.I.Ln("rpc tunnel port not provided, generating a random one.")
|
||||
|
||||
viper.Set(tunPortFlag, genRandomPort(10000))
|
||||
|
||||
tunnelPort = int(viper.GetUint16(tunPortFlag))
|
||||
}
|
||||
|
||||
func configurePeerWhitelist() {
|
||||
|
||||
@@ -101,11 +101,11 @@ func (sk *RPCPublicKey) Decode(key string) {
|
||||
copy(sk[:], base58.Decode(key))
|
||||
}
|
||||
|
||||
func DecodePublicKey(key string) *RPCPublicKey {
|
||||
func DecodePublicKey(key string) RPCPublicKey {
|
||||
|
||||
var pk RPCPublicKey
|
||||
|
||||
pk.Decode(key)
|
||||
|
||||
return &pk
|
||||
return pk
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user