2018-04-30 13:18:57 +00:00
|
|
|
#ifndef LLARP_EV_HPP
|
|
|
|
#define LLARP_EV_HPP
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2019-10-02 13:06:14 +00:00
|
|
|
#include <net/net_addr.hpp>
|
2019-01-11 01:19:36 +00:00
|
|
|
#include <ev/ev.h>
|
2019-02-02 23:12:42 +00:00
|
|
|
#include <util/buffer.hpp>
|
2019-01-13 22:39:10 +00:00
|
|
|
#include <util/codel.hpp>
|
2019-09-01 13:26:16 +00:00
|
|
|
#include <util/thread/threading.hpp>
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2018-10-01 02:08:03 +00:00
|
|
|
// writev
|
|
|
|
#ifndef _WIN32
|
2018-09-30 13:23:37 +00:00
|
|
|
#include <sys/uio.h>
|
2019-04-19 18:24:33 +00:00
|
|
|
#include <unistd.h>
|
2018-10-01 02:08:03 +00:00
|
|
|
#endif
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2018-11-02 12:35:20 +00:00
|
|
|
#include <algorithm>
|
2018-12-12 02:52:51 +00:00
|
|
|
#include <deque>
|
|
|
|
#include <list>
|
2019-03-03 20:51:47 +00:00
|
|
|
#include <future>
|
2019-07-30 23:42:13 +00:00
|
|
|
#include <utility>
|
2018-10-04 11:20:08 +00:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
2019-01-11 01:22:21 +00:00
|
|
|
#include <win32/win32_up.h>
|
|
|
|
#include <win32/win32_upoll.h>
|
2018-12-13 23:02:41 +00:00
|
|
|
// From the preview SDK, should take a look at that
|
|
|
|
// periodically in case its definition changes
|
|
|
|
#define UNIX_PATH_MAX 108
|
|
|
|
|
|
|
|
typedef struct sockaddr_un
|
2018-11-26 17:10:18 +00:00
|
|
|
{
|
2018-12-13 23:02:41 +00:00
|
|
|
ADDRESS_FAMILY sun_family; /* AF_UNIX */
|
|
|
|
char sun_path[UNIX_PATH_MAX]; /* pathname */
|
|
|
|
} SOCKADDR_UN, *PSOCKADDR_UN;
|
2018-12-03 20:37:25 +00:00
|
|
|
#else
|
2018-12-04 23:45:08 +00:00
|
|
|
|
|
|
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
|
|
|
|
|| (__APPLE__ && __MACH__)
|
|
|
|
#include <sys/event.h>
|
|
|
|
#endif
|
|
|
|
|
2018-12-03 20:37:25 +00:00
|
|
|
#include <sys/un.h>
|
2018-10-04 11:20:08 +00:00
|
|
|
#endif
|
|
|
|
|
2019-08-22 11:18:05 +00:00
|
|
|
struct llarp_ev_pkt_pipe;
|
|
|
|
|
2018-08-15 15:36:34 +00:00
|
|
|
#ifndef MAX_WRITE_QUEUE_SIZE
|
2018-11-09 14:48:43 +00:00
|
|
|
#define MAX_WRITE_QUEUE_SIZE (1024UL)
|
2018-08-15 15:36:34 +00:00
|
|
|
#endif
|
2018-04-30 13:18:57 +00:00
|
|
|
|
2018-09-06 20:31:58 +00:00
|
|
|
#ifndef EV_READ_BUF_SZ
|
2018-11-09 14:48:43 +00:00
|
|
|
#define EV_READ_BUF_SZ (4 * 1024UL)
|
2018-09-06 20:31:58 +00:00
|
|
|
#endif
|
2018-10-27 18:26:08 +00:00
|
|
|
#ifndef EV_WRITE_BUF_SZ
|
2018-11-09 14:48:43 +00:00
|
|
|
#define EV_WRITE_BUF_SZ (2 * 1024UL)
|
2018-10-27 18:26:08 +00:00
|
|
|
#endif
|
2018-09-06 20:31:58 +00:00
|
|
|
|
2019-03-15 14:31:54 +00:00
|
|
|
/// do io and reset errno after
|
|
|
|
static ssize_t
|
|
|
|
IO(std::function< ssize_t(void) > iofunc)
|
|
|
|
{
|
|
|
|
ssize_t ret = iofunc();
|
2019-03-26 21:07:16 +00:00
|
|
|
#ifndef _WIN32
|
|
|
|
errno = 0;
|
|
|
|
#else
|
|
|
|
WSASetLastError(0);
|
|
|
|
#endif
|
2019-03-15 14:31:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
struct win32_ev_io
|
2018-10-29 16:48:36 +00:00
|
|
|
{
|
2018-10-03 10:40:32 +00:00
|
|
|
struct WriteBuffer
|
2018-08-15 15:36:34 +00:00
|
|
|
{
|
2018-10-29 16:48:36 +00:00
|
|
|
llarp_time_t timestamp = 0;
|
2018-10-03 10:40:32 +00:00
|
|
|
size_t bufsz;
|
2018-10-31 01:48:41 +00:00
|
|
|
byte_t buf[EV_WRITE_BUF_SZ] = {0};
|
2018-10-03 10:40:32 +00:00
|
|
|
|
|
|
|
WriteBuffer() = default;
|
|
|
|
|
2018-10-25 12:09:29 +00:00
|
|
|
WriteBuffer(const byte_t* ptr, size_t sz)
|
2018-10-03 10:40:32 +00:00
|
|
|
{
|
|
|
|
if(sz <= sizeof(buf))
|
|
|
|
{
|
|
|
|
bufsz = sz;
|
|
|
|
memcpy(buf, ptr, bufsz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bufsz = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct GetTime
|
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
llarp_time_t
|
|
|
|
operator()(const WriteBuffer& buf) const
|
2018-10-03 10:40:32 +00:00
|
|
|
{
|
2018-10-29 16:48:36 +00:00
|
|
|
return buf.timestamp;
|
2018-10-03 10:40:32 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-12-03 14:39:30 +00:00
|
|
|
struct GetNow
|
|
|
|
{
|
2019-04-08 12:01:52 +00:00
|
|
|
llarp_ev_loop_ptr loop;
|
|
|
|
GetNow(llarp_ev_loop_ptr l) : loop(l)
|
2018-12-03 14:39:30 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
llarp_time_t
|
|
|
|
operator()() const
|
|
|
|
{
|
|
|
|
return llarp_ev_loop_time_now_ms(loop);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-03 10:40:32 +00:00
|
|
|
struct PutTime
|
|
|
|
{
|
2019-04-08 12:01:52 +00:00
|
|
|
llarp_ev_loop_ptr loop;
|
|
|
|
PutTime(llarp_ev_loop_ptr l) : loop(l)
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
void
|
|
|
|
operator()(WriteBuffer& buf)
|
2018-10-03 10:40:32 +00:00
|
|
|
{
|
2018-10-29 16:48:36 +00:00
|
|
|
buf.timestamp = llarp_ev_loop_time_now_ms(loop);
|
2018-10-03 10:40:32 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Compare
|
|
|
|
{
|
|
|
|
bool
|
|
|
|
operator()(const WriteBuffer& left, const WriteBuffer& right) const
|
|
|
|
{
|
|
|
|
return left.timestamp < right.timestamp;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-11-22 23:59:03 +00:00
|
|
|
using LosslessWriteQueue_t = std::deque< WriteBuffer >;
|
2018-10-24 18:02:42 +00:00
|
|
|
|
2018-12-23 13:29:11 +00:00
|
|
|
intptr_t
|
|
|
|
fd; // Sockets only, fuck UNIX-style reactive IO with a rusty knife
|
2018-11-19 07:55:19 +00:00
|
|
|
|
2018-12-23 13:29:11 +00:00
|
|
|
int flags = 0;
|
2018-12-14 12:04:14 +00:00
|
|
|
win32_ev_io(intptr_t f) : fd(f){};
|
2018-11-19 07:55:19 +00:00
|
|
|
|
|
|
|
/// for tcp
|
2018-12-23 13:29:11 +00:00
|
|
|
win32_ev_io(intptr_t f, LosslessWriteQueue_t* q)
|
|
|
|
: fd(f), m_BlockingWriteQueue(q)
|
2018-10-25 22:16:03 +00:00
|
|
|
{
|
|
|
|
}
|
2018-11-19 07:55:19 +00:00
|
|
|
|
|
|
|
virtual void
|
|
|
|
error()
|
2018-10-25 22:16:03 +00:00
|
|
|
{
|
2018-12-14 14:38:37 +00:00
|
|
|
char ebuf[1024];
|
|
|
|
int err = WSAGetLastError();
|
|
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL,
|
|
|
|
ebuf, 1024, nullptr);
|
|
|
|
llarp::LogError(ebuf);
|
2018-10-25 22:16:03 +00:00
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2018-10-24 18:02:42 +00:00
|
|
|
virtual int
|
2018-12-03 14:39:30 +00:00
|
|
|
read(byte_t* buf, size_t sz) = 0;
|
2018-10-24 18:02:42 +00:00
|
|
|
|
|
|
|
virtual int
|
|
|
|
sendto(const sockaddr* dst, const void* data, size_t sz)
|
|
|
|
{
|
2018-12-13 19:27:01 +00:00
|
|
|
UNREFERENCED_PARAMETER(dst);
|
|
|
|
UNREFERENCED_PARAMETER(data);
|
|
|
|
UNREFERENCED_PARAMETER(sz);
|
2018-10-24 18:02:42 +00:00
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
|
2018-10-25 12:39:32 +00:00
|
|
|
/// return false if we want to deregister and remove ourselves
|
|
|
|
virtual bool
|
|
|
|
tick()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
};
|
2018-10-24 18:02:42 +00:00
|
|
|
|
|
|
|
/// used for tun interface and tcp conn
|
2018-10-27 20:02:37 +00:00
|
|
|
virtual ssize_t
|
2018-10-24 18:02:42 +00:00
|
|
|
do_write(void* data, size_t sz)
|
|
|
|
{
|
2018-12-14 12:04:14 +00:00
|
|
|
return uwrite(fd, (char*)data, sz);
|
2018-10-24 18:02:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
queue_write(const byte_t* buf, size_t sz)
|
|
|
|
{
|
2018-12-14 12:04:14 +00:00
|
|
|
if(m_BlockingWriteQueue)
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
|
|
|
m_BlockingWriteQueue->emplace_back(buf, sz);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-02 20:43:53 +00:00
|
|
|
virtual void
|
|
|
|
flush_write()
|
|
|
|
{
|
|
|
|
flush_write_buffers(0);
|
|
|
|
}
|
|
|
|
|
2018-10-24 18:02:42 +00:00
|
|
|
/// called in event loop when fd is ready for writing
|
|
|
|
/// requeues anything not written
|
|
|
|
/// this assumes fd is set to non blocking
|
|
|
|
virtual void
|
2018-11-02 20:43:53 +00:00
|
|
|
flush_write_buffers(size_t amount)
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
2018-12-23 13:29:11 +00:00
|
|
|
if(m_BlockingWriteQueue)
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
2018-11-02 20:43:53 +00:00
|
|
|
if(amount)
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
2018-11-02 20:43:53 +00:00
|
|
|
while(amount && m_BlockingWriteQueue->size())
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
2018-11-02 20:43:53 +00:00
|
|
|
auto& itr = m_BlockingWriteQueue->front();
|
|
|
|
ssize_t result = do_write(itr.buf, std::min(amount, itr.bufsz));
|
|
|
|
if(result == -1)
|
|
|
|
return;
|
|
|
|
ssize_t dlt = itr.bufsz - result;
|
|
|
|
if(dlt > 0)
|
|
|
|
{
|
|
|
|
// queue remaining to front of queue
|
|
|
|
WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt);
|
|
|
|
m_BlockingWriteQueue->pop_front();
|
|
|
|
m_BlockingWriteQueue->push_front(buff);
|
|
|
|
// TODO: errno?
|
|
|
|
return;
|
|
|
|
}
|
2018-10-24 18:02:42 +00:00
|
|
|
m_BlockingWriteQueue->pop_front();
|
2018-11-02 20:43:53 +00:00
|
|
|
amount -= result;
|
2018-10-24 18:02:42 +00:00
|
|
|
}
|
2018-11-02 20:43:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// write buffers
|
|
|
|
while(m_BlockingWriteQueue->size())
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
2018-11-02 20:43:53 +00:00
|
|
|
auto& itr = m_BlockingWriteQueue->front();
|
|
|
|
ssize_t result = do_write(itr.buf, itr.bufsz);
|
|
|
|
if(result == -1)
|
|
|
|
return;
|
|
|
|
ssize_t dlt = itr.bufsz - result;
|
|
|
|
if(dlt > 0)
|
|
|
|
{
|
|
|
|
// queue remaining to front of queue
|
|
|
|
WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt);
|
|
|
|
m_BlockingWriteQueue->pop_front();
|
|
|
|
m_BlockingWriteQueue->push_front(buff);
|
|
|
|
// TODO: errno?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_BlockingWriteQueue->pop_front();
|
2018-11-20 06:12:56 +00:00
|
|
|
int wsaerr = WSAGetLastError();
|
2018-12-14 12:04:14 +00:00
|
|
|
if(wsaerr == WSA_IO_PENDING || wsaerr == WSAEWOULDBLOCK)
|
2018-11-02 20:43:53 +00:00
|
|
|
{
|
2018-11-20 06:12:56 +00:00
|
|
|
WSASetLastError(0);
|
2018-11-02 20:43:53 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-10-24 18:02:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// reset errno
|
2018-11-20 06:12:56 +00:00
|
|
|
WSASetLastError(0);
|
2018-10-24 18:02:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr< LosslessWriteQueue_t > m_BlockingWriteQueue;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
virtual ~win32_ev_io()
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
2018-12-14 12:04:14 +00:00
|
|
|
uclose(fd);
|
2018-10-03 10:40:32 +00:00
|
|
|
};
|
|
|
|
};
|
2018-12-14 14:38:37 +00:00
|
|
|
#else
|
2018-10-29 23:56:05 +00:00
|
|
|
struct posix_ev_io
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
struct WriteBuffer
|
|
|
|
{
|
|
|
|
llarp_time_t timestamp = 0;
|
|
|
|
size_t bufsz;
|
|
|
|
byte_t buf[EV_WRITE_BUF_SZ];
|
|
|
|
|
|
|
|
WriteBuffer() = default;
|
|
|
|
|
|
|
|
WriteBuffer(const byte_t* ptr, size_t sz)
|
|
|
|
{
|
|
|
|
if(sz <= sizeof(buf))
|
|
|
|
{
|
|
|
|
bufsz = sz;
|
|
|
|
memcpy(buf, ptr, bufsz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bufsz = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct GetTime
|
|
|
|
{
|
|
|
|
llarp_time_t
|
2019-04-25 23:21:19 +00:00
|
|
|
operator()(const WriteBuffer& writebuf) const
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2019-04-25 23:21:19 +00:00
|
|
|
return writebuf.timestamp;
|
2018-10-29 23:56:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-11-15 13:13:19 +00:00
|
|
|
struct GetNow
|
|
|
|
{
|
2019-04-08 12:01:52 +00:00
|
|
|
llarp_ev_loop_ptr loop;
|
2019-07-30 23:42:13 +00:00
|
|
|
GetNow(llarp_ev_loop_ptr l) : loop(std::move(l))
|
2018-11-15 13:13:19 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
llarp_time_t
|
|
|
|
operator()() const
|
|
|
|
{
|
|
|
|
return llarp_ev_loop_time_now_ms(loop);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
struct PutTime
|
|
|
|
{
|
2019-04-08 12:01:52 +00:00
|
|
|
llarp_ev_loop_ptr loop;
|
2019-07-30 23:42:13 +00:00
|
|
|
PutTime(llarp_ev_loop_ptr l) : loop(std::move(l))
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
void
|
2019-04-25 23:21:19 +00:00
|
|
|
operator()(WriteBuffer& writebuf)
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2019-04-25 23:21:19 +00:00
|
|
|
writebuf.timestamp = llarp_ev_loop_time_now_ms(loop);
|
2018-10-29 23:56:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Compare
|
|
|
|
{
|
|
|
|
bool
|
|
|
|
operator()(const WriteBuffer& left, const WriteBuffer& right) const
|
|
|
|
{
|
|
|
|
return left.timestamp < right.timestamp;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-11-22 23:59:03 +00:00
|
|
|
using LossyWriteQueue_t =
|
|
|
|
llarp::util::CoDelQueue< WriteBuffer, WriteBuffer::GetTime,
|
|
|
|
WriteBuffer::PutTime, WriteBuffer::Compare,
|
|
|
|
WriteBuffer::GetNow, llarp::util::NullMutex,
|
|
|
|
llarp::util::NullLock, 5, 100, 1024 >;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2018-11-22 23:59:03 +00:00
|
|
|
using LosslessWriteQueue_t = std::deque< WriteBuffer >;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
int fd;
|
|
|
|
int flags = 0;
|
2018-11-02 12:35:20 +00:00
|
|
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
|
|
|
|
|| (__APPLE__ && __MACH__)
|
|
|
|
struct kevent change;
|
|
|
|
#endif
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
posix_ev_io(int f) : fd(f)
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
/// for tun
|
|
|
|
posix_ev_io(int f, LossyWriteQueue_t* q) : fd(f), m_LossyWriteQueue(q)
|
2018-10-25 13:40:07 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
/// for tcp
|
|
|
|
posix_ev_io(int f, LosslessWriteQueue_t* q) : fd(f), m_BlockingWriteQueue(q)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-11-01 12:47:14 +00:00
|
|
|
virtual void
|
|
|
|
error()
|
|
|
|
{
|
|
|
|
llarp::LogError(strerror(errno));
|
|
|
|
}
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
virtual int
|
2018-12-01 14:35:11 +00:00
|
|
|
read(byte_t* buf, size_t sz) = 0;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
virtual int
|
2018-11-07 15:30:22 +00:00
|
|
|
sendto(__attribute__((unused)) const sockaddr* dst,
|
|
|
|
__attribute__((unused)) const void* data,
|
|
|
|
__attribute__((unused)) size_t sz)
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
|
|
|
return -1;
|
2019-04-24 23:27:31 +00:00
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
/// return false if we want to deregister and remove ourselves
|
|
|
|
virtual bool
|
|
|
|
tick()
|
|
|
|
{
|
|
|
|
return true;
|
2019-04-24 23:27:31 +00:00
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
/// used for tun interface and tcp conn
|
2018-10-27 20:02:37 +00:00
|
|
|
virtual ssize_t
|
2018-10-29 23:56:05 +00:00
|
|
|
do_write(void* data, size_t sz)
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
return write(fd, data, sz);
|
2018-10-25 12:00:29 +00:00
|
|
|
}
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
bool
|
|
|
|
queue_write(const byte_t* buf, size_t sz)
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
if(m_LossyWriteQueue)
|
|
|
|
{
|
|
|
|
m_LossyWriteQueue->Emplace(buf, sz);
|
|
|
|
return true;
|
|
|
|
}
|
2019-07-06 17:03:40 +00:00
|
|
|
if(m_BlockingWriteQueue)
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
m_BlockingWriteQueue->emplace_back(buf, sz);
|
|
|
|
return true;
|
2018-10-25 12:00:29 +00:00
|
|
|
}
|
2019-07-06 17:03:40 +00:00
|
|
|
|
|
|
|
return false;
|
2018-10-29 23:56:05 +00:00
|
|
|
}
|
|
|
|
|
2018-11-02 12:35:20 +00:00
|
|
|
virtual void
|
|
|
|
flush_write()
|
|
|
|
{
|
|
|
|
flush_write_buffers(0);
|
|
|
|
}
|
|
|
|
|
2018-12-14 15:43:44 +00:00
|
|
|
virtual void
|
2019-04-24 23:27:31 +00:00
|
|
|
before_flush_write()
|
|
|
|
{
|
|
|
|
}
|
2018-12-14 15:43:44 +00:00
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
/// called in event loop when fd is ready for writing
|
|
|
|
/// requeues anything not written
|
|
|
|
/// this assumes fd is set to non blocking
|
|
|
|
virtual void
|
2018-11-02 12:35:20 +00:00
|
|
|
flush_write_buffers(size_t amount)
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2018-12-14 16:01:32 +00:00
|
|
|
before_flush_write();
|
2018-10-29 23:56:05 +00:00
|
|
|
if(m_LossyWriteQueue)
|
2018-12-14 15:43:44 +00:00
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
m_LossyWriteQueue->Process([&](WriteBuffer& buffer) {
|
|
|
|
do_write(buffer.buf, buffer.bufsz);
|
|
|
|
// if we would block we save the entries for later
|
|
|
|
// discard entry
|
|
|
|
});
|
2018-12-14 15:43:44 +00:00
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
else if(m_BlockingWriteQueue)
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-11-02 12:35:20 +00:00
|
|
|
if(amount)
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2018-11-02 12:35:20 +00:00
|
|
|
while(amount && m_BlockingWriteQueue->size())
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2018-11-02 12:35:20 +00:00
|
|
|
auto& itr = m_BlockingWriteQueue->front();
|
|
|
|
ssize_t result = do_write(itr.buf, std::min(amount, itr.bufsz));
|
2019-04-08 14:04:58 +00:00
|
|
|
if(result <= 0)
|
2018-11-02 12:35:20 +00:00
|
|
|
return;
|
|
|
|
ssize_t dlt = itr.bufsz - result;
|
|
|
|
if(dlt > 0)
|
|
|
|
{
|
|
|
|
// queue remaining to front of queue
|
|
|
|
WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt);
|
|
|
|
m_BlockingWriteQueue->pop_front();
|
|
|
|
m_BlockingWriteQueue->push_front(buff);
|
|
|
|
// TODO: errno?
|
|
|
|
return;
|
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
m_BlockingWriteQueue->pop_front();
|
2018-11-02 12:35:20 +00:00
|
|
|
amount -= result;
|
2018-10-29 23:56:05 +00:00
|
|
|
}
|
2018-11-02 12:35:20 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// write buffers
|
|
|
|
while(m_BlockingWriteQueue->size())
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2018-11-02 12:35:20 +00:00
|
|
|
auto& itr = m_BlockingWriteQueue->front();
|
|
|
|
ssize_t result = do_write(itr.buf, itr.bufsz);
|
2019-04-08 14:04:58 +00:00
|
|
|
if(result <= 0)
|
2019-02-28 16:02:36 +00:00
|
|
|
{
|
|
|
|
errno = 0;
|
2018-11-02 12:35:20 +00:00
|
|
|
return;
|
2019-02-28 16:02:36 +00:00
|
|
|
}
|
2018-11-02 12:35:20 +00:00
|
|
|
ssize_t dlt = itr.bufsz - result;
|
|
|
|
if(dlt > 0)
|
|
|
|
{
|
|
|
|
// queue remaining to front of queue
|
|
|
|
WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt);
|
|
|
|
m_BlockingWriteQueue->pop_front();
|
|
|
|
m_BlockingWriteQueue->push_front(buff);
|
|
|
|
// TODO: errno?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_BlockingWriteQueue->pop_front();
|
|
|
|
if(errno == EAGAIN || errno == EWOULDBLOCK)
|
|
|
|
{
|
|
|
|
errno = 0;
|
|
|
|
return;
|
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
}
|
|
|
|
}
|
2018-10-25 12:00:29 +00:00
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
/// reset errno
|
|
|
|
errno = 0;
|
2018-10-25 12:00:29 +00:00
|
|
|
}
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
std::unique_ptr< LossyWriteQueue_t > m_LossyWriteQueue;
|
|
|
|
std::unique_ptr< LosslessWriteQueue_t > m_BlockingWriteQueue;
|
2018-10-25 12:00:29 +00:00
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
virtual ~posix_ev_io()
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-10-29 23:56:05 +00:00
|
|
|
close(fd);
|
2019-04-24 23:27:31 +00:00
|
|
|
}
|
2018-10-29 23:56:05 +00:00
|
|
|
};
|
2018-12-14 14:38:37 +00:00
|
|
|
#endif
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
// finally create aliases by platform
|
|
|
|
#ifdef _WIN32
|
|
|
|
using ev_io = win32_ev_io;
|
|
|
|
#else
|
|
|
|
using ev_io = posix_ev_io;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// wew, managed to get away with using
|
|
|
|
// 'int fd' across all platforms
|
|
|
|
// since we're operating entirely
|
|
|
|
// on sockets
|
|
|
|
struct tcp_conn : public ev_io
|
|
|
|
{
|
2018-11-01 12:47:14 +00:00
|
|
|
sockaddr_storage _addr;
|
|
|
|
bool _shouldClose = false;
|
|
|
|
bool _calledConnected = false;
|
|
|
|
llarp_tcp_conn tcp;
|
|
|
|
// null if inbound otherwise outbound
|
|
|
|
llarp_tcp_connecter* _conn;
|
|
|
|
|
2019-06-02 21:17:05 +00:00
|
|
|
static void
|
|
|
|
DoClose(llarp_tcp_conn* conn)
|
|
|
|
{
|
|
|
|
static_cast< tcp_conn* >(conn->impl)->_shouldClose = true;
|
|
|
|
}
|
|
|
|
|
2018-11-01 12:47:14 +00:00
|
|
|
/// inbound
|
2019-08-02 09:27:27 +00:00
|
|
|
tcp_conn(llarp_ev_loop* loop, int _fd)
|
|
|
|
: ev_io(_fd, new LosslessWriteQueue_t{}), _conn(nullptr)
|
2018-11-01 12:47:14 +00:00
|
|
|
{
|
|
|
|
tcp.impl = this;
|
|
|
|
tcp.loop = loop;
|
|
|
|
tcp.closed = nullptr;
|
|
|
|
tcp.user = nullptr;
|
|
|
|
tcp.read = nullptr;
|
|
|
|
tcp.tick = nullptr;
|
2019-06-02 21:17:05 +00:00
|
|
|
tcp.close = &DoClose;
|
2018-11-01 12:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// outbound
|
2019-08-02 09:27:27 +00:00
|
|
|
tcp_conn(llarp_ev_loop* loop, int _fd, const sockaddr* addr,
|
2018-11-01 12:47:14 +00:00
|
|
|
llarp_tcp_connecter* conn)
|
2019-08-02 09:27:27 +00:00
|
|
|
: ev_io(_fd, new LosslessWriteQueue_t{}), _conn(conn)
|
2018-10-29 23:56:05 +00:00
|
|
|
{
|
2018-11-01 12:47:14 +00:00
|
|
|
socklen_t slen = sizeof(sockaddr_in);
|
|
|
|
if(addr->sa_family == AF_INET6)
|
|
|
|
slen = sizeof(sockaddr_in6);
|
|
|
|
else if(addr->sa_family == AF_UNIX)
|
|
|
|
slen = sizeof(sockaddr_un);
|
|
|
|
memcpy(&_addr, addr, slen);
|
|
|
|
tcp.impl = this;
|
|
|
|
tcp.loop = loop;
|
|
|
|
tcp.closed = nullptr;
|
|
|
|
tcp.user = nullptr;
|
|
|
|
tcp.read = nullptr;
|
|
|
|
tcp.tick = nullptr;
|
2019-06-02 21:17:05 +00:00
|
|
|
tcp.close = &DoClose;
|
2018-10-29 23:56:05 +00:00
|
|
|
}
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
~tcp_conn() override = default;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2018-11-01 12:47:14 +00:00
|
|
|
/// start connecting
|
|
|
|
void
|
|
|
|
connect();
|
|
|
|
|
|
|
|
/// calls connected hooks
|
|
|
|
void
|
|
|
|
connected()
|
|
|
|
{
|
2019-02-27 15:19:55 +00:00
|
|
|
sockaddr_storage st;
|
|
|
|
socklen_t sl;
|
2019-03-01 19:10:42 +00:00
|
|
|
if(getpeername(fd, (sockaddr*)&st, &sl) == 0)
|
2018-11-01 12:47:14 +00:00
|
|
|
{
|
2019-02-27 15:19:55 +00:00
|
|
|
// we are connected yeh boi
|
|
|
|
if(_conn)
|
|
|
|
{
|
|
|
|
if(_conn->connected && !_calledConnected)
|
|
|
|
_conn->connected(_conn, &tcp);
|
|
|
|
}
|
|
|
|
_calledConnected = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error();
|
2018-11-01 12:47:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-02-28 22:59:36 +00:00
|
|
|
flush_write() override;
|
2018-11-01 12:47:14 +00:00
|
|
|
|
|
|
|
void
|
2019-02-28 22:59:36 +00:00
|
|
|
flush_write_buffers(size_t a) override
|
2018-11-02 12:35:20 +00:00
|
|
|
{
|
|
|
|
connected();
|
|
|
|
ev_io::flush_write_buffers(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-02-27 15:19:55 +00:00
|
|
|
error() override
|
2018-11-02 12:35:20 +00:00
|
|
|
{
|
2019-02-27 15:19:55 +00:00
|
|
|
_shouldClose = true;
|
2018-11-02 12:35:20 +00:00
|
|
|
if(_conn)
|
|
|
|
{
|
2018-11-20 06:12:56 +00:00
|
|
|
#ifndef _WIN32
|
2018-11-02 12:35:20 +00:00
|
|
|
llarp::LogError("tcp_conn error: ", strerror(errno));
|
2018-11-20 06:12:56 +00:00
|
|
|
#else
|
|
|
|
char ebuf[1024];
|
|
|
|
int err = WSAGetLastError();
|
|
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL,
|
|
|
|
ebuf, 1024, nullptr);
|
|
|
|
llarp::LogError("tcp_conn error: ", ebuf);
|
|
|
|
#endif
|
2018-11-02 12:35:20 +00:00
|
|
|
if(_conn->error)
|
|
|
|
_conn->error(_conn);
|
|
|
|
}
|
2019-02-28 16:02:36 +00:00
|
|
|
errno = 0;
|
2018-11-02 12:35:20 +00:00
|
|
|
}
|
2018-11-01 12:47:14 +00:00
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
ssize_t
|
2019-02-28 22:59:36 +00:00
|
|
|
do_write(void* buf, size_t sz) override;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
int
|
2019-02-28 22:59:36 +00:00
|
|
|
read(byte_t* buf, size_t sz) override;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
|
|
|
bool
|
2019-02-28 22:59:36 +00:00
|
|
|
tick() override;
|
2018-10-25 12:00:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct tcp_serv : public ev_io
|
|
|
|
{
|
|
|
|
llarp_ev_loop* loop;
|
|
|
|
llarp_tcp_acceptor* tcp;
|
2019-08-02 09:27:27 +00:00
|
|
|
tcp_serv(llarp_ev_loop* l, int _fd, llarp_tcp_acceptor* t)
|
|
|
|
: ev_io(_fd), loop(l), tcp(t)
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
2018-11-01 12:47:14 +00:00
|
|
|
tcp->impl = this;
|
2018-10-25 12:00:29 +00:00
|
|
|
}
|
|
|
|
|
2018-10-25 12:39:32 +00:00
|
|
|
bool
|
2019-07-30 23:42:13 +00:00
|
|
|
tick() override
|
2018-10-25 12:00:29 +00:00
|
|
|
{
|
|
|
|
if(tcp->tick)
|
|
|
|
tcp->tick(tcp);
|
2018-10-25 12:39:32 +00:00
|
|
|
return true;
|
2018-10-25 12:00:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// actually does accept() :^)
|
2019-07-30 23:42:13 +00:00
|
|
|
int
|
|
|
|
read(byte_t*, size_t) override;
|
2018-10-25 12:00:29 +00:00
|
|
|
};
|
|
|
|
|
2019-04-25 23:21:19 +00:00
|
|
|
} // namespace llarp
|
2018-04-30 13:18:57 +00:00
|
|
|
|
2018-12-03 14:39:30 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
struct llarp_fd_promise
|
|
|
|
{
|
2019-11-14 15:07:40 +00:00
|
|
|
void
|
|
|
|
Set(std::pair< int, int >)
|
2018-12-03 14:39:30 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
Get()
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#else
|
2018-11-26 22:46:22 +00:00
|
|
|
struct llarp_fd_promise
|
|
|
|
{
|
2019-04-08 15:54:19 +00:00
|
|
|
using promise_val_t = std::pair< int, int >;
|
|
|
|
llarp_fd_promise(std::promise< promise_val_t >* p) : _impl(p)
|
2018-12-02 18:07:07 +00:00
|
|
|
{
|
|
|
|
}
|
2019-04-08 15:54:19 +00:00
|
|
|
std::promise< promise_val_t >* _impl;
|
2018-12-02 18:07:07 +00:00
|
|
|
|
|
|
|
void
|
2019-04-08 15:54:19 +00:00
|
|
|
Set(promise_val_t fds)
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
2019-04-08 15:54:19 +00:00
|
|
|
_impl->set_value(fds);
|
2018-11-26 22:46:22 +00:00
|
|
|
}
|
|
|
|
|
2019-04-08 15:54:19 +00:00
|
|
|
promise_val_t
|
2018-12-02 18:07:07 +00:00
|
|
|
Get()
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
|
|
|
auto future = _impl->get_future();
|
|
|
|
future.wait();
|
|
|
|
return future.get();
|
|
|
|
}
|
|
|
|
};
|
2018-12-03 14:39:30 +00:00
|
|
|
#endif
|
2018-11-26 22:46:22 +00:00
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
// this (nearly!) abstract base class
|
|
|
|
// is overriden for each platform
|
2018-05-22 15:54:19 +00:00
|
|
|
struct llarp_ev_loop
|
|
|
|
{
|
2018-10-30 12:30:21 +00:00
|
|
|
byte_t readbuf[EV_READ_BUF_SZ] = {0};
|
2019-01-23 22:16:16 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
virtual bool
|
|
|
|
init() = 0;
|
2019-01-23 22:16:16 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
virtual int
|
|
|
|
run() = 0;
|
2018-06-06 12:46:26 +00:00
|
|
|
|
2019-01-23 22:16:16 +00:00
|
|
|
virtual bool
|
|
|
|
running() const = 0;
|
|
|
|
|
2019-06-02 21:17:05 +00:00
|
|
|
virtual void
|
2019-03-15 14:31:54 +00:00
|
|
|
update_time()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual llarp_time_t
|
|
|
|
time_now() const
|
|
|
|
{
|
2019-11-05 16:58:53 +00:00
|
|
|
return llarp::time_now_ms();
|
2019-03-15 14:31:54 +00:00
|
|
|
}
|
|
|
|
|
2019-06-02 21:17:05 +00:00
|
|
|
virtual void
|
|
|
|
stopped(){};
|
|
|
|
|
2019-01-23 22:16:16 +00:00
|
|
|
/// return false on socket error (non blocking)
|
|
|
|
virtual bool
|
|
|
|
tcp_connect(llarp_tcp_connecter* tcp, const sockaddr* addr) = 0;
|
|
|
|
|
2018-06-06 12:46:26 +00:00
|
|
|
virtual int
|
2018-06-06 21:23:57 +00:00
|
|
|
tick(int ms) = 0;
|
2018-06-06 12:46:26 +00:00
|
|
|
|
2019-09-05 17:39:09 +00:00
|
|
|
virtual bool
|
|
|
|
add_ticker(std::function< void(void) > ticker) = 0;
|
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
virtual void
|
|
|
|
stop() = 0;
|
2018-04-30 13:18:57 +00:00
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
virtual bool
|
|
|
|
udp_listen(llarp_udp_io* l, const sockaddr* src) = 0;
|
2018-08-15 15:36:34 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
virtual bool
|
|
|
|
udp_close(llarp_udp_io* l) = 0;
|
2018-10-25 12:39:32 +00:00
|
|
|
/// deregister event listener
|
2018-05-22 15:54:19 +00:00
|
|
|
virtual bool
|
|
|
|
close_ev(llarp::ev_io* ev) = 0;
|
2018-04-30 16:14:20 +00:00
|
|
|
|
2019-06-02 21:17:05 +00:00
|
|
|
virtual bool
|
|
|
|
tun_listen(llarp_tun_io* tun)
|
|
|
|
{
|
|
|
|
auto dev = create_tun(tun);
|
|
|
|
tun->impl = dev;
|
|
|
|
if(dev)
|
|
|
|
{
|
|
|
|
return add_ev(dev, false);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-15 15:36:34 +00:00
|
|
|
virtual llarp::ev_io*
|
|
|
|
create_tun(llarp_tun_io* tun) = 0;
|
|
|
|
|
2018-10-29 23:56:05 +00:00
|
|
|
virtual llarp::ev_io*
|
|
|
|
bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* addr) = 0;
|
2018-10-24 18:02:42 +00:00
|
|
|
|
2019-08-22 11:18:05 +00:00
|
|
|
virtual bool
|
2019-08-23 13:29:57 +00:00
|
|
|
add_pipe(llarp_ev_pkt_pipe*)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2019-08-22 11:18:05 +00:00
|
|
|
|
2019-09-16 10:21:12 +00:00
|
|
|
/// give this event loop a logic thread for calling
|
2019-10-02 13:06:14 +00:00
|
|
|
virtual void set_logic(std::shared_ptr< llarp::Logic >) = 0;
|
2019-09-16 10:21:12 +00:00
|
|
|
|
2018-10-25 12:39:32 +00:00
|
|
|
/// register event listener
|
2018-08-15 15:36:34 +00:00
|
|
|
virtual bool
|
2018-11-02 12:35:20 +00:00
|
|
|
add_ev(llarp::ev_io* ev, bool write) = 0;
|
2018-08-15 15:36:34 +00:00
|
|
|
|
2019-06-02 21:17:05 +00:00
|
|
|
virtual bool
|
|
|
|
tcp_listen(llarp_tcp_acceptor* tcp, const sockaddr* addr)
|
|
|
|
{
|
|
|
|
auto conn = bind_tcp(tcp, addr);
|
|
|
|
return conn && add_ev(conn, true);
|
|
|
|
}
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
virtual ~llarp_ev_loop() = default;
|
2018-06-27 13:14:07 +00:00
|
|
|
|
2018-10-24 18:02:42 +00:00
|
|
|
std::list< std::unique_ptr< llarp::ev_io > > handlers;
|
2018-08-15 15:36:34 +00:00
|
|
|
|
2019-10-02 13:06:14 +00:00
|
|
|
virtual void
|
2018-08-15 15:36:34 +00:00
|
|
|
tick_listeners()
|
|
|
|
{
|
2018-11-08 12:31:50 +00:00
|
|
|
auto itr = handlers.begin();
|
|
|
|
while(itr != handlers.end())
|
2018-10-25 12:39:32 +00:00
|
|
|
{
|
|
|
|
if((*itr)->tick())
|
|
|
|
++itr;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
close_ev(itr->get());
|
|
|
|
itr = handlers.erase(itr);
|
|
|
|
}
|
|
|
|
}
|
2018-08-15 15:36:34 +00:00
|
|
|
}
|
2018-04-30 13:18:57 +00:00
|
|
|
};
|
|
|
|
|
2019-10-02 13:06:14 +00:00
|
|
|
struct PacketBuffer
|
|
|
|
{
|
|
|
|
PacketBuffer(PacketBuffer&& other)
|
|
|
|
{
|
|
|
|
_ptr = other._ptr;
|
|
|
|
_sz = other._sz;
|
|
|
|
other._ptr = nullptr;
|
|
|
|
other._sz = 0;
|
|
|
|
}
|
|
|
|
|
2019-10-28 18:21:08 +00:00
|
|
|
PacketBuffer(const PacketBuffer&) = delete;
|
|
|
|
|
2019-10-28 18:34:39 +00:00
|
|
|
PacketBuffer&
|
|
|
|
operator=(const PacketBuffer&) = delete;
|
|
|
|
|
2019-10-02 13:06:14 +00:00
|
|
|
PacketBuffer() : PacketBuffer(nullptr, 0){};
|
2019-10-28 18:08:59 +00:00
|
|
|
explicit PacketBuffer(size_t sz) : _sz{sz}
|
2019-10-02 13:06:14 +00:00
|
|
|
{
|
2019-10-28 18:08:59 +00:00
|
|
|
_ptr = new char[sz];
|
2019-10-02 13:06:14 +00:00
|
|
|
}
|
2019-11-03 19:38:34 +00:00
|
|
|
PacketBuffer(char* buf, size_t sz)
|
2019-10-02 13:06:14 +00:00
|
|
|
{
|
2019-11-03 19:38:34 +00:00
|
|
|
_ptr = buf;
|
|
|
|
_sz = sz;
|
2019-10-02 13:06:14 +00:00
|
|
|
}
|
|
|
|
~PacketBuffer()
|
|
|
|
{
|
|
|
|
if(_ptr)
|
|
|
|
delete[] _ptr;
|
|
|
|
}
|
|
|
|
byte_t*
|
|
|
|
data()
|
|
|
|
{
|
|
|
|
return (byte_t*)_ptr;
|
|
|
|
}
|
|
|
|
size_t
|
|
|
|
size()
|
|
|
|
{
|
|
|
|
return _sz;
|
|
|
|
}
|
|
|
|
byte_t& operator[](size_t sz)
|
|
|
|
{
|
|
|
|
return data()[sz];
|
|
|
|
}
|
|
|
|
void
|
|
|
|
reserve(size_t sz)
|
|
|
|
{
|
|
|
|
if(_ptr)
|
|
|
|
delete[] _ptr;
|
|
|
|
_ptr = new char[sz];
|
2019-10-28 18:34:39 +00:00
|
|
|
_sz = sz;
|
2019-10-02 13:06:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
char* _ptr = nullptr;
|
|
|
|
size_t _sz = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PacketEvent
|
|
|
|
{
|
2019-10-28 18:08:59 +00:00
|
|
|
llarp::Addr remote;
|
|
|
|
PacketBuffer pkt;
|
2019-10-02 13:06:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct llarp_pkt_list : public std::vector< PacketEvent >
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
2018-04-30 13:18:57 +00:00
|
|
|
#endif
|