From c580a00aac271a524e5a75b35f4b91c174ed227b Mon Sep 17 00:00:00 2001 From: michele papalini Date: Thu, 23 Feb 2017 17:01:34 +0100 Subject: Initial commit: sb-forwarder, metis. Change-Id: I65ee3c851a6901929ef4417ad80d34bca0dce445 Signed-off-by: michele papalini --- metis/ccnx/forwarder/metis/core/metis_Dispatcher.h | 303 +++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 metis/ccnx/forwarder/metis/core/metis_Dispatcher.h (limited to 'metis/ccnx/forwarder/metis/core/metis_Dispatcher.h') diff --git a/metis/ccnx/forwarder/metis/core/metis_Dispatcher.h b/metis/ccnx/forwarder/metis/core/metis_Dispatcher.h new file mode 100644 index 00000000..e936df22 --- /dev/null +++ b/metis/ccnx/forwarder/metis/core/metis_Dispatcher.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @header Metis Dispatcher + * @abstract The dispatcher is the event loop run by MetisForwarder. + * @discussion + * These functions manage listeners, timers, and network events inside + * the event loop. + * + * Curently, it is a thin wrapper around an event so we don't have to + * expose that implementation detail to other modules. + * + */ + +#ifndef Metis_metis_Dispatcher_h +#define Metis_metis_Dispatcher_h + +#include +#include + +struct metis_dispatcher; +typedef struct metis_dispatcher MetisDispatcher; + +#include +#include +#include +#include +#include +#include +#include + +#include + +PARCEventScheduler *metisDispatcher_GetEventScheduler(MetisDispatcher *dispatcher); +/** + * Creates an event dispatcher + * + * Event dispatcher based on PARCEvent + * + * @return non-null Allocated event dispatcher + * @return null An error + * + * Example: + * @code + * <#example#> + * @endcode + */ +MetisDispatcher *metisDispatcher_Create(MetisLogger *logger); + +/** + * Destroys event dispatcher + * + * Caller is responsible for destroying call events before destroying + * the event dispatcher. + * + * @param [<#in out in,out#>] <#name#> <#description#> + * + * @return <#value#> <#explanation#> + * + * Example: + * @code + * <#example#> + * @endcode + */ +void metisDispatcher_Destroy(MetisDispatcher **dispatcherPtr); + +/** + * @function metisDispatcher_Stop + * @abstract Called from a different thread, tells the dispatcher to stop + * @discussion + * Called from a user thread or from an interrupt handler. + * Does not block. Use metisDispatcher_WaitForStopped() to + * block until stopped after calling this. + * + * @param <#param1#> + * @return <#return#> + */ +void metisDispatcher_Stop(MetisDispatcher *dispatcher); + +/** + * @function metisDispatcher_WaitForStopped + * @abstract Blocks until dispatcher in stopped state + * @discussion + * Used after metisDispatcher_Stop() to wait for stop. + * + * @param <#param1#> + * @return <#return#> + */ +void metisDispatcher_WaitForStopped(MetisDispatcher *dispatcher); + +/** + * @function metisDispatcher_Run + * @abstract Runs the forwarder, blocks. + * @discussion + * <#Discussion#> + * + * @param <#param1#> + */ +void metisDispatcher_Run(MetisDispatcher *dispatcher); + +/** + * @function metisDispatcher_RunDuration + * @abstract Runs forwarder for at most duration, blocks. + * @discussion + * Blocks running the forwarder for a duration. May be called + * iteratively to keep running. Duration is a minimum, actual + * runtime may be slightly longer. + * + * @param <#param1#> + */ +void metisDispatcher_RunDuration(MetisDispatcher *dispatcher, struct timeval *duration); + +/** + * @header metisDispatcher_RunCount + * @abstract Run the event loop for the given count cycles + * @discussion + * Runs the event loop for the given number of cycles, blocking + * until done. May be called sequentially over and over. + * + */ +void metisDispatcher_RunCount(MetisDispatcher *dispatcher, unsigned count); + +typedef int MetisSocketType; + +typedef struct evconnlistener MetisListener; + +/** + * @typedef MetisListenerCallback + * @abstract Callback function typedef for a stream listener + * + * @constant listener is the object created by metisForwarder_NewBind() that received the client connection + * @constant client_socket is the client socket + * @constant user_data is the user_data passed to metisForwarder_NewBind() + * @constant client_addr is the client address + * @constant socklen is the length of client_addr + * @discussion <#Discussion#> + */ +typedef void (MetisListenerCallback)(MetisListener *listener, MetisSocketType client_socket, + struct sockaddr *client_addr, int socklen, void *user_data); + +/** + * @header metisForwarder_NewBind + * @abstract Allocate a new stream listener + * @discussion + * The server socket will be freed when closed and will be reusable. + * + * @param metis the forwarder that owns the event loop + * @param cb is the callback for a new connection + * @param user_data is opaque user data passed to the callback + * @param backlog is the listen() depth, may use -1 for a default value + * @param sa is the socket address to bind to (INET, INET6, LOCAL) + * @param socklen is the sizeof the actual sockaddr (e.g. sizeof(sockaddr_un)) + */ +PARCEventSocket *metisDispatcher_CreateListener(MetisDispatcher *dispatcher, + PARCEventSocket_Callback *callback, void *user_data, + int backlog, const struct sockaddr *sa, int socklen); + +void metisDispatcher_DestroyListener(MetisDispatcher *dispatcher, PARCEventSocket **listenerPtr); + +typedef struct event MetisTimerEvent; +typedef struct event MetisNetworkEvent; +typedef struct event MetisSignalEvent; + +/** + * @typedef MetisEventCallback + * @abstract A network event or a timer callback + * @constant fd The file descriptor associated with the event, may be -1 for timers + * @constant which_event is a bitmap of the MetisEventType + * @constant user_data is the user_data passed to MetisForwarder_CreateEvent() + * @discussion <#Discussion#> + */ +typedef void (MetisEventCallback)(MetisSocketType fd, short which_event, void *user_data); + +/** + * @function metisDispatcher_CreateTimer + * @abstract Creates a MetisEvent for use as a timer. + * @discussion + * + * When created, the timer is idle and you need to call metisForwarder_StartTimer() + * + * @param isPeriodic means the timer will fire repeatidly, otherwise it is a one-shot and + * needs to be set again with metisDispatcher_StartTimer() + * @return <#return#> + */ +PARCEventTimer *metisDispatcher_CreateTimer(MetisDispatcher *dispatcher, bool isPeriodic, PARCEvent_Callback *callback, void *userData); + +/** + * @function metisDispatcher_StartTimer + * @abstract Starts the timer with the given delay. + * @discussion + * If the timer is periodic, it will keep firing with the given delay + * + * @param <#param1#> + * @return <#return#> + */ +void metisDispatcher_StartTimer(MetisDispatcher *dispatcher, PARCEventTimer *timerEvent, struct timeval *delay); + +void metisDispatcher_StopTimer(MetisDispatcher *dispatcher, PARCEventTimer *timerEvent); + +/** + * @function metisDispatcher_DestroyTimerEvent + * @abstract Cancels the timer and frees the event + * @discussion + * <#Discussion#> + * + * @param <#param1#> + * @return <#return#> + */ +void metisDispatcher_DestroyTimerEvent(MetisDispatcher *dispatcher, PARCEventTimer **eventPtr); + +/** + * @function metisDispatcher_CreateNetworkEvent + * @abstract Creates a network event callback on the socket + * @discussion + * May be used on any sort of file descriptor or socket. The event is edge triggered and non-reentrent. + * This means you need to drain the events off the socket, as the callback will not be called again + * until a new event arrives. + * + * When created, the event is idle and you need to call metisForwarder_StartNetworkEvent() + * + * @param isPersistent means the callback will keep firing with new events, otherwise its a one-shot + * @param fd is the socket to monitor + * @return <#return#> + */ +//MetisNetworkEvent *metisDispatcher_CreateNetworkEvent(MetisDispatcher *dispatcher, bool isPersistent, MetisEventCallback *callback, void *userData, MetisSocketType fd); +PARCEvent *metisDispatcher_CreateNetworkEvent(MetisDispatcher *dispatcher, bool isPersistent, PARCEvent_Callback *callback, void *userData, int fd); + +//void metisDispatcher_StartNetworkEvent(MetisDispatcher *dispatcher, MetisNetworkEvent *event); +//void metisDispatcher_StopNetworkEvent(MetisDispatcher *dispatcher, MetisNetworkEvent *event); +void metisDispatcher_StartNetworkEvent(MetisDispatcher *dispatcher, PARCEvent *event); +void metisDispatcher_StopNetworkEvent(MetisDispatcher *dispatcher, PARCEvent *event); + +//void metisDispatcher_DestroyNetworkEvent(MetisDispatcher *dispatcher, MetisNetworkEvent **eventPtr); +void metisDispatcher_DestroyNetworkEvent(MetisDispatcher *dispatcher, PARCEvent **eventPtr); + +/** + * @function metisDispatcher_CreateSignalEvent + * @abstract Creates a signal trap + * @discussion + * May be used on catchable signals. The event is edge triggered and non-reentrent. Signal events are persistent. + * + * When created, the signal trap is idle and you need to call metisForwarder_StartSignalEvent() + * + * @param signal is the system signal to monitor (e.g. SIGINT). + * @return <#return#> + */ +PARCEventSignal *metisDispatcher_CreateSignalEvent(MetisDispatcher *dispatcher, PARCEventSignal_Callback *callback, void *userData, int signal); + +void metisDispatcher_DestroySignalEvent(MetisDispatcher *dispatcher, PARCEventSignal **eventPtr); + +void metisDispatcher_StartSignalEvent(MetisDispatcher *dispatcher, PARCEventSignal *event); +void metisDispatcher_StopSignalEvent(MetisDispatcher *dispatcher, PARCEventSignal *event); + +// ============= +// stream buffers + +#include +#include + +/** + * @function metisDispatcher_CreateStreamBuffer + * @abstract Creates a high-function buffer around a stream socket + * @discussion + * <#Discussion#> + * + * @param <#param1#> + * @return <#return#> + */ +PARCEventQueue *metisDispatcher_CreateStreamBufferFromSocket(MetisDispatcher *dispatcher, MetisSocketType fd); + +/** + * @function metisDispatcher_StreamBufferConnect + * @abstract Create a TCP tunnel to a remote peer + * @discussion + * For TCP, both address pairs need to be the same address family: both INET or both INET6. The remote + * address must have the complete socket information (address, port). The local socket could be wildcarded or + * may specify down to the (address, port) pair. + * + * If the local address is IPADDR_ANY and the port is 0, then it is a normal call to "connect" that will use + * whatever local IP address and whatever local port for the connection. If either the address or port is + * set, the local socket will first be bound (via bind(2)), and then call connect(). + * + * It is unlikely that the buffer will be connected by the time the function returns. The eventCallback will + * fire once the remote system accepts the conneciton. + * + * @param <#param1#> + * @return NULL on error, otherwise a streambuffer. + */ +PARCEventQueue *metisDispatcher_StreamBufferConnect(MetisDispatcher *dispatcher, const MetisAddressPair *pair); +#endif // Metis_metis_Dispatcher_h -- cgit 1.2.3-korg