<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Great comments. Thank you. I’ll get on it. And next time I’ll try to squash all three files atm.c, amt.h and Makefile.am into a single patch since they need to be applied together.<div class="">Wayne.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 18, 2019, at 12:34 PM, Tristan Matthews <<a href="mailto:tmatth@videolan.org" class="">tmatth@videolan.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Hi,</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">On Thu, Jan 17, 2019 at 6:41 AM Wayne Brassem <</span><a href="mailto:wbrassem@rogers.com" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">wbrassem@rogers.com</a><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">> wrote:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class="">Addressing items raised in <a href="https://mailman.videolan.org/pipermail/vlc-devel/2018-November/121776.html" class="">https://mailman.videolan.org/pipermail/vlc-devel/2018-November/121776.html</a> and added FQDN support to the AMT code.<br class="">AMT stands for Automatic Multicast Tunnelling and allow the user to receive multicast streams over an non-multicast enabled network by tunnelling through an AMT relay.<br class=""><br class="">From 91ef0bbc4b43eceaa3aea6cb2710232370a67ec8 Mon Sep 17 00:00:00 2001<br class="">From: Wayne Brassem <<a href="mailto:wbrassem@rogers.com" class="">wbrassem@rogers.com</a>><br class="">Date: Mon, 14 Jan 2019 18:25:02 -0500<br class="">Subject: [PATCH 1/3] Addressed items in original AMT code submission and added<br class="">FQDN support<br class=""><br class="">---<br class="">modules/access/Makefile.am | 4 ++++<br class="">1 file changed, 4 insertions(+)<br class=""><br class="">diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am<br class="">index c56cb8fe3a..792c6efb04 100644<br class="">--- a/modules/access/Makefile.am<br class="">+++ b/modules/access/Makefile.am<br class="">@@ -373,6 +373,10 @@ libudp_plugin_la_SOURCES = access/udp.c<br class="">libudp_plugin_la_LIBADD = $(SOCKET_LIBS)<br class="">access_LTLIBRARIES += <a href="http://libudp_plugin.la" class="">libudp_plugin.la</a><br class=""><br class="">+libamt_plugin_la_SOURCES = access/amt.c access/amt.h<br class="">+libamt_plugin_la_LIBADD = $(SOCKET_LIBS)<br class="">+access_LTLIBRARIES += <a href="http://libamt_plugin.la" class="">libamt_plugin.la</a><br class="">+<br class="">libunc_plugin_la_SOURCES = access/unc.c access/smb_common.h<br class="">libunc_plugin_la_LIBADD = -lmpr -lnetapi32<br class="">if HAVE_WIN32<br class="">--<br class="">2.17.2 (Apple Git-113)<br class=""><br class="">From 91c757f47445095ac8de8574a8b216cca3043898 Mon Sep 17 00:00:00 2001<br class="">From: Wayne Brassem <<a href="mailto:wbrassem@rogers.com" class="">wbrassem@rogers.com</a>><br class="">Date: Mon, 14 Jan 2019 18:47:06 -0500<br class="">Subject: [PATCH 2/3] Addressed concerns in first submissions and added support<br class="">for FQDN<br class=""><br class="">---<br class="">modules/access/amt.c | 1208 ++++++++++++++++++++++++++++++++++++++++++<br class="">1 file changed, 1208 insertions(+)<br class="">create mode 100644 modules/access/amt.c<br class=""><br class="">diff --git a/modules/access/amt.c b/modules/access/amt.c<br class="">new file mode 100644<br class="">index 0000000000..df023be9dc<br class="">--- /dev/null<br class="">+++ b/modules/access/amt.c<br class="">@@ -0,0 +1,1208 @@<br class="">+/**<br class="">+ * @file amt.c<br class="">+ * @brief Automatic Multicast Tunneling Protocol (AMT) file for VLC media player<br class="">+ * Allows multicast streaming when not in a multicast-enabled network<br class="">+ * Currently IPv4 is supported, but IPv6 is not yet.<br class="">+ *<br class="">+ * Copyright (C) 2018 VLC authors and VideoLAN<br class="">+ * Copyright (c) Juniper Networks, Inc., 2018. All rights reserved.<br class="">+ *<br class="">+ * Authors: Christophe Massiot <<a href="mailto:massiot@via.ecp.fr" class="">massiot@via.ecp.fr</a>> - original UDP code<br class="">+ * Tristan Leteurtre <<a href="mailto:tooney@via.ecp.fr" class="">tooney@via.ecp.fr</a>> - original UDP code<br class="">+ * Laurent Aimar <<a href="mailto:fenrir@via.ecp.fr" class="">fenrir@via.ecp.fr</a>> - original UDP code<br class="">+ * Jean-Paul Saman <jpsaman #_at_# m2x dot nl> - original UDP code<br class="">+ * Remi Denis-Courmont - original UDP code<br class="">+ * Natalie Landsberg <a href="mailto:natalie.landsberg97@gmail.com" class="">natalie.landsberg97@gmail.com</a> - AMT support<br class="">+ * Wayne Brassem <<a href="mailto:wbrassem@rogers.com" class="">wbrassem@rogers.com</a>> - Added FQDN support<br class="">+ *<br class="">+ * This code is licensed to you under the GNU Lesser General Public License<br class="">+ * version 2.1 or later. You may not use this code except in compliance with<br class="">+ * the GNU Lesser General Public License.<br class="">+ * This code is not an official Juniper product.<br class="">+ *<br class="">+ * This library is free software; you can redistribute it and/or<br class="">+ * modify it under the terms of the GNU Lesser General Public License<br class="">+ * as published by the Free Software Foundation; either version 2.1<br class="">+ * of the License, or (at your option) any later version.<br class="">+ *<br class="">+ * This library is distributed in the hope that it will be useful,<br class="">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br class="">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br class="">+ * GNU Lesser General Public License for more details.<br class="">+ *<br class="">+ * You should have received a copy of the GNU Lesser General Public<br class="">+ * License along with this library; if not, write to the Free Software<br class="">+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br class="">+ ****************************************************************************/<br class="">+#ifdef HAVE_CONFIG_H<br class="">+# include "config.h"<br class="">+#endif<br class="">+<br class="">+#include <errno.h><br class="">+#include <ctype.h><br class="">+#ifdef HAVE_ARPA_INET_H<br class="">+# include <arpa/inet.h><br class="">+#endif<br class="">+<br class="">+#ifdef HAVE_SYS_SELECT_H<br class="">+# include <sys/select.h><br class="">+#endif<br class="">+<br class="">+#ifdef HAVE_SYS_SOCKET_H<br class="">+# include <sys/socket.h><br class="">+#endif<br class="">+<br class="">+#include <vlc_common.h><br class="">+#include <vlc_demux.h><br class="">+#include <vlc_plugin.h><br class="">+#include <vlc_access.h><br class="">+#include <vlc_network.h><br class="">+#include <vlc_block.h><br class="">+#include <vlc_interrupt.h><br class="">+#include <vlc_url.h><br class="">+<br class="">+#include "amt.h"<br class="">+<br class="">+#ifdef HAVE_POLL<br class="">+ #include <poll.h><br class="">+#endif<br class="">+#ifdef HAVE_SYS_UIO_H<br class="">+ #include <sys/uio.h><br class="">+#endif<br class="">+<br class="">+#define BUFFER_TEXT N_("Receive buffer")<br class="">+#define BUFFER_LONGTEXT N_("AMT receive buffer size (bytes)" )<br class="">+#define TIMEOUT_TEXT N_("Native multicast timeout (sec)")<br class="">+#define AMT_TIMEOUT_TEXT N_("AMT timeout (sec)")<br class="">+#define AMT_RELAY_ADDRESS N_("AMT relay (IP address or FQDN)")<br class="">+#define AMT_RELAY_ADDR_LONG N_("AMT relay anycast address, or specify the relay you want by address or fully qualified domain name")<br class="">+#define AMT_DEFAULT_RELAY N_("<a href="http://amt-relay.m2icast.net" class="">amt-relay.m2icast.net</a>")<br class="">+<br class="">+static int Open (vlc_object_t *);<br class="">+static void Close (vlc_object_t *);<br class="">+<br class="">+/* memory leak and packet counters */<br class="">+static int mem_alloc, packet;<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">This information should be stored in the access_sys_t struct instead</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">of static globals, or just deleted since it seems to be for debugging</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">only.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+vlc_module_begin ()<br class="">+ set_shortname( N_("AMT" ) )<br class="">+ set_description( N_("AMT input") )<br class="">+ set_category( CAT_INPUT )<br class="">+ set_subcategory( SUBCAT_INPUT_ACCESS )<br class="">+<br class="">+ add_integer( "amt-timeout", 5, AMT_TIMEOUT_TEXT, NULL, true )<br class="">+ add_integer( "amt-native-timeout", 3, TIMEOUT_TEXT, NULL, true )<br class="">+ add_string( "amt-relay", AMT_DEFAULT_RELAY, AMT_RELAY_ADDRESS, AMT_RELAY_ADDR_LONG, true )<br class="">+<br class="">+ set_capability( "access", 0 )<br class="">+ add_shortcut( "amt" )<br class="">+<br class="">+ set_callbacks( Open, Close )<br class="">+vlc_module_end ()<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Control:<br class="">+ *****************************************************************************/<br class="">+static int Control( stream_t *p_access, int i_query, va_list args )<br class="">+{<br class="">+ bool *pb_bool;<br class="">+<br class="">+/* msg_Dbg( p_access, "Control: mem_alloc = %d", mem_alloc); */<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">This can be deleted.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+ switch( i_query )<br class="">+ {<br class="">+ case STREAM_CAN_SEEK:<br class="">+ case STREAM_CAN_FASTSEEK:<br class="">+ case STREAM_CAN_PAUSE:<br class="">+ case STREAM_CAN_CONTROL_PACE:<br class="">+ pb_bool = va_arg( args, bool * );<br class="">+ *pb_bool = false;<br class="">+ break;<br class="">+<br class="">+ case STREAM_GET_PTS_DELAY:<br class="">+ *va_arg( args, vlc_tick_t * ) =<br class="">+ VLC_TICK_FROM_MS(var_InheritInteger( p_access, "network-caching" ));<br class="">+ break;<br class="">+<br class="">+ default:<br class="">+ return VLC_EGENERIC;<br class="">+ }<br class="">+ return VLC_SUCCESS;<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * BlockUDP:<br class="">+ *****************************************************************************/<br class="">+static block_t *BlockUDP(stream_t *p_access, bool *restrict eof)<br class="">+{<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+ ssize_t len;<br class="">+<br class="">+ block_t *pkt = block_Alloc(sys->mtu);<br class="">+ char *amtpkt = malloc( DEFAULT_MTU );<br class="">+<br class="">+ packet++;<br class="">+ mem_alloc++; /* do not include *pkt in memory alloc count because it gets freed by caller */<br class="">+<br class="">+/* msg_Dbg( p_access, "BlockUDP Enter: packet = %d, mem_alloc = %d, pkt = %016x, amtpkt = %016x", packet, mem_alloc, (int) pkt, (int) amtpkt); */<br class="">+<br class="">+ if (unlikely(pkt == NULL))<br class="">+ { /* OOM - dequeue and discard one packet */<br class="">+ char dummy;<br class="">+ recv(sys->fd, &dummy, 1, 0);<br class="">+ return NULL;<br class="">+ }<br class="">+<br class="">+ if (unlikely(amtpkt == NULL))<br class="">+ goto error;<br class="">+<br class="">+ struct iovec iov = {<br class="">+ .iov_base = pkt->p_buffer,<br class="">+ .iov_len = sys->mtu,<br class="">+ };<br class="">+ struct msghdr msg = {<br class="">+ .msg_iov = &iov,<br class="">+ .msg_iovlen = 1,<br class="">+#ifdef __linux__<br class="">+ .msg_flags = MSG_TRUNC,<br class="">+#endif<br class="">+ };<br class="">+<br class="">+ struct pollfd ufd[1];<br class="">+<br class="">+ if( sys->tryAMT )<br class="">+ ufd[0].fd = sys->sAMT;<br class="">+ else<br class="">+ ufd[0].fd = sys->fd;<br class="">+ ufd[0].events = POLLIN;<br class="">+<br class="">+ switch (vlc_poll_i11e(ufd, 1, sys->timeout))<br class="">+ {<br class="">+ case 0:<br class="">+ msg_Err(p_access, "native multicast receive time-out, packet = %d", packet);<br class="">+ net_Close( sys->fd );<br class="">+ if( !sys->tryAMT )<br class="">+ {<br class="">+ if( open_amt_tunnel( p_access ) == false )<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">You can just do if (!open_amt_tunnel( p_access ))</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+ goto error;<br class="">+ break;<br class="">+ }<br class="">+ else<br class="">+ {<br class="">+ msg_Err(p_access, "AMT receive time-out");<br class="">+ *eof = true;<br class="">+ }<br class="">+ /* fall through */<br class="">+ case -1:<br class="">+/* msg_Dbg(p_access, "Exiting vlc_poll switch, packet = %d", packet); */<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ if( sys->tryAMT )<br class="">+ {<br class="">+ len = recv( sys->sAMT, amtpkt, DEFAULT_MTU, 0 );<br class="">+<br class="">+ if( len < 0 || amtpkt[0] != AMT_MULT_DATA )<br class="">+ goto error;<br class="">+<br class="">+ ssize_t shift = IP_HDR_LEN + UDP_HDR_LEN + AMT_HDR_LEN;<br class="">+<br class="">+ if( len < shift )<br class="">+ {<br class="">+ msg_Err(p_access, "%zd bytes packet truncated (MTU was %zu)",<br class="">+ len, sys->mtu);<br class="">+ pkt->i_flags |= BLOCK_FLAG_CORRUPTED;<br class="">+ sys->mtu = len;<br class="">+ } else {<br class="">+ len -= shift;<br class="">+ }<br class="">+<br class="">+ memcpy( pkt->p_buffer, &amtpkt[shift], len );<br class="">+ }<br class="">+ else<br class="">+ len = recvmsg(sys->fd, &msg, 0);<br class="">+<br class="">+#ifdef MSG_TRUNC<br class="">+ if (msg.msg_flags & MSG_TRUNC)<br class="">+ {<br class="">+ msg_Err(p_access, "%zd bytes packet truncated (MTU was %zu)",<br class="">+ len, sys->mtu);<br class="">+ pkt->i_flags |= BLOCK_FLAG_CORRUPTED;<br class="">+ sys->mtu = len;<br class="">+ }<br class="">+ else<br class="">+#endif<br class="">+ pkt->i_buffer = len;<br class="">+<br class="">+ free( amtpkt );<br class="">+ mem_alloc--;<br class="">+<br class="">+/* msg_Dbg( p_access, "BlockUDP: Main Exit: mem_alloc = %d, packet = %d", mem_alloc, packet); */<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">This can be deleted.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+ return pkt;<br class="">+<br class="">+error:<br class="">+ free( amtpkt );<br class="">+ mem_alloc--;<br class="">+<br class="">+/* msg_Dbg( p_access, "BlockUDP: Error Exit: mem_alloc = %d, packet = %d", mem_alloc, packet); */<br class="">+<br class="">+ return NULL;<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Open: open the socket<br class="">+ *****************************************************************************/<br class="">+static int Open( vlc_object_t *p_this )<br class="">+{<br class="">+ stream_t *p_access = (stream_t*) p_this;<br class="">+ access_sys_t *sys = NULL;<br class="">+ struct addrinfo hints, *serverinfo = NULL;<br class="">+ struct sockaddr_in *server_addr;<br class="">+ char *psz_name = NULL, *saveptr, ip_buffer[INET_ADDRSTRLEN];<br class="">+ int i_bind_port = 1234, i_server_port = 0, VLC_ret = VLC_SUCCESS, res;<br class="">+ vlc_url_t url;<br class="">+<br class="">+ mem_alloc = 0; packet = 0;<br class="">+/* msg_Dbg( p_access, "Open: Enter: mem_alloc = %d", mem_alloc);<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">This can be deleted.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+ if( p_access->b_preparsing )<br class="">+ {<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ sys = vlc_obj_malloc( p_this, sizeof( *sys ) );<br class="">+ mem_alloc++;<br class="">+<br class="">+ if( unlikely( sys == NULL ) )<br class="">+ {<br class="">+ VLC_ret = VLC_ENOMEM;<br class="">+ goto cleanup;<br class="">+ }<br class="">+ else<br class="">+ memset( sys, 0, sizeof( *sys ));<br class="">+<br class="">+ p_access->p_sys = sys;<br class="">+<br class="">+ /* Set up p_access */<br class="">+ ACCESS_SET_CALLBACKS( NULL, BlockUDP, Control, NULL );<br class="">+<br class="">+ if( !p_access->psz_location )<br class="">+ {<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ psz_name = strdup( p_access->psz_location );<br class="">+ mem_alloc++;<br class="">+ if ( unlikely( psz_name == NULL ) )<br class="">+ {<br class="">+ VLC_ret = VLC_ENOMEM;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ /* Parse psz_name syntax :<br class="">+ * [serveraddr[:serverport]][@[bindaddr]:[bindport]] */<br class="">+ if( vlc_UrlParse( &url, p_access->psz_url ) != 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Invalid URL" );<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+ mem_alloc++;<br class="">+<br class="">+ if( url.i_port > 0 )<br class="">+ i_bind_port = url.i_port;<br class="">+<br class="">+ msg_Dbg( p_access, "opening multicast: %s:%d local=%s:%d",<br class="">+ url.psz_host, i_server_port, url.psz_path, i_bind_port );<br class="">+<br class="">+ if( ( url.psz_host == NULL ) || ( strlen( url.psz_host ) == 0 ) )<br class="">+ {<br class="">+ msg_Err( p_access, "Please enter a group and/or source address." );<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ memset( &hints, 0, sizeof( hints ));<br class="">+ hints.ai_family = AF_INET; /* Setting to AF_UNSPEC accepts both IPv4 and IPv6 */<br class="">+ hints.ai_socktype = SOCK_DGRAM;<br class="">+<br class="">+ /* retrieve list of multicast addresses matching the multicast group identifier */<br class="">+ res = vlc_getaddrinfo( url.psz_host, AMT_PORT, &hints, &serverinfo );<br class="">+ mem_alloc++;<br class="">+<br class="">+ if( res )<br class="">+ {<br class="">+ msg_Err( p_access, "Could not find multicast group %s, reason: %s", url.psz_host, gai_strerror(res) );<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ /* Convert binary socket address to string */<br class="">+ server_addr = (struct sockaddr_in *) serverinfo->ai_addr;<br class="">+ inet_ntop(AF_INET, &(server_addr->sin_addr), ip_buffer, INET_ADDRSTRLEN);<br class="">+<br class="">+ /* release the allocated memory */<br class="">+ freeaddrinfo(serverinfo);<br class="">+ serverinfo = NULL;<br class="">+ mem_alloc--;<br class="">+<br class="">+ msg_Dbg( p_access, "Setting multicast group address to %s", ip_buffer);<br class="">+<br class="">+ sys->mcastGroup = strdup( ip_buffer );<br class="">+ mem_alloc++;<br class="">+ if( unlikely( sys->mcastGroup == NULL ) )<br class="">+ {<br class="">+ VLC_ret = VLC_ENOMEM;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ /* The following uses strtok_r() because strtok() is not thread safe */<br class="">+ sys->srcAddr = strdup( strtok_r( psz_name, "@", &saveptr ) );<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">You may want to do this in 2 steps to check that strok_r worked as expected.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+ mem_alloc++;<br class="">+<br class="">+ if( unlikely( sys->srcAddr == NULL ) )<br class="">+ {<br class="">+ VLC_ret = VLC_ENOMEM;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ /* if strings are equal then no multicast source has been specified */<br class="">+ if( strcmp( url.psz_host, sys->srcAddr ) == 0 )<br class="">+ {<br class="">+ strcpy(sys->srcAddr, "0.0.0.0");<br class="">+ msg_Dbg( p_access, "No multicast source address specified, trying ASM...");<br class="">+ }<br class="">+<br class="">+ /* retrieve list of source addresses matching the multicast source identifier */<br class="">+ res = vlc_getaddrinfo( sys->srcAddr, AMT_PORT, &hints, &serverinfo );<br class="">+ mem_alloc++;<br class="">+<br class="">+ if( res )<br class="">+ {<br class="">+ msg_Err( p_access, "Could not find multicast source %s, reason: %s", sys->srcAddr, gai_strerror(res) );<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ /* Convert binary socket address to string */<br class="">+ server_addr = (struct sockaddr_in *) serverinfo->ai_addr;<br class="">+ inet_ntop(AF_INET, &(server_addr->sin_addr), ip_buffer, INET_ADDRSTRLEN);<br class="">+<br class="">+ msg_Dbg( p_access, "Setting multicast source address to %s", ip_buffer);<br class="">+<br class="">+ /* free the original source address buffer (IP or FQDN) and assign it just the IP address */<br class="">+ free(sys->srcAddr);<br class="">+ sys->srcAddr = strdup( ip_buffer );<br class="">+<br class="">+ if( unlikely( sys->srcAddr == NULL ) )<br class="">+ {<br class="">+ VLC_ret = VLC_ENOMEM;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ if( strcmp( url.psz_host, sys->srcAddr ) == 0 )<br class="">+ strcpy(sys->srcAddr, "0.0.0.0");<br class="">+<br class="">+ sys->relayAddr = var_InheritString( p_access, "amt-relay" );<br class="">+<br class="">+ if( unlikely(sys->relayAddr == NULL ) )<br class="">+ {<br class="">+ msg_Err( p_access, "No relay anycast or unicast address specified." );<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ msg_Dbg( p_access, "Addresses: mcastGroup: %s srcAddr: %s relayAddr: %s", \<br class="">+ sys->mcastGroup, sys->srcAddr, sys->relayAddr);<br class="">+<br class="">+ sys->fd = net_OpenDgram( p_access, sys->mcastGroup, i_bind_port,<br class="">+ sys->srcAddr, i_server_port, IPPROTO_UDP );<br class="">+ if( sys->fd == -1 )<br class="">+ {<br class="">+ msg_Err( p_access, "cannot open socket" );<br class="">+ VLC_ret = VLC_EGENERIC;<br class="">+ goto cleanup;<br class="">+ }<br class="">+<br class="">+ sys->mtu = 7 * 188;<br class="">+<br class="">+ sys->timeout = var_InheritInteger( p_access, "amt-native-timeout");<br class="">+ if( sys->timeout > 0)<br class="">+ sys->timeout *= 1000;<br class="">+<br class="">+ sys->amtTimeout = var_InheritInteger( p_access, "amt-timeout" );<br class="">+ if( sys->amtTimeout > 0)<br class="">+ sys->amtTimeout *= 1000;<br class="">+<br class="">+ sys->tryAMT = false;<br class="">+ sys->threadReady = false;<br class="">+<br class="">+cleanup: /* fall through */<br class="">+<br class="">+ /* release the allocated memory */<br class="">+ free( psz_name );<br class="">+ vlc_UrlClean( &url );<br class="">+ freeaddrinfo( serverinfo );<br class="">+<br class="">+ mem_alloc-=3;<br class="">+<br class="">+ /* if an error occurred free the memory */<br class="">+ if ( VLC_ret != VLC_SUCCESS )<br class="">+ {<br class="">+ free( sys->mcastGroup );<br class="">+ free( sys->srcAddr );<br class="">+ vlc_obj_free( p_this, sys );<br class="">+ mem_alloc -= 3;<br class="">+ }<br class="">+<br class="">+/* msg_Dbg( p_access, "Open: Exit: mem_alloc = %d", mem_alloc); */<br class="">+<br class="">+ return VLC_ret;<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Close: free unused data structures<br class="">+ *****************************************************************************/<br class="">+static void Close( vlc_object_t *p_this )<br class="">+{<br class="">+ char relay_ip[INET_ADDRSTRLEN];<br class="">+ stream_t *p_access = (stream_t*)p_this;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ inet_ntop(AF_INET, &(sys->relayAddrDisco.sin_addr), relay_ip, INET_ADDRSTRLEN);<br class="">+<br class="">+ if( strcmp(sys->srcAddr, "0.0.0.0") == 0 )<br class="">+ amt_leaveASM_group( p_access );<br class="">+ else<br class="">+ amt_leaveSSM_group( p_access );<br class="">+ amt_send_mem_update( p_access, relay_ip, true );<br class="">+<br class="">+ if( sys->threadReady )<br class="">+ {<br class="">+ sys->threadReady = false;<br class="">+ vlc_cancel( sys->updateThread );<br class="">+ vlc_join( sys->updateThread, NULL );<br class="">+ }<br class="">+<br class="">+ free( sys->mcastGroup );<br class="">+ free( sys->srcAddr );<br class="">+ vlc_obj_free( p_this, sys );<br class="">+<br class="">+ mem_alloc -= 3;<br class="">+ if (mem_alloc)<br class="">+ msg_Err( p_access, "Closing AMT plugin, mem_alloc = %d", mem_alloc);<br class="">+ else<br class="">+ msg_Dbg( p_access, "Closing AMT plugin, mem_alloc = %d", mem_alloc);<br class="">+<br class="">+ net_Close( sys->fd );<br class="">+ net_Close( sys->sAMT );<br class="">+ net_Close( sys->sQuery );<br class="">+}<br class="">+<br class="">+<br class="">+bool open_amt_tunnel( stream_t *p_access )<br class="">+{<br class="">+ struct addrinfo hints, *serverinfo, *server;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ memset( &hints, 0, sizeof( hints ));<br class="">+ hints.ai_family = AF_INET; /* Setting to AF_UNSPEC accepts both IPv4 and IPv6 */<br class="">+ hints.ai_socktype = SOCK_DGRAM;<br class="">+<br class="">+/* msg_Dbg( p_access, "open_amt_tunnel: Enter: mem_alloc = %d", mem_alloc); */<br class="">+<br class="">+ msg_Dbg( p_access, "Attempting AMT to %s...", sys->relayAddr);<br class="">+ sys->tryAMT = true;<br class="">+<br class="">+ /* retrieve list of addresses matching the AMT relay */<br class="">+ int res = vlc_getaddrinfo( sys->relayAddr, AMT_PORT, &hints, &serverinfo );<br class="">+ mem_alloc++;<br class="">+<br class="">+ if( res )<br class="">+ {<br class="">+ msg_Err( p_access, "Could not find relay %s, reason: %s", sys->relayAddr, gai_strerror(res) );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ /* iterate through the list of sockets to find one the works */<br class="">+ for (server = serverinfo; server != NULL; server = server->ai_next)<br class="">+ {<br class="">+ struct sockaddr_in *server_addr = (struct sockaddr_in *) server->ai_addr;<br class="">+ char relay_ip[INET_ADDRSTRLEN];<br class="">+<br class="">+ inet_ntop(AF_INET, &(server_addr->sin_addr), relay_ip, INET_ADDRSTRLEN);<br class="">+<br class="">+ msg_Dbg( p_access, "Trying AMT Server: %s", relay_ip);<br class="">+<br class="">+ sys->relayAddrDisco.sin_addr = server_addr->sin_addr;<br class="">+<br class="">+ /* if can't open socket try any others in list */<br class="">+ if( amt_sockets_init( p_access ) != 0 )<br class="">+ msg_Err( p_access, "Error initializing socket to %s", relay_ip );<br class="">+<br class="">+ /* Otherwise negotiate with AMT relay and confirm you can pull a UDP packet */<br class="">+ else<br class="">+ {<br class="">+ amt_send_relay_discovery_msg( p_access, relay_ip );<br class="">+ msg_Dbg( p_access, "Sent relay AMT discovery message to %s", relay_ip );<br class="">+<br class="">+ if( !amt_rcv_relay_adv( p_access ) )<br class="">+ {<br class="">+ msg_Err( p_access, "Error receiving AMT relay advertisement msg from %s, skipping", relay_ip );<br class="">+ goto error;<br class="">+ }<br class="">+ msg_Dbg( p_access, "Received AMT relay advertisement from %s", relay_ip );<br class="">+<br class="">+ amt_send_relay_request( p_access, relay_ip );<br class="">+ msg_Dbg( p_access, "Sent AMT relay request message to %s", relay_ip );<br class="">+<br class="">+ if( !amt_rcv_relay_mem_query( p_access ) )<br class="">+ {<br class="">+ msg_Err( p_access, "Could not receive AMT relay membership query from %s, reason: %s", relay_ip, vlc_strerror(errno));<br class="">+ goto error;<br class="">+ }<br class="">+ msg_Dbg( p_access, "Received AMT relay membership query from %s", relay_ip );<br class="">+<br class="">+ if( strcmp(sys->srcAddr, "") == 0 )<br class="">+ {<br class="">+ if( amt_joinASM_group( p_access ) != 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Error joining ASM %s", vlc_strerror(errno) );<br class="">+ goto error;<br class="">+ }<br class="">+ msg_Dbg( p_access, "Joined ASM group: %s", sys->mcastGroup );<br class="">+ }<br class="">+ else {<br class="">+ if( amt_joinSSM_group( p_access ) != 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Error joining SSM %s", vlc_strerror(errno) );<br class="">+ goto error;<br class="">+ }<br class="">+ msg_Dbg( p_access, "Joined SSM src: %s group: %s", sys->srcAddr, sys->mcastGroup );<br class="">+ }<br class="">+<br class="">+ bool eof=false;<br class="">+ block_t *pkt;<br class="">+<br class="">+ /* Confirm that you can pull a UDP packet from the socket */<br class="">+ if ( (pkt = BlockUDP( p_access, &eof )) == false )<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">A ! here would be sufficient, checking that a pointer == false is not</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">really idiomatic.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+ msg_Dbg( p_access, "Unable to receive UDP packet from AMT relay %s for multicast group %s, skipping...", relay_ip, sys->mcastGroup );<br class="">+ else<br class="">+ {<br class="">+ block_Release(pkt); /* don't decrement mem_alloc since pkt not included in count */<br class="">+ msg_Dbg( p_access, "Got UDP packet from multicast group %s via AMT relay %s, continuing...", sys->mcastGroup, relay_ip );<br class="">+ break; /* found an active server sending UDP packets, so exit loop */<br class="">+ }<br class="">+ }<br class="">+ }<br class="">+<br class="">+ /* if server is NULL then no AMT relay is responding */<br class="">+ if (server == NULL)<br class="">+ {<br class="">+ msg_Err( p_access, "No AMT servers responding" );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ sys->queryTime = vlc_tick_now() / CLOCK_FREQ;<br class="">+<br class="">+ /* release the allocated memory */<br class="">+ freeaddrinfo(serverinfo);<br class="">+ mem_alloc--;<br class="">+<br class="">+/* msg_Dbg( p_access, "open_amt_tunnel: Exit: mem_alloc = %d", mem_alloc); */<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">This can be deleted.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+ return true;<br class="">+<br class="">+error:<br class="">+ /* release the allocated memory */<br class="">+ freeaddrinfo(serverinfo);<br class="">+ mem_alloc--;<br class="">+<br class="">+/* msg_Dbg( p_access, "open_amt_tunnel: Exit: mem_alloc = %d", mem_alloc); */<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">This can be deleted.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+ sys->threadReady = false;<br class="">+ return false;<br class="">+}<br class="">+/**<br class="">+ * Calculate checksum<br class="">+ * */<br class="">+unsigned short getChecksum( unsigned short *buffer, int nLen )<br class="">+{<br class="">+ int nleft = nLen;<br class="">+ int sum = 0;<br class="">+ unsigned short *w = buffer;<br class="">+ unsigned short answer = 0;<br class="">+<br class="">+ while (nleft > 1)<br class="">+ {<br class="">+ sum += *w++;<br class="">+ nleft -= 2;<br class="">+ }<br class="">+ if (nleft == 1)<br class="">+ {<br class="">+ *(unsigned char*)(&answer) = *(unsigned char*)w;<br class="">+ sum += answer;<br class="">+ }<br class="">+ sum = (sum >> 16) + (sum & 0xffff);<br class="">+ answer = ~sum;<br class="">+ return (answer);<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Make IGMP Membership report<br class="">+ * */<br class="">+void makeReport( amt_igmpv3_membership_report_t *mr )<br class="">+{<br class="">+ mr->type = AMT_IGMPV3_MEMBERSHIP_REPORT_TYPEID;<br class="">+ mr->resv = 0;<br class="">+ mr->checksum = 0;<br class="">+ mr->resv2 = 0;<br class="">+ mr->nGroupRecord = htons(1);<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Make IP header<br class="">+ * */<br class="">+void makeIPHeader( amt_ip_alert_t *p_ipHead )<br class="">+{<br class="">+ p_ipHead->ver_ihl = 0x46;<br class="">+ p_ipHead->tos = 0xc0;<br class="">+ p_ipHead->tot_len = htons( IP_HDR_IGMP_LEN + IGMP_REPORT_LEN );<br class="">+ p_ipHead->id = 0x00;<br class="">+ p_ipHead->frag_off = 0x0000;<br class="">+ p_ipHead->ttl = 0x01;<br class="">+ p_ipHead->protocol = 0x02;<br class="">+ p_ipHead->check = 0;<br class="">+ p_ipHead->srcAddr = INADDR_ANY;<br class="">+ p_ipHead->options = 0x0000;<br class="">+}<br class="">+<br class="">+/** Create relay discovery socket, query socket, UDP socket and<br class="">+ * fills in relay anycast address for discovery<br class="">+ * return 0 if successful, -1 if not<br class="">+ */<br class="">+int amt_sockets_init( stream_t *p_access )<br class="">+{<br class="">+ struct sockaddr_in rcvAddr;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+ memset( &rcvAddr, 0, sizeof(struct sockaddr_in) );<br class="">+ int enable = 0, res = 0;<br class="">+<br class="">+ /* Relay anycast address for discovery */<br class="">+ sys->relayAddrDisco.sin_family = AF_INET;<br class="">+ sys->relayAddrDisco.sin_port = htons( AMT_PORT );<br class="">+<br class="">+ /* create UDP socket */<br class="">+ sys->sAMT = vlc_socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP, true );<br class="">+ if( sys->sAMT == -1 )<br class="">+ {<br class="">+ msg_Err( p_access, "Failed to create UDP socket" );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ res = setsockopt(sys->sAMT, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));<br class="">+ if(res < 0)<br class="">+ {<br class="">+ msg_Err( p_access, "Couldn't set socket options for IPPROTO_IP, IP_PKTINFO\n %s", vlc_strerror(errno));<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ res = setsockopt(sys->sAMT, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));<br class="">+ if(res < 0)<br class="">+ {<br class="">+ msg_Err( p_access, "Couldn't make socket reusable");<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ rcvAddr.sin_family = AF_INET;<br class="">+ rcvAddr.sin_port = htons( 0 );<br class="">+ rcvAddr.sin_addr.s_addr = INADDR_ANY;<br class="">+<br class="">+ if( bind(sys->sAMT, (struct sockaddr *)&rcvAddr, sizeof(rcvAddr) ) != 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Failed to bind UDP socket error: %s", vlc_strerror(errno) );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ sys->sQuery = vlc_socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP, true );<br class="">+ if( sys->sQuery == -1 )<br class="">+ {<br class="">+ msg_Err( p_access, "Failed to create query socket" );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ /* bind socket to local address */<br class="">+ sys->stLocalAddr.sin_family = AF_INET;<br class="">+ sys->stLocalAddr.sin_port = htons( 0 );<br class="">+ sys->stLocalAddr.sin_addr.s_addr = INADDR_ANY;<br class="">+<br class="">+ if( bind(sys->sQuery, (struct sockaddr *)&sys->stLocalAddr, sizeof(struct sockaddr) ) != 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Failed to bind query socket" );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ sys->stSvrAddr.sin_family = AF_INET;<br class="">+ sys->stSvrAddr.sin_port = htons( 9124 );<br class="">+ res = inet_pton( AF_INET, "127.0.0.1", &sys->stSvrAddr.sin_addr );<br class="">+ if( res == 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Could not convert loopback address" );<br class="">+ goto error;<br class="">+ }<br class="">+<br class="">+ return 0;<br class="">+<br class="">+error:<br class="">+ net_Close( sys->sAMT );<br class="">+ net_Close( sys->sQuery );<br class="">+ return -1;<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Send a relay discovery message, before 3-way handshake<br class="">+ * */<br class="">+void amt_send_relay_discovery_msg( stream_t *p_access, char *relay_ip )<br class="">+{<br class="">+ char chaSendBuffer[AMT_DISCO_MSG_LEN];<br class="">+ unsigned int ulNonce;<br class="">+ int nRet;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ /* initialize variables */<br class="">+ memset( chaSendBuffer, 0, sizeof(chaSendBuffer) );<br class="">+ ulNonce = 0;<br class="">+ nRet = 0;<br class="">+<br class="">+ /*<br class="">+ * create AMT discovery message format<br class="">+ * +---------------------------------------------------+<br class="">+ * | Msg Type(1Byte)| Reserved (3 byte)| nonce (4byte) |<br class="">+ * +---------------------------------------------------+<br class="">+ */<br class="">+<br class="">+ chaSendBuffer[0] = AMT_RELAY_DISCO;<br class="">+ chaSendBuffer[1] = 0;<br class="">+ chaSendBuffer[2] = 0;<br class="">+ chaSendBuffer[3] = 0;<br class="">+<br class="">+ /* create nonce and copy into send buffer */<br class="">+ srand( (unsigned int)time(NULL) );<br class="">+ ulNonce = htonl( rand() );<br class="">+ memcpy( (void*)&chaSendBuffer[4], (void*)&ulNonce, sizeof(ulNonce) );<br class="">+ sys->glob_ulNonce = ulNonce;<br class="">+<br class="">+ /* send it */<br class="">+ nRet = sendto( sys->sAMT, chaSendBuffer, sizeof(chaSendBuffer), 0,\<br class="">+ (struct sockaddr *)&sys->relayAddrDisco, sizeof(struct sockaddr) );<br class="">+<br class="">+ if( nRet < 0)<br class="">+ msg_Err( p_access, "Sendto failed to %s with error %d.", relay_ip, errno);<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Send relay request message, stage 2 of handshake<br class="">+ * */<br class="">+void amt_send_relay_request( stream_t *p_access, char *relay_ip )<br class="">+{<br class="">+ char chaSendBuffer[AMT_REQUEST_MSG_LEN];<br class="">+ uint32_t ulNonce;<br class="">+ int nRet;<br class="">+ int nRetry;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ memset( chaSendBuffer, 0, sizeof(chaSendBuffer) );<br class="">+<br class="">+ ulNonce = 0;<br class="">+ nRet = 0;<br class="">+ nRetry = 0;<br class="">+<br class="">+ /*<br class="">+ * create AMT request message format<br class="">+ * +-----------------------------------------------------------------+<br class="">+ * | Msg Type(1Byte)| Reserved(1byte)|P flag(1byte)|Reserved (2 byte)|<br class="">+ * +-----------------------------------------------------------------+<br class="">+ * | nonce (4byte) |<br class="">+ * +-----------------------------------------------------------------+<br class="">+ *<br class="">+ * The P flag is set to indicate which group membership protocol the<br class="">+ * gateway wishes the relay to use in the Membership Query response:<br class="">+<br class="">+ * Value Meaning<br class="">+<br class="">+ * 0 The relay MUST respond with a Membership Query message that<br class="">+ * contains an IPv4 packet carrying an IGMPv3 General Query<br class="">+ * message.<br class="">+ * 1 The relay MUST respond with a Membership Query message that<br class="">+ * contains an IPv6 packet carrying an MLDv2 General Query<br class="">+ * message.<br class="">+ *<br class="">+ */<br class="">+<br class="">+ chaSendBuffer[0] = AMT_REQUEST;<br class="">+ chaSendBuffer[1] = 0;<br class="">+ chaSendBuffer[2] = 0;<br class="">+ chaSendBuffer[3] = 0;<br class="">+<br class="">+ ulNonce = sys->glob_ulNonce;<br class="">+ memcpy( (void*)&chaSendBuffer[4], (void*)&ulNonce, sizeof(uint32_t) );<br class="">+<br class="">+ nRet = send( sys->sAMT, chaSendBuffer, sizeof(chaSendBuffer), 0 );<br class="">+<br class="">+ if( nRet < 0 )<br class="">+ msg_Err(p_access, "Error sending relay request to %s error: %s", relay_ip, vlc_strerror(errno) );<br class="">+}<br class="">+<br class="">+/*<br class="">+* create AMT request message format<br class="">+* +----------------------------------------------------------------------------------+<br class="">+* | Msg Type(1 byte)| Reserved (1 byte)| MAC (6 byte)| nonce (4 byte) | IGMP packet |<br class="">+* +----------------------------------------------------------------------------------+<br class="">+*/<br class="">+void amt_send_mem_update( stream_t *p_access, char *relay_ip, bool leave)<br class="">+{<br class="">+ int sendBufSize = IP_HDR_IGMP_LEN + MAC_LEN + NONCE_LEN + AMT_HDR_LEN;<br class="">+ char pSendBuffer[ sendBufSize + IGMP_REPORT_LEN ];<br class="">+ uint32_t ulNonce = 0;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ memset( &pSendBuffer, 0, sizeof(pSendBuffer) );<br class="">+<br class="">+ pSendBuffer[0] = AMT_MEM_UPD;<br class="">+<br class="">+ /* copy relay MAC response */<br class="">+ memcpy( (void*)&pSendBuffer[2], (void*)sys->relay_mem_query_msg.uchaMAC, MAC_LEN );<br class="">+<br class="">+ /* copy nonce */<br class="">+ ulNonce = ntohl(sys->glob_ulNonce);<br class="">+ memcpy( (void*)&pSendBuffer[8], (void*)&ulNonce, NONCE_LEN );<br class="">+<br class="">+ /* make IP header for IGMP packet */<br class="">+ amt_ip_alert_t p_ipHead;<br class="">+ memset( &p_ipHead, 0, IP_HDR_IGMP_LEN );<br class="">+ makeIPHeader( &p_ipHead );<br class="">+<br class="">+ struct sockaddr_in temp;<br class="">+ inet_pton( AF_INET, MCAST_ALLHOSTS, &(temp.sin_addr) );<br class="">+ p_ipHead.destAddr = temp.sin_addr.s_addr;<br class="">+ p_ipHead.check = getChecksum( (unsigned short*)&p_ipHead, IP_HDR_IGMP_LEN );<br class="">+<br class="">+ amt_igmpv3_groupRecord_t groupRcd;<br class="">+ groupRcd.auxDatalen = 0;<br class="">+ inet_pton( AF_INET, sys->mcastGroup, &(temp.sin_addr) );<br class="">+ groupRcd.ssm = temp.sin_addr.s_addr;<br class="">+<br class="">+ if( strcmp(sys->srcAddr, "0.0.0.0") != 0 )<br class="">+ {<br class="">+ groupRcd.type = leave ? AMT_IGMP_BLOCK:AMT_IGMP_INCLUDE;<br class="">+ groupRcd.nSrc = htons(1);<br class="">+<br class="">+ inet_pton( AF_INET, sys->srcAddr, &(temp.sin_addr) );<br class="">+ groupRcd.srcIP[0] = temp.sin_addr.s_addr;<br class="">+<br class="">+ } else {<br class="">+ groupRcd.type = leave ? AMT_IGMP_INCLUDE_CHANGE:AMT_IGMP_EXCLUDE_CHANGE;<br class="">+ groupRcd.nSrc = htons(0);<br class="">+ }<br class="">+<br class="">+ /* make IGMP membership report */<br class="">+ amt_igmpv3_membership_report_t p_igmpMemRep;<br class="">+ makeReport( &p_igmpMemRep );<br class="">+<br class="">+ memcpy((void *)&p_igmpMemRep.grp[0], (void *)&groupRcd, (int)sizeof(groupRcd) );<br class="">+ p_igmpMemRep.checksum = getChecksum( (unsigned short*)&p_igmpMemRep, IGMP_REPORT_LEN );<br class="">+<br class="">+ amt_membership_update_msg_t memUpdateMsg;<br class="">+ memset((void*)&memUpdateMsg, 0, sizeof(memUpdateMsg));<br class="">+ memcpy((void*)&memUpdateMsg.ipHead, (void*)&p_ipHead, sizeof(p_ipHead) );<br class="">+ memcpy((void*)&memUpdateMsg.memReport, (void*)&p_igmpMemRep, sizeof(p_igmpMemRep) );<br class="">+<br class="">+ memcpy( (void*)&pSendBuffer[12], (void*)&memUpdateMsg, sizeof(memUpdateMsg) );<br class="">+<br class="">+ send( sys->sAMT, pSendBuffer, sizeof(pSendBuffer), 0 );<br class="">+<br class="">+ msg_Dbg( p_access, "AMT relay membership report sent to %s", relay_ip );<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Receive relay advertisement message<br class="">+ *<br class="">+ *<br class="">+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ * | V=0 |Type=2 | Reserved |<br class="">+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ * | Discovery Nonce |<br class="">+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ * | |<br class="">+ * ~ Relay Address (IPv4 or IPv6) ~<br class="">+ * | |<br class="">+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ * */<br class="">+bool amt_rcv_relay_adv( stream_t *p_access )<br class="">+{<br class="">+ char pkt[RELAY_ADV_MSG_LEN];<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ memset( &pkt, 0, RELAY_ADV_MSG_LEN );<br class="">+<br class="">+ struct pollfd ufd[1];<br class="">+<br class="">+ ufd[0].fd = sys->sAMT;<br class="">+ ufd[0].events = POLLIN;<br class="">+<br class="">+ switch( vlc_poll_i11e(ufd, 1, sys->timeout) )<br class="">+ {<br class="">+ case 0:<br class="">+ msg_Err(p_access, "AMT relay advertisement receive time-out");<br class="">+ /* fall through */<br class="">+ case -1:<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ struct sockaddr temp;<br class="">+ uint32_t temp_size = sizeof( struct sockaddr );<br class="">+ ssize_t len = recvfrom( sys->sAMT, &pkt, RELAY_ADV_MSG_LEN, 0, &temp, &temp_size );<br class="">+<br class="">+ if (len < 0)<br class="">+ {<br class="">+ msg_Err(p_access, "Received message length less than zero");<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ memcpy( (void*)&sys->relay_adv_msg.type, &pkt[0], MSG_TYPE_LEN );<br class="">+ if( sys->relay_adv_msg.type != AMT_RELAY_ADV )<br class="">+ {<br class="">+ msg_Err( p_access, "Received message not an AMT relay advertisement, ignoring. ");<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ memcpy( (void*)&sys->relay_adv_msg.ulRcvNonce, &pkt[NONCE_LEN], NONCE_LEN );<br class="">+ if( sys->glob_ulNonce != sys->relay_adv_msg.ulRcvNonce )<br class="">+ {<br class="">+ msg_Err( p_access, "Discovery nonces differ! currNonce:%x rcvd%x", sys->glob_ulNonce, ntohl(sys->relay_adv_msg.ulRcvNonce) );<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ memcpy( (void*)&sys->relay_adv_msg.ipAddr, &pkt[8], 4 );<br class="">+<br class="">+ memset( &sys->relayAddress, 0, sizeof(sys->relayAddress) );<br class="">+ sys->relayAddress.sin_family = AF_INET;<br class="">+ sys->relayAddress.sin_addr.s_addr = sys->relay_adv_msg.ipAddr;<br class="">+ sys->relayAddress.sin_port = htons( AMT_PORT );<br class="">+<br class="">+ int nRet = connect( sys->sAMT, (struct sockaddr *)&sys->relayAddress, sizeof(sys->relayAddress) );<br class="">+ if( nRet < 0 )<br class="">+ {<br class="">+ msg_Err( p_access, "Error connecting AMT UDP socket: %s", vlc_strerror(errno) );<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ return true;<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Receive relay membership query message<br class="">+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ | V=0 |Type=4 | Reserved |L|G| Response MAC |<br class="">+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +<br class="">+ | |<br class="">+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ | Request Nonce |<br class="">+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ | |<br class="">+ | Encapsulated General Query Message |<br class="">+ ~ IPv4:IGMPv3(Membership Query) ~<br class="">+ | IPv6:MLDv2(Listener Query) |<br class="">+ | |<br class="">+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ | Gateway Port Number | |<br class="">+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +<br class="">+ | |<br class="">+ + +<br class="">+ | Gateway IP Address (IPv4 or IPv6) |<br class="">+ + +<br class="">+ | |<br class="">+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ | |<br class="">+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br class="">+ */<br class="">+bool amt_rcv_relay_mem_query( stream_t *p_access )<br class="">+{<br class="">+ char pkt[RELAY_QUERY_MSG_LEN];<br class="">+ memset( &pkt, 0, RELAY_QUERY_MSG_LEN );<br class="">+ struct pollfd ufd[1];<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ ufd[0].fd = sys->sAMT;<br class="">+ ufd[0].events = POLLIN;<br class="">+<br class="">+ switch( vlc_poll_i11e(ufd, 1, sys->timeout) )<br class="">+ {<br class="">+ case 0:<br class="">+ msg_Err(p_access, "AMT relay membership query receive time-out");<br class="">+ /* fall through */<br class="">+ case -1:<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ ssize_t len = recv( sys->sAMT, &pkt, RELAY_QUERY_MSG_LEN, 0 );<br class="">+<br class="">+ if (len < 0)<br class="">+ {<br class="">+ msg_Err(p_access, "length less than zero");<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ memcpy( (void*)&sys->relay_mem_query_msg.type, &pkt[0], MSG_TYPE_LEN );<br class="">+ /* pkt[1] is reserved */<br class="">+ memcpy( (void*)&sys->relay_mem_query_msg.uchaMAC[0], &pkt[AMT_HDR_LEN], MAC_LEN );<br class="">+ memcpy( (void*)&sys->relay_mem_query_msg.ulRcvedNonce, &pkt[AMT_HDR_LEN + MAC_LEN], NONCE_LEN );<br class="">+ if( sys->relay_mem_query_msg.ulRcvedNonce != sys->glob_ulNonce )<br class="">+ {<br class="">+ msg_Warn( p_access, "Nonces are different rcvd: %x glob: %x", sys->relay_mem_query_msg.ulRcvedNonce, sys->glob_ulNonce );<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ sys->glob_ulNonce = ntohl(sys->relay_mem_query_msg.ulRcvedNonce);<br class="">+<br class="">+ int shift = AMT_HDR_LEN + MAC_LEN + NONCE_LEN;<br class="">+ memcpy( (void*)&sys->relay_ip_hdr, (void*)&pkt[shift], IP_HDR_IGMP_LEN );<br class="">+<br class="">+ shift += IP_HDR_IGMP_LEN;<br class="">+ sys->relay_igmp_query.type = pkt[shift];<br class="">+ shift++;<br class="">+ sys->relay_igmp_query.max_resp_code = pkt[shift];<br class="">+ shift++;<br class="">+ memcpy( (void*)&sys->relay_igmp_query.checksum, &pkt[shift], 2 );<br class="">+ shift += 2;<br class="">+ memcpy( (void*)&sys->relay_igmp_query.ssmIP, &pkt[shift], 4 );<br class="">+ shift += 4;<br class="">+ sys->relay_igmp_query.s_qrv = pkt[shift];<br class="">+ shift++;<br class="">+ if( (int)pkt[shift] == 0 )<br class="">+ sys->relay_igmp_query.qqic = 125;<br class="">+ else if( (int)pkt[shift] < 128 )<br class="">+ sys->relay_igmp_query.qqic = pkt[shift];<br class="">+ else {<br class="">+ int qqic;<br class="">+ qqic = ((pkt[shift]&0x0f) + 0x10) << (((pkt[shift] >> 4)&0x07) + 3);<br class="">+ sys->relay_igmp_query.qqic = qqic;<br class="">+ }<br class="">+<br class="">+ shift++;<br class="">+ memcpy( (void*)&sys->relay_igmp_query.nSrc, &pkt[shift], 2 );<br class="">+ if( sys->relay_igmp_query.nSrc != 0 )<br class="">+ {<br class="">+ shift += 2;<br class="">+ memcpy( (void*)&sys->relay_igmp_query.srcIP, &pkt[shift], 4 );<br class="">+ }<br class="">+<br class="">+ /* if a membership thread exists cancel it */<br class="">+ if( sys->threadReady )<br class="">+ {<br class="">+ msg_Dbg( p_access, "Cancelling existing AMT relay membership update thread");<br class="">+<br class="">+ sys->threadReady = false;<br class="">+ vlc_cancel( sys->updateThread );<br class="">+ vlc_join( sys->updateThread, NULL );<br class="">+ }<br class="">+<br class="">+ msg_Dbg( p_access, "Spawning AMT relay membership update thread");<br class="">+<br class="">+ if( vlc_clone( &sys->updateThread, amt_mem_upd, p_access, VLC_THREAD_PRIORITY_LOW) )<br class="">+ {<br class="">+ msg_Err( p_access, "Could not create AMT relay membership update thread" );<br class="">+ return false;<br class="">+ }<br class="">+<br class="">+ /* set theadReady to true, thread will send periodic membership updates until false */<br class="">+ sys->threadReady = true;<br class="">+ return true;<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Join SSM group based on input addresses, or use the defaults<br class="">+ * */<br class="">+int amt_joinSSM_group( stream_t *p_access )<br class="">+{<br class="">+ struct ip_mreq_source imr;<br class="">+ struct sockaddr_in temp;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ inet_pton( AF_INET, sys->mcastGroup, &(temp.sin_addr.s_addr) );<br class="">+ imr.imr_multiaddr.s_addr = temp.sin_addr.s_addr;<br class="">+<br class="">+ inet_pton( AF_INET, sys->srcAddr, &(temp.sin_addr.s_addr) );<br class="">+ imr.imr_sourceaddr.s_addr = temp.sin_addr.s_addr;<br class="">+ imr.imr_interface.s_addr = INADDR_ANY;<br class="">+<br class="">+ return setsockopt( sys->sAMT, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *)&imr, sizeof(imr) );<br class="">+}<br class="">+<br class="">+int amt_joinASM_group( stream_t *p_access )<br class="">+{<br class="">+ struct ip_mreq imr;<br class="">+ struct sockaddr_in temp;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ inet_pton( AF_INET, sys->mcastGroup, &(temp.sin_addr.s_addr) );<br class="">+ imr.imr_multiaddr.s_addr = temp.sin_addr.s_addr;<br class="">+ imr.imr_interface.s_addr = INADDR_ANY;<br class="">+<br class="">+ return setsockopt( sys->sAMT, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr, sizeof(imr) );<br class="">+}<br class="">+<br class="">+/**<br class="">+ * Leave SSM group that was joined earlier.<br class="">+ * */<br class="">+int amt_leaveSSM_group( stream_t *p_access )<br class="">+{<br class="">+ struct ip_mreq_source imr;<br class="">+ struct sockaddr_in temp;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ inet_pton( AF_INET, sys->mcastGroup, &(temp.sin_addr.s_addr) );<br class="">+ imr.imr_multiaddr.s_addr = temp.sin_addr.s_addr;<br class="">+<br class="">+ inet_pton( AF_INET, sys->srcAddr, &(temp.sin_addr.s_addr) );<br class="">+ imr.imr_sourceaddr.s_addr = temp.sin_addr.s_addr;<br class="">+ imr.imr_interface.s_addr = INADDR_ANY;<br class="">+<br class="">+ return setsockopt( sys->sAMT, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, (char *)&imr, sizeof(imr) );<br class="">+}<br class="">+<br class="">+int amt_leaveASM_group( stream_t *p_access )<br class="">+{<br class="">+ struct ip_mreq imr;<br class="">+ struct sockaddr_in temp;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ inet_pton( AF_INET, sys->mcastGroup, &(temp.sin_addr.s_addr) );<br class="">+ imr.imr_multiaddr.s_addr = temp.sin_addr.s_addr;<br class="">+ imr.imr_interface.s_addr = INADDR_ANY;<br class="">+<br class="">+ return setsockopt( sys->sAMT, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&imr, sizeof(imr) );<br class="">+}<br class="">+<br class="">+void *amt_mem_upd( void *data )<br class="">+{<br class="">+ char relay_ip[INET_ADDRSTRLEN];<br class="">+ stream_t *p_access = (stream_t*) data;<br class="">+ access_sys_t *sys = p_access->p_sys;<br class="">+<br class="">+ msg_Dbg( p_access, "AMT relay membership update thread started" );<br class="">+<br class="">+ inet_ntop(AF_INET, &(sys->relayAddrDisco.sin_addr), relay_ip, INET_ADDRSTRLEN);<br class="">+<br class="">+ /* thread sends periodic AMT membership updates until Close() which clears sys->threadReady and terminates thread */<br class="">+ while ( sys->threadReady )<br class="">+ {<br class="">+ amt_send_mem_update( p_access, relay_ip, false );<br class="">+ vlc_tick_sleep( (vlc_tick_t)sys->relay_igmp_query.qqic * CLOCK_FREQ );<br class="">+ }<br class="">+<br class="">+ return NULL;<br class="">+}<br class="">--<br class="">2.17.2 (Apple Git-113)<br class=""><br class="">From 72ea76afdb7679f11e19b0ac2cba6c81ec1aed33 Mon Sep 17 00:00:00 2001<br class="">From: Wayne Brassem <<a href="mailto:wbrassem@rogers.com" class="">wbrassem@rogers.com</a>><br class="">Date: Mon, 14 Jan 2019 18:48:17 -0500<br class="">Subject: [PATCH 3/3] Modifed function declarations<br class=""><br class="">---<br class="">modules/access/amt.h | 220 +++++++++++++++++++++++++++++++++++++++++++<br class="">1 file changed, 220 insertions(+)<br class="">create mode 100644 modules/access/amt.h<br class=""><br class="">diff --git a/modules/access/amt.h b/modules/access/amt.h<br class="">new file mode 100644<br class="">index 0000000000..7c14365cff<br class="">--- /dev/null<br class="">+++ b/modules/access/amt.h<br class="">@@ -0,0 +1,220 @@<br class="">+/*****************************************************************************<br class="">+ * @file amt.h<br class="">+ * @brief AMT access module structs<br class="">+ *<br class="">+ * Some of this code was pulled from or based off Cisco's open-source<br class="">+ * SSMAMTtools repo.<br class="">+ * Copyright (c) Juniper Networks, Inc., 2018 - 2018. All rights reserved.<br class="">+ *<br class="">+ * This code is licensed to you under the GNU Lesser General Public License<br class="">+ * version 2.1 or later. You may not use this code except in compliance with<br class="">+ * the GNU Lesser General Public License.<br class="">+ * This code is not an official Juniper product.<br class="">+ *<br class="">+ * Authors: Natalie Landsberg <<a href="mailto:nlandsberg@juniper.net" class="">nlandsberg@juniper.net</a>><br class="">+ * Wayne Brassem <<a href="mailto:wbrassem@rogers.com" class="">wbrassem@rogers.com</a>><br class="">+ *<br class="">+ * This library is free software; you can redistribute it and/or<br class="">+ * modify it under the terms of the GNU Lesser General Public License<br class="">+ * as published by the Free Software Foundation; either version 2.1<br class="">+ * of the License, or (at your option) any later version.<br class="">+ *<br class="">+ * This library is distributed in the hope that it will be useful,<br class="">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br class="">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br class="">+ * GNU Lesser General Public License for more details.<br class="">+ *<br class="">+ * You should have received a copy of the GNU Lesser General Public<br class="">+ * License along with this library; if not, write to the Free Software<br class="">+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br class="">+ ****************************************************************************/<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Various Lengths of Msgs or Hdrs<br class="">+ *****************************************************************************/<br class="">+#define MAC_LEN 6 /* length of generated MAC in bytes */<br class="">+#define NONCE_LEN 4 /* length of nonce in bytes */<br class="">+<br class="">+#define MSG_TYPE_LEN 1 /* length of msg type */<br class="">+#define RELAY_QUERY_MSG_LEN 48 /* total length of relay query */<br class="">+#define RELAY_ADV_MSG_LEN 12 /* length of relay advertisement message */<br class="">+#define IGMP_QUERY_LEN 24 /* length of encapsulated IGMP query message */<br class="">+#define IGMP_REPORT_LEN 20<br class="">+#define AMT_HDR_LEN 2 /* length of AMT header on a packet */<br class="">+#define IP_HDR_LEN 20 /* length of standard IP header */<br class="">+#define IP_HDR_IGMP_LEN 24 /* length of IP header with an IGMP report */<br class="">+#define UDP_HDR_LEN 8 /* length of standard UDP header */<br class="">+#define AMT_REQUEST_MSG_LEN 9<br class="">+#define AMT_DISCO_MSG_LEN 8<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Different AMT Message Types<br class="">+ *****************************************************************************/<br class="">+#define AMT_RELAY_DISCO 1 /* relay discovery */<br class="">+#define AMT_RELAY_ADV 2 /* relay advertisement */<br class="">+#define AMT_REQUEST 3 /* request */<br class="">+#define AMT_MEM_QUERY 4 /* membership query */<br class="">+#define AMT_MEM_UPD 5 /* membership update */<br class="">+#define AMT_MULT_DATA 6 /* multicast data */<br class="">+#define AMT_TEARDOWN 7 /* teardown (not currently supported) */<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Different IGMP Message Types<br class="">+ *****************************************************************************/<br class="">+#define AMT_IGMPV3_MEMBERSHIP_QUERY_TYPEID 0x11<br class="">+#define AMT_IGMPV3_MEMBERSHIP_REPORT_TYPEID 0x22<br class="">+/* IGMPv2, interoperability */<br class="">+#define AMT_IGMPV1_MEMBERSHIP_REPORT_TYPEID 0x12<br class="">+#define AMT_IGMPV2_MEMBERSHIP_REPORT_TYPEID 0x16<br class="">+#define AMT_IGMPV2_MEMBERSHIP_LEAVE_TYPEID 0x17<br class="">+<br class="">+#define AMT_IGMP_INCLUDE 0x01<br class="">+#define AMT_IGMP_EXCLUDE 0x02<br class="">+#define AMT_IGMP_INCLUDE_CHANGE 0x03<br class="">+#define AMT_IGMP_EXCLUDE_CHANGE 0x04<br class="">+#define AMT_IGMP_ALLOW 0x05<br class="">+#define AMT_IGMP_BLOCK 0x06<br class="">+<br class="">+#define MCAST_ALLHOSTS "224.0.0.22"<br class="">+#define AMT_PORT 2268<br class="">+<br class="">+#define DEFAULT_MTU (1500u - (20 + 8))<br class="">+<br class="">+typedef struct access_sys_t access_sys_t;<br class="">+<br class="">+typedef struct _amt_ip {<br class="">+ uint8_t ver_ihl;<br class="">+ uint8_t tos;<br class="">+ uint16_t tot_len;<br class="">+ uint16_t id;<br class="">+ uint16_t frag_off;<br class="">+ uint8_t ttl;<br class="">+ uint8_t protocol;<br class="">+ uint16_t check;<br class="">+ uint32_t srcAddr;<br class="">+ uint32_t destAddr;<br class="">+} amt_ip_t;<br class="">+<br class="">+typedef struct _amt_ip_alert {<br class="">+ uint8_t ver_ihl;<br class="">+ uint8_t tos;<br class="">+ uint16_t tot_len;<br class="">+ uint16_t id;<br class="">+ uint16_t frag_off;<br class="">+ uint8_t ttl;<br class="">+ uint8_t protocol;<br class="">+ uint16_t check;<br class="">+ uint32_t srcAddr;<br class="">+ uint32_t destAddr;<br class="">+ uint32_t options;<br class="">+} amt_ip_alert_t;<br class="">+<br class="">+typedef struct _amt_igmpv3_groupRecord {<br class="">+ uint8_t type;<br class="">+ uint8_t auxDatalen;<br class="">+ uint16_t nSrc;<br class="">+ uint32_t ssm;<br class="">+ uint32_t srcIP[1];<br class="">+} amt_igmpv3_groupRecord_t;<br class="">+<br class="">+typedef struct _amt_igmpv3_membership_report {<br class="">+ uint8_t type;<br class="">+ uint8_t resv;<br class="">+ uint16_t checksum;<br class="">+ uint16_t resv2;<br class="">+ uint16_t nGroupRecord;<br class="">+ amt_igmpv3_groupRecord_t grp[1];<br class="">+} amt_igmpv3_membership_report_t;<br class="">+<br class="">+typedef struct _amt_igmpv3_membership_query {<br class="">+ uint8_t type;<br class="">+ uint8_t max_resp_code; /* in 100ms, Max Resp Time = (mant | 0x10) << (exp + 3) */<br class="">+ uint32_t checksum;<br class="">+ uint32_t ssmIP;<br class="">+ uint8_t s_qrv;<br class="">+ uint8_t qqic; /* in second, query Time = (mant | 0x10) << (exp + 3) */<br class="">+ uint16_t nSrc;<br class="">+ uint32_t srcIP[1];<br class="">+} amt_igmpv3_membership_query_t;<br class="">+<br class="">+typedef struct _amt_membership_update_msg {<br class="">+ amt_ip_alert_t ipHead;<br class="">+ amt_igmpv3_membership_report_t memReport;<br class="">+} amt_membership_update_msg_t;<br class="">+<br class="">+typedef struct _amt_udpHdr {<br class="">+ uint16_t srcPort;<br class="">+ uint16_t dstPort;<br class="">+ uint16_t len;<br class="">+ uint16_t check;<br class="">+} amt_udpHdr_t;<br class="">+<br class="">+typedef struct _amt_multicast_data {<br class="">+ uint8_t type;<br class="">+ uint8_t resv;<br class="">+ amt_ip_t ip;<br class="">+ amt_udpHdr_t udp;<br class="">+ uint8_t *buf;<br class="">+} amt_multicast_data_t;<br class="">+<br class="">+/* AMT Functions */<br class="">+int amt_sockets_init( stream_t *p_access );<br class="">+void amt_send_relay_discovery_msg( stream_t *p_access, char *relay_ip );<br class="">+void amt_send_relay_request( stream_t *p_access, char *relay_ip );<br class="">+int amt_joinSSM_group( stream_t *p_access );<br class="">+int amt_joinASM_group( stream_t *p_access );<br class="">+int amt_leaveASM_group( stream_t *p_access );<br class="">+int amt_leaveSSM_group( stream_t *p_access );<br class="">+bool amt_rcv_relay_adv( stream_t *p_access );<br class="">+bool amt_rcv_relay_mem_query( stream_t *p_access );<br class="">+void amt_send_mem_update( stream_t *p_access, char *relay_ip, bool leave );<br class="">+bool open_amt_tunnel( stream_t *p_access );<br class="">+void *amt_mem_upd( void *data );<br class="">+<br class="">+/* Utility functions */<br class="">+unsigned short getChecksum( unsigned short *buffer, int nLen );<br class="">+void makeReport( amt_igmpv3_membership_report_t *mr );<br class="">+void makeIPHeader( amt_ip_alert_t *p_ipHead );<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">These should be static and only in amt.c if they are not used outside</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">of that file. Also we tend to use snake case rather than camel case.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+<br class="">+struct access_sys_t<br class="">+{<br class="">+ int fd;<br class="">+ int sAMT;<br class="">+ int sQuery;<br class="">+ int timeout;<br class="">+ int amtTimeout;<br class="">+ size_t mtu;<br class="">+ bool tryAMT;<br class="">+ bool threadReady;<br class="">+<br class="">+ vlc_thread_t updateThread;<br class="">+ vlc_tick_t queryTime;<br class="">+<br class="">+ char *mcastGroup;<br class="">+ char *srcAddr;<br class="">+ char *relayAddr;<br class="">+<br class="">+ struct sockaddr_in relayAddrDisco;<br class="">+ struct sockaddr_in relayAddress;<br class="">+ struct sockaddr_in stLocalAddr;<br class="">+ struct sockaddr_in stSvrAddr;<br class="">+<br class="">+ uint32_t glob_ulNonce;<br class="">+ uint32_t ulRelayNonce;<br class="">+<br class="">+ struct relay_mem_query_msg_t {<br class="">+ uint8_t type;<br class="">+ uint32_t ulRcvedNonce;<br class="">+ uint8_t uchaMAC[MAC_LEN];<br class="">+ uint8_t uchaIGMP[IGMP_QUERY_LEN];<br class="">+ } relay_mem_query_msg;<br class="">+<br class="">+ struct relay_adv_msg_t {<br class="">+ uint8_t type;<br class="">+ uint32_t ulRcvNonce;<br class="">+ uint32_t ipAddr;<br class="">+ } relay_adv_msg;<br class="">+<br class="">+ amt_ip_t relay_ip_hdr;<br class="">+ amt_igmpv3_membership_query_t relay_igmp_query;<br class="">+};<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">You may want to reorder this:<span class="Apple-converted-space"> </span></span><a href="http://www.catb.org/esr/structure-packing/" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">http://www.catb.org/esr/structure-packing/</a><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">--<br class="">2.17.2 (Apple Git-113)<br class="">_______________________________________________<br class="">vlc-devel mailing list<br class="">To unsubscribe or modify your subscription options:<br class=""><a href="https://mailman.videolan.org/listinfo/vlc-devel" class="">https://mailman.videolan.org/listinfo/vlc-devel</a><br class=""></blockquote><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">_______________________________________________</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">vlc-devel mailing list</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">To unsubscribe or modify your subscription options:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><a href="https://mailman.videolan.org/listinfo/vlc-devel" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://mailman.videolan.org/listinfo/vlc-devel</a></div></blockquote></div><br class=""></div></body></html>