-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #367 from libp2p/1.1.1
- Loading branch information
Showing
22 changed files
with
630 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
name: Bug Report | ||
description: Create a bug report for jvm-libp2p | ||
|
||
body: | ||
- type: markdown | ||
attributes: | ||
value: | | ||
Thank you for filing a bug report! | ||
- type: textarea | ||
attributes: | ||
label: Summary | ||
description: Please provide a short summary of the bug, along with any information you feel relevant to replicate the bug. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Expected behavior | ||
description: Describe what you expect to happen. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Actual behavior | ||
description: Describe what actually happens. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Relevant log output | ||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. | ||
render: shell | ||
validations: | ||
required: false | ||
- type: textarea | ||
attributes: | ||
label: Possible Solution | ||
description: Suggest a fix/reason for the bug, or ideas how to implement the addition or change. | ||
validations: | ||
required: false | ||
- type: textarea | ||
attributes: | ||
label: Version | ||
description: Which version of libp2p are you using? libp2p version (version number, commit, or branch) | ||
validations: | ||
required: false | ||
- type: dropdown | ||
attributes: | ||
label: Would you like to work on fixing this bug ? | ||
description: Any contribution towards fixing the bug is greatly appreciated. We are more than happy to provide help on the process. | ||
options: | ||
- "Yes" | ||
- "No" | ||
- Maybe | ||
validations: | ||
required: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
blank_issues_enabled: true | ||
contact_links: | ||
- name: Technical Questions | ||
url: https://github.com/libp2p/jvm-libp2p/discussions/new?category=q-a | ||
about: Please ask technical questions in the jvm-libp2p Github Discussions forum. | ||
- name: Community-wide libp2p Discussion | ||
url: https://discuss.libp2p.io | ||
about: Discussions and questions about the libp2p community. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: Enhancement | ||
description: Suggest an improvement to an existing jvm-libp2p feature. | ||
body: | ||
- type: textarea | ||
attributes: | ||
label: Description | ||
description: Describe the enhancement that you are proposing. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Motivation | ||
description: Explain why this enhancement is beneficial. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Current Implementation | ||
description: Describe the current implementation. | ||
validations: | ||
required: true | ||
- type: dropdown | ||
attributes: | ||
label: Are you planning to do it yourself in a pull request ? | ||
description: Any contribution is greatly appreciated. We are more than happy to provide help on the process. | ||
options: | ||
- "Yes" | ||
- "No" | ||
- Maybe | ||
validations: | ||
required: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Feature request | ||
description: Suggest a new feature in jvm-libp2p | ||
body: | ||
- type: markdown | ||
attributes: | ||
value: | | ||
If you'd like to suggest a feature related to libp2p but not specifically related to the JVM implementation, please file an issue at https://github.com/libp2p/specs instead. | ||
- type: textarea | ||
attributes: | ||
label: Description | ||
description: Briefly describe the feature that you are requesting. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Motivation | ||
description: Explain why this feature is needed. | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Requirements | ||
description: Write a list of what you want this feature to do. | ||
placeholder: "1." | ||
validations: | ||
required: true | ||
- type: textarea | ||
attributes: | ||
label: Open questions | ||
description: Use this section to ask any questions that are related to the feature. | ||
validations: | ||
required: false | ||
- type: dropdown | ||
attributes: | ||
label: Are you planning to do it yourself in a pull request ? | ||
description: Any contribution is greatly appreciated. We are more than happy to provide help on the process. | ||
options: | ||
- "Yes" | ||
- "No" | ||
- Maybe | ||
validations: | ||
required: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
172 changes: 172 additions & 0 deletions
172
libp2p/src/main/java/io/libp2p/protocol/autonat/AutonatProtocol.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package io.libp2p.protocol.autonat; | ||
|
||
import com.google.protobuf.*; | ||
import io.libp2p.core.*; | ||
import io.libp2p.core.Stream; | ||
import io.libp2p.core.multiformats.*; | ||
import io.libp2p.core.multistream.*; | ||
import io.libp2p.protocol.*; | ||
import io.libp2p.protocol.autonat.pb.*; | ||
import java.io.*; | ||
import java.net.*; | ||
import java.util.*; | ||
import java.util.concurrent.*; | ||
import java.util.stream.*; | ||
import org.jetbrains.annotations.*; | ||
|
||
public class AutonatProtocol extends ProtobufProtocolHandler<AutonatProtocol.AutoNatController> { | ||
|
||
public static class Binding extends StrictProtocolBinding<AutoNatController> { | ||
public Binding() { | ||
super("/libp2p/autonat/v1.0.0", new AutonatProtocol()); | ||
} | ||
} | ||
|
||
public interface AutoNatController { | ||
CompletableFuture<Autonat.Message> rpc(Autonat.Message req); | ||
|
||
default CompletableFuture<Autonat.Message.DialResponse> requestDial( | ||
PeerId ourId, List<Multiaddr> us) { | ||
if (us.isEmpty()) | ||
throw new IllegalStateException("Requested autonat dial with no addresses!"); | ||
return rpc(Autonat.Message.newBuilder() | ||
.setType(Autonat.Message.MessageType.DIAL) | ||
.setDial( | ||
Autonat.Message.Dial.newBuilder() | ||
.setPeer( | ||
Autonat.Message.PeerInfo.newBuilder() | ||
.addAllAddrs( | ||
us.stream() | ||
.map(a -> ByteString.copyFrom(a.serialize())) | ||
.collect(Collectors.toList())) | ||
.setId(ByteString.copyFrom(ourId.getBytes())))) | ||
.build()) | ||
.thenApply(msg -> msg.getDialResponse()); | ||
} | ||
} | ||
|
||
public static class Sender implements ProtocolMessageHandler<Autonat.Message>, AutoNatController { | ||
private final Stream stream; | ||
private final LinkedBlockingDeque<CompletableFuture<Autonat.Message>> queue = | ||
new LinkedBlockingDeque<>(); | ||
|
||
public Sender(Stream stream) { | ||
this.stream = stream; | ||
} | ||
|
||
@Override | ||
public void onMessage(@NotNull Stream stream, Autonat.Message msg) { | ||
queue.poll().complete(msg); | ||
} | ||
|
||
public CompletableFuture<Autonat.Message> rpc(Autonat.Message req) { | ||
CompletableFuture<Autonat.Message> res = new CompletableFuture<>(); | ||
queue.add(res); | ||
stream.writeAndFlush(req); | ||
return res; | ||
} | ||
} | ||
|
||
private static boolean sameIP(Multiaddr a, Multiaddr b) { | ||
if (a.has(Protocol.IP4)) | ||
return a.getFirstComponent(Protocol.IP4).equals(b.getFirstComponent(Protocol.IP4)); | ||
if (a.has(Protocol.IP6)) | ||
return a.getFirstComponent(Protocol.IP6).equals(b.getFirstComponent(Protocol.IP6)); | ||
return false; | ||
} | ||
|
||
private static boolean reachableIP(Multiaddr a) { | ||
try { | ||
if (a.has(Protocol.IP4)) | ||
return InetAddress.getByName(a.getFirstComponent(Protocol.IP4).getStringValue()) | ||
.isReachable(1000); | ||
if (a.has(Protocol.IP6)) | ||
return InetAddress.getByName(a.getFirstComponent(Protocol.IP6).getStringValue()) | ||
.isReachable(1000); | ||
} catch (IOException e) { | ||
} | ||
return false; | ||
} | ||
|
||
public static class Receiver | ||
implements ProtocolMessageHandler<Autonat.Message>, AutoNatController { | ||
private final Stream p2pstream; | ||
|
||
public Receiver(Stream p2pstream) { | ||
this.p2pstream = p2pstream; | ||
} | ||
|
||
@Override | ||
public void onMessage(@NotNull Stream stream, Autonat.Message msg) { | ||
switch (msg.getType()) { | ||
case DIAL: | ||
{ | ||
Autonat.Message.Dial dial = msg.getDial(); | ||
PeerId peerId = new PeerId(dial.getPeer().getId().toByteArray()); | ||
List<Multiaddr> requestedDials = | ||
dial.getPeer().getAddrsList().stream() | ||
.map(s -> Multiaddr.deserialize(s.toByteArray())) | ||
.collect(Collectors.toList()); | ||
PeerId streamPeerId = stream.remotePeerId(); | ||
if (!peerId.equals(streamPeerId)) { | ||
p2pstream.close(); | ||
return; | ||
} | ||
|
||
Multiaddr remote = stream.getConnection().remoteAddress(); | ||
Optional<Multiaddr> reachable = | ||
requestedDials.stream() | ||
.filter(a -> sameIP(a, remote)) | ||
.filter(a -> !a.has(Protocol.P2PCIRCUIT)) | ||
.filter(a -> reachableIP(a)) | ||
.findAny(); | ||
Autonat.Message.Builder resp = | ||
Autonat.Message.newBuilder().setType(Autonat.Message.MessageType.DIAL_RESPONSE); | ||
if (reachable.isPresent()) { | ||
resp = | ||
resp.setDialResponse( | ||
Autonat.Message.DialResponse.newBuilder() | ||
.setStatus(Autonat.Message.ResponseStatus.OK) | ||
.setAddr(ByteString.copyFrom(reachable.get().serialize()))); | ||
} else { | ||
resp = | ||
resp.setDialResponse( | ||
Autonat.Message.DialResponse.newBuilder() | ||
.setStatus(Autonat.Message.ResponseStatus.E_DIAL_ERROR)); | ||
} | ||
p2pstream.writeAndFlush(resp); | ||
} | ||
default: | ||
{ | ||
} | ||
} | ||
} | ||
|
||
public CompletableFuture<Autonat.Message> rpc(Autonat.Message msg) { | ||
return CompletableFuture.failedFuture( | ||
new IllegalStateException("Cannot send form a receiver!")); | ||
} | ||
} | ||
|
||
private static final int TRAFFIC_LIMIT = 2 * 1024; | ||
|
||
public AutonatProtocol() { | ||
super(Autonat.Message.getDefaultInstance(), TRAFFIC_LIMIT, TRAFFIC_LIMIT); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
protected CompletableFuture<AutoNatController> onStartInitiator(@NotNull Stream stream) { | ||
Sender replyPropagator = new Sender(stream); | ||
stream.pushHandler(replyPropagator); | ||
return CompletableFuture.completedFuture(replyPropagator); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
protected CompletableFuture<AutoNatController> onStartResponder(@NotNull Stream stream) { | ||
Receiver dialer = new Receiver(stream); | ||
stream.pushHandler(dialer); | ||
return CompletableFuture.completedFuture(dialer); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.