diff options
author | Zaheer Abbas Merali <zaheerabbas@merali.org> | 2004-06-12 10:55:10 +0000 |
---|---|---|
committer | Zaheer Abbas Merali <zaheerabbas@merali.org> | 2004-06-12 10:55:10 +0000 |
commit | ff6de28f39796eabe1eb145539184ecb0d101d34 (patch) | |
tree | 571e11a80db7aa6445b3dbfd1fe663afbaeddcde | |
parent | 6598d236ff36f5755c44302b7facc563bd84a0c1 (diff) |
gst/tcp/: Modified the tcp plugins so they are portable (IPv4,IPv6, any future version of IP)
Original commit message from CVS:
2004-06-12 Zaheer Abbas Merali <zaheerabbas@merali.org>
* gst/tcp/gsttcpclientsink.c: (gst_tcpclientsink_init_send):
* gst/tcp/gsttcpclientsink.h:
* gst/tcp/gsttcpclientsrc.c: (gst_tcpclientsrc_init_receive):
* gst/tcp/gsttcpclientsrc.h:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_init_send):
* gst/tcp/gsttcpserversink.h:
* gst/tcp/gsttcpserversrc.c: (gst_tcpserversrc_init_receive):
* gst/tcp/gsttcpserversrc.h:
Modified the tcp plugins so they are portable (IPv4,IPv6, any future
version of IP)
-rw-r--r-- | ChangeLog | 15 | ||||
m--------- | common | 0 | ||||
-rw-r--r-- | gst/tcp/gsttcpclientsink.c | 76 | ||||
-rw-r--r-- | gst/tcp/gsttcpclientsink.h | 1 | ||||
-rw-r--r-- | gst/tcp/gsttcpclientsrc.c | 79 | ||||
-rw-r--r-- | gst/tcp/gsttcpclientsrc.h | 1 | ||||
-rw-r--r-- | gst/tcp/gsttcpserversink.c | 90 | ||||
-rw-r--r-- | gst/tcp/gsttcpserversink.h | 1 | ||||
-rw-r--r-- | gst/tcp/gsttcpserversrc.c | 83 | ||||
-rw-r--r-- | gst/tcp/gsttcpserversrc.h | 2 |
10 files changed, 202 insertions, 146 deletions
@@ -1,5 +1,20 @@ 2004-06-12 Zaheer Abbas Merali <zaheerabbas@merali.org> + * gst/tcp/gsttcpclientsink.c: (gst_tcpclientsink_init_send): + * gst/tcp/gsttcpclientsink.h: + * gst/tcp/gsttcpclientsrc.c: (gst_tcpclientsrc_init_receive): + * gst/tcp/gsttcpclientsrc.h: + * gst/tcp/gsttcpserversink.c: (gst_tcpserversink_init), + (gst_tcpserversink_handle_server_read), + (gst_tcpserversink_init_send): + * gst/tcp/gsttcpserversink.h: + * gst/tcp/gsttcpserversrc.c: (gst_tcpserversrc_init_receive): + * gst/tcp/gsttcpserversrc.h: + Modified the tcp plugins so they are portable (IPv4,IPv6, any future + version of IP) + +2004-06-12 Zaheer Abbas Merali <zaheerabbas@merali.org> + * configure.ac: Added ogg library so that OSX detects libtheora properly diff --git a/common b/common -Subproject 21888634686506a6938e435f9c4fd5a9f20ccc3 +Subproject 1af22afdec71295108f882c828e08f10d8a3e94 diff --git a/gst/tcp/gsttcpclientsink.c b/gst/tcp/gsttcpclientsink.c index 89cc299ce..e4c1a340a 100644 --- a/gst/tcp/gsttcpclientsink.c +++ b/gst/tcp/gsttcpclientsink.c @@ -302,8 +302,9 @@ gst_tcpclientsink_get_property (GObject * object, guint prop_id, GValue * value, static gboolean gst_tcpclientsink_init_send (GstTCPClientSink * this) { - int ret; - gchar *ip; + int ret, error; + gchar *tempport; + struct addrinfo hints, *res, *ressave; /* reset caps_sent flag */ this->caps_sent = FALSE; @@ -311,45 +312,50 @@ gst_tcpclientsink_init_send (GstTCPClientSink * this) /* create sending client socket */ GST_DEBUG_OBJECT (this, "opening sending client socket to %s:%d", this->host, this->port); - if ((this->sock_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_WRITE, (NULL), GST_ERROR_SYSTEM); + + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + tempport = g_strdup_printf ("%d", this->port); + error = getaddrinfo (this->host, tempport, &hints, &res); + g_free (tempport); + if (error != 0) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, + (_("Error getting address info (%s:%d): %s"), this->host, this->port, + gai_strerror (error)), (NULL)); return FALSE; } - GST_DEBUG_OBJECT (this, "opened sending client socket with fd %d", - this->sock_fd); - /* look up name if we need to */ - ip = gst_tcp_host_to_ip (GST_ELEMENT (this), this->host); - if (!ip) - return FALSE; - GST_DEBUG_OBJECT (this, "IP address for host %s is %s", this->host, ip); - - /* connect to server */ - memset (&this->server_sin, 0, sizeof (this->server_sin)); - this->server_sin.sin_family = AF_INET; /* network socket */ - this->server_sin.sin_port = htons (this->port); /* on port */ - this->server_sin.sin_addr.s_addr = inet_addr (ip); /* on host ip */ - - GST_DEBUG_OBJECT (this, "connecting to server"); - ret = connect (this->sock_fd, (struct sockaddr *) &this->server_sin, - sizeof (this->server_sin)); - - if (ret) { - switch (errno) { - case ECONNREFUSED: - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_WRITE, - (_("Connection to %s:%d refused."), this->host, this->port), - (NULL)); - return FALSE; - break; - default: - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), - ("connect to %s:%d failed: %s", this->host, this->port, - g_strerror (errno))); - return FALSE; + ressave = res; + + this->sock_fd = -1; + + while (res) { + this->sock_fd = socket (res->ai_family, res->ai_socktype, res->ai_protocol); + if (this->sock_fd >= 0) { + ret = connect (this->sock_fd, res->ai_addr, res->ai_addrlen); + if (ret == 0) break; + close (this->sock_fd); + this->sock_fd = -1; } + res = res->ai_next; } + freeaddrinfo (ressave); + + if (errno == ECONNREFUSED) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, + (_("Connection to %s:%d refused."), this->host, this->port), (NULL)); + return FALSE; + } + + if (this->sock_fd == -1) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); + return FALSE; + } + + GST_DEBUG_OBJECT (this, "opened sending client socket with fd %d", + this->sock_fd); GST_FLAG_SET (this, GST_TCPCLIENTSINK_OPEN); diff --git a/gst/tcp/gsttcpclientsink.h b/gst/tcp/gsttcpclientsink.h index 9cd657ac8..722203f88 100644 --- a/gst/tcp/gsttcpclientsink.h +++ b/gst/tcp/gsttcpclientsink.h @@ -73,7 +73,6 @@ struct _GstTCPClientSink { /* server information */ int port; gchar *host; - struct sockaddr_in server_sin; /* socket */ int sock_fd; diff --git a/gst/tcp/gsttcpclientsrc.c b/gst/tcp/gsttcpclientsrc.c index 2b833adba..44741bee7 100644 --- a/gst/tcp/gsttcpclientsrc.c +++ b/gst/tcp/gsttcpclientsrc.c @@ -393,52 +393,61 @@ gst_tcpclientsrc_get_property (GObject * object, guint prop_id, GValue * value, static gboolean gst_tcpclientsrc_init_receive (GstTCPClientSrc * this) { - int ret; - gchar *ip; + int ret, error; + gchar *tempport; + + struct addrinfo hints, *res, *ressave; /* create receiving client socket */ GST_DEBUG_OBJECT (this, "opening receiving client socket to %s:%d", this->host, this->port); - if ((this->sock_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); + + memset (&hints, 0, sizeof (struct addrinfo)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + tempport = g_strdup_printf ("%d", this->port); + + error = getaddrinfo (this->host, tempport, &hints, &res); + g_free (tempport); + if (error != 0) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, + (_("Error getting address info (%s:%d): %s"), this->host, this->port, + gai_strerror (error)), (NULL)); return FALSE; } - GST_DEBUG_OBJECT (this, "opened receiving client socket with fd %d", - this->sock_fd); - /* look up name if we need to */ - ip = gst_tcp_host_to_ip (GST_ELEMENT (this), this->host); - if (!ip) - return FALSE; - GST_DEBUG_OBJECT (this, "IP address for host %s is %s", this->host, ip); - - /* connect to server */ - memset (&this->server_sin, 0, sizeof (this->server_sin)); - this->server_sin.sin_family = AF_INET; /* network socket */ - this->server_sin.sin_port = htons (this->port); /* on port */ - this->server_sin.sin_addr.s_addr = inet_addr (ip); /* on host ip */ - - GST_DEBUG_OBJECT (this, "connecting to server"); - ret = connect (this->sock_fd, (struct sockaddr *) &this->server_sin, - sizeof (this->server_sin)); - - if (ret) { - switch (errno) { - case ECONNREFUSED: - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, - (_("Connection to %s:%d refused."), this->host, this->port), - (NULL)); - return FALSE; - break; - default: - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), - ("connect to %s:%d failed: %s", this->host, this->port, - g_strerror (errno))); - return FALSE; + ressave = res; + + this->sock_fd = -1; + while (res) { + this->sock_fd = socket (res->ai_family, res->ai_socktype, res->ai_protocol); + if (this->sock_fd >= 0) { + ret = connect (this->sock_fd, res->ai_addr, res->ai_addrlen); + if (ret == 0) break; + close (this->sock_fd); + this->sock_fd = -1; } + res = res->ai_next; + } + freeaddrinfo (ressave); + + if (errno == ECONNREFUSED) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, + (_("Connection to %s:%d refused."), this->host, this->port), (NULL)); + return FALSE; } + if (this->sock_fd == -1) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); + return FALSE; + } + GST_DEBUG_OBJECT (this, "opened receiving client socket with fd %d", + this->sock_fd); + + this->send_discont = TRUE; this->buffer_after_discont = NULL; GST_FLAG_SET (this, GST_TCPCLIENTSRC_OPEN); diff --git a/gst/tcp/gsttcpclientsrc.h b/gst/tcp/gsttcpclientsrc.h index 414082b03..234677ef6 100644 --- a/gst/tcp/gsttcpclientsrc.h +++ b/gst/tcp/gsttcpclientsrc.h @@ -62,7 +62,6 @@ struct _GstTCPClientSrc { /* server information */ int port; gchar *host; - struct sockaddr_in server_sin; /* socket */ int sock_fd; diff --git a/gst/tcp/gsttcpserversink.c b/gst/tcp/gsttcpserversink.c index 42780a1ac..ea58ef6de 100644 --- a/gst/tcp/gsttcpserversink.c +++ b/gst/tcp/gsttcpserversink.c @@ -29,6 +29,8 @@ #include <sys/filio.h> #endif +#include <glib.h> + #include "gsttcpserversink.h" #include "gsttcp-marshal.h" @@ -187,6 +189,7 @@ gst_tcpserversink_init (GstTCPServerSink * this) this->protocol = GST_TCP_PROTOCOL_TYPE_NONE; this->clock = NULL; + this->host = NULL; } static void @@ -208,8 +211,11 @@ gst_tcpserversink_handle_server_read (GstTCPServerSink * sink) { /* new client */ int client_sock_fd; - struct sockaddr_in client_address; + struct sockaddr_storage client_address; int client_address_len; + char clienthost[NI_MAXHOST]; + char clientservice[NI_MAXSERV]; + int error; client_sock_fd = accept (sink->server_sock_fd, (struct sockaddr *) &client_address, @@ -220,11 +226,19 @@ gst_tcpserversink_handle_server_read (GstTCPServerSink * sink) return FALSE; } FD_SET (client_sock_fd, &(sink->clientfds)); - GST_DEBUG_OBJECT (sink, "added new client ip %s with fd %d", - inet_ntoa (client_address.sin_addr), client_sock_fd); + error = getnameinfo ((struct sockaddr *) &client_address, client_address_len, + clienthost, sizeof (clienthost), clientservice, + sizeof (clientservice), NI_NUMERICHOST); + if (error != 0) { + GST_DEBUG_OBJECT (sink, "added new client address %s with fd %d", + clienthost, client_sock_fd); + } else { + GST_DEBUG_OBJECT (sink, "problem error received from getnameinfo: %d", + error); + } g_signal_emit (G_OBJECT (sink), gst_tcpserversink_signals[SIGNAL_CLIENT_ADDED], 0, - inet_ntoa (client_address.sin_addr), client_sock_fd); + g_strdup (clienthost), client_sock_fd); return TRUE; } @@ -546,15 +560,49 @@ gst_tcpserversink_get_property (GObject * object, guint prop_id, GValue * value, static gboolean gst_tcpserversink_init_send (GstTCPServerSink * this) { - int ret; + int ret, error; + struct addrinfo hints, *res, *ressave; + char *tempport; - /* create sending server socket */ - if ((this->server_sock_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_WRITE, (NULL), GST_ERROR_SYSTEM); + + /* name the socket */ + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + tempport = g_strdup_printf ("%d", this->server_port); + + error = getaddrinfo (this->host, tempport, &hints, &res); + g_free (tempport); + if (error != 0) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), + ("getaddrinfo failed: %s", gai_strerror (error))); + return FALSE; + } + ressave = res; + + /* Try open socket with each address getaddrinfo returned, until getting + a valid listening socket */ + this->server_sock_fd = -1; + while (res) { + this->server_sock_fd = + socket (res->ai_family, res->ai_socktype, res->ai_protocol); + if (this->server_sock_fd >= 0) { + ret = bind (this->server_sock_fd, res->ai_addr, res->ai_addrlen); + if (ret == 0) + break; + close (this->server_sock_fd); + this->server_sock_fd = -1; + } + res = res->ai_next; + } + freeaddrinfo (ressave); + + if (this->server_sock_fd < 0) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), + ("bind failed: %s", g_strerror (errno))); return FALSE; } - GST_DEBUG_OBJECT (this, "opened sending server socket with fd %d", - this->server_sock_fd); /* make address reusable */ if (setsockopt (this->server_sock_fd, SOL_SOCKET, SO_REUSEADDR, &ret, @@ -570,28 +618,6 @@ gst_tcpserversink_init_send (GstTCPServerSink * this) ("Could not setsockopt: %s", g_strerror (errno))); return FALSE; } - - /* name the socket */ - memset (&this->server_sin, 0, sizeof (this->server_sin)); - this->server_sin.sin_family = AF_INET; /* network socket */ - this->server_sin.sin_port = htons (this->server_port); /* on port */ - this->server_sin.sin_addr.s_addr = htonl (INADDR_ANY); /* for hosts */ - - /* bind it */ - GST_DEBUG_OBJECT (this, "binding server socket to address"); - ret = bind (this->server_sock_fd, (struct sockaddr *) &this->server_sin, - sizeof (this->server_sin)); - - if (ret) { - switch (errno) { - default: - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), - ("bind failed: %s", g_strerror (errno))); - return FALSE; - break; - } - } - /* set the server socket to nonblocking */ fcntl (this->server_sock_fd, F_SETFL, O_NONBLOCK); diff --git a/gst/tcp/gsttcpserversink.h b/gst/tcp/gsttcpserversink.h index 449962368..37e5984f7 100644 --- a/gst/tcp/gsttcpserversink.h +++ b/gst/tcp/gsttcpserversink.h @@ -73,7 +73,6 @@ struct _GstTCPServerSink { /* server information */ int server_port; gchar *host; - struct sockaddr_in server_sin; /* socket */ int server_sock_fd; diff --git a/gst/tcp/gsttcpserversrc.c b/gst/tcp/gsttcpserversrc.c index 115a330d4..dd5e5948e 100644 --- a/gst/tcp/gsttcpserversrc.c +++ b/gst/tcp/gsttcpserversrc.c @@ -456,18 +456,50 @@ gst_tcpserversrc_get_property (GObject * object, guint prop_id, GValue * value, static gboolean gst_tcpserversrc_init_receive (GstTCPServerSrc * this) { - int ret; + int ret, error; + struct addrinfo hints, *res, *ressave; + gchar *tempport; + struct sockaddr_storage client_address; + int client_address_len; - /* reset caps_received flag */ - this->caps_received = FALSE; + /* name the socket */ + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + tempport = g_strdup_printf ("%d", this->server_port); + + error = getaddrinfo (this->host, tempport, &hints, &res); + g_free (tempport); + if (error != 0) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), + ("getaddrinfo failed: %s", gai_strerror (error))); + return FALSE; + } + ressave = res; - /* create the server listener socket */ - if ((this->server_sock_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); + /* Try open socket with each address getaddrinfo returned, until getting + a valid listening socket */ + this->server_sock_fd = -1; + while (res) { + this->server_sock_fd = + socket (res->ai_family, res->ai_socktype, res->ai_protocol); + if (this->server_sock_fd >= 0) { + ret = bind (this->server_sock_fd, res->ai_addr, res->ai_addrlen); + if (ret == 0) + break; + close (this->server_sock_fd); + this->server_sock_fd = -1; + } + res = res->ai_next; + } + freeaddrinfo (ressave); + + if (this->server_sock_fd < 0) { + GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), + ("bind failed: %s", g_strerror (errno))); return FALSE; } - GST_DEBUG_OBJECT (this, "opened receiving server socket with fd %d", - this->server_sock_fd); /* make address reusable */ if (setsockopt (this->server_sock_fd, SOL_SOCKET, SO_REUSEADDR, &ret, @@ -477,35 +509,8 @@ gst_tcpserversrc_init_receive (GstTCPServerSrc * this) return FALSE; } - /* name the socket */ - memset (&this->server_sin, 0, sizeof (this->server_sin)); - this->server_sin.sin_family = AF_INET; /* network socket */ - this->server_sin.sin_port = htons (this->server_port); /* on port */ - if (this->host) { - gchar *host = gst_tcp_host_to_ip (GST_ELEMENT (this), this->host); - - if (!host) - return FALSE; - - this->server_sin.sin_addr.s_addr = inet_addr (host); - g_free (host); - } else - this->server_sin.sin_addr.s_addr = htonl (INADDR_ANY); - - /* bind it */ - GST_DEBUG_OBJECT (this, "binding server socket to address"); - ret = bind (this->server_sock_fd, (struct sockaddr *) &this->server_sin, - sizeof (this->server_sin)); - - if (ret) { - switch (errno) { - default: - GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), - ("bind failed: %s", g_strerror (errno))); - return FALSE; - break; - } - } + /* reset caps_received flag */ + this->caps_received = FALSE; GST_DEBUG_OBJECT (this, "listening on server socket %d with queue of %d", this->server_sock_fd, TCP_BACKLOG); @@ -519,8 +524,8 @@ gst_tcpserversrc_init_receive (GstTCPServerSrc * this) somewhere else */ GST_DEBUG_OBJECT (this, "waiting for client"); this->client_sock_fd = - accept (this->server_sock_fd, (struct sockaddr *) &this->client_sin, - &this->client_sin_len); + accept (this->server_sock_fd, (struct sockaddr *) &client_address, + &client_address_len); if (this->client_sock_fd == -1) { GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), ("Could not accept client on server socket: %s", g_strerror (errno))); diff --git a/gst/tcp/gsttcpserversrc.h b/gst/tcp/gsttcpserversrc.h index fbc9e3618..4645118a2 100644 --- a/gst/tcp/gsttcpserversrc.h +++ b/gst/tcp/gsttcpserversrc.h @@ -72,8 +72,6 @@ struct _GstTCPServerSrc { int server_sock_fd; /* client information */ - struct sockaddr_in client_sin; - socklen_t client_sin_len; int client_sock_fd; /* number of bytes we've gotten */ |