summaryrefslogtreecommitdiff
path: root/src/3rd_party-static/message_broker/src/server/networking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rd_party-static/message_broker/src/server/networking.cpp')
-rw-r--r--src/3rd_party-static/message_broker/src/server/networking.cpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/3rd_party-static/message_broker/src/server/networking.cpp b/src/3rd_party-static/message_broker/src/server/networking.cpp
new file mode 100644
index 0000000000..f054431690
--- /dev/null
+++ b/src/3rd_party-static/message_broker/src/server/networking.cpp
@@ -0,0 +1,189 @@
+/*
+ * JsonRpc-Cpp - JSON-RPC implementation.
+ * Copyright (C) 2008-2011 Sebastien Vincent <sebastien.vincent@cppextrem.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file networking.cpp
+ * \brief Networking utils.
+ * \author Sebastien Vincent
+ */
+
+#include <cstdio>
+#include <cstring>
+
+#include "networking.h"
+
+namespace networking {
+#ifdef _WIN32
+/**
+ * \var wsaData
+ * \brief MS Windows object to start
+ * networking stuff.
+ */
+static WSAData wsaData;
+#endif
+
+bool init() {
+ bool ret = false;
+
+#ifdef _WIN32
+ ret = (WSAStartup(MAKEWORD(2, 0), &wsaData) == 0);
+#else
+ /* unix-like */
+ ret = true;
+#endif
+
+ return ret;
+}
+
+void cleanup() {
+#ifdef _WIN32
+ WSACleanup();
+#endif
+}
+
+int connect(enum TransportProtocol protocol,
+ const std::string& address,
+ uint16_t port, struct sockaddr_storage* sockaddr,
+ socklen_t* addrlen) {
+ struct addrinfo hints;
+ struct addrinfo* res = NULL;
+ struct addrinfo* p = NULL;
+ char service[8];
+ int sock = -1;
+
+ if (!port || address == "") {
+ return -1;
+ }
+
+ snprintf(service, sizeof(service), "%u", port);
+ service[sizeof(service) - 1] = 0x00;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = protocol == UDP ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_protocol = protocol;
+ hints.ai_flags = 0;
+
+ if (getaddrinfo(address.c_str(),
+ service, &hints, &res) != 0) {
+ return -1;
+ }
+
+ for (p = res ; p ; p = p->ai_next) {
+ sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+
+ if (sock == -1) {
+ continue;
+ }
+
+ if (protocol == TCP && ::connect(sock, (struct sockaddr*)p->ai_addr, p->ai_addrlen) == -1) {
+ ::close(sock);
+ sock = -1;
+ continue;
+ }
+
+ if (sockaddr) {
+ memcpy(sockaddr, p->ai_addr, p->ai_addrlen);
+ }
+
+ if (addrlen) {
+ *addrlen = p->ai_addrlen;
+ }
+
+ /* ok so now we have a socket bound, break the loop */
+ break;
+ }
+
+ freeaddrinfo(res);
+ p = NULL;
+
+ return sock;
+}
+
+int bind(enum TransportProtocol protocol,
+ const std::string& address, uint16_t port,
+ struct sockaddr_storage* sockaddr, socklen_t* addrlen) {
+ struct addrinfo hints;
+ struct addrinfo* res = NULL;
+ struct addrinfo* p = NULL;
+ char service[8];
+ int sock = -1;
+
+ if (!port || address == "") {
+ return -1;
+ }
+
+ snprintf(service, sizeof(service), "%u", port);
+ service[sizeof(service) - 1] = 0x00;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = protocol == UDP ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_protocol = protocol;
+ hints.ai_flags = AI_PASSIVE;
+
+ if (getaddrinfo(address.c_str(), service, &hints, &res) != 0) {
+ return -1;
+ }
+
+ for (p = res ; p ; p = p->ai_next) {
+ int on = 1;
+ on = on;
+
+ sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+
+ if (sock == -1) {
+ continue;
+ }
+
+#ifndef _WIN32
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
+
+ /* accept IPv6 OR IPv4 on the same socket */
+ on = 1;
+ setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+#else
+ on = 0;
+#endif
+
+ if (::bind(sock, p->ai_addr, p->ai_addrlen) == -1) {
+ ::close(sock);
+ sock = -1;
+ continue;
+ }
+
+ if (sockaddr) {
+ memcpy(sockaddr, p->ai_addr, p->ai_addrlen);
+ }
+
+ if (addrlen) {
+ *addrlen = p->ai_addrlen;
+ }
+
+ /* ok so now we have a socket bound, break the loop */
+ break;
+ }
+
+ freeaddrinfo(res);
+ p = NULL;
+
+ return sock;
+}
+
+} /* namespace networking */
+