Code

memcache plugin: Make connecting via UNIX socket possible.
[collectd.git] / src / memcached.c
index b5a4b208365b8fba6d99453387f8c10d492ae916..bef97001a41c5d6ca4ee6cf1362e5f06dce0150f 100644 (file)
@@ -31,6 +31,7 @@
 # include <poll.h>
 # include <netdb.h>
 # include <sys/socket.h>
+# include <sys/un.h>
 # include <netinet/in.h>
 # include <netinet/tcp.h>
 
 
 static const char *config_keys[] =
 {
+       "Socket",
        "Host",
        "Port"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
+static char *memcached_socket = NULL;
 static char *memcached_host = NULL;
 static char memcached_port[16];
 
@@ -54,66 +57,92 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */
        int fd;
        ssize_t status;
        int buffer_fill;
-
-       const char *host;
-       const char *port;
-
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list, *ai_ptr;
-       int              ai_return, i = 0;
-
-       memset (&ai_hints, '\0', sizeof (ai_hints));
-       ai_hints.ai_flags    = 0;
+    int i = 0;
+
+    if (memcached_socket != NULL) {
+        
+        struct sockaddr_un serv_addr;
+
+        memset(&serv_addr, '\0', sizeof (serv_addr));
+        serv_addr.sun_family = AF_UNIX;
+        strncpy(serv_addr.sun_path, memcached_socket, sizeof (serv_addr.sun_path));
+
+        /* create our socket descriptor */
+        if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
+            char errbuf[1024];
+            ERROR ("memcached: unix socket: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
+            return -1;
+        }
+
+        /* connect to the memcached daemon */
+        if (connect (fd, (struct sockaddr *) &serv_addr, SUN_LEN(&serv_addr))) {
+            shutdown(fd, SHUT_RDWR);
+            close(fd);
+            fd = -1;
+        }
+
+    } else {   
+
+        const char *host;
+        const char *port;
+        
+        struct addrinfo  ai_hints;
+        struct addrinfo *ai_list, *ai_ptr;
+        int              ai_return = 0;
+        
+        memset (&ai_hints, '\0', sizeof (ai_hints));
+        ai_hints.ai_flags    = 0;
 #ifdef AI_ADDRCONFIG
-/*     ai_hints.ai_flags   |= AI_ADDRCONFIG; */
+        /*     ai_hints.ai_flags   |= AI_ADDRCONFIG; */
 #endif
-       ai_hints.ai_family   = AF_INET;
-       ai_hints.ai_socktype = SOCK_STREAM;
-       ai_hints.ai_protocol = 0;
-
-       host = memcached_host;
-       if (host == NULL) {
-               host = MEMCACHED_DEF_HOST;
-       }
-
-       port = memcached_port;
-       if (strlen (port) == 0) {
-               port = MEMCACHED_DEF_PORT;
-       }
-
-       if ((ai_return = getaddrinfo (host, port, NULL, &ai_list)) != 0) {
-               char errbuf[1024];
-               ERROR ("memcached: getaddrinfo (%s, %s): %s",
-                               host, port,
-                               (ai_return == EAI_SYSTEM)
-                               ? sstrerror (errno, errbuf, sizeof (errbuf))
-                               : gai_strerror (ai_return));
-               return -1;
-       }
-
-       fd = -1;
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
-               /* create our socket descriptor */
-               if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) {
-                       char errbuf[1024];
-                       ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
-                       continue;
-               }
-
-               /* connect to the memcached daemon */
-               if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) {
-                       shutdown(fd, SHUT_RDWR);
-                       close(fd);
-                       fd = -1;
-                       continue;
-               }
-
-               /* A socket could be opened and connecting succeeded. We're
-                * done. */
-               break;
-       }
-
-       freeaddrinfo (ai_list);
+        ai_hints.ai_family   = AF_INET;
+        ai_hints.ai_socktype = SOCK_STREAM;
+        ai_hints.ai_protocol = 0;
+        
+        host = memcached_host;
+        if (host == NULL) {
+            host = MEMCACHED_DEF_HOST;
+        }
+        
+        port = memcached_port;
+        if (strlen (port) == 0) {
+            port = MEMCACHED_DEF_PORT;
+        }
+        
+        if ((ai_return = getaddrinfo (host, port, NULL, &ai_list)) != 0) {
+            char errbuf[1024];
+            ERROR ("memcached: getaddrinfo (%s, %s): %s",
+                   host, port,
+                   (ai_return == EAI_SYSTEM)
+                   ? sstrerror (errno, errbuf, sizeof (errbuf))
+                   : gai_strerror (ai_return));
+            return -1;
+        }
+        
+        fd = -1;
+        for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
+            /* create our socket descriptor */
+            if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) {
+                char errbuf[1024];
+                ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
+                continue;
+            }
+            
+            /* connect to the memcached daemon */
+            if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) {
+                shutdown(fd, SHUT_RDWR);
+                close(fd);
+                fd = -1;
+                continue;
+            }
+            
+            /* A socket could be opened and connecting succeeded. We're
+             * done. */
+            break;
+        }
+        
+        freeaddrinfo (ai_list);
+    }
 
        if (fd < 0) {
                ERROR ("memcached: Could not connect to daemon.");
@@ -204,7 +233,12 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */
 
 static int memcached_config (const char *key, const char *value) /* {{{ */
 {
-       if (strcasecmp (key, "Host") == 0) {
+    if (strcasecmp (key, "Socket") == 0) {
+        if (memcached_socket != NULL) {
+            free (memcached_socket);
+        }
+        memcached_socket = strdup (value);
+    } else if (strcasecmp (key, "Host") == 0) {
                if (memcached_host != NULL) {
                        free (memcached_host);
                }