summaryrefslogtreecommitdiff
path: root/libavformat/udp.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2011-11-09 11:45:01 +0200
committerMartin Storsjö <martin@martin.st>2011-11-09 20:19:39 +0200
commit65ac51373b7e6a2e2bf4e8131acfda32c0708034 (patch)
treee766b2afb9051ea464a8fd220dbc231ec1eeb591 /libavformat/udp.c
parentc33d4916fba4e81a520b0a579cfb5c3b7c7cf9c7 (diff)
udp: Allow specifying the local IP address
This is useful if sending multicast data on a host with multiple interfaces. Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat/udp.c')
-rw-r--r--libavformat/udp.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/libavformat/udp.c b/libavformat/udp.c
index bd95a811de..178cef477a 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -29,6 +29,7 @@
#include "avformat.h"
#include "avio_internal.h"
#include "libavutil/parseutils.h"
+#include "libavutil/avstring.h"
#include <unistd.h>
#include "internal.h"
#include "network.h"
@@ -178,8 +179,8 @@ static int udp_set_url(struct sockaddr_storage *addr,
return addr_len;
}
-static int udp_socket_create(UDPContext *s,
- struct sockaddr_storage *addr, int *addr_len)
+static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
+ int *addr_len, const char *localaddr)
{
int udp_fd = -1;
struct addrinfo *res0 = NULL, *res = NULL;
@@ -187,7 +188,8 @@ static int udp_socket_create(UDPContext *s,
if (((struct sockaddr *) &s->dest_addr)->sa_family)
family = ((struct sockaddr *) &s->dest_addr)->sa_family;
- res0 = udp_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE);
+ res0 = udp_resolve_host(localaddr[0] ? localaddr : NULL, s->local_port,
+ SOCK_DGRAM, family, AI_PASSIVE);
if (res0 == 0)
goto fail;
for (res = res0; res; res=res->ai_next) {
@@ -302,7 +304,7 @@ static int udp_get_file_handle(URLContext *h)
/* return non zero if error */
static int udp_open(URLContext *h, const char *uri, int flags)
{
- char hostname[1024];
+ char hostname[1024], localaddr[1024] = "";
int port, udp_fd = -1, tmp, bind_ret = -1;
UDPContext *s = NULL;
int is_output;
@@ -350,6 +352,9 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
s->is_connected = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
+ av_strlcpy(localaddr, buf, sizeof(localaddr));
+ }
}
/* fill the dest addr */
@@ -367,7 +372,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if ((s->is_multicast || !s->local_port) && (h->flags & AVIO_FLAG_READ))
s->local_port = port;
- udp_fd = udp_socket_create(s, &my_addr, &len);
+ udp_fd = udp_socket_create(s, &my_addr, &len, localaddr);
if (udp_fd < 0)
goto fail;