From 658f4b67027025542fe494448838ff5e6277d455 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 25 Sep 2014 00:51:01 +0200 Subject: removing clients works now --- src/udp.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'src/udp.c') diff --git a/src/udp.c b/src/udp.c index 3c51511..c4da533 100644 --- a/src/udp.c +++ b/src/udp.c @@ -52,31 +52,46 @@ #define UDP_PROTO_CMD_RM_CLIENT "remove_client\n" #define UDP_PROTO_CMD_RM_CLIENT_LEN (sizeof(UDP_PROTO_CMD_RM_CLIENT)-1) - -static void udpsink_add_client(struct sockaddr_storage *addr, socklen_t addrlen, struct udp_sink* sink) +static struct udp_client* udp_client_new(struct sockaddr_storage *addr, socklen_t addrlen) { - struct addr_port* client = g_new(struct addr_port, 1); - if(!client) return; + struct udp_client* client = g_new(struct udp_client, 1); + if(!client) return NULL; switch(addr->ss_family) { - case AF_INET: client->type_ = IPv4; client->port_ = ntohs(((struct sockaddr_in*)addr)->sin_port); break; - case AF_INET6: client->type_ = IPv6; client->port_ = ntohs(((struct sockaddr_in6*)addr)->sin6_port); break; - default: return; + case AF_INET: client->host_.type_ = IPv4; client->host_.port_ = ntohs(((struct sockaddr_in*)addr)->sin_port); break; + case AF_INET6: client->host_.type_ = IPv6; client->host_.port_ = ntohs(((struct sockaddr_in6*)addr)->sin6_port); break; + default: g_free(client); return NULL; } - int errcode = getnameinfo((struct sockaddr *)addr, addrlen, client->addr_, sizeof(client->addr_), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); + int errcode = getnameinfo((struct sockaddr *)addr, addrlen, client->host_.addr_, sizeof(client->host_.addr_), + NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); if (errcode != 0) { log_printf(WARNING, "getnameinfo() error: %s", gai_strerror(errcode)); - return; + g_free(client); + return NULL; } + return client; +} + +static void udpsink_add_client(struct sockaddr_storage *addr, socklen_t addrlen, struct udp_sink* sink) +{ + struct udp_client* client = udp_client_new(addr, addrlen); + if(!client) return; + + GTimeVal now; + g_get_current_time(&now); + client->last_seen_ = GST_TIMEVAL_TO_TIME(now); + gchar* name = gst_element_get_name(sink->udp_); - if(!g_list_find_custom(sink->clients_, client, cmp_addr_port)) { - log_printf(INFO, "adding host %s%c%d to list of receivers for element %s", client->addr_, client->type_ == IPv4 ? ':' : '.', client->port_, name); - g_signal_emit_by_name(G_OBJECT(sink->udp_), "add", client->addr_, client->port_, NULL); + if(!g_list_find_custom(sink->clients_, client, cmp_udp_client)) { + log_printf(INFO, "adding host %s%c%d to list of receivers for element %s", + client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name); + g_signal_emit_by_name(G_OBJECT(sink->udp_), "add", client->host_.addr_, client->host_.port_, NULL); sink->clients_ = g_list_append(sink->clients_, client); } else { - log_printf(DEBUG, "not adding host %s%c%d to list of receivers for element %s - already added", client->addr_, client->type_ == IPv4 ? ':' : '.', client->port_, name); + log_printf(DEBUG, "not adding host %s%c%d to list of receivers for element %s since it already exists", + client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name); g_free(client); } g_free(name); @@ -84,10 +99,22 @@ static void udpsink_add_client(struct sockaddr_storage *addr, socklen_t addrlen, static void udpsink_remove_client(struct sockaddr_storage *addr, socklen_t addrlen, struct udp_sink* sink) { - // TODO: implement this! + struct udp_client* client = udp_client_new(addr, addrlen); + if(!client) return; + + GList* removee = g_list_find_custom(sink->clients_, client, cmp_udp_client); gchar* name = gst_element_get_name(sink->udp_); - log_printf(ERROR, "removing client from %s failed! - removing not yet implemented!", name); + if(!removee) { + log_printf(WARNING, "client %s%c%d not found in client list for %s - nothing removed", + client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name, name); + } else { + g_signal_emit_by_name(G_OBJECT(sink->udp_), "remove", client->host_.addr_, client->host_.port_, NULL); + log_printf(INFO, "client %s%c%d removed from list of receivers for element %s", + client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name, name); + sink->clients_ = g_list_remove(sink->clients_, removee->data); + } g_free(name); + g_free(client); } static gboolean on_udp_desc_ready(gint fd, GIOCondition cond, gpointer user_data) -- cgit v1.2.3