gator: Version 5.21.1
[firefly-linux-kernel-4.4.55.git] / tools / gator / daemon / OlySocket.cpp
index aa0ce4929916eb57d1637ff63acf5a07af87548b..078d2020922684f011a5f6cd66a888964b919fc7 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
 #include <unistd.h>
 #include <netdb.h>
 #include <fcntl.h>
+#include <stddef.h>
 #endif
 
 #include "Logging.h"
@@ -78,7 +79,7 @@ OlyServerSocket::OlyServerSocket(int port) {
 #ifdef WIN32
   WSADATA wsaData;
   if (WSAStartup(0x0202, &wsaData) != 0) {
-    logg->logError(__FILE__, __LINE__, "Windows socket initialization failed");
+    logg->logError("Windows socket initialization failed");
     handleException();
   }
 #endif
@@ -97,11 +98,11 @@ OlySocket::OlySocket(int socketID) : mSocketID(socketID) {
   __a > __b ? __b : __a; \
 })
 
-OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize) {
+OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize, const bool calculateAddrlen) {
   // Create socket
   mFDServer = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
   if (mFDServer < 0) {
-    logg->logError(__FILE__, __LINE__, "Error creating server socket");
+    logg->logError("Error creating server socket");
     handleException();
   }
 
@@ -113,19 +114,19 @@ OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize) {
   sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0';
 
   // Bind the socket to an address
-  if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
-    logg->logError(__FILE__, __LINE__, "Binding of server socket failed.");
+  if (bind(mFDServer, (const struct sockaddr*)&sockaddr, calculateAddrlen ? offsetof(struct sockaddr_un, sun_path) + pathSize - 1 : sizeof(sockaddr)) < 0) {
+    logg->logError("Binding of server socket failed.");
     handleException();
   }
 
   // Listen for connections on this socket
   if (listen(mFDServer, 1) < 0) {
-    logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
+    logg->logError("Listening of server socket failed");
     handleException();
   }
 }
 
-int OlySocket::connect(const char* path, const size_t pathSize) {
+int OlySocket::connect(const char* path, const size_t pathSize, const bool calculateAddrlen) {
   int fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
   if (fd < 0) {
     return -1;
@@ -138,7 +139,7 @@ int OlySocket::connect(const char* path, const size_t pathSize) {
   memcpy(sockaddr.sun_path, path, MIN(pathSize, sizeof(sockaddr.sun_path)));
   sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0';
 
-  if (::connect(fd, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
+  if (::connect(fd, (const struct sockaddr*)&sockaddr, calculateAddrlen ? offsetof(struct sockaddr_un, sun_path) + pathSize - 1 : sizeof(sockaddr)) < 0) {
     close(fd);
     return -1;
   }
@@ -174,11 +175,11 @@ void OlySocket::closeSocket() {
 }
 
 void OlyServerSocket::closeServerSocket() {
-  if (CLOSE_SOCKET(mFDServer) != 0) {
-    logg->logError(__FILE__, __LINE__, "Failed to close server socket.");
+  if (mFDServer > 0 && CLOSE_SOCKET(mFDServer) != 0) {
+    logg->logError("Failed to close server socket.");
     handleException();
   }
-  mFDServer = 0;
+  mFDServer = -1;
 }
 
 void OlyServerSocket::createServerSocket(int port) {
@@ -190,7 +191,7 @@ void OlyServerSocket::createServerSocket(int port) {
     family = AF_INET;
     mFDServer = socket_cloexec(PF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (mFDServer < 0) {
-      logg->logError(__FILE__, __LINE__, "Error creating server socket");
+      logg->logError("Error creating server socket");
       handleException();
     }
   }
@@ -198,10 +199,16 @@ void OlyServerSocket::createServerSocket(int port) {
   // Enable address reuse, another solution would be to create the server socket once and only close it when the object exits
   int on = 1;
   if (setsockopt(mFDServer, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
-    logg->logError(__FILE__, __LINE__, "Setting server socket options failed");
+    logg->logError("Setting server socket reuse option failed");
     handleException();
   }
 
+  // Listen on both IPv4 and IPv6
+  on = 0;
+  if (setsockopt(mFDServer, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) != 0) {
+    logg->logMessage("setsockopt IPV6_V6ONLY failed");
+  }
+
   // Create sockaddr_in structure, ensuring non-populated fields are zero
   struct sockaddr_in6 sockaddr;
   memset((void*)&sockaddr, 0, sizeof(sockaddr));
@@ -211,13 +218,13 @@ void OlyServerSocket::createServerSocket(int port) {
 
   // Bind the socket to an address
   if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
-    logg->logError(__FILE__, __LINE__, "Binding of server socket failed.\nIs an instance already running?");
+    logg->logError("Binding of server socket on port %i failed.\nIs an instance already running or is another application using that port?", port);
     handleException();
   }
 
   // Listen for connections on this socket
   if (listen(mFDServer, 1) < 0) {
-    logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
+    logg->logError("Listening of server socket failed");
     handleException();
   }
 }
@@ -227,14 +234,14 @@ void OlyServerSocket::createServerSocket(int port) {
 int OlyServerSocket::acceptConnection() {
   int socketID;
   if (mFDServer <= 0) {
-    logg->logError(__FILE__, __LINE__, "Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
+    logg->logError("Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
     handleException();
   }
 
   // Accept a connection, note that this call blocks until a client connects
   socketID = accept_cloexec(mFDServer, NULL, NULL);
   if (socketID < 0) {
-    logg->logError(__FILE__, __LINE__, "Socket acceptance failed");
+    logg->logError("Socket acceptance failed");
     handleException();
   }
   return socketID;
@@ -248,7 +255,7 @@ void OlySocket::send(const char* buffer, int size) {
   while (size > 0) {
     int n = ::send(mSocketID, buffer, size, 0);
     if (n < 0) {
-      logg->logError(__FILE__, __LINE__, "Socket send error");
+      logg->logError("Socket send error");
       handleException();
     }
     size -= n;
@@ -264,7 +271,7 @@ int OlySocket::receive(char* buffer, int size) {
 
   int bytes = recv(mSocketID, buffer, size, 0);
   if (bytes < 0) {
-    logg->logError(__FILE__, __LINE__, "Socket receive error");
+    logg->logError("Socket receive error");
     handleException();
   } else if (bytes == 0) {
     logg->logMessage("Socket disconnected");
@@ -279,7 +286,7 @@ int OlySocket::receiveNBytes(char* buffer, int size) {
   while (size > 0 && buffer != NULL) {
     bytes = recv(mSocketID, buffer, size, 0);
     if (bytes < 0) {
-      logg->logError(__FILE__, __LINE__, "Socket receive error");
+      logg->logError("Socket receive error");
       handleException();
     } else if (bytes == 0) {
       logg->logMessage("Socket disconnected");
@@ -304,7 +311,7 @@ int OlySocket::receiveString(char* buffer, int size) {
     // Receive a single character
     int bytes = recv(mSocketID, &buffer[bytes_received], 1, 0);
     if (bytes < 0) {
-      logg->logError(__FILE__, __LINE__, "Socket receive error");
+      logg->logError("Socket receive error");
       handleException();
     } else if (bytes == 0) {
       logg->logMessage("Socket disconnected");