diff --git a/htroot/SettingsAck_p.html b/htroot/SettingsAck_p.html index daedbbc1f..271ebfde6 100644 --- a/htroot/SettingsAck_p.html +++ b/htroot/SettingsAck_p.html @@ -28,18 +28,26 @@ Your request cannot be processed.
Nothing changed. Your administration account setting has been made.
Your new administration account name is #[user]#. The password has been accepted.
If you go back to the Settings page, you must log-in again. :: -Your proxy access setting has been changed.
-Your proxy account check has been disabled, since you did not supply a password.

-The new proxy IP filter is set to #[filter]#
-The proxy port is: #[port]#

-if you changed the Port or Port Forwarding Settings, you need to restart YaCy. + Your proxy access setting has been changed.
+ Your proxy account check has been disabled, since you did not supply a password.

+ The new proxy IP filter is set to #[filter]#
+ The proxy port is: #[port]#

+ #(restart)# + :: + Port rebinding will be done in a view seconds.
+ You can reach your YaCy server under the new location http://#[ip]#:#[port]#/ + #(/restart)# :: -Your proxy access setting has been changed.
-Your new proxy account name is #[user]#. The password has been accepted.
-If you open any public web page through the proxy, you must log-in then.

-The new proxy IP filter is set to #[filter]#.
-The proxy port is: #[port]#

-if you changed the Port or Port Forwarding Settings, you need to restart YaCy. + Your proxy access setting has been changed.
+ Your new proxy account name is #[user]#. The password has been accepted.
+ If you open any public web page through the proxy, you must log-in then.

+ The new proxy IP filter is set to #[filter]#.
+ The proxy port is: #[port]#

+ #(restart)# + :: + Port rebinding will be done in a view seconds.
+ You can reach your YaCy server under the new location http://#[ip]#:#[port]#/ + #(/restart)# :: Your server access filter is now set to #[filter]#
You are now in Cache Mode. Only Proxy-cache ist available in this mode. After a short while you should see the effect on the status page.
+:: +

Unable to bild the server to the new Port: #[port]#
+This values seems not to be a valid port configuration. #(/info)#

You can now go back to the Settings page if you want to make more changes.

- #[footer]# diff --git a/htroot/SettingsAck_p.java b/htroot/SettingsAck_p.java index 89e34a4ed..8e710581e 100644 --- a/htroot/SettingsAck_p.java +++ b/htroot/SettingsAck_p.java @@ -46,6 +46,8 @@ // javac -classpath .:../Classes SettingsAck_p.java // if the shell's current path is HTROOT +import java.net.InetSocketAddress; +import java.net.SocketException; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -127,10 +129,30 @@ public class SettingsAck_p { // proxy password if (post.containsKey("proxyaccount")) { - // set new port + /* + * set new port + */ String port = (String) post.get("port"); - env.setConfig("port", port); prop.put("info_port", port); + if (!env.getConfig("port", port).equals(port)) { + // validation port + serverCore theServerCore = (serverCore) env.getThread("10_httpd"); + try { + InetSocketAddress theNewAddress = theServerCore.generateSocketAddress(port); + String hostName = theNewAddress.getHostName(); + prop.put("info_restart",1); + prop.put("info_restart_ip",(hostName.equals("0.0.0.0"))?"localhost":hostName); + prop.put("info_restart_port",Integer.toString(theNewAddress.getPort())); + + env.setConfig("port", port); + + theServerCore.reconnect(); + } catch (SocketException e) { + prop.put("info_restart",0); + } + } else { + prop.put("info_restart",26); + } // read and process data String filter = (String) post.get("proxyfilter"); diff --git a/htroot/Settings_ProxyAccess.inc b/htroot/Settings_ProxyAccess.inc index a237cbd97..277d728e7 100644 --- a/htroot/Settings_ProxyAccess.inc +++ b/htroot/Settings_ProxyAccess.inc @@ -2,12 +2,21 @@
Server Access Settings These settings configure the access method to your own http proxy and server. All traffic is routed throug one single port, for both proxy and server.
-
Port Configuration

+
Server/Proxy Port Configuration
+

The socket addresses where YaCy should listen for incomming connections from other YaCy peers or http clients.
+You have four possibilities to specify the address:


+Hint: Dont forget to change your firewall configuration after you have changed the port. +

- - + +
Proxy and http-Server Administration Port:Changes will take effect after restart only.Changes will take effect in 5-10 seconds
diff --git a/source/de/anomic/server/serverCore.java b/source/de/anomic/server/serverCore.java index eb75ce801..fbfef0e67 100644 --- a/source/de/anomic/server/serverCore.java +++ b/source/de/anomic/server/serverCore.java @@ -60,6 +60,7 @@ import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketException; import java.net.URL; import java.net.UnknownHostException; import java.nio.channels.ClosedByInterruptException; @@ -80,6 +81,7 @@ import de.anomic.icap.icapd; import de.anomic.server.logging.serverLog; import de.anomic.yacy.yacyCore; import de.anomic.yacy.yacySeed; +import de.anomic.yacy.yacySeedDB; import de.anomic.plasma.plasmaSwitchboard; public final class serverCore extends serverAbstractThread implements serverThread { @@ -97,6 +99,7 @@ public final class serverCore extends serverAbstractThread implements serverThre // class variables private String port; // the listening port + public boolean forceRestart = false; // specifies if the server should try to do a restart public static boolean portForwardingEnabled = false; public static serverPortForwarding portForwarding = null; @@ -115,7 +118,7 @@ public final class serverCore extends serverAbstractThread implements serverThre /** * The session-object pool */ - final SessionPool theSessionPool; + SessionPool theSessionPool; final ThreadGroup theSessionThreadGroup = new ThreadGroup("sessionThreadGroup"); private Config cralwerPoolConfig = null; @@ -171,15 +174,13 @@ public final class serverCore extends serverAbstractThread implements serverThre } // class initializer - public serverCore( - String port, + public serverCore( int timeout, boolean blockAttack, serverHandler handlerPrototype, serverSwitch switchboard, int commandMaxLength ) throws IOException { - this.port = port.trim(); this.timeout = timeout; this.commandMaxLength = commandMaxLength; @@ -189,80 +190,27 @@ public final class serverCore extends serverAbstractThread implements serverThre // initialize logger this.log = new serverLog("SERVER"); + + // init servercore + init(); + } + + public synchronized void init() { + this.log.logInfo("Initializing serverCore ..."); - /* - try { - ServerSocketFactory ssf = getServerSocketFactory(false, new File("D:\\dev\\proxy\\addon\\testkeys"), "passphrase"); - this.socket = ssf.createServerSocket(port); - //((SSLServerSocket) this.socket ).setNeedClientAuth(true); - } catch (java.net.BindException e) { - System.out.println("FATAL ERROR: " + e.getMessage() + " - probably root access rights needed. check port number"); System.exit(0); - } - */ + // read some config values + this.port = this.switchboard.getConfig("port", "8080").trim(); // Open a new server-socket channel try { - this.log.logInfo("Trying to bind server to port " + port); - - // parsing the port configuration - String bindIP = null; - int bindPort; - - int pos = -1; - if ((pos = port.indexOf(":"))!= -1) { - bindIP = port.substring(0,pos).trim(); - port = port.substring(pos+1); - - if (bindIP.startsWith("#")) { - String interfaceName = bindIP.substring(1); - String hostName = null; - this.log.logFine("Trying to determine IP address of interface '" + interfaceName + "'."); - - Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); - if (interfaces != null) { - while (interfaces.hasMoreElements()) { - NetworkInterface interf = (NetworkInterface) interfaces.nextElement(); - if (interf.getName().equalsIgnoreCase(interfaceName)) { - Enumeration addresses = interf.getInetAddresses(); - if (addresses != null) { - while (addresses.hasMoreElements()) { - InetAddress address = (InetAddress)addresses.nextElement(); - if (address instanceof Inet4Address) { - hostName = address.getHostAddress(); - break; - } - } - } - } - } - } - if (hostName == null) { - this.log.logWarning("Unable to find interface with name '" + interfaceName + "'. Binding server to all interfaces"); - bindIP = null; - } else { - this.log.logInfo("Binding server to interface '" + interfaceName + "' with IP '" + hostName + "'."); - bindIP = hostName; - } - } - } - bindPort = Integer.parseInt(port); - - // Binds the ServerSocket to a specific address - this.socket = new ServerSocket(); - this.socket.bind((bindIP == null) - ? new InetSocketAddress(bindPort) - : new InetSocketAddress(bindIP, bindPort)); - - // this.socket = new ServerSocket(port); - } catch (java.net.BindException e) { + this.initPort(this.port); + } catch (Exception e) { String errorMsg = "FATAL ERROR: " + e.getMessage() + " - probably root access rights needed. check port number"; this.log.logSevere(errorMsg); System.out.println(errorMsg); System.exit(0); } - - // init port forwarding try { this.initPortForwarding(); @@ -274,6 +222,13 @@ public final class serverCore extends serverAbstractThread implements serverThre this.switchboard.setConfig("portForwardingEnabled","false"); } + // init session pool + initSessionPool(); + } + + public void initSessionPool() { + this.log.logInfo("Initializing session pool ..."); + // implementation of session thread pool this.cralwerPoolConfig = new GenericObjectPool.Config(); @@ -295,13 +250,75 @@ public final class serverCore extends serverAbstractThread implements serverThre this.cralwerPoolConfig.minEvictableIdleTimeMillis = this.thresholdSleep; this.cralwerPoolConfig.testOnReturn = true; - this.theSessionPool = new SessionPool(new SessionFactory(this.theSessionThreadGroup),this.cralwerPoolConfig); + this.theSessionPool = new SessionPool(new SessionFactory(this.theSessionThreadGroup),this.cralwerPoolConfig); + } + + public void initPort(String thePort) throws IOException { + this.log.logInfo("Trying to bind server to port " + thePort); + + // Binds the ServerSocket to a specific address + InetSocketAddress bindAddress = null; + this.socket = new ServerSocket(); + this.socket.bind(bindAddress = generateSocketAddress(thePort)); + + // updating the port information + yacyCore.seedDB.mySeed.put(yacySeed.PORT,Integer.toString(bindAddress.getPort())); + } + + public InetSocketAddress generateSocketAddress(String thePort) throws SocketException { + + // parsing the port configuration + String bindIP = null; + int bindPort; + + int pos = -1; + if ((pos = thePort.indexOf(":"))!= -1) { + bindIP = thePort.substring(0,pos).trim(); + thePort = thePort.substring(pos+1); + + if (bindIP.startsWith("#")) { + String interfaceName = bindIP.substring(1); + String hostName = null; + this.log.logFine("Trying to determine IP address of interface '" + interfaceName + "'."); + + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + if (interfaces != null) { + while (interfaces.hasMoreElements()) { + NetworkInterface interf = (NetworkInterface) interfaces.nextElement(); + if (interf.getName().equalsIgnoreCase(interfaceName)) { + Enumeration addresses = interf.getInetAddresses(); + if (addresses != null) { + while (addresses.hasMoreElements()) { + InetAddress address = (InetAddress)addresses.nextElement(); + if (address instanceof Inet4Address) { + hostName = address.getHostAddress(); + break; + } + } + } + } + } + } + if (hostName == null) { + this.log.logWarning("Unable to find interface with name '" + interfaceName + "'. Binding server to all interfaces"); + bindIP = null; + } else { + this.log.logInfo("Binding server to interface '" + interfaceName + "' with IP '" + hostName + "'."); + bindIP = hostName; + } + } + } + bindPort = Integer.parseInt(thePort); + return (bindIP == null) + ? new InetSocketAddress(bindPort) + : new InetSocketAddress(bindIP, bindPort); } public void initPortForwarding() throws Exception { // doing the port forwarding stuff if (this.switchboard.getConfig("portForwardingEnabled","false").equalsIgnoreCase("true")) { + this.log.logInfo("Initializing port forwarding ..."); try { String localHost = this.socket.getInetAddress().getHostName(); Integer localPort = new Integer(this.socket.getLocalPort()); @@ -441,52 +458,62 @@ public final class serverCore extends serverAbstractThread implements serverThre // class body public boolean job() throws Exception { - // prepare for new connection - // idleThreadCheck(); - this.switchboard.handleBusyState(this.theSessionPool.getNumActive() /*activeThreads.size() */); - - this.log.logFinest( - "* waiting for connections, " + this.theSessionPool.getNumActive() + " sessions running, " + - this.theSessionPool.getNumIdle() + " sleeping"); - - // wait for new connection - announceThreadBlockApply(); - Socket controlSocket = this.socket.accept(); - announceThreadBlockRelease(); - - String cIP = clientAddress(controlSocket); - //System.out.println("server bfHosts=" + bfHost.toString()); - if (bfHost.get(cIP) != null) { - Integer attempts = (Integer) bfHost.get(cIP); - if (attempts == null) attempts = new Integer(1); else attempts = new Integer(attempts.intValue() + 1); - bfHost.put(cIP, attempts); - this.log.logWarning("SLOWING DOWN ACCESS FOR BRUTE-FORCE PREVENTION FROM " + cIP + ", ATTEMPT " + attempts.intValue()); - // add a delay to make brute-force harder + try { + // prepare for new connection + // idleThreadCheck(); + this.switchboard.handleBusyState(this.theSessionPool.getNumActive() /*activeThreads.size() */); + + this.log.logFinest( + "* waiting for connections, " + this.theSessionPool.getNumActive() + " sessions running, " + + this.theSessionPool.getNumIdle() + " sleeping"); + + // wait for new connection announceThreadBlockApply(); - try {Thread.sleep(attempts.intValue() * 2000);} catch (InterruptedException e) {} + Socket controlSocket = this.socket.accept(); announceThreadBlockRelease(); - if ((attempts.intValue() >= 10) && (this.denyHost != null)) { - this.denyHost.put(cIP, "deny"); + + String cIP = clientAddress(controlSocket); + //System.out.println("server bfHosts=" + bfHost.toString()); + if (bfHost.get(cIP) != null) { + Integer attempts = (Integer) bfHost.get(cIP); + if (attempts == null) attempts = new Integer(1); else attempts = new Integer(attempts.intValue() + 1); + bfHost.put(cIP, attempts); + this.log.logWarning("SLOWING DOWN ACCESS FOR BRUTE-FORCE PREVENTION FROM " + cIP + ", ATTEMPT " + attempts.intValue()); + // add a delay to make brute-force harder + announceThreadBlockApply(); + try {Thread.sleep(attempts.intValue() * 2000);} catch (InterruptedException e) {} + announceThreadBlockRelease(); + if ((attempts.intValue() >= 10) && (this.denyHost != null)) { + this.denyHost.put(cIP, "deny"); + } } - } - - if ((this.denyHost == null) || (this.denyHost.get(cIP) == null)) { - // setting the timeout properly - controlSocket.setSoTimeout(this.timeout); - // getting a free session thread from the pool - Session connection = (Session) this.theSessionPool.borrowObject(); + if ((this.denyHost == null) || (this.denyHost.get(cIP) == null)) { + // setting the timeout properly + controlSocket.setSoTimeout(this.timeout); + + // getting a free session thread from the pool + Session connection = (Session) this.theSessionPool.borrowObject(); + + // processing the new request + connection.execute(controlSocket,this.timeout); + } else { + this.log.logWarning("ACCESS FROM " + cIP + " DENIED"); + } - // processing the new request - connection.execute(controlSocket,this.timeout); - } else { - this.log.logWarning("ACCESS FROM " + cIP + " DENIED"); + return true; + } catch (SocketException e) { + if (this.forceRestart) { + // reinitialize serverCore + init(); + this.forceRestart = false; + return true; + } + throw e; } - - return true; } - public void close() { + public synchronized void close() { // consuming the isInterrupted Flag. Otherwise we could not properly close the session pool Thread.interrupted(); @@ -1192,5 +1219,29 @@ public final class serverCore extends serverAbstractThread implements serverThre if (currentThread.isInterrupted()) throw new InterruptedException(); if ((currentThread instanceof serverCore.Session) && ((serverCore.Session)currentThread).isStopped()) throw new InterruptedException(); } - + + public void reconnect() { + Thread restart = new Restarter(); + restart.start(); + } + + // restarting the serverCore + public class Restarter extends Thread { + public serverCore theServerCore = null; + public void run() { + // waiting for a while + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + // signaling restart + serverCore.this.forceRestart = true; + + // closing socket to notify the thread + serverCore.this.close(); + } + } } diff --git a/source/yacy.java b/source/yacy.java index ea7567bf6..3e565cf0e 100644 --- a/source/yacy.java +++ b/source/yacy.java @@ -327,7 +327,7 @@ public final class yacy { // start main threads try { final httpd protocolHandler = new httpd(sb, new httpdFileHandler(sb), new httpdProxyHandler(sb)); - final serverCore server = new serverCore(port, + final serverCore server = new serverCore( timeout /*control socket timeout in milliseconds*/, true /* block attacks (wrong protocol) */, protocolHandler /*command class*/,