Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UPnP implementation - rebased #94

Merged
merged 1 commit into from
Mar 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modP2pImpl/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<path id="cp">
<pathelement location="${dir.mod}/modP2p.jar" />
<pathelement location="${dir.lib}/libminiupnp/miniupnpc_linux.jar"/>
</path>

<target name="clean_build" depends="clean">
Expand Down
1 change: 1 addition & 0 deletions modP2pImpl/module-info.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module aion.p2p.impl {
requires aion.p2p;
requires miniupnpc.linux;
exports org.aion.p2p.impl;
}
11 changes: 4 additions & 7 deletions modP2pImpl/src/org/aion/p2p/impl/P2pMgr.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public final class P2pMgr implements IP2pMgr {

private final static int TIMEOUT_OUTBOUND_CONNECT = 10000;
private final static int TIMEOUT_OUTBOUND_NODES = 10000;
private final static int PERIOD_UPNP_PORT_MAPPING = 3600000;

private final static int TIMEOUT_MSG_READ = 10000;

Expand Down Expand Up @@ -678,10 +679,6 @@ private void handleKernelMsg(int _nodeIdHash, int _route, final byte[] _msgBytes
}
}

private void runUpnp() {
// TODO: implement
}

@Override
public void run() {
try {
Expand All @@ -697,13 +694,13 @@ public void run() {
tcpServer.socket().bind(new InetSocketAddress(Node.ipBytesToStr(selfIp), selfPort));
tcpServer.register(selector, SelectionKey.OP_ACCEPT);

if (this.upnpEnable)
runUpnp();

Thread boss = new Thread(new TaskInbound(), "p2p-pi");
boss.setPriority(Thread.MAX_PRIORITY);
boss.start();

if (upnpEnable)
scheduledWorkers.scheduleWithFixedDelay(new TaskUPnPManager(selfPort), 1, PERIOD_UPNP_PORT_MAPPING, TimeUnit.MILLISECONDS);

if (showStatus)
scheduledWorkers.scheduleWithFixedDelay(new TaskStatus(), 2, PERIOD_SHOW_STATUS, TimeUnit.MILLISECONDS);
scheduledWorkers.scheduleWithFixedDelay(new TaskRequestActiveNodes(this), 5, PERIOD_REQUEST_ACTIVE_NODES,
Expand Down
103 changes: 103 additions & 0 deletions modP2pImpl/src/org/aion/p2p/impl/TaskUPnPManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.aion.p2p.impl;

import fr.free.miniupnp.IGDdatas;
import fr.free.miniupnp.MiniupnpcLibrary;
import fr.free.miniupnp.UPNPDev;
import fr.free.miniupnp.UPNPUrls;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

public class TaskUPnPManager implements Runnable {

private final static String UPNP_PROTOCOL_TCP = "TCP";
private final static String UPNP_PORT_MAPPING_DESCRIPTION = "aion-UPnP";
private final static int DEFAULT_UPNP_PORT_MAPPING_LIFETIME_IN_SECONDS = 3600;
private final static int UPNP_DELAY = 2000;

private int port;
MiniupnpcLibrary miniupnpc;

TaskUPnPManager(int port){
this.port = port;
miniupnpc = MiniupnpcLibrary.INSTANCE;
}

@Override
public void run() {
Thread.currentThread().setName("p2p-UPnP");

UPNPUrls urls = new UPNPUrls();
IGDdatas data = new IGDdatas();

ByteBuffer lanaddr = ByteBuffer.allocate(16);

UPNPDev devlist = miniupnpc.upnpDiscover(UPNP_DELAY, null, null, 0, 0, (byte) 2, IntBuffer.allocate(1));
if (devlist != null) {
if (miniupnpc.UPNP_GetValidIGD(devlist, urls, data, lanaddr, 16) != 0) {
System.out.println("<p2p-UPnP Found possible IGD : " + urls.controlURL.getString(0) + ">");
System.out.println("<p2p-UPnP Local LAN ip address : " + new String(lanaddr.array()) + ">");

getExternalIpAddress(urls, data);
addPortMapping(urls, data, lanaddr);
getMappedPortInfo(urls, data);

miniupnpc.FreeUPNPUrls(urls);
} else {
System.out.println("<p2p-UPnP no-valid-UPNP-internet-gateway-device-found>");
}
} else {
System.out.println("<p2p-UPnP no-IGD-UPnP-device-found-on-network>");
}
}

private void addPortMapping(UPNPUrls urls, IGDdatas data, ByteBuffer lanaddr) {
int ret = miniupnpc.UPNP_AddPortMapping(
urls.controlURL.getString(0),
new String(data.first.servicetype),
String.valueOf(port),
String.valueOf(port),
new String(lanaddr.array()),
UPNP_PORT_MAPPING_DESCRIPTION,
UPNP_PROTOCOL_TCP,
null,
String.valueOf(DEFAULT_UPNP_PORT_MAPPING_LIFETIME_IN_SECONDS));

if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
System.out.println("<p2p-UPnP AddPortMapping() failed with code " + ret + ">");
}

private void getMappedPortInfo(UPNPUrls urls, IGDdatas data) {
ByteBuffer intClient = ByteBuffer.allocate(16);
ByteBuffer intPort = ByteBuffer.allocate(6);
ByteBuffer desc = ByteBuffer.allocate(80);
ByteBuffer enabled = ByteBuffer.allocate(4);
ByteBuffer leaseDuration = ByteBuffer.allocate(16);

int ret = miniupnpc.UPNP_GetSpecificPortMappingEntry(
urls.controlURL.getString(0), new String(data.first.servicetype),
String.valueOf(port), UPNP_PROTOCOL_TCP, null, intClient, intPort,
desc, enabled, leaseDuration);

if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) {
System.out.println("<p2p-UPnP GetSpecificPortMappingEntry() failed with code " + ret + ">");
return;
}

System.out.println("<p2p-UPnP InternalIP:Port = " +
new String(intClient.array()) + ":" + new String(intPort.array()) +
" (" + new String(desc.array()) + ") >");
}

private void getExternalIpAddress(UPNPUrls urls, IGDdatas data) {
ByteBuffer externalAddress = ByteBuffer.allocate(16);
int ret = miniupnpc.UPNP_GetExternalIPAddress(urls.controlURL.getString(0),
new String(data.first.servicetype), externalAddress);

if(ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) {
System.out.println("<p2p-UPnP get external ip address command failed with code = " + ret + ">");
return;
}

System.out.println("<p2p-UPnP ExternalIPAddress = " + new String(externalAddress.array()) + ">");
}
}