diff --git a/apps/BOB/nbproject/private/private.xml b/apps/BOB/nbproject/private/private.xml index 685ecc5a1..653e554c3 100644 --- a/apps/BOB/nbproject/private/private.xml +++ b/apps/BOB/nbproject/private/private.xml @@ -2,6 +2,6 @@ - file:/usblv/NetBeansProjects/wi2p.i2p/apps/BOB/src/net/i2p/BOB/BOB.java + file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/TCPio.java diff --git a/apps/BOB/src/net/i2p/BOB/DoCMDS.java b/apps/BOB/src/net/i2p/BOB/DoCMDS.java index 8e4afb143..dcb0a195d 100644 --- a/apps/BOB/src/net/i2p/BOB/DoCMDS.java +++ b/apps/BOB/src/net/i2p/BOB/DoCMDS.java @@ -50,7 +50,7 @@ public class DoCMDS implements Runnable { // FIX ME // I need a better way to do versioning, but this will do for now. - public static final String BMAJ = "00", BMIN = "00", BREV = "08", BEXT = ""; + public static final String BMAJ = "00", BMIN = "00", BREV = "0A", BEXT = ""; public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT; private Socket server; private Properties props; diff --git a/apps/BOB/src/net/i2p/BOB/I2Plistener.java b/apps/BOB/src/net/i2p/BOB/I2Plistener.java index e55e54b9d..fc6dde603 100644 --- a/apps/BOB/src/net/i2p/BOB/I2Plistener.java +++ b/apps/BOB/src/net/i2p/BOB/I2Plistener.java @@ -60,20 +60,9 @@ public class I2Plistener implements Runnable { this._log = _log; this.socketManager = S; this.serverSocket = SS; -// tgwatch = 1; this.lives = lives; } - private void rlock() throws Exception { - database.getReadLock(); - info.getReadLock(); - } - - private void runlock() throws Exception { - database.releaseReadLock(); - info.releaseReadLock(); - } - /** * Simply listen on I2P port, and thread connections * @@ -83,34 +72,31 @@ public class I2Plistener implements Runnable { I2PSocket sessSocket = null; int conn = 0; try { - die: - { - try { - serverSocket.setSoTimeout(50); - - while (lives.get()) { - try { - sessSocket = serverSocket.accept(); - g = true; - } catch (ConnectException ce) { - g = false; - } catch (SocketTimeoutException ste) { - g = false; - } - if (g) { - g = false; - conn++; - // toss the connection to a new thread. - I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives); - Thread t = new Thread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn); - t.start(); - } + try { + serverSocket.setSoTimeout(50); + while (lives.get()) { + try { + sessSocket = serverSocket.accept(); + g = true; + } catch (ConnectException ce) { + g = false; + } catch (SocketTimeoutException ste) { + g = false; } - } catch (I2PException e) { - // bad shit - System.out.println("Exception " + e); + if (g) { + g = false; + conn++; + // toss the connection to a new thread. + I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives); + Thread t = new Thread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn); + t.start(); + } + } + } catch (I2PException e) { + // bad shit + System.out.println("Exception " + e); } } finally { try { diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java index c91a8743c..671fffa95 100644 --- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java +++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java @@ -104,10 +104,10 @@ public class MUXlisten implements Runnable { this.database.releaseReadLock(); this.info.releaseReadLock(); - socketManager = I2PSocketManagerFactory.createManager(prikey, Q); if (this.come_in) { this.listener = new ServerSocket(port, backlog, host); } + socketManager = I2PSocketManagerFactory.createManager(prikey, Q); // I2PException, IOException, RuntimeException // To bad we can't just catch and enumerate.... // } catch (I2PException e) { @@ -141,8 +141,6 @@ public class MUXlisten implements Runnable { this.info.add("STARTING", new Boolean(false)); this.info.releaseWriteLock(); this.database.releaseWriteLock(); - // throw new Exception(e); - // Debugging, I guess. e.printStackTrace(); throw new RuntimeException(e); } diff --git a/apps/BOB/src/net/i2p/BOB/TCPio.java b/apps/BOB/src/net/i2p/BOB/TCPio.java index d501759ef..5e99637dd 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPio.java +++ b/apps/BOB/src/net/i2p/BOB/TCPio.java @@ -78,16 +78,20 @@ public class TCPio implements Runnable { * --Sponge * * Tested with 128 bytes, and there was no performance gain. + * 8192 bytes did lower load average across many connections. + * Should I raise it higer? The correct thing to do would be to + * override... perhaps use NTCP, but I2P's streaming lib lacks + * anything NTCP compatable. * * --Sponge */ int b; - byte a[] = new byte[1]; + byte a[] = new byte[8192]; try { try { while (lives.get()) { - b = Ain.read(a, 0, 1); + b = Ain.read(a, 0, 8192); if (b > 0) { Aout.write(a, 0, b); } else if (b == 0) { diff --git a/apps/BOB/src/net/i2p/BOB/TCPlistener.java b/apps/BOB/src/net/i2p/BOB/TCPlistener.java index b5addc27b..714ee1e7f 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPlistener.java +++ b/apps/BOB/src/net/i2p/BOB/TCPlistener.java @@ -64,16 +64,6 @@ public class TCPlistener implements Runnable { this.lives = lives; } - private void rlock() throws Exception { - database.getReadLock(); - info.getReadLock(); - } - - private void runlock() throws Exception { - database.releaseReadLock(); - info.releaseReadLock(); - } - /** * Simply listen on TCP port, and thread connections * @@ -81,30 +71,27 @@ public class TCPlistener implements Runnable { public void run() { boolean g = false; int conn = 0; + Socket server = null; try { - die: - { - try { - Socket server = new Socket(); - listener.setSoTimeout(50); // We don't block, we cycle and check. - while (lives.get()) { - try { - server = listener.accept(); - g = true; - } catch (SocketTimeoutException ste) { - g = false; - } - if (g) { - conn++; - // toss the connection to a new thread. - TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives); - Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn); - t.start(); - g = false; - } + try { + listener.setSoTimeout(50); // We don't block, we cycle and check. + while (lives.get()) { + try { + server = listener.accept(); + g = true; + } catch (SocketTimeoutException ste) { + g = false; + } + if (g) { + conn++; + // toss the connection to a new thread. + TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives); + Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn); + t.start(); + g = false; } - } catch (IOException ioe) { } + } catch (IOException ioe) { } } finally { try { diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 9c0cd78dc..f1d716273 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -734,12 +734,12 @@ public class I2PSnarkServlet extends HttpServlet { out.write("\n"); // *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file out.write("\n"); - out.write("\n"); - out.write("Add Torrent:\n"); - out.write("From URL : \n"); + out.write("\n"); + out.write("Add Torrent\n"); + out.write("From URL : \n"); // not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve) //out.write("From file: \n"); - out.write("\n"); + out.write("\n"); out.write("Alternately, you can copy .torrent files to " + _manager.getDataDir().getAbsolutePath() + "\n"); out.write("Removing that .torrent file will cause the torrent to stop.\n"); out.write("\n"); @@ -754,12 +754,12 @@ public class I2PSnarkServlet extends HttpServlet { out.write("\n"); // *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file out.write("\n"); - out.write("\n"); - out.write("Create Torrent:\n"); + out.write("\n"); + out.write("Create Torrent\n"); //out.write("From file: \n"); out.write("Data to seed: " + _manager.getDataDir().getAbsolutePath() + File.separatorChar + "\n"); + + "\" title=\"File to seed (must be within the specified path)\" >\n"); out.write("Tracker: Select a tracker\n"); Map trackers = _manager.getTrackers(); for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) { @@ -773,8 +773,8 @@ public class I2PSnarkServlet extends HttpServlet { } out.write("\n"); out.write("or "); - out.write("\n"); + "title=\"Custom tracker URL\" > "); + out.write("\n"); out.write("\n"); } @@ -788,13 +788,13 @@ public class I2PSnarkServlet extends HttpServlet { out.write("\n"); out.write("\n"); - out.write("\n"); - out.write("Configuration:\n"); - out.write("Data directory: (Edit i2psnark.config and restart to change)\n"); - out.write("Auto start: \n"); + out.write("Configuration\n"); + out.write("Data directory: (Edit i2psnark.config and restart to change)\n"); + out.write("Auto start: "); + + "title=\"If true, automatically start torrents that are added\" >"); //Auto add: //Auto stop: //out.write("\n"); @@ -814,26 +814,26 @@ public class I2PSnarkServlet extends HttpServlet { out.write("150%\n\t"); out.write("\n"); */ - out.write("Total uploader limit: peers\n"); - out.write("Up bandwidth limit: KBps (Half available bandwidth recommended.)\n"); + out.write("Total uploader limit: peers\n"); + out.write("Up bandwidth limit: KBps (Half available bandwidth recommended.)\n"); - out.write("Use open trackers also: Use open trackers also: "); - out.write("Announce URLs: \n"); + + "title=\"If true, uses open trackers in addition\" > "); + out.write("Open tracker announce URLs: \n"); //out.write("\n"); //out.write("EepProxy host: "); //out.write("port: \n"); - out.write("I2CP host: "); - out.write("port: \n"); + out.write("I2CP host: "); + out.write("I2CP port: \n"); StringBuilder opts = new StringBuilder(64); Map options = new TreeMap(_manager.util().getI2CPOptions()); for (Iterator iter = options.entrySet().iterator(); iter.hasNext(); ) { @@ -842,10 +842,10 @@ public class I2PSnarkServlet extends HttpServlet { String val = (String)entry.getValue(); opts.append(key).append('=').append(val).append(' '); } - out.write("I2CP opts: \n"); - out.write("\n"); - out.write("\n"); + out.write("I2CP options: " + + opts.toString() + "\n"); + out.write(" \n"); + out.write("\n"); out.write(""); } @@ -869,7 +869,7 @@ public class I2PSnarkServlet extends HttpServlet { return ((bytes + 512*1024*1024)/(1024*1024*1024)) + "GB"; } - private static final String HEADER = ""; + private static final String HEADER = ""; private static final String TABLE_HEADER = "\n" + diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 683c9d6aa..df0d75019 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -268,6 +268,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable OutputStream out = null; String targetRequest = null; boolean usingWWWProxy = false; + boolean usingInternalServer = false; String currentProxy = null; long requestId = ++__requestId; try { @@ -294,6 +295,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable int pos = line.indexOf(" "); if (pos == -1) break; method = line.substring(0, pos); + // TODO use Java URL class to make all this simpler and more robust String request = line.substring(pos + 1); if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) { request = "http://i2p" + request; @@ -339,8 +341,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } } - // Quick hack for foo.bar.i2p - if (host.toLowerCase().endsWith(".i2p")) { + if (host.toLowerCase().equals("proxy.i2p")) { + // so we don't do any naming service lookups + destination = "proxy.i2p"; + usingInternalServer = true; + } else if (host.toLowerCase().endsWith(".i2p")) { // Destination gets the host name destination = host; // Host becomes the destination key @@ -477,15 +482,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } destination = request.substring(0, pos); line = method + " " + request.substring(pos); - } + } // end host name processing - boolean isValid = usingWWWProxy || isSupportedAddress(host, protocol); + boolean isValid = usingWWWProxy || usingInternalServer || isSupportedAddress(host, protocol); if (!isValid) { if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")"); method = null; destination = null; break; - } else if (!usingWWWProxy) { + } else if ((!usingWWWProxy) && (!usingInternalServer)) { if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")"); host = getHostName(destination); // hide original host } @@ -496,7 +501,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable _log.debug(getPrefix(requestId) + "HOST :" + host + ":"); _log.debug(getPrefix(requestId) + "DEST :" + destination + ":"); } - + + // end first line processing + } else { if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) { line = "Host: " + host; @@ -528,14 +535,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable continue; // completely strip the line } } - + if (line.length() == 0) { String ok = getTunnel().getClientOptions().getProperty("i2ptunnel.gzip"); boolean gzip = DEFAULT_GZIP; if (ok != null) gzip = Boolean.valueOf(ok).booleanValue(); - if (gzip) { + if (gzip && !usingInternalServer) { // according to rfc2616 s14.3, this *should* force identity, even if // an explicit q=0 for gzip doesn't. tested against orion.i2p, and it // seems to work. @@ -549,7 +556,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } else { newRequest.append(line).append("\r\n"); // HTTP spec } - } + } // end header processing + if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]"); @@ -571,7 +579,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable // Serve local proxy files (images, css linked from error pages) // Ignore all the headers - if (destination.equals("proxy.i2p")) { + if (usingInternalServer) { serveLocalFile(out, method, targetRequest); s.close(); return; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java index be398f770..db37b9e59 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java @@ -55,7 +55,7 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase { I2PSocket destSock = serv.getDestinationI2PSocket(this); new I2PTunnelRunner(clientSock, destSock, sockLock, null, mySockets); } catch (SOCKSException e) { - _log.error("Error from SOCKS connection: " + e.getMessage()); + _log.error("Error from SOCKS connection", e); closeSocket(s); } } diff --git a/apps/routerconsole/java/build.xml b/apps/routerconsole/java/build.xml index e5b602129..d8d85e21d 100644 --- a/apps/routerconsole/java/build.xml +++ b/apps/routerconsole/java/build.xml @@ -89,7 +89,7 @@ - + diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java index 35045d485..373a272f0 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java @@ -232,7 +232,7 @@ public class ConfigNetHandler extends FormHandler { if (_requireIntroductions) { _context.router().setConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS, "true"); - addFormNotice(_("Requiring SSU introduers")); + addFormNotice(_("Requiring SSU introducers")); } else { _context.router().removeConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS); } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java index fffdcad6a..50a949fe1 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java @@ -36,10 +36,10 @@ public class ConfigUIHelper extends HelperBase { return rv; } - private static final String langs[] = {"de", "en", "fr", "nl", "se", "zh"}; - private static final String flags[] = {"de", "us", "fr", "nl", "se", "cn"}; + private static final String langs[] = {"de", "en", "fr", "nl", "ru", "sv", "zh"}; + private static final String flags[] = {"de", "us", "fr", "nl", "ru", "se", "cn"}; private static final String xlangs[] = {_x("German"), _x("English"), _x("French"), - _x("Dutch"), _x("Swedish"), _x("Chinese")}; + _x("Dutch"), _x("Russian"), _x("Swedish"), _x("Chinese")}; /** todo sort by translated string */ public String getLangSettings() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java index ef61f0663..18c454cc7 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; +import net.i2p.data.DataHelper; public class NetDbHelper extends HelperBase { private String _routerPrefix; @@ -12,7 +13,11 @@ public class NetDbHelper extends HelperBase { public NetDbHelper() {} - public void setRouter(String r) { _routerPrefix = r; } + public void setRouter(String r) { + if (r != null) + _routerPrefix = DataHelper.stripHTML(r); // XSS + } + public void setFull(String f) { try { _full = Integer.parseInt(f); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java index 5e7ef4b94..14863acf3 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java @@ -46,13 +46,13 @@ class ProfileOrganizerRenderer { Hash peer = (Hash)iter.next(); if (_organizer.getUs().equals(peer)) continue; PeerProfile prof = _organizer.getProfile(peer); - if (_organizer.isWellIntegrated(peer)) { - integratedPeers.add(prof); - } else { + //if (_organizer.isWellIntegrated(peer)) { + // integratedPeers.add(prof); + //} else { RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer); if (info != null && info.getCapabilities().indexOf("f") >= 0) integratedPeers.add(prof); - } + //} if (prof.getLastSendSuccessful() <= hideBefore) { older++; continue; diff --git a/apps/routerconsole/jsp/config.jsp b/apps/routerconsole/jsp/config.jsp index c422e1016..9a9942c79 100644 --- a/apps/routerconsole/jsp/config.jsp +++ b/apps/routerconsole/jsp/config.jsp @@ -32,15 +32,18 @@ " /> <%=intl._("KBps In")%> () +<% /******** +*********/ %> " /> <%=intl._("KBps Out")%> () +<% /******** +*********/ %> <%=intl._("Share")%> () @@ -121,6 +125,7 @@ <%=intl._("UDP Configuration:")%> <%=intl._("UDP port:")%> " /> +<% /******** +*********/ %> <%=intl._("TCP Configuration")%>: <%=intl._("Externally reachable hostname or IP address")%>: @@ -163,10 +169,12 @@ <%=intl._("Most of the options above are for special situations, for example where UPnP does not work correctly, or a firewall not under your control is doing harm.")%> <%=intl._("Certain firewalls such as symmetric NATs may not work well with I2P.")%> +<% /******** +*********/ %> <%=intl._("UPnP is used to communicate with Internet Gateway Devices (IGDs) to detect the external IP address and forward ports.")%> <%=intl._("UPnP support is beta, and may not work for any number of reasons")%>: diff --git a/apps/routerconsole/jsp/configpeer.jsp b/apps/routerconsole/jsp/configpeer.jsp index 8b61f274d..bd5390108 100644 --- a/apps/routerconsole/jsp/configpeer.jsp +++ b/apps/routerconsole/jsp/configpeer.jsp @@ -24,7 +24,7 @@ <% String peer = ""; if (request.getParameter("peer") != null) - peer = request.getParameter("peer"); + peer = net.i2p.data.DataHelper.stripHTML(request.getParameter("peer")); // XSS %> diff --git a/apps/routerconsole/jsp/i2ptunnel/index.jsp b/apps/routerconsole/jsp/i2ptunnel/index.jsp index 8c7eefc2e..f3cceda0d 100644 --- a/apps/routerconsole/jsp/i2ptunnel/index.jsp +++ b/apps/routerconsole/jsp/i2ptunnel/index.jsp @@ -3,5 +3,5 @@ -The I2P Tunnel Manager is not currently running. Please visit theClient Configuration page to start it. +The I2P Tunnel Manager is not currently running. Please visit the Client Configuration page to start it.
<%=intl._("UDP Configuration:")%> <%=intl._("UDP port:")%> " /> +<% /******** +*********/ %>
<%=intl._("TCP Configuration")%>: <%=intl._("Externally reachable hostname or IP address")%>: @@ -163,10 +169,12 @@ <%=intl._("Most of the options above are for special situations, for example where UPnP does not work correctly, or a firewall not under your control is doing harm.")%> <%=intl._("Certain firewalls such as symmetric NATs may not work well with I2P.")%>
<%=intl._("UPnP is used to communicate with Internet Gateway Devices (IGDs) to detect the external IP address and forward ports.")%> <%=intl._("UPnP support is beta, and may not work for any number of reasons")%>: diff --git a/apps/routerconsole/jsp/configpeer.jsp b/apps/routerconsole/jsp/configpeer.jsp index 8b61f274d..bd5390108 100644 --- a/apps/routerconsole/jsp/configpeer.jsp +++ b/apps/routerconsole/jsp/configpeer.jsp @@ -24,7 +24,7 @@ <% String peer = ""; if (request.getParameter("peer") != null) - peer = request.getParameter("peer"); + peer = net.i2p.data.DataHelper.stripHTML(request.getParameter("peer")); // XSS %>