package net.i2p.router.transport;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Vector;
import net.i2p.data.Hash;
import net.i2p.data.router.RouterAddress;
import net.i2p.data.router.RouterInfo;
import net.i2p.router.CommSystemFacade.Status;
import net.i2p.router.OutNetMessage;
/**
* Defines a way to send a message to another peer and start listening for messages.
*
* To implement a new or pluggable I2P transport, implement this interface,
* and add it to TransportManager.startListening().
*
*/
public interface Transport {
public TransportBid bid(RouterInfo toAddress, long dataSize);
/**
* Asynchronously send the message as requested in the message and, if the
* send is successful, queue up any msg.getOnSendJob job, and register it
* with the OutboundMessageRegistry (if it has a reply selector). If the
* send fails, queue up any msg.getOnFailedSendJob
*
*/
public void send(OutNetMessage msg);
public void startListening();
public void stopListening();
/**
* What addresses are we currently listening to?
* Replaces getCurrentAddress()
* @return all addresses, non-null
* @since IPv6
*/
public List<RouterAddress> getCurrentAddresses();
/**
* Do we have any current address?
* @since IPv6
*/
public boolean hasCurrentAddress();
/**
* Ask the transport to update its addresses based on current information and return them
* @return all addresses, non-null
*/
public List<RouterAddress> updateAddress();
/**
* @since IPv6
*/
public enum AddressSource {
SOURCE_UPNP("upnp"),
SOURCE_INTERFACE("local"),
/** unused */
SOURCE_CONFIG("config"),
SOURCE_SSU("ssu");
private final String cfgstr;
AddressSource(String cfgstr) {
this.cfgstr = cfgstr;
}
public String toConfigString() {
return cfgstr;
}
}
/**
* Notify a transport of an external address change.
* This may be from a local interface, UPnP, a config change, etc.
* This should not be called if the ip didn't change
* (from that source's point of view), or is a local address.
* May be called multiple times for IPv4 or IPv6.
* The transport should also do its own checking on whether to accept
* notifications from this source.
*
* This can be called before startListening() to set an initial address,
* or after the transport is running.
*
* @param source defined in Transport.java
* @param ip typ. IPv4 or IPv6 non-local; may be null to indicate IPv4 failure or port info only
* @param port 0 for unknown or unchanged
*/
public void externalAddressReceived(AddressSource source, byte[] ip, int port);
/**
* Notify a transport of an external address change.
* This may be from a local interface, UPnP, a config change, etc.
* This should not be called if the ip didn't change
* (from that source's point of view), or is a local address.
* May be called multiple times for IPv4 or IPv6.
* The transport should also do its own checking on whether to accept
* notifications from this source.
*
* This can be called after the transport is running.
*
* TODO externalAddressRemoved(source, ip, port)
*
* @param source defined in Transport.java
* @since 0.9.20
*/
public void externalAddressRemoved(AddressSource source, boolean ipv6);
/**
* Notify a transport of the results of trying to forward a port.
*
* @param ip may be null
* @param port the internal port
* @param externalPort the external port, which for now should always be the same as
* the internal port if the forwarding was successful.
*/
public void forwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason);
/**
* What INTERNAL port would the transport like to have forwarded by UPnP.
* This can't be passed via getCurrentAddress(), as we have to open the port
* before we can publish the address, and that's the external port anyway.
*
* @return port or -1 for none or 0 for any
*/
public int getRequestedPort();
/** Who to notify on message availability */
public void setListener(TransportEventListener listener);
/** The unique identity of this Transport */
public String getStyle();
public int countPeers();
public int countActivePeers();
public int countActiveSendPeers();
public boolean haveCapacity();
public boolean haveCapacity(int pct);
public Vector<Long> getClockSkews();
public List<String> getMostRecentErrorMessages();
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException;
/**
* Previously returned short, now enum as of 0.9.20
*/
public Status getReachabilityStatus();
/**
* @deprecated unused
*/
@Deprecated
public void recheckReachability();
public boolean isBacklogged(Hash peer);
/**
* Was the peer UNreachable (outbound only) the last time we tried it?
* This is NOT reset if the peer contacts us and it is never expired.
*/
public boolean wasUnreachable(Hash peer);
public boolean isUnreachable(Hash peer);
public boolean isEstablished(Hash peer);
/**
* Tell the transport that we may disconnect from this peer.
* This is advisory only.
*
* @since 0.9.24
*/
public void mayDisconnect(Hash peer);
}