SLP Server
This contains the entry point for the SLP
and starts the SLP Server.
Change-Id: I5976c8168a1af2703143c9bead61583197949115
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/slp_server.cpp b/slp_server.cpp
new file mode 100644
index 0000000..e307dab
--- /dev/null
+++ b/slp_server.cpp
@@ -0,0 +1,110 @@
+#include "slp_server.hpp"
+
+#include <memory>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "sock_channel.hpp"
+
+/** General udp server which waits for the POLLIN event
+ on the port and calls the call back once it gets the event.
+ usage would be create the server with the port and the call back
+ and call the run method.
+ */
+int slp::udp::Server::run()
+{
+ struct sockaddr_in in {};
+
+ sd_event* event = nullptr;
+
+ slp::deleted_unique_ptr<sd_event> eventPtr(event, [](sd_event * event)
+ {
+ if (!event)
+ {
+ event = sd_event_unref(event);
+ }
+ });
+
+ int fd = -1, r;
+ sigset_t ss;
+
+ r = sd_event_default(&event);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ eventPtr.reset(event);
+ event = nullptr;
+
+ if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 ||
+ sigaddset(&ss, SIGINT) < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+ /* Block SIGTERM first, so that the event loop can handle it */
+ if (sigprocmask(SIG_BLOCK, &ss, NULL) < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ /* Let's make use of the default handler and "floating"
+ reference features of sd_event_add_signal() */
+
+ r = sd_event_add_signal(eventPtr.get(), NULL, SIGTERM, NULL, NULL);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ r = sd_event_add_signal(eventPtr.get(), NULL, SIGINT, NULL, NULL);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (fd < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ in.sin_family = AF_INET;
+ in.sin_port = htons(this->port);
+ in.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(fd, (struct sockaddr*)&in, sizeof(in)) < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ r = sd_event_add_io(eventPtr.get(), nullptr, fd, EPOLLIN, this->callme,
+ nullptr);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ r = sd_event_loop(eventPtr.get());
+
+finish:
+
+ if (fd >= 0)
+ {
+ (void) close(fd);
+ }
+
+ if (r < 0)
+ {
+ fprintf(stderr, "Failure: %s\n", strerror(-r));
+ }
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}