Quellcode durchsuchen

system: add BIPC, BIPCServer

ambrop7 vor 15 Jahren
Ursprung
Commit
bbcd58c8a7
5 geänderte Dateien mit 432 neuen und 0 gelöschten Zeilen
  1. 152 0
      system/BIPC.c
  2. 114 0
      system/BIPC.h
  3. 85 0
      system/BIPCServer.c
  4. 79 0
      system/BIPCServer.h
  5. 2 0
      system/CMakeLists.txt

+ 152 - 0
system/BIPC.c

@@ -0,0 +1,152 @@
+/**
+ * @file BIPC.c
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <system/BIPC.h>
+
+#define COMPONENT_SOURCE 1
+#define COMPONENT_SINK 2
+
+static void error_handler (BIPC *o, int component, const void *data)
+{
+    ASSERT(component == COMPONENT_SOURCE || component == COMPONENT_SINK)
+    DebugObject_Access(&o->d_obj);
+    
+    #ifndef NDEBUG
+    DEAD_ENTER(o->dead)
+    #endif
+    
+    o->handler(o->user);
+    
+    #ifndef NDEBUG
+    ASSERT(DEAD_KILLED)
+    DEAD_LEAVE(o->dead);
+    #endif
+}
+
+int BIPC_InitConnect (BIPC *o, const char *path, int send_mtu, int recv_mtu, BIPC_handler handler, void *user, BReactor *reactor)
+{
+    ASSERT(send_mtu >= 0)
+    ASSERT(recv_mtu >= 0)
+    
+    // init arguments
+    o->handler = handler;
+    o->user = user;
+    
+    // init dead var
+    DEAD_INIT(o->dead);
+    
+    // init socket
+    if (BSocket_Init(&o->sock, reactor, BADDR_TYPE_UNIX, BSOCKET_TYPE_SEQPACKET) < 0) {
+        DEBUG("BSocket_Init failed");
+        goto fail0;
+    }
+    
+    // connect socket
+    if (BSocket_ConnectUnix(&o->sock, path) < 0) {
+        DEBUG("BSocket_ConnectUnix failed (%d)", BSocket_GetError(&o->sock));
+        goto fail1;
+    }
+    
+    // init error domain
+    FlowErrorDomain_Init(&o->domain, (FlowErrorDomain_handler)error_handler, o);
+    
+    // init sink
+    SeqPacketSocketSink_Init(&o->sink, FlowErrorReporter_Create(&o->domain, COMPONENT_SINK), &o->sock, send_mtu);
+    
+    // init source
+    SeqPacketSocketSource_Init(&o->source, FlowErrorReporter_Create(&o->domain, COMPONENT_SOURCE), &o->sock, recv_mtu);
+    
+    DebugObject_Init(&o->d_obj);
+    
+    return 1;
+    
+fail1:
+    BSocket_Free(&o->sock);
+fail0:
+    return 0;
+}
+
+int BIPC_InitAccept (BIPC *o, BIPCServer *server, int send_mtu, int recv_mtu, BIPC_handler handler, void *user)
+{
+    ASSERT(send_mtu >= 0)
+    ASSERT(recv_mtu >= 0)
+    
+    // init arguments
+    o->handler = handler;
+    o->user = user;
+    
+    // init dead var
+    DEAD_INIT(o->dead);
+    
+    // accept socket
+    if (Listener_Accept(&server->listener, &o->sock, NULL) < 0) {
+        DEBUG("Listener_Accept failed");
+        goto fail0;
+    }
+    
+    // init error domain
+    FlowErrorDomain_Init(&o->domain, (FlowErrorDomain_handler)error_handler, o);
+    
+    // init sink
+    SeqPacketSocketSink_Init(&o->sink, FlowErrorReporter_Create(&o->domain, COMPONENT_SINK), &o->sock, send_mtu);
+    
+    // init source
+    SeqPacketSocketSource_Init(&o->source, FlowErrorReporter_Create(&o->domain, COMPONENT_SOURCE), &o->sock, recv_mtu);
+    
+    DebugObject_Init(&o->d_obj);
+    
+    return 1;
+    
+fail0:
+    return 0;
+}
+
+void BIPC_Free (BIPC *o)
+{
+    DebugObject_Free(&o->d_obj);
+    
+    // free source
+    SeqPacketSocketSource_Free(&o->source);
+    
+    // free sink
+    SeqPacketSocketSink_Free(&o->sink);
+    
+    // free socket
+    BSocket_Free(&o->sock);
+    
+    // free dead var
+    DEAD_KILL(o->dead);
+}
+
+PacketPassInterface * BIPC_GetSendInterface (BIPC *o)
+{
+    DebugObject_Access(&o->d_obj);
+    
+    return SeqPacketSocketSink_GetInput(&o->sink);
+}
+
+PacketRecvInterface * BIPC_GetRecvInterface (BIPC *o)
+{
+    DebugObject_Access(&o->d_obj);
+    
+    return SeqPacketSocketSource_GetOutput(&o->source);
+}

+ 114 - 0
system/BIPC.h

@@ -0,0 +1,114 @@
+/**
+ * @file BIPC.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * @section DESCRIPTION
+ * 
+ * An abstraction of a reliable, sequenced, message-oriented two-way IPC.
+ * Uses unix sockets on *nix systems, and named pipes on Windows.
+ */
+
+#ifndef BADVPN_SYSTEM_BIPC_H
+#define BADVPN_SYSTEM_BIPC_H
+
+#include <misc/debug.h>
+#include <misc/dead.h>
+#include <system/BSocket.h>
+#include <system/DebugObject.h>
+#include <system/BIPCServer.h>
+#include <flow/SeqPacketSocketSink.h>
+#include <flow/SeqPacketSocketSource.h>
+
+/**
+ * Handler function called when an error occurs.
+ * The object must be freed from within this handler.
+ * 
+ * @param user as in {@link BIPC_InitConnect}
+ */
+typedef void (*BIPC_handler) (void *user);
+
+/**
+ * An abstraction of a reliable, sequenced, message-oriented two-way IPC.
+ */
+typedef struct {
+    dead_t dead;
+    BSocket sock;
+    FlowErrorDomain domain;
+    SeqPacketSocketSink sink;
+    SeqPacketSocketSource source;
+    BIPC_handler handler;
+    void *user;
+    DebugObject d_obj;
+} BIPC;
+
+/**
+ * Initializes the object by connecting to an IPC server.
+ * 
+ * @param o the object
+ * @param path path of the IPC object. On *nix path of the unix socket, on Windows
+ *             path of the named pipe.
+ * @param send_mtu maximum packet size for sending. Must be >=0.
+ * @param recv_mtu maximum packet size for receiving. Must be >=0.
+ * @param handler handler function called when an error occurs
+ * @param user value to pass to handler function
+ * @param reactor reactor we live in
+ * @return 1 on success, 0 on failure
+ */
+int BIPC_InitConnect (BIPC *o, const char *path, int send_mtu, int recv_mtu, BIPC_handler handler, void *user, BReactor *reactor) WARN_UNUSED;
+
+/**
+ * Initializes the object by acception a connection on an IPC server.
+ * 
+ * @param o the object
+ * @param server IPC server to accept a connection on
+ * @param send_mtu maximum packet size for sending. Must be >=0.
+ * @param recv_mtu maximum packet size for receiving. Must be >=0.
+ * @param handler handler function called when an error occurs
+ * @param user value to pass to handler function
+ * @return 1 on success, 0 on failure
+ */
+int BIPC_InitAccept (BIPC *o, BIPCServer *server, int send_mtu, int recv_mtu, BIPC_handler handler, void *user) WARN_UNUSED;
+
+/**
+ * Frees the object.
+ * 
+ * @param o the object
+ */
+void BIPC_Free (BIPC *o);
+
+/**
+ * Returns the interface for sending.
+ * The MTU of the interface will be as send_mtu in {@link BIPC_InitConnect}.
+ * 
+ * @param o the object
+ * @return interface for sending
+ */
+PacketPassInterface * BIPC_GetSendInterface (BIPC *o);
+
+/**
+ * Returns the interface for receiving.
+ * The MTU of the interface will be as recv_mtu in {@link BIPC_InitConnect}.
+ * 
+ * @param o the object
+ * @return interface for receiving
+ */
+PacketRecvInterface * BIPC_GetRecvInterface (BIPC *o);
+
+#endif

+ 85 - 0
system/BIPCServer.c

@@ -0,0 +1,85 @@
+/**
+ * @file BIPCServer.c
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <system/BIPCServer.h>
+
+static void listener_handler (BIPCServer *o)
+{
+    DebugObject_Access(&o->d_obj);
+    
+    o->handler(o->user);
+    return;
+}
+
+int BIPCServer_Init (BIPCServer *o, const char *path, BIPCServer_handler handler, void *user, BReactor *reactor)
+{
+    // init arguments
+    o->handler = handler;
+    o->user = user;
+    
+    // init dead var
+    DEAD_INIT(o->dead);
+    
+    // init socket
+    if (BSocket_Init(&o->sock, reactor, BADDR_TYPE_UNIX, BSOCKET_TYPE_SEQPACKET) < 0) {
+        DEBUG("BSocket_Init failed");
+        goto fail0;
+    }
+    
+    // bind socket
+    if (BSocket_BindUnix(&o->sock, path) < 0) {
+        DEBUG("BSocket_BindUnix failed (%d)", BSocket_GetError(&o->sock));
+        goto fail1;
+    }
+    
+    // listen socket
+    if (BSocket_Listen(&o->sock, -1) < 0) {
+        DEBUG("BSocket_Listen failed (%d)", BSocket_GetError(&o->sock));
+        goto fail1;
+    }
+    
+    // init listener
+    Listener_InitExisting(&o->listener, reactor, &o->sock, (Listener_handler)listener_handler, o);
+    
+    DebugObject_Init(&o->d_obj);
+    
+    return 1;
+    
+fail1:
+    BSocket_Free(&o->sock);
+fail0:
+    return 0;
+}
+
+void BIPCServer_Free (BIPCServer *o)
+{
+    DebugObject_Free(&o->d_obj);
+    
+    // free listener
+    Listener_Free(&o->listener);
+    
+    // free socket
+    BSocket_Free(&o->sock);
+    
+    // free dead var
+    DEAD_KILL(o->dead);
+}

+ 79 - 0
system/BIPCServer.h

@@ -0,0 +1,79 @@
+/**
+ * @file BIPCServer.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * @section DESCRIPTION
+ * 
+ * Server part of {@link BIPC}, an abstraction of a reliable, sequenced,
+ * message-oriented two-way IPC.
+ */
+
+#ifndef BADVPN_SYSTEM_BIPCSERVER_H
+#define BADVPN_SYSTEM_BIPCSERVER_H
+
+#include <misc/debug.h>
+#include <misc/dead.h>
+#include <system/BSocket.h>
+#include <system/Listener.h>
+#include <system/DebugObject.h>
+
+/**
+ * Handler function called when a client may be accepted
+ * (using {@link BIPC_InitAccept}).
+ * 
+ * @param user as in {@link BIPCServer_Init}
+ */
+typedef void (*BIPCServer_handler) (void *user);
+
+/**
+ * Server part of {@link BIPC}, an abstraction of a reliable, sequenced,
+ * message-oriented two-way IPC.
+ */
+typedef struct {
+    dead_t dead;
+    BSocket sock;
+    Listener listener;
+    BIPCServer_handler handler;
+    void *user;
+    DebugObject d_obj;
+} BIPCServer;
+
+/**
+ * Initializes the object.
+ * 
+ * @param o the object
+ * @param path path of the IPC object. On *nix path of the unix socket, on Windows
+ *             path of the named pipe.
+ * @param handler handler function called when a client may be accepted
+ *                (using {@link BIPC_InitAccept})
+ * @param user value to pass to handler function
+ * @param reactor reactor we live in
+ * @return 1 on success, 0 on failure
+ */
+int BIPCServer_Init (BIPCServer *o, const char *path, BIPCServer_handler handler, void *user, BReactor *reactor) WARN_UNUSED;
+
+/**
+ * Frees the object.
+ * 
+ * @param o the object
+ */
+void BIPCServer_Free (BIPCServer *o);
+
+#endif

+ 2 - 0
system/CMakeLists.txt

@@ -7,6 +7,8 @@ set(BSYSTEM_ADDITIONAL_SOURCES)
 if (NOT WIN32)
 if (NOT WIN32)
     list(APPEND BSYSTEM_ADDITIONAL_SOURCES
     list(APPEND BSYSTEM_ADDITIONAL_SOURCES
         BLog_syslog.c
         BLog_syslog.c
+        BIPC.c
+        BIPCServer.c
     )
     )
 endif ()
 endif ()