]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add information about local ip address so we can send back connections to the client...
authorMike Brady <mikebrady@eircom.net>
Sun, 1 May 2016 21:37:57 +0000 (22:37 +0100)
committerMike Brady <mikebrady@eircom.net>
Sun, 1 May 2016 21:37:57 +0000 (22:37 +0100)
rtp.c
rtsp.c

diff --git a/rtp.c b/rtp.c
index 79aefa4bdb238cb3edc690c8b02f5bd2835a4d7d..501dc66d09c58f6f05f5004b78288beca3d4aa4e 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -59,7 +59,8 @@ typedef struct time_ping_record {
 static int running = 0;
 
 static char client_ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client
-static short client_ip_family;                  // AF_INET / AF_INET6
+static char self_ip_string[INET6_ADDRSTRLEN]; // the ip string being used by this program -- it could be one of many, so we need to know it
+static short connection_ip_family;                  // AF_INET / AF_INET6
 static uint32_t client_active_remote;           // used when you want to control the client...
 
 static SOCKADDR rtp_client_control_socket; // a socket pointing to the control port of the client
@@ -543,47 +544,27 @@ void *rtp_timing_receiver(void *arg) {
   return NULL;
 }
 
-static int bind_port(SOCKADDR *remote, int *sock) {
+static int bind_port(int ip_family,const char *self_ip_address, int *sock) {
   struct addrinfo hints, *info;
 
   memset(&hints, 0, sizeof(hints));
-  hints.ai_family = remote->SAFAMILY;
+  hints.ai_family = ip_family;
   hints.ai_socktype = SOCK_DGRAM;
   hints.ai_flags = AI_PASSIVE;
 
-  char buffer[10];
+  char buffer[20];
   
   // look for a port in the range, if any was specified.
   int desired_port = config.udp_port_base;
   int ret;
   do {
     snprintf(buffer, 10, "%d", desired_port);
-
-    ret = getaddrinfo(NULL, buffer, &hints, &info);
-
+    ret = getaddrinfo(self_ip_address, buffer, &hints, &info);
     if (ret < 0)
       die("failed to get usable addrinfo?! %s.", gai_strerror(ret));
-
-    *sock = socket(remote->SAFAMILY, SOCK_DGRAM, IPPROTO_UDP);
-    
-/*
-  // this doesn't compile properly with OpenWrt Barrier Breaker.
-    #if defined(__linux__)
-    #ifdef AF_INET6
-    // now, if we are on IPv6, prefer a public ipv6 address
-    if (remote->SAFAMILY==AF_INET6) {
-      int value = IPV6_PREFER_SRC_PUBLIC;
-      ret = setsockopt(*sock, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &value, sizeof(value));
-      if (ret<0)
-        die("error: could not select a preference for public IPv6 address");
-    }
-    #endif
-    #endif
-*/
+    *sock = socket(ip_family, SOCK_DGRAM, IPPROTO_UDP);    
     ret = bind(*sock, info->ai_addr, info->ai_addrlen);
-
     freeaddrinfo(info);
-
   } while ((ret<0) && (errno==EADDRINUSE) && (desired_port!=0) && (desired_port++ < config.udp_port_base+config.udp_port_range));
   
   // debug(1,"UDP port chosen: %d.",desired_port);
@@ -592,7 +573,6 @@ static int bind_port(SOCKADDR *remote, int *sock) {
      die("error: could not bind a UDP port!");
   }
  
-  
   int sport;
   SOCKADDR local;
   socklen_t local_len = sizeof(local);
@@ -611,8 +591,13 @@ static int bind_port(SOCKADDR *remote, int *sock) {
   return sport;
 }
 
-void rtp_setup(SOCKADDR *remote, int cport, int tport, uint32_t active_remote, int *lsport,
+void rtp_setup(SOCKADDR *local, SOCKADDR *remote, int cport, int tport, uint32_t active_remote, int *lsport,
                int *lcport, int *ltport) {
+               
+  // this gets the local and remote ip numbers (and ports used for the TCD stuff)
+  // we use the local stuff to specify the address we are coming from and
+  // we use the remote stuff to specify where we're goint to
+  
   if (running)
     die("rtp_setup called with active stream!");
 
@@ -621,28 +606,39 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, uint32_t active_remote, i
   client_active_remote = active_remote;
 
   // print out what we know about the client
-  void *addr;
+  void *client_addr,*self_addr;
   char *ipver;
-  int port;
-  char portstr[20];
-  client_ip_family = remote->SAFAMILY; // keep information about the kind of ip of the client
+  int client_port,self_port;
+  char client_port_str[20];
+  char self_addr_str[20];
+  
+  connection_ip_family = remote->SAFAMILY; // keep information about the kind of ip of the client
+  
 #ifdef AF_INET6
-  if (remote->SAFAMILY == AF_INET6) {
-    struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)remote;
-    addr = &(sa6->sin6_addr);
-    port = ntohs(sa6->sin6_port);
+  if (connection_ip_family == AF_INET6) {
     ipver = "IPv6";
+    struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)remote;
+    client_addr = &(sa6->sin6_addr);
+    client_port = ntohs(sa6->sin6_port);
+    sa6 = (struct sockaddr_in6 *)local;
+    self_addr = &(sa6->sin6_addr);
+    self_port = ntohs(sa6->sin6_port);
   }
 #endif
-  if (remote->SAFAMILY == AF_INET) {
-    struct sockaddr_in *sa4 = (struct sockaddr_in *)remote;
-    addr = &(sa4->sin_addr);
-    port = ntohs(sa4->sin_port);
+  if (connection_ip_family == AF_INET) {
     ipver = "IPv4";
+    struct sockaddr_in *sa4 = (struct sockaddr_in *)remote;
+    client_addr = &(sa4->sin_addr);
+    client_port = ntohs(sa4->sin_port);
+    sa4 = (struct sockaddr_in *)local;
+    self_addr = &(sa4->sin_addr);
+    self_port = ntohs(sa4->sin_port);
   }
-  inet_ntop(remote->SAFAMILY, addr, client_ip_string,
+  inet_ntop(connection_ip_family, client_addr, client_ip_string,
             sizeof(client_ip_string)); // keep the client's ip number
-  debug(1, "Connection from %s: %s:%d", ipver, client_ip_string, port);
+  inet_ntop(connection_ip_family, self_addr, self_ip_string,
+            sizeof(self_ip_string)); // keep the client's ip number
+  debug(1, "Connection via %s from AirPlay client at: %s:%u to this Shairport Sync AirPlay server at: %s:%u.", ipver, client_ip_string, client_port,self_ip_string,self_port);
 
   // set up a the record of the remote's control socket
   struct addrinfo hints;
@@ -650,8 +646,9 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, uint32_t active_remote, i
 
   memset(&rtp_client_control_socket, 0, sizeof(rtp_client_control_socket));
   memset(&hints, 0, sizeof hints);
-  hints.ai_family = remote->SAFAMILY;
+  hints.ai_family = connection_ip_family;
   hints.ai_socktype = SOCK_DGRAM;
+  char portstr[20];
   snprintf(portstr, 20, "%d", cport);
   if (getaddrinfo(client_ip_string, portstr, &hints, &servinfo) != 0)
     die("Can't get address of client's control port");
@@ -667,7 +664,7 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, uint32_t active_remote, i
   // set up a the record of the remote's timing socket
   memset(&rtp_client_timing_socket, 0, sizeof(rtp_client_timing_socket));
   memset(&hints, 0, sizeof hints);
-  hints.ai_family = remote->SAFAMILY;
+  hints.ai_family = connection_ip_family;
   hints.ai_socktype = SOCK_DGRAM;
   snprintf(portstr, 20, "%d", tport);
   if (getaddrinfo(client_ip_string, portstr, &hints, &servinfo) != 0)
@@ -683,9 +680,9 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, uint32_t active_remote, i
   // now, we open three sockets -- one for the audio stream, one for the timing and one for the
   // control
 
-  *lsport = bind_port(remote, &audio_socket);
-  *lcport = bind_port(remote, &control_socket);
-  *ltport = bind_port(remote, &timing_socket);
+  *lsport = bind_port(connection_ip_family,self_ip_string,&audio_socket);
+  *lcport = bind_port(connection_ip_family,self_ip_string,&control_socket);
+  *ltport = bind_port(connection_ip_family,self_ip_string,&timing_socket);
 
   debug(2, "listening for audio, control and timing on ports %d, %d, %d.", *lsport, *lcport,
         *ltport);
diff --git a/rtsp.c b/rtsp.c
index e8867042c9f83b8beb25c4559317f7e80b43a62f..f101affea6a10bc05758bca314751c86eb1a890a 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -89,7 +89,7 @@ static pthread_mutex_t reference_counter_lock = PTHREAD_MUTEX_INITIALIZER;
 typedef struct {
   int fd;
   stream_cfg stream;
-  SOCKADDR remote;
+  SOCKADDR remote,local;
   int stop;
   int running;
   pthread_t thread;
@@ -806,7 +806,7 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req,
   tport = atoi(p);
 
 //  rtsp_take_player();
-  rtp_setup(&conn->remote, cport, tport, active_remote, &lsport, &lcport,
+  rtp_setup(&conn->local, &conn->remote, cport, tport, active_remote, &lsport, &lcport,
             &ltport);
   if (!lsport)
     goto error;
@@ -1904,12 +1904,46 @@ void rtsp_listen_loop(void) {
     memset(conn, 0, sizeof(rtsp_conn_info));
     socklen_t slen = sizeof(conn->remote);
 
-    debug(1, "New RTSP connection on port %d", config.port);
     conn->fd = accept(acceptfd, (struct sockaddr *)&conn->remote, &slen);
     if (conn->fd < 0) {
+      debug(1, "New RTSP connection on port %d not accepted:", config.port);
       perror("failed to accept connection");
       free(conn);
     } else {
+      SOCKADDR *local_info = (SOCKADDR*)&conn->local;
+      socklen_t size_of_reply = sizeof(*local_info);
+      memset(local_info,0,sizeof(SOCKADDR));
+      if (getsockname(conn->fd, (struct sockaddr*)local_info, &size_of_reply)==0) {
+        char host[1024];
+        char service[20];
+                
+        // IPv4:
+        if (local_info->SAFAMILY==AF_INET) {
+          char ip4[INET_ADDRSTRLEN];  // space to hold the IPv4 string
+          struct sockaddr_in *sa = (struct sockaddr_in*)local_info;      // pretend this is loaded with something
+
+          inet_ntop(AF_INET, &(sa->sin_addr), ip4, INET_ADDRSTRLEN);
+          unsigned short int tport = ntohs(sa->sin_port);
+          debug(1,"New RTSP connection at: %s:%u", ip4,tport);
+        }
+#ifdef AF_INET6
+        if (local_info->SAFAMILY==AF_INET6) {
+          // IPv6:
+
+          char ip6[INET6_ADDRSTRLEN]; // space to hold the IPv6 string
+          struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)local_info; ;    // pretend this is loaded with something
+
+          inet_ntop(AF_INET6, &(sa6->sin6_addr), ip6, INET6_ADDRSTRLEN);
+          u_int16_t tport = ntohs(sa6->sin6_port);
+          debug(1,"New RTSP connection at: %s:%u", ip6,tport);
+        }
+ #endif       
+      
+      } else {
+        debug(1,"Error figuring out Shairport Sync's own ipnumber");
+      }
+
       usleep(500000);
       pthread_t rtsp_conversation_thread;
       ret = pthread_create(&rtsp_conversation_thread, NULL,