*) 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>
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 -->
<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>
The new proxy IP filter is set to #[filter]#<br>
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>
<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>
The new proxy IP filter is set to <font color="#556699">#[filter]#</font><br>
The proxy port is: <font color="#556699">#[port]#</font><p>
#(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 -->
<b>Your proxy access setting has been changed.</b><br>
Your new proxy account name is #[user]#. The password has been accepted.<br>
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 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>
<b>Your proxy access setting has been changed.</b><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>
The new proxy IP filter is set to <font color="#556699">#[filter]#</font>.<br>
The proxy port is: <font color="#556699">#[port]#</font><p>
#(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 -->
<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>
@ -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>
::<!-- 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>
::<!-- 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)#
</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]#
</body>
</html>

@ -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");

@ -2,12 +2,21 @@
<fieldset><legend id="ProxyAccess">Server Access Settings</legend>
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>
<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">
<tr valign="top">
<td>Proxy and http-Server Administration Port:</td>
<td><input name="port" type="text" size="5" maxlength="5" value="#[port]#"></td>
<td><i>Changes will take effect after restart only.</i></td>
<td><input name="port" type="text" size="30" maxlength="30" value="#[port]#"></td>
<td><i>Changes will take effect in 5-10 seconds</i></td>
</tr>
</table>

@ -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();
}
}
}

@ -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*/,

Loading…
Cancel
Save