public void run() { // Listen for packets tracker.startReceive(System.currentTimeMillis()); try { runLoop(); } catch (Throwable t) { // Impossible? It keeps on exiting. We get the below, // but not this... try { System.err.print(t.getClass().getName()); System.err.println(); } catch (Throwable tt) { } ; try { System.err.print(t.getMessage()); System.err.println(); } catch (Throwable tt) { } ; try { System.gc(); System.runFinalization(); System.gc(); System.runFinalization(); } catch (Throwable tt) { } try { Runtime r = Runtime.getRuntime(); System.err.print(r.freeMemory()); System.err.println(); System.err.print(r.totalMemory()); System.err.println(); } catch (Throwable tt) { } ; try { t.printStackTrace(); } catch (Throwable tt) { } ; } finally { System.err.println("run() exiting for UdpSocketHandler on port " + _sock.getLocalPort()); Logger.error(this, "run() exiting for UdpSocketHandler on port " + _sock.getLocalPort()); synchronized (this) { _isDone = true; notifyAll(); } } }
/** * Send a block of encoded bytes to a peer. This is called by send, and by * IncomingPacketFilter.processOutgoing(..). * * @param blockToSend The data block to send. * @param destination The peer to send it to. */ public void sendPacket(byte[] blockToSend, Peer destination, boolean allowLocalAddresses) throws LocalAddressException { assert (blockToSend != null); if (!_active) { Logger.error(this, "Trying to send packet but no longer active"); // It is essential that for recording accurate AddressTracker data that we don't send any more // packets after shutdown. return; } // there should be no DNS needed here, but go ahead if we can, but complain doing it if (destination.getAddress(false, allowLocalAddresses) == null) { Logger.error( this, "Tried sending to destination without pre-looked up IP address(needs a real Peer.getHostname()): null:" + destination.getPort(), new Exception("error")); if (destination.getAddress(true, allowLocalAddresses) == null) { Logger.error( this, "Tried sending to bad destination address: null:" + destination.getPort(), new Exception("error")); return; } } if (_dropProbability > 0) { if (dropRandom.nextInt() % _dropProbability == 0) { Logger.normal(this, "DROPPED: " + _sock.getLocalPort() + " -> " + destination.getPort()); return; } } InetAddress address = destination.getAddress(false, allowLocalAddresses); assert (address != null); int port = destination.getPort(); DatagramPacket packet = new DatagramPacket(blockToSend, blockToSend.length); packet.setAddress(address); packet.setPort(port); try { _sock.send(packet); tracker.sentPacketTo(destination); collector.addInfo(address + ":" + port, 0, blockToSend.length + UDP_HEADERS_LENGTH); if (logMINOR) Logger.minor( this, "Sent packet length " + blockToSend.length + " to " + address + ':' + port); } catch (IOException e) { if (packet.getAddress() instanceof Inet6Address) { Logger.normal( this, "Error while sending packet to IPv6 address: " + destination + ": " + e, e); } else { Logger.error(this, "Error while sending packet to " + destination + ": " + e, e); } } }
public UdpSocketHandler( int listenPort, InetAddress bindto, Node node, long startupTime, String title, IOStatisticCollector collector) throws SocketException { this.node = node; this.collector = collector; this.title = title; _bindTo = bindto; // Keep the Updater code in, just commented out, for now // We may want to be able to do on-line updates. // if (Updater.hasResource()) { // _sock = (DatagramSocket) Updater.getResource(); // } else { this.listenPort = listenPort; _sock = new DatagramSocket(listenPort, bindto); int sz = _sock.getReceiveBufferSize(); if (sz < 65536) { _sock.setReceiveBufferSize(65536); } try { // Exit reasonably quickly _sock.setReuseAddress(true); } catch (SocketException e) { throw new RuntimeException(e); } // } // Only used for debugging, no need to seed from Yarrow dropRandom = node.fastWeakRandom; logMINOR = Logger.shouldLog(LogLevel.MINOR, this); logDEBUG = Logger.shouldLog(LogLevel.DEBUG, this); tracker = AddressTracker.create(node.lastBootID, node.runDir(), listenPort); tracker.startSend(startupTime); }
public void close() { Logger.normal(this, "Closing.", new Exception("error")); synchronized (this) { _active = false; _sock.close(); if (!_started) return; while (!_isDone) { try { wait(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } tracker.storeData(node.bootID, node.runDir(), listenPort); }
private void realRun(DatagramPacket packet) { // Single receiving thread boolean gotPacket = getPacket(packet); long now = System.currentTimeMillis(); if (gotPacket) { long startTime = System.currentTimeMillis(); Peer peer = new Peer(packet.getAddress(), packet.getPort()); tracker.receivedPacketFrom(peer); long endTime = System.currentTimeMillis(); if (endTime - startTime > 50) { if (endTime - startTime > 3000) { Logger.error(this, "packet creation took " + (endTime - startTime) + "ms"); } else { if (logMINOR) Logger.minor(this, "packet creation took " + (endTime - startTime) + "ms"); } } byte[] data = packet.getData(); int offset = packet.getOffset(); int length = packet.getLength(); try { if (logMINOR) Logger.minor(this, "Processing packet of length " + length + " from " + peer); startTime = System.currentTimeMillis(); lowLevelFilter.process(data, offset, length, peer, now); endTime = System.currentTimeMillis(); if (endTime - startTime > 50) { if (endTime - startTime > 3000) { Logger.error(this, "processing packet took " + (endTime - startTime) + "ms"); } else { if (logMINOR) Logger.minor(this, "processing packet took " + (endTime - startTime) + "ms"); } } if (logMINOR) Logger.minor(this, "Successfully handled packet length " + length); } catch (Throwable t) { Logger.error(this, "Caught " + t + " from " + lowLevelFilter, t); } } else { if (logDEBUG) Logger.debug(this, "No packet received"); } }
public int getDetectedConnectivityStatus() { return tracker.getPortForwardStatus(); }
public void rescanPortForward() { tracker.rescan(); }