github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/routing/dht/pb/message.go (about)

     1  package dht_pb
     2  
     3  import (
     4  	ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
     5  
     6  	key "github.com/ipfs/go-ipfs/blocks/key"
     7  	inet "github.com/ipfs/go-ipfs/p2p/net"
     8  	peer "github.com/ipfs/go-ipfs/p2p/peer"
     9  	eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog"
    10  )
    11  
    12  var log = eventlog.Logger("dht.pb")
    13  
    14  type PeerRoutingInfo struct {
    15  	peer.PeerInfo
    16  	inet.Connectedness
    17  }
    18  
    19  // NewMessage constructs a new dht message with given type, key, and level
    20  func NewMessage(typ Message_MessageType, key string, level int) *Message {
    21  	m := &Message{
    22  		Type: &typ,
    23  		Key:  &key,
    24  	}
    25  	m.SetClusterLevel(level)
    26  	return m
    27  }
    28  
    29  func peerRoutingInfoToPBPeer(p PeerRoutingInfo) *Message_Peer {
    30  	pbp := new(Message_Peer)
    31  
    32  	pbp.Addrs = make([][]byte, len(p.Addrs))
    33  	for i, maddr := range p.Addrs {
    34  		pbp.Addrs[i] = maddr.Bytes() // Bytes, not String. Compressed.
    35  	}
    36  	s := string(p.ID)
    37  	pbp.Id = &s
    38  	c := ConnectionType(p.Connectedness)
    39  	pbp.Connection = &c
    40  	return pbp
    41  }
    42  
    43  func peerInfoToPBPeer(p peer.PeerInfo) *Message_Peer {
    44  	pbp := new(Message_Peer)
    45  
    46  	pbp.Addrs = make([][]byte, len(p.Addrs))
    47  	for i, maddr := range p.Addrs {
    48  		pbp.Addrs[i] = maddr.Bytes() // Bytes, not String. Compressed.
    49  	}
    50  	s := string(p.ID)
    51  	pbp.Id = &s
    52  	return pbp
    53  }
    54  
    55  // PBPeerToPeer turns a *Message_Peer into its peer.PeerInfo counterpart
    56  func PBPeerToPeerInfo(pbp *Message_Peer) peer.PeerInfo {
    57  	return peer.PeerInfo{
    58  		ID:    peer.ID(pbp.GetId()),
    59  		Addrs: pbp.Addresses(),
    60  	}
    61  }
    62  
    63  // RawPeerInfosToPBPeers converts a slice of Peers into a slice of *Message_Peers,
    64  // ready to go out on the wire.
    65  func RawPeerInfosToPBPeers(peers []peer.PeerInfo) []*Message_Peer {
    66  	pbpeers := make([]*Message_Peer, len(peers))
    67  	for i, p := range peers {
    68  		pbpeers[i] = peerInfoToPBPeer(p)
    69  	}
    70  	return pbpeers
    71  }
    72  
    73  // PeersToPBPeers converts given []peer.Peer into a set of []*Message_Peer,
    74  // which can be written to a message and sent out. the key thing this function
    75  // does (in addition to PeersToPBPeers) is set the ConnectionType with
    76  // information from the given inet.Network.
    77  func PeerInfosToPBPeers(n inet.Network, peers []peer.PeerInfo) []*Message_Peer {
    78  	pbps := RawPeerInfosToPBPeers(peers)
    79  	for i, pbp := range pbps {
    80  		c := ConnectionType(n.Connectedness(peers[i].ID))
    81  		pbp.Connection = &c
    82  	}
    83  	return pbps
    84  }
    85  
    86  func PeerRoutingInfosToPBPeers(peers []PeerRoutingInfo) []*Message_Peer {
    87  	pbpeers := make([]*Message_Peer, len(peers))
    88  	for i, p := range peers {
    89  		pbpeers[i] = peerRoutingInfoToPBPeer(p)
    90  	}
    91  	return pbpeers
    92  }
    93  
    94  // PBPeersToPeerInfos converts given []*Message_Peer into []peer.PeerInfo
    95  // Invalid addresses will be silently omitted.
    96  func PBPeersToPeerInfos(pbps []*Message_Peer) []peer.PeerInfo {
    97  	peers := make([]peer.PeerInfo, 0, len(pbps))
    98  	for _, pbp := range pbps {
    99  		peers = append(peers, PBPeerToPeerInfo(pbp))
   100  	}
   101  	return peers
   102  }
   103  
   104  // Addresses returns a multiaddr associated with the Message_Peer entry
   105  func (m *Message_Peer) Addresses() []ma.Multiaddr {
   106  	if m == nil {
   107  		return nil
   108  	}
   109  
   110  	var err error
   111  	maddrs := make([]ma.Multiaddr, len(m.Addrs))
   112  	for i, addr := range m.Addrs {
   113  		maddrs[i], err = ma.NewMultiaddrBytes(addr)
   114  		if err != nil {
   115  			log.Debugf("error decoding Multiaddr for peer: %s", m.GetId())
   116  			continue
   117  		}
   118  	}
   119  	return maddrs
   120  }
   121  
   122  // GetClusterLevel gets and adjusts the cluster level on the message.
   123  // a +/- 1 adjustment is needed to distinguish a valid first level (1) and
   124  // default "no value" protobuf behavior (0)
   125  func (m *Message) GetClusterLevel() int {
   126  	level := m.GetClusterLevelRaw() - 1
   127  	if level < 0 {
   128  		return 0
   129  	}
   130  	return int(level)
   131  }
   132  
   133  // SetClusterLevel adjusts and sets the cluster level on the message.
   134  // a +/- 1 adjustment is needed to distinguish a valid first level (1) and
   135  // default "no value" protobuf behavior (0)
   136  func (m *Message) SetClusterLevel(level int) {
   137  	lvl := int32(level)
   138  	m.ClusterLevelRaw = &lvl
   139  }
   140  
   141  // Loggable turns a Message into machine-readable log output
   142  func (m *Message) Loggable() map[string]interface{} {
   143  	return map[string]interface{}{
   144  		"message": map[string]string{
   145  			"type": m.Type.String(),
   146  			"key":  key.Key(m.GetKey()).Pretty(),
   147  		},
   148  	}
   149  }
   150  
   151  // ConnectionType returns a Message_ConnectionType associated with the
   152  // inet.Connectedness.
   153  func ConnectionType(c inet.Connectedness) Message_ConnectionType {
   154  	switch c {
   155  	default:
   156  		return Message_NOT_CONNECTED
   157  	case inet.NotConnected:
   158  		return Message_NOT_CONNECTED
   159  	case inet.Connected:
   160  		return Message_CONNECTED
   161  	case inet.CanConnect:
   162  		return Message_CAN_CONNECT
   163  	case inet.CannotConnect:
   164  		return Message_CANNOT_CONNECT
   165  	}
   166  }
   167  
   168  // Connectedness returns an inet.Connectedness associated with the
   169  // Message_ConnectionType.
   170  func Connectedness(c Message_ConnectionType) inet.Connectedness {
   171  	switch c {
   172  	default:
   173  		return inet.NotConnected
   174  	case Message_NOT_CONNECTED:
   175  		return inet.NotConnected
   176  	case Message_CONNECTED:
   177  		return inet.Connected
   178  	case Message_CAN_CONNECT:
   179  		return inet.CanConnect
   180  	case Message_CANNOT_CONNECT:
   181  		return inet.CannotConnect
   182  	}
   183  }