Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#3415][#3417]multi-homing: manage coma separated list of incoming interfaces #300

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deluge/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def __init__(

# GeoIP instance with db loaded
self.geoip_instance = None
self.geoip_instance_v6 = None

# These keys will be dropped from the set_config() RPC and are
# configurable from the command-line.
Expand Down
43 changes: 36 additions & 7 deletions deluge/core/preferencesmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import unicode_literals

import ipaddress
import logging
import os
import platform
Expand Down Expand Up @@ -122,6 +123,7 @@
'peer_tos': '0x00',
'rate_limit_ip_overhead': True,
'geoip_db_location': '/usr/share/GeoIP/GeoIP.dat',
'geoip_v6_db_location': '/usr/share/GeoIP/GeoIPv6.dat',
'cache_size': 512,
'cache_expiry': 60,
'auto_manage_prefer_seeds': False,
Expand Down Expand Up @@ -214,24 +216,39 @@ def __set_listen_on(self):
listen_ports = self.config['listen_ports']

if self.config['listen_interface']:
interface = self.config['listen_interface'].strip()
interfaces = self.config['listen_interface'].strip()
else:
interface = '0.0.0.0'
interfaces = '0.0.0.0'

lib_interfaces = []
for interface in interfaces.split(','):
interface = interface.strip()
try:
# add square brackets to ipv6 only, as needed by lib torrent
lib_interfaces.append(
'[' + interface + ']'
if ipaddress.ip_address(interface).version == 6
else interface
)
except ValueError:
# ip address format failed, assume network interface name
lib_interfaces.append(interface)

log.debug(
'Listen Interface: %s, Ports: %s with use_sys_port: %s',
interface,
lib_interfaces,
listen_ports,
self.config['listen_use_sys_port'],
)
interfaces = [
'%s:%s' % (interface, port)
interface_port_list = [
'%s:%s' % (lib_interface, port)
for port in range(listen_ports[0], listen_ports[1] + 1)
for lib_interface in lib_interfaces
]
self.core.apply_session_settings(
{
'listen_system_port_fallback': self.config['listen_use_sys_port'],
'listen_interfaces': ''.join(interfaces),
'listen_interfaces': ','.join(interface_port_list),
}
)

Expand Down Expand Up @@ -461,7 +478,7 @@ def _on_set_rate_limit_ip_overhead(self, key, value):
self.core.apply_session_setting('rate_limit_ip_overhead', value)

def _on_set_geoip_db_location(self, key, geoipdb_path):
# Load the GeoIP DB for country look-ups if available
# Load the GeoIP v4 DB for country look-ups if available
if os.path.exists(geoipdb_path):
try:
self.core.geoip_instance = GeoIP.open(
Expand All @@ -472,6 +489,18 @@ def _on_set_geoip_db_location(self, key, geoipdb_path):
else:
log.warning('Unable to find GeoIP database file: %s', geoipdb_path)

def _on_set_geoip_v6_db_location(self, key, geoipdb_path):
# Load the GeoIP v6 DB for country look-ups if available
if os.path.exists(geoipdb_path):
try:
self.core.geoip_instance_v6 = GeoIP.open(
geoipdb_path, GeoIP.GEOIP_STANDARD
)
except AttributeError:
log.warning('GeoIP Unavailable')
else:
log.warning('Unable to find GeoIP database file: %s', geoipdb_path)

def _on_set_cache_size(self, key, value):
self.core.apply_session_setting('cache_size', value)

Expand Down
11 changes: 9 additions & 2 deletions deluge/core/torrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from __future__ import division, unicode_literals

import ipaddress
import logging
import os
import socket
Expand Down Expand Up @@ -817,8 +818,14 @@ def get_peers(self):
client = 'unknown'

try:
country = component.get('Core').geoip_instance.country_code_by_addr(
peer.ip[0]
country = (
component.get('Core').geoip_instance.country_code_by_addr(
peer.ip[0]
)
if ipaddress.ip_address(peer.ip[0]).version == 4
else component.get(
'Core'
).geoip_instance_v6.country_code_by_addr_v6(peer.ip[0])
)
except AttributeError:
country = ''
Expand Down
6 changes: 5 additions & 1 deletion deluge/ui/console/modes/preferences/preference_panes.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,14 @@ def create_pane(self, core_conf, console_config):
_('Yes, please send anonymous statistics.'),
core_conf['send_info'],
)
self.add_header(_('GeoIP Database'), space_above=True)
self.add_header(_('GeoIP Database IPv4'), space_above=True)
self.add_text_input(
'geoip_db_location', 'Location:', core_conf['geoip_db_location']
)
self.add_header(_('GeoIP Database IPv6'), space_above=True)
self.add_text_input(
'geoip_v6_db_location', 'Location:', core_conf['geoip_v6_db_location']
)


class DaemonPane(BasePreferencePane):
Expand Down
91 changes: 78 additions & 13 deletions deluge/ui/gtk3/glade/preferences_dialog.ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="adjustment_cache_expiry">
Expand Down Expand Up @@ -245,7 +245,7 @@
<property name="type_hint">dialog</property>
<signal name="configure-event" handler="on_pref_dialog_configure_event" swapped="no"/>
<signal name="delete-event" handler="on_pref_dialog_delete_event" swapped="no"/>
<child>
<child type="titlebar">
<placeholder/>
</child>
<child internal-child="vbox">
Expand Down Expand Up @@ -2555,9 +2555,9 @@ used sparingly.</property>
<object class="GtkEntry" id="entry_interface">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The IP address of the interface to listen for incoming bittorrent connections on. Leave this empty if you want to use the default.</property>
<property name="max_length">15</property>
<property name="width_chars">15</property>
<property name="tooltip_text" translatable="yes">Coma separated list of IP addresses / network interface names to be listened for incoming bittorrent connections. Leave this empty if you want to use the default.</property>
<property name="max_length">100</property>
<property name="width_chars">30</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
Expand All @@ -2569,7 +2569,7 @@ used sparingly.</property>
<object class="GtkLabel" id="label110">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Incoming Address</property>
<property name="label" translatable="yes">Incoming Interfaces</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
Expand Down Expand Up @@ -2775,12 +2775,10 @@ used sparingly.</property>
<object class="GtkEntry" id="entry_outgoing_interface">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">
The network interface name or IP address for outgoing BitTorrent connections. (Leave empty for default.)
</property>
<property name="max_length">15</property>
<property name="tooltip_text" translatable="yes">Coma separated list of allowed IP addresses / network interface names for outgoing bittorrent TCP connections. Leave this empty if you want to use the default.</property>
<property name="max_length">100</property>
<property name="invisible_char">●</property>
<property name="width_chars">15</property>
<property name="width_chars">30</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
Expand Down Expand Up @@ -4270,7 +4268,7 @@ the proxy instead of using the local DNS service</property>
<object class="GtkLabel" id="label108">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">GeoIP Database</property>
<property name="label" translatable="yes">GeoIP Database IPv4</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
Expand All @@ -4284,6 +4282,73 @@ the proxy instead of using the local DNS service</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame23">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment31">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="top_padding">2</property>
<property name="left_padding">12</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkLabel" id="label26">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Location:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_geoipv6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If Deluge cannot find the database file at this location it will fallback to using DNS to resolve the peer's country.</property>
<property name="invisible_char">●</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label34">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">GeoIP Database IPv6</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame17">
<property name="visible">True</property>
Expand Down Expand Up @@ -4363,7 +4428,7 @@ the proxy instead of using the local DNS service</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
</object>
Expand Down
5 changes: 3 additions & 2 deletions deluge/ui/gtk3/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ def _show(self):
'chk_new_releases': ('active', 'new_release_check'),
'chk_send_info': ('active', 'send_info'),
'entry_geoip': ('text', 'geoip_db_location'),
'entry_geoipv6': ('text', 'geoip_v6_db_location'),
'combo_encin': ('active', 'enc_in_policy'),
'combo_encout': ('active', 'enc_out_policy'),
'combo_enclevel': ('active', 'enc_level'),
Expand Down Expand Up @@ -677,8 +678,8 @@ def set_config(self, hide=False):
'chk_random_outgoing_ports'
).get_active()
incoming_address = self.builder.get_object('entry_interface').get_text().strip()
if deluge.common.is_ip(incoming_address) or not incoming_address:
new_core_config['listen_interface'] = incoming_address

new_core_config['listen_interface'] = incoming_address
new_core_config['outgoing_interface'] = (
self.builder.get_object('entry_outgoing_interface').get_text().strip()
)
Expand Down
18 changes: 4 additions & 14 deletions deluge/ui/web/js/deluge-all/preferences/NetworkPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@
*/
Ext.namespace('Deluge.preferences');

// custom Vtype for vtype:'IPAddress'
Ext.apply(Ext.form.VTypes, {
IPAddress: function(v) {
return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(v);
},
IPAddressText: 'Must be a numeric IP address',
IPAddressMask: /[\d\.]/i,
});

/**
* @class Deluge.preferences.Network
* @extends Ext.form.FormPanel
Expand All @@ -35,7 +26,7 @@ Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Incoming Address'),
title: _('Incoming Interfaces (coma separated)'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
Expand All @@ -47,8 +38,7 @@ Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
name: 'listen_interface',
fieldLabel: '',
labelSeparator: '',
width: 200,
vtype: 'IPAddress',
width: 250,
})
);

Expand Down Expand Up @@ -98,7 +88,7 @@ Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Outgoing Interface'),
title: _('Outgoing Interfaces (coma separated)'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
Expand All @@ -110,7 +100,7 @@ Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
name: 'outgoing_interface',
fieldLabel: '',
labelSeparator: '',
width: 40,
width: 250,
})
);

Expand Down
20 changes: 19 additions & 1 deletion deluge/ui/web/js/deluge-all/preferences/OtherPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, {
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('GeoIP Database'),
title: _('GeoIP IPv4 Database'),
autoHeight: true,
labelWidth: 80,
defaultType: 'textfield',
Expand All @@ -96,5 +96,23 @@ Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, {
width: 200,
})
);

fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('GeoIP IPv6 Database'),
autoHeight: true,
labelWidth: 80,
defaultType: 'textfield',
});
optMan.bind(
'geoip_v6_db_location',
fieldset.add({
name: 'geoip_v6_db_location',
fieldLabel: _('Path:'),
labelSeparator: '',
width: 200,
})
);
},
});