Skip to content

Commit

Permalink
sdk/js, net, node, peer, provider: initial work for allowing for anon…
Browse files Browse the repository at this point in the history
…ymously-identified microservices
  • Loading branch information
lithdew committed Jun 13, 2020
1 parent 22a6521 commit 25b423e
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 53 deletions.
56 changes: 39 additions & 17 deletions net.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ func releaseContext(ctx *Context) { contextPool.Put(ctx) }

type Handler func(ctx *Context) []byte

var DefaultHandler Handler = func(ctx *Context) []byte { return nil }

type Opcode = uint8

const (
Expand All @@ -55,7 +53,7 @@ type PayloadPacket struct {
}

type HandshakePacket struct {
ID kademlia.ID
ID *kademlia.ID
Services []string
Signature kademlia.Signature
}
Expand All @@ -69,23 +67,42 @@ func (h HandshakePacket) AppendPayloadTo(dst []byte) []byte {
}

func (h HandshakePacket) AppendTo(dst []byte) []byte {
dst = h.ID.AppendTo(dst)
if h.ID != nil {
dst = append(dst, 1)
dst = h.ID.AppendTo(dst)
} else {
dst = append(dst, 0)
}
dst = append(dst, uint8(len(h.Services)))
for _, service := range h.Services {
dst = append(dst, uint8(len(service)))
dst = append(dst, service...)
}
dst = append(dst, h.Signature[:]...)
if h.ID != nil {
dst = append(dst, h.Signature[:]...)
}
return dst
}

func UnmarshalHandshakePacket(buf []byte) (HandshakePacket, error) {
var pkt HandshakePacket
id, buf, err := kademlia.UnmarshalID(buf)
if err != nil {
return pkt, err

if len(buf) < 1 {
return pkt, io.ErrUnexpectedEOF
}

hasID := buf[0] == 1
buf = buf[1:]

if hasID {
id, leftover, err := kademlia.UnmarshalID(buf)
if err != nil {
return pkt, err
}
pkt.ID = &id

buf = leftover
}
pkt.ID = id

if len(buf) < 1 {
return pkt, io.ErrUnexpectedEOF
Expand All @@ -111,19 +128,24 @@ func UnmarshalHandshakePacket(buf []byte) (HandshakePacket, error) {
buf = buf[size:]
}

if len(buf) < kademlia.SizeSignature {
return pkt, io.ErrUnexpectedEOF
}
if hasID {
if len(buf) < kademlia.SizeSignature {
return pkt, io.ErrUnexpectedEOF
}

pkt.Signature, buf = *(*kademlia.Signature)(unsafe.Pointer(&((buf[:kademlia.SizeSignature])[0]))),
buf[kademlia.SizeSignature:]
pkt.Signature, buf = *(*kademlia.Signature)(unsafe.Pointer(&((buf[:kademlia.SizeSignature])[0]))),
buf[kademlia.SizeSignature:]
}

return pkt, nil
}

func (h HandshakePacket) Validate(dst []byte) error {
if err := h.ID.Validate(); err != nil {
return err
if h.ID != nil {
err := h.ID.Validate()
if err != nil {
return err
}
}

for _, service := range h.Services {
Expand All @@ -136,7 +158,7 @@ func (h HandshakePacket) Validate(dst []byte) error {
}
}

if !h.Signature.Verify(h.ID.Pub, h.AppendPayloadTo(dst)) {
if h.ID != nil && !h.Signature.Verify(h.ID.Pub, h.AppendPayloadTo(dst)) {
return errors.New("signature is malformed")
}

Expand Down
2 changes: 1 addition & 1 deletion node.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (n *Node) handleHandshakePacket(ctx *monte.Context, body []byte) error {
fmt.Printf("%s has connected to you. Services: %s\n", provider.Addr(), provider.Services())

pkt = HandshakePacket{
ID: n.id,
ID: &n.id,
Services: n.Services(),
}
pkt.Signature = n.sec.Sign(pkt.AppendPayloadTo(body[:0]))
Expand Down
4 changes: 2 additions & 2 deletions peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (p *Peer) Dial() {
defer close(p.ready)

pkt := HandshakePacket{
ID: p.node.id,
ID: &p.node.id,
Services: p.node.Services(),
}
pkt.Signature = p.node.sec.Sign(pkt.AppendPayloadTo(nil))
Expand Down Expand Up @@ -126,7 +126,7 @@ func (p *Peer) Dial() {
return
}

p.id = pkt.ID
p.id = *pkt.ID
p.svcs = pkt.Services

fmt.Printf("You are now connected to %s. Services: %s\n", p.addr, p.svcs)
Expand Down
12 changes: 9 additions & 3 deletions provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ import (
)

type Provider struct {
id kademlia.ID
id *kademlia.ID
conn *monte.Conn
services map[string]struct{}
}

func (p *Provider) Addr() string { return Addr(p.id.Host, p.id.Port) }
func (p *Provider) Addr() string {
if p.id != nil {
return Addr(p.id.Host, p.id.Port)
} else {
return "???"
}
}

func (p *Provider) Services() []string {
services := make([]string, 0, len(p.services))
Expand Down Expand Up @@ -71,7 +77,7 @@ func (p *Providers) getProviders(services ...string) []*Provider {
return providers
}

func (p *Providers) register(conn *monte.Conn, id kademlia.ID, services []string) *Provider {
func (p *Providers) register(conn *monte.Conn, id *kademlia.ID, services []string) *Provider {
p.Lock()
defer p.Unlock()

Expand Down
17 changes: 9 additions & 8 deletions ts/flatend.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ const OPCODE_REQUEST = 1;
class Flatend {
/**
*
* @param {ID} [id]
* @param {nacl.SignKeyPair} [keys]
* @param {{id: ID, keys: nacl.SignKeyPair} | null} [opts]
*/
constructor({id, keys}) {
constructor(opts) {
this.listeners = new EventEmitter();
this.self = id;
this.keys = keys;

if (opts?.id && opts?.keys) {
this.self = opts.id;
this.keys = opts.keys;
}
}

/**
Expand Down Expand Up @@ -93,9 +95,8 @@ class Flatend {
}

async handshake() {
let packet = new HandshakePacket(
{id: this.self, services: [...this.listeners.eventNames()]}
).sign(this.keys.secretKey);
let packet = new HandshakePacket({id: this.self, services: [...this.listeners.eventNames()]});
if (this.self) packet = packet.sign(this.keys.secretKey);

packet = HandshakePacket.decode(await this.request(OPCODE_HANDSHAKE, packet.encode()));

Expand Down
21 changes: 15 additions & 6 deletions ts/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import nacl from "tweetnacl";
import {Flatend} from "./flatend.js";
import {ID} from "./packet.js";
import ip from "ip";

const getTodos = data => {
Expand All @@ -15,10 +13,7 @@ const getTodos = data => {
}

async function main() {
const keys = nacl.sign.keyPair();
const id = new ID({publicKey: keys.publicKey, host: "127.0.0.1", port: 12000});

const backend = new Flatend({id, keys});
const backend = new Flatend();

backend.register("all_todos", () => "hello world!");
backend.register("get_todos", getTodos);
Expand All @@ -28,4 +23,18 @@ async function main() {
console.log(`Successfully connected to ${ip.toString(backend.id.host, 12, 4)}:${backend.id.port}.`);
}

// async function main() {
// const keys = nacl.sign.keyPair();
// const id = new ID({publicKey: keys.publicKey, host: "127.0.0.1", port: 12000});
//
// const backend = new Flatend({id, keys});
//
// backend.register("all_todos", () => "hello world!");
// backend.register("get_todos", getTodos);
//
// await backend.start({port: 9000, host: "127.0.0.1"});
//
// console.log(`Successfully connected to ${ip.toString(backend.id.host, 12, 4)}:${backend.id.port}.`);
// }

main().catch(err => console.error(err));
56 changes: 40 additions & 16 deletions ts/packet.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ class ID {


class HandshakePacket {
constructor({id = new ID({}), services = [], signature = Buffer.alloc(nacl.sign.signatureLength)}) {
/**
*
* @param {ID | null}id
* @param {[]} services
* @param {Buffer} signature
*/
constructor({id = null, services = [], signature = Buffer.alloc(nacl.sign.signatureLength)}) {
this.id = id;
this.services = services;
this.signature = signature;
Expand All @@ -101,11 +107,22 @@ class HandshakePacket {
Buffer.of(this.services.length),
);

return Buffer.concat([
this.id.encode(),
services,
this.signature,
]);
const bufs = [];

if (this.id) {
bufs.push(Buffer.of(1))
bufs.push(this.id.encode())
} else {
bufs.push(Buffer.of(0))
}

bufs.push(services);

if (this.id) {
bufs.push(this.signature);
}

return Buffer.concat(bufs);
}

/**
Expand All @@ -114,15 +131,22 @@ class HandshakePacket {
* @return {HandshakePacket}
*/
static decode(buf) {
let decoded = ID.decode(buf);
const hasID = buf.readUInt8();
buf = buf.slice(1);

let id = decoded[0];
buf = decoded[1];
const packet = new HandshakePacket({});

if (hasID) {
let decoded = ID.decode(buf);

packet.id = decoded[0];
buf = decoded[1];
}

const size = buf.readUInt8();
buf = buf.slice(1);

const services = [...Array(size)].map(() => {
packet.services = [...Array(size)].map(() => {
const size = buf.readUInt8();
buf = buf.slice(1);

Expand All @@ -132,13 +156,13 @@ class HandshakePacket {
return service.toString("utf8");
});

const signature = buf.slice(0, nacl.sign.signatureLength);
buf = buf.slice(nacl.sign.signatureLength);
if (hasID) {
packet.signature = buf.slice(0, nacl.sign.signatureLength);
buf = buf.slice(nacl.sign.signatureLength);

const packet = new HandshakePacket({id, services, signature});

if (!nacl.sign.detached.verify(packet.payload, packet.signature, packet.id.publicKey)) {
throw new Error(`Signature specified in handshake packet is invalid.`)
if (!nacl.sign.detached.verify(packet.payload, packet.signature, packet.id.publicKey)) {
throw new Error(`Signature specified in handshake packet is invalid.`)
}
}

return packet;
Expand Down

0 comments on commit 25b423e

Please sign in to comment.