forked from I2P_Developers/i2p.i2p
merge of '5f806c16d9ddce033dc0527c22c5559e00f692e5'
and '893000f2731ec12111a70dbb912005b82642fcaa'
This commit is contained in:
@@ -3,9 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar, war" />
|
<target name="build" depends="builddep, jar, war" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../jetty/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
<ant dir="../../streaming/java/" target="build" />
|
|
||||||
<!-- streaming will build ministreaming and core -->
|
|
||||||
</target>
|
</target>
|
||||||
<condition property="depend.available">
|
<condition property="depend.available">
|
||||||
<typefound name="depend" />
|
<typefound name="depend" />
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
package org.klomp.snark;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.klomp.snark.bencode.BEncoder;
|
||||||
|
import org.klomp.snark.bencode.BEValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REF: BEP 10 Extension Protocol
|
||||||
|
* @since 0.8.2
|
||||||
|
*/
|
||||||
|
class ExtensionHandshake {
|
||||||
|
|
||||||
|
private static final byte[] _payload = buildPayload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bencoded data
|
||||||
|
*/
|
||||||
|
static byte[] getPayload() {
|
||||||
|
return _payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** just a test for now */
|
||||||
|
private static byte[] buildPayload() {
|
||||||
|
Map<String, Object> handshake = new HashMap();
|
||||||
|
Map<String, Integer> m = new HashMap();
|
||||||
|
m.put("foo", Integer.valueOf(99));
|
||||||
|
m.put("bar", Integer.valueOf(101));
|
||||||
|
handshake.put("m", m);
|
||||||
|
handshake.put("p", Integer.valueOf(6881));
|
||||||
|
handshake.put("v", "I2PSnark");
|
||||||
|
handshake.put("reqq", Integer.valueOf(5));
|
||||||
|
return BEncoder.bencode(handshake);
|
||||||
|
}
|
||||||
|
}
|
@@ -66,6 +66,7 @@ public class Peer implements Comparable
|
|||||||
private long options;
|
private long options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Outgoing connection.
|
||||||
* Creates a disconnected peer given a PeerID, your own id and the
|
* Creates a disconnected peer given a PeerID, your own id and the
|
||||||
* relevant MetaInfo.
|
* relevant MetaInfo.
|
||||||
*/
|
*/
|
||||||
@@ -80,6 +81,7 @@ public class Peer implements Comparable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Incoming connection.
|
||||||
* Creates a unconnected peer from the input and output stream got
|
* Creates a unconnected peer from the input and output stream got
|
||||||
* from the socket. Note that the complete handshake (which can take
|
* from the socket. Note that the complete handshake (which can take
|
||||||
* some time or block indefinitely) is done in the calling Thread to
|
* some time or block indefinitely) is done in the calling Thread to
|
||||||
@@ -201,6 +203,7 @@ public class Peer implements Comparable
|
|||||||
// Do we need to handshake?
|
// Do we need to handshake?
|
||||||
if (din == null)
|
if (din == null)
|
||||||
{
|
{
|
||||||
|
// Outgoing connection
|
||||||
sock = util.connect(peerID);
|
sock = util.connect(peerID);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Connected to " + peerID + ": " + sock);
|
_log.debug("Connected to " + peerID + ": " + sock);
|
||||||
@@ -234,6 +237,7 @@ public class Peer implements Comparable
|
|||||||
+ PeerID.idencode(expected_id) + "'");
|
+ PeerID.idencode(expected_id) + "'");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Incoming connection
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Already have din [" + sock + "] with " + toString());
|
_log.debug("Already have din [" + sock + "] with " + toString());
|
||||||
}
|
}
|
||||||
@@ -242,6 +246,12 @@ public class Peer implements Comparable
|
|||||||
PeerConnectionOut out = new PeerConnectionOut(this, dout);
|
PeerConnectionOut out = new PeerConnectionOut(this, dout);
|
||||||
PeerState s = new PeerState(this, listener, metainfo, in, out);
|
PeerState s = new PeerState(this, listener, metainfo, in, out);
|
||||||
|
|
||||||
|
if ((options & OPTION_EXTENSION) != 0) {
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Peer supports extensions, sending test message");
|
||||||
|
out.sendExtension(0, ExtensionHandshake.getPayload());
|
||||||
|
}
|
||||||
|
|
||||||
// Send our bitmap
|
// Send our bitmap
|
||||||
if (bitfield != null)
|
if (bitfield != null)
|
||||||
s.out.sendBitfield(bitfield);
|
s.out.sendBitfield(bitfield);
|
||||||
@@ -331,12 +341,10 @@ public class Peer implements Comparable
|
|||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Read the remote side's hash and peerID fully from " + toString());
|
_log.debug("Read the remote side's hash and peerID fully from " + toString());
|
||||||
|
|
||||||
// if ((options & OPTION_EXTENSION) != 0) {
|
|
||||||
if (options != 0) {
|
if (options != 0) {
|
||||||
// send them something
|
// send them something
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
//_log.debug("Peer supports extension message, what should we say? " + toString());
|
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ": " + toString());
|
||||||
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ", what should we say? " + toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs;
|
return bs;
|
||||||
|
@@ -114,8 +114,9 @@ class PeerCheckerTask extends TimerTask
|
|||||||
|
|
||||||
// Choke a percentage of them rather than all so it isn't so drastic...
|
// Choke a percentage of them rather than all so it isn't so drastic...
|
||||||
// unless this torrent is over the limit all by itself.
|
// unless this torrent is over the limit all by itself.
|
||||||
|
// choke 5/8 of the time when seeding and 3/8 when leeching
|
||||||
boolean overBWLimitChoke = upload > 0 &&
|
boolean overBWLimitChoke = upload > 0 &&
|
||||||
((overBWLimit && random.nextBoolean()) ||
|
((overBWLimit && (random.nextInt(8) > (coordinator.completed() ? 2 : 4))) ||
|
||||||
(coordinator.overUpBWLimit(uploaded)));
|
(coordinator.overUpBWLimit(uploaded)));
|
||||||
|
|
||||||
// If we are at our max uploaders and we have lots of other
|
// If we are at our max uploaders and we have lots of other
|
||||||
|
@@ -615,13 +615,13 @@ public class PeerCoordinator implements PeerListener
|
|||||||
// share blocks rather than starting from 0 with each peer.
|
// share blocks rather than starting from 0 with each peer.
|
||||||
// This is where the flaws of the snark data model are really exposed.
|
// This is where the flaws of the snark data model are really exposed.
|
||||||
// Could also randomize within the duplicate set rather than strict rarest-first
|
// Could also randomize within the duplicate set rather than strict rarest-first
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.debug("parallel request (end game?) for " + peer + ": piece = " + piece);
|
_log.info("parallel request (end game?) for " + peer + ": piece = " + piece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (record) {
|
if (record) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.debug("Now requesting: piece " + piece + " priority " + piece.getPriority());
|
_log.info(peer + " is now requesting: piece " + piece + " priority " + piece.getPriority());
|
||||||
piece.setRequested(true);
|
piece.setRequested(true);
|
||||||
}
|
}
|
||||||
return piece.getId();
|
return piece.getId();
|
||||||
@@ -945,11 +945,11 @@ public class PeerCoordinator implements PeerListener
|
|||||||
PartialPiece pp = iter.next();
|
PartialPiece pp = iter.next();
|
||||||
int savedPiece = pp.getPiece();
|
int savedPiece = pp.getPiece();
|
||||||
if (havePieces.get(savedPiece)) {
|
if (havePieces.get(savedPiece)) {
|
||||||
|
iter.remove();
|
||||||
// this is just a double-check, it should be in there
|
// this is just a double-check, it should be in there
|
||||||
for(Piece piece : wantedPieces) {
|
for(Piece piece : wantedPieces) {
|
||||||
if (piece.getId() == savedPiece) {
|
if (piece.getId() == savedPiece) {
|
||||||
piece.setRequested(true);
|
piece.setRequested(true);
|
||||||
iter.remove();
|
|
||||||
if (_log.shouldLog(Log.INFO)) {
|
if (_log.shouldLog(Log.INFO)) {
|
||||||
_log.info("Restoring orphaned partial piece " + pp +
|
_log.info("Restoring orphaned partial piece " + pp +
|
||||||
" Partial list size now: " + partialPieces.size());
|
" Partial list size now: " + partialPieces.size());
|
||||||
@@ -957,8 +957,12 @@ public class PeerCoordinator implements PeerListener
|
|||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Partial piece " + pp + " NOT in wantedPieces??");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_log.shouldLog(Log.WARN) && !partialPieces.isEmpty())
|
||||||
|
_log.warn("Peer " + peer + " has none of our partials " + partialPieces);
|
||||||
}
|
}
|
||||||
// ...and this section turns this into the general move-requests-around code!
|
// ...and this section turns this into the general move-requests-around code!
|
||||||
// Temporary? So PeerState never calls wantPiece() directly for now...
|
// Temporary? So PeerState never calls wantPiece() directly for now...
|
||||||
@@ -1004,7 +1008,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wantPiece(peer, havePieces, false) > 0;
|
return wantPiece(peer, havePieces, false) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -609,6 +609,9 @@ class PeerState implements DataLoader
|
|||||||
*/
|
*/
|
||||||
synchronized void addRequest()
|
synchronized void addRequest()
|
||||||
{
|
{
|
||||||
|
// no bitfield yet? nothing to request then.
|
||||||
|
if (bitfield == null)
|
||||||
|
return;
|
||||||
boolean more_pieces = true;
|
boolean more_pieces = true;
|
||||||
while (more_pieces)
|
while (more_pieces)
|
||||||
{
|
{
|
||||||
|
@@ -3,9 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar, war" />
|
<target name="build" depends="builddep, jar, war" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../ministreaming/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
<ant dir="../../jetty/" target="build" />
|
|
||||||
<!-- ministreaming will build core -->
|
|
||||||
</target>
|
</target>
|
||||||
<condition property="depend.available">
|
<condition property="depend.available">
|
||||||
<typefound name="depend" />
|
<typefound name="depend" />
|
||||||
|
@@ -1573,6 +1573,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
|||||||
*
|
*
|
||||||
* Since file:<filename> isn't really used, this method is deprecated,
|
* Since file:<filename> isn't really used, this method is deprecated,
|
||||||
* just call context.namingService.lookup() directly.
|
* just call context.namingService.lookup() directly.
|
||||||
|
* @deprecated Don't use i2ptunnel for lookup! Use I2PAppContext.getGlobalContext().namingService().lookup(name) from i2p.jar
|
||||||
*/
|
*/
|
||||||
public static Destination destFromName(String name) throws DataFormatException {
|
public static Destination destFromName(String name) throws DataFormatException {
|
||||||
|
|
||||||
|
@@ -42,15 +42,11 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
|
|||||||
dests = new ArrayList(1);
|
dests = new ArrayList(1);
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
String destination = tok.nextToken();
|
String destination = tok.nextToken();
|
||||||
try {
|
Destination destN = _context.namingService().lookup(destination);
|
||||||
Destination destN = I2PTunnel.destFromName(destination);
|
if (destN == null)
|
||||||
if (destN == null)
|
l.log("Could not resolve " + destination);
|
||||||
l.log("Could not resolve " + destination);
|
else
|
||||||
else
|
dests.add(destN);
|
||||||
dests.add(destN);
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
l.log("Bad format parsing \"" + destination + "\"");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dests.isEmpty()) {
|
if (dests.isEmpty()) {
|
||||||
|
@@ -278,7 +278,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Destination clientDest = I2PTunnel.destFromName(destination);
|
Destination clientDest = _context.namingService().lookup(destination);
|
||||||
if (clientDest == null) {
|
if (clientDest == null) {
|
||||||
String str;
|
String str;
|
||||||
byte[] header;
|
byte[] header;
|
||||||
|
@@ -28,7 +28,6 @@ import net.i2p.client.streaming.I2PSocketManager;
|
|||||||
import net.i2p.client.streaming.I2PSocketOptions;
|
import net.i2p.client.streaming.I2PSocketOptions;
|
||||||
import net.i2p.data.Base32;
|
import net.i2p.data.Base32;
|
||||||
import net.i2p.data.Base64;
|
import net.i2p.data.Base64;
|
||||||
import net.i2p.data.DataFormatException;
|
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
@@ -431,11 +430,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
|||||||
// Host resolvable from database, verify addresshelper key
|
// Host resolvable from database, verify addresshelper key
|
||||||
// Silently bypass correct keys, otherwise alert
|
// Silently bypass correct keys, otherwise alert
|
||||||
String destB64 = null;
|
String destB64 = null;
|
||||||
try {
|
Destination _dest = _context.namingService().lookup(host);
|
||||||
Destination _dest = I2PTunnel.destFromName(host);
|
if (_dest != null)
|
||||||
if (_dest != null)
|
destB64 = _dest.toBase64();
|
||||||
destB64 = _dest.toBase64();
|
|
||||||
} catch (DataFormatException dfe) {}
|
|
||||||
if (destB64 != null && !destB64.equals(ahelperKey))
|
if (destB64 != null && !destB64.equals(ahelperKey))
|
||||||
{
|
{
|
||||||
// Conflict: handle when URL reconstruction done
|
// Conflict: handle when URL reconstruction done
|
||||||
@@ -721,7 +718,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
|||||||
if ("i2p".equals(host))
|
if ("i2p".equals(host))
|
||||||
clientDest = null;
|
clientDest = null;
|
||||||
else
|
else
|
||||||
clientDest = I2PTunnel.destFromName(destination);
|
clientDest = _context.namingService().lookup(destination);
|
||||||
|
|
||||||
if (clientDest == null) {
|
if (clientDest == null) {
|
||||||
//l.log("Could not resolve " + destination + ".");
|
//l.log("Could not resolve " + destination + ".");
|
||||||
@@ -814,17 +811,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
|||||||
* @return b32hash.b32.i2p, or "i2p" on lookup failure.
|
* @return b32hash.b32.i2p, or "i2p" on lookup failure.
|
||||||
* Prior to 0.7.12, returned b64 key
|
* Prior to 0.7.12, returned b64 key
|
||||||
*/
|
*/
|
||||||
private final static String getHostName(String host) {
|
private final String getHostName(String host) {
|
||||||
if (host == null) return null;
|
if (host == null) return null;
|
||||||
if (host.length() == 60 && host.toLowerCase().endsWith(".b32.i2p"))
|
if (host.length() == 60 && host.toLowerCase().endsWith(".b32.i2p"))
|
||||||
return host;
|
return host;
|
||||||
try {
|
Destination dest = _context.namingService().lookup(host);
|
||||||
Destination dest = I2PTunnel.destFromName(host);
|
if (dest == null) return "i2p";
|
||||||
if (dest == null) return "i2p";
|
return Base32.encode(dest.calculateHash().getData()) + ".b32.i2p";
|
||||||
return Base32.encode(dest.calculateHash().getData()) + ".b32.i2p";
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
return "i2p";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -947,12 +940,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
|||||||
// Skip jump servers we don't know
|
// Skip jump servers we don't know
|
||||||
String jumphost = jurl.substring(7); // "http://"
|
String jumphost = jurl.substring(7); // "http://"
|
||||||
jumphost = jumphost.substring(0, jumphost.indexOf('/'));
|
jumphost = jumphost.substring(0, jumphost.indexOf('/'));
|
||||||
try {
|
Destination dest = I2PAppContext.getGlobalContext().namingService().lookup(jumphost);
|
||||||
Destination dest = I2PTunnel.destFromName(jumphost);
|
if (dest == null) continue;
|
||||||
if (dest == null) continue;
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.write("<br><a href=\"".getBytes());
|
out.write("<br><a href=\"".getBytes());
|
||||||
out.write(jurl.getBytes());
|
out.write(jurl.getBytes());
|
||||||
@@ -1014,7 +1003,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
|||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
try {
|
try {
|
||||||
Destination d = I2PTunnel.destFromName(host);
|
Destination d = _context.namingService().lookup(host);
|
||||||
if (d == null) return false;
|
if (d == null) return false;
|
||||||
} catch (DataFormatException dfe) {
|
} catch (DataFormatException dfe) {
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,6 @@ import java.util.List;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import net.i2p.client.streaming.I2PSocket;
|
import net.i2p.client.streaming.I2PSocket;
|
||||||
import net.i2p.data.DataFormatException;
|
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PAppThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
@@ -52,15 +51,11 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
dests = new ArrayList(2);
|
dests = new ArrayList(2);
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
String destination = tok.nextToken();
|
String destination = tok.nextToken();
|
||||||
try {
|
Destination destN = _context.namingService().lookup(destination);
|
||||||
Destination destN = I2PTunnel.destFromName(destination);
|
if (destN == null)
|
||||||
if (destN == null)
|
l.log("Could not resolve " + destination);
|
||||||
l.log("Could not resolve " + destination);
|
else
|
||||||
else
|
dests.add(destN);
|
||||||
dests.add(destN);
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
l.log("Bad format parsing \"" + destination + "\"");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dests.isEmpty()) {
|
if (dests.isEmpty()) {
|
||||||
|
@@ -10,6 +10,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.I2PException;
|
import net.i2p.I2PException;
|
||||||
import net.i2p.client.streaming.I2PSocketManager;
|
import net.i2p.client.streaming.I2PSocketManager;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
@@ -200,7 +201,7 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Destination dest = I2PTunnel.destFromName(destination);
|
Destination dest = I2PAppContext.getGlobalContext().namingService().lookup(destination);
|
||||||
if (dest == null) {
|
if (dest == null) {
|
||||||
synchronized (lock) { // Logger is not thread safe
|
synchronized (lock) { // Logger is not thread safe
|
||||||
l.log("Unresolvable: " + destination + "");
|
l.log("Unresolvable: " + destination + "");
|
||||||
|
@@ -204,7 +204,7 @@ public class SOCKS4aServer extends SOCKSServer {
|
|||||||
// Let's not due a new Dest for every request, huh?
|
// Let's not due a new Dest for every request, huh?
|
||||||
//I2PSocketManager sm = I2PSocketManagerFactory.createManager();
|
//I2PSocketManager sm = I2PSocketManagerFactory.createManager();
|
||||||
//destSock = sm.connect(I2PTunnel.destFromName(connHostName), null);
|
//destSock = sm.connect(I2PTunnel.destFromName(connHostName), null);
|
||||||
destSock = t.createI2PSocket(I2PTunnel.destFromName(connHostName));
|
destSock = t.createI2PSocket(I2PAppContext.getGlobalContext().namingService().lookup(connHostName));
|
||||||
} else if ("localhost".equals(connHostName) || "127.0.0.1".equals(connHostName)) {
|
} else if ("localhost".equals(connHostName) || "127.0.0.1".equals(connHostName)) {
|
||||||
String err = "No localhost accesses allowed through the Socks Proxy";
|
String err = "No localhost accesses allowed through the Socks Proxy";
|
||||||
_log.error(err);
|
_log.error(err);
|
||||||
@@ -237,7 +237,7 @@ public class SOCKS4aServer extends SOCKSServer {
|
|||||||
_log.debug("connecting to port " + connPort + " proxy " + proxy + " for " + connHostName + "...");
|
_log.debug("connecting to port " + connPort + " proxy " + proxy + " for " + connHostName + "...");
|
||||||
// this isn't going to work, these need to be socks outproxies so we need
|
// this isn't going to work, these need to be socks outproxies so we need
|
||||||
// to do a socks session to them?
|
// to do a socks session to them?
|
||||||
destSock = t.createI2PSocket(I2PTunnel.destFromName(proxy));
|
destSock = t.createI2PSocket(I2PAppContext.getGlobalContext().namingService().lookup(proxy));
|
||||||
}
|
}
|
||||||
confirmConnection();
|
confirmConnection();
|
||||||
_log.debug("connection confirmed - exchanging data...");
|
_log.debug("connection confirmed - exchanging data...");
|
||||||
|
@@ -360,14 +360,14 @@ public class SOCKS5Server extends SOCKSServer {
|
|||||||
// Let's not due a new Dest for every request, huh?
|
// Let's not due a new Dest for every request, huh?
|
||||||
//I2PSocketManager sm = I2PSocketManagerFactory.createManager();
|
//I2PSocketManager sm = I2PSocketManagerFactory.createManager();
|
||||||
//destSock = sm.connect(I2PTunnel.destFromName(connHostName), null);
|
//destSock = sm.connect(I2PTunnel.destFromName(connHostName), null);
|
||||||
Destination dest = I2PTunnel.destFromName(connHostName);
|
Destination dest = I2PAppContext.getGlobalContext().namingService().lookup(connHostName);
|
||||||
if (dest == null) {
|
if (dest == null) {
|
||||||
try {
|
try {
|
||||||
sendRequestReply(Reply.HOST_UNREACHABLE, AddressType.DOMAINNAME, null, "0.0.0.0", 0, out);
|
sendRequestReply(Reply.HOST_UNREACHABLE, AddressType.DOMAINNAME, null, "0.0.0.0", 0, out);
|
||||||
} catch (IOException ioe) {}
|
} catch (IOException ioe) {}
|
||||||
throw new SOCKSException("Host not found");
|
throw new SOCKSException("Host not found");
|
||||||
}
|
}
|
||||||
destSock = t.createI2PSocket(I2PTunnel.destFromName(connHostName));
|
destSock = t.createI2PSocket(I2PAppContext.getGlobalContext().namingService().lookup(connHostName));
|
||||||
} else if ("localhost".equals(connHostName) || "127.0.0.1".equals(connHostName)) {
|
} else if ("localhost".equals(connHostName) || "127.0.0.1".equals(connHostName)) {
|
||||||
String err = "No localhost accesses allowed through the Socks Proxy";
|
String err = "No localhost accesses allowed through the Socks Proxy";
|
||||||
_log.error(err);
|
_log.error(err);
|
||||||
@@ -455,10 +455,10 @@ public class SOCKS5Server extends SOCKSServer {
|
|||||||
Properties overrides = new Properties();
|
Properties overrides = new Properties();
|
||||||
overrides.setProperty("option.i2p.streaming.connectDelay", "1000");
|
overrides.setProperty("option.i2p.streaming.connectDelay", "1000");
|
||||||
I2PSocketOptions proxyOpts = tun.buildOptions(overrides);
|
I2PSocketOptions proxyOpts = tun.buildOptions(overrides);
|
||||||
Destination dest = I2PTunnel.destFromName(proxy);
|
Destination dest = I2PAppContext.getGlobalContext().namingService().lookup(proxy);
|
||||||
if (dest == null)
|
if (dest == null)
|
||||||
throw new SOCKSException("Outproxy not found");
|
throw new SOCKSException("Outproxy not found");
|
||||||
I2PSocket destSock = tun.createI2PSocket(I2PTunnel.destFromName(proxy), proxyOpts);
|
I2PSocket destSock = tun.createI2PSocket(I2PAppContext.getGlobalContext().namingService().lookup(proxy), proxyOpts);
|
||||||
try {
|
try {
|
||||||
DataOutputStream out = new DataOutputStream(destSock.getOutputStream());
|
DataOutputStream out = new DataOutputStream(destSock.getOutputStream());
|
||||||
boolean authAvail = Boolean.valueOf(props.getProperty(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH)).booleanValue();
|
boolean authAvail = Boolean.valueOf(props.getProperty(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH)).booleanValue();
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package net.i2p.i2ptunnel.socks;
|
package net.i2p.i2ptunnel.socks;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.data.Base32;
|
import net.i2p.data.Base32;
|
||||||
import net.i2p.data.DataFormatException;
|
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.i2ptunnel.I2PTunnel;
|
import net.i2p.i2ptunnel.I2PTunnel;
|
||||||
|
|
||||||
@@ -74,11 +74,8 @@ public class SOCKSHeader {
|
|||||||
String name = getHost();
|
String name = getHost();
|
||||||
if (name == null)
|
if (name == null)
|
||||||
return null;
|
return null;
|
||||||
try {
|
// the naming service does caching (thankfully)
|
||||||
// the naming service does caching (thankfully)
|
return I2PAppContext.getGlobalContext().namingService().lookup(name);
|
||||||
return I2PTunnel.destFromName(name);
|
|
||||||
} catch (DataFormatException dfe) {}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
|
@@ -117,9 +117,7 @@ import net.i2p.util.Log;
|
|||||||
|
|
||||||
// Setup the sink. Always send repliable datagrams.
|
// Setup the sink. Always send repliable datagrams.
|
||||||
if (destination != null && destination.length() > 0) {
|
if (destination != null && destination.length() > 0) {
|
||||||
try {
|
_otherDest = _context.namingService().lookup(destination);
|
||||||
_otherDest = I2PTunnel.destFromName(destination);
|
|
||||||
} catch (DataFormatException dfe) {}
|
|
||||||
if (_otherDest == null) {
|
if (_otherDest == null) {
|
||||||
l.log("Could not resolve " + destination);
|
l.log("Could not resolve " + destination);
|
||||||
throw new RuntimeException("failed to create session - could not resolve " + destination);
|
throw new RuntimeException("failed to create session - could not resolve " + destination);
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../../core/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
</target>
|
</target>
|
||||||
<condition property="depend.available">
|
<condition property="depend.available">
|
||||||
<typefound name="depend" />
|
<typefound name="depend" />
|
||||||
@@ -45,9 +45,7 @@
|
|||||||
<delete dir="./build" />
|
<delete dir="./build" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<ant dir="../../../core/java/" target="cleandep" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<ant dir="../../../core/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -3,12 +3,10 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../../router/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
<ant dir="../../systray/java/" target="build" />
|
|
||||||
<!-- router will build core -->
|
|
||||||
</target>
|
</target>
|
||||||
<target name="prepare">
|
<target name="prepare">
|
||||||
<ant dir="../../jetty/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
</target>
|
</target>
|
||||||
<condition property="depend.available">
|
<condition property="depend.available">
|
||||||
<typefound name="depend" />
|
<typefound name="depend" />
|
||||||
@@ -235,13 +233,7 @@
|
|||||||
<delete file="../jsp/web-out.xml" />
|
<delete file="../jsp/web-out.xml" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<!-- router will clean core -->
|
|
||||||
<ant dir="../../../router/java/" target="cleandep" />
|
|
||||||
<ant dir="../../systray/java/" target="cleandep" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<!-- router will clean core -->
|
|
||||||
<ant dir="../../../router/java/" target="distclean" />
|
|
||||||
<ant dir="../../systray/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -3,9 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../ministreaming/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
<ant dir="../../streaming/java/" target="build" />
|
|
||||||
<!-- ministreaming will build core -->
|
|
||||||
</target>
|
</target>
|
||||||
<condition property="depend.available">
|
<condition property="depend.available">
|
||||||
<typefound name="depend" />
|
<typefound name="depend" />
|
||||||
@@ -69,13 +67,7 @@
|
|||||||
<delete dir="./build" />
|
<delete dir="./build" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<!-- ministreaming will clean core -->
|
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
<ant dir="../../streaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<!-- ministreaming will clean core -->
|
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
<ant dir="../../streaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -3,8 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../ministreaming/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
<!-- ministreaming will build core -->
|
|
||||||
</target>
|
</target>
|
||||||
<condition property="depend.available">
|
<condition property="depend.available">
|
||||||
<typefound name="depend" />
|
<typefound name="depend" />
|
||||||
@@ -62,11 +61,7 @@
|
|||||||
<delete dir="./build" />
|
<delete dir="./build" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<!-- ministreaming will clean core -->
|
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<!-- ministreaming will clean core -->
|
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../jetty/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
</target>
|
</target>
|
||||||
<property name="javac.compilerargs" value="" />
|
<property name="javac.compilerargs" value="" />
|
||||||
<target name="compile">
|
<target name="compile">
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../../core/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
</target>
|
</target>
|
||||||
<property name="javac.compilerargs" value="" />
|
<property name="javac.compilerargs" value="" />
|
||||||
<target name="compile">
|
<target name="compile">
|
||||||
@@ -55,10 +55,7 @@
|
|||||||
<delete dir="./build" />
|
<delete dir="./build" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<!-- router will clean core -->
|
|
||||||
<ant dir="../../../core/java/" target="cleandep" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<ant dir="../../../core/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
79
build.xml
79
build.xml
@@ -62,33 +62,79 @@
|
|||||||
<target name="build2" depends="builddep, jar, buildWEB" />
|
<target name="build2" depends="builddep, jar, buildWEB" />
|
||||||
<target name="buildSmall" depends="builddepSmall, jarSmall, buildWEB" />
|
<target name="buildSmall" depends="builddepSmall, jarSmall, buildWEB" />
|
||||||
<target name="buildclean" depends="distclean, build" />
|
<target name="buildclean" depends="distclean, build" />
|
||||||
<target name="builddep" depends="builddepSmall">
|
|
||||||
<!-- build *everything* here, but only once -->
|
<target name="builddep" depends="builddepSmall, buildBOB, buildSAM, buildSusiMail, buildSusiDNS, buildI2PSnark" />
|
||||||
|
|
||||||
|
<target name="builddepSmall" depends="buildrouter, buildSystray, buildRouterConsole, buildStreaming, buildI2PTunnel, buildAddressbook" />
|
||||||
|
|
||||||
|
<!-- start of buildX, one for each sub-build.xml.
|
||||||
|
Do not put ant tasks in the sub-build.xmls anymore,
|
||||||
|
so the build will go faster.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- TODO remove I2PTunnel dependency in BOB -->
|
||||||
|
<target name="buildBOB" depends="buildStreaming, buildI2PTunnel" >
|
||||||
<ant dir="apps/BOB/" target="jar" />
|
<ant dir="apps/BOB/" target="jar" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildSAM" depends="buildStreaming" >
|
||||||
<ant dir="apps/sam/java/" target="jar" />
|
<ant dir="apps/sam/java/" target="jar" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildSusiMail" depends="buildCore, buildJetty" >
|
||||||
<ant dir="apps/susimail/" target="war" />
|
<ant dir="apps/susimail/" target="war" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildSusiDNS" depends="buildCore, buildJetty" >
|
||||||
<ant dir="apps/susidns/src" target="all" />
|
<ant dir="apps/susidns/src" target="all" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildI2PSnark" depends="buildStreaming, buildJetty" >
|
||||||
<ant dir="apps/i2psnark/java/" target="war" />
|
<ant dir="apps/i2psnark/java/" target="war" />
|
||||||
</target>
|
</target>
|
||||||
<target name="builddepSmall">
|
|
||||||
<ant dir="core/java/" target="jar" />
|
<target name="buildAddressbook" depends="buildCore, buildJetty" >
|
||||||
<ant dir="router/java/" target="jar" />
|
|
||||||
<ant dir="apps/systray/java/" target="jar" />
|
|
||||||
<ant dir="apps/routerconsole/java/" target="jar" />
|
|
||||||
<ant dir="apps/ministreaming/java/" target="jar" />
|
|
||||||
<ant dir="apps/streaming/java/" target="jar" />
|
|
||||||
<ant dir="apps/i2ptunnel/java/" target="build" />
|
|
||||||
<ant dir="apps/addressbook/" target="war" />
|
<ant dir="apps/addressbook/" target="war" />
|
||||||
</target>
|
</target>
|
||||||
<target name="buildrouter">
|
|
||||||
<ant dir="core/java/" target="jar" />
|
<target name="buildI2PTunnel" depends="buildStreaming, buildJetty" >
|
||||||
|
<ant dir="apps/i2ptunnel/java/" target="build" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildRouterConsole" depends="buildrouter, buildSystray, buildJetty" >
|
||||||
|
<ant dir="apps/routerconsole/java/" target="jar" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildJetty" >
|
||||||
|
<ant dir="apps/jetty" target="build" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildSystray" depends="buildCore" >
|
||||||
|
<ant dir="apps/systray/java/" target="jar" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildStreaming" depends="buildMinistreaming" >
|
||||||
|
<ant dir="apps/streaming/java/" target="jar" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildMinistreaming" depends="buildCore" >
|
||||||
|
<ant dir="apps/ministreaming/java/" target="jar" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="buildRouter" depends="buildrouter" />
|
||||||
|
<target name="buildrouter" depends="buildCore" >
|
||||||
<ant dir="router/java/" target="jar" />
|
<ant dir="router/java/" target="jar" />
|
||||||
<copy file="core/java/build/i2p.jar" todir="build/" />
|
|
||||||
<copy file="router/java/build/router.jar" todir="build/" />
|
<copy file="router/java/build/router.jar" todir="build/" />
|
||||||
</target>
|
</target>
|
||||||
<target name="buildWEB">
|
|
||||||
<ant dir="apps/jetty" target="ensureJettylib" />
|
<target name="buildCore" >
|
||||||
<ant dir="apps/routerconsole/java" target="build" />
|
<ant dir="core/java/" target="jar" />
|
||||||
|
<copy file="core/java/build/i2p.jar" todir="build/" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- end of sub-build.xml targets -->
|
||||||
|
|
||||||
|
<target name="buildWEB" depends="buildRouterConsole" >
|
||||||
<copy file="apps/routerconsole/java/build/routerconsole.jar" todir="build/" />
|
<copy file="apps/routerconsole/java/build/routerconsole.jar" todir="build/" />
|
||||||
<copy file="apps/routerconsole/java/build/routerconsole.war" todir="build/" />
|
<copy file="apps/routerconsole/java/build/routerconsole.war" todir="build/" />
|
||||||
<copy file="apps/jetty/jettylib/org.mortbay.jetty.jar" todir="build/" />
|
<copy file="apps/jetty/jettylib/org.mortbay.jetty.jar" todir="build/" />
|
||||||
@@ -98,6 +144,7 @@
|
|||||||
<copy file="apps/jetty/jettylib/commons-el.jar" todir="build/" />
|
<copy file="apps/jetty/jettylib/commons-el.jar" todir="build/" />
|
||||||
<copy file="apps/jetty/jettylib/javax.servlet.jar" todir="build/" />
|
<copy file="apps/jetty/jettylib/javax.servlet.jar" todir="build/" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="buildexe">
|
<target name="buildexe">
|
||||||
<condition property="noExe">
|
<condition property="noExe">
|
||||||
<os arch="x86_64" />
|
<os arch="x86_64" />
|
||||||
|
@@ -1,3 +1,12 @@
|
|||||||
|
2010-11-28 zzz
|
||||||
|
* Build: Move all dependencies to top-level build.xml,
|
||||||
|
so each sub-build.xml is only executed once
|
||||||
|
* i2psnark:
|
||||||
|
- Fix NPE and other partials bugs
|
||||||
|
- More extension message stubbing
|
||||||
|
- Log tweaks
|
||||||
|
* I2PTunnel: Deprecate destFromName()
|
||||||
|
|
||||||
2010-11-27 zzz
|
2010-11-27 zzz
|
||||||
* Build:
|
* Build:
|
||||||
- Add man pages to package
|
- Add man pages to package
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<target name="all" depends="clean, build" />
|
<target name="all" depends="clean, build" />
|
||||||
<target name="build" depends="builddep, jar" />
|
<target name="build" depends="builddep, jar" />
|
||||||
<target name="builddep">
|
<target name="builddep">
|
||||||
<ant dir="../../core/java/" target="build" />
|
<!-- run from top level build.xml to get dependencies built -->
|
||||||
</target>
|
</target>
|
||||||
<target name="builddeptest">
|
<target name="builddeptest">
|
||||||
<ant dir="../../core/java/" target="jarTest" />
|
<ant dir="../../core/java/" target="jarTest" />
|
||||||
@@ -131,9 +131,7 @@
|
|||||||
<delete dir="./build" />
|
<delete dir="./build" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<ant dir="../../core/java/" target="cleandep" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<ant dir="../../core/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 12;
|
public final static long BUILD = 13;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user