From a80a585b8a5653557dce1e810ed604e2c60d4919 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Thu, 18 Oct 2012 01:03:20 +0000 Subject: [PATCH] Partially synchronized with the TCP transport --- src/transport/udp.c | 64 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/src/transport/udp.c b/src/transport/udp.c index 19f15c5..088072d 100644 --- a/src/transport/udp.c +++ b/src/transport/udp.c @@ -16,8 +16,11 @@ #include +#include #include +#include #include +#include #include #include #include @@ -65,8 +68,10 @@ AppTransportPluginDefinition definition = /* functions */ /* plug-in */ /* udp_init */ +static int _init_address(char const * name, struct sockaddr_in * sa); static int _init_client(UDP * udp, char const * name); static int _init_server(UDP * udp, char const * name); +static int _init_socket(UDP * udp); static UDP * _udp_init(AppTransportPluginHelper * helper, AppTransportMode mode, char const * name) @@ -96,31 +101,82 @@ static UDP * _udp_init(AppTransportPluginHelper * helper, return udp; } +static int _init_address(char const * name, struct sockaddr_in * sa) +{ + long l; + char const * p; + char * q; + + /* obtain the port number */ + if((p = strrchr(name, ':')) == NULL) + return -error_set_code(1, "%s", strerror(EINVAL)); + l = strtol(++p, &q, 10); + if(p[0] == '\0' || *q != '\0' || l < 0 || l > 65535) + return -error_set_code(1, "%s", strerror(EINVAL)); + sa->sin_family = AF_INET; + sa->sin_port = htons(l); + /* FIXME hard-coded */ + sa->sin_addr.s_addr = htons(INADDR_LOOPBACK); + return 0; +} + static int _init_client(UDP * udp, char const * name) { - if((udp->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return -_udp_error("socket", 1); + struct sockaddr_in sa; + + /* obtain the remote address */ + if(_init_address(name, &sa) != 0) + return -1; + /* create the socket */ + if(_init_socket(udp) != 0) + return -1; /* FIXME really implement */ return -1; } static int _init_server(UDP * udp, char const * name) { - if((udp->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return -_udp_error("socket", 1); + struct sockaddr_in sa; + + /* obtain the local address */ + if(_init_address(name, &sa) != 0) + return -1; + /* create the socket */ + if(_init_socket(udp) != 0) + return -1; + /* listen for incoming messages */ /* FIXME really implement */ return -1; } +static int _init_socket(UDP * udp) +{ + int flags; + + if((udp->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return -_udp_error("socket", 1); + /* set the socket as non-blocking */ + if((flags = fcntl(udp->fd, F_GETFL)) == -1) + return -_udp_error("fcntl", 1); + if((flags & O_NONBLOCK) == 0) + if(fcntl(udp->fd, F_SETFL, flags | O_NONBLOCK) == -1) + return -_udp_error("fcntl", 1); + return 0; +} + /* udp_destroy */ static void _udp_destroy(UDP * udp) { /* FIXME really implement */ + if(udp->fd >= 0) + close(udp->fd); object_delete(udp); } + /* useful */ +/* udp_error */ static int _udp_error(char const * message, int code) { return error_set_code(code, "%s%s%s", (message != NULL) ? message : "",