use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.
the class CoreImpl method start.
@Override
public void start() throws CoreException {
if (!canStart()) {
throw (new CoreException("Core: already started (alternative process)"));
}
AEThread2.setOurThread();
try {
this_mon.enter();
if (started) {
throw (new CoreException("Core: already started"));
}
if (stopped) {
throw (new CoreException("Core: already stopped"));
}
started = true;
} finally {
this_mon.exit();
}
// If a user sets this property, it is an alias for the following settings.
if ("1".equals(System.getProperty(SystemProperties.SYSPROP_SAFEMODE))) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Safe mode enabled"));
Constants.isSafeMode = true;
System.setProperty(SystemProperties.SYSPROP_LOADPLUGINS, "0");
System.setProperty(SystemProperties.SYSPROP_DISABLEDOWNLOADS, "1");
System.setProperty(SystemProperties.SYSPROP_SKIP_SWTCHECK, "1");
// Not using localised text - not sure it's safe to this early.
Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogEvent.LT_WARNING, "You are running " + Constants.APP_NAME + " in safe mode - you " + "can change your configuration, but any downloads added will " + "not be remembered when you close " + Constants.APP_NAME + "."));
}
/**
* test to see if UI plays nicely with a really slow initialization
*/
String sDelayCore = System.getProperty("delay.core", null);
if (sDelayCore != null) {
try {
long delayCore = Long.parseLong(sDelayCore);
Thread.sleep(delayCore);
} catch (Exception e) {
e.printStackTrace();
}
}
// run plugin loading in parallel to the global manager loading
AEThread2 pluginload = new AEThread2("PluginLoader", true) {
@Override
public void run() {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Loading of Plugins starts"));
pi.loadPlugins(CoreImpl.this, false, !"0".equals(System.getProperty(SystemProperties.SYSPROP_LOADPLUGINS)), true, true);
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Loading of Plugins complete"));
}
};
if (LOAD_PLUGINS_IN_OTHER_THREAD) {
pluginload.start();
} else {
pluginload.run();
}
// Disable async loading of existing torrents, because there are many things
// (like hosting) that require all the torrents to be loaded. While we
// can write code for each of these cases to wait until the torrents are
// loaded, it's a pretty big job to find them all and fix all their quirks.
// Too big of a job for this late in the release stage.
// Other example is the tracker plugin that is coded in a way where it must
// always publish a complete rss feed
global_manager = GlobalManagerFactory.create(this, null, 0);
if (stopped) {
System.err.println("Core stopped while starting");
return;
}
// wait until plugin loading is done
if (LOAD_PLUGINS_IN_OTHER_THREAD) {
pluginload.join();
}
if (stopped) {
System.err.println("Core stopped while starting");
return;
}
VuzeFileHandler.getSingleton().addProcessor(new VuzeFileProcessor() {
@Override
public void process(VuzeFile[] files, int expected_types) {
for (int i = 0; i < files.length; i++) {
VuzeFile vf = files[i];
VuzeFileComponent[] comps = vf.getComponents();
for (int j = 0; j < comps.length; j++) {
VuzeFileComponent comp = comps[j];
int comp_type = comp.getType();
if (comp_type == VuzeFileComponent.COMP_TYPE_ADD_TORRENT) {
PluginInterface default_pi = getPluginManager().getDefaultPluginInterface();
Map map = comp.getContent();
try {
Torrent torrent;
String url = MapUtils.getMapString(map, "torrent_url", null);
if (url != null) {
TorrentDownloader dl = default_pi.getTorrentManager().getURLDownloader(new URL(url));
torrent = dl.download();
} else {
String tf = MapUtils.getMapString(map, "torrent_file", null);
if (tf != null) {
File file = new File(tf);
if (!file.canRead() || file.isDirectory()) {
throw (new Exception("torrent_file '" + tf + "' is invalid"));
}
torrent = default_pi.getTorrentManager().createFromBEncodedFile(file);
} else {
throw (new Exception("torrent_url or torrent_file must be specified"));
}
}
File dest = null;
String save_folder = MapUtils.getMapString(map, "save_folder", null);
if (save_folder != null) {
dest = new File(save_folder, torrent.getName());
} else {
String save_file = MapUtils.getMapString(map, "save_file", null);
if (save_file != null) {
dest = new File(save_file);
}
}
if (dest != null) {
dest.getParentFile().mkdirs();
}
default_pi.getDownloadManager().addDownload(torrent, null, dest);
} catch (Throwable e) {
Debug.out(e);
}
comp.setProcessed();
}
}
}
}
});
triggerLifeCycleComponentCreated(global_manager);
pi.initialisePlugins();
if (stopped) {
System.err.println("Core stopped while starting");
return;
}
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Initializing Plugins complete"));
try {
PluginInterface dht_pi = getPluginManager().getPluginInterfaceByClass(DHTPlugin.class);
if (dht_pi != null) {
dht_pi.addEventListener(new PluginEventListener() {
private boolean first_dht = true;
@Override
public void handleEvent(PluginEvent ev) {
if (ev.getType() == DHTPlugin.EVENT_DHT_AVAILABLE) {
if (first_dht) {
first_dht = false;
DHT dht = (DHT) ev.getValue();
dht.addListener(new DHTListener() {
@Override
public void speedTesterAvailable(DHTSpeedTester tester) {
if (speed_manager != null) {
speed_manager.setSpeedTester(tester);
}
}
});
global_manager.addListener(new GlobalManagerAdapter() {
@Override
public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
checkConfig();
}
});
COConfigurationManager.addAndFireParameterListeners(new String[] { TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY, TransferSpeedValidator.AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY }, new ParameterListener() {
@Override
public void parameterChanged(String parameterName) {
checkConfig();
}
});
}
}
}
protected void checkConfig() {
if (speed_manager != null) {
speed_manager.setEnabled(TransferSpeedValidator.isAutoSpeedActive(global_manager));
}
}
});
}
} catch (Throwable e) {
}
if (COConfigurationManager.getBooleanParameter("Resume Downloads On Start")) {
global_manager.resumeDownloads();
}
VersionCheckClient.getSingleton().initialise();
instance_manager.initialize();
NetworkManager.getSingleton().initialize(this);
SpeedLimitHandler.getSingleton(this);
Runtime.getRuntime().addShutdownHook(new AEThread("Shutdown Hook") {
@Override
public void runSupport() {
Logger.log(new LogEvent(LOGID, "Shutdown hook triggered"));
CoreImpl.this.stop();
}
});
DelayedTask delayed_task = UtilitiesImpl.addDelayedTask("Core", new Runnable() {
@Override
public void run() {
new AEThread2("core:delayTask", true) {
@Override
public void run() {
AEDiagnostics.checkDumpsAndNatives();
COConfigurationManager.setParameter("diags.enable.pending.writes", true);
AEDiagnostics.flushPendingLogs();
NetworkAdmin na = NetworkAdmin.getSingleton();
na.runInitialChecks(CoreImpl.this);
na.addPropertyChangeListener(new NetworkAdminPropertyChangeListener() {
private String last_as;
@Override
public void propertyChanged(String property) {
NetworkAdmin na = NetworkAdmin.getSingleton();
if (property.equals(NetworkAdmin.PR_NETWORK_INTERFACES)) {
boolean found_usable = false;
NetworkAdminNetworkInterface[] intf = na.getInterfaces();
for (int i = 0; i < intf.length; i++) {
NetworkAdminNetworkInterfaceAddress[] addresses = intf[i].getAddresses();
for (int j = 0; j < addresses.length; j++) {
if (!addresses[j].isLoopback()) {
found_usable = true;
}
}
}
if (!found_usable) {
return;
}
Logger.log(new LogEvent(LOGID, "Network interfaces have changed (new=" + na.getNetworkInterfacesAsString() + ")"));
announceAll(false);
} else if (property.equals(NetworkAdmin.PR_AS)) {
String as = na.getCurrentASN().getAS();
if (last_as == null) {
last_as = as;
} else if (!as.equals(last_as)) {
Logger.log(new LogEvent(LOGID, "AS has changed (new=" + as + ")"));
last_as = as;
announceAll(false);
}
}
}
});
setupSleepAndCloseActions();
}
}.start();
}
});
delayed_task.queue();
if (stopped) {
System.err.println("Core stopped while starting");
return;
}
PairingManagerFactory.getSingleton();
CoreRunningListener[] runningListeners;
mon_coreRunningListeners.enter();
try {
if (coreRunningListeners == null) {
runningListeners = new CoreRunningListener[0];
} else {
runningListeners = coreRunningListeners.toArray(new CoreRunningListener[0]);
coreRunningListeners = null;
}
} finally {
mon_coreRunningListeners.exit();
}
// Trigger Listeners now that core is started
new AEThread2("Plugin Init Complete", false) {
@Override
public void run() {
try {
PlatformManagerFactory.getPlatformManager().startup(CoreImpl.this);
} catch (Throwable e) {
Debug.out("PlatformManager: init failed", e);
}
Iterator it = lifecycle_listeners.iterator();
while (it.hasNext()) {
try {
CoreLifecycleListener listener = (CoreLifecycleListener) it.next();
if (!listener.requiresPluginInitCompleteBeforeStartedEvent()) {
listener.started(CoreImpl.this);
}
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
pi.initialisationComplete();
it = lifecycle_listeners.iterator();
while (it.hasNext()) {
try {
CoreLifecycleListener listener = (CoreLifecycleListener) it.next();
if (listener.requiresPluginInitCompleteBeforeStartedEvent()) {
listener.started(CoreImpl.this);
}
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
}
}.start();
// Typically there are many runningListeners, most with quick execution, and
// a few longer ones. Let 3 run at a time, queue the rest. Without
// a ThreadPool, the slow ones would delay the startup processes that run
// after this start() method
ThreadPool tp = new ThreadPool("Trigger CoreRunning Listeners", 3);
for (final CoreRunningListener l : runningListeners) {
try {
tp.run(new AERunnable() {
@Override
public void runSupport() {
l.coreRunning(CoreImpl.this);
}
});
} catch (Throwable t) {
Debug.out(t);
}
}
// Debug.out("Core Start Complete");
}
use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.
the class WebPlugin method setupServer.
protected void setupServer() {
try {
if (!plugin_enabled) {
if (tracker_context != null) {
tracker_context.destroy();
tracker_context = null;
}
return;
}
final int port = param_port.getValue();
String protocol_str = param_protocol.getValue().trim();
String bind_str = param_bind.getValue().trim();
InetAddress bind_ip = null;
if (bind_str.length() > 0) {
try {
bind_ip = InetAddress.getByName(bind_str);
} catch (Throwable e) {
}
if (bind_ip == null) {
// might be an interface name, see if we can resolve it
final NetworkAdmin na = NetworkAdmin.getSingleton();
InetAddress[] addresses = na.resolveBindAddresses(bind_str);
if (addresses.length > 0) {
bind_ip = addresses[0];
if (!na_intf_listener_added) {
na_intf_listener_added = true;
na.addPropertyChangeListener(new NetworkAdminPropertyChangeListener() {
@Override
public void propertyChanged(String property) {
if (unloaded) {
na.removePropertyChangeListener(this);
} else {
if (property == NetworkAdmin.PR_NETWORK_INTERFACES) {
new AEThread2("setupserver") {
@Override
public void run() {
setupServer();
}
}.start();
}
}
}
});
}
}
}
if (bind_ip == null) {
log.log(LoggerChannel.LT_ERROR, "Bind IP parameter '" + bind_str + "' is invalid");
}
}
if (tracker_context != null) {
URL url = tracker_context.getURLs()[0];
String existing_protocol = url.getProtocol();
int existing_port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();
InetAddress existing_bind_ip = tracker_context.getBindIP();
if (existing_port == port && existing_protocol.equalsIgnoreCase(protocol_str) && sameAddress(bind_ip, existing_bind_ip)) {
return;
}
tracker_context.destroy();
tracker_context = null;
}
int protocol = protocol_str.equalsIgnoreCase("HTTP") ? Tracker.PR_HTTP : Tracker.PR_HTTPS;
Map<String, Object> tc_properties = new HashMap<>();
Boolean prop_non_blocking = (Boolean) properties.get(PR_NON_BLOCKING);
if (prop_non_blocking != null && prop_non_blocking) {
tc_properties.put(Tracker.PR_NON_BLOCKING, true);
}
log.log(LoggerChannel.LT_INFORMATION, "Server initialisation: port=" + port + (bind_ip == null ? "" : (", bind=" + bind_str + "->" + bind_ip + ")")) + ", protocol=" + protocol_str + (root_dir.length() == 0 ? "" : (", root=" + root_dir)) + (properties.size() == 0 ? "" : (", props=" + properties)));
tracker_context = plugin_interface.getTracker().createWebContext(Constants.APP_NAME + " - " + plugin_interface.getPluginName(), port, protocol, bind_ip, tc_properties);
Boolean prop_enable_i2p = (Boolean) properties.get(PR_ENABLE_I2P);
if (prop_enable_i2p == null || prop_enable_i2p) {
network_dispatcher.dispatch(new AERunnable() {
@Override
public void runSupport() {
Map<String, Object> options = new HashMap<>();
options.put(AEProxyFactory.SP_PORT, port);
Map<String, Object> reply = AEProxyFactory.getPluginServerProxy(plugin_interface.getPluginName(), AENetworkClassifier.AT_I2P, plugin_interface.getPluginID(), options);
if (reply != null) {
param_i2p_dest.setVisible(true);
String host = (String) reply.get("host");
if (!param_i2p_dest.getValue().equals(host)) {
param_i2p_dest.setValue(host);
if (p_sid != null) {
updatePairing(p_sid);
}
}
}
}
});
}
Boolean prop_enable_tor = (Boolean) properties.get(PR_ENABLE_TOR);
if (prop_enable_tor == null || prop_enable_tor) {
network_dispatcher.dispatch(new AERunnable() {
@Override
public void runSupport() {
Map<String, Object> options = new HashMap<>();
options.put(AEProxyFactory.SP_PORT, port);
Map<String, Object> reply = AEProxyFactory.getPluginServerProxy(plugin_interface.getPluginName(), AENetworkClassifier.AT_TOR, plugin_interface.getPluginID(), options);
if (reply != null) {
param_tor_dest.setVisible(true);
String host = (String) reply.get("host");
if (!param_tor_dest.getValue().equals(host)) {
param_tor_dest.setValue(host);
if (p_sid != null) {
updatePairing(p_sid);
}
}
}
}
});
}
Boolean pr_enable_keep_alive = (Boolean) properties.get(PR_ENABLE_KEEP_ALIVE);
if (pr_enable_keep_alive != null && pr_enable_keep_alive) {
tracker_context.setEnableKeepAlive(true);
}
tracker_context.addPageGenerator(this);
tracker_context.addAuthenticationListener(new TrackerAuthenticationAdapter() {
private String last_pw = "";
private byte[] last_hash = {};
private final int DELAY = 10 * 1000;
private Map<String, Object[]> fail_map = new HashMap<>();
@Override
public boolean authenticate(String headers, URL resource, String user, String pw) {
// System.out.println( resource + ": " + user + "/" + pw );
long now = SystemTime.getMonotonousTime();
String client_address = getHeaderField(headers, "X-Real-IP");
if (client_address == null) {
client_address = "<unknown>";
}
synchronized (logout_timer) {
Long logout_time = logout_timer.get(client_address);
if (logout_time != null && now - logout_time <= LOGOUT_GRACE_MILLIS) {
tls.set(GRACE_PERIOD_MARKER);
return (true);
}
}
boolean result = authenticateSupport(headers, resource, user, pw);
if (!result) {
if (!pw.equals("")) {
AESemaphore waiter = null;
synchronized (fail_map) {
Object[] x = fail_map.get(client_address);
if (x == null) {
x = new Object[] { new AESemaphore("af:waiter"), new Long(-1), new Long(-1), now };
fail_map.put(client_address, x);
} else {
x[1] = x[2];
x[2] = x[3];
x[3] = now;
long t = (Long) x[1];
if (now - t < 10 * 1000) {
log("Too many recent authentication failures from '" + client_address + "' - rate limiting");
x[2] = now + DELAY;
// there's a bug where flipping the password on doesn't reset the pw so we automatically fail without checking
// this is not the correct fix, but it works
last_pw = "";
waiter = (AESemaphore) x[0];
}
}
}
if (waiter != null) {
waiter.reserve(DELAY);
}
}
} else {
synchronized (fail_map) {
fail_map.remove(client_address);
}
String cookies = getHeaderField(headers, "Cookie");
if (pairing_session_code != null) {
if (cookies == null || !cookies.contains(pairing_session_code)) {
tls.set(pairing_session_code);
}
}
}
recordAuthRequest(client_address, result);
if (!result) {
// going to be generous here as (old android browsers at least) sometimes fail to provide
// auth on .png files
// no I'm not, too many risks associated with this (e.g. xmwebui has some
// prefix url logic which may be exploitable)
// if ( resource.getPath().endsWith( ".png" )){
//
// result = true;
// }
}
return (result);
}
private boolean authenticateSupport(String headers, URL resource, String user, String pw) {
boolean result;
boolean auto_auth = param_auto_auth != null && param_auto_auth.getValue();
if (!pw_enable.getValue()) {
String whitelist = p_no_pw_whitelist.getValue().trim();
if (whitelist.equals("*")) {
result = true;
} else {
String actual_host = getHeaderField(headers, "host");
int actual_port = protocol == Tracker.PR_HTTP ? 80 : 443;
String referrer = getHeaderField(headers, "referer");
if (actual_host.startsWith("[")) {
int pos = actual_host.lastIndexOf(']');
if (pos != -1) {
String rem = actual_host.substring(pos + 1);
actual_host = actual_host.substring(0, pos + 1);
pos = rem.indexOf(':');
if (pos != -1) {
actual_port = Integer.parseInt(rem.substring(pos + 1).trim());
}
}
} else {
int pos = actual_host.indexOf(':');
if (pos != -1) {
actual_port = Integer.parseInt(actual_host.substring(pos + 1).trim());
actual_host = actual_host.substring(0, pos);
}
}
String[] allowed = whitelist.split(",");
result = false;
String msg = "";
if (actual_port != port) {
msg = "port mismatch: " + port + "/" + actual_port;
} else {
for (String a : allowed) {
a = a.trim();
if (a.equals("$")) {
InetAddress bind = getServerBindIP();
if (bind != null) {
if (bind instanceof Inet6Address) {
a = "[" + bind.getHostAddress() + "]";
} else {
a = bind.getHostAddress();
}
}
}
if (actual_host.equals(a.trim())) {
result = true;
break;
}
// Support ranges (copied from code in setupAccess)
IPRange ip_range = plugin_interface.getIPFilter().createRange(true);
String aTrimmed = a.trim();
int sep = aTrimmed.indexOf("-");
if (sep == -1) {
ip_range.setStartIP(aTrimmed);
ip_range.setEndIP(aTrimmed);
} else {
ip_range.setStartIP(aTrimmed.substring(0, sep).trim());
ip_range.setEndIP(aTrimmed.substring(sep + 1).trim());
}
ip_range.checkValid();
if (ip_range.isValid() && ip_range.isInRange(actual_host)) {
result = true;
break;
}
}
if (!result) {
msg = "host '" + actual_host + "' not in whitelist";
} else {
if (referrer != null) {
result = false;
try {
URL url = new URL(referrer);
int ref_port = url.getPort();
if (ref_port == -1) {
ref_port = url.getDefaultPort();
}
if (ref_port == port) {
result = true;
}
} catch (Throwable e) {
}
if (!result) {
msg = "referrer mismatch: " + referrer;
}
}
}
}
if (!result) {
log.log("Access denied: No password and " + msg);
}
}
} else {
if (auto_auth) {
user = user.trim().toLowerCase();
pw = pw.toUpperCase();
}
if (!user.equals(p_user_name.getValue())) {
log.log("Access denied: Incorrect user name: " + user);
result = false;
} else {
byte[] hash = last_hash;
if (!last_pw.equals(pw)) {
hash = plugin_interface.getUtilities().getSecurityManager().calculateSHA1(auto_auth ? pw.toUpperCase().getBytes() : pw.getBytes());
last_pw = pw;
last_hash = hash;
}
result = Arrays.equals(hash, p_password.getValue());
if (!result) {
log.log("Access denied: Incorrect password");
}
}
}
if (result) {
// user name and password match, see if we've come from the pairing process
checkCookieSet(headers, resource);
} else if (auto_auth) {
// either the ac is in the url, referer or we have a cookie set
int x = checkCookieSet(headers, resource);
if (x == 1) {
result = true;
} else if (x == 0) {
result = hasOurCookie(getHeaderField(headers, "Cookie"));
}
} else {
result = hasOurCookie(getHeaderField(headers, "Cookie"));
}
return (result);
}
/**
* @param headers
* @param resource
* @return 0 = unknown, 1 = ok, 2 = bad
*/
private int checkCookieSet(String headers, URL resource) {
if (pairing_access_code == null) {
return (2);
}
String[] locations = { resource.getQuery(), getHeaderField(headers, "Referer") };
for (String location : locations) {
if (location != null) {
boolean skip_fail = false;
int param_len = 0;
int p1 = location.indexOf("vuze_pairing_ac=");
if (p1 == -1) {
p1 = location.indexOf("ac=");
if (p1 != -1) {
param_len = 3;
skip_fail = true;
}
} else {
param_len = 16;
}
if (p1 != -1) {
int p2 = location.indexOf('&', p1);
String ac = location.substring(p1 + param_len, p2 == -1 ? location.length() : p2).trim();
p2 = ac.indexOf('#');
if (p2 != -1) {
ac = ac.substring(0, p2);
}
if (ac.equalsIgnoreCase(pairing_access_code)) {
tls.set(pairing_session_code);
return (1);
} else {
if (!skip_fail) {
return (2);
}
}
}
}
}
return (0);
}
private String getHeaderField(String headers, String field) {
String[] lines = headers.split("\n");
for (String line : lines) {
int pos = line.indexOf(':');
if (pos != -1) {
if (line.substring(0, pos).equalsIgnoreCase(field)) {
return (line.substring(pos + 1).trim());
}
}
}
return (null);
}
});
} catch (TrackerException e) {
log.log("Server initialisation failed", e);
}
}
use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.
the class PMSWTImpl method initialise.
@Override
public void initialise(final PluginInterface pi, final BooleanParameter icon_enable) {
final NetworkAdmin na = NetworkAdmin.getSingleton();
na.addPropertyChangeListener(new NetworkAdminPropertyChangeListener() {
@Override
public void propertyChanged(String property) {
if (property == NetworkAdmin.PR_NETWORK_INTERFACES) {
updateLocalAddresses(na);
}
}
});
updateLocalAddresses(na);
pi.getUIManager().addUIListener(new UIManagerListener() {
@Override
public void UIAttached(final UIInstance instance) {
if (instance instanceof UISWTInstance) {
UIFunctions uif = UIFunctionsManager.getUIFunctions();
if (uif != null) {
uiUpdaterListener = new UIUpdaterListener() {
@Override
public void updateComplete(int count) {
last_update_count = count;
updateStatus(true);
}
};
uif.getUIUpdater().addListener(uiUpdaterListener);
}
Utils.execSWTThread(new AERunnable() {
@Override
public void runSupport() {
ImageLoader imageLoader = ImageLoader.getInstance();
icon_idle = imageLoader.getImage("pair_sb_idle");
icon_green = imageLoader.getImage("pair_sb_green");
icon_red = imageLoader.getImage("pair_sb_red");
UISWTInstance ui_instance = (UISWTInstance) instance;
status = ui_instance.createStatusEntry();
last_tooltip_text = MessageText.getString("pairing.ui.icon.tip");
status.setTooltipText(last_tooltip_text);
status.setImageEnabled(true);
status.setImage(icon_idle);
last_image = icon_idle;
boolean is_visible = icon_enable.getValue();
status.setVisible(is_visible);
if (is_visible) {
updateStatus(false);
}
final MenuItem mi_show = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "pairing.ui.icon.show");
mi_show.setStyle(MenuItem.STYLE_CHECK);
mi_show.setData(Boolean.valueOf(is_visible));
mi_show.addListener(new MenuItemListener() {
@Override
public void selected(MenuItem menu, Object target) {
icon_enable.setValue(false);
}
});
iconEnableListener = new ParameterListener() {
@Override
public void parameterChanged(Parameter param) {
boolean is_visible = icon_enable.getValue();
status.setVisible(is_visible);
mi_show.setData(Boolean.valueOf(is_visible));
if (is_visible) {
updateStatus(false);
}
}
};
icon_enable.addListener(iconEnableListener);
MenuItem mi_pairing = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "MainWindow.menu.pairing");
mi_pairing.addListener(new MenuItemListener() {
@Override
public void selected(MenuItem menu, Object target) {
UIFunctions uif = UIFunctionsManager.getUIFunctions();
if (uif == null) {
Debug.out("UIFunctions not available, can't open remote pairing window");
} else {
uif.openRemotePairingWindow();
}
}
});
MenuItem mi_sep = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "");
mi_sep.setStyle(MenuItem.STYLE_SEPARATOR);
MenuItem mi_options = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "MainWindow.menu.view.configuration");
mi_options.addListener(new MenuItemListener() {
@Override
public void selected(MenuItem menu, Object target) {
UIFunctions uif = UIFunctionsManager.getUIFunctions();
if (uif != null) {
uif.getMDI().showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, PairingManager.CONFIG_SECTION_ID);
}
}
});
UISWTStatusEntryListener click_listener = new UISWTStatusEntryListener() {
@Override
public void entryClicked(UISWTStatusEntry entry) {
UIFunctions uif = UIFunctionsManager.getUIFunctions();
if (uif != null) {
uif.getMDI().showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, PairingManager.CONFIG_SECTION_ID);
}
}
};
status.setListener(click_listener);
}
});
}
}
@Override
public void UIDetached(UIInstance instance) {
if (instance instanceof UISWTInstance) {
UIFunctions uif = UIFunctionsManager.getUIFunctions();
if (uif != null && uiUpdaterListener != null) {
uif.getUIUpdater().removeListener(uiUpdaterListener);
uiUpdaterListener = null;
}
if (status != null) {
// menu items get destroyed with this call
status.destroy();
status = null;
}
if (icon_enable != null && iconEnableListener != null) {
icon_enable.removeListener(iconEnableListener);
iconEnableListener = null;
}
}
}
});
}
use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.
the class PRUDPPacketHandlerImpl method receiveLoop.
protected void receiveLoop(AESemaphore init_sem) {
long last_socket_close_time = 0;
NetworkAdminPropertyChangeListener prop_listener = new NetworkAdminPropertyChangeListener() {
@Override
public void propertyChanged(String property) {
if (property == NetworkAdmin.PR_DEFAULT_BIND_ADDRESS) {
setDefaultBindAddress(NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress());
}
}
};
NetworkAdmin.getSingleton().addPropertyChangeListener(prop_listener);
try {
while (!(failed || destroyed)) {
if (socket != null) {
try {
socket.close();
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
InetSocketAddress address = null;
DatagramSocket new_socket = null;
try {
if (target_bind_ip == null) {
address = new InetSocketAddress("127.0.0.1", port);
new_socket = new DatagramSocket(port);
} else {
address = new InetSocketAddress(target_bind_ip, port);
new_socket = new DatagramSocket(address);
}
} catch (BindException e) {
// some firewalls (e.g. Comodo) seem to close sockets on us and then not release them quickly so we come through here and get
// an 'address already in use' failure
boolean rebind_worked = false;
int delay = 25;
for (int i = 0; i < 16 && !(failed || destroyed); i++) {
try {
Thread.sleep(delay);
delay = delay * 2;
if (delay > 1000) {
delay = 1000;
}
if (target_bind_ip == null) {
address = new InetSocketAddress("127.0.0.1", port);
new_socket = new DatagramSocket(port);
} else {
address = new InetSocketAddress(target_bind_ip, port);
new_socket = new DatagramSocket(address);
}
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: rebind to " + target_bind_ip + " worked (tries=" + (i + 1) + ") after getting " + Debug.getNestedExceptionMessage(e)));
rebind_worked = true;
break;
} catch (Throwable f) {
}
}
if (!rebind_worked) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: bind failed with " + Debug.getNestedExceptionMessage(e)));
if (target_bind_ip.isAnyLocalAddress()) {
InetAddress guess = NetworkAdmin.getSingleton().guessRoutableBindAddress();
if (guess != null) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: retrying with bind IP guess of " + guess));
try {
InetSocketAddress guess_address = new InetSocketAddress(guess, port);
new_socket = new DatagramSocket(guess_address);
target_bind_ip = guess;
address = guess_address;
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: Switched to explicit bind ip " + target_bind_ip + " after initial bind failure with wildcard (" + e.getMessage() + ")"));
} catch (Throwable f) {
throw (e);
}
} else {
throw (e);
}
} else {
throw (e);
}
}
}
new_socket.setReuseAddress(true);
// short timeout on receive so that we can interrupt a receive fairly quickly
new_socket.setSoTimeout(1000);
// only make the socket public once fully configured
socket = new_socket;
current_bind_ip = target_bind_ip;
init_sem.release();
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: receiver established on port " + port + (current_bind_ip == null ? "" : (", bound to " + current_bind_ip))));
byte[] buffer = null;
long successful_accepts = 0;
long failed_accepts = 0;
while (!(failed || destroyed)) {
if (current_bind_ip != target_bind_ip) {
break;
}
try {
if (buffer == null) {
buffer = new byte[MAX_PACKET_SIZE];
}
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address);
receiveFromSocket(packet);
if (packet.getLength() > MAX_PACKET_SIZE) {
if (MAX_PACKET_SIZE < PRUDPPacket.MAX_PACKET_SIZE) {
Debug.out("UDP Packet truncated: received length=" + packet.getLength() + ", current max=" + MAX_PACKET_SIZE);
MAX_PACKET_SIZE = Math.min(packet.getLength() + 256, PRUDPPacket.MAX_PACKET_SIZE);
buffer = null;
continue;
}
}
long receive_time = SystemTime.getCurrentTime();
successful_accepts++;
failed_accepts = 0;
for (PRUDPPrimordialHandler prim_hand : primordial_handlers) {
if (prim_hand.packetReceived(packet)) {
// primordial handlers get their own buffer as we can't guarantee
// that they don't need to hang onto the data
buffer = null;
stats.primordialPacketReceived(packet.getLength());
break;
}
}
if (buffer != null) {
process(packet, receive_time);
}
} catch (SocketTimeoutException e) {
} catch (Throwable e) {
// on vista we get periodic socket closures
String message = e.getMessage();
if (socket.isClosed() || (message != null && message.toLowerCase().contains("socket closed"))) {
long now = SystemTime.getCurrentTime();
if (now - last_socket_close_time < 500) {
Thread.sleep(250);
}
last_socket_close_time = now;
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: recycled UDP port " + port + " after close: ok=" + successful_accepts));
break;
}
failed_accepts++;
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: receive failed on port " + port + ": ok=" + successful_accepts + ", fails=" + failed_accepts, e));
if ((failed_accepts > 100 && successful_accepts == 0) || failed_accepts > 1000) {
Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Network.alert.acceptfail"), new String[] { "" + port, "UDP" });
// break, sometimes get a screaming loop. e.g.
/*
[2:01:55] DEBUG::Tue Dec 07 02:01:55 EST 2004
[2:01:55] java.net.SocketException: Socket operation on nonsocket: timeout in datagram socket peek
[2:01:55] at java.net.PlainDatagramSocketImpl.peekData(Native Method)
[2:01:55] at java.net.DatagramSocket.receive(Unknown Source)
[2:01:55] at com.biglybt.core.tracker.server.impl.udp.TRTrackerServerUDP.recvLoop(TRTrackerServerUDP.java:118)
[2:01:55] at com.biglybt.core.tracker.server.impl.udp.TRTrackerServerUDP$1.runSupport(TRTrackerServerUDP.java:90)
[2:01:55] at com.biglybt.core.util.AEThread.run(AEThread.java:45)
*/
init_error = e;
failed = true;
}
}
}
}
} catch (Throwable e) {
init_error = e;
if (!(e instanceof BindException && Constants.isWindowsVistaOrHigher)) {
Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Tracker.alert.listenfail"), new String[] { "UDP:" + port });
}
Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: " + "DatagramSocket bind failed on port " + port, e));
} finally {
init_sem.release();
destroy_sem.releaseForever();
if (socket != null) {
try {
socket.close();
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
// make sure we destroy the delegate too if something happend
PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
if (delegate != null) {
delegate.destroy();
}
NetworkAdmin.getSingleton().removePropertyChangeListener(prop_listener);
}
}
Aggregations