]> git.sesse.net Git - vlc/commitdiff
* configure.ac: check for struct sockaddr_storage
authorRémi Denis-Courmont <rem@videolan.org>
Mon, 5 Jul 2004 15:43:56 +0000 (15:43 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Mon, 5 Jul 2004 15:43:56 +0000 (15:43 +0000)
* src/misc/httpd.c: use sockaddr_storage instead of sockaddr_in
         (so I may have a chance of storing a sockaddr_in6 one day)

configure.ac
src/misc/httpd.c

index d3f2901578036df8d83549dc4401d24bf7e42e70..efd89a06f548e452f85f99f5834b55bcefe65388 100644 (file)
@@ -343,6 +343,26 @@ if test "${ac_cv_type_socklen_t}" != "no"; then
   AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define if <sys/socket.h> defines socklen_t.])
 fi
 
+dnl Check for struct sockaddr_storage
+AH_TEMPLATE(sockaddr_storage, [Define to `sockaddr' if <sys/socket.h> does not define.])
+AH_TEMPLATE(ss_family, [Define to `sa_family' if <sys/socket.h> does not define.])
+AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_struct_sockaddr_storage,
+  [AC_TRY_COMPILE(
+    [#include <sys/types.h>
+     #if defined( UNDER_CE )
+     # include <winsock.h>
+     #elif defined( WIN32 )
+     # include <winsock2.h>
+     #else
+     # include <sys/socket.h>
+     #endif], [struct sockaddr_storage addr;],
+     ac_cv_struct_sockaddr_storage=yes,
+     ac_cv_struct_sockaddr_storage=no)])
+if test $ac_cv_struct_sockaddr_storage = no; then
+  AC_DEFINE(sockaddr_storage, sockaddr)
+  AC_DEFINE(ss_family, sa_family)
+fi
+
 dnl Check for va_copy
 AC_CACHE_CHECK([for va_copy], ac_cv_c_va_copy,
   AC_TRY_LINK(
index b5929309e67d405500e8349bf4f5a55572f9c75f..4a4d19bbc4f7e66687346c172dceff6451fc54c9 100644 (file)
@@ -5,6 +5,7 @@
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Remi Denis-Courmont <courmisch@via.ecp.fr> 
  *
  * 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
@@ -26,6 +27,7 @@
 
 #include "vlc_httpd.h"
 
+#include <string.h>
 #include <errno.h>
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
@@ -200,8 +202,9 @@ struct httpd_host_t
     int         i_ref;
 
     /* address/port and socket for listening at connections */
-    struct sockaddr_in sock;
-    int                fd;
+    struct sockaddr_storage sock;
+    int                     i_sock_size;
+    int                     fd;
 
     vlc_mutex_t lock;
 
@@ -260,7 +263,8 @@ struct httpd_client_t
 
     int     i_ref;
 
-    struct  sockaddr_in sock;
+    struct  sockaddr_storage sock;
+    int     i_sock_size;
     int     fd;
 
     int     i_mode;
@@ -857,7 +861,7 @@ void httpd_StreamDelete( httpd_stream_t *stream )
 #endif
 
 static void httpd_HostThread( httpd_host_t * );
-static int BuildAddr( struct sockaddr_in * p_socket,
+static int BuildAddr( struct sockaddr_storage * p_socket, int *pi_sock_size,
                       const char * psz_address, int i_port );
 
 
@@ -867,11 +871,11 @@ httpd_host_t *httpd_HostNew( vlc_object_t *p_this, char *psz_host, int i_port )
     httpd_t      *httpd;
     httpd_host_t *host;
     vlc_value_t lockval;
-    struct sockaddr_in sock;
-    int i;
+    struct sockaddr_storage sock;
+    int i, i_sock_size;
 
     /* resolv */
-    if( BuildAddr( &sock, psz_host, i_port ) )
+    if( BuildAddr( &sock, &i_sock_size, psz_host, i_port ) )
     {
         msg_Err( p_this, "cannot build address for %s:%d", psz_host, i_port );
         return NULL;
@@ -901,9 +905,34 @@ httpd_host_t *httpd_HostNew( vlc_object_t *p_this, char *psz_host, int i_port )
     /* verify if it already exist */
     for( i = 0; i < httpd->i_host; i++ )
     {
-        if( httpd->host[i]->sock.sin_port == sock.sin_port &&
-            ( httpd->host[i]->sock.sin_addr.s_addr == INADDR_ANY ||
-              httpd->host[i]->sock.sin_addr.s_addr == sock.sin_addr.s_addr ) )
+        vlc_bool_t b_match = VLC_FALSE;
+
+        if (sock.ss_family != httpd->host[i]->sock.ss_family ||
+            i_sock_size != httpd->host[i]->i_sock_size)
+            continue;
+        
+        switch (sock.ss_family)
+        {
+            case AF_INET:
+            {
+                const struct sockaddr_in *p_mysock, *p_thatsock;
+                
+                p_mysock = (const struct sockaddr_in *)&sock;
+                p_thatsock = (const struct sockaddr_in *)&httpd->host[i]->sock;
+                
+                b_match = p_mysock->sin_port == p_thatsock->sin_port &&
+                          ( p_mysock->sin_addr.s_addr == INADDR_ANY ||
+                            p_mysock->sin_addr.s_addr ==
+                                              p_thatsock->sin_addr.s_addr ) ?
+                          VLC_TRUE : VLC_FALSE;
+                break;
+            }
+            
+            default:
+                msg_Dbg( p_this, "host with unknown address family" );
+        }
+        
+        if (b_match == VLC_TRUE)
         {
             /* yep found */
             host = httpd->host[i];
@@ -920,14 +949,15 @@ httpd_host_t *httpd_HostNew( vlc_object_t *p_this, char *psz_host, int i_port )
     host->httpd = httpd;
     vlc_mutex_init( httpd, &host->lock );
     host->i_ref = 1;
-    memcpy( &host->sock, &sock, sizeof( struct sockaddr_in ) );
+    memcpy( &host->sock, &sock, sizeof( struct sockaddr_storage ) );
+    host->i_sock_size = i_sock_size;
     host->i_url     = 0;
     host->url       = NULL;
     host->i_client  = 0;
     host->client    = NULL;
 
     /* create the listening socket */
-    if( ( host->fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
+    if( ( host->fd = socket( PF_INET, SOCK_STREAM, 0 ) ) < 0 )
     {
         goto socket_error;
     }
@@ -939,8 +969,7 @@ httpd_host_t *httpd_HostNew( vlc_object_t *p_this, char *psz_host, int i_port )
         msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR)" );
     }
     /* bind it */
-    if( bind( host->fd, (struct sockaddr *)&host->sock,
-        sizeof( struct sockaddr_in ) ) < 0 )
+    if( bind( host->fd, (struct sockaddr *)&host->sock, host->i_sock_size ) )
     {
         msg_Err( p_this, "cannot bind socket" );
         goto socket_error;
@@ -1291,8 +1320,8 @@ void httpd_ClientModeBidir( httpd_client_t *cl )
 
 char* httpd_ClientIP( httpd_client_t *cl )
 {
-    /* FIXME not thread safe */
-    return strdup( inet_ntoa( cl->sock.sin_addr ) );
+    /* FIXME not thread safe - should use inet_ntop if available */
+    return strdup( inet_ntoa( ((const struct sockaddr_in *)&cl->sock)->sin_addr ) );
 }
 
 static void httpd_ClientClean( httpd_client_t *cl )
@@ -1313,7 +1342,8 @@ static void httpd_ClientClean( httpd_client_t *cl )
     }
 }
 
-static httpd_client_t *httpd_ClientNew( int fd, struct sockaddr_in *sock )
+static httpd_client_t *httpd_ClientNew( int fd, struct sockaddr_storage *sock,
+                                        int i_sock_size )
 {
     httpd_client_t *cl = malloc( sizeof( httpd_client_t ) );
     /* set this new socket non-block */
@@ -1327,7 +1357,8 @@ static httpd_client_t *httpd_ClientNew( int fd, struct sockaddr_in *sock )
 #endif
     cl->i_ref   = 0;
     cl->fd      = fd;
-    cl->sock    = *sock;
+    memcpy( &cl->sock, sock, sizeof( cl->sock ) );
+    cl->i_sock_size = i_sock_size;
     cl->url     = NULL;
 
     httpd_ClientInit( cl );
@@ -1796,7 +1827,7 @@ static void httpd_HostThread( httpd_host_t *host )
                   cl->i_activity_date + cl->i_activity_timeout < mdate() ) ) )
             {
                 msg_Dbg( host, "connection closed(%s)",
-                         inet_ntoa(cl->sock.sin_addr) );
+                         inet_ntoa(((const struct sockaddr_in *)&cl->sock)->sin_addr) );
                 httpd_ClientClean( cl );
                 TAB_REMOVE( host->i_client, host->client, cl );
                 free( cl );
@@ -2141,21 +2172,21 @@ static void httpd_HostThread( httpd_host_t *host )
         /* accept new connections */
         if( FD_ISSET( host->fd, &fds_read ) )
         {
-            int     i_sock_size = sizeof( struct sockaddr_in );
-            struct  sockaddr_in sock;
+            int     i_sock_size = sizeof( struct sockaddr_storage );
+            struct  sockaddr_storage sock;
             int     fd;
 
             fd = accept( host->fd, (struct sockaddr *)&sock, &i_sock_size );
             if( fd > 0 )
             {
-                httpd_client_t *cl = httpd_ClientNew( fd, &sock );
+                httpd_client_t *cl = httpd_ClientNew( fd, &sock, i_sock_size );
 
                 vlc_mutex_lock( &host->lock );
                 TAB_APPEND( host->i_client, host->client, cl );
                 vlc_mutex_unlock( &host->lock );
 
                 msg_Dbg( host, "new connection (%s)",
-                         inet_ntoa(sock.sin_addr) );
+                         inet_ntoa(((const struct sockaddr_in *)&sock)->sin_addr) );
             }
         }
         /* now try all others socket */
@@ -2183,16 +2214,17 @@ static void httpd_HostThread( httpd_host_t *host )
     }
 }
 
-static int BuildAddr( struct sockaddr_in * p_socket,
+static int BuildAddr( struct sockaddr_storage * p_socket, int *pi_sock_size,
                       const char * psz_address, int i_port )
 {
     /* Reset struct */
-    memset( p_socket, 0, sizeof( struct sockaddr_in ) );
-    p_socket->sin_family = AF_INET;                                /* family */
-    p_socket->sin_port = htons( (uint16_t)i_port );
+    memset( p_socket, 0, sizeof( struct sockaddr_storage ) );
+    p_socket->ss_family = AF_INET;                                /* family */
+    *pi_sock_size = sizeof( struct sockaddr_in );
+    ((struct sockaddr_in *)p_socket)->sin_port = htons( (uint16_t)i_port );
     if( !*psz_address )
     {
-        p_socket->sin_addr.s_addr = INADDR_ANY;
+        ((struct sockaddr_in *)p_socket)->sin_addr.s_addr = INADDR_ANY;
     }
     else
     {
@@ -2201,11 +2233,11 @@ static int BuildAddr( struct sockaddr_in * p_socket,
         /* Try to convert address directly from in_addr - this will work if
          * psz_address is dotted decimal. */
 #ifdef HAVE_ARPA_INET_H
-        if( !inet_aton( psz_address, &p_socket->sin_addr ) )
+        if( !inet_aton( psz_address, &((struct sockaddr_in *)p_socket)->sin_addr ) )
 #else
-        p_socket->sin_addr.s_addr = inet_addr( psz_address );
-/*        if( p_socket->sin_addr.s_addr == INADDR_NONE )*/
-        if( p_socket->sin_addr.s_addr == INADDR_BROADCAST )
+        ((struct sockaddr_in *)p_socket)->sin_addr.s_addr = inet_addr( psz_address );
+/*        if( ((struct sockaddr_in *)p_socket)->sin_addr.s_addr == INADDR_NONE )*/
+        if( ((struct sockaddr_in *)p_socket)->sin_addr.s_addr == INADDR_BROADCAST )
 #endif
         {
             /* We have a fqdn, try to find its address */
@@ -2215,7 +2247,7 @@ static int BuildAddr( struct sockaddr_in * p_socket,
             }
 
             /* Copy the first address of the host in the socket address */
-            memcpy( &p_socket->sin_addr, p_hostent->h_addr_list[0],
+            memcpy( &((struct sockaddr_in *)p_socket)->sin_addr, p_hostent->h_addr_list[0],
                      p_hostent->h_length );
         }
     }