stream: add support for TCP stream services
authorMartin Willi <martin@revosec.ch>
Thu, 27 Jun 2013 15:25:51 +0000 (17:25 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Jul 2013 14:00:28 +0000 (16:00 +0200)
src/libstrongswan/networking/streams/stream_manager.c
src/libstrongswan/networking/streams/stream_service.c
src/libstrongswan/networking/streams/stream_service.h

index 0141e1d..db38977 100644 (file)
@@ -250,6 +250,7 @@ METHOD(stream_manager_t, destroy, void,
        remove_stream(this, stream_create_unix);
        remove_stream(this, stream_create_tcp);
        remove_service(this, stream_service_create_unix);
+       remove_service(this, stream_service_create_tcp);
 
        this->streams->destroy(this->streams);
        this->services->destroy(this->services);
@@ -285,6 +286,7 @@ stream_manager_t *stream_manager_create()
        add_stream(this, "unix://", stream_create_unix);
        add_stream(this, "tcp://", stream_create_tcp);
        add_service(this, "unix://", stream_service_create_unix);
+       add_service(this, "tcp://", stream_service_create_tcp);
 
        return &this->public;
 }
index 609ff3c..ab7a7e3 100644 (file)
@@ -205,3 +205,46 @@ stream_service_t *stream_service_create_unix(char *uri)
        }
        return stream_service_create_from_fd(fd);
 }
+
+/**
+ * See header
+ */
+stream_service_t *stream_service_create_tcp(char *uri)
+{
+       union {
+               struct sockaddr_in in;
+               struct sockaddr_in6 in6;
+               struct sockaddr sa;
+       } addr;
+       int fd, len, on = 1;
+
+       len = stream_parse_uri_tcp(uri, &addr.sa);
+       if (len == -1)
+       {
+               DBG1(DBG_NET, "invalid stream URI: '%s'", uri);
+               return NULL;
+       }
+       fd = socket(addr.sa.sa_family, SOCK_STREAM, 0);
+       if (fd < 0)
+       {
+               DBG1(DBG_NET, "opening socket '%s' failed: %s", uri, strerror(errno));
+               return NULL;
+       }
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0)
+       {
+               DBG1(DBG_NET, "SO_REUSADDR on '%s' failed: %s", uri, strerror(errno));
+       }
+       if (bind(fd, &addr.sa, len) < 0)
+       {
+               DBG1(DBG_NET, "binding socket '%s' failed: %s", uri, strerror(errno));
+               close(fd);
+               return NULL;
+       }
+       if (listen(fd, 5) < 0)
+       {
+               DBG1(DBG_NET, "listen on socket '%s' failed: %s", uri, strerror(errno));
+               close(fd);
+               return NULL;
+       }
+       return stream_service_create_from_fd(fd);
+}
index f864a7a..f1dc643 100644 (file)
@@ -83,4 +83,12 @@ stream_service_t *stream_service_create_from_fd(int fd);
  */
 stream_service_t *stream_service_create_unix(char *uri);
 
+/**
+ * Create a service instance for TCP sockets.
+ *
+ * @param uri          TCP socket specific URI, must start with "tcp://"
+ * @return                     stream_service instance, NULL on failure
+ */
+stream_service_t *stream_service_create_tcp(char *uri);
+
 #endif /** STREAM_SERVICE_H_ @}*/