more meat for iwp

pull/1/head
Jeff Becker 6 years ago
parent 3f675f0290
commit ce8e5088c4
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -25,7 +25,7 @@ struct llarp_udp_io {
void *user;
void *impl;
struct llarp_ev_loop * parent;
void (*recvfrom)(struct llarp_udp_io *, const struct sockaddr *, void *,
void (*recvfrom)(struct llarp_udp_io *, const struct sockaddr *, const void *,
ssize_t);
};

@ -86,12 +86,11 @@ bool llarp_link_initialized(struct llarp_link * link);
struct llarp_link_session {
struct sockaddr addr;
void *impl;
struct llarp_rc *(*remote_rc)(struct llarp_link_session *);
/** send an entire message, splits up into smaller pieces and does encryption
*/
ssize_t (*sendto)(struct llarp_link_session *, llarp_buffer_t);
bool (*sendto)(struct llarp_link_session *, llarp_buffer_t);
/** receive raw data from link layer */
bool (*recv)(struct llarp_link_session *, const uint8_t *, size_t);
void (*recv)(struct llarp_link_session *, const void *, size_t);
/** return true if this session is timed out */
bool (*timeout)(struct llarp_link_session *);

@ -9,6 +9,7 @@
#endif
extern "C" {
void llarp_ev_loop_alloc(struct llarp_ev_loop **ev) {
#ifdef __linux__
*ev = new llarp_epoll_loop;
@ -39,4 +40,10 @@ int llarp_ev_close_udp_close(struct llarp_udp_io * udp) {
}
void llarp_ev_loop_stop(struct llarp_ev_loop *loop) { loop->stop(); }
int llarp_ev_udp_sendto(struct llarp_udp_io * udp, const sockaddr * to, const void * buf, size_t sz)
{
return static_cast<llarp::ev_io*>(udp->impl)->sendto(to, buf,sz);
}
}

@ -4,6 +4,8 @@
#include <cassert>
#include <fstream>
#include <map>
#include <vector>
#include <list>
#include "crypto.hpp"
#include "fs.hpp"
@ -16,25 +18,105 @@ struct session
{
llarp_crypto * crypto;
llarp_seckey_t eph_seckey;
llarp_pubkey_t remote;
llarp_sharedkey_t sessionkey;
llarp_link_session_listener establish_listener = {nullptr, nullptr, nullptr, nullptr};
llarp::Addr addr;
typedef std::vector<uint8_t> sendbuf_t;
typedef std::list<sendbuf_t> sendqueue_t;
sendqueue_t sendq;
enum State
{
eInitial,
eIntroSent,
eIntroAckSent,
eIntroAckRecv,
eTokenOfferSent,
eTokenOfferRecv,
eTokenAckSent,
eTokenAckRecv,
eEstablished,
eTimeout
};
State state;
session(llarp_crypto * c) :
crypto(c)
session(llarp_crypto * c, const llarp::Addr & a) :
crypto(c),
addr(a),
state(eInitial)
{
c->keygen(&eph_seckey);
}
static bool sendto(llarp_link_session * s, llarp_buffer_t msg)
{
session * self = static_cast<session *>(s->impl);
self->sendq.emplace_back(msg.sz);
memcpy(self->sendq.back().data(), msg.base, msg.sz);
self->pump();
return true;
}
// pump sending messages
void pump()
{
}
static void handle_recv(llarp_link_session * s, const void * buf, size_t sz)
{
session * self = static_cast<session *>(s->impl);
switch (self->state)
{
case eIntroSent:
// got intro ack
self->on_intro_ack(buf, sz);
return;
default:
// invalid state?
return;
}
}
static bool is_timedout(llarp_link_session * s)
{
return false;
}
static void close(llarp_link_session * s)
{
}
void on_intro_ack(const void * buf, size_t sz)
{
printf("iwp intro ack\n");
}
void introduce(llarp_udp_io * udp, llarp_pubkey_t pub)
{
uint8_t buf[140];
size_t sz = sizeof(buf);
sz -= rand() % (sizeof(buf) - 128);
generate_intro(pub, buf, sz);
llarp_ev_udp_sendto(udp, addr, buf, sz);
printf("sent introduce of size %ld\n", sz);
}
/** generate session intro for outbound session */
void generate_intro(llarp_pubkey_t remote, uint8_t * buf, size_t sz)
void generate_intro(llarp_pubkey_t remotepub, uint8_t * buf, size_t sz)
{
assert(sz > 64);
memcpy(remote, remotepub, 32);
assert(sz >= 128);
uint8_t tmp[64];
llarp_nounce_t nounce;
llarp_buffer_t buffer;
llarp_shorthash_t e_key;
uint8_t * sig = buf;
buf += 64;
uint8_t * n = buf;
uint8_t * n = buf + 64;
// n = RAND(32)
crypto->randbytes(n, 32);
// nounce = n[0:24]
@ -43,17 +125,18 @@ struct session
memcpy(tmp, remote, 32);
memcpy(tmp +32, n, 32);
buffer.base = (char*)tmp;
buffer.cur = (char*)tmp;
buffer.sz = sizeof(tmp);
crypto->shorthash(&e_key, buffer);
// e = SE(a.k, e_k, nounce)
crypto->xchacha20(buffer, e_key, nounce);
// S = TKE(a.k, a.b, n)
crypto->transport_dh_client(&sessionkey, remote, eph_seckey, n);
// randomize w0
if(sz > 128)
crypto->randbytes(sig + 128, sz-128);
// s = S(a.k.privkey, n + e + w0)
buffer.base = (char*)n;
buffer.cur = (char*)n;
buffer.sz = sz - 64;
// s = S(a.k.privkey, n + e + w0)
crypto->sign(sig, eph_seckey, buffer);
}
};
@ -72,11 +155,19 @@ struct server
llarp_seckey_t seckey;
void inbound_session(llarp::Addr & src)
session * create_session(llarp::Addr & src)
{
session * impl = new session(crypto, src);
llarp_link_session s;
s.impl = impl;
s.sendto = session::sendto;
s.recv = session::handle_recv;
s.timeout = session::is_timedout;
s.close = session::close;
sessions[src] = s;
return impl;
}
void cleanup_dead()
{
// todo: implement
@ -123,15 +214,18 @@ struct server
}
}
static void handle_recvfrom(struct llarp_udp_io * udp, const struct sockaddr *saddr, void * buf, ssize_t sz)
static void handle_recvfrom(struct llarp_udp_io * udp, const struct sockaddr *saddr, const void * buf, ssize_t sz)
{
server * link = static_cast<server *>(udp->user);
llarp::Addr src = *saddr;
auto itr = link->sessions.find(src);
if (itr == link->sessions.end())
{
link->inbound_session(src);
// new inbound session
link->create_session(src);
}
auto & session = link->sessions[src];
session.recv(&session, buf, sz);
}
void cancel_timer()
@ -173,7 +267,7 @@ struct server
const char * link_name()
{
return "dtls";
return "iwp";
}
@ -238,8 +332,13 @@ void link_iter_sessions(struct llarp_link * l, struct llarp_link_session_iter *
}
void link_try_establish(struct llarp_link * link, struct llarp_link_establish_job job, struct llarp_link_session_listener l)
void link_try_establish(struct llarp_link * l, struct llarp_link_establish_job job, struct llarp_link_session_listener listener)
{
server * link = static_cast<server *>(l->impl);
llarp::Addr dst(*job.ai);
session * s = link->create_session(dst);
s->establish_listener = listener;
s->introduce(&link->udp, job.ai->enc_key);
}
void link_mark_session_active(struct llarp_link * link, struct llarp_link_session * s)

@ -7,6 +7,6 @@ bool llarp_link_initialized(struct llarp_link * link)
bool llarp_link_session_initialized(struct llarp_link_session * s)
{
return s && s->impl && s->remote_rc && s->sendto && s->recv && s->timeout && s->close;
return s && s->impl && s->sendto && s->recv && s->timeout && s->close;
}

@ -39,20 +39,40 @@ namespace llarp
int af = AF_INET;
in6_addr addr = {0};
uint16_t port = 0;
sockaddr saddr;
Addr() {};
Addr(const Addr & other) {
af = other.af;
port = other.port;
memcpy(addr.s6_addr, other.addr.s6_addr, 16);
memcpy(&saddr, &other.saddr, sizeof(sockaddr));
}
Addr(const llarp_ai & other) {
af = AF_INET6;
memcpy(addr.s6_addr, other.ip.s6_addr, 16);
port = htons(other.port);
saddr.sa_family = af;
memcpy(((sockaddr_in6 *)&saddr)->sin6_addr.s6_addr, addr.s6_addr, 16);
((sockaddr_in6 *)&saddr)->sin6_port = port;
}
Addr(const sockaddr & other) {
uint8_t * addrptr = addr.s6_addr;
switch(other.sa_family)
{
case AF_INET:
// SIIT
af = AF_INET;
memcpy(12+addrptr, &((const sockaddr_in*)(&other))->sin_addr, 4);
addrptr[11] = 0xff;
addrptr[10] = 0xff;
port = ((sockaddr_in*)(&other))->sin_port;
break;
case AF_INET6:
af = AF_INET6;
memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr, 16);
port = ((sockaddr_in6*)(&other))->sin6_port;
break;
@ -60,6 +80,13 @@ namespace llarp
default:
break;
}
saddr.sa_family = af;
memcpy(saddr.sa_data, other.sa_data, sizeof(saddr.sa_data));
}
operator const sockaddr * () const
{
return &saddr;
}
bool operator < (const Addr & other) const

Loading…
Cancel
Save