diff options
Diffstat (limited to 'src/udp_server.c')
-rw-r--r-- | src/udp_server.c | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/src/udp_server.c b/src/udp_server.c deleted file mode 100644 index f96b40b6b..000000000 --- a/src/udp_server.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "udp_server.h" -#include "io_thread.h" -#include "glib_socket.h" -#include "gcc.h" - -#include <glib.h> -#include <unistd.h> -#include <sys/time.h> -#include <errno.h> - -#ifdef WIN32 -#include <ws2tcpip.h> -#include <winsock.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -#endif - -#if GCC_CHECK_VERSION(4, 2) -/* allow C99 initialisers on struct sockaddr_in, even if the - (non-portable) attribute "sin_zero" is missing */ -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif - -struct udp_server { - const struct udp_server_handler *handler; - void *handler_ctx; - - int fd; - GIOChannel *channel; - GSource *source; - - char buffer[8192]; -}; - -static gboolean -udp_in_event(G_GNUC_UNUSED GIOChannel *source, - G_GNUC_UNUSED GIOCondition condition, - gpointer data) -{ - struct udp_server *udp = data; - - struct sockaddr_storage address_storage; - struct sockaddr *address = (struct sockaddr *)&address_storage; - socklen_t address_length = sizeof(address_storage); - - ssize_t nbytes = recvfrom(udp->fd, udp->buffer, sizeof(udp->buffer), -#ifdef WIN32 - 0, -#else - MSG_DONTWAIT, -#endif - address, &address_length); - if (nbytes <= 0) - return true; - - udp->handler->datagram(udp->fd, udp->buffer, nbytes, - address, address_length, udp->handler_ctx); - return true; -} - -struct udp_server * -udp_server_new(unsigned port, - const struct udp_server_handler *handler, void *ctx, - GError **error_r) -{ - int fd = socket(PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - g_set_error(error_r, udp_server_quark(), errno, - "failed to create UDP socket: %s", - g_strerror(errno)); - return NULL; - } - - const struct sockaddr_in address = { - .sin_family = AF_INET, - .sin_addr = { - .s_addr = htonl(INADDR_ANY), - }, - .sin_port = htons(port), -#if defined(__linux__) && !GCC_CHECK_VERSION(4, 2) - .sin_zero = { 0 }, -#endif - }; - - if (bind(fd, (const struct sockaddr *)&address, sizeof(address)) < 0) { - g_set_error(error_r, udp_server_quark(), errno, - "failed to bind UDP port %u: %s", - port, g_strerror(errno)); - close(fd); - return NULL; - } - - struct udp_server *udp = g_new(struct udp_server, 1); - udp->handler = handler; - udp->handler_ctx = ctx; - - udp->fd = fd; - udp->channel = g_io_channel_new_socket(fd); - /* NULL encoding means the stream is binary safe */ - g_io_channel_set_encoding(udp->channel, NULL, NULL); - /* no buffering */ - g_io_channel_set_buffered(udp->channel, false); - - udp->source = g_io_create_watch(udp->channel, G_IO_IN); - g_source_set_callback(udp->source, (GSourceFunc)udp_in_event, udp, - NULL); - g_source_attach(udp->source, io_thread_context()); - - return udp; -} - -void -udp_server_free(struct udp_server *udp) -{ - g_source_destroy(udp->source); - g_source_unref(udp->source); - g_io_channel_unref(udp->channel); - close(udp->fd); - g_free(udp); -} |