|
@@ -26,18 +26,19 @@ import (
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
|
"github.com/mudler/edgevpn/pkg/blockchain"
|
|
|
protocol "github.com/mudler/edgevpn/pkg/protocol"
|
|
|
+ "github.com/pkg/errors"
|
|
|
|
|
|
"github.com/mudler/edgevpn/pkg/types"
|
|
|
)
|
|
|
|
|
|
-func ExposeService(ledger *blockchain.Ledger, node types.Node, l log.StandardLogger, announcetime time.Duration, serviceID, dstaddress string) {
|
|
|
+func ExposeService(ctx context.Context, ledger *blockchain.Ledger, node types.Node, l log.StandardLogger, announcetime time.Duration, serviceID, dstaddress string) {
|
|
|
|
|
|
l.Infof("Exposing service '%s' (%s)", serviceID, dstaddress)
|
|
|
|
|
|
// 1) Register the ServiceID <-> PeerID Association
|
|
|
// By announcing periodically our service to the blockchain
|
|
|
ledger.Announce(
|
|
|
- context.Background(),
|
|
|
+ ctx,
|
|
|
announcetime,
|
|
|
func() {
|
|
|
// Retrieve current ID for ip in the blockchain
|
|
@@ -88,7 +89,7 @@ func ExposeService(ledger *blockchain.Ledger, node types.Node, l log.StandardLog
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func ConnectToService(ledger *blockchain.Ledger, node types.Node, ll log.StandardLogger, announcetime time.Duration, serviceID string, srcaddr string) error {
|
|
|
+func ConnectToService(ctx context.Context, ledger *blockchain.Ledger, node types.Node, ll log.StandardLogger, announcetime time.Duration, serviceID string, srcaddr string) error {
|
|
|
|
|
|
// Open local port for listening
|
|
|
l, err := net.Listen("tcp", srcaddr)
|
|
@@ -99,7 +100,7 @@ func ConnectToService(ledger *blockchain.Ledger, node types.Node, ll log.Standar
|
|
|
|
|
|
// Announce ourselves so nodes accepts our connection
|
|
|
ledger.Announce(
|
|
|
- context.Background(),
|
|
|
+ ctx,
|
|
|
announcetime,
|
|
|
func() {
|
|
|
// Retrieve current ID for ip in the blockchain
|
|
@@ -117,53 +118,58 @@ func ConnectToService(ledger *blockchain.Ledger, node types.Node, ll log.Standar
|
|
|
)
|
|
|
defer l.Close()
|
|
|
for {
|
|
|
- // Listen for an incoming connection.
|
|
|
- conn, err := l.Accept()
|
|
|
- if err != nil {
|
|
|
- ll.Error("Error accepting: ", err.Error())
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- ll.Info("New connection from", l.Addr().String())
|
|
|
- // Handle connections in a new goroutine, forwarding to the p2p service
|
|
|
- go func() {
|
|
|
- // Retrieve current ID for ip in the blockchain
|
|
|
- existingValue, found := ledger.GetKey(protocol.ServicesLedgerKey, serviceID)
|
|
|
- service := &types.Service{}
|
|
|
- existingValue.Unmarshal(service)
|
|
|
- // If mismatch, update the blockchain
|
|
|
- if !found {
|
|
|
- conn.Close()
|
|
|
- ll.Debugf("service '%s' not found on blockchain", serviceID)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // Decode the Peer
|
|
|
- d, err := peer.Decode(service.PeerID)
|
|
|
+ select {
|
|
|
+ case <-ctx.Done():
|
|
|
+ return errors.New("context canceled")
|
|
|
+ default:
|
|
|
+ // Listen for an incoming connection.
|
|
|
+ conn, err := l.Accept()
|
|
|
if err != nil {
|
|
|
- conn.Close()
|
|
|
- ll.Debugf("could not decode peer '%s'", service.PeerID)
|
|
|
- return
|
|
|
+ ll.Error("Error accepting: ", err.Error())
|
|
|
+ continue
|
|
|
}
|
|
|
|
|
|
- // Open a stream
|
|
|
- stream, err := node.Host().NewStream(context.Background(), d, protocol.ServiceProtocol.ID())
|
|
|
- if err != nil {
|
|
|
- conn.Close()
|
|
|
- ll.Debugf("could not open stream '%s'", err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
- ll.Debugf("(service %s) Redirecting", serviceID, l.Addr().String())
|
|
|
+ ll.Info("New connection from", l.Addr().String())
|
|
|
+ // Handle connections in a new goroutine, forwarding to the p2p service
|
|
|
+ go func() {
|
|
|
+ // Retrieve current ID for ip in the blockchain
|
|
|
+ existingValue, found := ledger.GetKey(protocol.ServicesLedgerKey, serviceID)
|
|
|
+ service := &types.Service{}
|
|
|
+ existingValue.Unmarshal(service)
|
|
|
+ // If mismatch, update the blockchain
|
|
|
+ if !found {
|
|
|
+ conn.Close()
|
|
|
+ ll.Debugf("service '%s' not found on blockchain", serviceID)
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- closer := make(chan struct{}, 2)
|
|
|
- go copyStream(closer, stream, conn)
|
|
|
- go copyStream(closer, conn, stream)
|
|
|
- <-closer
|
|
|
+ // Decode the Peer
|
|
|
+ d, err := peer.Decode(service.PeerID)
|
|
|
+ if err != nil {
|
|
|
+ conn.Close()
|
|
|
+ ll.Debugf("could not decode peer '%s'", service.PeerID)
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- stream.Close()
|
|
|
- conn.Close()
|
|
|
- ll.Infof("(service %s) Done handling %s", serviceID, l.Addr().String())
|
|
|
- }()
|
|
|
+ // Open a stream
|
|
|
+ stream, err := node.Host().NewStream(context.Background(), d, protocol.ServiceProtocol.ID())
|
|
|
+ if err != nil {
|
|
|
+ conn.Close()
|
|
|
+ ll.Debugf("could not open stream '%s'", err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ ll.Debugf("(service %s) Redirecting", serviceID, l.Addr().String())
|
|
|
+
|
|
|
+ closer := make(chan struct{}, 2)
|
|
|
+ go copyStream(closer, stream, conn)
|
|
|
+ go copyStream(closer, conn, stream)
|
|
|
+ <-closer
|
|
|
+
|
|
|
+ stream.Close()
|
|
|
+ conn.Close()
|
|
|
+ ll.Infof("(service %s) Done handling %s", serviceID, l.Addr().String())
|
|
|
+ }()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|