github.com/ethersphere/bee/v2@v2.2.0/pkg/api/peer.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package api 6 7 import ( 8 "errors" 9 "net/http" 10 11 "github.com/ethersphere/bee/v2/pkg/jsonhttp" 12 "github.com/ethersphere/bee/v2/pkg/p2p" 13 "github.com/ethersphere/bee/v2/pkg/swarm" 14 "github.com/gorilla/mux" 15 "github.com/multiformats/go-multiaddr" 16 ) 17 18 type peerConnectResponse struct { 19 Address string `json:"address"` 20 } 21 22 func (s *Service) peerConnectHandler(w http.ResponseWriter, r *http.Request) { 23 logger := s.logger.WithValues("post_connect").Build() 24 25 mux.Vars(r)["multi-address"] = "/" + mux.Vars(r)["multi-address"] 26 paths := struct { 27 MultiAddress multiaddr.Multiaddr `map:"multi-address" validate:"required"` 28 }{} 29 if response := s.mapStructure(mux.Vars(r), &paths); response != nil { 30 response("invalid path params", logger, w) 31 return 32 } 33 34 bzzAddr, err := s.p2p.Connect(r.Context(), paths.MultiAddress) 35 if err != nil { 36 logger.Debug("p2p connect failed", "addresses", paths.MultiAddress, "error", err) 37 logger.Error(nil, "p2p connect failed", "addresses", paths.MultiAddress) 38 jsonhttp.InternalServerError(w, err) 39 return 40 } 41 42 if err := s.topologyDriver.Connected(r.Context(), p2p.Peer{Address: bzzAddr.Overlay}, true); err != nil { 43 _ = s.p2p.Disconnect(bzzAddr.Overlay, "failed to notify topology") 44 logger.Debug("connect to peer failed", "addresses", paths.MultiAddress, "error", err) 45 logger.Error(nil, "connect to peer failed", "addresses", paths.MultiAddress) 46 jsonhttp.InternalServerError(w, err) 47 return 48 } 49 50 jsonhttp.OK(w, peerConnectResponse{ 51 Address: bzzAddr.Overlay.String(), 52 }) 53 } 54 55 func (s *Service) peerDisconnectHandler(w http.ResponseWriter, r *http.Request) { 56 logger := s.logger.WithValues("delete_peer").Build() 57 58 paths := struct { 59 Address swarm.Address `map:"address" validate:"required"` 60 }{} 61 if response := s.mapStructure(mux.Vars(r), &paths); response != nil { 62 response("invalid path params", logger, w) 63 return 64 } 65 66 if err := s.p2p.Disconnect(paths.Address, "user requested disconnect"); err != nil { 67 logger.Debug("p2p disconnect failed", "peer_address", paths.Address, "error", err) 68 if errors.Is(err, p2p.ErrPeerNotFound) { 69 jsonhttp.NotFound(w, "peer not found") 70 return 71 } 72 logger.Error(nil, "p2p disconnect failed", "peer_address", paths.Address) 73 jsonhttp.InternalServerError(w, err) 74 return 75 } 76 77 jsonhttp.OK(w, nil) 78 } 79 80 // Peer holds information about a Peer. 81 type Peer struct { 82 Address swarm.Address `json:"address"` 83 FullNode bool `json:"fullNode"` 84 } 85 86 type BlockListedPeer struct { 87 Peer 88 Reason string `json:"reason"` 89 Duration int `json:"duration"` 90 } 91 92 type peersResponse struct { 93 Peers []Peer `json:"peers"` 94 } 95 96 type blockListedPeersResponse struct { 97 Peers []BlockListedPeer `json:"peers"` 98 } 99 100 func (s *Service) peersHandler(w http.ResponseWriter, _ *http.Request) { 101 jsonhttp.OK(w, peersResponse{ 102 Peers: mapPeers(s.p2p.Peers()), 103 }) 104 } 105 106 func (s *Service) blocklistedPeersHandler(w http.ResponseWriter, _ *http.Request) { 107 logger := s.logger.WithValues("get_blocklist").Build() 108 109 peers, err := s.p2p.BlocklistedPeers() 110 if err != nil { 111 logger.Debug("get blocklisted peers failed", "error", err) 112 jsonhttp.InternalServerError(w, "get blocklisted peers failed") 113 return 114 } 115 116 jsonhttp.OK(w, blockListedPeersResponse{ 117 Peers: mapBlockListedPeers(peers), 118 }) 119 } 120 121 func mapPeers(peers []p2p.Peer) (out []Peer) { 122 out = make([]Peer, 0, len(peers)) 123 for _, peer := range peers { 124 out = append(out, Peer{ 125 Address: peer.Address, 126 FullNode: peer.FullNode, 127 }) 128 } 129 return 130 } 131 132 func mapBlockListedPeers(peers []p2p.BlockListedPeer) []BlockListedPeer { 133 out := make([]BlockListedPeer, 0, len(peers)) 134 for _, peer := range peers { 135 out = append(out, BlockListedPeer{ 136 Peer: Peer{ 137 Address: peer.Address, 138 FullNode: peer.FullNode, 139 }, 140 Reason: peer.Reason, 141 Duration: int(peer.Duration.Seconds()), 142 }) 143 } 144 return out 145 }