]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
UDP: rearrange udp_connect/udp_sendinit
authorJaroslav Kysela <perex@perex.cz>
Tue, 3 Mar 2015 15:01:01 +0000 (16:01 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 11 Mar 2015 20:41:12 +0000 (21:41 +0100)
src/udp.c
src/udp.h

index ff5ef23241899487f0c242619f8265af3120b5de..b0504f8c41ac01a27da06010200db377a3113b2a 100644 (file)
--- a/src/udp.c
+++ b/src/udp.c
 extern int tcp_preferred_address_family;
 
 static int
-udp_resolve( udp_connection_t *uc, int receiver )
+udp_resolve( udp_connection_t *uc,
+             struct sockaddr_storage *ss,
+             const char *host,
+             int port, int *multicast,
+             int receiver )
 {
   struct addrinfo hints, *res, *ressave, *use = NULL;
   char port_buf[6];
   int x;
 
-  snprintf(port_buf, 6, "%d", uc->port);
+  snprintf(port_buf, 6, "%d", port);
 
   memset(&hints, 0, sizeof(struct addrinfo));
   hints.ai_flags = (receiver ? AI_PASSIVE : 0) | AI_NUMERICSERV;
   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_DGRAM;
   
-  x = getaddrinfo(uc->host, port_buf, &hints, &res);
+  x = getaddrinfo(host, port_buf, &hints, &res);
   if (x < 0) {
     tvhlog(LOG_ERR, uc->subsystem, "getaddrinfo: %s: %s",
-           uc->host != NULL ? uc->host : "*",
+           host != NULL ? host : "*",
            x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x));
     return -1;
   }
@@ -71,19 +75,19 @@ udp_resolve( udp_connection_t *uc, int receiver )
     res = res->ai_next;
   }
   if (use->ai_family == AF_INET6) {
-    uc->ip.ss_family        = AF_INET6;
-    IP_AS_V6(uc->ip, port)  = htons(uc->port);
-    memcpy(&IP_AS_V6(uc->ip, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr,
+    ss->ss_family        = AF_INET6;
+    IP_AS_V6(*ss, port)  = htons(port);
+    memcpy(&IP_AS_V6(*ss, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr,
                                                              sizeof(struct in6_addr));
-    uc->multicast           = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(uc->ip, addr));
+    *multicast           = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(*ss, addr));
   } else if (use->ai_family == AF_INET) {
-    uc->ip.ss_family        = AF_INET;
-    IP_AS_V4(uc->ip, port)  = htons(uc->port);
-    IP_AS_V4(uc->ip, addr)  = ((struct sockaddr_in *)use->ai_addr)->sin_addr;
-    uc->multicast           = !!IN_MULTICAST(ntohl(IP_AS_V4(uc->ip, addr.s_addr)));
+    ss->ss_family        = AF_INET;
+    IP_AS_V4(*ss, port)  = htons(port);
+    IP_AS_V4(*ss, addr)  = ((struct sockaddr_in *)use->ai_addr)->sin_addr;
+    *multicast           = !!IN_MULTICAST(ntohl(IP_AS_V4(*ss, addr.s_addr)));
   }
   freeaddrinfo(ressave);
-  if (uc->ip.ss_family != AF_INET && uc->ip.ss_family != AF_INET6) {
+  if (ss->ss_family != AF_INET && ss->ss_family != AF_INET6) {
     tvherror(uc->subsystem, "%s - failed to process host '%s'", uc->name, uc->host);
     return -1;
   }
@@ -167,7 +171,7 @@ udp_bind ( const char *subsystem, const char *name,
   uc->name                 = name ? strdup(name) : NULL;
   uc->rxtxsize             = rxsize;
 
-  if (udp_resolve(uc, 1) < 0) {
+  if (udp_resolve(uc, &uc->ip, uc->host, port, &uc->multicast, 1)) {
     udp_close(uc);
     return UDP_FATAL_ERROR;
   }
@@ -206,7 +210,7 @@ udp_bind ( const char *subsystem, const char *name,
     memset(&m,   0, sizeof(m));
 
     /* Bind */
-    if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in)) == -1) {
+    if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in))) {
       inet_ntop(AF_INET, &IP_AS_V4(uc->ip, addr), buf, sizeof(buf));
       tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]",
                name, buf, ntohs(IP_AS_V4(uc->ip, port)), strerror(errno));
@@ -240,7 +244,7 @@ udp_bind ( const char *subsystem, const char *name,
     memset(&m,   0, sizeof(m));
 
     /* Bind */
-    if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in6)) == -1) {
+    if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in6))) {
       inet_ntop(AF_INET6, &IP_AS_V6(uc->ip, addr), buf, sizeof(buf));
       tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]",
                name, buf, ntohs(IP_AS_V6(uc->ip, port)), strerror(errno));
@@ -335,27 +339,19 @@ fail:
 }
 
 udp_connection_t *
-udp_connect ( const char *subsystem, const char *name,
-              const char *host, int port,
-              const char *ifname, int txsize )
+udp_sendinit ( const char *subsystem, const char *name,
+               const char *ifname, int txsize )
 {
   int fd, ifindex;
   udp_connection_t *uc;
 
   uc = calloc(1, sizeof(udp_connection_t));
   uc->fd                   = -1;
-  uc->host                 = host ? strdup(host) : NULL;
-  uc->port                 = port;
   uc->ifname               = ifname ? strdup(ifname) : NULL;
   uc->subsystem            = subsystem ? strdup(subsystem) : NULL;
   uc->name                 = name ? strdup(name) : NULL;
   uc->rxtxsize             = txsize;
 
-  if (udp_resolve(uc, 1) < 0) {
-    udp_close(uc);
-    return UDP_FATAL_ERROR;
-  }
-
   /* Open socket */
   if ((fd = tvh_socket(uc->ip.ss_family, SOCK_DGRAM, 0)) == -1) {
     tvherror(subsystem, "%s - failed to create socket [%s]",
@@ -418,6 +414,33 @@ error:
   return NULL;
 }
 
+int
+udp_connect( udp_connection_t *uc, const char *name,
+              const char *host, int port )
+{
+  char buf[50];
+  int r;
+
+  if (uc == NULL || uc == UDP_FATAL_ERROR)
+    return -1;
+
+  uc->peer_host = host ? strdup(host) : NULL;
+  uc->peer_port = port;
+  uc->peer_multicast = 0;
+
+  if (udp_resolve(uc, &uc->peer, host, port, &uc->peer_multicast, 1))
+    return -1;
+
+  if (connect(uc->fd, (struct sockaddr *)&uc->peer, sizeof(struct sockaddr_in))) {
+    inet_ntop(uc->peer.ss_family, IP_IN_ADDR(uc->peer), buf, sizeof(buf));
+    tvherror(uc->subsystem, "%s - cannot bind %s:%hu [e=%s]",
+             name, buf, ntohs(IP_PORT(uc->peer)), strerror(errno));
+    r = -errno;
+    return r;
+  }
+  return 0;
+}
+
 void
 udp_close( udp_connection_t *uc )
 {
index 5bc142014651645db64c8854d7c7cd55a1a3291b..b584ac8752cdd7c7e33feb435ea6cad4023eeaf2 100644 (file)
--- a/src/udp.h
+++ b/src/udp.h
@@ -31,6 +31,10 @@ typedef struct udp_connection {
   int multicast;
   char *ifname;
   struct sockaddr_storage ip;
+  char *peer_host;
+  int peer_port;
+  int peer_multicast;
+  struct sockaddr_storage peer;
   int fd;
   char *subsystem;
   char *name;
@@ -48,9 +52,11 @@ udp_bind_double ( udp_connection_t **_u1, udp_connection_t **_u2,
                   const char *ifname, int rxsize1, int rxsize2,
                   int txsize1, int txsize2 );
 udp_connection_t *
-udp_connect ( const char *subsystem, const char *name,
-              const char *host, int port,
-              const char *ifname, int txsize );
+udp_sendinit ( const char *subsystem, const char *name,
+               const char *ifname, int txsize );
+int
+udp_connect ( udp_connection_t *uc, const char *name,
+              const char *host, int port );
 void
 udp_close ( udp_connection_t *uc );
 int