*) Possibility to change the server port on-the-fly.

- Now it's possible to change the server port without the need to restart the whole server.
   

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@1089 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
theli 19 years ago
parent bf6e534975
commit 8e308cf50e

@ -28,18 +28,26 @@ Your request cannot be processed.<br>Nothing changed.
<b>Your administration account setting has been made.</b><br> <b>Your administration account setting has been made.</b><br>
Your new administration account name is #[user]#. The password has been accepted.<br>If you go back to the Settings page, you must log-in again. Your new administration account name is #[user]#. The password has been accepted.<br>If you go back to the Settings page, you must log-in again.
::<!-- 6 --> ::<!-- 6 -->
<b>Your proxy access setting has been changed.<br> <b>Your proxy access setting has been changed.<br>
Your proxy account check has been disabled, since you did not supply a password.</b><p> Your proxy account check has been disabled, since you did not supply a password.</b><p>
The new proxy IP filter is set to #[filter]#<br> The new proxy IP filter is set to <font color="#556699">#[filter]#</font><br>
The proxy port is: <font color="#556699">#[port]#</font><p> The proxy port is: <font color="#556699">#[port]#</font><p>
<u>if you changed the Port or Port Forwarding Settings, you need to restart YaCy.</u> #(restart)#
::
Port rebinding will be done in a view seconds.<br>
You can reach your YaCy server under the new location <a href="http://#[ip]#:#[port]#/">http://#[ip]#:#[port]#/</a>
#(/restart)#
::<!-- 7 --> ::<!-- 7 -->
<b>Your proxy access setting has been changed.</b><br> <b>Your proxy access setting has been changed.</b><br>
Your new proxy account name is #[user]#. The password has been accepted.<br> Your new proxy account name is <font color="#556699">#[user]#</font>. The password has been accepted.<br>
If you open any public web page through the proxy, you must log-in then.<p> If you open any public web page through the proxy, you must log-in then.<p>
The new proxy IP filter is set to #[filter]#.<br> The new proxy IP filter is set to <font color="#556699">#[filter]#</font>.<br>
The proxy port is: <font color="#556699">#[port]#</font><p> The proxy port is: <font color="#556699">#[port]#</font><p>
<u>if you changed the Port or Port Forwarding Settings, you need to restart YaCy.</u> #(restart)#
::
Port rebinding will be done in a view seconds.<br>
You can reach your YaCy server under the new location <a href="http://#[ip]#:#[port]#/">http://#[ip]#:#[port]#/</a>
#(/restart)#
::<!-- 8 --> ::<!-- 8 -->
<b>Your server access filter is now set to #[filter]#</b><br> <b>Your server access filter is now set to #[filter]#</b><br>
<!--Your new server account name is #[user]#. The password has been accepted.<br> <!--Your new server account name is #[user]#. The password has been accepted.<br>
@ -143,10 +151,12 @@ Please return to the settings page and modify the data.<br>
You are now <b>event-based online</b>. After a short while you should see the effect on the <a href="Status.html">status</a> page.<br> You are now <b>event-based online</b>. After a short while you should see the effect on the <a href="Status.html">status</a> page.<br>
::<!-- 25 --> ::<!-- 25 -->
You are now in <b>Cache Mode</b>. Only Proxy-cache ist available in this mode. After a short while you should see the effect on the <a href="Status.html">status</a> page.<br> You are now in <b>Cache Mode</b>. Only Proxy-cache ist available in this mode. After a short while you should see the effect on the <a href="Status.html">status</a> page.<br>
::<!-- 26 -->
<p><font color="red">Unable to bild the server to the new Port: <font color="#556699">#[port]#</font></font><br>
This values seems not to be a valid port configuration.
#(/info)# #(/info)#
</p> </p>
<p>You can now go back to the <a href="Settings_p.html">Settings</a> page if you want to make more changes.</p> <p>You can now go back to the <a href="Settings_p.html">Settings</a> page if you want to make more changes.</p>
#[footer]# #[footer]#
</body> </body>
</html> </html>

@ -46,6 +46,8 @@
// javac -classpath .:../Classes SettingsAck_p.java // javac -classpath .:../Classes SettingsAck_p.java
// if the shell's current path is HTROOT // if the shell's current path is HTROOT
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -127,10 +129,30 @@ public class SettingsAck_p {
// proxy password // proxy password
if (post.containsKey("proxyaccount")) { if (post.containsKey("proxyaccount")) {
// set new port /*
* set new port
*/
String port = (String) post.get("port"); String port = (String) post.get("port");
env.setConfig("port", port);
prop.put("info_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 // read and process data
String filter = (String) post.get("proxyfilter"); String filter = (String) post.get("proxyfilter");

@ -2,12 +2,21 @@
<fieldset><legend id="ProxyAccess">Server Access Settings</legend> <fieldset><legend id="ProxyAccess">Server Access Settings</legend>
These settings configure the access method to your own http proxy and server. 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.<br> All traffic is routed throug one single port, for both proxy and server.<br>
<br><b>Port Configuration</b><br><br> <br><b>Server/Proxy Port Configuration</b><br>
<p>The socket addresses where YaCy should listen for incomming connections from other YaCy peers or http clients.<br>
You have four possibilities to specify the address:<ul>
<li>defining a port only (<i>e.g. 8080</i>)</li>
<li>defining IP address and port (<i>e.g. 192.168.0.1:8080</i>)</li>
<li>defining host name and port (<i>e.g. home:8080</i>)</li>
<li>defining interface name and port (<i>e.g. #eth0:8080</i>)</li>
</ul><br>
<i>Hint: Dont forget to change your firewall configuration after you have changed the port.</i>
</p>
<table border="0" cellspacing="5"> <table border="0" cellspacing="5">
<tr valign="top"> <tr valign="top">
<td>Proxy and http-Server Administration Port:</td> <td>Proxy and http-Server Administration Port:</td>
<td><input name="port" type="text" size="5" maxlength="5" value="#[port]#"></td> <td><input name="port" type="text" size="30" maxlength="30" value="#[port]#"></td>
<td><i>Changes will take effect after restart only.</i></td> <td><i>Changes will take effect in 5-10 seconds</i></td>
</tr> </tr>
</table> </table>

@ -60,6 +60,7 @@ import java.net.InetSocketAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException;
import java.net.URL; import java.net.URL;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.channels.ClosedByInterruptException; import java.nio.channels.ClosedByInterruptException;
@ -80,6 +81,7 @@ import de.anomic.icap.icapd;
import de.anomic.server.logging.serverLog; import de.anomic.server.logging.serverLog;
import de.anomic.yacy.yacyCore; import de.anomic.yacy.yacyCore;
import de.anomic.yacy.yacySeed; import de.anomic.yacy.yacySeed;
import de.anomic.yacy.yacySeedDB;
import de.anomic.plasma.plasmaSwitchboard; import de.anomic.plasma.plasmaSwitchboard;
public final class serverCore extends serverAbstractThread implements serverThread { public final class serverCore extends serverAbstractThread implements serverThread {
@ -97,6 +99,7 @@ public final class serverCore extends serverAbstractThread implements serverThre
// class variables // class variables
private String port; // the listening port 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 boolean portForwardingEnabled = false;
public static serverPortForwarding portForwarding = null; public static serverPortForwarding portForwarding = null;
@ -115,7 +118,7 @@ public final class serverCore extends serverAbstractThread implements serverThre
/** /**
* The session-object pool * The session-object pool
*/ */
final SessionPool theSessionPool; SessionPool theSessionPool;
final ThreadGroup theSessionThreadGroup = new ThreadGroup("sessionThreadGroup"); final ThreadGroup theSessionThreadGroup = new ThreadGroup("sessionThreadGroup");
private Config cralwerPoolConfig = null; private Config cralwerPoolConfig = null;
@ -171,15 +174,13 @@ public final class serverCore extends serverAbstractThread implements serverThre
} }
// class initializer // class initializer
public serverCore( public serverCore(
String port,
int timeout, int timeout,
boolean blockAttack, boolean blockAttack,
serverHandler handlerPrototype, serverHandler handlerPrototype,
serverSwitch switchboard, serverSwitch switchboard,
int commandMaxLength int commandMaxLength
) throws IOException { ) throws IOException {
this.port = port.trim();
this.timeout = timeout; this.timeout = timeout;
this.commandMaxLength = commandMaxLength; this.commandMaxLength = commandMaxLength;
@ -189,80 +190,27 @@ public final class serverCore extends serverAbstractThread implements serverThre
// initialize logger // initialize logger
this.log = new serverLog("SERVER"); this.log = new serverLog("SERVER");
// init servercore
init();
}
public synchronized void init() {
this.log.logInfo("Initializing serverCore ...");
/* // read some config values
try { this.port = this.switchboard.getConfig("port", "8080").trim();
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);
}
*/
// Open a new server-socket channel // Open a new server-socket channel
try { try {
this.log.logInfo("Trying to bind server to port " + port); this.initPort(this.port);
} catch (Exception e) {
// 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) {
String errorMsg = "FATAL ERROR: " + e.getMessage() + " - probably root access rights needed. check port number"; String errorMsg = "FATAL ERROR: " + e.getMessage() + " - probably root access rights needed. check port number";
this.log.logSevere(errorMsg); this.log.logSevere(errorMsg);
System.out.println(errorMsg); System.out.println(errorMsg);
System.exit(0); System.exit(0);
} }
// init port forwarding // init port forwarding
try { try {
this.initPortForwarding(); this.initPortForwarding();
@ -274,6 +222,13 @@ public final class serverCore extends serverAbstractThread implements serverThre
this.switchboard.setConfig("portForwardingEnabled","false"); this.switchboard.setConfig("portForwardingEnabled","false");
} }
// init session pool
initSessionPool();
}
public void initSessionPool() {
this.log.logInfo("Initializing session pool ...");
// implementation of session thread pool // implementation of session thread pool
this.cralwerPoolConfig = new GenericObjectPool.Config(); this.cralwerPoolConfig = new GenericObjectPool.Config();
@ -295,13 +250,75 @@ public final class serverCore extends serverAbstractThread implements serverThre
this.cralwerPoolConfig.minEvictableIdleTimeMillis = this.thresholdSleep; this.cralwerPoolConfig.minEvictableIdleTimeMillis = this.thresholdSleep;
this.cralwerPoolConfig.testOnReturn = true; 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 { public void initPortForwarding() throws Exception {
// doing the port forwarding stuff // doing the port forwarding stuff
if (this.switchboard.getConfig("portForwardingEnabled","false").equalsIgnoreCase("true")) { if (this.switchboard.getConfig("portForwardingEnabled","false").equalsIgnoreCase("true")) {
this.log.logInfo("Initializing port forwarding ...");
try { try {
String localHost = this.socket.getInetAddress().getHostName(); String localHost = this.socket.getInetAddress().getHostName();
Integer localPort = new Integer(this.socket.getLocalPort()); Integer localPort = new Integer(this.socket.getLocalPort());
@ -441,52 +458,62 @@ public final class serverCore extends serverAbstractThread implements serverThre
// class body // class body
public boolean job() throws Exception { public boolean job() throws Exception {
// prepare for new connection try {
// idleThreadCheck(); // prepare for new connection
this.switchboard.handleBusyState(this.theSessionPool.getNumActive() /*activeThreads.size() */); // idleThreadCheck();
this.switchboard.handleBusyState(this.theSessionPool.getNumActive() /*activeThreads.size() */);
this.log.logFinest(
"* waiting for connections, " + this.theSessionPool.getNumActive() + " sessions running, " + this.log.logFinest(
this.theSessionPool.getNumIdle() + " sleeping"); "* waiting for connections, " + this.theSessionPool.getNumActive() + " sessions running, " +
this.theSessionPool.getNumIdle() + " sleeping");
// wait for new connection
announceThreadBlockApply(); // wait for new connection
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
announceThreadBlockApply(); announceThreadBlockApply();
try {Thread.sleep(attempts.intValue() * 2000);} catch (InterruptedException e) {} Socket controlSocket = this.socket.accept();
announceThreadBlockRelease(); 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 if ((this.denyHost == null) || (this.denyHost.get(cIP) == null)) {
Session connection = (Session) this.theSessionPool.borrowObject(); // 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 return true;
connection.execute(controlSocket,this.timeout); } catch (SocketException e) {
} else { if (this.forceRestart) {
this.log.logWarning("ACCESS FROM " + cIP + " DENIED"); // 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 // consuming the isInterrupted Flag. Otherwise we could not properly close the session pool
Thread.interrupted(); Thread.interrupted();
@ -1192,5 +1219,29 @@ public final class serverCore extends serverAbstractThread implements serverThre
if (currentThread.isInterrupted()) throw new InterruptedException(); if (currentThread.isInterrupted()) throw new InterruptedException();
if ((currentThread instanceof serverCore.Session) && ((serverCore.Session)currentThread).isStopped()) 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();
}
}
} }

@ -327,7 +327,7 @@ public final class yacy {
// start main threads // start main threads
try { try {
final httpd protocolHandler = new httpd(sb, new httpdFileHandler(sb), new httpdProxyHandler(sb)); 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*/, timeout /*control socket timeout in milliseconds*/,
true /* block attacks (wrong protocol) */, true /* block attacks (wrong protocol) */,
protocolHandler /*command class*/, protocolHandler /*command class*/,

Loading…
Cancel
Save