mirror of
https://git.openwrt.org/feed/routing.git
synced 2025-01-07 03:06:53 +08:00
mcproxy: remove this package
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>
This commit is contained in:
parent
233b3c6637
commit
cbf04774c4
@ -1,57 +0,0 @@
|
||||
#
|
||||
# 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))
|
@ -1,68 +0,0 @@
|
||||
######################################
|
||||
##-- 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
|
@ -1,239 +0,0 @@
|
||||
# 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)'
|
@ -1,184 +0,0 @@
|
||||
#!/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
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
--- /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/)
|
||||
+
|
@ -1,40 +0,0 @@
|
||||
--- 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;
|
||||
}
|
||||
|
@ -1,181 +0,0 @@
|
||||
--- 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;
|
||||
+}
|
@ -1,11 +0,0 @@
|
||||
--- 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__ */
|
||||
|
@ -1,46 +0,0 @@
|
||||
--- 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;
|
@ -1,88 +0,0 @@
|
||||
--- 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;
|
@ -1,116 +0,0 @@
|
||||
--- 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 {
|
Loading…
Reference in New Issue
Block a user