version 3.0
This commit is contained in:
commit
d837490606
209 changed files with 19662 additions and 0 deletions
24
COPYRIGHT
Normal file
24
COPYRIGHT
Normal file
|
@ -0,0 +1,24 @@
|
|||
WANProxy is distributed under the following terms:
|
||||
|
||||
Copyright (c) 2008-2013 WANProxy.org. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
53
LAYOUT
Normal file
53
LAYOUT
Normal file
|
@ -0,0 +1,53 @@
|
|||
Component directory layout:
|
||||
|
||||
Directory Description
|
||||
============= =============================================================
|
||||
common Non-specific functionality that is of general interest, e.g.
|
||||
the logging system, test infrastructure and Buffer class.
|
||||
common/thread Threading infrastructure.
|
||||
common/timer Time sampling infrastructure.
|
||||
common/uuid UUID API.
|
||||
config General-purpose configuration system infrastructure and some
|
||||
essential types and classes.
|
||||
crypto Cryptographic API and implementations, including hashes, MACs
|
||||
and encryption algorithms.
|
||||
event The event system and infrastructure to support it, such as
|
||||
the various implementations of the poll interface.
|
||||
http HTTP protocol implementation and utility functions.
|
||||
io IO system, namely file descriptors interfaces.
|
||||
io/net Networking abstractions for the IO system, utility functions and
|
||||
protocols.
|
||||
io/pipe Pipe infrastructure; abstractions and useful types.
|
||||
io/socket Sockets interface to the IO system.
|
||||
network Low-level networking, e.g. packet capture.
|
||||
network/uinet User-space TCP/IP stack (see network/uinet/LAYOUT for futher
|
||||
layout info).
|
||||
programs Stand-alone programs, organized into sub-directories named by
|
||||
program.
|
||||
programs/diskdup
|
||||
Block storage demonstration program, for making two block
|
||||
devices or files have identical contents with a minimal number
|
||||
of writes.
|
||||
programs/fwdproxy
|
||||
Simple file-driven port-forwarding proxy.
|
||||
programs/tack File-oriented dictionary compression using XCodec.
|
||||
programs/wanproxy
|
||||
WANProxy.
|
||||
programs/websplat
|
||||
Simple web server.
|
||||
programs/xcdump XCodec stream decoder and pretty-printer.
|
||||
ssh SSH protocol implementation.
|
||||
xcodec The XCodec codec, which performs deduplication, and its
|
||||
internal interfaces.
|
||||
xml Trivial XML functions.
|
||||
zlib Wrappers around zlib, providing Pipes that do inflate and
|
||||
deflate.
|
||||
|
||||
Standard sub-directories:
|
||||
|
||||
Directory Description
|
||||
============= =============================================================
|
||||
test Unit tests.
|
||||
example Example programs which may test functionality in a
|
||||
non-automated fashion or merely provide example usage of a
|
||||
complex interface.
|
12
Makefile
Normal file
12
Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
#SUBDIR+=common
|
||||
#SUBDIR+=config
|
||||
#SUBDIR+=crypto
|
||||
#SUBDIR+=event
|
||||
#SUBDIR+=http
|
||||
#SUBDIR+=io
|
||||
SUBDIR+=programs
|
||||
#SUBDIR+=ssh
|
||||
#SUBDIR+=xcodec
|
||||
#SUBDIR+=zlib
|
||||
|
||||
include common/subdir.mk
|
20
README
Normal file
20
README
Normal file
|
@ -0,0 +1,20 @@
|
|||
WANProxy XTech version 3.0
|
||||
==========================
|
||||
|
||||
This is an efficiency-oriented light-weight version of the original WANProxy as released by Juli Mallett on 2013, modified later by Diego Woitasen to add a persistent cache on disk based on Squid COSS patterns.
|
||||
|
||||
The main objectives of this version have been:
|
||||
|
||||
1. Introduce a multithreaded structure with a helper thread servicing network connections while the main thread takes care of the whole data processing.
|
||||
|
||||
2. Simplify the data flow on the main thread using direct calls instead of callbacks to increase performance and reduce memory usage, so that servers can support hundreds of clients and clients can run on light network appliances.
|
||||
|
||||
3. Optimize the persistent cache on disk making indices faster, avoiding duplication of segments and reusing disk space based on LRU criteria in order to keep data cached as long as it can be useful.
|
||||
|
||||
Only the core wanproxy program is included here without any associated utilities or additional functionalities not essential to its basic operation mode, to be able to optimize this one as much as possible.
|
||||
|
||||
This version has been originated, sponsored and advised by XTech.
|
||||
|
||||
|
||||
|
||||
|
217
TODO
Normal file
217
TODO
Normal file
|
@ -0,0 +1,217 @@
|
|||
High-priority:
|
||||
Add a mechanism for forwarding callbacks between EventThread instances,
|
||||
or even just between thread instances. Have a callback queue and an
|
||||
fd to poll on, and when a remote thread adds something to an empty
|
||||
callback queue, it writes something to the fd so as to wake up its
|
||||
peer thread. NB: Even better if the poll-compatible wakeups (note,
|
||||
that's the real point here: don't want to mix fd polling and cv waiting,
|
||||
for instance) were dependent on the EventPoll implementation. That way
|
||||
we could use kqueue's user types, etc., rather than needing to use a
|
||||
pipe.
|
||||
|
||||
Alternately, move fd polling to its own thread and use condvars and
|
||||
callback queues for everything else.
|
||||
|
||||
As part of testing/enabling/proofing that work, split EventThread into
|
||||
two threads, and add one more. One thread which does FD polling. One
|
||||
thread which does callback / timeout dispatch. And then move the I/O
|
||||
system into its own thread. Does that sound about right? Easy then to
|
||||
start to move other things to their own threads, because the threading
|
||||
concerns of each of those subsystems would be covered. So we could
|
||||
have some number of XCodec threads or whatever. A work submission
|
||||
model that's fairly generic would be nice. So you could submit
|
||||
callbacks or timeouts to the callback thread, fd registration and
|
||||
deregestration to the poll thread, and I/O requests to the I/O thread.
|
||||
|
||||
Adds some latency, but probably worth it?
|
||||
|
||||
And for threads which need a specialized work submission process, we
|
||||
could just override some method from Thread. Have a simple base class
|
||||
for work items, let each type of thread do a dynamic_cast from there
|
||||
up? Or provide more specific interfaces, do queueing in each thread's
|
||||
class, and just provide a common alert() / biff() / ping() / wakeup()
|
||||
method which alerts that an empty mailbox has become non-empty. So
|
||||
the poll thread doesn't have to use condvars AND fds somehow. And let
|
||||
each thread specify a timeout for sleeping, mostly useful for the
|
||||
callback thread.
|
||||
|
||||
Make it so that Actions can be given a callback after they are created, and
|
||||
then the source of the Action from that gets the hint to start and where to
|
||||
continue after the asynchronous action. This has the nice benefit of getting
|
||||
rid of the callback parameter to async methods, e.g.
|
||||
handler_.wait(socket_->read(0, handler_.callback()));
|
||||
Becomes:
|
||||
handler_.wait(socket_->read(0));
|
||||
Where handler_.wait is like:
|
||||
void wait(Action *a)
|
||||
{
|
||||
a->callback(this, &EventHandler::handle_callback);
|
||||
action_ = a;
|
||||
}
|
||||
Alternately, it would be nice to make asynchronous interfaces move to taking
|
||||
CallbackHandler or EventHandler instances, e.g.
|
||||
socket_->read(0, &handler_);
|
||||
And then socket_->read is like:
|
||||
void read(size_t amt, EventHandler *handler)
|
||||
{
|
||||
read_callback_ = handler->callback();
|
||||
handler->wait(cancellation(this, Socket::read_cancel));
|
||||
|
||||
start_read();
|
||||
}
|
||||
|
||||
I feel like continuing to live with these possibilities may make clear how the
|
||||
various APIs may best change, e.g. perhaps read should be:
|
||||
void read(size_t amt, EventHandler *handler)
|
||||
{
|
||||
read_handler_ = handler;
|
||||
read_handler_->cancellation(this, Socket::read_cancel);
|
||||
|
||||
start_read();
|
||||
}
|
||||
...
|
||||
void read_complete(Event e)
|
||||
{
|
||||
read_handler_->consume(e);
|
||||
}
|
||||
|
||||
%%%
|
||||
|
||||
o) Do a pass with Log taking a LogHandle& not a const LogHandle& so I can
|
||||
find places using hard-coded strings to move into LogHandles. Using a
|
||||
LogHandle is vastly superior since it probably means doing the right
|
||||
thing in virtual classes so that errors in the base class caused by the
|
||||
subclass make it clear where the problem might be.
|
||||
|
||||
o) PipeProducer::input_do; PipeProducer::input_cork(), partial consume() ->
|
||||
require input_cork().
|
||||
|
||||
Note:
|
||||
o) Callbacks are going through a period of major change. For now, except for
|
||||
the CallbackSchedulers, it is assumed that all callbacks will need to be
|
||||
strongly typed, that is that most interfaces will take a SimpleCallback or
|
||||
an EventCallback or similar, and use it directly. This will mostly be a
|
||||
problem in the TimeoutQueue. If some class feels that it ought to be able
|
||||
to schedule a timeout to handle a callback for, say, an EventCallback that
|
||||
has already had its parameter set, we'll have problems.
|
||||
|
||||
NB: Once all extant code is converted in this manner, the CallbackBase
|
||||
class could be named back to Callback, but since few things should be
|
||||
using it directly, the more obtuse name may be desirable as an aid in
|
||||
avoiding foot-shooting. Or just rename CallbackBase to Schedulable
|
||||
and have done with it.
|
||||
|
||||
XXX Eventually the schedule function could be moved into SimpleCallback,
|
||||
TypedCallback, etc., so that we can in the latter case blow up badly
|
||||
if someone asks to schedule a function whose parameter has not been
|
||||
set.
|
||||
|
||||
o) Make tack use the EventSystem and IOSystem now that the performance of
|
||||
the latter is substantially better than the hand-rolled I/O of tack.
|
||||
o) Replace singletons with thread-local storage.
|
||||
o) Get simple packet capture/injection stuff working, enough to do some trivial
|
||||
packet tunneling / deduplication stuff.
|
||||
o) Packet framing, so we can divide incoming Buffers up into protocol control
|
||||
and data fields, so that we deduplicate at useful boundaries and don't do
|
||||
things like include ephemeral fields or sensitive information.
|
||||
o) Begin introducing locking.
|
||||
o) Split polling across multiple threads, or do callbacks in one thread and
|
||||
run the IOSystem on another (IOThread?)
|
||||
o) Find ways to reduce the cost of the EventThread abstraction, possibly by
|
||||
decomposing it into several things and running timeouts and polling in
|
||||
separate threads, so the inner loops are tighter. callback-speed1 has
|
||||
gotten quite painful on Mac OS X (though little impact on FreeBSD, perhaps
|
||||
thread-local storage is faster on FreeBSD?)
|
||||
o) Add centralized implementations of Catenate and other patterns in lots of
|
||||
the tests.
|
||||
o) When splitting things into different threads, add a pipe-oriented condition
|
||||
variable facility or something, at least for threads which need to poll,
|
||||
rather than just use condition variabls. Or perhaps we should just use an
|
||||
inter-thread messaging paradigm to handle different queues for each thread,
|
||||
which is slow but we can probably batch updates through a scheduler.
|
||||
|
||||
For 0.7.1:
|
||||
o) Add an ActionCache which classes can use to dole out Actions and which at
|
||||
destruction time will assert that there are no outstanding actions. This
|
||||
will make debugging code involving Actions easier and give better Action
|
||||
allocation performance, done properly.
|
||||
|
||||
For 0.7.2:
|
||||
o) Test error handling in epoll.
|
||||
o) Test error handling with port(3C).
|
||||
o) Make UnixClient and UnixServer take the SocketType as an argument to make
|
||||
it possible to support both stream-orientation and datagram-orientation?
|
||||
Would need to update UnixServer's API to support both models.
|
||||
o) Something higher-level than Pipe which supports various disciplines and
|
||||
makes it easier to write stream processing modules.
|
||||
o) Make *Client::connect() work like TCPClient::connect().
|
||||
o) Move to the getrusage-based Timer class and make it clear that that is what
|
||||
it is for. Perhaps create a Timer base class and a UserTimer and WallTimer
|
||||
for real use?
|
||||
o) Add a flush token for Pipe::input() ?
|
||||
o) Add a flush Event type for Pipe::output() ?
|
||||
XXX It's unclear, but I think a flush method or similar may be needed to
|
||||
implement buffer limiting? A flush method being like input(), except
|
||||
that it only returns once the last Pipe in the Pipeline has returned
|
||||
flush complete, or error if data cannot be flushed because there is not
|
||||
enough to finish processing the data that is pending, at which point
|
||||
you at least know that everything else has been flushed?
|
||||
o) Make Pipe::input take a parameter to send EOS along with data.
|
||||
o) How do we find out if remote has shut down read channel so we can stop
|
||||
writing and shut down a Splice?
|
||||
o) Make interface/listener objects automatically start listening.
|
||||
o) Clean up address configuration objects to be more sensible, being either
|
||||
specific components of addresses (e.g. to specify an IP address) or socket
|
||||
addresses (e.g. AF_UNIX paths, IP+port pairs for TCP or UDP or SCTP.)
|
||||
o) Connector abstraction: connection pooling / connecting via a SOCKS server.
|
||||
|
||||
For 0.8.0:
|
||||
o) Cache hierarchy, including persistent storage.
|
||||
o) TLS.
|
||||
|
||||
For 0.9.0:
|
||||
o) Handle TCP OOB data.
|
||||
|
||||
After 1.0.0:
|
||||
o) A CLI program for management. Remember to USE_POLL=select since Mac OS X can
|
||||
only use select(2) for stdin and stdout.
|
||||
o) Make it possible to detect when we are sending to a socket that is also
|
||||
within WANProxy and avoid a system call -- just copy directly to the
|
||||
appropriate buffer. It should be pretty easy to do this with the IO queueing
|
||||
system if we getpeername/getsockname to identify this occurring.
|
||||
o) Add an IO queueing system that will make it possible to use lio_listio on
|
||||
systems that support it.
|
||||
o) Make the XCodec encoder and decoder asynchronous.
|
||||
o) Connection table. Database.
|
||||
o) HTTP termination and reinitiation good enough to support an HTTP proxy mode.
|
||||
|
||||
Ongoing:
|
||||
o) Add lots of comments.
|
||||
o) Fix bugs.
|
||||
o) Audit log levels.
|
||||
o) Try to remove HALTs and NOTREACHEDs that aren't legitimate.
|
||||
o) Give better debug information from configuration system.
|
||||
|
||||
Maybe:
|
||||
o) A resolver that's less fragile than the OS-supplied ones. Mac OS X, at
|
||||
minimum, neither keeps a pool of file descriptors nor errors out gracefully
|
||||
when the OS is out of them, leading to hangs.
|
||||
o) Send definitions out-of-band, too, so that QoS and backpressure on one
|
||||
connection can't delay other connections.
|
||||
o) In-path forwarding using BPF and a tiny network stack.
|
||||
o) Run-length-encoding.
|
||||
o) Many compression algorithms.
|
||||
o) Allow chaining codecs.
|
||||
o) SOCKS IPv6 support.
|
||||
o) Some decent way to configure Pipelines.
|
||||
o) Figure out a good name for a Pipeline, since Pipeline seems rubbish.
|
||||
o) Merge two Pipelines.
|
||||
o) Convert the SOCKS proxy server to a PipeEndpoint that merges the Pipeline
|
||||
that it is connected to with a newly-created one.
|
||||
o) Be less protocol-ignorant; add protocol-aware framing to WANProxy. For
|
||||
example, HTTP response headers are likely to include some amount of changing
|
||||
data (timestamps, etc.) so perhaps it's better to take a clean shot at the
|
||||
start of the content. And perhaps it's better to convert to large chunks in
|
||||
chunked encoding mode to get bigger windows of data to encode. No need to
|
||||
remember the last 3 bytes of a chunk, the chunk header, and the next N bytes,
|
||||
if the chunks won't be laid out the same every time. Right?
|
5
common/Makefile
Normal file
5
common/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
SUBDIR+=thread
|
||||
SUBDIR+=timer
|
||||
SUBDIR+=uuid
|
||||
|
||||
include ../common/subdir.mk
|
167
common/buffer.cc
Normal file
167
common/buffer.cc
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/uio.h>
|
||||
#include <limits.h>
|
||||
#include <iostream>
|
||||
#include <common/limits.h>
|
||||
#include <common/buffer.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: buffer.cc //
|
||||
// Description: generic buffer composed by reference counted segments //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if USING_SEGMENT_CACHE
|
||||
std::deque<BufferSegment *> BufferSegment::segment_cache;
|
||||
pthread_mutex_t BufferSegment::segment_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
size_t
|
||||
Buffer::fill_iovec(struct iovec *iov, size_t niov) const
|
||||
{
|
||||
if (niov == 0)
|
||||
return (0);
|
||||
|
||||
if (niov > IOV_MAX)
|
||||
niov = IOV_MAX;
|
||||
|
||||
segment_list_t::const_iterator iter = data_.begin();
|
||||
size_t iovcnt = 0;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < niov; i++) {
|
||||
if (iter == data_.end())
|
||||
break;
|
||||
const BufferSegment *seg = *iter;
|
||||
iov[i].iov_base = (void *)(uintptr_t)seg->data();
|
||||
iov[i].iov_len = seg->length();
|
||||
iovcnt++;
|
||||
iter++;
|
||||
}
|
||||
return (iovcnt);
|
||||
}
|
||||
|
||||
std::string
|
||||
Buffer::hexdump(unsigned start) const
|
||||
{
|
||||
static const char hexchars[] = "0123456789abcdef";
|
||||
|
||||
std::string hex;
|
||||
std::string vis;
|
||||
|
||||
segment_list_t::const_iterator iter = data_.begin();
|
||||
while (iter != data_.end()) {
|
||||
const BufferSegment *seg = *iter++;
|
||||
const uint8_t *p;
|
||||
|
||||
for (p = seg->data(); p < seg->end(); p++) {
|
||||
hex += hexchars[(*p & 0xf0) >> 4];
|
||||
hex += hexchars[*p & 0xf];
|
||||
|
||||
if (isprint(*p))
|
||||
vis += (char)*p;
|
||||
else
|
||||
vis += '.';
|
||||
}
|
||||
}
|
||||
|
||||
std::string dump;
|
||||
unsigned cur = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned offset = start + cur;
|
||||
std::string str;
|
||||
unsigned n;
|
||||
|
||||
while (offset != 0) {
|
||||
str = hexchars[offset & 0xf] + str;
|
||||
offset >>= 4;
|
||||
}
|
||||
|
||||
while (str.length() < 8)
|
||||
str = '0' + str;
|
||||
|
||||
dump += str;
|
||||
|
||||
if (cur == length_) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print hex.
|
||||
*/
|
||||
for (n = 0; n < 16; n++) {
|
||||
if (n % 8 == 0)
|
||||
dump += " ";
|
||||
dump += " ";
|
||||
if (cur + n < length_) {
|
||||
dump += hex[n * 2];
|
||||
dump += hex[n * 2 + 1];
|
||||
} else {
|
||||
hex = "";
|
||||
dump += " ";
|
||||
}
|
||||
}
|
||||
if (hex != "")
|
||||
hex = hex.substr(32);
|
||||
|
||||
dump += " |";
|
||||
for (n = 0; cur < length_ && n < 16; n++) {
|
||||
dump += vis[n];
|
||||
cur++;
|
||||
}
|
||||
if (cur < length_)
|
||||
vis = vis.substr(16);
|
||||
dump += "|";
|
||||
|
||||
if (cur == length_ && cur % 16 == 0)
|
||||
break;
|
||||
|
||||
dump += "\n";
|
||||
}
|
||||
|
||||
|
||||
return (dump);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, const Buffer *buf)
|
||||
{
|
||||
std::string str;
|
||||
buf->extract(str);
|
||||
return (os << str);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, const Buffer& buf)
|
||||
{
|
||||
return (os << &buf);
|
||||
}
|
1755
common/buffer.h
Normal file
1755
common/buffer.h
Normal file
File diff suppressed because it is too large
Load diff
42
common/common.h
Normal file
42
common/common.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_COMMON_H
|
||||
#define COMMON_COMMON_H
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/log.h>
|
||||
#include <common/types.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <string> /* Already here for log.h, but be explicit. */
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wcovered-switch-default"
|
||||
#endif
|
||||
|
||||
#endif /* !COMMON_COMMON_H */
|
69
common/debug.h
Normal file
69
common/debug.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_DEBUG_H
|
||||
#define COMMON_DEBUG_H
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#define ASSERT(log, p) \
|
||||
do { \
|
||||
if (false) \
|
||||
(void)(p); \
|
||||
} while (0)
|
||||
#else
|
||||
#define ASSERT(log, p) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
HALT((log)) << "Assertion (" << #p << \
|
||||
") failed at " \
|
||||
<< __FILE__ << ':' << __LINE__ \
|
||||
<< " in function " \
|
||||
<< __PRETTY_FUNCTION__ \
|
||||
<< '.'; \
|
||||
for (;;) \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Newer GCCs are horribly broken and seem to have become unable to detect
|
||||
* that HALT(x) << bar will prevent a function ever returning. We add the
|
||||
* infinite loop here to help.
|
||||
*/
|
||||
#if defined(NDEBUG)
|
||||
#define NOTREACHED(log) \
|
||||
abort()
|
||||
#else
|
||||
#define NOTREACHED(log) \
|
||||
do { \
|
||||
ASSERT(log, "Should not be reached." == NULL); \
|
||||
for (;;) \
|
||||
abort(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* !COMMON_DEBUG_H */
|
141
common/endian.h
Normal file
141
common/endian.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ENDIAN_H
|
||||
#define COMMON_ENDIAN_H
|
||||
|
||||
#if !defined(BYTE_ORDER) && !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#if defined(_LITTLE_ENDIAN)
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#elif defined(_BIG_ENDIAN)
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#else
|
||||
#error "Can't determine host byte order."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#error "BYTE_ORDER must be defined."
|
||||
#else
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#elif BYTE_ORDER == BIG_ENDIAN
|
||||
#else
|
||||
#error "Unexpected BYTE_ORDER value."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct Endian {
|
||||
static uint16_t swap(const uint16_t& in)
|
||||
{
|
||||
return (((in & 0xff00u) >> 0x08) | ((in & 0x00ffu) << 0x08));
|
||||
}
|
||||
|
||||
static uint32_t swap(const uint32_t& in)
|
||||
{
|
||||
return (((in & 0xff000000u) >> 0x18) |
|
||||
((in & 0x00ff0000u) >> 0x08) |
|
||||
((in & 0x0000ff00u) << 0x08) |
|
||||
((in & 0x000000ffu) << 0x18));
|
||||
}
|
||||
|
||||
static uint64_t swap(const uint64_t& in)
|
||||
{
|
||||
return (((in & 0xff00000000000000ull) >> 0x38) |
|
||||
((in & 0x00ff000000000000ull) >> 0x28) |
|
||||
((in & 0x0000ff0000000000ull) >> 0x18) |
|
||||
((in & 0x000000ff00000000ull) >> 0x08) |
|
||||
((in & 0x00000000ff000000ull) << 0x08) |
|
||||
((in & 0x0000000000ff0000ull) << 0x18) |
|
||||
((in & 0x000000000000ff00ull) << 0x28) |
|
||||
((in & 0x00000000000000ffull) << 0x38));
|
||||
}
|
||||
};
|
||||
|
||||
struct SwapEndian {
|
||||
template<typename T>
|
||||
static T encode(const T& in)
|
||||
{
|
||||
return (Endian::swap(in));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T decode(const T& in)
|
||||
{
|
||||
return (Endian::swap(in));
|
||||
}
|
||||
|
||||
template<class C, typename T>
|
||||
static void append(C *out, const T& in)
|
||||
{
|
||||
T swapped = encode(in);
|
||||
out->append(&swapped);
|
||||
}
|
||||
|
||||
template<class C, typename T>
|
||||
static void extract(T *out, const C *in)
|
||||
{
|
||||
T wire;
|
||||
in->extract(&wire);
|
||||
*out = decode(wire);
|
||||
}
|
||||
};
|
||||
|
||||
struct HostEndian {
|
||||
template<typename T>
|
||||
static T encode(const T& in)
|
||||
{
|
||||
return (in);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T decode(const T& in)
|
||||
{
|
||||
return (in);
|
||||
}
|
||||
|
||||
template<class C, typename T>
|
||||
static void append(C *out, const T& in)
|
||||
{
|
||||
out->append(&in);
|
||||
}
|
||||
|
||||
template<class C, typename T>
|
||||
static void extract(T *out, const C *in)
|
||||
{
|
||||
in->extract(out);
|
||||
}
|
||||
};
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
typedef HostEndian LittleEndian;
|
||||
typedef SwapEndian BigEndian;
|
||||
#elif BYTE_ORDER == BIG_ENDIAN
|
||||
typedef SwapEndian LittleEndian;
|
||||
typedef HostEndian BigEndian;
|
||||
#endif
|
||||
|
||||
#endif /* !COMMON_ENDIAN_H */
|
171
common/factory.h
Normal file
171
common/factory.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_FACTORY_H
|
||||
#define COMMON_FACTORY_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
template<class C>
|
||||
class Factory {
|
||||
public:
|
||||
Factory(void)
|
||||
{ }
|
||||
|
||||
virtual ~Factory()
|
||||
{ }
|
||||
|
||||
virtual C *create(void) const = 0;
|
||||
};
|
||||
|
||||
template<class B, class C>
|
||||
class ConstructorFactory : public Factory<B> {
|
||||
public:
|
||||
ConstructorFactory(void)
|
||||
{ }
|
||||
|
||||
~ConstructorFactory()
|
||||
{ }
|
||||
|
||||
B *create(void) const
|
||||
{
|
||||
return (new C());
|
||||
}
|
||||
};
|
||||
|
||||
template<class B, class C, typename A>
|
||||
class ConstructorArgFactory : public Factory<B> {
|
||||
A a_;
|
||||
public:
|
||||
ConstructorArgFactory(A a)
|
||||
: a_(a)
|
||||
{ }
|
||||
|
||||
~ConstructorArgFactory()
|
||||
{ }
|
||||
|
||||
B *create(void) const
|
||||
{
|
||||
return (new C(a_));
|
||||
}
|
||||
};
|
||||
|
||||
template<class B, class C>
|
||||
class SubclassFactory : public Factory<B> {
|
||||
Factory<C> *factory_;
|
||||
public:
|
||||
SubclassFactory(Factory<C> *factory)
|
||||
: factory_(factory)
|
||||
{ }
|
||||
|
||||
~SubclassFactory()
|
||||
{
|
||||
delete factory_;
|
||||
factory_ = NULL;
|
||||
}
|
||||
|
||||
B *create(void) const
|
||||
{
|
||||
return (factory_->create());
|
||||
}
|
||||
};
|
||||
|
||||
template<class B, class C = B>
|
||||
struct factory {
|
||||
Factory<B> *operator() (void) const
|
||||
{
|
||||
return (new ConstructorFactory<B, C>);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Factory<B> *operator() (T arg) const
|
||||
{
|
||||
return (new ConstructorArgFactory<B, C, T>(arg));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename K, typename C>
|
||||
class FactoryMap {
|
||||
typedef std::map<K, Factory<C> *> map_type;
|
||||
|
||||
map_type map_;
|
||||
public:
|
||||
FactoryMap(void)
|
||||
: map_()
|
||||
{ }
|
||||
|
||||
~FactoryMap()
|
||||
{
|
||||
typename map_type::iterator it;
|
||||
|
||||
while ((it = map_.begin()) != map_.end()) {
|
||||
delete it->second;
|
||||
map_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
C *create(const K& key) const
|
||||
{
|
||||
typename map_type::const_iterator it;
|
||||
|
||||
it = map_.find(key);
|
||||
if (it == map_.end())
|
||||
return (NULL);
|
||||
return (it->second->create());
|
||||
}
|
||||
|
||||
void enter(const K& key, Factory<C> *factory)
|
||||
{
|
||||
typename map_type::iterator it;
|
||||
|
||||
it = map_.find(key);
|
||||
if (it != map_.end()) {
|
||||
delete it->second;
|
||||
map_.erase(it);
|
||||
}
|
||||
|
||||
map_[key] = factory;
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
void enter(const K& key, Factory<S> *factory)
|
||||
{
|
||||
enter(key, new SubclassFactory<C, S>(factory));
|
||||
}
|
||||
|
||||
std::set<K> keys(void) const
|
||||
{
|
||||
typename map_type::const_iterator it;
|
||||
std::set<K> key_set;
|
||||
|
||||
for (it = map_.begin(); it != map_.end(); ++it)
|
||||
key_set.insert(it->first);
|
||||
|
||||
return (key_set);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !COMMON_FACTORY_H */
|
82
common/filter.h
Normal file
82
common/filter.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: filter.h //
|
||||
// Description: base classes for chained data processors //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COMMON_FILTER_H
|
||||
#define COMMON_FILTER_H
|
||||
|
||||
#include <list>
|
||||
#include <common/log.h>
|
||||
#include <common/buffer.h>
|
||||
|
||||
class Filter
|
||||
{
|
||||
private:
|
||||
Filter* recipient_;
|
||||
|
||||
public:
|
||||
Filter () { recipient_ = 0; }
|
||||
virtual ~Filter () { }
|
||||
|
||||
void chain (Filter* nxt) { recipient_ = nxt; }
|
||||
virtual bool consume (Buffer& buf) { return produce (buf); }
|
||||
virtual bool produce (Buffer& buf) { return (recipient_ && recipient_->consume (buf)); }
|
||||
virtual void flush (int flg) { if (recipient_) recipient_->flush (flg); }
|
||||
};
|
||||
|
||||
class CountFilter : public Filter
|
||||
{
|
||||
private:
|
||||
intmax_t& counter_;
|
||||
|
||||
public:
|
||||
CountFilter (intmax_t& p) : counter_(p) { }
|
||||
virtual bool consume (Buffer& buf) { counter_ += buf.length (); return produce (buf); }
|
||||
};
|
||||
|
||||
class BufferedFilter : public Filter
|
||||
{
|
||||
protected:
|
||||
LogHandle log_;
|
||||
Buffer pending_;
|
||||
bool flushing_;
|
||||
int flush_flags_;
|
||||
|
||||
public:
|
||||
BufferedFilter (const LogHandle& log) : log_ (log) { flushing_ = 0; flush_flags_ = 0; }
|
||||
};
|
||||
|
||||
class LogisticFilter : public BufferedFilter
|
||||
{
|
||||
protected:
|
||||
Filter* upstream_;
|
||||
|
||||
public:
|
||||
LogisticFilter (const LogHandle& log) : BufferedFilter (log) { upstream_ = 0; }
|
||||
void set_upstream (Filter* f) { upstream_ = f; }
|
||||
};
|
||||
|
||||
class FilterChain : public Filter
|
||||
{
|
||||
private:
|
||||
std::list<Filter*> nodes_;
|
||||
Filter* holder_;
|
||||
|
||||
public:
|
||||
FilterChain (Filter* f) { holder_ = f; }
|
||||
virtual ~FilterChain () { while (! nodes_.empty ()) { delete nodes_.front (); nodes_.pop_front (); }}
|
||||
|
||||
void prepend (Filter* f) { Filter* act = (nodes_.empty () ? holder_ : nodes_.front ());
|
||||
if (f && act) nodes_.push_front (f), chain (f), f->chain (act); }
|
||||
void append (Filter* f) { Filter* act = (nodes_.empty () ? this : nodes_.front ());
|
||||
if (f && act) nodes_.push_front (f), act->chain (f), f->chain (holder_); }
|
||||
virtual void flush (int flg) { if (nodes_.empty ()) chain (holder_); Filter::flush (flg); }
|
||||
};
|
||||
|
||||
#endif /* !COMMON_FILTER_H */
|
6
common/lib.mk
Normal file
6
common/lib.mk
Normal file
|
@ -0,0 +1,6 @@
|
|||
VPATH+= ${TOPDIR}/common
|
||||
|
||||
SRCS+= buffer.cc
|
||||
SRCS+= log.cc
|
||||
|
||||
CXXFLAGS+=-include common/common.h
|
33
common/limits.h
Normal file
33
common/limits.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_LIMITS_H
|
||||
#define COMMON_LIMITS_H
|
||||
|
||||
#if defined(__OPENNT)
|
||||
#define IOV_MAX 1024
|
||||
#endif
|
||||
|
||||
#endif /* !COMMON_LIMITS_H */
|
188
common/log.cc
Normal file
188
common/log.cc
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef USE_SYSLOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
struct LogMask {
|
||||
regex_t regex_;
|
||||
enum Log::Priority priority_;
|
||||
};
|
||||
|
||||
static std::list<LogMask> log_masks;
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
static int syslog_priority(const Log::Priority&);
|
||||
#endif
|
||||
static std::ostream& operator<< (std::ostream&, const Log::Priority&);
|
||||
static std::ostream& operator<< (std::ostream&, const struct timeval&);
|
||||
|
||||
void
|
||||
Log::log(const Priority& priority, const LogHandle& handle,
|
||||
const std::string& message)
|
||||
{
|
||||
std::list<LogMask>::const_iterator it;
|
||||
std::string handle_string = (std::string)handle;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Skip this all if we're in a HALT or NOTREACHED, since we can
|
||||
* generate those here. Critical logs cannot ever be masked, right?
|
||||
*/
|
||||
for (it = log_masks.begin(); it != log_masks.end(); ++it) {
|
||||
const LogMask& mask = *it;
|
||||
int rv;
|
||||
|
||||
rv = regexec(&mask.regex_, handle_string.c_str(), 0, NULL, 0);
|
||||
switch (rv) {
|
||||
case 0:
|
||||
if (priority <= mask.priority_)
|
||||
goto done;
|
||||
return;
|
||||
case REG_NOMATCH:
|
||||
continue;
|
||||
default:
|
||||
HALT("/log") << "Could not match regex: " << rv;
|
||||
return;
|
||||
}
|
||||
NOTREACHED("/log");
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef USE_SYSLOG
|
||||
std::string syslog_message;
|
||||
|
||||
syslog_message += "[";
|
||||
syslog_message += (std::string)handle;
|
||||
syslog_message += "] ";
|
||||
syslog_message += message;
|
||||
|
||||
syslog(syslog_priority(priority), "%s", syslog_message.c_str());
|
||||
#endif
|
||||
|
||||
struct timeval now;
|
||||
int rv;
|
||||
|
||||
rv = gettimeofday(&now, NULL);
|
||||
if (rv == -1)
|
||||
memset(&now, 0, sizeof now);
|
||||
|
||||
std::cerr << now << " [" << handle_string << "] " <<
|
||||
priority << ": " <<
|
||||
message <<
|
||||
std::endl;
|
||||
}
|
||||
|
||||
bool
|
||||
Log::mask(const std::string& handle_regex, const Log::Priority& priority)
|
||||
{
|
||||
LogMask mask;
|
||||
|
||||
if (::regcomp(&mask.regex_, handle_regex.c_str(),
|
||||
REG_NOSUB | REG_EXTENDED) != 0) {
|
||||
return (false);
|
||||
}
|
||||
mask.priority_ = priority;
|
||||
|
||||
log_masks.push_back(mask);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
static int
|
||||
syslog_priority(const Log::Priority& priority)
|
||||
{
|
||||
switch (priority) {
|
||||
case Log::Emergency:
|
||||
return (LOG_EMERG);
|
||||
case Log::Alert:
|
||||
return (LOG_ALERT);
|
||||
case Log::Critical:
|
||||
return (LOG_CRIT);
|
||||
case Log::Error:
|
||||
return (LOG_ERR);
|
||||
case Log::Warning:
|
||||
return (LOG_WARNING);
|
||||
case Log::Notice:
|
||||
return (LOG_NOTICE);
|
||||
case Log::Info:
|
||||
return (LOG_INFO);
|
||||
case Log::Debug:
|
||||
case Log::Trace:
|
||||
return (LOG_DEBUG);
|
||||
default:
|
||||
HALT("/log") << "Unhandled log priority!";
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::ostream&
|
||||
operator<< (std::ostream& os, const Log::Priority& priority)
|
||||
{
|
||||
switch (priority) {
|
||||
case Log::Emergency:
|
||||
return (os << "EMERG");
|
||||
case Log::Alert:
|
||||
return (os << "ALERT");
|
||||
case Log::Critical:
|
||||
return (os << "CRIT");
|
||||
case Log::Error:
|
||||
return (os << "ERR");
|
||||
case Log::Warning:
|
||||
return (os << "WARNING");
|
||||
case Log::Notice:
|
||||
return (os << "NOTICE");
|
||||
case Log::Info:
|
||||
return (os << "INFO");
|
||||
case Log::Debug:
|
||||
return (os << "DEBUG");
|
||||
case Log::Trace:
|
||||
return (os << "TRACE");
|
||||
default:
|
||||
HALT("/log") << "Unhandled log priority!";
|
||||
return (os);
|
||||
}
|
||||
}
|
||||
|
||||
static std::ostream&
|
||||
operator<< (std::ostream& os, const struct timeval& tv)
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
snprintf(buf, sizeof buf, "%u.%06u", (unsigned)tv.tv_sec,
|
||||
(unsigned)tv.tv_usec);
|
||||
return (os << buf);
|
||||
}
|
217
common/log.h
Normal file
217
common/log.h
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_LOG_H
|
||||
#define COMMON_LOG_H
|
||||
|
||||
#include <stdlib.h> /* For abort(3). */
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
class LogNull {
|
||||
public:
|
||||
LogNull(void)
|
||||
{ }
|
||||
|
||||
~LogNull()
|
||||
{ }
|
||||
|
||||
template<typename T>
|
||||
const LogNull& operator<< (T) const
|
||||
{
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LogNull& operator<< (std::ostream& (*)(std::ostream&)) const
|
||||
{
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
|
||||
class LogHandle {
|
||||
std::string string_;
|
||||
public:
|
||||
LogHandle(const char *s)
|
||||
: string_(s)
|
||||
{ }
|
||||
|
||||
LogHandle(const std::string& s)
|
||||
: string_(s)
|
||||
{ }
|
||||
|
||||
~LogHandle()
|
||||
{ }
|
||||
|
||||
operator const std::string& (void) const
|
||||
{
|
||||
return (string_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
LogHandle operator+ (T x) const
|
||||
{
|
||||
LogHandle appended = *this;
|
||||
appended.string_ += x;
|
||||
return (appended);
|
||||
}
|
||||
};
|
||||
|
||||
class Log {
|
||||
public:
|
||||
enum Priority {
|
||||
Emergency,
|
||||
Alert,
|
||||
Critical,
|
||||
Error,
|
||||
Warning,
|
||||
Notice,
|
||||
Info,
|
||||
Trace,
|
||||
Debug,
|
||||
};
|
||||
|
||||
class Halt {
|
||||
public:
|
||||
Halt(void)
|
||||
{ }
|
||||
|
||||
~Halt()
|
||||
{ }
|
||||
};
|
||||
|
||||
private:
|
||||
LogHandle handle_;
|
||||
Priority priority_;
|
||||
std::ostringstream str_;
|
||||
bool pending_;
|
||||
bool halted_;
|
||||
public:
|
||||
Log(const LogHandle& handle, const Priority& priority, const std::string function)
|
||||
: handle_(handle),
|
||||
priority_(priority),
|
||||
str_(),
|
||||
pending_(false),
|
||||
halted_(false)
|
||||
{
|
||||
/*
|
||||
* Print the function name for non-routine messages.
|
||||
*/
|
||||
switch (priority_) {
|
||||
case Emergency:
|
||||
case Alert:
|
||||
case Critical:
|
||||
case Error:
|
||||
#if !defined(NDEBUG)
|
||||
case Debug:
|
||||
#endif
|
||||
str_ << function << ": ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
~Log()
|
||||
{
|
||||
flush();
|
||||
if (halted_) {
|
||||
abort(); /* XXX */
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream&
|
||||
operator << (T x)
|
||||
{
|
||||
pending_ = true;
|
||||
return (str_ << x);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator << (const Halt&)
|
||||
{
|
||||
pending_ = true;
|
||||
halted_ = true;
|
||||
return (str_ << "Halting: ");
|
||||
}
|
||||
|
||||
void
|
||||
flush(void)
|
||||
{
|
||||
if (!pending_)
|
||||
return;
|
||||
Log::log(priority_, handle_, str_.str());
|
||||
}
|
||||
|
||||
static void log(const Priority&, const LogHandle&, const std::string&);
|
||||
static bool mask(const std::string&, const Priority&);
|
||||
};
|
||||
|
||||
/* A panic condition. */
|
||||
#define EMERGENCY(log) Log(log, Log::Emergency, __PRETTY_FUNCTION__)
|
||||
/* A condition that should be corrected immediately. */
|
||||
#define ALERT(log) Log(log, Log::Alert, __PRETTY_FUNCTION__)
|
||||
/* Critical condition. */
|
||||
#define CRITICAL(log) Log(log, Log::Critical, __PRETTY_FUNCTION__)
|
||||
/* Errors. */
|
||||
#define ERROR(log) Log(log, Log::Error, __PRETTY_FUNCTION__)
|
||||
/* Warnings. */
|
||||
#define WARNING(log) Log(log, Log::Warning, __PRETTY_FUNCTION__)
|
||||
/* Conditions that are not error conditions, but may need handled. */
|
||||
#define NOTICE(log) Log(log, Log::Notice, __PRETTY_FUNCTION__)
|
||||
/* Informational. */
|
||||
#define INFO(log) Log(log, Log::Info, __PRETTY_FUNCTION__)
|
||||
/* Debugging information. */
|
||||
#if !defined(NDEBUG)
|
||||
#define DEBUG(log) Log(log, Log::Debug, __PRETTY_FUNCTION__)
|
||||
#else
|
||||
#define DEBUG(log) LogNull()
|
||||
#endif
|
||||
|
||||
/* A condition which cannot be continued from. */
|
||||
#define HALT(log) EMERGENCY(log) << Log::Halt()
|
||||
|
||||
class Trace {
|
||||
LogHandle log_;
|
||||
std::string function_;
|
||||
public:
|
||||
Trace(const LogHandle& log, const std::string& function)
|
||||
: log_(log),
|
||||
function_(function)
|
||||
{
|
||||
Log(log_, Log::Trace, __PRETTY_FUNCTION__) << "Entered " << function_;
|
||||
}
|
||||
|
||||
~Trace()
|
||||
{
|
||||
Log(log_, Log::Trace, __PRETTY_FUNCTION__) << "Exited " << function_;
|
||||
}
|
||||
};
|
||||
|
||||
/* Selective debug tracing. */
|
||||
#define TRACE(log) Trace trace_(log, __PRETTY_FUNCTION__)
|
||||
|
||||
#endif /* !COMMON_LOG_H */
|
110
common/program.mk
Normal file
110
common/program.mk
Normal file
|
@ -0,0 +1,110 @@
|
|||
ifndef TOPDIR
|
||||
$(error "TOPDIR must be defined")
|
||||
endif
|
||||
|
||||
ifdef NETWORK_TEST
|
||||
TEST=${NETWORK_TEST}
|
||||
endif
|
||||
|
||||
ifdef SKIP_NETWORK_TESTS
|
||||
SKIP_TESTS=${SKIP_NETWORK_TESTS}
|
||||
endif
|
||||
|
||||
ifdef TEST
|
||||
ifndef SKIP_TESTS
|
||||
PROGRAM=${TEST}
|
||||
SRCS+=${TEST}.cc
|
||||
|
||||
all: ${PROGRAM}
|
||||
|
||||
# Build and run regression tests.
|
||||
regress: ${PROGRAM}
|
||||
ifdef TEST_WRAPPER
|
||||
${TEST_WRAPPER} ${PWD}/${PROGRAM}
|
||||
else
|
||||
${PWD}/${PROGRAM}
|
||||
endif
|
||||
else
|
||||
# Build but don't run regression tests.
|
||||
regress: ${PROGRAM}
|
||||
endif
|
||||
else
|
||||
ifndef PROGRAM
|
||||
$(error "Must have a program to build.")
|
||||
endif
|
||||
|
||||
all: ${PROGRAM}
|
||||
|
||||
# Not a regression test, do nothing.
|
||||
regress:
|
||||
@true
|
||||
endif
|
||||
|
||||
.PHONY: regress
|
||||
|
||||
OSNAME:=$(shell uname -s)
|
||||
|
||||
CFLAGS+=-pipe
|
||||
CPPFLAGS+=-I${TOPDIR}
|
||||
ifdef NDEBUG
|
||||
CFLAGS+=-O2
|
||||
CPPFLAGS+=-DNDEBUG=1
|
||||
else
|
||||
CFLAGS+=-O0
|
||||
ifneq "${OSNAME}" "SunOS"
|
||||
CFLAGS+=-g
|
||||
endif
|
||||
endif
|
||||
|
||||
# OpenBSD needs no -Werror.
|
||||
ifeq "${OSNAME}" "OpenBSD"
|
||||
NO_WERROR=1
|
||||
endif
|
||||
|
||||
# Linux needs no -Werror because the epoll headers are terrible.
|
||||
# XXX Should just disable -Werror for the one file using epoll.
|
||||
ifeq "${OSNAME}" "Linux"
|
||||
NO_WERROR=1
|
||||
endif
|
||||
|
||||
#CFLAGS+=--std gnu++0x
|
||||
#CFLAGS+=-pedantic
|
||||
CFLAGS+=-W -Wall
|
||||
ifndef NO_WERROR
|
||||
CFLAGS+=-Werror
|
||||
endif
|
||||
CFLAGS+=-Wno-system-headers
|
||||
CFLAGS+=-Wno-unused-parameter
|
||||
CFLAGS+=-Wno-switch
|
||||
CFLAGS+=-Wno-uninitialized
|
||||
CFLAGS+=-Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wshadow -Wcast-align -Wchar-subscripts -Wreorder
|
||||
#CFLAGS+=-Winline
|
||||
CXXFLAGS+=-Wno-deprecated
|
||||
CXXFLAGS+=-Wnon-virtual-dtor
|
||||
|
||||
$(foreach _lib,${USE_LIBS},$(eval include ${TOPDIR}/$(strip ${_lib})/lib.mk))
|
||||
|
||||
define __library_conditionals
|
||||
ifdef CFLAGS_${1}
|
||||
CFLAGS+=${CFLAGS_${1}}
|
||||
endif
|
||||
ifdef SRCS_${1}
|
||||
SRCS+= ${SRCS_${1}}
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach _lib,${USE_LIBS},$(eval $(call __library_conditionals,$(subst /,_,${_lib}))))
|
||||
|
||||
OBJS+= $(patsubst %.cc,bin/%.o,$(patsubst %.c,bin/%.o,${SRCS}))
|
||||
|
||||
${PROGRAM}: ${OBJS}
|
||||
${CXX} ${CXXFLAGS} ${CFLAGS} ${LDFLAGS} -o bin/$@ ${OBJS} ${LDADD}
|
||||
|
||||
bin/%.o: %.cc
|
||||
${CXX} ${CPPFLAGS} ${CXXFLAGS} ${CFLAGS} -c -o $@ $<
|
||||
|
||||
bin/%.o: %.c
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f ${PROGRAM} ${OBJS}
|
154
common/ref.h
Normal file
154
common/ref.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_REF_H
|
||||
#define COMMON_REF_H
|
||||
|
||||
template<typename T>
|
||||
class Ref {
|
||||
class RefObj {
|
||||
T *ptr_;
|
||||
unsigned count_;
|
||||
public:
|
||||
RefObj(T *ptr)
|
||||
: ptr_(ptr),
|
||||
count_(1)
|
||||
{ }
|
||||
|
||||
private:
|
||||
~RefObj()
|
||||
{
|
||||
delete ptr_;
|
||||
ptr_ = NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
void hold(void)
|
||||
{
|
||||
count_++;
|
||||
}
|
||||
|
||||
void drop(void)
|
||||
{
|
||||
if (count_-- == 1)
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool exclusive(void) const
|
||||
{
|
||||
return (count_ == 1);
|
||||
}
|
||||
|
||||
T *get(void) const
|
||||
{
|
||||
return (ptr_);
|
||||
}
|
||||
};
|
||||
|
||||
RefObj *obj_;
|
||||
public:
|
||||
Ref(void)
|
||||
: obj_(NULL)
|
||||
{ }
|
||||
|
||||
Ref(T *ptr)
|
||||
: obj_(NULL)
|
||||
{
|
||||
if (ptr != NULL)
|
||||
obj_ = new RefObj(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Template... See operator=.
|
||||
*/
|
||||
Ref(const Ref& ref)
|
||||
: obj_(ref.obj_)
|
||||
{
|
||||
if (obj_ != NULL)
|
||||
obj_->hold();
|
||||
}
|
||||
|
||||
~Ref()
|
||||
{
|
||||
if (obj_ != NULL) {
|
||||
obj_->drop();
|
||||
obj_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Template so we can take a pointer from a Ref<> with a compatible
|
||||
* base class?
|
||||
*/
|
||||
const Ref& operator= (const Ref& ref)
|
||||
{
|
||||
if (obj_ != NULL) {
|
||||
obj_->drop();
|
||||
obj_ = NULL;
|
||||
}
|
||||
|
||||
if (ref.obj_ != NULL) {
|
||||
obj_ = ref.obj_;
|
||||
obj_->hold();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
T *operator-> (void) const
|
||||
{
|
||||
return (obj_->get());
|
||||
}
|
||||
|
||||
const T& operator* (void) const
|
||||
{
|
||||
const T *ptr = obj_->get();
|
||||
return (*ptr);
|
||||
}
|
||||
|
||||
template<typename Tc>
|
||||
Tc cast(void) const
|
||||
{
|
||||
const T *ptr = obj_->get();
|
||||
return (dynamic_cast<Tc>(ptr));
|
||||
}
|
||||
|
||||
bool exclusive(void) const
|
||||
{
|
||||
return (obj_->exclusive());
|
||||
}
|
||||
|
||||
bool null(void) const
|
||||
{
|
||||
return (obj_ == NULL);
|
||||
}
|
||||
|
||||
bool operator< (const Ref& b) const
|
||||
{
|
||||
return (obj_ < b.obj_);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !COMMON_REF_H */
|
66
common/registrar.h
Normal file
66
common/registrar.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_REGISTRAR_H
|
||||
#define COMMON_REGISTRAR_H
|
||||
|
||||
#include <set>
|
||||
|
||||
/*
|
||||
* U is merely a type used as a unique key, so that multiple Registrars of
|
||||
* objects with the same type can coexist.
|
||||
*/
|
||||
template<typename U, typename T>
|
||||
class Registrar {
|
||||
std::set<T> registered_set_;
|
||||
|
||||
Registrar(void)
|
||||
: registered_set_()
|
||||
{ }
|
||||
|
||||
~Registrar()
|
||||
{ }
|
||||
public:
|
||||
void enter(T item)
|
||||
{
|
||||
registered_set_.insert(item);
|
||||
}
|
||||
|
||||
std::set<T> enumerate(void) const
|
||||
{
|
||||
return (registered_set_);
|
||||
}
|
||||
|
||||
static Registrar *instance(void)
|
||||
{
|
||||
static Registrar *instance;
|
||||
|
||||
if (instance == NULL)
|
||||
instance = new Registrar();
|
||||
return (instance);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !COMMON_REGISTRAR_H */
|
151
common/ring_buffer.h
Normal file
151
common/ring_buffer.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: ring_buffer.h //
|
||||
// Description: circular buffer for unlocked exchange of data //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COMMON_RING_BUFFER_H
|
||||
#define COMMON_RING_BUFFER_H
|
||||
|
||||
#define STANDARD_RING_BUFFER_CAPACITY 32768
|
||||
#define ITEM_SIZE ((int) sizeof (T))
|
||||
|
||||
template<typename T, int N = STANDARD_RING_BUFFER_CAPACITY> class RingBuffer
|
||||
{
|
||||
private:
|
||||
unsigned char buffer[N * ITEM_SIZE];
|
||||
unsigned char* reader;
|
||||
unsigned char* writer;
|
||||
|
||||
public:
|
||||
RingBuffer ();
|
||||
|
||||
int read (T& trg);
|
||||
int write (const T& src);
|
||||
|
||||
bool is_empty () { return (reader == writer); }
|
||||
int data_size () { return (writer >= reader ? writer - reader : sizeof buffer - (reader - writer)); }
|
||||
};
|
||||
|
||||
template<typename T, int N> RingBuffer<T, N>::RingBuffer ()
|
||||
{
|
||||
reader = writer = buffer;
|
||||
}
|
||||
|
||||
template<typename T, int N> int RingBuffer<T, N>::read (T& trg)
|
||||
{
|
||||
unsigned char* r;
|
||||
unsigned char* w;
|
||||
int s, t, n1, n2;
|
||||
|
||||
r = reader;
|
||||
w = writer;
|
||||
s = (w >= r ? (w - r) : sizeof buffer - (r - w));
|
||||
if (s >= ITEM_SIZE)
|
||||
{
|
||||
t = buffer + sizeof buffer - r;
|
||||
if (ITEM_SIZE <= t)
|
||||
n1 = ITEM_SIZE, n2 = 0;
|
||||
else
|
||||
n1 = t, n2 = ITEM_SIZE - t;
|
||||
memcpy (&trg, r, n1);
|
||||
if (n2)
|
||||
memcpy (((char*) &trg) + n1, buffer, n2);
|
||||
reader = (ITEM_SIZE < t ? r + n1 : buffer + n2);
|
||||
return ITEM_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T, int N> int RingBuffer<T, N>::write (const T& src)
|
||||
{
|
||||
unsigned char* r;
|
||||
unsigned char* w;
|
||||
int s, t, n1, n2;
|
||||
|
||||
r = reader;
|
||||
w = writer;
|
||||
s = (w >= r ? sizeof buffer - (w - r) : (r - w));
|
||||
if (s > ITEM_SIZE)
|
||||
{
|
||||
t = buffer + sizeof buffer - w;
|
||||
if (ITEM_SIZE <= t)
|
||||
n1 = ITEM_SIZE, n2 = 0;
|
||||
else
|
||||
n1 = t, n2 = ITEM_SIZE - t;
|
||||
memcpy (w, &src, n1);
|
||||
if (n2)
|
||||
memcpy (buffer, ((const char*) &src) + n1, n2);
|
||||
writer = (ITEM_SIZE < t ? w + n1 : buffer + n2);
|
||||
return ITEM_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
template<typename T> class WaitBuffer
|
||||
{
|
||||
private:
|
||||
RingBuffer<T> ring;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t ready;
|
||||
|
||||
public:
|
||||
WaitBuffer ();
|
||||
~WaitBuffer ();
|
||||
|
||||
int read (T& trg);
|
||||
int write (const T& src);
|
||||
|
||||
void wakeup () { if (ring.is_empty ()) pthread_cond_signal (&ready); }
|
||||
};
|
||||
|
||||
template<typename T> WaitBuffer<T>::WaitBuffer ()
|
||||
{
|
||||
pthread_mutex_init (&mutex, 0);
|
||||
pthread_cond_init (&ready, 0);
|
||||
}
|
||||
|
||||
template<typename T> WaitBuffer<T>::~WaitBuffer ()
|
||||
{
|
||||
pthread_mutex_destroy (&mutex);
|
||||
pthread_cond_destroy (&ready);
|
||||
}
|
||||
|
||||
template<typename T> int WaitBuffer<T>::read (T& trg)
|
||||
{
|
||||
if (ring.is_empty ())
|
||||
{
|
||||
pthread_mutex_lock (&mutex);
|
||||
if (ring.is_empty ())
|
||||
pthread_cond_wait (&ready, &mutex);
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
return ring.read (trg);
|
||||
}
|
||||
|
||||
template<typename T> int WaitBuffer<T>::write (const T& src)
|
||||
{
|
||||
int rsl = ring.write (src);
|
||||
|
||||
if (rsl && ring.data_size () == ITEM_SIZE)
|
||||
{
|
||||
pthread_mutex_lock (&mutex);
|
||||
pthread_cond_signal (&ready);
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
return rsl;
|
||||
}
|
||||
|
||||
#endif /* !COMMON_RING_BUFFER_H */
|
7
common/subdir.mk
Normal file
7
common/subdir.mk
Normal file
|
@ -0,0 +1,7 @@
|
|||
all install regress clean:
|
||||
@for _dir in ${SUBDIR}; do \
|
||||
echo "==> ${SUBMAKE_DIR}$$_dir ($@)" ; \
|
||||
(cd $$_dir && \
|
||||
SUBMAKE_DIR=${SUBMAKE_DIR}$$_dir/ ${MAKE} $@) || \
|
||||
exit $$? ; \
|
||||
done
|
107
common/test.h
Normal file
107
common/test.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_TEST_H
|
||||
#define COMMON_TEST_H
|
||||
|
||||
class TestGroup {
|
||||
friend class Test;
|
||||
|
||||
LogHandle log_;
|
||||
const std::string description_;
|
||||
unsigned tests_;
|
||||
unsigned passes_;
|
||||
public:
|
||||
TestGroup(const LogHandle& log, const std::string& description)
|
||||
: log_(log),
|
||||
description_(description),
|
||||
tests_(0),
|
||||
passes_(0)
|
||||
{
|
||||
INFO(log_) << "Running tests in group: " << description_;
|
||||
}
|
||||
|
||||
~TestGroup()
|
||||
{
|
||||
ASSERT(log_, tests_ != 0);
|
||||
|
||||
INFO(log_) << "Test results for group: " << description_;
|
||||
if (passes_ == tests_) {
|
||||
INFO(log_) << "All tests passed.";
|
||||
} else {
|
||||
if (passes_ == 0) {
|
||||
ERROR(log_) << "All tests failed.";
|
||||
} else {
|
||||
INFO(log_) << passes_ << "/" << tests_ << " tests passed.";
|
||||
ERROR(log_) << (tests_ - passes_) << " tests failed.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void test(bool passed, const std::string& description)
|
||||
{
|
||||
if (passed) {
|
||||
#if 0
|
||||
DEBUG(log_) << "PASS: " << description;
|
||||
#endif
|
||||
passes_++;
|
||||
} else {
|
||||
ERROR(log_) << "FAIL: " << description;
|
||||
}
|
||||
tests_++;
|
||||
}
|
||||
};
|
||||
|
||||
class Test {
|
||||
TestGroup& group_;
|
||||
const std::string description_;
|
||||
bool passed_;
|
||||
public:
|
||||
Test(TestGroup& group, const std::string& description)
|
||||
: group_(group),
|
||||
description_(description),
|
||||
passed_(false)
|
||||
{ }
|
||||
|
||||
Test(TestGroup& group, const std::string& description, bool passed)
|
||||
: group_(group),
|
||||
description_(description),
|
||||
passed_(passed)
|
||||
{ }
|
||||
|
||||
~Test()
|
||||
{
|
||||
group_.test(passed_, description_);
|
||||
}
|
||||
|
||||
void pass(void)
|
||||
{
|
||||
ASSERT("/test", !passed_);
|
||||
passed_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !COMMON_TEST_H */
|
0
common/thread/Makefile
Normal file
0
common/thread/Makefile
Normal file
15
common/thread/TODO
Normal file
15
common/thread/TODO
Normal file
|
@ -0,0 +1,15 @@
|
|||
Threads need to pick a blocking mechanism and somehow stick to it reliably, so there can be a neat and tidy Thread::kill function. A signal should knock a thread out of anything, but that can still have races. It would be nice if Thread::kill didn't have to be virtual, and if it could be worked into a generalized thread-to-thread messaging paradigm, but that's problematic when one of the major purposes of having threads in the first place is to be able to use other polling mechanisms in separate threads, i.e. blocking for libpcap or X11 or whatever.
|
||||
|
||||
Maybe it would be best to remove virtual void main() and instead have a worker-thread model, where threads can perform work, wait, or be signalled. The work, wait and signal functions would be virtual, which would hide a lot of the complexity about whether it's okay to block, or whether we've been signalled. And then threads could determine their own needs for block and signal; most threads might use EventPoll to do that work, but some might use something like pcap or X11 instead. No inter-thread messaging at a low-level, but maybe some higher-level interfaces that could be implemented on top of them.
|
||||
|
||||
If moving to a worker model, why not provide a work unit, too, and the possibility of some messaging primitives? That also has the benefit of mirroring some of the hardware models it'd be nice for the event system and threading to be compatible with, like that of Octeon. And it allows for lossless messaging between threads, whereas signal/wait can have problems with races and spurious wakeups, right? Especially if there's any chance of the signal being consumed by something like a system call, rather than an instance of wait. But with some slightly-heavyweight locking, there's no chance of those kinds of races, because e.g. the thread state lock would be held during work processing. That nearly serializes processing, though. *Unless* we have a lockless work-queueing model in addition to a wakeup mechanism. Right? Then we can guarantee that a thread will acquire a lock, check for work, and only then block. There's still races, though, such as with pcap, or X11, which won't let us specify a lock to relinquish at wait time. Argh!
|
||||
|
||||
Maybe too much generalization is a curse, and it would be better to find a limited and reliable model to support, and make sure all the applications we care about in the immediate future are plausible.
|
||||
|
||||
Why not just register threads that need to generate callbacks as an "EventSource" with the EventThread/EventSystem? This is non-ideal for a world in which we would have multiple EventThreads but it's a start for now. But with this, the EventSource could include a pipe to read/write on, which would be very neat and tidy.
|
||||
|
||||
I tried moving towards making EventThread the normative model for threads, and parameterizing anything using callbacks on EventThread (as a CallbackScheduler mostly, but also for timeouts, although there's no reason to not have timeouts in a different thread, and merely schedule them back to EventThread.) This is OK, but mostly devolves into single-threading anyway.
|
||||
|
||||
If polling code is simplified a little further and moved to common/poll/..., it makes sense indeed to move polling into *every* thread, and to use pipes to communicate between threads (or, where possible, we could use user events like with kqueue.) That can all mostly be done under the hood after the fact for real if we begin with the EventSource model, in which new sources are registered with the EventSystem. Then we have one-direction communication, which is probably most of what we need anyway. Right?
|
||||
|
||||
Actually, to avoid races, the method of inter-thread communication must be a condvar so that we can savely use mutexes. Otherwise we can go to sleep with work waiting, right? Unless we get really fussy about the data on the inter-thread pipe, but why not just use condvars instead? Then we just need to have a WorkerThread which has block/signal/work abstractions, and make EventPoll one of the few that uses something other than the default. And have a single poll thread, of course. Yes, this doesn't solve the pcap race problem, but nothing will; pcap is thread hell.
|
95
common/thread/atomic.h
Normal file
95
common/thread/atomic.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_THREAD_ATOMIC_H
|
||||
#define COMMON_THREAD_ATOMIC_H
|
||||
|
||||
template<typename T>
|
||||
class Atomic {
|
||||
T val_;
|
||||
public:
|
||||
Atomic(void)
|
||||
: val_()
|
||||
{ }
|
||||
|
||||
template<typename Ta>
|
||||
Atomic(Ta arg)
|
||||
: val_(arg)
|
||||
{ }
|
||||
|
||||
~Atomic()
|
||||
{ }
|
||||
|
||||
T val () const { return val_; }
|
||||
bool operator == (T v) const { return (v == val_); }
|
||||
bool operator != (T v) const { return (v != val_); }
|
||||
|
||||
/*
|
||||
* Note that these are deliberately not operator overloads, to force
|
||||
* deliberate use of this class.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__)
|
||||
template<typename Ta>
|
||||
T add(Ta arg)
|
||||
{
|
||||
return (__sync_add_and_fetch (&val_, arg));
|
||||
}
|
||||
|
||||
template<typename Ta>
|
||||
T subtract(Ta arg)
|
||||
{
|
||||
return (__sync_sub_and_fetch (&val_, arg));
|
||||
}
|
||||
|
||||
template<typename Ta>
|
||||
T set(Ta arg)
|
||||
{
|
||||
return (__sync_or_and_fetch (&val_, arg));
|
||||
}
|
||||
|
||||
template<typename Ta>
|
||||
T mask(Ta arg)
|
||||
{
|
||||
return (__sync_and_and_fetch (&val_, arg));
|
||||
}
|
||||
|
||||
template<typename Ta>
|
||||
T clear(Ta arg)
|
||||
{
|
||||
return (__sync_and_and_fetch (&val_, ~arg));
|
||||
}
|
||||
|
||||
template<typename To, typename Tn>
|
||||
bool cmpset(To oldval, Tn newval)
|
||||
{
|
||||
return (__sync_bool_compare_and_swap (&val_, oldval, newval));
|
||||
}
|
||||
#else
|
||||
#error "No support for atomic operations for your compiler. Why not add some?"
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* !COMMON_THREAD_ATOMIC_H */
|
6
common/thread/lib.mk
Normal file
6
common/thread/lib.mk
Normal file
|
@ -0,0 +1,6 @@
|
|||
VPATH+= ${TOPDIR}/common/thread
|
||||
|
||||
SRCS+= thread.cc
|
||||
|
||||
LDADD+= -lpthread
|
||||
|
71
common/thread/thread.cc
Normal file
71
common/thread/thread.cc
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <common/thread/thread.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: thread.cc //
|
||||
// Description: basic structure for generic thread objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
static void* thread_posix_start (void* arg)
|
||||
{
|
||||
Thread* td = (Thread*) arg;
|
||||
td->main ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Thread::Thread (const std::string& name) : name_(name), thread_id_(0), stop_(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool Thread::start ()
|
||||
{
|
||||
int rv = pthread_create (&thread_id_, NULL, thread_posix_start, this);
|
||||
if (rv != 0)
|
||||
{
|
||||
ERROR("/thread/posix") << "Unable to start thread.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Thread::stop ()
|
||||
{
|
||||
stop_ = true;
|
||||
void* val;
|
||||
int rv = pthread_join (thread_id_, &val);
|
||||
if (rv == -1)
|
||||
ERROR("/thread/posix") << "Thread join failed.";
|
||||
}
|
||||
|
59
common/thread/thread.h
Normal file
59
common/thread/thread.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_THREAD_THREAD_H
|
||||
#define COMMON_THREAD_THREAD_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: thread.h //
|
||||
// Description: basic structure for generic thread objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Thread
|
||||
{
|
||||
protected:
|
||||
std::string name_;
|
||||
pthread_t thread_id_;
|
||||
bool stop_;
|
||||
|
||||
protected:
|
||||
Thread (const std::string&);
|
||||
|
||||
public:
|
||||
virtual ~Thread () {}
|
||||
|
||||
bool start ();
|
||||
virtual void stop ();
|
||||
virtual void main () = 0;
|
||||
};
|
||||
|
||||
#endif /* !COMMON_THREAD_THREAD_H */
|
3
common/time/Makefile
Normal file
3
common/time/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBDIR+=
|
||||
|
||||
include ../../common/subdir.mk
|
3
common/time/lib.mk
Normal file
3
common/time/lib.mk
Normal file
|
@ -0,0 +1,3 @@
|
|||
VPATH+= ${TOPDIR}/common/time
|
||||
|
||||
SRCS+= time.cc
|
68
common/time/time.cc
Normal file
68
common/time/time.cc
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <common/time/time.h>
|
||||
|
||||
NanoTime
|
||||
NanoTime::current_time(void)
|
||||
{
|
||||
NanoTime nt;
|
||||
int rv;
|
||||
|
||||
#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
|
||||
struct timespec ts;
|
||||
|
||||
rv = ::clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
ASSERT("/nano/time/posix", rv != -1);
|
||||
|
||||
nt.seconds_ = ts.tv_sec;
|
||||
nt.nanoseconds_ = ts.tv_nsec;
|
||||
#else
|
||||
struct timeval tv;
|
||||
|
||||
rv = ::gettimeofday(&tv, NULL);
|
||||
ASSERT("/nano/time/gtod", rv != -1);
|
||||
nt.seconds_ = tv.tv_sec;
|
||||
nt.nanoseconds_ = tv.tv_usec * 1000;
|
||||
#endif
|
||||
|
||||
return (nt);
|
||||
}
|
||||
|
||||
void
|
||||
NanoTime::sleep(int ms)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms - ts.tv_sec) * 1000000;
|
||||
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
105
common/time/time.h
Normal file
105
common/time/time.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_TIME_TIME_H
|
||||
#define COMMON_TIME_TIME_H
|
||||
|
||||
#include <map>
|
||||
|
||||
struct NanoTime {
|
||||
uintmax_t seconds_;
|
||||
uintmax_t nanoseconds_;
|
||||
|
||||
NanoTime(void)
|
||||
: seconds_(0),
|
||||
nanoseconds_(0)
|
||||
{ }
|
||||
|
||||
NanoTime(const NanoTime& src)
|
||||
: seconds_(src.seconds_),
|
||||
nanoseconds_(src.nanoseconds_)
|
||||
{ }
|
||||
|
||||
bool operator< (const NanoTime& b) const
|
||||
{
|
||||
if (seconds_ == b.seconds_)
|
||||
return (nanoseconds_ < b.nanoseconds_);
|
||||
return (seconds_ < b.seconds_);
|
||||
}
|
||||
|
||||
bool operator> (const NanoTime& b) const
|
||||
{
|
||||
if (seconds_ == b.seconds_)
|
||||
return (nanoseconds_ > b.nanoseconds_);
|
||||
return (seconds_ > b.seconds_);
|
||||
}
|
||||
|
||||
bool operator<= (const NanoTime& b) const
|
||||
{
|
||||
if (seconds_ == b.seconds_)
|
||||
return (nanoseconds_ <= b.nanoseconds_);
|
||||
return (seconds_ <= b.seconds_);
|
||||
}
|
||||
|
||||
bool operator>= (const NanoTime& b) const
|
||||
{
|
||||
if (seconds_ == b.seconds_)
|
||||
return (nanoseconds_ >= b.nanoseconds_);
|
||||
return (seconds_ >= b.seconds_);
|
||||
}
|
||||
|
||||
NanoTime& operator+= (const NanoTime& b)
|
||||
{
|
||||
seconds_ += b.seconds_;
|
||||
nanoseconds_ += b.nanoseconds_;
|
||||
|
||||
if (nanoseconds_ >= 1000000000) {
|
||||
seconds_++;
|
||||
nanoseconds_ -= 1000000000;
|
||||
}
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
NanoTime& operator-= (const NanoTime& b)
|
||||
{
|
||||
ASSERT("/nano/time", *this >= b);
|
||||
|
||||
if (nanoseconds_ < b.nanoseconds_) {
|
||||
nanoseconds_ += 1000000000;
|
||||
seconds_ -= 1;
|
||||
}
|
||||
|
||||
seconds_ -= b.seconds_;
|
||||
nanoseconds_ -= b.nanoseconds_;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
static NanoTime current_time(void);
|
||||
static void sleep(int ms);
|
||||
};
|
||||
|
||||
#endif /* !COMMON_TIME_TIME_H */
|
3
common/timer/Makefile
Normal file
3
common/timer/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBDIR+=
|
||||
|
||||
include ../../common/subdir.mk
|
3
common/timer/lib.mk
Normal file
3
common/timer/lib.mk
Normal file
|
@ -0,0 +1,3 @@
|
|||
VPATH+= ${TOPDIR}/common/timer
|
||||
|
||||
SRCS+= timer.cc
|
56
common/timer/timer.cc
Normal file
56
common/timer/timer.cc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2010 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <common/timer/timer.h>
|
||||
|
||||
void
|
||||
Timer::start(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
int rv;
|
||||
|
||||
rv = gettimeofday(&tv, NULL);
|
||||
if (rv == -1)
|
||||
HALT("/timer") << "Could not gettimeofday.";
|
||||
start_ = (tv.tv_sec * 1000 * 1000) + tv.tv_usec;
|
||||
}
|
||||
|
||||
void
|
||||
Timer::stop(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
int rv;
|
||||
|
||||
rv = gettimeofday(&tv, NULL);
|
||||
if (rv == -1)
|
||||
HALT("/timer") << "Could not gettimeofday.";
|
||||
stop_ = (tv.tv_sec * 1000 * 1000) + tv.tv_usec;
|
||||
|
||||
samples_.push_back(stop_ - start_);
|
||||
}
|
65
common/timer/timer.h
Normal file
65
common/timer/timer.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_TIMER_TIMER_H
|
||||
#define COMMON_TIMER_TIMER_H
|
||||
|
||||
class Timer {
|
||||
uintmax_t start_;
|
||||
uintmax_t stop_;
|
||||
|
||||
std::vector<uintmax_t> samples_;
|
||||
public:
|
||||
Timer(void)
|
||||
: start_(),
|
||||
stop_(),
|
||||
samples_()
|
||||
{ }
|
||||
|
||||
~Timer()
|
||||
{ }
|
||||
|
||||
void reset(void)
|
||||
{
|
||||
samples_.clear();
|
||||
}
|
||||
|
||||
void start(void);
|
||||
void stop(void);
|
||||
|
||||
uintmax_t sample(void) const
|
||||
{
|
||||
if (samples_.size() != 1)
|
||||
HALT("/timer") << "Requested 1 sample but " << samples_.size() << " available.";
|
||||
return (samples_[0]);
|
||||
}
|
||||
|
||||
std::vector<uintmax_t> samples(void) const
|
||||
{
|
||||
return (samples_);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !COMMON_TIMER_TIMER_H */
|
41
common/types.h
Normal file
41
common/types.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_TYPES_H
|
||||
#define COMMON_TYPES_H
|
||||
|
||||
#if !defined(__OPENNT)
|
||||
#include <stdint.h> /* XXX cstdint? */
|
||||
#endif
|
||||
|
||||
#if defined(__OPENNT)
|
||||
typedef unsigned long long uintmax_t;
|
||||
typedef long long intmax_t;
|
||||
typedef unsigned int uintptr_t; /* XXX Appears to be in stddef.h! */
|
||||
typedef int socklen_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
|
||||
#endif /* !COMMON_TYPES_H */
|
3
common/uuid/Makefile
Normal file
3
common/uuid/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBDIR+=
|
||||
|
||||
include ../../common/subdir.mk
|
7
common/uuid/lib.mk
Normal file
7
common/uuid/lib.mk
Normal file
|
@ -0,0 +1,7 @@
|
|||
VPATH+= ${TOPDIR}/common/uuid
|
||||
|
||||
SRCS+= uuid.cc
|
||||
|
||||
ifeq "${OSNAME}" "Linux"
|
||||
LDADD+= -luuid
|
||||
endif
|
131
common/uuid/uuid.cc
Normal file
131
common/uuid/uuid.cc
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <common/uuid/uuid.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: uuid.cc //
|
||||
// Description: basic handling of standard UUID objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool UUID::from_string (const uint8_t* str)
|
||||
{
|
||||
#ifdef USE_LIBUUID
|
||||
int rv = uuid_parse ((const char*) str, uuid_);
|
||||
if (rv == -1)
|
||||
return (false);
|
||||
ASSERT("/uuid/libuuid", rv == 0);
|
||||
#else
|
||||
uint32_t status;
|
||||
uuid_from_string ((const char*) str, &uuid_, &status);
|
||||
if (status != uuid_s_ok)
|
||||
return (false);
|
||||
#endif
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool UUID::to_string (uint8_t* str) const
|
||||
{
|
||||
#ifdef USE_LIBUUID
|
||||
uuid_unparse (uuid_, (char*) str);
|
||||
#else
|
||||
char *p;
|
||||
uuid_to_string (&uuid_, &p, NULL);
|
||||
ASSERT("/uuid/libc", p != NULL);
|
||||
strcpy ((char*) str, p);
|
||||
free (p);
|
||||
#endif
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool UUID::from_file (std::string& path)
|
||||
{
|
||||
std::fstream file;
|
||||
std::string s;
|
||||
file.open (path.c_str(), std::ios::in);
|
||||
if (file.good())
|
||||
{
|
||||
file >> s;
|
||||
return from_string ((const uint8_t*) s.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UUID::to_file (std::string& path) const
|
||||
{
|
||||
std::fstream file;
|
||||
file.open (path.c_str(), std::ios::out);
|
||||
if (file.good())
|
||||
{
|
||||
uint8_t str[UUID_STRING_SIZE + 1];
|
||||
to_string (str);
|
||||
std::string s ((const char*) str);
|
||||
file << s;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UUID::decode (Buffer& buf)
|
||||
{
|
||||
if (buf.length() < UUID_STRING_SIZE)
|
||||
return (false);
|
||||
|
||||
uint8_t str[UUID_STRING_SIZE + 1];
|
||||
buf.moveout (str, UUID_STRING_SIZE);
|
||||
str[UUID_STRING_SIZE] = 0;
|
||||
return from_string (str);
|
||||
}
|
||||
|
||||
bool UUID::encode (Buffer& buf) const
|
||||
{
|
||||
uint8_t str[UUID_STRING_SIZE + 1];
|
||||
to_string (str);
|
||||
buf.append (str, UUID_STRING_SIZE);
|
||||
return (true);
|
||||
}
|
||||
|
||||
void UUID::generate(void)
|
||||
{
|
||||
#ifdef USE_LIBUUID
|
||||
uuid_generate (uuid_);
|
||||
#else
|
||||
uuid_create (&uuid_, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const UUID& uuid)
|
||||
{
|
||||
uint8_t str[UUID_STRING_SIZE + 1];
|
||||
uuid.to_string (str);
|
||||
return os << str;
|
||||
}
|
86
common/uuid/uuid.h
Normal file
86
common/uuid/uuid.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_UUID_UUID_H
|
||||
#define COMMON_UUID_UUID_H
|
||||
|
||||
#include <string.h>
|
||||
#include <ostream>
|
||||
#include <common/buffer.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: uuid.h //
|
||||
// Description: basic handling of standard UUID objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#else
|
||||
#define USE_LIBUUID
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBUUID
|
||||
#include <uuid/uuid.h>
|
||||
#else
|
||||
#include <uuid.h>
|
||||
#endif
|
||||
|
||||
#define UUID_STRING_SIZE (sizeof (uuid_t) * 2 + 4)
|
||||
|
||||
struct UUID
|
||||
{
|
||||
uuid_t uuid_;
|
||||
|
||||
bool from_string (const uint8_t* str);
|
||||
bool to_string (uint8_t* str) const;
|
||||
bool from_file (std::string& path);
|
||||
bool to_file (std::string& path) const;
|
||||
bool decode (Buffer&);
|
||||
bool encode (Buffer& buf) const;
|
||||
void generate (void);
|
||||
|
||||
UUID ()
|
||||
{
|
||||
memset (&uuid_, 0, sizeof uuid_);
|
||||
}
|
||||
|
||||
bool operator< (const UUID& b) const
|
||||
{
|
||||
return (memcmp (&uuid_, &b.uuid_, sizeof uuid_) < 0);
|
||||
}
|
||||
|
||||
bool is_valid () const
|
||||
{
|
||||
uuid_t u; return (memcmp (&uuid_, &u, sizeof uuid_) != 0);
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const UUID& uuid);
|
||||
|
||||
#endif /* !COMMON_UUID_UUID_H */
|
0
config/Makefile
Normal file
0
config/Makefile
Normal file
144
config/config.cc
Normal file
144
config/config.cc
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: config.cc //
|
||||
// Description: main configuration parser //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
Config::activate(const std::string& oname)
|
||||
{
|
||||
if (object_map_.find(oname) == object_map_.end()) {
|
||||
ERROR(log_) << "Object (" << oname << ") can not be activated as it does not exist.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
ConfigObject *co = object_map_[oname];
|
||||
return (co->activate());
|
||||
}
|
||||
|
||||
bool
|
||||
Config::create(const std::string& cname, const std::string& oname)
|
||||
{
|
||||
if (class_map_.find(cname) == class_map_.end()) {
|
||||
ERROR(log_) << "Class (" << cname << ") not present.";
|
||||
return (false);
|
||||
}
|
||||
if (object_map_.find(oname) != object_map_.end()) {
|
||||
ERROR(log_) << "Refusing to create object (" << oname << ") twice.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
ConfigClass *cc = class_map_[cname];
|
||||
|
||||
object_map_[oname] = new ConfigObject(this, oname, cc, cc->allocate());
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
Config::set(const std::string& oname, const std::string& mname,
|
||||
const std::string& vstr)
|
||||
{
|
||||
if (object_map_.find(oname) == object_map_.end()) {
|
||||
ERROR(log_) << "Can not set member value on object (" << oname << ") that does not exist.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
ConfigObject *co = object_map_[oname];
|
||||
|
||||
#if 0
|
||||
ConfigType *ct = cc->member(mname);
|
||||
if (ct == NULL) {
|
||||
ERROR(log_) << "No such member (" << mname << ") in object (" << oname << ")";
|
||||
return (false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vstr[0] == '$') {
|
||||
std::string::const_iterator dot;
|
||||
|
||||
dot = std::find(vstr.begin(), vstr.end(), '.');
|
||||
|
||||
std::string ooname(vstr.begin() + 1, dot);
|
||||
std::string omname(dot + 1, vstr.end());
|
||||
|
||||
if (ooname == "" || omname == "") {
|
||||
ERROR(log_) << "Refernece to invalid object (" << ooname << ") or member (" << omname << ") by name.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (object_map_.find(ooname) == object_map_.end()) {
|
||||
ERROR(log_) << "Reference to non-existant object (" << ooname << ")";
|
||||
return (false);
|
||||
}
|
||||
|
||||
ConfigObject *oco = object_map_[ooname];
|
||||
|
||||
object_field_string_map_t::const_iterator fsit;
|
||||
fsit = field_strings_map_.find(object_field_string_map_t::key_type(oco, omname));
|
||||
if (fsit == field_strings_map_.end()) {
|
||||
ERROR(log_) << "Reference to unset member (" << omname << ") in object (" << ooname << ")";
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (set(oname, mname, fsit->second));
|
||||
}
|
||||
|
||||
if (!co->set(mname, vstr)) {
|
||||
ERROR(log_) << "Member (" << mname << ") in object (" << oname << ") could not be set.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
field_strings_map_[object_field_string_map_t::key_type(co, mname)] = vstr;
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
void
|
||||
Config::import(ConfigClass *cc)
|
||||
{
|
||||
if (class_map_.find(cc->name_) != class_map_.end())
|
||||
return;
|
||||
|
||||
class_map_[cc->name_] = cc;
|
||||
}
|
||||
|
||||
void
|
||||
Config::marshall(ConfigExporter *exp) const
|
||||
{
|
||||
std::map<std::string, ConfigObject *>::const_iterator it;
|
||||
|
||||
for (it = object_map_.begin(); it != object_map_.end(); ++it)
|
||||
exp->object(it->second, it->first);
|
||||
}
|
87
config/config.h
Normal file
87
config/config.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_H
|
||||
#define CONFIG_CONFIG_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <config/config_class.h>
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_object.h>
|
||||
#include <config/config_type.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: config.h //
|
||||
// Description: main configuration parser //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Config {
|
||||
typedef std::map<std::pair<ConfigObject *, std::string>, std::string> object_field_string_map_t;
|
||||
|
||||
LogHandle log_;
|
||||
std::map<std::string, ConfigClass *> class_map_;
|
||||
std::map<std::string, ConfigObject *> object_map_;
|
||||
object_field_string_map_t field_strings_map_;
|
||||
|
||||
public:
|
||||
Config(void)
|
||||
: log_("/config"),
|
||||
class_map_(),
|
||||
object_map_()
|
||||
{ }
|
||||
|
||||
~Config()
|
||||
{
|
||||
std::map<std::string, ConfigObject *>::const_iterator it;
|
||||
for (it = object_map_.begin(); it != object_map_.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
bool activate(const std::string&);
|
||||
bool create(const std::string&, const std::string&);
|
||||
bool set(const std::string&, const std::string&, const std::string&);
|
||||
|
||||
void import(ConfigClass *);
|
||||
|
||||
void marshall(ConfigExporter *) const;
|
||||
|
||||
ConfigObject *lookup(const std::string& oname) const
|
||||
{
|
||||
std::map<std::string, ConfigObject *>::const_iterator omit;
|
||||
|
||||
omit = object_map_.find(oname);
|
||||
if (omit == object_map_.end())
|
||||
return (NULL);
|
||||
return (omit->second);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !CONFIG_CONFIG_H */
|
74
config/config_class.cc
Normal file
74
config/config_class.cc
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_class.h>
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_type.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: config_class.cc //
|
||||
// Description: parser for configuration classes //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConfigClass::~ConfigClass()
|
||||
{
|
||||
std::map<std::string, const ConfigClassMember *>::iterator it;
|
||||
|
||||
while ((it = members_.begin()) != members_.end()) {
|
||||
delete it->second;
|
||||
members_.erase(it);
|
||||
}
|
||||
|
||||
delete factory_;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigClass::set(ConfigObject *co, const std::string& mname, const std::string& vstr) const
|
||||
{
|
||||
#if 0
|
||||
ASSERT("/config/class", co->class_ == this);
|
||||
#endif
|
||||
|
||||
std::map<std::string, const ConfigClassMember *>::const_iterator it = members_.find(mname);
|
||||
if (it == members_.end()) {
|
||||
ERROR("/config/class") << "Object member (" << mname << ") does not exist.";
|
||||
return (false);
|
||||
}
|
||||
return (it->second->set(co, vstr));
|
||||
}
|
||||
|
||||
void
|
||||
ConfigClass::marshall(ConfigExporter *exp, const ConfigClassInstance *co) const
|
||||
{
|
||||
std::map<std::string, const ConfigClassMember *>::const_iterator it;
|
||||
for (it = members_.begin(); it != members_.end(); ++it) {
|
||||
exp->field(co, it->second, it->first);
|
||||
}
|
||||
}
|
111
config/config_class.h
Normal file
111
config/config_class.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_CLASS_H
|
||||
#define CONFIG_CONFIG_CLASS_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <common/factory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: config_class.h //
|
||||
// Description: parser for configuration classes //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Config;
|
||||
class ConfigExporter;
|
||||
class ConfigType;
|
||||
class ConfigObject;
|
||||
|
||||
/*
|
||||
* A base type for class instances.
|
||||
*/
|
||||
class ConfigClassInstance {
|
||||
protected:
|
||||
ConfigClassInstance(void)
|
||||
{ }
|
||||
public:
|
||||
virtual ~ConfigClassInstance()
|
||||
{ }
|
||||
|
||||
virtual bool activate(const ConfigObject *) = 0;
|
||||
};
|
||||
|
||||
class ConfigClassMember {
|
||||
protected:
|
||||
ConfigClassMember(void)
|
||||
{ }
|
||||
public:
|
||||
virtual ~ConfigClassMember()
|
||||
{ }
|
||||
|
||||
virtual void marshall(ConfigExporter *, const ConfigClassInstance *) const = 0;
|
||||
virtual bool set(ConfigObject *, const std::string&) const = 0;
|
||||
virtual ConfigType *type(void) const = 0;
|
||||
};
|
||||
|
||||
class ConfigClass {
|
||||
friend class Config;
|
||||
friend struct ConfigObject;
|
||||
|
||||
std::string name_;
|
||||
Factory<ConfigClassInstance> *factory_;
|
||||
std::map<std::string, const ConfigClassMember *> members_;
|
||||
protected:
|
||||
ConfigClass(const std::string& xname, Factory<ConfigClassInstance> *factory)
|
||||
: name_(xname),
|
||||
factory_(factory),
|
||||
members_()
|
||||
{ }
|
||||
|
||||
virtual ~ConfigClass();
|
||||
|
||||
template<typename Tc, typename Tf, typename Ti>
|
||||
void add_member(const std::string& mname, Tc type, Tf Ti::*fieldp);
|
||||
|
||||
private:
|
||||
ConfigClassInstance *allocate(void) const
|
||||
{
|
||||
return (factory_->create());
|
||||
}
|
||||
|
||||
bool set(ConfigObject *, const std::string&, const std::string&) const;
|
||||
|
||||
public:
|
||||
void marshall(ConfigExporter *, const ConfigClassInstance *) const;
|
||||
|
||||
std::string name(void) const
|
||||
{
|
||||
return (name_);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !CONFIG_CONFIG_CLASS_H */
|
56
config/config_class_address.cc
Normal file
56
config/config_class_address.cc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_class.h>
|
||||
#include <config/config_object.h>
|
||||
#include <config/config_class_address.h>
|
||||
|
||||
ConfigClassAddress config_class_address;
|
||||
|
||||
bool
|
||||
ConfigClassAddress::Instance::activate(const ConfigObject *)
|
||||
{
|
||||
switch (family_) {
|
||||
case SocketAddressFamilyIP:
|
||||
case SocketAddressFamilyIPv4:
|
||||
case SocketAddressFamilyIPv6:
|
||||
if (path_ != "") {
|
||||
ERROR("/config/class/address") << "IP socket has path field set, which is only valid for Unix domain sockets.";
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
|
||||
case SocketAddressFamilyUnix:
|
||||
if (host_ != "" || port_ != "") {
|
||||
ERROR("/config/class/address") << "Unix domain socket has host and/or port field set, which is only valid for IP sockets.";
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
|
||||
default:
|
||||
ERROR("/config/class/address") << "Unsupported address family.";
|
||||
return (false);
|
||||
}
|
||||
}
|
70
config/config_class_address.h
Normal file
70
config/config_class_address.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_CLASS_ADDRESS_H
|
||||
#define CONFIG_CONFIG_CLASS_ADDRESS_H
|
||||
|
||||
#include <config/config_type_address_family.h>
|
||||
#include <config/config_type_string.h>
|
||||
#include <config/config_type_proto.h>
|
||||
|
||||
class ConfigClassAddress : public ConfigClass {
|
||||
public:
|
||||
struct Instance : public ConfigClassInstance {
|
||||
SocketAddressFamily family_;
|
||||
std::string host_;
|
||||
std::string port_;
|
||||
std::string path_;
|
||||
ConfigProto proto_;
|
||||
|
||||
Instance(void)
|
||||
: family_(SocketAddressFamilyUnspecified),
|
||||
host_(""),
|
||||
port_(""),
|
||||
path_(""),
|
||||
proto_(ConfigProtoNone)
|
||||
{
|
||||
}
|
||||
|
||||
bool activate(const ConfigObject *);
|
||||
};
|
||||
|
||||
ConfigClassAddress(const std::string& xname = "address")
|
||||
: ConfigClass(xname, new ConstructorFactory<ConfigClassInstance, Instance>)
|
||||
{
|
||||
add_member("family", &config_type_address_family, &Instance::family_);
|
||||
add_member("host", &config_type_string, &Instance::host_);
|
||||
add_member("port", &config_type_string, &Instance::port_); /* XXX enum? */
|
||||
add_member("path", &config_type_string, &Instance::path_);
|
||||
add_member("proto", &config_type_proto, &Instance::proto_);
|
||||
}
|
||||
|
||||
~ConfigClassAddress()
|
||||
{ }
|
||||
};
|
||||
|
||||
extern ConfigClassAddress config_class_address;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_CLASS_ADDRESS_H */
|
41
config/config_class_log_mask.cc
Normal file
41
config/config_class_log_mask.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_class.h>
|
||||
#include <config/config_object.h>
|
||||
#include <config/config_class_log_mask.h>
|
||||
|
||||
ConfigClassLogMask config_class_log_mask;
|
||||
|
||||
bool
|
||||
ConfigClassLogMask::Instance::activate(const ConfigObject *)
|
||||
{
|
||||
if (!Log::mask(regex_, mask_)) {
|
||||
ERROR("/config/class/logmask") << "Could not set log mask.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
53
config/config_class_log_mask.h
Normal file
53
config/config_class_log_mask.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_CLASS_LOG_MASK_H
|
||||
#define CONFIG_CONFIG_CLASS_LOG_MASK_H
|
||||
|
||||
#include <config/config_type_log_level.h>
|
||||
#include <config/config_type_string.h>
|
||||
|
||||
class ConfigClassLogMask : public ConfigClass {
|
||||
struct Instance : public ConfigClassInstance {
|
||||
std::string regex_;
|
||||
Log::Priority mask_;
|
||||
|
||||
bool activate(const ConfigObject *);
|
||||
};
|
||||
public:
|
||||
ConfigClassLogMask(void)
|
||||
: ConfigClass("log-mask", new ConstructorFactory<ConfigClassInstance, Instance>)
|
||||
{
|
||||
add_member("regex", &config_type_string, &Instance::regex_);
|
||||
add_member("mask", &config_type_log_level, &Instance::mask_);
|
||||
}
|
||||
|
||||
~ConfigClassLogMask()
|
||||
{ }
|
||||
};
|
||||
|
||||
extern ConfigClassLogMask config_class_log_mask;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_CLASS_LOG_MASK_H */
|
49
config/config_exporter.h
Normal file
49
config/config_exporter.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_EXPORTER_H
|
||||
#define CONFIG_CONFIG_EXPORTER_H
|
||||
|
||||
class ConfigClass;
|
||||
class ConfigClassInstance;
|
||||
class ConfigClassMember;
|
||||
struct ConfigObject;
|
||||
class ConfigType;
|
||||
|
||||
class ConfigExporter {
|
||||
protected:
|
||||
ConfigExporter(void)
|
||||
{ }
|
||||
|
||||
virtual ~ConfigExporter()
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual void field(const ConfigClassInstance *, const ConfigClassMember *, const std::string&) = 0;
|
||||
virtual void object(const ConfigObject *, const std::string&) = 0;
|
||||
virtual void value(const ConfigType *, const std::string&) = 0;
|
||||
};
|
||||
|
||||
#endif /* !CONFIG_CONFIG_EXPORTER_H */
|
54
config/config_object.cc
Normal file
54
config/config_object.cc
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_object.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: config_object.cc //
|
||||
// Description: parser for configuration objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
ConfigObject::activate(void) const
|
||||
{
|
||||
return (instance_->activate(this));
|
||||
}
|
||||
|
||||
void
|
||||
ConfigObject::marshall(ConfigExporter *exp) const
|
||||
{
|
||||
class_->marshall(exp, instance_);
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigObject::set(const std::string& mname, const std::string& vstr)
|
||||
{
|
||||
return (class_->set(this, mname, vstr));
|
||||
}
|
105
config/config_object.h
Normal file
105
config/config_object.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_OBJECT_H
|
||||
#define CONFIG_CONFIG_OBJECT_H
|
||||
|
||||
#include <config/config_class.h>
|
||||
#include <config/config_exporter.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: config_object.h //
|
||||
// Description: parser for configuration objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Config;
|
||||
|
||||
struct ConfigObject {
|
||||
Config *config_;
|
||||
std::string name_;
|
||||
const ConfigClass *class_;
|
||||
ConfigClassInstance *instance_;
|
||||
|
||||
ConfigObject(Config *config, const std::string& name, const ConfigClass *cc, ConfigClassInstance *inst)
|
||||
: config_(config),
|
||||
name_(name),
|
||||
class_(cc),
|
||||
instance_(inst)
|
||||
{ }
|
||||
|
||||
virtual ~ConfigObject()
|
||||
{
|
||||
delete instance_;
|
||||
}
|
||||
|
||||
bool activate(void) const;
|
||||
void marshall(ConfigExporter *) const;
|
||||
bool set(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
template<typename Tc, typename Tf, typename Ti>
|
||||
void ConfigClass::add_member(const std::string& mname, Tc type, Tf Ti::*fieldp)
|
||||
{
|
||||
struct TypedConfigClassMember : public ConfigClassMember {
|
||||
Tc config_type_;
|
||||
Tf Ti::*config_field_;
|
||||
|
||||
TypedConfigClassMember(Tc config_type, Tf Ti::*config_field)
|
||||
: config_type_(config_type),
|
||||
config_field_(config_field)
|
||||
{ }
|
||||
virtual ~TypedConfigClassMember()
|
||||
{ }
|
||||
|
||||
void marshall(ConfigExporter *exp, const ConfigClassInstance *instance) const
|
||||
{
|
||||
const Ti *inst = dynamic_cast<const Ti *>(instance);
|
||||
ASSERT("/config/class/field", inst != NULL);
|
||||
config_type_->marshall(exp, &(inst->*config_field_));
|
||||
}
|
||||
|
||||
bool set(ConfigObject *co, const std::string& vstr) const
|
||||
{
|
||||
Ti *inst = dynamic_cast<Ti *>(co->instance_);
|
||||
ASSERT("/config/class/field", inst != NULL);
|
||||
return (config_type_->set(co, vstr, &(inst->*config_field_)));
|
||||
}
|
||||
|
||||
ConfigType *type(void) const
|
||||
{
|
||||
return (config_type_);
|
||||
}
|
||||
};
|
||||
|
||||
ASSERT("/config/class/" + name_, members_.find(mname) == members_.end());
|
||||
members_[mname] = new TypedConfigClassMember(type, fieldp);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_CONFIG_OBJECT_H */
|
48
config/config_type.h
Normal file
48
config/config_type.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_H
|
||||
#define CONFIG_CONFIG_TYPE_H
|
||||
|
||||
class Config;
|
||||
class ConfigExporter;
|
||||
|
||||
class ConfigType {
|
||||
std::string name_;
|
||||
protected:
|
||||
ConfigType(const std::string& xname)
|
||||
: name_(xname)
|
||||
{ }
|
||||
|
||||
virtual ~ConfigType()
|
||||
{ }
|
||||
public:
|
||||
std::string name(void) const
|
||||
{
|
||||
return (name_);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_H */
|
37
config/config_type_address_family.cc
Normal file
37
config/config_type_address_family.cc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_type_address_family.h>
|
||||
|
||||
static struct ConfigTypeAddressFamily::Mapping config_type_address_family_map[] = {
|
||||
{ "IP", SocketAddressFamilyIP },
|
||||
{ "IPv4", SocketAddressFamilyIPv4 },
|
||||
{ "IPv6", SocketAddressFamilyIPv6 },
|
||||
{ "Unix", SocketAddressFamilyUnix },
|
||||
{ NULL, SocketAddressFamilyUnspecified }
|
||||
};
|
||||
|
||||
ConfigTypeAddressFamily
|
||||
config_type_address_family("address-family", config_type_address_family_map);
|
37
config/config_type_address_family.h
Normal file
37
config/config_type_address_family.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_ADDRESS_FAMILY_H
|
||||
#define CONFIG_CONFIG_TYPE_ADDRESS_FAMILY_H
|
||||
|
||||
#include <config/config_type_enum.h>
|
||||
|
||||
#include <io/socket/socket_types.h>
|
||||
|
||||
typedef ConfigTypeEnum<SocketAddressFamily> ConfigTypeAddressFamily;
|
||||
|
||||
extern ConfigTypeAddressFamily config_type_address_family;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_ADDRESS_FAMILY_H */
|
85
config/config_type_enum.h
Normal file
85
config/config_type_enum.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_ENUM_H
|
||||
#define CONFIG_CONFIG_TYPE_ENUM_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_type.h>
|
||||
|
||||
template<typename E>
|
||||
class ConfigTypeEnum : public ConfigType {
|
||||
public:
|
||||
struct Mapping {
|
||||
const char *string_;
|
||||
E enum_;
|
||||
};
|
||||
private:
|
||||
std::map<std::string, E> enum_map_;
|
||||
public:
|
||||
ConfigTypeEnum(const std::string& xname, struct Mapping *mappings)
|
||||
: ConfigType(xname),
|
||||
enum_map_()
|
||||
{
|
||||
ASSERT("/config/type/enum", mappings != NULL);
|
||||
while (mappings->string_ != NULL) {
|
||||
enum_map_[mappings->string_] = mappings->enum_;
|
||||
mappings++;
|
||||
}
|
||||
}
|
||||
|
||||
~ConfigTypeEnum()
|
||||
{ }
|
||||
|
||||
void marshall(ConfigExporter *exp, const E *enump) const
|
||||
{
|
||||
E xenum = *enump;
|
||||
|
||||
typename std::map<std::string, E>::const_iterator it;
|
||||
for (it = enum_map_.begin(); it != enum_map_.end(); ++it) {
|
||||
if (it->second != xenum)
|
||||
continue;
|
||||
exp->value(this, it->first);
|
||||
return;
|
||||
}
|
||||
HALT("/config/type/enum") << "Trying to marshall unknown enum.";
|
||||
}
|
||||
|
||||
bool set(ConfigObject *, const std::string& vstr, E *enump)
|
||||
{
|
||||
if (enum_map_.find(vstr) == enum_map_.end()) {
|
||||
ERROR("/config/type/enum") << "Invalid value (" << vstr << ")";
|
||||
return (false);
|
||||
}
|
||||
|
||||
*enump = enum_map_[vstr];
|
||||
|
||||
return (true);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_ENUM_H */
|
92
config/config_type_flags.h
Normal file
92
config/config_type_flags.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_FLAGS_H
|
||||
#define CONFIG_CONFIG_TYPE_FLAGS_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_type.h>
|
||||
|
||||
template<typename T>
|
||||
class ConfigTypeFlags : public ConfigType {
|
||||
public:
|
||||
struct Mapping {
|
||||
const char *string_;
|
||||
T flag_;
|
||||
};
|
||||
private:
|
||||
std::map<std::string, T> flag_map_;
|
||||
public:
|
||||
ConfigTypeFlags(const std::string& xname, struct Mapping *mappings)
|
||||
: ConfigType(xname),
|
||||
flag_map_()
|
||||
{
|
||||
ASSERT("/config/type/flags", mappings != NULL);
|
||||
while (mappings->string_ != NULL) {
|
||||
flag_map_[mappings->string_] = mappings->flag_;
|
||||
mappings++;
|
||||
}
|
||||
}
|
||||
|
||||
~ConfigTypeFlags()
|
||||
{ }
|
||||
|
||||
void marshall(ConfigExporter *exp, const T *flagsp) const
|
||||
{
|
||||
T flags = *flagsp;
|
||||
|
||||
std::string str;
|
||||
typename std::map<std::string, T>::const_iterator it;
|
||||
for (it = flag_map_.begin(); it != flag_map_.end(); ++it) {
|
||||
if ((it->second & flags) == 0)
|
||||
continue;
|
||||
flags &= ~it->second;
|
||||
if (!str.empty())
|
||||
str += "|";
|
||||
str += it->first;
|
||||
}
|
||||
if (flags != 0)
|
||||
HALT("/config/type/flags") << "Trying to marshall unknown flags.";
|
||||
if (flags == 0 && str.empty())
|
||||
str = "0";
|
||||
exp->value(this, str);
|
||||
}
|
||||
|
||||
bool set(ConfigObject *, const std::string& vstr, T *flagsp)
|
||||
{
|
||||
if (flag_map_.find(vstr) == flag_map_.end()) {
|
||||
ERROR("/config/type/flags") << "Invalid value (" << vstr << ")";
|
||||
return (false);
|
||||
}
|
||||
|
||||
*flagsp |= flag_map_[vstr];
|
||||
|
||||
return (true);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_FLAGS_H */
|
67
config/config_type_int.cc
Normal file
67
config/config_type_int.cc
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(__OPENNT)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_type_int.h>
|
||||
|
||||
ConfigTypeInt config_type_int;
|
||||
|
||||
void
|
||||
ConfigTypeInt::marshall(ConfigExporter *exp, const intmax_t *valp) const
|
||||
{
|
||||
intmax_t val = *valp;
|
||||
|
||||
char buf[sizeof val * 2 + 2 + 1];
|
||||
snprintf(buf, sizeof buf, "0x%016jx", val);
|
||||
exp->value(this, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigTypeInt::set(ConfigObject *, const std::string& vstr, intmax_t *valp)
|
||||
{
|
||||
const char *str = vstr.c_str();
|
||||
char *endp;
|
||||
intmax_t imax;
|
||||
|
||||
#if !defined(__OPENNT)
|
||||
imax = strtoimax(str, &endp, 0);
|
||||
#else
|
||||
imax = strtoll(str, &endp, 0);
|
||||
#endif
|
||||
if (*endp != '\0') {
|
||||
ERROR("/config/type/int") << "Invalid numeric format.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
*valp = imax;
|
||||
|
||||
return (true);
|
||||
}
|
49
config/config_type_int.h
Normal file
49
config/config_type_int.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_INT_H
|
||||
#define CONFIG_CONFIG_TYPE_INT_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <config/config_type.h>
|
||||
|
||||
class ConfigTypeInt : public ConfigType {
|
||||
public:
|
||||
ConfigTypeInt(void)
|
||||
: ConfigType("int")
|
||||
{ }
|
||||
|
||||
~ConfigTypeInt()
|
||||
{ }
|
||||
|
||||
void marshall(ConfigExporter *, const intmax_t *) const;
|
||||
|
||||
bool set(ConfigObject *, const std::string&, intmax_t *);
|
||||
};
|
||||
|
||||
extern ConfigTypeInt config_type_int;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_INT_H */
|
41
config/config_type_log_level.cc
Normal file
41
config/config_type_log_level.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_type_log_level.h>
|
||||
|
||||
struct ConfigTypeLogLevel::Mapping config_type_log_level_map[] = {
|
||||
{ "EMERG", Log::Emergency },
|
||||
{ "ALERT", Log::Alert },
|
||||
{ "CRIT", Log::Critical },
|
||||
{ "ERR", Log::Error },
|
||||
{ "WARNING", Log::Warning },
|
||||
{ "NOTICE", Log::Notice },
|
||||
{ "INFO", Log::Info },
|
||||
{ "DEBUG", Log::Debug },
|
||||
{ NULL, Log::Debug }
|
||||
};
|
||||
|
||||
ConfigTypeLogLevel
|
||||
config_type_log_level("log-level", config_type_log_level_map);
|
35
config/config_type_log_level.h
Normal file
35
config/config_type_log_level.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_LOG_LEVEL_H
|
||||
#define CONFIG_CONFIG_TYPE_LOG_LEVEL_H
|
||||
|
||||
#include <config/config_type_enum.h>
|
||||
|
||||
typedef ConfigTypeEnum<Log::Priority> ConfigTypeLogLevel;
|
||||
|
||||
extern ConfigTypeLogLevel config_type_log_level;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_LOG_LEVEL_H */
|
64
config/config_type_pointer.cc
Normal file
64
config/config_type_pointer.cc
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <config/config.h>
|
||||
#include <config/config_class.h>
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_object.h>
|
||||
#include <config/config_type_pointer.h>
|
||||
|
||||
ConfigTypePointer config_type_pointer;
|
||||
|
||||
void
|
||||
ConfigTypePointer::marshall(ConfigExporter *exp, ConfigObject *const *cop) const
|
||||
{
|
||||
const ConfigObject *co = *cop;
|
||||
|
||||
if (co == NULL)
|
||||
exp->value(this, "None");
|
||||
else
|
||||
exp->value(this, co->name_);
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigTypePointer::set(ConfigObject *co, const std::string& vstr, ConfigObject **cop)
|
||||
{
|
||||
if (vstr == "None") {
|
||||
*cop = NULL;
|
||||
return (true);
|
||||
}
|
||||
|
||||
ConfigObject *target = co->config_->lookup(vstr);
|
||||
if (target == NULL) {
|
||||
ERROR("/config/type/pointer") << "Referenced object (" << vstr << ") does not exist.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
*cop = target;
|
||||
|
||||
return (true);
|
||||
}
|
49
config/config_type_pointer.h
Normal file
49
config/config_type_pointer.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_POINTER_H
|
||||
#define CONFIG_CONFIG_TYPE_POINTER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <config/config_type.h>
|
||||
|
||||
class ConfigTypePointer : public ConfigType {
|
||||
public:
|
||||
ConfigTypePointer(void)
|
||||
: ConfigType("pointer")
|
||||
{ }
|
||||
|
||||
~ConfigTypePointer()
|
||||
{ }
|
||||
|
||||
void marshall(ConfigExporter *, ConfigObject *const *) const;
|
||||
|
||||
bool set(ConfigObject *, const std::string&, ConfigObject **);
|
||||
};
|
||||
|
||||
extern ConfigTypePointer config_type_pointer;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_POINTER_H */
|
10
config/config_type_proto.cc
Normal file
10
config/config_type_proto.cc
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "config_type_proto.h"
|
||||
|
||||
static struct ConfigTypeProto::Mapping config_type_proto_map[] = {
|
||||
{ "TCP", ConfigProtoTCP },
|
||||
{ "TCP_POOL", ConfigProtoTCPPool },
|
||||
{ NULL, ConfigProtoNone }
|
||||
};
|
||||
|
||||
ConfigTypeProto
|
||||
config_type_proto("proto", config_type_proto_map);
|
16
config/config_type_proto.h
Normal file
16
config/config_type_proto.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef CONFIG_CONFIG_TYPE_PROTO_H
|
||||
#define CONFIG_CONFIG_TYPE_PROTO_H
|
||||
|
||||
#include <config/config_type_enum.h>
|
||||
|
||||
enum ConfigProto {
|
||||
ConfigProtoTCP,
|
||||
ConfigProtoTCPPool,
|
||||
ConfigProtoNone,
|
||||
};
|
||||
|
||||
typedef ConfigTypeEnum<ConfigProto> ConfigTypeProto;
|
||||
|
||||
extern ConfigTypeProto config_type_proto;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_PROTO_H */
|
28
config/config_type_string.cc
Normal file
28
config/config_type_string.cc
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config/config_type_string.h>
|
||||
|
||||
ConfigTypeString config_type_string;
|
72
config/config_type_string.h
Normal file
72
config/config_type_string.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2013 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_TYPE_STRING_H
|
||||
#define CONFIG_CONFIG_TYPE_STRING_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <config/config_exporter.h>
|
||||
#include <config/config_type.h>
|
||||
|
||||
class ConfigTypeString : public ConfigType {
|
||||
public:
|
||||
ConfigTypeString(void)
|
||||
: ConfigType("string")
|
||||
{ }
|
||||
|
||||
~ConfigTypeString()
|
||||
{ }
|
||||
|
||||
void marshall(ConfigExporter *exp, const std::string *stringp) const
|
||||
{
|
||||
exp->value(this, *stringp);
|
||||
}
|
||||
|
||||
bool set(ConfigObject *, const std::string& vstr, std::string *stringp)
|
||||
{
|
||||
if (*vstr.begin() != '"') {
|
||||
ERROR("/config/type/string") << "String does not begin with '\"'.";
|
||||
return (false);
|
||||
}
|
||||
if (*vstr.rbegin() != '"') {
|
||||
ERROR("/config/type/string") << "String does not end with '\"'.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
std::string str(vstr.begin() + 1, vstr.end() - 1);
|
||||
if (std::find(str.begin(), str.end(), '"') != str.end()) {
|
||||
ERROR("/config/type/string") << "String has '\"' other than at beginning or end.";
|
||||
return (false);
|
||||
}
|
||||
|
||||
*stringp = str;
|
||||
return (true);
|
||||
}
|
||||
};
|
||||
|
||||
extern ConfigTypeString config_type_string;
|
||||
|
||||
#endif /* !CONFIG_CONFIG_TYPE_STRING_H */
|
14
config/lib.mk
Normal file
14
config/lib.mk
Normal file
|
@ -0,0 +1,14 @@
|
|||
VPATH+= ${TOPDIR}/config
|
||||
|
||||
SRCS+= config.cc
|
||||
SRCS+= config_class.cc
|
||||
SRCS+= config_class_log_mask.cc
|
||||
SRCS+= config_object.cc
|
||||
SRCS+= config_type_int.cc
|
||||
SRCS+= config_type_log_level.cc
|
||||
SRCS+= config_type_pointer.cc
|
||||
SRCS+= config_type_string.cc
|
||||
SRCS+= config_type_proto.cc
|
||||
|
||||
SRCS_io_socket+=config_class_address.cc
|
||||
SRCS_io_socket+=config_type_address_family.cc
|
0
crypto/Makefile
Normal file
0
crypto/Makefile
Normal file
5
crypto/TODO
Normal file
5
crypto/TODO
Normal file
|
@ -0,0 +1,5 @@
|
|||
o) Find a good way to integrate the CryptoThread, CryptoSystem code.
|
||||
o) Process all cryptographic operations in the (a?) CryptoThread.
|
||||
o) DH infrastructure.
|
||||
o) BIGNUM infrastructure?
|
||||
o) Lots more algorithms.
|
103
crypto/crypto_encryption.cc
Normal file
103
crypto/crypto_encryption.cc
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <common/registrar.h>
|
||||
|
||||
#include <crypto/crypto_encryption.h>
|
||||
|
||||
namespace {
|
||||
struct MethodRegistrarKey;
|
||||
typedef Registrar<MethodRegistrarKey, const CryptoEncryption::Method *> MethodRegistrar;
|
||||
}
|
||||
|
||||
CryptoEncryption::Method::Method(const std::string& name)
|
||||
: name_(name)
|
||||
{
|
||||
MethodRegistrar::instance()->enter(this);
|
||||
}
|
||||
|
||||
const CryptoEncryption::Method *
|
||||
CryptoEncryption::Method::method(CryptoEncryption::Cipher cipher)
|
||||
{
|
||||
std::set<const CryptoEncryption::Method *> method_set = MethodRegistrar::instance()->enumerate();
|
||||
std::set<const CryptoEncryption::Method *>::const_iterator it;
|
||||
|
||||
for (it = method_set.begin(); it != method_set.end(); ++it) {
|
||||
const CryptoEncryption::Method *m = *it;
|
||||
std::set<CryptoEncryption::Cipher> cipher_set = m->ciphers();
|
||||
if (cipher_set.find(cipher) == cipher_set.end())
|
||||
continue;
|
||||
|
||||
return (*it);
|
||||
}
|
||||
|
||||
ERROR("/crypto/encryption/method") << "Could not find a method for cipher: " << cipher;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, CryptoEncryption::Algorithm algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case CryptoEncryption::TripleDES:
|
||||
return (os << "3DES");
|
||||
case CryptoEncryption::AES128:
|
||||
return (os << "AES128");
|
||||
case CryptoEncryption::AES192:
|
||||
return (os << "AES192");
|
||||
case CryptoEncryption::AES256:
|
||||
return (os << "AES256");
|
||||
case CryptoEncryption::Blowfish:
|
||||
return (os << "Blowfish");
|
||||
case CryptoEncryption::CAST:
|
||||
return (os << "CAST");
|
||||
case CryptoEncryption::IDEA:
|
||||
return (os << "IDEA");
|
||||
case CryptoEncryption::RC4:
|
||||
return (os << "RC4");
|
||||
}
|
||||
NOTREACHED("/crypto/encryption");
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, CryptoEncryption::Mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case CryptoEncryption::CBC:
|
||||
return (os << "CBC");
|
||||
case CryptoEncryption::CTR:
|
||||
return (os << "CTR");
|
||||
case CryptoEncryption::Stream:
|
||||
return (os << "Stream");
|
||||
}
|
||||
NOTREACHED("/crypto/encryption");
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, CryptoEncryption::Cipher cipher)
|
||||
{
|
||||
return (os << cipher.first << "/" << cipher.second);
|
||||
}
|
110
crypto/crypto_encryption.h
Normal file
110
crypto/crypto_encryption.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_CRYPTO_ENCRYPTION_H
|
||||
#define CRYPTO_CRYPTO_ENCRYPTION_H
|
||||
|
||||
#include <set>
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_encryption.h //
|
||||
// Description: basic encryption machinery //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace CryptoEncryption {
|
||||
class Method;
|
||||
|
||||
enum Algorithm {
|
||||
TripleDES,
|
||||
AES128,
|
||||
AES192,
|
||||
AES256,
|
||||
Blowfish,
|
||||
CAST,
|
||||
IDEA,
|
||||
RC4,
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
CBC,
|
||||
CTR,
|
||||
Stream,
|
||||
};
|
||||
typedef std::pair<Algorithm, Mode> Cipher;
|
||||
|
||||
enum Operation {
|
||||
Encrypt,
|
||||
Decrypt,
|
||||
};
|
||||
|
||||
class Session {
|
||||
protected:
|
||||
Session(void)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual ~Session()
|
||||
{ }
|
||||
|
||||
virtual unsigned block_size(void) const = 0;
|
||||
virtual unsigned key_size(void) const = 0;
|
||||
virtual unsigned iv_size(void) const = 0;
|
||||
|
||||
virtual Session *clone(void) const = 0;
|
||||
|
||||
virtual bool initialize(Operation, const Buffer *, const Buffer *) = 0;
|
||||
|
||||
virtual bool cipher(Buffer *, const Buffer *) = 0;
|
||||
|
||||
//virtual Action *submit(Buffer *, EventCallback *) = 0;
|
||||
};
|
||||
|
||||
class Method {
|
||||
std::string name_;
|
||||
protected:
|
||||
Method(const std::string&);
|
||||
|
||||
virtual ~Method()
|
||||
{ }
|
||||
public:
|
||||
virtual std::set<Cipher> ciphers(void) const = 0;
|
||||
virtual Session *session(Cipher) const = 0;
|
||||
|
||||
static const Method *method(Cipher);
|
||||
};
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream&, CryptoEncryption::Algorithm);
|
||||
std::ostream& operator<< (std::ostream&, CryptoEncryption::Mode);
|
||||
std::ostream& operator<< (std::ostream&, CryptoEncryption::Cipher);
|
||||
|
||||
#endif /* !CRYPTO_CRYPTO_ENCRYPTION_H */
|
306
crypto/crypto_encryption_openssl.cc
Normal file
306
crypto/crypto_encryption_openssl.cc
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <common/factory.h>
|
||||
#include <crypto/crypto_encryption.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_encryption_openssl.cc //
|
||||
// Description: interface to the OpenSSL encryption functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
class SessionEVP : public CryptoEncryption::Session {
|
||||
LogHandle log_;
|
||||
const EVP_CIPHER *cipher_;
|
||||
EVP_CIPHER_CTX ctx_;
|
||||
public:
|
||||
SessionEVP(const EVP_CIPHER *xcipher)
|
||||
: log_("/crypto/encryption/session/openssl"),
|
||||
cipher_(xcipher),
|
||||
ctx_()
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&ctx_);
|
||||
}
|
||||
|
||||
~SessionEVP()
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_);
|
||||
}
|
||||
|
||||
unsigned block_size(void) const
|
||||
{
|
||||
return (EVP_CIPHER_block_size(cipher_));
|
||||
}
|
||||
|
||||
unsigned key_size(void) const
|
||||
{
|
||||
return (EVP_CIPHER_key_length(cipher_));
|
||||
}
|
||||
|
||||
unsigned iv_size(void) const
|
||||
{
|
||||
return (EVP_CIPHER_iv_length(cipher_));
|
||||
}
|
||||
|
||||
Session *clone(void) const
|
||||
{
|
||||
return (new SessionEVP(cipher_));
|
||||
}
|
||||
|
||||
bool initialize(CryptoEncryption::Operation operation, const Buffer *key, const Buffer *iv)
|
||||
{
|
||||
if (key->length() < (size_t)EVP_CIPHER_key_length(cipher_))
|
||||
return (false);
|
||||
|
||||
if (iv->length() < (size_t)EVP_CIPHER_iv_length(cipher_))
|
||||
return (false);
|
||||
|
||||
int enc;
|
||||
switch (operation) {
|
||||
case CryptoEncryption::Encrypt:
|
||||
enc = 1;
|
||||
break;
|
||||
case CryptoEncryption::Decrypt:
|
||||
enc = 0;
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
|
||||
uint8_t keydata[key->length()];
|
||||
key->copyout(keydata, sizeof keydata);
|
||||
|
||||
uint8_t ivdata[iv->length()];
|
||||
iv->copyout(ivdata, sizeof ivdata);
|
||||
|
||||
int rv = EVP_CipherInit(&ctx_, cipher_, keydata, ivdata, enc);
|
||||
if (rv == 0)
|
||||
return (false);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool cipher(Buffer *out, const Buffer *in)
|
||||
{
|
||||
/*
|
||||
* We process a single, large, linear byte buffer here rather
|
||||
* than going a BufferSegment at a time, even though the byte
|
||||
* buffer is less efficient than some alternatives, because
|
||||
* there are padding and buffering implications if each
|
||||
* BufferSegment's length is not modular to the block size.
|
||||
*/
|
||||
uint8_t indata[in->length()];
|
||||
in->copyout(indata, sizeof indata);
|
||||
|
||||
uint8_t outdata[sizeof indata];
|
||||
int rv = EVP_Cipher(&ctx_, outdata, indata, sizeof indata);
|
||||
if (rv == 0)
|
||||
return (false);
|
||||
out->append(outdata, sizeof outdata);
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
Action *submit(Buffer *in, EventCallback *cb)
|
||||
{
|
||||
Buffer out;
|
||||
if (!cipher(&out, in)) {
|
||||
in->clear();
|
||||
cb->param(Event::Error);
|
||||
return (cb->schedule());
|
||||
}
|
||||
in->clear();
|
||||
cb->param(Event(Event::Done, out));
|
||||
return (cb->schedule());
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
class SessionAES128CTR : public CryptoEncryption::Session {
|
||||
LogHandle log_;
|
||||
AES_KEY key_;
|
||||
uint8_t iv_[AES_BLOCK_SIZE];
|
||||
public:
|
||||
SessionAES128CTR(void)
|
||||
: log_("/crypto/encryption/session/openssl"),
|
||||
key_(),
|
||||
iv_()
|
||||
{ }
|
||||
|
||||
~SessionAES128CTR()
|
||||
{ }
|
||||
|
||||
unsigned block_size(void) const
|
||||
{
|
||||
return (AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
unsigned key_size(void) const
|
||||
{
|
||||
return (AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
unsigned iv_size(void) const
|
||||
{
|
||||
return (AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
Session *clone(void) const
|
||||
{
|
||||
return (new SessionAES128CTR());
|
||||
}
|
||||
|
||||
bool initialize(CryptoEncryption::Operation operation, const Buffer *key, const Buffer *iv)
|
||||
{
|
||||
(void)operation;
|
||||
|
||||
if (key->length() != AES_BLOCK_SIZE)
|
||||
return (false);
|
||||
|
||||
if (iv->length() != AES_BLOCK_SIZE)
|
||||
return (false);
|
||||
|
||||
uint8_t keydata[key->length()];
|
||||
key->copyout(keydata, sizeof keydata);
|
||||
|
||||
AES_set_encrypt_key(keydata, AES_BLOCK_SIZE * 8, &key_);
|
||||
|
||||
iv->copyout(iv_, sizeof iv_);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool cipher(Buffer *out, const Buffer *in)
|
||||
{
|
||||
ASSERT(log_, in->length() % AES_BLOCK_SIZE == 0);
|
||||
|
||||
/*
|
||||
* Temporaries for AES_ctr128_encrypt.
|
||||
*
|
||||
* Their values only need to persist if we aren't using block-sized
|
||||
* buffers, which we are. We could just use AES_ctr128_inc and do
|
||||
* the crypt operation by hand here.
|
||||
*/
|
||||
uint8_t counterbuf[AES_BLOCK_SIZE]; /* Will be initialized if countern==0. */
|
||||
unsigned countern = 0;
|
||||
|
||||
/*
|
||||
* We process a single, large, linear byte buffer here rather
|
||||
* than going a BufferSegment at a time, even though the byte
|
||||
* buffer is less efficient than some alternatives, because
|
||||
* there are padding and buffering implications if each
|
||||
* BufferSegment's length is not modular to the block size.
|
||||
*/
|
||||
uint8_t indata[in->length()];
|
||||
in->copyout(indata, sizeof indata);
|
||||
|
||||
uint8_t outdata[sizeof indata];
|
||||
AES_ctr128_encrypt(indata, outdata, sizeof indata, &key_, iv_, counterbuf, &countern);
|
||||
|
||||
out->append(outdata, sizeof outdata);
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
Action *submit(Buffer *in, EventCallback *cb)
|
||||
{
|
||||
Buffer out;
|
||||
if (!cipher(&out, in)) {
|
||||
in->clear();
|
||||
cb->param(Event::Error);
|
||||
return (cb->schedule());
|
||||
}
|
||||
in->clear();
|
||||
cb->param(Event(Event::Done, out));
|
||||
return (cb->schedule());
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
class MethodOpenSSL : public CryptoEncryption::Method {
|
||||
LogHandle log_;
|
||||
FactoryMap<CryptoEncryption::Cipher, CryptoEncryption::Session> cipher_map_;
|
||||
public:
|
||||
MethodOpenSSL(void)
|
||||
: CryptoEncryption::Method("OpenSSL"),
|
||||
log_("/crypto/encryption/openssl"),
|
||||
cipher_map_()
|
||||
{
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
factory<SessionEVP> evp_factory;
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::TripleDES, CryptoEncryption::CBC), evp_factory(EVP_des_ede3_cbc()));
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES128, CryptoEncryption::CBC), evp_factory(EVP_aes_128_cbc()));
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES192, CryptoEncryption::CBC), evp_factory(EVP_aes_192_cbc()));
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES256, CryptoEncryption::CBC), evp_factory(EVP_aes_256_cbc()));
|
||||
#if 0
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES128, CryptoEncryption::CTR), evp_factory(EVP_aes_128_ctr()));
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES192, CryptoEncryption::CTR), evp_factory(EVP_aes_192_ctr()));
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES256, CryptoEncryption::CTR), evp_factory(EVP_aes_256_ctr()));
|
||||
#else
|
||||
factory<SessionAES128CTR> aes128ctr_factory;
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::AES128, CryptoEncryption::CTR), aes128ctr_factory());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BF
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::Blowfish, CryptoEncryption::CBC), evp_factory(EVP_bf_cbc()));
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAST
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::CAST, CryptoEncryption::CBC), evp_factory(EVP_cast5_cbc()));
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::IDEA, CryptoEncryption::CBC), evp_factory(EVP_idea_cbc()));
|
||||
#endif
|
||||
cipher_map_.enter(CryptoEncryption::Cipher(CryptoEncryption::RC4, CryptoEncryption::Stream), evp_factory(EVP_rc4()));
|
||||
|
||||
/* XXX Register. */
|
||||
}
|
||||
|
||||
~MethodOpenSSL()
|
||||
{
|
||||
/* XXX Unregister. */
|
||||
}
|
||||
|
||||
std::set<CryptoEncryption::Cipher> ciphers(void) const
|
||||
{
|
||||
return (cipher_map_.keys());
|
||||
}
|
||||
|
||||
CryptoEncryption::Session *session(CryptoEncryption::Cipher cipher) const
|
||||
{
|
||||
return (cipher_map_.create(cipher));
|
||||
}
|
||||
};
|
||||
|
||||
static MethodOpenSSL crypto_encryption_method_openssl;
|
||||
}
|
77
crypto/crypto_hash.cc
Normal file
77
crypto/crypto_hash.cc
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <common/registrar.h>
|
||||
|
||||
#include <crypto/crypto_hash.h>
|
||||
|
||||
namespace {
|
||||
struct MethodRegistrarKey;
|
||||
typedef Registrar<MethodRegistrarKey, const CryptoHash::Method *> MethodRegistrar;
|
||||
}
|
||||
|
||||
CryptoHash::Method::Method(const std::string& name)
|
||||
: name_(name)
|
||||
{
|
||||
MethodRegistrar::instance()->enter(this);
|
||||
}
|
||||
|
||||
const CryptoHash::Method *
|
||||
CryptoHash::Method::method(CryptoHash::Algorithm algorithm)
|
||||
{
|
||||
std::set<const CryptoHash::Method *> method_set = MethodRegistrar::instance()->enumerate();
|
||||
std::set<const CryptoHash::Method *>::const_iterator it;
|
||||
|
||||
for (it = method_set.begin(); it != method_set.end(); ++it) {
|
||||
const CryptoHash::Method *m = *it;
|
||||
std::set<CryptoHash::Algorithm> algorithm_set = m->algorithms();
|
||||
if (algorithm_set.find(algorithm) == algorithm_set.end())
|
||||
continue;
|
||||
|
||||
return (*it);
|
||||
}
|
||||
|
||||
ERROR("/crypto/encryption/method") << "Could not find a method for algorithm: " << algorithm;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, CryptoHash::Algorithm algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case CryptoHash::MD5:
|
||||
return (os << "MD5");
|
||||
case CryptoHash::SHA1:
|
||||
return (os << "SHA1");
|
||||
case CryptoHash::SHA256:
|
||||
return (os << "SHA256");
|
||||
case CryptoHash::SHA512:
|
||||
return (os << "SHA512");
|
||||
case CryptoHash::RIPEMD160:
|
||||
return (os << "RIPEMD160");
|
||||
}
|
||||
NOTREACHED("/crypto/encryption");
|
||||
}
|
103
crypto/crypto_hash.h
Normal file
103
crypto/crypto_hash.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_CRYPTO_HASH_H
|
||||
#define CRYPTO_CRYPTO_HASH_H
|
||||
|
||||
#include <set>
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_hash.h //
|
||||
// Description: basic encryption machinery //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace CryptoHash {
|
||||
class Method;
|
||||
|
||||
enum Algorithm {
|
||||
MD5,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA512,
|
||||
RIPEMD160,
|
||||
};
|
||||
|
||||
class Instance {
|
||||
protected:
|
||||
Instance(void)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual ~Instance()
|
||||
{ }
|
||||
|
||||
virtual bool hash(Buffer *, const Buffer *) = 0;
|
||||
|
||||
//virtual Action *submit(Buffer *, EventCallback *) = 0;
|
||||
};
|
||||
|
||||
class Method {
|
||||
std::string name_;
|
||||
protected:
|
||||
Method(const std::string&);
|
||||
|
||||
virtual ~Method()
|
||||
{ }
|
||||
public:
|
||||
virtual std::set<Algorithm> algorithms(void) const = 0;
|
||||
virtual Instance *instance(Algorithm) const = 0;
|
||||
|
||||
static const Method *method(Algorithm);
|
||||
};
|
||||
|
||||
static inline Instance *instance(Algorithm algorithm)
|
||||
{
|
||||
const Method *method = Method::method(algorithm);
|
||||
if (method == NULL)
|
||||
return (NULL);
|
||||
return (method->instance(algorithm));
|
||||
}
|
||||
|
||||
static inline bool hash(Algorithm algorithm, Buffer *out, const Buffer *in)
|
||||
{
|
||||
Instance *i = instance(algorithm);
|
||||
if (i == NULL)
|
||||
return (false);
|
||||
bool ok = i->hash(out, in);
|
||||
delete i;
|
||||
return (ok);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream&, CryptoHash::Algorithm);
|
||||
|
||||
#endif /* !CRYPTO_CRYPTO_HASH_H */
|
130
crypto/crypto_hash_openssl.cc
Normal file
130
crypto/crypto_hash_openssl.cc
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <common/factory.h>
|
||||
#include <crypto/crypto_hash.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_hash_openssl.cc //
|
||||
// Description: interface to the OpenSSL encryption functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
class InstanceEVP : public CryptoHash::Instance {
|
||||
LogHandle log_;
|
||||
const EVP_MD *algorithm_;
|
||||
public:
|
||||
InstanceEVP(const EVP_MD *algorithm)
|
||||
: log_("/crypto/hash/instance/openssl"),
|
||||
algorithm_(algorithm)
|
||||
{ }
|
||||
|
||||
~InstanceEVP()
|
||||
{ }
|
||||
|
||||
virtual bool hash(Buffer *out, const Buffer *in)
|
||||
{
|
||||
/*
|
||||
* We process a single, large, linear byte buffer here rather
|
||||
* than going a BufferSegment at a time, even though the byte
|
||||
* buffer is less efficient than some alternatives, because
|
||||
* there are padding and buffering implications if each
|
||||
* BufferSegment's length is not modular to the block size.
|
||||
*/
|
||||
uint8_t indata[in->length()];
|
||||
in->copyout(indata, sizeof indata);
|
||||
|
||||
uint8_t macdata[EVP_MD_size(algorithm_)];
|
||||
unsigned maclen;
|
||||
if (!EVP_Digest(indata, sizeof indata, macdata, &maclen, algorithm_, NULL))
|
||||
return (false);
|
||||
ASSERT(log_, maclen == sizeof macdata);
|
||||
out->append(macdata, maclen);
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
Action *submit(Buffer *in, EventCallback *cb)
|
||||
{
|
||||
Buffer out;
|
||||
if (!hash(&out, in)) {
|
||||
in->clear();
|
||||
cb->param(Event::Error);
|
||||
return (cb->schedule());
|
||||
}
|
||||
in->clear();
|
||||
cb->param(Event(Event::Done, out));
|
||||
return (cb->schedule());
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
class MethodOpenSSL : public CryptoHash::Method {
|
||||
LogHandle log_;
|
||||
FactoryMap<CryptoHash::Algorithm, CryptoHash::Instance> algorithm_map_;
|
||||
public:
|
||||
MethodOpenSSL(void)
|
||||
: CryptoHash::Method("OpenSSL"),
|
||||
log_("/crypto/hash/openssl"),
|
||||
algorithm_map_()
|
||||
{
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
factory<InstanceEVP> evp_factory;
|
||||
algorithm_map_.enter(CryptoHash::MD5, evp_factory(EVP_md5()));
|
||||
algorithm_map_.enter(CryptoHash::SHA1, evp_factory(EVP_sha1()));
|
||||
algorithm_map_.enter(CryptoHash::SHA256, evp_factory(EVP_sha256()));
|
||||
algorithm_map_.enter(CryptoHash::SHA512, evp_factory(EVP_sha512()));
|
||||
algorithm_map_.enter(CryptoHash::RIPEMD160, evp_factory(EVP_ripemd160()));
|
||||
|
||||
/* XXX Register. */
|
||||
}
|
||||
|
||||
~MethodOpenSSL()
|
||||
{
|
||||
/* XXX Unregister. */
|
||||
}
|
||||
|
||||
std::set<CryptoHash::Algorithm> algorithms(void) const
|
||||
{
|
||||
return (algorithm_map_.keys());
|
||||
}
|
||||
|
||||
CryptoHash::Instance *instance(CryptoHash::Algorithm algorithm) const
|
||||
{
|
||||
return (algorithm_map_.create(algorithm));
|
||||
}
|
||||
};
|
||||
|
||||
static MethodOpenSSL crypto_hash_method_openssl;
|
||||
}
|
77
crypto/crypto_mac.cc
Normal file
77
crypto/crypto_mac.cc
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <common/registrar.h>
|
||||
|
||||
#include <crypto/crypto_mac.h>
|
||||
|
||||
namespace {
|
||||
struct MethodRegistrarKey;
|
||||
typedef Registrar<MethodRegistrarKey, const CryptoMAC::Method *> MethodRegistrar;
|
||||
}
|
||||
|
||||
CryptoMAC::Method::Method(const std::string& name)
|
||||
: name_(name)
|
||||
{
|
||||
MethodRegistrar::instance()->enter(this);
|
||||
}
|
||||
|
||||
const CryptoMAC::Method *
|
||||
CryptoMAC::Method::method(CryptoMAC::Algorithm algorithm)
|
||||
{
|
||||
std::set<const CryptoMAC::Method *> method_set = MethodRegistrar::instance()->enumerate();
|
||||
std::set<const CryptoMAC::Method *>::const_iterator it;
|
||||
|
||||
for (it = method_set.begin(); it != method_set.end(); ++it) {
|
||||
const CryptoMAC::Method *m = *it;
|
||||
std::set<CryptoMAC::Algorithm> algorithm_set = m->algorithms();
|
||||
if (algorithm_set.find(algorithm) == algorithm_set.end())
|
||||
continue;
|
||||
|
||||
return (*it);
|
||||
}
|
||||
|
||||
ERROR("/crypto/encryption/method") << "Could not find a method for algorithm: " << algorithm;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, CryptoMAC::Algorithm algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case CryptoMAC::MD5:
|
||||
return (os << "HMAC-MD5");
|
||||
case CryptoMAC::SHA1:
|
||||
return (os << "HMAC-SHA1");
|
||||
case CryptoMAC::SHA256:
|
||||
return (os << "HMAC-SHA256");
|
||||
case CryptoMAC::SHA512:
|
||||
return (os << "HMAC-SHA512");
|
||||
case CryptoMAC::RIPEMD160:
|
||||
return (os << "HMAC-RIPEMD160");
|
||||
}
|
||||
NOTREACHED("/crypto/encryption");
|
||||
}
|
91
crypto/crypto_mac.h
Normal file
91
crypto/crypto_mac.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_CRYPTO_MAC_H
|
||||
#define CRYPTO_CRYPTO_MAC_H
|
||||
|
||||
#include <set>
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_mac.h //
|
||||
// Description: basic encryption machinery //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace CryptoMAC {
|
||||
class Method;
|
||||
|
||||
enum Algorithm {
|
||||
MD5,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA512,
|
||||
RIPEMD160,
|
||||
};
|
||||
|
||||
class Instance {
|
||||
protected:
|
||||
Instance(void)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual ~Instance()
|
||||
{ }
|
||||
|
||||
virtual unsigned size(void) const = 0;
|
||||
|
||||
virtual Instance *clone(void) const = 0;
|
||||
|
||||
virtual bool initialize(const Buffer * = NULL) = 0;
|
||||
|
||||
virtual bool mac(Buffer *, const Buffer *) = 0;
|
||||
|
||||
//virtual Action *submit(Buffer *, EventCallback *) = 0;
|
||||
};
|
||||
|
||||
class Method {
|
||||
std::string name_;
|
||||
protected:
|
||||
Method(const std::string&);
|
||||
|
||||
virtual ~Method()
|
||||
{ }
|
||||
public:
|
||||
virtual std::set<Algorithm> algorithms(void) const = 0;
|
||||
virtual Instance *instance(Algorithm) const = 0;
|
||||
|
||||
static const Method *method(Algorithm);
|
||||
};
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream&, CryptoMAC::Algorithm);
|
||||
|
||||
#endif /* !CRYPTO_CRYPTO_MAC_H */
|
156
crypto/crypto_mac_openssl.cc
Normal file
156
crypto/crypto_mac_openssl.cc
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <common/factory.h>
|
||||
#include <crypto/crypto_mac.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_mac_openssl.cc //
|
||||
// Description: interface to the OpenSSL encryption functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
class InstanceEVP : public CryptoMAC::Instance {
|
||||
LogHandle log_;
|
||||
const EVP_MD *algorithm_;
|
||||
uint8_t key_[EVP_MAX_KEY_LENGTH];
|
||||
size_t key_length_;
|
||||
public:
|
||||
InstanceEVP(const EVP_MD *algorithm)
|
||||
: log_("/crypto/mac/instance/openssl"),
|
||||
algorithm_(algorithm),
|
||||
key_(),
|
||||
key_length_(0)
|
||||
{ }
|
||||
|
||||
~InstanceEVP()
|
||||
{ }
|
||||
|
||||
unsigned size(void) const
|
||||
{
|
||||
return (EVP_MD_size(algorithm_));
|
||||
}
|
||||
|
||||
Instance *clone(void) const
|
||||
{
|
||||
ASSERT(log_, key_length_ == 0);
|
||||
return (new InstanceEVP(algorithm_));
|
||||
}
|
||||
|
||||
bool initialize(const Buffer *key)
|
||||
{
|
||||
if (key->length() > EVP_MAX_KEY_LENGTH)
|
||||
return (false);
|
||||
|
||||
key->copyout(key_, key->length());
|
||||
key_length_ = key->length();
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool mac(Buffer *out, const Buffer *in)
|
||||
{
|
||||
/*
|
||||
* We process a single, large, linear byte buffer here rather
|
||||
* than going a BufferSegment at a time, even though the byte
|
||||
* buffer is less efficient than some alternatives, because
|
||||
* there are padding and buffering implications if each
|
||||
* BufferSegment's length is not modular to the block size.
|
||||
*/
|
||||
uint8_t indata[in->length()];
|
||||
in->copyout(indata, sizeof indata);
|
||||
|
||||
uint8_t macdata[EVP_MD_size(algorithm_)];
|
||||
unsigned maclen;
|
||||
if (HMAC(algorithm_, key_, key_length_, indata, sizeof indata, macdata, &maclen) == NULL)
|
||||
return (false);
|
||||
ASSERT(log_, maclen == sizeof macdata);
|
||||
out->append(macdata, maclen);
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
Action *submit(Buffer *in, EventCallback *cb)
|
||||
{
|
||||
Buffer out;
|
||||
if (!mac(&out, in)) {
|
||||
in->clear();
|
||||
cb->param(Event::Error);
|
||||
return (cb->schedule());
|
||||
}
|
||||
in->clear();
|
||||
cb->param(Event(Event::Done, out));
|
||||
return (cb->schedule());
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
class MethodOpenSSL : public CryptoMAC::Method {
|
||||
LogHandle log_;
|
||||
FactoryMap<CryptoMAC::Algorithm, CryptoMAC::Instance> algorithm_map_;
|
||||
public:
|
||||
MethodOpenSSL(void)
|
||||
: CryptoMAC::Method("OpenSSL"),
|
||||
log_("/crypto/mac/openssl"),
|
||||
algorithm_map_()
|
||||
{
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
factory<InstanceEVP> evp_factory;
|
||||
algorithm_map_.enter(CryptoMAC::MD5, evp_factory(EVP_md5()));
|
||||
algorithm_map_.enter(CryptoMAC::SHA1, evp_factory(EVP_sha1()));
|
||||
algorithm_map_.enter(CryptoMAC::SHA256, evp_factory(EVP_sha256()));
|
||||
algorithm_map_.enter(CryptoMAC::SHA512, evp_factory(EVP_sha512()));
|
||||
algorithm_map_.enter(CryptoMAC::RIPEMD160, evp_factory(EVP_ripemd160()));
|
||||
|
||||
/* XXX Register. */
|
||||
}
|
||||
|
||||
~MethodOpenSSL()
|
||||
{
|
||||
/* XXX Unregister. */
|
||||
}
|
||||
|
||||
std::set<CryptoMAC::Algorithm> algorithms(void) const
|
||||
{
|
||||
return (algorithm_map_.keys());
|
||||
}
|
||||
|
||||
CryptoMAC::Instance *instance(CryptoMAC::Algorithm algorithm) const
|
||||
{
|
||||
return (algorithm_map_.create(algorithm));
|
||||
}
|
||||
};
|
||||
|
||||
static MethodOpenSSL crypto_mac_method_openssl;
|
||||
}
|
80
crypto/crypto_random.h
Normal file
80
crypto/crypto_random.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_CRYPTO_RANDOM_H
|
||||
#define CRYPTO_CRYPTO_RANDOM_H
|
||||
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_random.h //
|
||||
// Description: basic encryption machinery //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CryptoRandomMethod;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Add a CryptoTypeBest, which will use whatever the best, available method is.
|
||||
*/
|
||||
enum CryptoRandomType {
|
||||
CryptoTypeRNG,
|
||||
CryptoTypePRNG,
|
||||
};
|
||||
|
||||
class CryptoRandomSession {
|
||||
protected:
|
||||
CryptoRandomSession(void)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual ~CryptoRandomSession()
|
||||
{ }
|
||||
|
||||
//virtual Action *generate(size_t, EventCallback *) = 0;
|
||||
};
|
||||
|
||||
class CryptoRandomMethod {
|
||||
protected:
|
||||
CryptoRandomMethod(void)
|
||||
{ }
|
||||
|
||||
virtual ~CryptoRandomMethod()
|
||||
{ }
|
||||
public:
|
||||
virtual bool generate(CryptoRandomType, size_t, Buffer *) const = 0;
|
||||
virtual CryptoRandomSession *session(CryptoRandomType) const = 0;
|
||||
|
||||
/* XXX Registration API somehow. */
|
||||
static const CryptoRandomMethod *default_method;
|
||||
};
|
||||
|
||||
#endif /* !CRYPTO_CRYPTO_RANDOM_H */
|
130
crypto/crypto_random_openssl.cc
Normal file
130
crypto/crypto_random_openssl.cc
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <common/factory.h>
|
||||
#include <crypto/crypto_random.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: crypto_random_openssl.cc //
|
||||
// Description: interface to the OpenSSL encryption functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
typedef int (RAND_func)(unsigned char *, int);
|
||||
}
|
||||
|
||||
class CryptoRandomSessionRAND : public CryptoRandomSession {
|
||||
LogHandle log_;
|
||||
RAND_func *func_;
|
||||
public:
|
||||
CryptoRandomSessionRAND(RAND_func *func)
|
||||
: log_("/crypto/random/session/openssl"),
|
||||
func_(func)
|
||||
{ }
|
||||
|
||||
~CryptoRandomSessionRAND()
|
||||
{ }
|
||||
|
||||
/*
|
||||
Action *generate(size_t len, EventCallback *cb)
|
||||
{
|
||||
ASSERT(log_, len != 0);
|
||||
|
||||
uint8_t bytes[len];
|
||||
int rv = func_(bytes, sizeof bytes);
|
||||
if (rv == 0) {
|
||||
cb->param(Event::Error);
|
||||
return (cb->schedule());
|
||||
}
|
||||
cb->param(Event(Event::Done, Buffer(bytes, sizeof bytes)));
|
||||
return (cb->schedule());
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
class CryptoRandomMethodOpenSSL : public CryptoRandomMethod {
|
||||
LogHandle log_;
|
||||
std::map<CryptoRandomType, RAND_func *> func_map_;
|
||||
public:
|
||||
CryptoRandomMethodOpenSSL(void)
|
||||
: log_("/crypto/random/openssl"),
|
||||
func_map_()
|
||||
{
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
func_map_[CryptoTypeRNG] = RAND_bytes;
|
||||
func_map_[CryptoTypePRNG] = RAND_pseudo_bytes;
|
||||
|
||||
/* XXX Register. */
|
||||
}
|
||||
|
||||
~CryptoRandomMethodOpenSSL()
|
||||
{
|
||||
/* XXX Unregister. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Synchronous randomness generation. May not succeed.
|
||||
*/
|
||||
bool generate(CryptoRandomType func, size_t len, Buffer *out) const
|
||||
{
|
||||
std::map<CryptoRandomType, RAND_func *>::const_iterator it;
|
||||
|
||||
it = func_map_.find(func);
|
||||
if (it == func_map_.end())
|
||||
return (false);
|
||||
|
||||
uint8_t bytes[len];
|
||||
int rv = it->second(bytes, sizeof bytes);
|
||||
if (rv == 0)
|
||||
return (false);
|
||||
|
||||
out->append(bytes, sizeof bytes);
|
||||
return (true);
|
||||
}
|
||||
|
||||
CryptoRandomSession *session(CryptoRandomType func) const
|
||||
{
|
||||
std::map<CryptoRandomType, RAND_func *>::const_iterator it;
|
||||
|
||||
it = func_map_.find(func);
|
||||
if (it != func_map_.end())
|
||||
return (new CryptoRandomSessionRAND(it->second));
|
||||
return (NULL);
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
static CryptoRandomMethodOpenSSL crypto_random_method_openssl;
|
||||
}
|
||||
const CryptoRandomMethod *CryptoRandomMethod::default_method = &crypto_random_method_openssl; /* XXX */
|
17
crypto/lib.mk
Normal file
17
crypto/lib.mk
Normal file
|
@ -0,0 +1,17 @@
|
|||
VPATH+= ${TOPDIR}/crypto
|
||||
|
||||
SRCS+= crypto_encryption.cc
|
||||
SRCS+= crypto_hash.cc
|
||||
SRCS+= crypto_mac.cc
|
||||
|
||||
SRCS+= crypto_encryption_openssl.cc
|
||||
SRCS+= crypto_hash_openssl.cc
|
||||
SRCS+= crypto_mac_openssl.cc
|
||||
SRCS+= crypto_random_openssl.cc
|
||||
|
||||
# Apple has decided to deprecate all of OpenSSL in Mac OS X ~Lion~. Brilliant.
|
||||
ifeq "${OSNAME}" "Darwin"
|
||||
CFLAGS+= -Wno-deprecated-declarations
|
||||
endif
|
||||
|
||||
LDADD+= -lcrypto
|
0
event/Makefile
Normal file
0
event/Makefile
Normal file
91
event/action.h
Normal file
91
event/action.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_ACTION_H
|
||||
#define EVENT_ACTION_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: action.h //
|
||||
// Description: basic classes for event callback management //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Action
|
||||
{
|
||||
protected:
|
||||
bool cancelled_;
|
||||
|
||||
Action () : cancelled_(false)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~Action ()
|
||||
{
|
||||
ASSERT("/action", cancelled_);
|
||||
}
|
||||
|
||||
virtual void cancel () = 0;
|
||||
|
||||
bool is_cancelled ()
|
||||
{
|
||||
return cancelled_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class S, class C> class CallbackAction : public Action
|
||||
{
|
||||
typedef void (S::*const method_t)(void);
|
||||
|
||||
public:
|
||||
S* const obj_;
|
||||
method_t method_;
|
||||
C* callback_;
|
||||
|
||||
public:
|
||||
CallbackAction (S* obj, method_t method, C* cb) : obj_(obj), method_(method)
|
||||
{
|
||||
ASSERT("/action", obj && method);
|
||||
callback_ = cb;
|
||||
}
|
||||
|
||||
~CallbackAction()
|
||||
{
|
||||
delete callback_;
|
||||
}
|
||||
|
||||
virtual void cancel ()
|
||||
{
|
||||
cancelled_ = true;
|
||||
(obj_->*method_) ();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !EVENT_ACTION_H */
|
46
event/callback.h
Normal file
46
event/callback.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_CALLBACK_H
|
||||
#define EVENT_CALLBACK_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: callback.h //
|
||||
// Description: base class for event callback specializations //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Callback
|
||||
{
|
||||
public:
|
||||
virtual ~Callback () {}
|
||||
virtual void execute () = 0;
|
||||
};
|
||||
|
||||
#endif /* !EVENT_CALLBACK_H */
|
150
event/callback_queue.h
Normal file
150
event/callback_queue.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_CALLBACK_QUEUE_H
|
||||
#define EVENT_CALLBACK_QUEUE_H
|
||||
|
||||
#include <deque>
|
||||
#include <event/callback.h>
|
||||
#include <event/action.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: callback_queue.h //
|
||||
// Description: collection classes for event callback management //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CallbackQueue
|
||||
{
|
||||
class QueuedAction : public Action
|
||||
{
|
||||
CallbackQueue& queue_;
|
||||
uint64_t generation_;
|
||||
Callback* callback_;
|
||||
|
||||
public:
|
||||
QueuedAction (CallbackQueue& q, uint64_t g, Callback* cb)
|
||||
: queue_(q),
|
||||
generation_(g),
|
||||
callback_(cb)
|
||||
{
|
||||
}
|
||||
|
||||
~QueuedAction ()
|
||||
{
|
||||
delete callback_;
|
||||
}
|
||||
|
||||
virtual void cancel ()
|
||||
{
|
||||
cancelled_ = true;
|
||||
queue_.cancel (this);
|
||||
}
|
||||
|
||||
friend class CallbackQueue;
|
||||
};
|
||||
|
||||
std::deque<QueuedAction*> queue_;
|
||||
uint64_t generation_;
|
||||
|
||||
public:
|
||||
CallbackQueue ()
|
||||
: queue_(),
|
||||
generation_(0)
|
||||
{ }
|
||||
|
||||
~CallbackQueue ()
|
||||
{
|
||||
std::deque<QueuedAction*>::iterator it;
|
||||
for (it = queue_.begin (); it != queue_.end (); ++it)
|
||||
{
|
||||
delete *it;
|
||||
*it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Action* schedule (Callback* cb)
|
||||
{
|
||||
QueuedAction* a = new QueuedAction (*this, generation_, cb);
|
||||
queue_.push_back (a);
|
||||
return (a);
|
||||
}
|
||||
|
||||
/*
|
||||
* Runs all callbacks that have already been queued, but none that
|
||||
* are added by callbacks that are called as part of the drain
|
||||
* operation. Returns true if there are queued callbacks that were
|
||||
* added during drain.
|
||||
*/
|
||||
bool drain (void)
|
||||
{
|
||||
generation_++;
|
||||
while (! queue_.empty ())
|
||||
{
|
||||
QueuedAction* a = queue_.front ();
|
||||
if (a->generation_ >= generation_)
|
||||
return (true);
|
||||
queue_.pop_front ();
|
||||
if (a->callback_)
|
||||
a->callback_->execute ();
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
return (queue_.empty ());
|
||||
}
|
||||
|
||||
void perform ()
|
||||
{
|
||||
if (! queue_.empty ())
|
||||
{
|
||||
QueuedAction* a = queue_.front ();
|
||||
if (a->callback_)
|
||||
a->callback_->execute ();
|
||||
}
|
||||
}
|
||||
|
||||
void cancel (QueuedAction* a)
|
||||
{
|
||||
std::deque<QueuedAction*>::iterator it;
|
||||
for (it = queue_.begin (); it != queue_.end (); ++it)
|
||||
{
|
||||
if (*it == a)
|
||||
{
|
||||
queue_.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete a;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !EVENT_CALLBACK_QUEUE_H */
|
136
event/event.h
Normal file
136
event/event.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_EVENT_H
|
||||
#define EVENT_EVENT_H
|
||||
|
||||
#include <common/buffer.h>
|
||||
|
||||
/*
|
||||
* The general-purpose event type. Never extended or anything like that.
|
||||
* Tracking a user-specified pointer is handled by the callback, providers of
|
||||
* Events can pass extra data by extending their Callback type, e.g. the
|
||||
* SocketEventCallback used by Socket::accept() to pass back a Socket pointer
|
||||
* along with an Event.
|
||||
* XXX In light of this extension, it may make sense to move the Buffer out
|
||||
* of Event now, since the Callback can handle Buffers independently.
|
||||
*
|
||||
* Because we are primarily a data-movement/processing system, a Buffer is an
|
||||
* integral part of every Event. Plus, Buffers with no data are basically
|
||||
* free to copy, etc.
|
||||
*
|
||||
* Event handlers/callbacks always take a copy of the Event, which is subpar
|
||||
* but necessary since the first thing most of those callbacks do is to cancel
|
||||
* the Action that called them, which in turn deletes the underlying SimpleCallback
|
||||
* object, which would in turn delete the holder of the associated Event if a
|
||||
* reference or pointer were passed. One can argue that the right thing to do
|
||||
* is process the event fully before cancelling the Action, but that is not
|
||||
* how things are done at present.
|
||||
*/
|
||||
struct Event {
|
||||
enum Type {
|
||||
Invalid,
|
||||
Done,
|
||||
EOS,
|
||||
Error,
|
||||
};
|
||||
|
||||
Type type_;
|
||||
int error_;
|
||||
Buffer buffer_;
|
||||
|
||||
Event(void)
|
||||
: type_(Event::Invalid),
|
||||
error_(0),
|
||||
buffer_()
|
||||
{ }
|
||||
|
||||
Event(Type type)
|
||||
: type_(type),
|
||||
error_(0),
|
||||
buffer_()
|
||||
{ }
|
||||
|
||||
Event(Type type, int error)
|
||||
: type_(type),
|
||||
error_(error),
|
||||
buffer_()
|
||||
{ }
|
||||
|
||||
|
||||
Event(Type type, const Buffer& buffer)
|
||||
: type_(type),
|
||||
error_(0),
|
||||
buffer_(buffer)
|
||||
{ }
|
||||
|
||||
Event(Type type, int error, const Buffer& buffer)
|
||||
: type_(type),
|
||||
error_(error),
|
||||
buffer_(buffer)
|
||||
{ }
|
||||
|
||||
Event(const Event& e)
|
||||
: type_(e.type_),
|
||||
error_(e.error_),
|
||||
buffer_(e.buffer_)
|
||||
{ }
|
||||
|
||||
Event& operator= (const Event& e)
|
||||
{
|
||||
type_ = e.type_;
|
||||
error_ = e.error_;
|
||||
buffer_ = e.buffer_;
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
|
||||
static inline std::ostream&
|
||||
operator<< (std::ostream& os, Event::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case Event::Invalid:
|
||||
return (os << "<Invalid>");
|
||||
case Event::Done:
|
||||
return (os << "<Done>");
|
||||
case Event::EOS:
|
||||
return (os << "<EOS>");
|
||||
case Event::Error:
|
||||
return (os << "<Error>");
|
||||
default:
|
||||
return (os << "<Unexpected Event::Type>");
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::ostream&
|
||||
operator<< (std::ostream& os, Event e)
|
||||
{
|
||||
if (e.type_ != Event::Error && e.error_ == 0)
|
||||
return (os << e.type_);
|
||||
return (os << e.type_ << '/' << e.error_ << " [" <<
|
||||
strerror(e.error_) << "]");
|
||||
}
|
||||
|
||||
#endif /* !EVENT_EVENT_H */
|
34
event/event_callback.h
Normal file
34
event/event_callback.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_EVENT_CALLBACK_H
|
||||
#define EVENT_EVENT_CALLBACK_H
|
||||
|
||||
#include <event/event.h>
|
||||
#include <event/typed_callback.h>
|
||||
|
||||
typedef class TypedCallback<Event> EventCallback;
|
||||
|
||||
#endif /* !EVENT_EVENT_CALLBACK_H */
|
22
event/event_message.h
Normal file
22
event/event_message.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_message.h //
|
||||
// Description: sructures for data exchange in shared buffers //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EVENT_EVENT_MESSAGE_H
|
||||
#define EVENT_EVENT_MESSAGE_H
|
||||
|
||||
class EventAction;
|
||||
|
||||
struct EventMessage
|
||||
{
|
||||
int op;
|
||||
EventAction* action;
|
||||
};
|
||||
|
||||
#endif /* !EVENT_EVENT_MESSAGE_H */
|
152
event/event_poll_epoll.cc
Normal file
152
event/event_poll_epoll.cc
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <event/event_system.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_poll_epoll.cc //
|
||||
// Description: IO event handling using Linux epoll functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IoService::open_resources ()
|
||||
{
|
||||
handle_ = ::epoll_create (IO_POLL_EVENT_COUNT);
|
||||
ASSERT(log_, handle_ != -1);
|
||||
}
|
||||
|
||||
void IoService::close_resources ()
|
||||
{
|
||||
if (handle_ >= 0)
|
||||
::close (handle_);
|
||||
}
|
||||
|
||||
void IoService::set_fd (int fd, int rd, int wr, IoNode* node)
|
||||
{
|
||||
struct epoll_event eev;
|
||||
int rv;
|
||||
eev.events = ((rd > 0 ? EPOLLIN : 0) | (wr > 0 ? EPOLLOUT : 0));
|
||||
eev.data.ptr = node;
|
||||
if (eev.events)
|
||||
rv = ::epoll_ctl (handle_, (rd && wr ? EPOLL_CTL_MOD : EPOLL_CTL_ADD), fd, &eev);
|
||||
else
|
||||
rv = ::epoll_ctl (handle_, EPOLL_CTL_DEL, fd, &eev);
|
||||
if (rv < 0 && errno != EEXIST && errno != ENOENT)
|
||||
CRITICAL(log_) << "Could not add event to epoll.";
|
||||
}
|
||||
|
||||
void IoService::poll (int ms)
|
||||
{
|
||||
struct epoll_event eev[IO_POLL_EVENT_COUNT];
|
||||
int evcnt;
|
||||
|
||||
evcnt = ::epoll_wait (handle_, eev, IO_POLL_EVENT_COUNT, ms);
|
||||
if (evcnt < 0 && errno != EINTR)
|
||||
CRITICAL(log_) << "Could not poll epoll.";
|
||||
|
||||
for (int i = 0; i < evcnt; ++i)
|
||||
{
|
||||
int flg = eev[i].events;
|
||||
IoNode* node = (IoNode*) eev[i].data.ptr;
|
||||
EventAction* act;
|
||||
Event ok;
|
||||
|
||||
if ((flg & EPOLLIN))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeAccept && (ev.type_ = Event::Done)) || read_channel (node->fd, ev, 1))
|
||||
{
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
set_fd (node->fd, -1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
read_channel (node->fd, ok, 0);
|
||||
}
|
||||
|
||||
if ((flg & EPOLLOUT))
|
||||
{
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeConnect && (ev.type_ = Event::Done)) ||
|
||||
(act->mode_ == StreamModeWrite && write_channel (node->fd, ev)) ||
|
||||
(act->mode_ == StreamModeEnd && close_channel (node->fd, ev)))
|
||||
{
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
set_fd (node->fd, (node->reading ? 2 : 0), -1, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! (flg & (EPOLLIN | EPOLLOUT)))
|
||||
{
|
||||
if ((flg & EPOLLERR))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
set_fd (node->fd, -1, 0, node);
|
||||
}
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
set_fd (node->fd, 0, -1, node);
|
||||
}
|
||||
}
|
||||
else if ((flg & EPOLLHUP))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::EOS;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
set_fd (node->fd, -1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
159
event/event_poll_kqueue.cc
Normal file
159
event/event_poll_kqueue.cc
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <event/event_system.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_poll_kqueue.cc //
|
||||
// Description: IO event handling using FreeBSD kevent functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IoService::open_resources ()
|
||||
{
|
||||
handle_ = kqueue ();
|
||||
ASSERT(log_, handle_ != -1);
|
||||
}
|
||||
|
||||
void IoService::close_resources ()
|
||||
{
|
||||
if (handle_ >= 0)
|
||||
::close (handle_);
|
||||
}
|
||||
|
||||
void IoService::set_fd (int fd, int rd, int wr, IoNode* node)
|
||||
{
|
||||
struct kevent kev;
|
||||
int rv;
|
||||
if (rd == 1)
|
||||
EV_SET (&kev, fd, EVFILT_READ, EV_ADD, 0, 0, node);
|
||||
else if (wr == 1)
|
||||
EV_SET (&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, node);
|
||||
else if (rd == -1)
|
||||
EV_SET (&kev, fd, EVFILT_READ, EV_DELETE, 0, 0, node);
|
||||
else if (wr == -1)
|
||||
EV_SET (&kev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, node);
|
||||
rv = ::kevent (handle_, &kev, 1, 0, 0, 0);
|
||||
if (rv < 0 && errno != EEXIST && errno != ENOENT)
|
||||
CRITICAL(log_) << "Could not add event to kqueue.";
|
||||
}
|
||||
|
||||
void IoService::poll (int ms)
|
||||
{
|
||||
struct kevent kev[IO_POLL_EVENT_COUNT];
|
||||
struct timespec ts;
|
||||
int evcnt;
|
||||
|
||||
if (ms != -1)
|
||||
{
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000000;
|
||||
}
|
||||
|
||||
evcnt = ::kevent (handle_, 0, 0, kev, IO_POLL_EVENT_COUNT, (ms == -1 ? 0 : &ts));
|
||||
if (evcnt < 0 && errno != EINTR)
|
||||
CRITICAL(log_) << "Could not poll kqueue.";
|
||||
|
||||
for (int i = 0; i < evcnt; i++)
|
||||
{
|
||||
int sck = kev[i].ident;
|
||||
int flt = kev[i].filter;
|
||||
int flg = kev[i].flags;
|
||||
IoNode* node = (IoNode*) kev[i].udata;
|
||||
EventAction* act;
|
||||
Event ok;
|
||||
|
||||
if ((flg & EV_ERROR))
|
||||
{
|
||||
if (flt == EVFILT_READ && node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
set_fd (sck, -1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
else if (flt == EVFILT_WRITE && node && (act = node->write_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
set_fd (sck, (node->reading ? 2 : 0), -1, node);
|
||||
}
|
||||
}
|
||||
else if ((flg & EV_EOF))
|
||||
{
|
||||
if (flt == EVFILT_READ && node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::EOS;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
set_fd (sck, -1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
}
|
||||
else if ((flt == EVFILT_READ))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeAccept && (ev.type_ = Event::Done)) || read_channel (sck, ev, 1))
|
||||
{
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
set_fd (sck, -1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
read_channel (sck, ok, 0);
|
||||
}
|
||||
else if ((flt == EVFILT_WRITE))
|
||||
{
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeConnect && (ev.type_ = Event::Done)) ||
|
||||
(act->mode_ == StreamModeWrite && write_channel (sck, ev)) ||
|
||||
(act->mode_ == StreamModeEnd && close_channel (sck, ev)))
|
||||
{
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
set_fd (sck, (node->reading ? 2 : 0), -1, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
157
event/event_poll_poll.cc
Normal file
157
event/event_poll_poll.cc
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/errno.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <event/event_system.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_poll_poll.cc //
|
||||
// Description: IO event handling using standard poll functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IoService::open_resources ()
|
||||
{
|
||||
}
|
||||
|
||||
void IoService::close_resources ()
|
||||
{
|
||||
}
|
||||
|
||||
void IoService::set_fd (int fd, int rd, int wr, IoNode* node)
|
||||
{
|
||||
}
|
||||
|
||||
void IoService::poll (int ms)
|
||||
{
|
||||
struct pollfd fds[fd_map_.size () + 1];
|
||||
int i, j, f;
|
||||
int cnt;
|
||||
|
||||
fds[0].fd = rfd_;
|
||||
fds[0].events = POLLIN;
|
||||
fds[0].revents = 0;
|
||||
j = 1;
|
||||
|
||||
std::map<int, IoNode>::iterator it;
|
||||
for (it = fd_map_.begin (); it != fd_map_.end (); ++it)
|
||||
{
|
||||
if ((f = (it->second.reading ? POLLIN : 0) | (it->second.writing ? POLLOUT : 0)))
|
||||
{
|
||||
fds[j].fd = it->first;
|
||||
fds[j].events = f;
|
||||
fds[j].revents = 0;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
cnt = ::poll (fds, j, ms);
|
||||
if (cnt < 0 && errno != EINTR)
|
||||
CRITICAL(log_) << "Could not poll.";
|
||||
|
||||
for (i = 0; i < j; ++i)
|
||||
{
|
||||
if (fds[i].revents == 0)
|
||||
continue;
|
||||
if (cnt-- == 0)
|
||||
break;
|
||||
|
||||
int sck = fds[i].fd;
|
||||
int flg = fds[i].revents;
|
||||
it = fd_map_.find (sck);
|
||||
IoNode* node = (it != fd_map_.end () ? &it->second : 0);
|
||||
EventAction* act;
|
||||
Event ok;
|
||||
|
||||
if ((flg & POLLIN))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeAccept && (ev.type_ = Event::Done)) || read_channel (sck, ev, 1))
|
||||
{
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
read_channel (sck, ok, 0);
|
||||
}
|
||||
|
||||
if ((flg & POLLOUT))
|
||||
{
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeConnect && (ev.type_ = Event::Done)) ||
|
||||
(act->mode_ == StreamModeWrite && write_channel (sck, ev)) ||
|
||||
(act->mode_ == StreamModeEnd && close_channel (sck, ev)))
|
||||
{
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! (flg & (POLLIN | POLLOUT)))
|
||||
{
|
||||
if ((flg & (POLLERR | POLLNVAL)))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
}
|
||||
}
|
||||
else if ((flg & POLLHUP))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::EOS;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
174
event/event_poll_port.cc
Normal file
174
event/event_poll_port.cc
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <port.h>
|
||||
#include <unistd.h>
|
||||
#include <event/event_system.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_poll_port.cc //
|
||||
// Description: IO event handling using SunOS port functions //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IoService::open_resources ()
|
||||
{
|
||||
handle_ = port_create ();
|
||||
ASSERT(log_, handle_ != -1);
|
||||
}
|
||||
|
||||
void IoService::close_resources ()
|
||||
{
|
||||
if (handle_ >= 0)
|
||||
::close (handle_);
|
||||
}
|
||||
|
||||
void IoService::set_fd (int fd, int rd, int wr, IoNode* node)
|
||||
{
|
||||
int events;
|
||||
int rv;
|
||||
events = ((rd > 0 ? EPOLLIN : 0) | (wr > 0 ? EPOLLOUT : 0));
|
||||
if (events)
|
||||
{
|
||||
rv = ::port_associate (handle_, PORT_SOURCE_FD, fd, events, node);
|
||||
if (rv < 0 && errno != EEXIST)
|
||||
CRITICAL(log_) << "Could not add event to port.";
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = ::port_dissociate (handle_, PORT_SOURCE_FD, fd);
|
||||
if (rv < 0 && errno != ENOENT)
|
||||
CRITICAL(log_) << "Could not add event to port.";
|
||||
}
|
||||
}
|
||||
|
||||
void IoService::poll (int ms)
|
||||
{
|
||||
port_event_t pev[IO_POLL_EVENT_COUNT];
|
||||
unsigned int evcnt = 1;
|
||||
struct timespec ts;
|
||||
int rv;
|
||||
|
||||
if (ms != -1)
|
||||
{
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000000;
|
||||
}
|
||||
|
||||
rv = ::port_getn (handle_, pev, IO_POLL_EVENT_COUNT, &evcnt, (ms == -1 ? 0 : &ts));
|
||||
if (rv < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
CRITICAL(log_) << "Could not poll port.";
|
||||
evcnt = 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < evcnt; ++i)
|
||||
{
|
||||
int sck = pev[i].portev_object;
|
||||
int flg = pev[i].portev_events;
|
||||
IoNode* node = (IoNode*) pev[i].portev_user;
|
||||
EventAction* act;
|
||||
Event ok;
|
||||
|
||||
if ((flg & POLLIN))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeAccept && (ev.type_ = Event::Done)) || read_channel (sck, ev, 1))
|
||||
{
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
else
|
||||
set_fd (sck, 1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
else if (node)
|
||||
{
|
||||
read_channel (sck, ok, 0);
|
||||
set_fd (sck, 1, (node->writing ? 2 : 0), node);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flg & POLLOUT))
|
||||
{
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeConnect && (ev.type_ = Event::Done)) ||
|
||||
(act->mode_ == StreamModeWrite && write_channel (sck, ev)) ||
|
||||
(act->mode_ == StreamModeEnd && close_channel (sck, ev)))
|
||||
{
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
}
|
||||
else
|
||||
set_fd (sck, (node->reading ? 2 : 0), 1, node);
|
||||
}
|
||||
}
|
||||
|
||||
if (! (flg & (POLLIN | POLLOUT)))
|
||||
{
|
||||
if ((flg & POLLERR))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
}
|
||||
}
|
||||
else if ((flg & POLLHUP))
|
||||
{
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
if (act->callback_)
|
||||
act->callback_->param ().type_ = Event::EOS;
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
138
event/event_poll_select.cc
Normal file
138
event/event_poll_select.cc
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <event/event_system.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_poll_select.cc //
|
||||
// Description: IO event handling using traditional select calls //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IoService::open_resources ()
|
||||
{
|
||||
}
|
||||
|
||||
void IoService::close_resources ()
|
||||
{
|
||||
}
|
||||
|
||||
void IoService::set_fd (int fd, int rd, int wr, IoNode* node)
|
||||
{
|
||||
}
|
||||
|
||||
void IoService::poll (int ms)
|
||||
{
|
||||
fd_set read_set, write_set;
|
||||
struct timeval tv;
|
||||
int maxfd;
|
||||
int fdcnt;
|
||||
|
||||
FD_ZERO(&read_set);
|
||||
FD_ZERO(&write_set);
|
||||
FD_SET(rfd_, &read_set);
|
||||
maxfd = rfd_;
|
||||
|
||||
std::map<int, IoNode>::iterator it;
|
||||
for (it = fd_map_.begin (); it != fd_map_.end (); ++it)
|
||||
{
|
||||
if (it->second.reading)
|
||||
FD_SET (it->first, &read_set);
|
||||
if (it->second.writing)
|
||||
FD_SET (it->first, &write_set);
|
||||
if (maxfd < it->first)
|
||||
maxfd = it->first;
|
||||
}
|
||||
|
||||
ASSERT(log_, maxfd != -1);
|
||||
|
||||
if (ms != -1)
|
||||
{
|
||||
tv.tv_sec = ms / 1000;
|
||||
tv.tv_usec = ms % 1000;
|
||||
}
|
||||
|
||||
fdcnt = ::select (maxfd + 1, &read_set, &write_set, 0, (ms == -1 ? 0 : &tv));
|
||||
if (fdcnt < 0 && errno != EINTR)
|
||||
CRITICAL(log_) << "Could not poll select.";
|
||||
|
||||
for (int sck = 0; sck <= maxfd && fdcnt > 0; ++sck)
|
||||
{
|
||||
if (FD_ISSET (sck, &read_set))
|
||||
{
|
||||
it = fd_map_.find (sck);
|
||||
IoNode* node = (it != fd_map_.end () ? &it->second : 0);
|
||||
EventAction* act;
|
||||
Event ok;
|
||||
|
||||
if (node && (act = node->read_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeAccept && (ev.type_ = Event::Done)) || read_channel (sck, ev, 1))
|
||||
{
|
||||
schedule (act);
|
||||
node->reading = false;
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
read_channel (sck, ok, 0);
|
||||
|
||||
ASSERT(log_, fdcnt > 0);
|
||||
fdcnt--;
|
||||
}
|
||||
|
||||
if (FD_ISSET (sck, &write_set))
|
||||
{
|
||||
it = fd_map_.find (sck);
|
||||
IoNode* node = (it != fd_map_.end () ? &it->second : 0);
|
||||
EventAction* act;
|
||||
Event ok;
|
||||
|
||||
if (node && (act = node->write_action))
|
||||
{
|
||||
Event& ev = (act->callback_ ? act->callback_->param () : ok);
|
||||
if ((act->mode_ == StreamModeConnect && (ev.type_ = Event::Done)) ||
|
||||
(act->mode_ == StreamModeWrite && write_channel (sck, ev)) ||
|
||||
(act->mode_ == StreamModeEnd && close_channel (sck, ev)))
|
||||
{
|
||||
schedule (act);
|
||||
node->writing = false;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(log_, fdcnt > 0);
|
||||
fdcnt--;
|
||||
}
|
||||
}
|
||||
}
|
133
event/event_system.cc
Normal file
133
event/event_system.cc
Normal file
|
@ -0,0 +1,133 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_system.cc //
|
||||
// Description: global event handling core class implementation //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
#include <event/event_system.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
static void signal_reload (int) { event_system.reload (); }
|
||||
static void signal_stop (int) { event_system.stop (); }
|
||||
}
|
||||
|
||||
EventSystem::EventSystem () : log_ ("/event/system"), reload_ (false), stop_ (false)
|
||||
{
|
||||
::signal (SIGHUP, signal_reload);
|
||||
::signal (SIGINT, signal_stop);
|
||||
::signal (SIGPIPE, SIG_IGN);
|
||||
|
||||
struct rlimit rlim;
|
||||
int rv = ::getrlimit (RLIMIT_NOFILE, &rlim);
|
||||
if (rv == 0 && rlim.rlim_cur < rlim.rlim_max)
|
||||
{
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
rv = ::setrlimit (RLIMIT_NOFILE, &rlim);
|
||||
}
|
||||
}
|
||||
|
||||
void EventSystem::run ()
|
||||
{
|
||||
EventMessage msg;
|
||||
|
||||
INFO(log_) << "Starting event system.";
|
||||
|
||||
io_service_.start ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (gateway_.read (msg))
|
||||
{
|
||||
if (msg.op >= 0)
|
||||
{
|
||||
if (msg.action && ! msg.action->is_cancelled ())
|
||||
{
|
||||
if (msg.action->callback_)
|
||||
msg.action->callback_->execute ();
|
||||
else
|
||||
msg.action->cancel ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete msg.action;
|
||||
}
|
||||
}
|
||||
|
||||
if (reload_)
|
||||
{
|
||||
if (! interest_queue_[EventInterestReload].empty ())
|
||||
{
|
||||
INFO(log_) << "Running reload handlers.";
|
||||
interest_queue_[EventInterestReload].drain ();
|
||||
INFO(log_) << "Reload handlers have been run.";
|
||||
}
|
||||
reload_ = false;
|
||||
::signal (SIGHUP, signal_reload);
|
||||
}
|
||||
|
||||
if (stop_)
|
||||
{
|
||||
if (! interest_queue_[EventInterestStop].empty ())
|
||||
{
|
||||
INFO(log_) << "Running stop handlers.";
|
||||
interest_queue_[EventInterestStop].drain ();
|
||||
INFO(log_) << "Stop handlers have been run.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
io_service_.stop ();
|
||||
}
|
||||
|
||||
void EventSystem::reload ()
|
||||
{
|
||||
::signal (SIGHUP, SIG_IGN);
|
||||
reload_ = true;
|
||||
gateway_.wakeup ();
|
||||
}
|
||||
|
||||
void EventSystem::stop ()
|
||||
{
|
||||
::signal (SIGINT, SIG_IGN);
|
||||
stop_ = true;
|
||||
gateway_.wakeup ();
|
||||
}
|
||||
|
||||
Action* EventSystem::register_interest (EventInterest interest, Callback* cb)
|
||||
{
|
||||
return interest_queue_[interest].schedule (cb);
|
||||
}
|
||||
|
||||
Action* EventSystem::track (int fd, StreamMode mode, EventCallback* cb)
|
||||
{
|
||||
EventAction* act;
|
||||
|
||||
if ((act = new EventAction (*this, fd, mode, cb)))
|
||||
{
|
||||
EventMessage msg = {1, act};
|
||||
io_service_.take_message (msg);
|
||||
}
|
||||
|
||||
return (cb ? act : 0);
|
||||
}
|
||||
|
||||
void EventSystem::cancel (EventAction* act)
|
||||
{
|
||||
if (act)
|
||||
{
|
||||
EventMessage msg = {-1, act};
|
||||
io_service_.take_message (msg);
|
||||
}
|
||||
}
|
||||
|
||||
EventSystem event_system;
|
92
event/event_system.h
Normal file
92
event/event_system.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: event_system.h //
|
||||
// Description: global event handling core class definition //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EVENT_EVENT_SYSTEM_H
|
||||
#define EVENT_EVENT_SYSTEM_H
|
||||
|
||||
#include <common/buffer.h>
|
||||
#include <common/ring_buffer.h>
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
#include <event/object_callback.h>
|
||||
#include <event/callback_queue.h>
|
||||
#include <event/event_message.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
class EventAction;
|
||||
|
||||
enum EventInterest
|
||||
{
|
||||
EventInterestReload,
|
||||
EventInterestStop,
|
||||
EventInterests
|
||||
};
|
||||
|
||||
enum StreamMode
|
||||
{
|
||||
StreamModeConnect,
|
||||
StreamModeAccept,
|
||||
StreamModeRead,
|
||||
StreamModeWrite,
|
||||
StreamModeEnd
|
||||
};
|
||||
|
||||
class EventSystem
|
||||
{
|
||||
private:
|
||||
LogHandle log_;
|
||||
IoService io_service_;
|
||||
WaitBuffer<EventMessage> gateway_;
|
||||
CallbackQueue interest_queue_[EventInterests];
|
||||
bool reload_, stop_;
|
||||
|
||||
public:
|
||||
EventSystem ();
|
||||
|
||||
void run ();
|
||||
void reload ();
|
||||
void stop ();
|
||||
|
||||
Action* register_interest (EventInterest interest, Callback* cb);
|
||||
Action* track (int fd, StreamMode mode, EventCallback* cb);
|
||||
void cancel (EventAction* act);
|
||||
|
||||
int take_message (const EventMessage& msg) { return gateway_.write (msg); }
|
||||
};
|
||||
|
||||
class EventAction : public Action
|
||||
{
|
||||
public:
|
||||
EventSystem& system_;
|
||||
int fd_;
|
||||
StreamMode mode_;
|
||||
EventCallback* callback_;
|
||||
|
||||
public:
|
||||
EventAction (EventSystem& sys, int fd, StreamMode mode, EventCallback* cb) : system_ (sys)
|
||||
{
|
||||
fd_ = fd; mode_ = mode; callback_ = cb;
|
||||
}
|
||||
|
||||
~EventAction ()
|
||||
{
|
||||
delete callback_;
|
||||
}
|
||||
|
||||
virtual void cancel ()
|
||||
{
|
||||
cancelled_ = true;
|
||||
system_.cancel (this);
|
||||
}
|
||||
};
|
||||
|
||||
extern EventSystem event_system;
|
||||
|
||||
#endif /* !EVENT_EVENT_SYSTEM_H */
|
329
event/io_service.cc
Normal file
329
event/io_service.cc
Normal file
|
@ -0,0 +1,329 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: io_service.h //
|
||||
// Description: servicing of network IO requests for the event system //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <limits.h>
|
||||
#include <event/event_system.h>
|
||||
#include <event/io_service.h>
|
||||
|
||||
IoService::IoService () : Thread ("IoService"), log_ ("/io/thread")
|
||||
{
|
||||
handle_ = rfd_ = wfd_ = -1;
|
||||
|
||||
int fd[2];
|
||||
if (::pipe (fd) == 0)
|
||||
rfd_ = fd[0], wfd_ = fd[1];
|
||||
}
|
||||
|
||||
IoService::~IoService ()
|
||||
{
|
||||
if (rfd_ >= 0)
|
||||
::close (rfd_);
|
||||
if (wfd_ >= 0)
|
||||
::close (wfd_);
|
||||
}
|
||||
|
||||
void IoService::main ()
|
||||
{
|
||||
EventMessage msg;
|
||||
|
||||
INFO(log_) << "Starting IO thread.";
|
||||
|
||||
open_resources ();
|
||||
IoNode node = {rfd_, true, false, 0, 0};
|
||||
set_fd (rfd_, 1, 0, &node);
|
||||
|
||||
while (! stop_)
|
||||
{
|
||||
while (gateway_.read (msg))
|
||||
{
|
||||
if (msg.op >= 0)
|
||||
handle_request (msg.action);
|
||||
else
|
||||
cancel (msg.action);
|
||||
}
|
||||
|
||||
poll (-1);
|
||||
}
|
||||
|
||||
set_fd (rfd_, -1, 0);
|
||||
close_resources ();
|
||||
}
|
||||
|
||||
void IoService::stop ()
|
||||
{
|
||||
stop_ = true;
|
||||
wakeup ();
|
||||
Thread::stop ();
|
||||
}
|
||||
|
||||
void IoService::handle_request (EventAction* act)
|
||||
{
|
||||
Event ev;
|
||||
|
||||
if (act)
|
||||
{
|
||||
switch (act->mode_)
|
||||
{
|
||||
case StreamModeConnect:
|
||||
if (connect_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev)))
|
||||
schedule (act);
|
||||
else
|
||||
track (act);
|
||||
return;
|
||||
|
||||
case StreamModeAccept:
|
||||
track (act);
|
||||
return;
|
||||
|
||||
case StreamModeRead:
|
||||
if (read_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev), 1))
|
||||
schedule (act);
|
||||
else
|
||||
track (act);
|
||||
return;
|
||||
|
||||
case StreamModeWrite:
|
||||
if (write_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev)))
|
||||
schedule (act);
|
||||
else
|
||||
track (act);
|
||||
return;
|
||||
|
||||
case StreamModeEnd:
|
||||
if (close_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev)))
|
||||
schedule (act);
|
||||
else
|
||||
track (act);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IoService::connect_channel (int fd, Event& ev)
|
||||
{
|
||||
struct sockaddr adr;
|
||||
int n = 0;
|
||||
|
||||
if (ev.buffer_.length () <= sizeof adr)
|
||||
ev.buffer_.copyout ((uint8_t*) &adr, (n = ev.buffer_.length ()));
|
||||
|
||||
int rv = ::connect (fd, &adr, n);
|
||||
switch (rv)
|
||||
{
|
||||
case 0:
|
||||
ev.type_ = Event::Done;
|
||||
break;
|
||||
case -1:
|
||||
switch (errno)
|
||||
{
|
||||
case EINPROGRESS:
|
||||
return false;
|
||||
default:
|
||||
ev.type_ = Event::Error;
|
||||
ev.error_ = errno;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoService::read_channel (int fd, Event& ev, int flg)
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
len = ::read (fd, read_pool_, sizeof read_pool_);
|
||||
if (len < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
return false;
|
||||
default:
|
||||
ev.type_ = Event::Error;
|
||||
ev.error_ = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (len == 0)
|
||||
{
|
||||
ev.type_ = Event::EOS;
|
||||
}
|
||||
else if (flg & 1)
|
||||
{
|
||||
ev.type_ = Event::Done;
|
||||
ev.buffer_.append (read_pool_, len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoService::write_channel (int fd, Event& ev)
|
||||
{
|
||||
struct iovec iov[IOV_MAX];
|
||||
size_t iovcnt;
|
||||
ssize_t len;
|
||||
|
||||
if (ev.buffer_.empty ())
|
||||
{
|
||||
ev.type_ = Event::Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
iovcnt = ev.buffer_.fill_iovec (iov, IOV_MAX);
|
||||
len = ::writev (fd, iov, iovcnt);
|
||||
if (len < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
return false;
|
||||
default:
|
||||
ev.type_ = Event::Error;
|
||||
ev.error_ = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((size_t) len < ev.buffer_.length ())
|
||||
{
|
||||
ev.buffer_.skip (len);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.type_ = Event::Done;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoService::close_channel (int fd, Event& ev)
|
||||
{
|
||||
int rv = ::close (fd);
|
||||
if (rv == -1 && errno == EAGAIN)
|
||||
return false;
|
||||
|
||||
ev.type_ = Event::Done;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IoService::track (EventAction* act)
|
||||
{
|
||||
std::map<int, IoNode>::iterator it;
|
||||
int fd;
|
||||
|
||||
if (act)
|
||||
{
|
||||
fd = act->fd_;
|
||||
it = fd_map_.find (fd);
|
||||
|
||||
switch (act->mode_)
|
||||
{
|
||||
case StreamModeAccept:
|
||||
case StreamModeRead:
|
||||
if (it == fd_map_.end ())
|
||||
{
|
||||
IoNode node = {fd, true, false, act, 0};
|
||||
set_fd (fd, 1, 0, &(fd_map_[fd] = node));
|
||||
}
|
||||
else if (act->mode_ == StreamModeRead)
|
||||
{
|
||||
it->second.reading = true, it->second.read_action = act;
|
||||
set_fd (fd, 1, (it->second.writing ? 2 : 0), &it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (act->callback_) act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
}
|
||||
break;
|
||||
|
||||
case StreamModeConnect:
|
||||
case StreamModeWrite:
|
||||
case StreamModeEnd:
|
||||
if (it == fd_map_.end ())
|
||||
{
|
||||
IoNode node = {fd, false, true, 0, act};
|
||||
set_fd (fd, 0, 1, &(fd_map_[fd] = node));
|
||||
}
|
||||
else if (act->mode_ == StreamModeWrite)
|
||||
{
|
||||
it->second.writing = true, it->second.write_action = act;
|
||||
set_fd (fd, (it->second.reading ? 2 : 0), 1, &it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (act->callback_) act->callback_->param ().type_ = Event::Error;
|
||||
schedule (act);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IoService::cancel (EventAction* act)
|
||||
{
|
||||
std::map<int, IoNode>::iterator it;
|
||||
int fd;
|
||||
|
||||
if (act)
|
||||
{
|
||||
fd = act->fd_;
|
||||
it = fd_map_.find (fd);
|
||||
|
||||
switch (act->mode_)
|
||||
{
|
||||
case StreamModeAccept:
|
||||
case StreamModeRead:
|
||||
if (it != fd_map_.end () && it->second.read_action == act)
|
||||
{
|
||||
it->second.reading = false, it->second.read_action = 0;
|
||||
if (it->second.write_action == 0)
|
||||
fd_map_.erase (it);
|
||||
set_fd (fd, -1, (it->second.writing ? 2 : 0), &it->second);
|
||||
}
|
||||
break;
|
||||
|
||||
case StreamModeConnect:
|
||||
case StreamModeWrite:
|
||||
case StreamModeEnd:
|
||||
if (it != fd_map_.end () && it->second.write_action == act)
|
||||
{
|
||||
it->second.writing = false, it->second.write_action = 0;
|
||||
if (it->second.read_action == 0)
|
||||
fd_map_.erase (it);
|
||||
set_fd (fd, (it->second.reading ? 2 : 0), -1, &it->second);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
terminate (act);
|
||||
}
|
||||
}
|
||||
|
||||
void IoService::schedule (EventAction* act)
|
||||
{
|
||||
EventMessage msg = {1, act};
|
||||
event_system.take_message (msg);
|
||||
}
|
||||
|
||||
void IoService::terminate (EventAction* act)
|
||||
{
|
||||
EventMessage msg = {-1, act};
|
||||
event_system.take_message (msg);
|
||||
}
|
73
event/io_service.h
Normal file
73
event/io_service.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: io_service.h //
|
||||
// Description: servicing of network IO requests for the event system //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EVENT_IO_SERVICE_H
|
||||
#define EVENT_IO_SERVICE_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <common/buffer.h>
|
||||
#include <common/ring_buffer.h>
|
||||
#include <common/thread/thread.h>
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
#include <event/event_message.h>
|
||||
|
||||
#define IO_READ_BUFFER_SIZE 0x10000
|
||||
#define IO_POLL_EVENT_COUNT 512
|
||||
|
||||
struct IoNode
|
||||
{
|
||||
int fd;
|
||||
bool reading;
|
||||
bool writing;
|
||||
EventAction* read_action;
|
||||
EventAction* write_action;
|
||||
};
|
||||
|
||||
class IoService : public Thread
|
||||
{
|
||||
private:
|
||||
LogHandle log_;
|
||||
RingBuffer<EventMessage> gateway_;
|
||||
uint8_t read_pool_[IO_READ_BUFFER_SIZE];
|
||||
std::map<int, IoNode> fd_map_;
|
||||
int handle_, rfd_, wfd_;
|
||||
|
||||
public:
|
||||
IoService ();
|
||||
virtual ~IoService ();
|
||||
|
||||
virtual void main ();
|
||||
virtual void stop ();
|
||||
|
||||
private:
|
||||
void handle_request (EventAction* act);
|
||||
bool connect_channel (int fd, Event& ev);
|
||||
bool read_channel (int fd, Event& ev, int flg);
|
||||
bool write_channel (int fd, Event& ev);
|
||||
bool close_channel (int fd, Event& ev);
|
||||
void track (EventAction* act);
|
||||
void cancel (EventAction* act);
|
||||
void schedule (EventAction* act);
|
||||
void terminate (EventAction* act);
|
||||
|
||||
void open_resources ();
|
||||
void close_resources ();
|
||||
void set_fd (int fd, int rd, int wr, IoNode* node = 0);
|
||||
void poll (int ms);
|
||||
|
||||
public:
|
||||
bool idle () const { return fd_map_.empty (); }
|
||||
void wakeup () { ::write (wfd_, "*", 1); }
|
||||
void take_message (const EventMessage& msg) { gateway_.write (msg); wakeup (); }
|
||||
};
|
||||
|
||||
#endif /* !EVENT_IO_SERVICE_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue