SAT>IP: allow to specify the local bind IP address
This commit is contained in:
parent
02642ce851
commit
de306a0827
11 changed files with 68 additions and 32 deletions
|
@ -1169,7 +1169,7 @@ cwc_thread(void *aux)
|
|||
|
||||
pthread_mutex_unlock(&cwc_mutex);
|
||||
|
||||
fd = tcp_connect(hostname, port, errbuf, sizeof(errbuf), 10);
|
||||
fd = tcp_connect(hostname, port, NULL, errbuf, sizeof(errbuf), 10);
|
||||
|
||||
pthread_mutex_lock(&cwc_mutex);
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ struct http_client {
|
|||
char *hc_scheme;
|
||||
char *hc_host;
|
||||
int hc_port;
|
||||
char *hc_bindaddr;
|
||||
tvhpoll_t *hc_efd;
|
||||
int hc_pevents;
|
||||
|
||||
|
@ -289,8 +290,8 @@ void http_client_init ( void );
|
|||
void http_client_done ( void );
|
||||
|
||||
http_client_t*
|
||||
http_client_connect ( void *aux, http_ver_t ver,
|
||||
const char *scheme, const char *host, int port );
|
||||
http_client_connect ( void *aux, http_ver_t ver, const char *scheme,
|
||||
const char *host, int port, const char *bindaddr );
|
||||
void http_client_register ( http_client_t *hc );
|
||||
void http_client_close ( http_client_t *hc );
|
||||
|
||||
|
|
|
@ -1164,7 +1164,7 @@ http_client_reconnect
|
|||
hc->hc_port = port;
|
||||
if (port < 0)
|
||||
return -EINVAL;
|
||||
hc->hc_fd = tcp_connect(host, port, errbuf, sizeof(errbuf), -1);
|
||||
hc->hc_fd = tcp_connect(host, port, hc->hc_bindaddr, errbuf, sizeof(errbuf), -1);
|
||||
if (hc->hc_fd < 0) {
|
||||
tvhlog(LOG_ERR, "httpc", "Unable to connect to %s:%i - %s", host, port, errbuf);
|
||||
return -EINVAL;
|
||||
|
@ -1217,7 +1217,8 @@ err1:
|
|||
|
||||
http_client_t *
|
||||
http_client_connect
|
||||
( void *aux, http_ver_t ver, const char *scheme, const char *host, int port )
|
||||
( void *aux, http_ver_t ver, const char *scheme,
|
||||
const char *host, int port, const char *bindaddr )
|
||||
{
|
||||
http_client_t *hc;
|
||||
|
||||
|
@ -1226,6 +1227,7 @@ http_client_connect
|
|||
hc->hc_io_size = 1024;
|
||||
hc->hc_rtsp_stream_id = -1;
|
||||
hc->hc_verify_peer = -1;
|
||||
hc->hc_bindaddr = bindaddr ? strdup(bindaddr) : NULL;
|
||||
|
||||
TAILQ_INIT(&hc->hc_args);
|
||||
TAILQ_INIT(&hc->hc_wqueue);
|
||||
|
@ -1280,6 +1282,7 @@ http_client_close ( http_client_t *hc )
|
|||
free(hc->hc_data);
|
||||
free(hc->hc_host);
|
||||
free(hc->hc_scheme);
|
||||
free(hc->hc_bindaddr);
|
||||
free(hc);
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ imagecache_image_fetch ( imagecache_image_t *img )
|
|||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
hc = http_client_connect(NULL, HTTP_VERSION_1_1, url.scheme,
|
||||
url.host, url.port);
|
||||
url.host, url.port, NULL);
|
||||
if (hc == NULL)
|
||||
goto error;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ iptv_http_start
|
|||
int r;
|
||||
|
||||
if (!(hc = http_client_connect(im, HTTP_VERSION_1_1, u->scheme,
|
||||
u->host, u->port)))
|
||||
u->host, u->port, NULL)))
|
||||
return SM_CODE_TUNING_FAILED;
|
||||
hc->hc_hdr_received = iptv_http_header;
|
||||
hc->hc_data_received = iptv_http_data;
|
||||
|
|
|
@ -112,6 +112,13 @@ const idclass_t satip_device_class =
|
|||
.opts = PO_ADVANCED,
|
||||
.off = offsetof(satip_device_t, sd_pids0),
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "bindaddr",
|
||||
.name = "Local bind IP address",
|
||||
.opts = PO_ADVANCED,
|
||||
.off = offsetof(satip_device_t, sd_bindaddr),
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "addr",
|
||||
|
@ -227,7 +234,7 @@ const idclass_t satip_device_class =
|
|||
{
|
||||
.type = PT_STR,
|
||||
.id = "myaddr",
|
||||
.name = "Local IP Address",
|
||||
.name = "Local Discovery IP Address",
|
||||
.opts = PO_RDONLY | PO_NOSAVE,
|
||||
.off = offsetof(satip_device_t, sd_info.myaddr),
|
||||
},
|
||||
|
@ -455,6 +462,7 @@ satip_device_destroy( satip_device_t *sd )
|
|||
FREEM(presentation);
|
||||
FREEM(tunercfg);
|
||||
#undef FREEM
|
||||
free(sd->sd_bindaddr);
|
||||
|
||||
tvh_hardware_delete((tvh_hardware_t*)sd);
|
||||
free(sd);
|
||||
|
@ -573,10 +581,7 @@ satip_discovery_http_closed(http_client_t *hc, int errn)
|
|||
socklen_t addrlen = sizeof(ip);
|
||||
errbuf[0] = '\0';
|
||||
getsockname(hc->hc_fd, (struct sockaddr *)&ip, &addrlen);
|
||||
if (ip.ss_family == AF_INET6)
|
||||
inet_ntop(AF_INET6, &IP_AS_V6(ip, addr), errbuf, sizeof(errbuf));
|
||||
else
|
||||
inet_ntop(AF_INET, &IP_AS_V4(ip, addr), errbuf, sizeof(errbuf));
|
||||
inet_ntop(ip.ss_family, IP_IN_ADDR(ip), errbuf, sizeof(errbuf));
|
||||
free(d->myaddr);
|
||||
d->myaddr = strdup(errbuf);
|
||||
}
|
||||
|
@ -703,7 +708,7 @@ satip_discovery_timerq_cb(void *aux)
|
|||
}
|
||||
|
||||
d->http_client = http_client_connect(d, HTTP_VERSION_1_1, d->url.scheme,
|
||||
d->url.host, d->url.port);
|
||||
d->url.host, d->url.port, NULL);
|
||||
if (d->http_client == NULL)
|
||||
satip_discovery_destroy(d, 1);
|
||||
else {
|
||||
|
@ -803,7 +808,7 @@ satip_discovery_service_received
|
|||
/* Forward information to next layer */
|
||||
|
||||
d = calloc(1, sizeof(satip_discovery_t));
|
||||
if (inet_ntop(storage->ss_family, IP_IN_ADDR(conn->ip),
|
||||
if (inet_ntop(conn->ip.ss_family, IP_IN_ADDR(conn->ip),
|
||||
sockbuf, sizeof(sockbuf)) == NULL) {
|
||||
satip_discovery_destroy(d, 0);
|
||||
return;
|
||||
|
|
|
@ -42,6 +42,15 @@ satip_frontend_find_by_number( satip_device_t *sd, int num )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
satip_frontend_bindaddr( satip_frontend_t *lfe )
|
||||
{
|
||||
char *bindaddr = lfe->sf_device->sd_bindaddr;
|
||||
if (bindaddr == NULL || bindaddr[0] == '\0')
|
||||
bindaddr = lfe->sf_device->sd_bindaddr;
|
||||
return bindaddr;
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
* Class definition
|
||||
* *************************************************************************/
|
||||
|
@ -962,7 +971,8 @@ satip_frontend_input_thread ( void *aux )
|
|||
pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex);
|
||||
|
||||
rtsp = http_client_connect(lfe, RTSP_VERSION_1_0, "rstp",
|
||||
lfe->sf_device->sd_info.addr, 554);
|
||||
lfe->sf_device->sd_info.addr, 554,
|
||||
satip_frontend_bindaddr(lfe));
|
||||
if (rtsp == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -1245,7 +1255,7 @@ satip_frontend_tune0
|
|||
|
||||
if (udp_bind_double(&lfe->sf_rtp, &lfe->sf_rtcp,
|
||||
"satip", "rtp", "rtpc",
|
||||
lfe->sf_device->sd_info.myaddr, lfe->sf_udp_rtp_port,
|
||||
satip_frontend_bindaddr(lfe), lfe->sf_udp_rtp_port,
|
||||
NULL, SATIP_BUF_SIZE, 16384) < 0)
|
||||
return SM_CODE_TUNING_FAILED;
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ struct satip_device
|
|||
/*
|
||||
* RTSP
|
||||
*/
|
||||
char *sd_bindaddr;
|
||||
int sd_fullmux_ok;
|
||||
int sd_pids_max;
|
||||
int sd_pids_len;
|
||||
|
|
18
src/tcp.c
18
src/tcp.c
|
@ -48,8 +48,8 @@ th_pipe_t tcp_server_pipe;
|
|||
*
|
||||
*/
|
||||
int
|
||||
tcp_connect(const char *hostname, int port, char *errbuf, size_t errbufsize,
|
||||
int timeout)
|
||||
tcp_connect(const char *hostname, int port, const char *bindaddr,
|
||||
char *errbuf, size_t errbufsize, int timeout)
|
||||
{
|
||||
int fd, r, res, err;
|
||||
struct addrinfo *ai;
|
||||
|
@ -78,7 +78,19 @@ tcp_connect(const char *hostname, int port, char *errbuf, size_t errbufsize,
|
|||
*/
|
||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) {
|
||||
if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6) {
|
||||
if (bindaddr && bindaddr[0] != '\0') {
|
||||
struct sockaddr_storage ip;
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
ip.ss_family = ai->ai_family;
|
||||
if (inet_pton(AF_INET, bindaddr, IP_IN_ADDR(ip)) <= 0 ||
|
||||
bind(fd, (struct sockaddr *)&ip, IP_IN_ADDRLEN(ip)) < 0) {
|
||||
snprintf(errbuf, errbufsize, "Cannot bind to IPv%s addr '%s'", bindaddr,
|
||||
ai->ai_family == AF_INET6 ? "6" : "4");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
snprintf(errbuf, errbufsize, "Invalid protocol family");
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
|
|
19
src/tcp.h
19
src/tcp.h
|
@ -22,6 +22,21 @@
|
|||
#include "htsbuf.h"
|
||||
#include "htsmsg.h"
|
||||
|
||||
#define IP_AS_V4(storage, f) ((struct sockaddr_in *)&(storage))->sin_##f
|
||||
#define IP_AS_V6(storage, f) ((struct sockaddr_in6 *)&(storage))->sin6_##f
|
||||
#define IP_IN_ADDR(storage) \
|
||||
((storage).ss_family == AF_INET6 ? \
|
||||
&((struct sockaddr_in6 *)&(storage))->sin6_addr : \
|
||||
(void *)&((struct sockaddr_in *)&(storage))->sin_addr)
|
||||
#define IP_IN_ADDRLEN(storage) \
|
||||
((storage).ss_family == AF_INET6 ? \
|
||||
sizeof(struct sockaddr_in6) : \
|
||||
sizeof(struct sockaddr_in))
|
||||
#define IP_PORT(storage) \
|
||||
((storage).ss_family == AF_INET6 ? \
|
||||
((struct sockaddr_in6 *)&(storage))->sin6_port : \
|
||||
((struct sockaddr_in *)&(storage))->sin_port)
|
||||
|
||||
typedef struct tcp_server_ops
|
||||
{
|
||||
void (*start) (int fd, void **opaque,
|
||||
|
@ -37,8 +52,8 @@ extern int tcp_preferred_address_family;
|
|||
void tcp_server_init(int opt_ipv6);
|
||||
void tcp_server_done(void);
|
||||
|
||||
int tcp_connect(const char *hostname, int port, char *errbuf,
|
||||
size_t errbufsize, int timeout);
|
||||
int tcp_connect(const char *hostname, int port, const char *bindaddr,
|
||||
char *errbuf, size_t errbufsize, int timeout);
|
||||
|
||||
typedef void (tcp_server_callback_t)(int fd, void *opaque,
|
||||
struct sockaddr_storage *peer,
|
||||
|
|
11
src/udp.h
11
src/udp.h
|
@ -25,17 +25,6 @@
|
|||
|
||||
#define UDP_FATAL_ERROR ((void *)-1)
|
||||
|
||||
#define IP_AS_V4(storage, f) ((struct sockaddr_in *)&(storage))->sin_##f
|
||||
#define IP_AS_V6(storage, f) ((struct sockaddr_in6 *)&(storage))->sin6_##f
|
||||
#define IP_IN_ADDR(storage) \
|
||||
((storage).ss_family == AF_INET6 ? \
|
||||
&((struct sockaddr_in6 *)&(storage))->sin6_addr : \
|
||||
(void *)&((struct sockaddr_in *)&(storage))->sin_addr)
|
||||
#define IP_PORT(storage) \
|
||||
((storage).ss_family == AF_INET6 ? \
|
||||
((struct sockaddr_in6 *)&(storage))->sin6_port : \
|
||||
((struct sockaddr_in *)&(storage))->sin_port)
|
||||
|
||||
typedef struct udp_connection {
|
||||
char *host;
|
||||
int port;
|
||||
|
|
Loading…
Add table
Reference in a new issue