Upstream [1] looks dead. The latest commit was pushed 7 years ago.
Pull requests are not reviewed so far [2].
[1] https://github.com/mcproxy/mcproxy
[2] https://github.com/mcproxy/mcproxy/pull/18
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
+++ /dev/null
-#
-# Copyright (C) 2014-2017 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=mcproxy
-PKG_RELEASE:=9
-
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=https://github.com/mcproxy/mcproxy.git
-PKG_SOURCE_DATE:=2017-08-24
-PKG_SOURCE_VERSION:=93b5ace42268160ebbfff4c61818fb15fa2d9b99
-PKG_MIRROR_HASH:=1999a4cd799514816159b2bf496e107231f6affbeb0f75a7298f0731e1320018
-
-PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
-PKG_LICENSE:=GPL-2.0-or-later
-PKG_LICENSE_FILES:=COPYING
-
-include $(INCLUDE_DIR)/package.mk
-include $(INCLUDE_DIR)/cmake.mk
-
-define Package/mcproxy
- SECTION:=net
- CATEGORY:=Network
- SUBMENU:=Routing and Redirection
- TITLE:=Multicast Proxy for IGMP/MLD
- URL:=https://mcproxy.realmv6.org
- DEPENDS:=+libpthread +libstdcpp @(!GCC_VERSION_4_4&&!GCC_VERSION_4_6)
-endef
-
-define Package/mcproxy/description
- mcproxy is a free & open source implementation of the IGMP/MLD proxy function (see RFC 4605) for Linux systems.
- It operates on the kernel tables for multicast routing and allows for multiple instantiations,
- as well as dynamically changing downstream interfaces.
-endef
-
-define Package/mcproxy/conffiles
-/etc/mcproxy.conf
-/etc/config/mcproxy
-endef
-
-define Package/mcproxy/install
- $(INSTALL_DIR) $(1)/etc
- $(INSTALL_CONF) ./files/mcproxy.conf $(1)/etc/mcproxy.conf
- $(INSTALL_DIR) $(1)/etc/config
- $(INSTALL_CONF) ./files/mcproxy.config $(1)/etc/config/mcproxy
- $(INSTALL_DIR) $(1)/etc/init.d
- $(INSTALL_BIN) ./files/mcproxy.init $(1)/etc/init.d/mcproxy
- $(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/mcproxy-bin $(1)/usr/sbin/mcproxy
-endef
-
-$(eval $(call BuildPackage,mcproxy))
+++ /dev/null
-######################################
-##-- mcproxy configuration script --##
-######################################
-
-# Protocol: IGMPv1|IGMPv2|IGMPv3 (IPv4) - MLDv1|MLDv2 (IPv6)
-protocol IGMPv3;
-
-###########################################
-
-# Proxy Instance: upstream ==> downstream
-pinstance A: ap a1 ==> ap a2;
-pinstance B: bp b1 ==> bp b2;
-
-###########################################
-
-# Tables
-table allways {
- (*|*)
-};
-
-table piA_peering_ifs {
- ap(*|*)
-};
-
-table piA_upstreams {
- a1(*|*)
-};
-
-table piB_peering_ifs {
- bp(*|*)
-};
-
-table piB_upstreams {
- b1(*|*)
-};
-
-###########################################
-
-# Instance Behaviour
-pinstance A upstream * in rulematching mutex 10; #or 25ms (u4)
-#pinstance A upstream * out rulematching all; #default
-
-pinstance A upstream ap out blacklist table allways; #(u1)
-#pinstance A upstream ap in whitelist table {(*|*)}; #default (u2, u3)
-
-pinstance A upstream a1 out blacklist table piA_peering_ifs; #(u3_1)
-#pinstance A upstream a1 in whitelist table {(*|*)}; #default
-
-pinstance A downstream ap in blacklist table allways; #(d1)
-pinstance A downstream ap out blacklist table piA_upstreams; #(d2, d2_1, d3, d4)
-
-#pinstance A downstream a2 in whitelist table {(*|*)}; #default
-#pinstance A downstream a2 out whitelist table {(*|*)}; #default
-
-pinstance B upstream * in rulematching mutex 10; #or 25ms (u4)
-#pinstance B upstream * out rulematching all; #default
-
-pinstance B upstream bp out blacklist table allways; #(u1)
-#pinstance B upstream bp in whitelist table {(*|*)}; #default (u2, u3)
-
-pinstance B upstream b1 out blacklist table piB_peering_ifs; #(u3_1)
-#pinstance b upstream b1 in whitelist table {(*|*)}; #default
-
-pinstance B downstream bp in blacklist table allways; #(d1)
-pinstance B downstream bp out blacklist table piB_upstreams; #(d2, d2_1, d3, d4)
-
-#pinstance B downstream b2 in whitelist table {(*|*)}; #default
-#pinstance B downstream b2 out whitelist table {(*|*)}; #default
+++ /dev/null
-# Use your own MCProxy config file
-config mcproxy 'mcproxy_file'
- option disabled '1'
- option respawn '1'
- option file '/etc/mcproxy.conf'
-
-# Use OpenWrt UCI config
-config mcproxy 'mcproxy'
- option disabled '1'
- option respawn '1'
- option protocol 'IGMPv3'
-
-###########################################
-
-# Simple configuration examples
-
-config instance
- option disabled '1'
- option name 'proxy1'
- list upstream 'eth1'
- list downstream 'eth0.2'
-
-config instance
- option disabled '1'
- option name 'proxy2'
- list upstream 'eth0.2'
- list downstream 'eth0.4'
- list downstream 'br-lan'
-
-config instance
- option disabled '1'
- option name 'proxy3'
- list upstream 'eth1.2'
- list upstream 'eth1.4'
- list downstream 'eth0.1'
-
-###########################################
-
-# Advanced configuration example
-
-config instance
- option name 'A'
- list upstream 'ap'
- list upstream 'a1'
- list downstream 'ap'
- list downstream 'a2'
-
-config instance
- option name 'B'
- list upstream 'bp'
- list upstream 'b1'
- list downstream 'bp'
- list downstream 'b2'
-
-config table
- option name 'allways'
- list entries '(*|*)'
-
-config table
- option name 'piA_peering_ifs'
- list entries 'ap(*|*)'
-
-config table
- option name 'piA_upstreams'
- list entries 'a1(*|*)'
-
-config table
- option name 'piB_peering_ifs'
- list entries 'bp(*|*)'
-
-config table
- option name 'piB_upstreams'
- list entries 'b1(*|*)'
-
-config behaviour
- option instance 'A'
- option section 'upstream'
- option interface '*'
- option direction 'in'
- option rulematching 'mutex 10'
-
-config behaviour
- option disabled '1'
- option instance 'A'
- option section 'upstream'
- option interface '*'
- option direction 'out'
- option rulematching 'all'
-
-config behaviour
- option instance 'A'
- option section 'upstream'
- option interface 'ap'
- option direction 'out'
- option table 'allways'
-
-config behaviour
- option disabled '1'
- option instance 'A'
- option section 'upstream'
- option interface 'ap'
- option direction 'in'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option instance 'A'
- option section 'upstream'
- option interface 'a1'
- option direction 'out'
- option table 'piA_peering_ifs'
-
-config behaviour
- option disabled '1'
- option instance 'A'
- option section 'upstream'
- option interface 'a1'
- option direction 'in'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option instance 'A'
- option section 'downstream'
- option interface 'ap'
- option direction 'in'
- option table 'allways'
-
-config behaviour
- option instance 'A'
- option section 'downstream'
- option interface 'ap'
- option direction 'out'
- option table 'piA_upstreams'
-
-config behaviour
- option disabled '1'
- option instance 'A'
- option section 'downstream'
- option interface 'a2'
- option direction 'in'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option disabled '1'
- option instance 'A'
- option section 'downstream'
- option interface 'a2'
- option direction 'out'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option instance 'B'
- option section 'upstream'
- option interface '*'
- option direction 'in'
- option rulematching 'mutex 10'
-
-config behaviour
- option disabled '1'
- option instance 'B'
- option section 'upstream'
- option interface '*'
- option direction 'out'
- option rulematching 'all'
-
-config behaviour
- option instance 'B'
- option section 'upstream'
- option interface 'bp'
- option direction 'out'
- option table 'allways'
-
-config behaviour
- option disabled '1'
- option instance 'B'
- option section 'upstream'
- option interface 'bp'
- option direction 'in'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option instance 'B'
- option section 'upstream'
- option interface 'b1'
- option direction 'out'
- option table 'piB_peering_ifs'
-
-config behaviour
- option disabled '1'
- option instance 'B'
- option section 'upstream'
- option interface 'b1'
- option direction 'in'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option instance 'B'
- option section 'downstream'
- option interface 'bp'
- option direction 'in'
- option table 'allways'
-
-config behaviour
- option instance 'B'
- option section 'downstream'
- option interface 'bp'
- option direction 'out'
- option table 'piB_upstreams'
-
-config behaviour
- option disabled '1'
- option instance 'B'
- option section 'downstream'
- option interface 'b2'
- option direction 'in'
- option whitelist '1'
- option table '{(*|*)}'
-
-config behaviour
- option disabled '1'
- option instance 'B'
- option section 'downstream'
- option interface 'b2'
- option direction 'out'
- option whitelist '1'
- option table '{(*|*)}'
-
-config blocks blocks
- # mDNS
- list entries '(*|239.255.255.0/24)'
- # SSDP
- list entries '(*|224.0.0.0/24)'
- # SLP
- list entries '(*|239.192.0.0/16)'
+++ /dev/null
-#!/bin/sh /etc/rc.common
-# Copyright (C) 2014-2015 OpenWrt.org
-
-START=99
-USE_PROCD=1
-
-mcproxy_handle_instances() {
- local instance="$1"
- local conf_file="$2"
- local disabled
- local pre=""
- local name
- local upstreams
- local downstreams
-
- config_get_bool disabled "$instance" 'disabled' '0'
- config_get name "$instance" "name" "$instance"
- config_get upstreams "$instance" "upstream"
- config_get downstreams "$instance" "downstream"
-
- if [ $disabled -eq 1 ]; then
- pre="# "
- fi
-
- local str_up=""
- if [ -n "$upstreams" ]; then
- local upstream
- for upstream in $upstreams; do
- str_up="$str_up \"$upstream\""
- done
- fi
-
- local str_down=""
- if [ -n "$downstreams" ]; then
- local downstream
- for downstream in $downstreams; do
- str_down="$str_down \"$downstream\""
- done
- fi
-
- if [ ! -z $downstream ]; then
- echo -e "${pre}pinstance ${name}:${str_up} ==>${str_down};\n" >> $conf_file
- fi
-}
-
-# mcproxy_list_table <var> <section> <option>
-mcproxy_list_table() {
- local val
- local len
- local _buffer
- local c=1
-
- config_get len "$2" "${3}_LENGTH"
- [ -z "$len" ] && return 0
- while [ $c -le "$len" ]; do
- config_get val "$2" "${3}_ITEM$c"
- append _buffer "\t${val}\n"
- c="$(($c + 1))"
- done
-
- export "${1}=${_buffer}";
-}
-
-mcproxy_handle_tables() {
- local table="$1"
- local conf_file="$2"
- local name
- local entries
-
- config_get name "$table" "name" ""
- mcproxy_list_table entries "$table" "entries"
-
- if [ ! -z $name ] && [ ! -z $table ]; then
- echo -e "table $name {\n${entries}};\n" >> $conf_file
- fi
-}
-
-mcproxy_handle_behaviour() {
- local behaviour="$1"
- local conf_file="$2"
- local disabled
- local pre=""
- local instance
- local section
- local interface
- local direction
- local rulematching
- local table
-
- config_get_bool disabled "$behaviour" 'disabled' '0'
- config_get instance "$behaviour" "instance"
- config_get section "$behaviour" "section" "upstream"
- config_get interface "$behaviour" "interface" "*"
- config_get direction "$behaviour" "direction" "in"
- config_get rulematching "$behaviour" "rulematching"
- config_get table "$behaviour" "table"
-
- if [ -z $instance ]; then
- return 1
- fi
-
- local rule_table
- if [ ! -z $rulematching ]; then
- rule_table="rulematching $rulematching"
- elif [ ! -z $table ]; then
- local whitelist
- local list
-
- config_get_bool whitelist "$behaviour" 'whitelist' '0'
- if [ $whitelist -eq 1 ]; then
- list="whitelist"
- else
- list="blacklist"
- fi
-
- rule_table="$list table $table"
- else
- rule_table="rulematching all"
- fi
-
- if [ $disabled -eq 1 ]; then
- pre="# "
- fi
-
- echo -e "${pre}pinstance $instance $section \"$interface\" $direction $rule_table;\n" >> $conf_file
-}
-
-mcproxy_network_trigger() {
- procd_add_interface_trigger "interface.*" "$1" /etc/init.d/mcproxy restart
-}
-mcproxy_handle_network() {
- local instance="$1"
-
- config_list_foreach "$instance" upstream mcproxy_network_trigger
- config_list_foreach "$instance" downstream mcproxy_network_trigger
-}
-
-start_instance() {
- local cfg="$1"
- local aux
- local conf_file
-
- config_get_bool aux "$cfg" 'disabled' '0'
- [ "$aux" = 1 ] && return 1
-
- config_get conf_file "$cfg" "file"
- if [ ! -n "$conf_file" ]; then
- mkdir -p /var/etc
- conf_file="/var/etc/mcproxy_${cfg}.conf"
-
- local protocol
- config_get protocol "$cfg" "protocol" "IGMPv3"
- echo -e "protocol ${protocol};\n" > $conf_file
-
- config_foreach mcproxy_handle_instances instance $conf_file
- config_foreach mcproxy_handle_tables table $conf_file
- config_foreach mcproxy_handle_behaviour behaviour $conf_file
- fi
-
- procd_open_instance
-
- procd_set_param command /usr/sbin/mcproxy
- procd_append_param command -f $conf_file
-
- config_get_bool aux "$cfg" 'respawn' '0'
- [ "$aux" = 1 ] && procd_set_param respawn
-
- procd_open_trigger
- config_foreach mcproxy_handle_network instance
- procd_close_trigger
-
- procd_close_instance
-}
-
-service_triggers() {
- procd_open_trigger
- procd_add_config_trigger "config.change" "mcproxy" /etc/init.d/mcproxy restart
- procd_close_trigger
-}
-
-start_service() {
- config_load mcproxy
- config_foreach start_instance mcproxy
-}
+++ /dev/null
---- /dev/null
-+++ b/CMakeLists.txt
-@@ -0,0 +1,51 @@
-+cmake_minimum_required(VERSION 2.8)
-+
-+# Project Definition
-+project(mcproxy CXX)
-+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
-+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11")
-+add_definitions(-Wall -Wextra)
-+include_directories(${CMAKE_SOURCE_DIR}/mcproxy)
-+
-+
-+add_executable(mcproxy-bin mcproxy/src/main.cpp
-+ mcproxy/src/hamcast_logging.cpp
-+ #utils
-+ mcproxy/src/utils/mc_socket.cpp
-+ mcproxy/src/utils/addr_storage.cpp
-+ mcproxy/src/utils/mroute_socket.cpp
-+ mcproxy/src/utils/if_prop.cpp
-+ mcproxy/src/utils/reverse_path_filter.cpp
-+ #proxy
-+ mcproxy/src/proxy/proxy.cpp
-+ mcproxy/src/proxy/sender.cpp
-+ mcproxy/src/proxy/receiver.cpp
-+ mcproxy/src/proxy/mld_receiver.cpp
-+ mcproxy/src/proxy/igmp_receiver.cpp
-+ mcproxy/src/proxy/mld_sender.cpp
-+ mcproxy/src/proxy/igmp_sender.cpp
-+ mcproxy/src/proxy/proxy_instance.cpp
-+ mcproxy/src/proxy/routing.cpp
-+ mcproxy/src/proxy/worker.cpp
-+ mcproxy/src/proxy/timing.cpp
-+ mcproxy/src/proxy/check_if.cpp
-+ mcproxy/src/proxy/check_kernel.cpp
-+ mcproxy/src/proxy/membership_db.cpp
-+ mcproxy/src/proxy/querier.cpp
-+ mcproxy/src/proxy/timers_values.cpp
-+ mcproxy/src/proxy/interfaces.cpp
-+ mcproxy/src/proxy/def.cpp
-+ mcproxy/src/proxy/simple_mc_proxy_routing.cpp
-+ mcproxy/src/proxy/simple_routing_data.cpp
-+ #parser
-+ mcproxy/src/parser/scanner.cpp
-+ mcproxy/src/parser/token.cpp
-+ mcproxy/src/parser/configuration.cpp
-+ mcproxy/src/parser/parser.cpp
-+ mcproxy/src/parser/interface.cpp
-+)
-+target_link_libraries(mcproxy-bin pthread)
-+
-+# Installation
-+install(TARGETS mcproxy-bin DESTINATION bin/)
-+
+++ /dev/null
---- a/mcproxy/src/parser/parser.cpp
-+++ b/mcproxy/src/parser/parser.cpp
-@@ -126,7 +126,7 @@ void parser::parse_instance_definition(i
- get_next_token();
- if (m_current_token.get_type() == TT_STRING) {
- try {
-- table_number = std::stoi(m_current_token.get_string());
-+ table_number = atoi(m_current_token.get_string().c_str());
- user_selected_table_number = true;
- } catch (std::logic_error e) {
- HC_LOG_ERROR("failed to parse line " << m_current_line << " table number: " << table_number << " is not a number");
-@@ -299,7 +299,7 @@ std::unique_ptr<addr_match> parser::pars
- get_next_token();
- if (m_current_token.get_type() == TT_STRING) {
- try {
-- unsigned int prefix = std::stoi(m_current_token.get_string());
-+ unsigned int prefix = atoi(m_current_token.get_string().c_str());
- if (prefix > 128) {
- throw;
- }
-@@ -561,7 +561,7 @@ void parser::parse_interface_rule_match_
- get_next_token();
- if (m_current_token.get_type() == TT_STRING) {
- try {
-- int tmp_timeout = std::stoi(m_current_token.get_string());
-+ int tmp_timeout = atoi(m_current_token.get_string().c_str());
- timeout = std::chrono::milliseconds(tmp_timeout);
- } catch (...) {
- error_notification();
---- a/mcproxy/src/utils/addr_storage.cpp
-+++ b/mcproxy/src/utils/addr_storage.cpp
-@@ -298,7 +298,7 @@ addr_storage& addr_storage::set_port(uin
-
- addr_storage& addr_storage::set_port(const std::string& port)
- {
-- set_port(std::stoi(port.c_str()));
-+ set_port(atoi(port.c_str()));
- return *this;
- }
-
+++ /dev/null
---- a/mcproxy/src/utils/mc_socket.cpp
-+++ b/mcproxy/src/utils/mc_socket.cpp
-@@ -37,6 +37,10 @@
- #include <numeric>
- #include <unistd.h>
-
-+#if !defined(__GLIBC__) || defined(__UCLIBC__)
-+#include "sourcefilter.cpp"
-+#endif /* __GLIBC__ */
-+
- std::string ipAddrResolver(std::string ipAddr)
- {
- std::string str[][2] = {
---- /dev/null
-+++ b/mcproxy/src/utils/sourcefilter.cpp
-@@ -0,0 +1,165 @@
-+/* Get source filter. Linux version.
-+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include <assert.h>
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <stdint.h>
-+#include <netinet/in.h>
-+#include <netpacket/packet.h>
-+#include <sys/param.h>
-+#include <sys/socket.h>
-+
-+static const struct
-+{
-+ int sol;
-+ int af;
-+ socklen_t size;
-+} sol_map[] =
-+ {
-+ /* Sort the array according to importance of the protocols. Add
-+ more protocols when they become available. */
-+ { SOL_IP, AF_INET, sizeof (struct sockaddr_in) },
-+ { SOL_IPV6, AF_INET6, sizeof (struct sockaddr_in6) },
-+ { SOL_PACKET, AF_PACKET, sizeof (struct sockaddr_ll) }
-+ };
-+#define NSOL_MAP (sizeof (sol_map) / sizeof (sol_map[0]))
-+
-+
-+/* Try to determine the socket level value. Ideally both side and
-+ family are set. But sometimes only the size is correct and the
-+ family value might be bogus. Loop over the array entries and look
-+ for a perfect match or the first match based on size. */
-+static int
-+__get_sol (int af, socklen_t len)
-+{
-+ int first_size_sol = -1;
-+
-+ for (size_t cnt = 0; cnt < NSOL_MAP; ++cnt)
-+ {
-+ /* Just a test so that we make sure the special value used to
-+ signal the "we have so far no socket level value" is OK. */
-+ assert (sol_map[cnt].sol != -1);
-+
-+ if (len == sol_map[cnt].size)
-+ {
-+ /* The size matches, which is a requirement. If the family
-+ matches, too, we have a winner. Otherwise we remember the
-+ socket level value for this protocol if it is the first
-+ match. */
-+ if (af == sol_map[cnt].af)
-+ /* Bingo! */
-+ return sol_map[cnt].sol;
-+
-+ if (first_size_sol == -1)
-+ first_size_sol = sol_map[cnt].sol;
-+ }
-+ }
-+
-+ return first_size_sol;
-+}
-+
-+
-+int
-+getsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
-+ socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc,
-+ struct sockaddr_storage *slist)
-+{
-+ /* We have to create an struct ip_msfilter object which we can pass
-+ to the kernel. */
-+ socklen_t needed = GROUP_FILTER_SIZE (*numsrc);
-+ struct group_filter *gf;
-+ gf = (struct group_filter *) malloc (needed);
-+ if (gf == NULL)
-+ return -1;
-+
-+ gf->gf_interface = interface;
-+ memcpy (&gf->gf_group, group, grouplen);
-+ gf->gf_numsrc = *numsrc;
-+
-+ /* We need to provide the appropriate socket level value. */
-+ int result;
-+ int sol = __get_sol (group->sa_family, grouplen);
-+ if (sol == -1)
-+ {
-+ errno = EINVAL;
-+ result = -1;
-+ }
-+ else
-+ {
-+ result = getsockopt (s, sol, MCAST_MSFILTER, gf, &needed);
-+
-+ /* If successful, copy the results to the places the caller wants
-+ them in. */
-+ if (result == 0)
-+ {
-+ *fmode = gf->gf_fmode;
-+ memcpy (slist, gf->gf_slist,
-+ MIN (*numsrc, gf->gf_numsrc)
-+ * sizeof (struct sockaddr_storage));
-+ *numsrc = gf->gf_numsrc;
-+ }
-+ }
-+
-+ int save_errno = errno;
-+ free (gf);
-+ errno = save_errno;
-+
-+ return result;
-+}
-+
-+
-+int
-+setsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
-+ socklen_t grouplen, uint32_t fmode, uint32_t numsrc,
-+ const struct sockaddr_storage *slist)
-+{
-+ /* We have to create an struct ip_msfilter object which we can pass
-+ to the kernel. */
-+ size_t needed = GROUP_FILTER_SIZE (numsrc);
-+
-+ struct group_filter *gf;
-+ gf = (struct group_filter *) malloc (needed);
-+ if (gf == NULL)
-+ return -1;
-+
-+ gf->gf_interface = interface;
-+ memcpy (&gf->gf_group, group, grouplen);
-+ gf->gf_fmode = fmode;
-+ gf->gf_numsrc = numsrc;
-+ memcpy (gf->gf_slist, slist, numsrc * sizeof (struct sockaddr_storage));
-+
-+ /* We need to provide the appropriate socket level value. */
-+ int result;
-+ int sol = __get_sol (group->sa_family, grouplen);
-+ if (sol == -1)
-+ {
-+ errno = EINVAL;
-+ result = -1;
-+ }
-+ else
-+ result = setsockopt (s, sol, MCAST_MSFILTER, gf, needed);
-+
-+ int save_errno = errno;
-+ free (gf);
-+ errno = save_errno;
-+
-+ return result;
-+}
+++ /dev/null
---- a/mcproxy/src/utils/mc_socket.cpp
-+++ b/mcproxy/src/utils/mc_socket.cpp
-@@ -38,6 +38,8 @@
- #include <unistd.h>
-
- #if !defined(__GLIBC__) || defined(__UCLIBC__)
-+#define IP_MULTICAST_ALL 49
-+
- #include "sourcefilter.cpp"
- #endif /* __GLIBC__ */
-
+++ /dev/null
---- a/mcproxy/src/proxy/simple_mc_proxy_routing.cpp
-+++ b/mcproxy/src/proxy/simple_mc_proxy_routing.cpp
-@@ -118,13 +118,13 @@ void interface_memberships::process_upst
- for (auto source_it = cs.first.m_source_list.begin(); source_it != cs.first.m_source_list.end();) {
-
- //downstream out
-- if (!cs.second->match_output_filter(interfaces::get_if_name(upstr_e.m_if_index), gaddr, source_it->saddr)) {
-+ if (!cs.second->match_output_filter(interfaces::get_if_name(upstr_e.m_if_index), source_it->saddr, gaddr)) {
- source_it = cs.first.m_source_list.erase(source_it);
- continue;
- }
-
- //upstream in
-- if (!upstr_e.m_interface->match_input_filter(interfaces::get_if_name(upstr_e.m_if_index), gaddr, source_it->saddr)) {
-+ if (!upstr_e.m_interface->match_input_filter(interfaces::get_if_name(upstr_e.m_if_index), source_it->saddr, gaddr)) {
- tmp_sstate.m_source_list.insert(*source_it);
- source_it = cs.first.m_source_list.erase(source_it);
- continue;
-@@ -175,13 +175,13 @@ void interface_memberships::process_upst
- for (auto source_it = cs_it->first.m_source_list.begin(); source_it != cs_it->first.m_source_list.end();) {
-
- //downstream out
-- if (!cs_it->second->match_output_filter(interfaces::get_if_name(upstr_e.m_if_index), gaddr, source_it->saddr)) {
-+ if (!cs_it->second->match_output_filter(interfaces::get_if_name(upstr_e.m_if_index), source_it->saddr, gaddr)) {
- ++source_it;
- continue;
- }
-
- //upstream in
-- if (!upstr_e.m_interface->match_input_filter(interfaces::get_if_name(upstr_e.m_if_index), gaddr, source_it->saddr)) {
-+ if (!upstr_e.m_interface->match_input_filter(interfaces::get_if_name(upstr_e.m_if_index), source_it->saddr, gaddr)) {
- ++source_it;
- continue;
- }
-@@ -619,9 +619,9 @@ bool simple_mc_proxy_routing::check_inte
- std::string input_if_index_name = interfaces::get_if_name(input_if_index);
- if (!input_if_index_name.empty()) {
- if (interface_direction == ID_IN) {
-- return interf->match_input_filter(input_if_index_name, gaddr, saddr);
-+ return interf->match_input_filter(input_if_index_name, saddr, gaddr);
- } else if (interface_direction == ID_OUT) {
-- return interf->match_output_filter(input_if_index_name, gaddr, saddr);
-+ return interf->match_output_filter(input_if_index_name, saddr, gaddr);
- } else {
- HC_LOG_ERROR("unkown interface direction");
- return false;
+++ /dev/null
---- a/mcproxy/src/proxy/proxy_instance.cpp
-+++ b/mcproxy/src/proxy/proxy_instance.cpp
-@@ -171,6 +171,9 @@ void proxy_instance::worker_thread()
- HC_LOG_TRACE("");
- while (m_running) {
- auto msg = m_job_queue.dequeue();
-+
-+ HC_LOG_DEBUG("Proxy Message: " << msg->get_message_type_name(msg->get_type()) );
-+
- switch (msg->get_type()) {
- case proxy_msg::TEST_MSG:
- (*msg)();
-@@ -193,25 +196,66 @@ void proxy_instance::worker_thread()
- }
- break;
- case proxy_msg::GROUP_RECORD_MSG: {
-- auto r = std::static_pointer_cast<group_record_msg>(msg);
-+ auto gr = std::static_pointer_cast<group_record_msg>(msg);
-
- if (m_in_debug_testing_mode) {
- std::cout << "!!--ACTION: receive record" << std::endl;
-- std::cout << *r << std::endl;
-+ std::cout << *gr << std::endl;
- std::cout << std::endl;
- }
-
-- auto it = m_downstreams.find(r->get_if_index());
-+ auto slist = gr->get_slist();
-+ addr_storage saddr;
-+ if (slist.empty()) {
-+ saddr = "0.0.0.0";
-+ } else {
-+ saddr = slist.begin()->saddr;
-+ }
-+ auto it = m_downstreams.find(gr->get_if_index());
- if (it != std::end(m_downstreams)) {
-- it->second.m_querier->receive_record(msg);
-+ // Check for input filters
-+ if (!it->second.m_interface->match_input_filter(interfaces::get_if_name(gr->get_if_index()), saddr, gr->get_gaddr()))
-+ {
-+ HC_LOG_DEBUG("group report " << gr->get_gaddr() << " filtered");
-+ }
-+ else
-+ {
-+ it->second.m_querier->receive_record(msg);
-+ }
- } else {
-- HC_LOG_DEBUG("failed to find querier of interface: " << interfaces::get_if_name(std::static_pointer_cast<timer_msg>(msg)->get_if_index()));
-+ HC_LOG_DEBUG("failed to find querier of interface: " << interfaces::get_if_name( gr->get_if_index() ));
- }
-- }
-+ }
-+ break;
-+ case proxy_msg::NEW_SOURCE_MSG: {
-+ auto sm = std::static_pointer_cast<new_source_msg>(msg);
-+ // Find the interface
-+ std::shared_ptr<interface> interf;
-+ auto it = m_downstreams.find(sm->get_if_index());
-+ if (it != std::end(m_downstreams)) {
-+ interf = it->second.m_interface;
-+ } else {
-+ for (auto & e : m_upstreams) {
-+ if (e.m_if_index == sm->get_if_index()) {
-+ interf = e.m_interface;
-+ break;
-+ }
-+ }
-+ }
-+ if ( !interf )
-+ {
-+ HC_LOG_DEBUG("failed to find interface: " << interfaces::get_if_name( sm->get_if_index() ) << " for Source message " << sm->get_saddr() << " | " << sm->get_gaddr() );
-+ break;
-+ }
-+ // Check for input filters
-+ if (!interf->match_input_filter(interfaces::get_if_name(sm->get_if_index()), sm->get_saddr(), sm->get_gaddr()))
-+ {
-+ HC_LOG_DEBUG("source " << sm->get_saddr() << " | " << sm->get_gaddr() << " filtered");
-+ } else {
-+ m_routing_management->event_new_source(msg);
-+ }
-+ }
- break;
-- case proxy_msg::NEW_SOURCE_MSG:
-- m_routing_management->event_new_source(msg);
-- break;
- case proxy_msg::NEW_SOURCE_TIMER_MSG:
- m_routing_management->timer_triggerd_maintain_routing_table(msg);
- break;
+++ /dev/null
---- a/mcproxy/include/proxy/igmp_sender.hpp
-+++ b/mcproxy/include/proxy/igmp_sender.hpp
-@@ -37,9 +37,10 @@ class igmp_sender : public sender
- {
- private:
- bool send_igmpv3_query(unsigned int if_index, const timers_values& tv, const addr_storage& gaddr, bool s_flag, const source_list<source>& slist) const;
-+ bool send_igmpv2_query(unsigned int if_index, const timers_values& tv, const addr_storage& gaddr ) const;
-
- public:
-- igmp_sender(const std::shared_ptr<const interfaces>& interfaces);
-+ igmp_sender(const std::shared_ptr<const interfaces>& interfaces, const group_mem_protocol gmp);
-
- bool send_record(unsigned int if_index, mc_filter filter_mode, const addr_storage& gaddr, const source_list<source>& slist) const override;
-
---- a/mcproxy/src/proxy/igmp_sender.cpp
-+++ b/mcproxy/src/proxy/igmp_sender.cpp
-@@ -32,7 +32,7 @@
-
- #include <memory>
-
--igmp_sender::igmp_sender(const std::shared_ptr<const interfaces>& interfaces): sender(interfaces, IGMPv3)
-+igmp_sender::igmp_sender(const std::shared_ptr<const interfaces>& interfaces, const group_mem_protocol gmp): sender(interfaces, gmp)
- {
- HC_LOG_TRACE("");
-
-@@ -119,10 +119,79 @@ bool igmp_sender::send_mc_addr_and_src_s
- return rc;
- }
-
-+bool igmp_sender::send_igmpv2_query(unsigned int if_index, const timers_values& tv, const addr_storage& gaddr ) const
-+{
-+ HC_LOG_TRACE("");
-+
-+ std::unique_ptr<unsigned char[]> packet;
-+ unsigned int size;
-+
-+ size = sizeof(ip) + sizeof(router_alert_option) + sizeof(igmp);
-+ packet.reset(new unsigned char[size]);
-+
-+ addr_storage dst_addr;
-+
-+ if (gaddr == addr_storage(AF_INET)) { //is general query
-+ dst_addr = IPV4_ALL_HOST_ADDR;
-+ } else {
-+ dst_addr = gaddr;
-+ }
-+
-+ //-------------------------------------------------------------------
-+ //fill ip header
-+ ip* ip_hdr = reinterpret_cast<ip*>(packet.get());
-+
-+ ip_hdr->ip_v = 4;
-+ ip_hdr->ip_hl = (sizeof(ip) + sizeof(router_alert_option)) / 4;
-+ ip_hdr->ip_tos = 0;
-+ ip_hdr->ip_len = htons(size);
-+ ip_hdr->ip_id = 0;
-+ ip_hdr->ip_off = htons(0 | IP_DF); //dont fragment flag
-+ ip_hdr->ip_ttl = 1;
-+ ip_hdr->ip_p = IPPROTO_IGMP;
-+ ip_hdr->ip_sum = 0;
-+ ip_hdr->ip_src = m_interfaces->get_saddr(interfaces::get_if_name(if_index)).get_in_addr();
-+ ip_hdr->ip_dst = dst_addr.get_in_addr();
-+
-+ //-------------------------------------------------------------------
-+ //fill router_alert_option header
-+ router_alert_option* ra_hdr = reinterpret_cast<router_alert_option*>(reinterpret_cast<unsigned char*>(ip_hdr) + sizeof(ip));
-+ *ra_hdr = router_alert_option();
-+
-+ ip_hdr->ip_sum = m_sock.calc_checksum(reinterpret_cast<unsigned char*>(ip_hdr), sizeof(ip) + sizeof(router_alert_option));
-+
-+ //-------------------------------------------------------------------
-+ //fill igmpv3 query
-+ igmp* query = reinterpret_cast<igmp*>(reinterpret_cast<unsigned char*>(ra_hdr) + sizeof(router_alert_option));
-+
-+ query->igmp_type = IGMP_MEMBERSHIP_QUERY;
-+
-+ if (gaddr == addr_storage(AF_INET)) { //general query
-+ query->igmp_code = tv.maxrespi_to_maxrespc_igmpv3(tv.get_query_response_interval());
-+ } else {
-+ query->igmp_code = tv.maxrespi_to_maxrespc_igmpv3(tv.get_last_listener_query_time());
-+ }
-+
-+ query->igmp_cksum = 0;
-+ query->igmp_group = gaddr.get_in_addr();
-+
-+ query->igmp_cksum = m_sock.calc_checksum(reinterpret_cast<unsigned char*>(query), (sizeof(igmp) ));
-+
-+ if (!m_sock.choose_if(if_index)) {
-+ return false;
-+ }
-+
-+ return m_sock.send_packet(dst_addr, reinterpret_cast<unsigned char*>(ip_hdr), size);
-+}
-+
- bool igmp_sender::send_igmpv3_query(unsigned int if_index, const timers_values& tv, const addr_storage& gaddr, bool s_flag, const source_list<source>& slist) const
- {
- HC_LOG_TRACE("");
-
-+ if ( (m_group_mem_protocol & IGMPv3) == 0 ) {
-+ return send_igmpv2_query( if_index, tv, gaddr );
-+ }
-+
- std::unique_ptr<unsigned char[]> packet;
- unsigned int size;
-
---- a/mcproxy/src/proxy/proxy_instance.cpp
-+++ b/mcproxy/src/proxy/proxy_instance.cpp
-@@ -119,7 +119,7 @@ bool proxy_instance::init_sender()
- {
- HC_LOG_TRACE("");
- if (is_IPv4(m_group_mem_protocol)) {
-- m_sender = std::make_shared<igmp_sender>(m_interfaces);
-+ m_sender = std::make_shared<igmp_sender>(m_interfaces, m_group_mem_protocol );
- } else if (is_IPv6(m_group_mem_protocol)) {
- m_sender = std::make_shared<mld_sender>(m_interfaces);
- } else {