private void x_startTorrent() { boolean ok = _util.connect(); if (!ok) fatal("Unable to connect to I2P"); if (coordinator == null) { I2PServerSocket serversocket = _util.getServerSocket(); if (serversocket == null) fatal("Unable to listen for I2P connections"); else { Destination d = serversocket.getManager().getSession().getMyDestination(); if (_log.shouldLog(Log.INFO)) _log.info( "Listening on I2P destination " + d.toBase64() + " / " + d.calculateHash().toBase64()); } if (_log.shouldLog(Log.INFO)) _log.info("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient"); activity = "Collecting pieces"; coordinator = new PeerCoordinator(_util, id, infoHash, meta, storage, this, this); coordinator.setUploaded(savedUploaded); if (_peerCoordinatorSet != null) { // multitorrent _peerCoordinatorSet.add(coordinator); } else { // single torrent acceptor = new ConnectionAcceptor(_util, new PeerAcceptor(coordinator)); } // TODO pass saved closest DHT nodes to the tracker? or direct to the coordinator? trackerclient = new TrackerClient(_util, meta, additionalTrackerURL, coordinator, this); } // ensure acceptor is running when in multitorrent if (_peerCoordinatorSet != null && acceptor != null) { acceptor.startAccepting(); } stopped = false; if (coordinator.halted()) { coordinator.restart(); if (_peerCoordinatorSet != null) _peerCoordinatorSet.add(coordinator); } if (!trackerclient.started()) { trackerclient.start(); } else if (trackerclient.halted()) { if (storage != null) { try { storage.reopen(); } catch (IOException ioe) { try { storage.close(); } catch (IOException ioee) { ioee.printStackTrace(); } fatal("Could not reopen storage", ioe); } } trackerclient.start(); } else { if (_log.shouldLog(Log.INFO)) _log.info("NOT starting TrackerClient???"); } }
@Override public Destination lookup(String hostname) { Destination rv = super.lookup(hostname); if (rv != null) { hostname = hostname.toLowerCase(Locale.US); // If it's long, assume it's a key. if (hostname.length() < 516 && hostname.endsWith(".i2p") && !hostname.endsWith(".b32.i2p")) { File f = new File(_context.getRouterDir(), DEFAULT_HOSTS_FILE); if ((f.exists()) && (f.canWrite())) { synchronized (this) { FileOutputStream fos = null; try { fos = new FileOutputStream(f, true); String line = hostname + '=' + rv.toBase64() + System.getProperty("line.separator"); fos.write(DataHelper.getASCII(line)); } catch (IOException ioe) { System.err.println("Error appending: " + ioe); } finally { if (fos != null) try { fos.close(); } catch (IOException cioe) { } } } } } } return rv; }
public AddressBean getLookup() { if (this.detail == null) return null; if (isDirect()) { // go to some trouble to make this work for the published addressbook this.filter = this.detail.substring(0, 1); this.search = this.detail; // we don't want the messages, we just want to populate entries super.getLoadBookMessages(); for (int i = 0; i < this.entries.length; i++) { if (this.search.equals(this.entries[i].getName())) return this.entries[i]; } return null; } Properties nsOptions = new Properties(); Properties outProps = new Properties(); nsOptions.setProperty("list", getFileName()); Destination dest = getNamingService().lookup(this.detail, nsOptions, outProps); if (dest == null) return null; AddressBean rv = new AddressBean(this.detail, dest.toBase64()); rv.setProperties(outProps); return rv; }
public void notifyStreamIncomingConnection(int id, Destination d) throws IOException { if (getStreamSession() == null) { _log.error("BUG! Received stream connection, but session is null!"); return; } if (!writeString("STREAM CONNECTED DESTINATION=" + d.toBase64() + " ID=" + id + "\n")) { throw new IOException("Error notifying connection to SAM client"); } }
public void notifyStreamIncomingConnection(Destination d) throws IOException { if (getStreamSession() == null) { _log.error("BUG! Received stream connection, but session is null!"); throw new NullPointerException("BUG! STREAM session is null!"); } if (!writeString(d.toBase64() + "\n")) { throw new IOException("Error notifying connection to SAM client"); } }
// SAMDatagramReceiver implementation public void receiveDatagramBytes(Destination sender, byte data[]) throws IOException { if (getDatagramSession() == null) { _log.error("BUG! Received datagram bytes, but session is null!"); throw new NullPointerException("BUG! DATAGRAM session is null!"); } ByteArrayOutputStream msg = new ByteArrayOutputStream(); String msgText = "DATAGRAM RECEIVED DESTINATION=" + sender.toBase64() + " SIZE=" + data.length + "\n"; msg.write(msgText.getBytes("ISO-8859-1")); if (_log.shouldLog(Log.DEBUG)) _log.debug("sending to client: " + msgText); msg.write(data); msg.flush(); writeBytes(ByteBuffer.wrap(msg.toByteArray())); }
public void receiveDatagramBytes( Destination sender, byte[] data, int proto, int fromPort, int toPort) throws IOException { if (this.clientAddress == null) { this.handler.receiveDatagramBytes(sender, data, proto, fromPort, toPort); } else { StringBuilder buf = new StringBuilder(600); buf.append(sender.toBase64()); if ((handler.verMajor == 3 && handler.verMinor >= 2) || handler.verMajor > 3) { buf.append(" FROM_PORT=").append(fromPort).append(" TO_PORT=").append(toPort); } buf.append('\n'); String msg = buf.toString(); ByteBuffer msgBuf = ByteBuffer.allocate(msg.length() + data.length); msgBuf.put(DataHelper.getASCII(msg)); msgBuf.put(data); msgBuf.flip(); this.server.send(this.clientAddress, msgBuf); } }
/* Parse and execute a NAMING message */ protected boolean execNamingMessage(String opcode, Properties props) { if (opcode.equals("LOOKUP")) { if (props == null) { _log.debug("No parameters specified in NAMING LOOKUP message"); return false; } String name = props.getProperty("NAME"); if (name == null) { _log.debug("Name to resolve not specified in NAMING message"); return false; } Destination dest = null; if (name.equals("ME")) { if (getRawSession() != null) { dest = getRawSession().getDestination(); } else if (getStreamSession() != null) { dest = getStreamSession().getDestination(); } else if (getDatagramSession() != null) { dest = getDatagramSession().getDestination(); } else { _log.debug("Lookup for SESSION destination, but session is null"); return false; } } else { try { dest = SAMUtils.getDest(name); } catch (DataFormatException e) { } } if (dest == null) { return writeString("NAMING REPLY RESULT=KEY_NOT_FOUND NAME=" + name + "\n"); } return writeString( "NAMING REPLY RESULT=OK NAME=" + name + " VALUE=" + dest.toBase64() + "\n"); } else { _log.debug("Unrecognized NAMING message opcode: \"" + opcode + "\""); return false; } }
// SAMDatagramReceiver implementation public void receiveDatagramBytes( Destination sender, byte data[], int proto, int fromPort, int toPort) throws IOException { if (getDatagramSession() == null) { _log.error("BUG! Received datagram bytes, but session is null!"); return; } ByteArrayOutputStream msg = new ByteArrayOutputStream(100 + data.length); String msgText = "DATAGRAM RECEIVED DESTINATION=" + sender.toBase64() + " SIZE=" + data.length; msg.write(DataHelper.getASCII(msgText)); if ((verMajor == 3 && verMinor >= 2) || verMajor > 3) { msgText = " FROM_PORT=" + fromPort + " TO_PORT=" + toPort; msg.write(DataHelper.getASCII(msgText)); } msg.write((byte) '\n'); if (_log.shouldLog(Log.DEBUG)) _log.debug("sending to client: " + msgText); msg.write(data); msg.flush(); writeBytes(ByteBuffer.wrap(msg.toByteArray())); }
public String lookup(String name) { Destination dest = getDestination(name); if (dest == null) return null; return dest.toBase64(); }
String getOurIPString() { Destination dest = getMyDestination(); if (dest != null) return dest.toBase64(); return "unknown"; }
public static void notifyStreamIncomingConnection(SocketChannel client, Destination d) throws IOException { if (!writeString(d.toBase64() + "\n", client)) { throw new IOException("Error notifying connection to SAM client"); } }
/** Perform actions, returning messages about this. */ @Override public String getMessages() { if (isDirect()) return super.getMessages(); // Loading config and addressbook moved into getLoadBookMessages() String message = ""; if( action != null ) { Properties nsOptions = new Properties(); // only blockfile needs this nsOptions.setProperty("list", getFileName()); if (_context.getBooleanProperty(PROP_PW_ENABLE) || (serial != null && serial.equals(lastSerial))) { boolean changed = false; if (action.equals(_("Add")) || action.equals(_("Replace"))) { if(hostname != null && destination != null) { try { // throws IAE with translated message String host = AddressBean.toASCII(hostname); String displayHost = host.equals(hostname) ? hostname : hostname + " (" + host + ')'; Properties outProperties= new Properties(); Destination oldDest = getNamingService().lookup(host, nsOptions, outProperties); if (oldDest != null && destination.equals(oldDest.toBase64())) { message = _("Host name {0} is already in address book, unchanged.", displayHost); } else if (oldDest != null && !action.equals(_("Replace"))) { message = _("Host name {0} is already in address book with a different destination. Click \"Replace\" to overwrite.", displayHost); } else { try { Destination dest = new Destination(destination); if (oldDest != null) { nsOptions.putAll(outProperties); nsOptions.setProperty("m", Long.toString(_context.clock().now())); } nsOptions.setProperty("s", _("Manually added via SusiDNS")); boolean success = getNamingService().put(host, dest, nsOptions); if (success) { changed = true; if (oldDest == null) message = _("Destination added for {0}.", displayHost); else message = _("Destination changed for {0}.", displayHost); if (!host.endsWith(".i2p")) message += "<br>" + _("Warning - host name does not end with \".i2p\""); // clear form hostname = null; destination = null; } else { message = _("Failed to add Destination for {0} to naming service {1}", displayHost, getNamingService().getName()) + "<br>"; } } catch (DataFormatException dfe) { message = _("Invalid Base 64 destination."); } } } catch (IllegalArgumentException iae) { message = iae.getMessage(); if (message == null) message = _("Invalid host name \"{0}\".", hostname); } } else { message = _("Please enter a host name and destination"); } // clear search when adding search = null; } else if (action.equals(_("Delete Selected")) || action.equals(_("Delete Entry"))) { String name = null; int deleted = 0; for (String n : deletionMarks) { boolean success = getNamingService().remove(n, nsOptions); String uni = AddressBean.toUnicode(n); String displayHost = uni.equals(n) ? n : uni + " (" + n + ')'; if (!success) { message += _("Failed to delete Destination for {0} from naming service {1}", displayHost, getNamingService().getName()) + "<br>"; } else if (deleted++ == 0) { changed = true; name = displayHost; } } if( changed ) { if (deleted == 1) // parameter is a host name message += _("Destination {0} deleted.", name); else // parameter will always be >= 2 message = ngettext("1 destination deleted.", "{0} destinations deleted.", deleted); } else { message = _("No entries selected to delete."); } // clear search when deleting if (action.equals(_("Delete Entry"))) search = null; } if( changed ) { message += "<br>" + _("Address book saved."); } } else { message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.") + ' ' + _("If the problem persists, verify that you have cookies enabled in your browser."); } } action = null; if( message.length() > 0 ) message = "<p class=\"messages\">" + message + "</p>"; return message; }