testing client with unix sockets.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"git-indra.lan/indra-labs/indra/pkg/interrupt"
|
"git-indra.lan/indra-labs/indra/pkg/interrupt"
|
||||||
log2 "git-indra.lan/indra-labs/indra/pkg/proc/log"
|
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"
|
||||||
|
"git-indra.lan/indra-labs/indra/pkg/rpc/client"
|
||||||
"git-indra.lan/indra-labs/indra/pkg/seed"
|
"git-indra.lan/indra-labs/indra/pkg/seed"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"github.com/multiformats/go-multiaddr"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -85,6 +86,8 @@ var seedCmd = &cobra.Command{
|
|||||||
log.I.Ln("rpc server is ready")
|
log.I.Ln("rpc server is ready")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.Run(ctx)
|
||||||
|
|
||||||
//
|
//
|
||||||
// P2P
|
// P2P
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -2,101 +2,64 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"git-indra.lan/indra-labs/indra/pkg/rpc"
|
|
||||||
"github.com/multiformats/go-multiaddr"
|
|
||||||
"github.com/tutorialedge/go-grpc-tutorial/chat"
|
"github.com/tutorialedge/go-grpc-tutorial/chat"
|
||||||
"golang.zx2c4.com/wireguard/conn"
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
"golang.zx2c4.com/wireguard/tun/netstack"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
|
||||||
"net"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultClientIPAddr = netip.MustParseAddr("192.168.37.2")
|
tunnel tun.Device
|
||||||
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
|
|
||||||
network *netstack.Net
|
network *netstack.Net
|
||||||
}
|
dev *device.Device
|
||||||
|
)
|
||||||
|
|
||||||
func (r *RPCClient) Start() {
|
func getNetworkInstance(options *dialOptions) (err error) {
|
||||||
r.device.Up()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rpc *RPCClient) Stop() {
|
if tunnel, network, err = netstack.CreateNetTUN([]netip.Addr{netip.MustParseAddr(options.peerRPCIP)}, []netip.Addr{}, 1420); check(err) {
|
||||||
rpc.device.Close()
|
return
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 := "" +
|
deviceConf := "" +
|
||||||
"public_key=" + config.Peer.PublicKey.HexString() + "\n" +
|
"public_key=" + options.peerPubKey.HexString() + "\n" +
|
||||||
"endpoint=0.0.0.0:18222" + "\n" +
|
"endpoint=0.0.0.0:18222" + "\n" +
|
||||||
"allowed_ip=" + DefaultServerIPAddr.String() + "/32\n" +
|
"allowed_ip=" + options.peerRPCIP + "/32\n" +
|
||||||
"persistent_keepalive_interval=" + strconv.Itoa(int(config.Peer.KeepAliveInterval)) + "\n"
|
"persistent_keepalive_interval=" + strconv.Itoa(options.keepAliveInterval) + "\n"
|
||||||
|
|
||||||
if err = r.device.IpcSet(deviceConf); check(err) {
|
if err = dev.IpcSet(deviceConf); check(err) {
|
||||||
return nil, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run(ctx context.Context) {
|
||||||
|
|
||||||
|
var err error
|
||||||
var conn *grpc.ClientConn
|
var conn *grpc.ClientConn
|
||||||
|
|
||||||
//conn, err = grpc.Dial(
|
conn, err = Dial("unix:///tmp/indra.sock")
|
||||||
// "unix:///tmp/indra.sock",
|
|
||||||
// grpc.WithBlock(),
|
//conn, err = DialContext(ctx,
|
||||||
// grpc.WithTransportCredentials(insecure.NewCredentials()),
|
// "noise://0.0.0.0:18222",
|
||||||
|
// WithPrivateKey("Aj9CfbE1pXEVxPfjSaTwdY3B4kYHbwsTSyT3nrc34ATN"),
|
||||||
|
// WithPeer("G52UmsQpUmN2zFMkJaP9rwCvqQJzi1yHKA9RTrLJTk9f"),
|
||||||
|
// WithKeepAliveInterval(5),
|
||||||
//)
|
//)
|
||||||
|
|
||||||
conn, err = grpc.DialContext(context.Background(),
|
if err != nil {
|
||||||
DefaultServerIPAddr.String()+":80",
|
check(err)
|
||||||
grpc.WithBlock(),
|
os.Exit(1)
|
||||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
}
|
||||||
grpc.WithContextDialer(func(ctx context.Context, address string) (net.Conn, error) {
|
|
||||||
return r.network.DialContext(ctx, "tcp4", address)
|
|
||||||
}))
|
|
||||||
|
|
||||||
c := chat.NewChatServiceClient(conn)
|
c := chat.NewChatServiceClient(conn)
|
||||||
|
|
||||||
@@ -107,6 +70,4 @@ func NewClient(config *ClientConfig) (*RPCClient, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.I.F(response.Body)
|
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() {
|
func configureTunnelPort() {
|
||||||
|
|
||||||
if viper.GetUint16(tunPortFlag) != NullPort {
|
if viper.GetUint16(tunPortFlag) != NullPort {
|
||||||
|
|
||||||
|
tunnelPort = int(viper.GetUint16(tunPortFlag))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.I.Ln("rpc tunnel port not provided, generating a random one.")
|
log.I.Ln("rpc tunnel port not provided, generating a random one.")
|
||||||
|
|
||||||
viper.Set(tunPortFlag, genRandomPort(10000))
|
viper.Set(tunPortFlag, genRandomPort(10000))
|
||||||
|
|
||||||
|
tunnelPort = int(viper.GetUint16(tunPortFlag))
|
||||||
}
|
}
|
||||||
|
|
||||||
func configurePeerWhitelist() {
|
func configurePeerWhitelist() {
|
||||||
|
|||||||
@@ -101,11 +101,11 @@ func (sk *RPCPublicKey) Decode(key string) {
|
|||||||
copy(sk[:], base58.Decode(key))
|
copy(sk[:], base58.Decode(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecodePublicKey(key string) *RPCPublicKey {
|
func DecodePublicKey(key string) RPCPublicKey {
|
||||||
|
|
||||||
var pk RPCPublicKey
|
var pk RPCPublicKey
|
||||||
|
|
||||||
pk.Decode(key)
|
pk.Decode(key)
|
||||||
|
|
||||||
return &pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user