From 116f99fd4d0fe5397e95174762f9661d52d3cd21 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Thu, 6 Oct 2016 17:35:00 +0200 Subject: [PATCH] Main: use Jumbos when sending to ourselves Use Jumbos when sending and receirver run in one process and communicate through loopback. --- Makefile.in | 7 +-- src/control_socket.cpp | 42 +---------------- src/main.cpp | 74 +++++++++++++++++------------ src/utils/net.c | 104 +++++++++++++++++++++++++++++++++++++++++ src/utils/net.h | 60 ++++++++++++++++++++++++ 5 files changed, 212 insertions(+), 75 deletions(-) create mode 100644 src/utils/net.c create mode 100644 src/utils/net.h diff --git a/Makefile.in b/Makefile.in index 31ac68a5f..cf0982a15 100644 --- a/Makefile.in +++ b/Makefile.in @@ -115,14 +115,15 @@ OBJS = @OBJS@ \ src/crypto/md5.o \ src/crypto/random.o \ src/ihdtv/ihdtv.o \ + src/lib_common.o \ src/module.o \ src/rtsp/rtsp_utils.o \ - src/utils/config_file.o \ - src/utils/list.o \ - src/lib_common.o \ src/ug_runtime_error.o \ src/utils/audio_buffer.o \ + src/utils/config_file.o \ + src/utils/list.o \ src/utils/misc.o \ + src/utils/net.o \ src/utils/packet_counter.o \ src/utils/resource_manager.o \ src/utils/ring_buffer.o \ diff --git a/src/control_socket.cpp b/src/control_socket.cpp index 0481bce19..37269c326 100644 --- a/src/control_socket.cpp +++ b/src/control_socket.cpp @@ -56,6 +56,7 @@ #include "module.h" #include "rtp/net_udp.h" // socket_error #include "tv.h" +#include "utils/net.h" #define DEFAULT_CONTROL_PORT 5054 #define MAX_CLIENTS 16 @@ -66,17 +67,6 @@ typedef const char *sso_val_type; typedef void *sso_val_type; #endif /* WIN32 */ -#ifdef WIN32 -#define CLOSESOCKET closesocket -#else -#define CLOSESOCKET close -#endif - -// MSW does not have the macro defined -#ifndef IN_LOOPBACKNET -#define IN_LOOPBACKNET 127 -#endif - using namespace std; struct client { @@ -610,36 +600,6 @@ static bool parse_msg(char *buffer, int buffer_len, /* out */ char *message, int return ret; } -static bool is_addr_loopback(struct sockaddr_storage *ss) -{ - switch (ss->ss_family) { - case AF_UNIX: - return true; - case AF_INET: - { - struct sockaddr_in *sin = (struct sockaddr_in *) ss; - uint32_t addr = ntohl(sin->sin_addr.s_addr); - if ((addr >> 24) == IN_LOOPBACKNET) { - return true; - } - } - case AF_INET6: - { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *) ss; - if (IN6_IS_ADDR_V4MAPPED(&sin->sin6_addr)) { - uint32_t v4_addr = ntohl(*((uint32_t*)(sin->sin6_addr.s6_addr + 12))); - if ((v4_addr >> 24) == IN_LOOPBACKNET) { - return true; - } - } else { - return IN6_IS_ADDR_LOOPBACK(&sin->sin6_addr); - } - } - default: - return false; - } -} - static struct client *add_client(struct client *clients, int fd) { struct client *new_client = (struct client *) malloc(sizeof(struct client)); diff --git a/src/main.cpp b/src/main.cpp index f26e05aaa..3f5a915c0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,9 +73,11 @@ #include "lib_common.h" #include "messaging.h" #include "module.h" +#include "rtp/rtp.h" #include "rtsp/rtsp_utils.h" #include "ug_runtime_error.h" #include "utils/misc.h" +#include "utils/net.h" #include "utils/wait_obj.h" #include "video.h" #include "video_capture.h" @@ -537,7 +539,7 @@ int main(int argc, char *argv[]) long packet_rate; const char *requested_mcast_if = NULL; - unsigned requested_mtu = 1500; + unsigned requested_mtu = 0; const char *postprocess = NULL; const char *requested_display = "none"; const char *requested_receiver = "::1"; @@ -911,23 +913,6 @@ int main(int argc, char *argv[]) } } - printf("%s", PACKAGE_STRING); -#ifdef GIT_VERSION - printf(" (rev %s)", GIT_VERSION); -#endif - printf("\n"); - printf("Display device : %s\n", requested_display); - printf("Capture device : %s\n", vidcap_params_get_driver(vidcap_params_head)); - printf("Audio capture : %s\n", audio_send); - printf("Audio playback : %s\n", audio_recv); - printf("MTU : %d B\n", requested_mtu); - printf("Video compression: %s\n", requested_compression); - printf("Audio codec : %s\n", get_name_to_audio_codec(get_audio_codec(audio_codec))); - printf("Network protocol : %s\n", video_rxtx::get_long_name(video_protocol)); - printf("Audio FEC : %s\n", requested_audio_fec); - printf("Video FEC : %s\n", requested_video_fec); - printf("\n"); - if (strcmp("none", audio_recv) != 0) { audio_rxtx_mode |= MODE_RECEIVER; } @@ -979,12 +964,13 @@ int main(int argc, char *argv[]) } } - if(should_export) { - if(!enable_export(export_opts)) { - fprintf(stderr, "Export initialization failed.\n"); - return EXIT_FAILURE; + if (requested_mtu == 0) { + if (is_host_loopback(requested_receiver) && video_rx_port == video_tx_port && + audio_rx_port == audio_tx_port) { + requested_mtu = min(RTP_MAX_MTU, 65536); + } else { + requested_mtu = 1500; } - video_exporter = video_export_init(export_dir); } if (bitrate != RATE_AUTO && bitrate != RATE_UNLIMITED) { @@ -997,14 +983,7 @@ int main(int argc, char *argv[]) requested_receiver = argv[0]; } - if (control_port != -1) { - if (control_init(control_port, connection_type, &control, &uv.root_module) != 0) { - fprintf(stderr, "Error: Unable to initialize remote control!\n"); - return EXIT_FAIL_CONTROL_SOCK; - } - } - - if(!audio_host) { + if (!audio_host) { audio_host = requested_receiver; } #ifdef HAVE_RTSP_SERVER @@ -1013,6 +992,39 @@ int main(int argc, char *argv[]) isStd = TRUE; } #endif + + printf("%s", PACKAGE_STRING); +#ifdef GIT_VERSION + printf(" (rev %s)", GIT_VERSION); +#endif + printf("\n\n"); + printf("Display device : %s\n", requested_display); + printf("Capture device : %s\n", vidcap_params_get_driver(vidcap_params_head)); + printf("Audio capture : %s\n", audio_send); + printf("Audio playback : %s\n", audio_recv); + printf("MTU : %d B\n", requested_mtu); + printf("Video compression: %s\n", requested_compression); + printf("Audio codec : %s\n", get_name_to_audio_codec(get_audio_codec(audio_codec))); + printf("Network protocol : %s\n", video_rxtx::get_long_name(video_protocol)); + printf("Audio FEC : %s\n", requested_audio_fec); + printf("Video FEC : %s\n", requested_video_fec); + printf("\n"); + + if(should_export) { + if(!enable_export(export_opts)) { + fprintf(stderr, "Export initialization failed.\n"); + return EXIT_FAILURE; + } + video_exporter = video_export_init(export_dir); + } + + if (control_port != -1) { + if (control_init(control_port, connection_type, &control, &uv.root_module) != 0) { + fprintf(stderr, "Error: Unable to initialize remote control!\n"); + return EXIT_FAIL_CONTROL_SOCK; + } + } + uv.audio = audio_cfg_init (&uv.root_module, audio_host, audio_rx_port, audio_tx_port, audio_send, audio_recv, jack_cfg, requested_audio_fec, requested_encryption, diff --git a/src/utils/net.c b/src/utils/net.c new file mode 100644 index 000000000..af9dfe541 --- /dev/null +++ b/src/utils/net.c @@ -0,0 +1,104 @@ +/** + * @file utils/net.c + * @author Martin Pulec + */ +/* + * Copyright (c) 2016 CESNET z.s.p.o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#include "config_unix.h" +#include "config_win32.h" +#endif + +#include "utils/net.h" + +#include "debug.h" + +// MSW does not have the macro defined +#ifndef IN_LOOPBACKNET +#define IN_LOOPBACKNET 127 +#endif + +bool is_addr_loopback(struct sockaddr_storage *ss) +{ + switch (ss->ss_family) { + case AF_UNIX: + return true; + case AF_INET: + { + struct sockaddr_in *sin = (struct sockaddr_in *) ss; + uint32_t addr = ntohl(sin->sin_addr.s_addr); + if ((addr >> 24) == IN_LOOPBACKNET) { + return true; + } + } + case AF_INET6: + { + struct sockaddr_in6 *sin = (struct sockaddr_in6 *) ss; + if (IN6_IS_ADDR_V4MAPPED(&sin->sin6_addr)) { + uint32_t v4_addr = ntohl(*((uint32_t*)(sin->sin6_addr.s6_addr + 12))); + if ((v4_addr >> 24) == IN_LOOPBACKNET) { + return true; + } + } else { + return IN6_IS_ADDR_LOOPBACK(&sin->sin6_addr); + } + } + default: + return false; + } +} + +bool is_host_loopback(const char *hostname) +{ + int gai_err; + struct addrinfo hints, *ai; + bool ret; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ((gai_err = getaddrinfo(hostname, NULL, &hints, &ai))) { + error_msg("getaddrinfo: %s: %s\n", hostname, + gai_strerror(gai_err)); + return false; + } + + ret = is_addr_loopback((struct sockaddr_storage *) ai->ai_addr); + freeaddrinfo(ai); + + return ret; +} + diff --git a/src/utils/net.h b/src/utils/net.h new file mode 100644 index 000000000..def7e7c85 --- /dev/null +++ b/src/utils/net.h @@ -0,0 +1,60 @@ +/** + * @file utils/net.h + * @author Martin Pulec + */ +/* + * Copyright (c) 2016 CESNET z.s.p.o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UTILS_NET_H_ +#define UTILS_NET_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct sockaddr_storage; +bool is_addr_loopback(struct sockaddr_storage *ss); +bool is_host_loopback(const char *hostname); + +#ifdef WIN32 +#define CLOSESOCKET closesocket +#else +#define CLOSESOCKET close +#endif + +#ifdef __cplusplus +} +#endif + +#endif// UTILS_NET_H_ +