Browse Source

Code clean-up and comments added.

master
Bernd Fix 2 years ago
parent
commit
b2d49bfb99
28 changed files with 342 additions and 194 deletions
  1. +10
    -3
      src/gnunet/config/config.go
  2. +21
    -15
      src/gnunet/core/peer.go
  3. +3
    -0
      src/gnunet/crypto/hash.go
  4. +1
    -0
      src/gnunet/crypto/key_derivation.go
  5. +2
    -2
      src/gnunet/crypto/key_exchange.go
  6. +1
    -0
      src/gnunet/crypto/signature.go
  7. +15
    -4
      src/gnunet/crypto/symmetric.go
  8. +0
    -22
      src/gnunet/enums/block.go
  9. +23
    -0
      src/gnunet/enums/dht.go
  10. +1
    -0
      src/gnunet/enums/gns.go
  11. +8
    -0
      src/gnunet/message/message.go
  12. +23
    -10
      src/gnunet/message/msg_core.go
  13. +2
    -0
      src/gnunet/message/msg_dht.go
  14. +10
    -6
      src/gnunet/message/msg_gns.go
  15. +2
    -2
      src/gnunet/message/msg_namecache.go
  16. +125
    -82
      src/gnunet/message/msg_transport.go
  17. +2
    -1
      src/gnunet/service/client.go
  18. +2
    -1
      src/gnunet/service/service.go
  19. +1
    -0
      src/gnunet/transport/channel.go
  20. +28
    -11
      src/gnunet/transport/channel_netw.go
  21. +8
    -1
      src/gnunet/transport/connection.go
  22. +1
    -2
      src/gnunet/transport/session.go
  23. +38
    -17
      src/gnunet/util/address.go
  24. +2
    -11
      src/gnunet/util/format.go
  25. +2
    -1
      src/gnunet/util/id.go
  26. +0
    -3
      src/gnunet/util/msg_queue.go
  27. +3
    -0
      src/gnunet/util/peer_id.go
  28. +8
    -0
      src/gnunet/util/rnd.go

+ 10
- 3
src/gnunet/config/config.go View File

@ -7,9 +7,10 @@ import (
"regexp"
"strings"
"gnunet/util"
"github.com/bfix/gospel/crypto/ed25519"
"github.com/bfix/gospel/logger"
"gnunet/util"
)
///////////////////////////////////////////////////////////////////////
@ -64,6 +65,7 @@ type Config struct {
}
var (
// Cfg is the global configuration
Cfg *Config
)
@ -88,6 +90,8 @@ var (
rx = regexp.MustCompile("\\$\\{([^\\}]*)\\}")
)
// substString is a helper function to substitute environment variables
// with actual values.
func substString(s string, env map[string]string) string {
matches := rx.FindAllStringSubmatch(s, -1)
for _, m := range matches {
@ -102,7 +106,8 @@ func substString(s string, env map[string]string) string {
return s
}
// applySubstitutions
// applySubstitutions traverses the configuration data structure
// and applies string substitutions to all string values.
func applySubstitutions(x interface{}, env map[string]string) {
var process func(v reflect.Value)
@ -140,10 +145,11 @@ func applySubstitutions(x interface{}, env map[string]string) {
}
}
}
// start processing at the top-level structure
v := reflect.ValueOf(x)
switch v.Kind() {
case reflect.Ptr:
// indirect top-level
e := v.Elem()
if e.IsValid() {
process(e)
@ -151,6 +157,7 @@ func applySubstitutions(x interface{}, env map[string]string) {
logger.Printf(logger.ERROR, "[config] 'nil' pointer encountered")
}
case reflect.Struct:
// direct top-level
process(v)
}
}

+ 21
- 15
src/gnunet/core/peer.go View File

@ -3,30 +3,25 @@ package core
import (
"fmt"
"github.com/bfix/gospel/crypto/ed25519"
"gnunet/message"
"gnunet/util"
)
/*
type Peer interface {
GetID() []byte
GetIDString() string
GetAddressList() []*util.Address
Sign(msg []byte) ([]byte, error)
Verify(msg, sig []byte) bool
}
*/
"github.com/bfix/gospel/crypto/ed25519"
)
// Peer represents a node in the GNUnet P2P network.
type Peer struct {
pub *ed25519.PublicKey
idString string
addrList []*util.Address
prv *ed25519.PrivateKey // long-term signing key
prv *ed25519.PrivateKey // node private key (long-term signing key)
pub *ed25519.PublicKey // node public key (=identifier)
idString string // node identifier as string
addrList []*util.Address // list of addresses associated with node
ephPrv *ed25519.PrivateKey // ephemeral signing key
ephMsg *message.EphemeralKeyMsg // ephemeral signing key message
}
// NewPeer instantiates a new peer object from given data. If a local peer
// is created, the data is the seed for generating the private key of the node;
// for a remote peer the data is the binary representation of its public key.
func NewPeer(data []byte, local bool) (p *Peer, err error) {
p = new(Peer)
if local {
@ -45,42 +40,52 @@ func NewPeer(data []byte, local bool) (p *Peer, err error) {
return
}
// EphKeyMsg returns a new initialized message to negotiate session keys.
func (p *Peer) EphKeyMsg() *message.EphemeralKeyMsg {
return p.ephMsg
}
// SetEphKeyMsg saves a template for new key negotiation messages.
func (p *Peer) SetEphKeyMsg(msg *message.EphemeralKeyMsg) {
p.ephMsg = msg
}
// EphPrvKey returns the current ephemeral private key.
func (p *Peer) EphPrvKey() *ed25519.PrivateKey {
return p.ephPrv
}
// PrvKey return the private key of the node.
func (p *Peer) PrvKey() *ed25519.PrivateKey {
return p.prv
}
// PubKey return the public key of the node.
func (p *Peer) PubKey() *ed25519.PublicKey {
return p.pub
}
// GetID returns the node ID (public key) in binary format
func (p *Peer) GetID() []byte {
return p.pub.Bytes()
}
// GetIDString returns the string representation of the public key of the node.
func (p *Peer) GetIDString() string {
return p.idString
}
// GetAddressList returns a list of addresses associated with this peer.
func (p *Peer) GetAddressList() []*util.Address {
return p.addrList
}
// AddAddress adds a new address for a node.
func (p *Peer) AddAddress(a *util.Address) {
p.addrList = append(p.addrList, a)
}
// Sign a message with the (long-term) private key.
func (p *Peer) Sign(msg []byte) (*ed25519.EdSignature, error) {
if p.prv == nil {
return nil, fmt.Errorf("No private key")
@ -88,6 +93,7 @@ func (p *Peer) Sign(msg []byte) (*ed25519.EdSignature, error) {
return p.prv.EdSign(msg)
}
// Verify a message signature with the public key of a peer.
func (p *Peer) Verify(msg []byte, sig *ed25519.EdSignature) (bool, error) {
return p.pub.EdVerify(msg, sig)
}

+ 3
- 0
src/gnunet/crypto/hash.go View File

@ -6,16 +6,19 @@ import (
"gnunet/util"
)
// HashCode is the result of a 512-bit hash function (SHA-512)
type HashCode struct {
Bits []byte `size:"64"`
}
// NewHashCode creates a new, uninitalized hash value
func NewHashCode() *HashCode {
return &HashCode{
Bits: make([]byte, 64),
}
}
// Hash returns the SHA-512 hash value of a given blob
func Hash(data []byte) *HashCode {
val := sha512.Sum512(data)
return &HashCode{


+ 1
- 0
src/gnunet/crypto/key_derivation.go View File

@ -9,6 +9,7 @@ import (
"golang.org/x/crypto/hkdf"
)
// Curve parameters
var (
ED25519_N = ed25519.GetCurve().N
)


+ 2
- 2
src/gnunet/crypto/key_exchange.go View File

@ -4,8 +4,8 @@ import (
"github.com/bfix/gospel/crypto/ed25519"
)
// SharedSecret computes a 64 byte shared secret
// between (prvA,pubB) and (prvB,pubA).
// SharedSecret computes a 64 byte shared secret between (prvA,pubB)
// and (prvB,pubA) by a Diffie-Hellman-like scheme.
func SharedSecret(prv *ed25519.PrivateKey, pub *ed25519.PublicKey) *HashCode {
ss := pub.Mult(prv.D).Q.X().Bytes()
return Hash(ss)


+ 1
- 0
src/gnunet/crypto/signature.go View File

@ -1,5 +1,6 @@
package crypto
// SignaturePurpose is the GNUnet data structure used as header for signed data.
type SignaturePurpose struct {
Size uint32 `order:"big"` // How many bytes are signed?
Purpose uint32 `order:"big"` // Signature purpose


+ 15
- 4
src/gnunet/crypto/symmetric.go View File

@ -8,11 +8,17 @@ import (
"golang.org/x/crypto/twofish"
)
// Symmetric encryption in GNUnet uses a two-layer scheme:
// * Encryption: OUT = twofish_cfb(aes_cfb(IN))
// * Decryption: OUT = aes_cfb(twofish_cfb(IN))
// SymmetricKey is a key for the GNUnet-specific two-layer encryption scheme.
type SymmetricKey struct {
AESKey []byte `size:"32"`
TwofishKey []byte `size:"32"`
AESKey []byte `size:"32"` // key for AES-CFB
TwofishKey []byte `size:"32"` // key for Twofish-CFB
}
// NewSymmetricKey generates a new (random) symmetric key.
func NewSymmetricKey() *SymmetricKey {
skey := &SymmetricKey{
AESKey: make([]byte, 32),
@ -23,11 +29,14 @@ func NewSymmetricKey() *SymmetricKey {
return skey
}
// SymmetricIV is an initialization vector for the GNUnet-specific two-layer
// encryption scheme.
type SymmetricIV struct {
AESIv []byte `size:"16"`
TwofishIv []byte `size:"16"`
AESIv []byte `size:"16"` // IV for AES-CFB
TwofishIv []byte `size:"16"` // IV for Twofish-CFB
}
// NewSymmetricIV generates a new (random) initialization vector.
func NewSymmetricIV() *SymmetricIV {
iv := &SymmetricIV{
AESIv: make([]byte, 16),
@ -38,6 +47,7 @@ func NewSymmetricIV() *SymmetricIV {
return iv
}
// SymmetricDecrypt decrypts the data with given key and initialization vector.
func SymmetricDecrypt(data []byte, skey *SymmetricKey, iv *SymmetricIV) ([]byte, error) {
// Decrypt with Twofish CFB stream cipher
tf, err := twofish.NewCipher(skey.TwofishKey)
@ -58,6 +68,7 @@ func SymmetricDecrypt(data []byte, skey *SymmetricKey, iv *SymmetricIV) ([]byte,
return out, nil
}
// SymmetricEncrypt encrypts the data with given key and initialization vector.
func SymmetricEncrypt(data []byte, skey *SymmetricKey, iv *SymmetricIV) ([]byte, error) {
// Encrypt with AES CFB stream cipher
aes, err := aes.NewCipher(skey.AESKey)


+ 0
- 22
src/gnunet/enums/block.go View File

@ -1,22 +0,0 @@
package enums
var (
BLOCK_TYPE_ANY = 0 // Any type of block, used as a wildcard when searching.
BLOCK_TYPE_FS_DBLOCK = 1 // Data block (leaf) in the CHK tree.
BLOCK_TYPE_FS_IBLOCK = 2 // Inner block in the CHK tree.
BLOCK_TYPE_FS_KBLOCK = 3 // Legacy type, no longer in use.
BLOCK_TYPE_FS_SBLOCK = 4 // Legacy type, no longer in use.
BLOCK_TYPE_FS_NBLOCK = 5 // Legacy type, no longer in use.
BLOCK_TYPE_FS_ONDEMAND = 6 // Type of a block representing a block to be encoded on demand from disk.
BLOCK_TYPE_DHT_HELLO = 7 // Type of a block that contains a HELLO for a peer
BLOCK_TYPE_TEST = 8 // Block for testing.
BLOCK_TYPE_FS_UBLOCK = 9 // Type of a block representing any type of search result (universal).
BLOCK_TYPE_DNS = 10 // Block for storing DNS exit service advertisements.
BLOCK_TYPE_GNS_NAMERECORD = 11 // Block for storing record data
BLOCK_TYPE_REVOCATION = 12 // Block type for a revocation message by which a key is revoked.
BLOCK_TYPE_REGEX = 22 // Block to store a cadet regex state
BLOCK_TYPE_REGEX_ACCEPT = 23 // Block to store a cadet regex accepting state
BLOCK_TYPE_SET_TEST = 24 // Block for testing set/consensus.
BLOCK_TYPE_CONSENSUS_ELEMENT = 25 // Block type for consensus elements.
)

+ 23
- 0
src/gnunet/enums/dht.go View File

@ -1,5 +1,6 @@
package enums
// DHT flags and settings
var (
DHT_RO_NONE = 0 // Default. Do nothing special.
DHT_RO_DEMULTIPLEX_EVERYWHERE = 1 // Each peer along the way should look at 'enc'
@ -10,3 +11,25 @@ var (
DHT_GNS_REPLICATION_LEVEL = 10
)
// DHT block types
var (
BLOCK_TYPE_ANY = 0 // Any type of block, used as a wildcard when searching.
BLOCK_TYPE_FS_DBLOCK = 1 // Data block (leaf) in the CHK tree.
BLOCK_TYPE_FS_IBLOCK = 2 // Inner block in the CHK tree.
BLOCK_TYPE_FS_KBLOCK = 3 // Legacy type, no longer in use.
BLOCK_TYPE_FS_SBLOCK = 4 // Legacy type, no longer in use.
BLOCK_TYPE_FS_NBLOCK = 5 // Legacy type, no longer in use.
BLOCK_TYPE_FS_ONDEMAND = 6 // Type of a block representing a block to be encoded on demand from disk.
BLOCK_TYPE_DHT_HELLO = 7 // Type of a block that contains a HELLO for a peer
BLOCK_TYPE_TEST = 8 // Block for testing.
BLOCK_TYPE_FS_UBLOCK = 9 // Type of a block representing any type of search result (universal).
BLOCK_TYPE_DNS = 10 // Block for storing DNS exit service advertisements.
BLOCK_TYPE_GNS_NAMERECORD = 11 // Block for storing record data
BLOCK_TYPE_REVOCATION = 12 // Block type for a revocation message by which a key is revoked.
BLOCK_TYPE_REGEX = 22 // Block to store a cadet regex state
BLOCK_TYPE_REGEX_ACCEPT = 23 // Block to store a cadet regex accepting state
BLOCK_TYPE_SET_TEST = 24 // Block for testing set/consensus.
BLOCK_TYPE_CONSENSUS_ELEMENT = 25 // Block type for consensus elements.
)

+ 1
- 0
src/gnunet/enums/gns.go View File

@ -1,5 +1,6 @@
package enums
// GNS constants
var (
GNS_MAX_BLOCK_SIZE = (63 * 1024) // Maximum size of a value that can be stored in a GNS block.


+ 8
- 0
src/gnunet/message/message.go View File

@ -6,27 +6,35 @@ import (
"github.com/bfix/gospel/data"
)
// Error codes
var (
ErrMsgHeaderTooSmall = errors.New("Message header too small")
)
// Message is an interface for all GNUnet-specific messages.
type Message interface {
Header() *MessageHeader
}
// MessageHeader encapsulates the common part of all GNUnet messages (at the
// beginning of the data).
type MessageHeader struct {
MsgSize uint16 `order:"big"`
MsgType uint16 `order:"big"`
}
// Size returns the total size of the message (header + body)
func (mh *MessageHeader) Size() uint16 {
return mh.MsgSize
}
// Type returns the message type (defines the layout of the body data)
func (mh *MessageHeader) Type() uint16 {
return mh.MsgType
}
// GetMsgHeader returns the header of a message from a byte array (as the
// serialized form).
func GetMsgHeader(b []byte) (mh *MessageHeader, err error) {
if b == nil || len(b) < 4 {
return nil, ErrMsgHeaderTooSmall


+ 23
- 10
src/gnunet/message/msg_core.go View File

@ -5,21 +5,25 @@ import (
"fmt"
"time"
"github.com/bfix/gospel/crypto/ed25519"
"github.com/bfix/gospel/data"
"gnunet/crypto"
"gnunet/enums"
"gnunet/util"
"github.com/bfix/gospel/crypto/ed25519"
"github.com/bfix/gospel/data"
)
// EphKeyBlock defines the layout of signed ephemeral key with attributes.
type EphKeyBlock struct {
SignSize uint32 `order:"big"` // length of signed block
SigPurpose uint32 `order:"big"` // signature purpose: SIG_ECC_KEY
CreateTime util.AbsoluteTime // Time of key creation
ExpireTime util.RelativeTime // Time to live for key
EphemeralKey []byte `size:"32"` // Ephemeral EdDSA public key
PeerID *util.PeerID // Peer identity (EdDSA public key)
Purpose *crypto.SignaturePurpose // signature purpose: SIG_ECC_KEY
CreateTime util.AbsoluteTime // Time of key creation
ExpireTime util.RelativeTime // Time to live for key
EphemeralKey []byte `size:"32"` // Ephemeral EdDSA public key
PeerID *util.PeerID // Peer identity (EdDSA public key)
}
// EphemeralKeyMsg announces a new transient key for a peer. The key is signed
// by the issuing peer.
type EphemeralKeyMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // CORE_EPHEMERAL_KEY (88)
@ -28,6 +32,7 @@ type EphemeralKeyMsg struct {
SignedBlock *EphKeyBlock
}
// NewEphemeralKeyMsg creates an empty message for key announcement.
func NewEphemeralKeyMsg() *EphemeralKeyMsg {
return &EphemeralKeyMsg{
MsgSize: 160,
@ -35,8 +40,10 @@ func NewEphemeralKeyMsg() *EphemeralKeyMsg {
SenderStatus: 1,
Signature: make([]byte, 64),
SignedBlock: &EphKeyBlock{
SignSize: 88,
SigPurpose: enums.SIG_ECC_KEY,
Purpose: &crypto.SignaturePurpose{
Size: 88,
Purpose: enums.SIG_ECC_KEY,
},
CreateTime: util.AbsoluteTimeNow(),
ExpireTime: util.NewRelativeTime(12 * time.Hour),
EphemeralKey: make([]byte, 32),
@ -45,6 +52,7 @@ func NewEphemeralKeyMsg() *EphemeralKeyMsg {
}
}
// String returns a human-readable representation of the message.
func (m *EphemeralKeyMsg) String() string {
return fmt.Sprintf("EphKeyMsg{peer=%s,ephkey=%s,create=%s,expire=%s,status=%d}",
util.EncodeBinaryToString(m.SignedBlock.PeerID.Key),
@ -58,10 +66,13 @@ func (msg *EphemeralKeyMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}
// Public extracts the public key of an announcing peer.
func (m *EphemeralKeyMsg) Public() *ed25519.PublicKey {
return ed25519.NewPublicKeyFromBytes(m.SignedBlock.PeerID.Key)
}
// Verify the integrity of the message data using the public key of the
// announcing peer.
func (m *EphemeralKeyMsg) Verify(pub *ed25519.PublicKey) (bool, error) {
data, err := data.Marshal(m.SignedBlock)
if err != nil {
@ -74,6 +85,8 @@ func (m *EphemeralKeyMsg) Verify(pub *ed25519.PublicKey) (bool, error) {
return pub.EdVerify(data, sig)
}
// NewEphemeralKey creates a new ephemeral key signed by a long-term private
// key and the corresponding GNUnet message to announce the new key.
func NewEphemeralKey(peerId []byte, ltPrv *ed25519.PrivateKey) (*ed25519.PrivateKey, *EphemeralKeyMsg, error) {
msg := NewEphemeralKeyMsg()
copy(msg.SignedBlock.PeerID.Key, peerId)


+ 2
- 0
src/gnunet/message/msg_dht.go View File

@ -51,6 +51,7 @@ func (m *DHTClientGetMsg) SetXQuery(xq []byte) []byte {
return prev
}
// String returns a human-readable representation of the message.
func (m *DHTClientGetMsg) String() string {
return fmt.Sprintf("DHTClientGetMsg{Id:%d,Type=%d,Options=%d,Repl=%d,Key=%s}",
m.Id, m.Type, m.Options, m.ReplLevel, hex.EncodeToString(m.Key.Bits))
@ -98,6 +99,7 @@ func NewDHTClientResultMsg(key *crypto.HashCode) *DHTClientResultMsg {
}
}
// String returns a human-readable representation of the message.
func (m *DHTClientResultMsg) String() string {
return fmt.Sprintf("DHTClientResultMsg{id:%d,expire=%s}", m.Id, m.Expire)
}


+ 10
- 6
src/gnunet/message/msg_gns.go View File

@ -3,9 +3,10 @@ package message
import (
"fmt"
"github.com/bfix/gospel/logger"
"gnunet/enums"
"gnunet/util"
"github.com/bfix/gospel/logger"
)
//----------------------------------------------------------------------
@ -38,13 +39,13 @@ func NewGNSLookupMsg() *GNSLookupMsg {
}
}
// SetName
// SetName appends the name to lookup to the message
func (m *GNSLookupMsg) SetName(name string) {
m.Name = util.Clone(append([]byte(name), 0))
m.MsgSize = uint16(48 + len(m.Name))
}
// GetName
// GetName returns the name to lookup from the message
func (m *GNSLookupMsg) GetName() string {
size := len(m.Name)
if m.Name[size-1] != 0 {
@ -55,7 +56,7 @@ func (m *GNSLookupMsg) GetName() string {
return string(m.Name[:size])
}
// String
// String returns a human-readable representation of the message.
func (m *GNSLookupMsg) String() string {
return fmt.Sprintf(
"GNSLookupMsg{Id=%d,Zone=%s,Options=%d,Type=%d,Name=%s}",
@ -72,6 +73,8 @@ func (msg *GNSLookupMsg) Header() *MessageHeader {
// GNS_LOOKUP_RESULT
//----------------------------------------------------------------------
// GNSResourceRecord is the GNUnet-specific representation of resource
// records (not to be confused with DNS resource records).
type GNSResourceRecord struct {
Expires util.AbsoluteTime // Expiration time for the record
Size uint32 `order:"big"` // Number of bytes in 'Data'
@ -80,6 +83,7 @@ type GNSResourceRecord struct {
Data []byte `size:"Size"` // Record data
}
// String returns a human-readable representation of the message.
func (r *GNSResourceRecord) String() string {
return fmt.Sprintf("GNSResourceRecord{type=%s,expire=%s,flags=%d,size=%d}",
enums.GNS_TYPE[int(r.Type)], r.Expires, r.Flags, r.Size)
@ -105,7 +109,7 @@ func NewGNSLookupResultMsg(id uint32) *GNSLookupResultMsg {
}
}
// AddRecord
// AddRecord adds a GNS resource recordto the response message.
func (m *GNSLookupResultMsg) AddRecord(rec *GNSResourceRecord) error {
recSize := 20 + int(rec.Size)
if int(m.MsgSize)+recSize > enums.GNS_MAX_BLOCK_SIZE {
@ -117,7 +121,7 @@ func (m *GNSLookupResultMsg) AddRecord(rec *GNSResourceRecord) error {
return nil
}
// String
// String returns a human-readable representation of the message.
func (m *GNSLookupResultMsg) String() string {
return fmt.Sprintf("GNSLookupResultMsg{Id=%d,Count=%d}", m.Id, m.Count)
}


+ 2
- 2
src/gnunet/message/msg_namecache.go View File

@ -33,7 +33,7 @@ func NewNamecacheLookupMsg(query *crypto.HashCode) *NamecacheLookupMsg {
}
}
// String
// String returns a human-readable representation of the message.
func (m *NamecacheLookupMsg) String() string {
return fmt.Sprintf("NamecacheLookupMsg{Id=%d,Query=%s}",
m.Id, hex.EncodeToString(m.Query.Bits))
@ -72,7 +72,7 @@ func NewNamecacheLookupResultMsg() *NamecacheLookupResultMsg {
}
}
// String
// String returns a human-readable representation of the message.
func (m *NamecacheLookupResultMsg) String() string {
return fmt.Sprintf("NamecacheLookupResultMsg{id=%d,expire=%s}",
m.Id, m.Expire)


+ 125
- 82
src/gnunet/message/msg_transport.go View File

@ -4,22 +4,26 @@ import (
"fmt"
"time"
"github.com/bfix/gospel/crypto/ed25519"
"github.com/bfix/gospel/data"
"gnunet/crypto"
"gnunet/enums"
"gnunet/util"
"github.com/bfix/gospel/crypto/ed25519"
"github.com/bfix/gospel/data"
)
//----------------------------------------------------------------------
// TRANSPORT_TCP_WELCOME
//----------------------------------------------------------------------
// TransportTcpWelcomeMsg
type TransportTcpWelcomeMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_TCP_WELCOME (61)
PeerID *util.PeerID // Peer identity (EdDSA public key)
}
// NewTransportTcpWelcomeMsg creates a new message for a given peer.
func NewTransportTcpWelcomeMsg(peerid *util.PeerID) *TransportTcpWelcomeMsg {
if peerid == nil {
peerid = util.NewPeerID(nil)
@ -31,6 +35,7 @@ func NewTransportTcpWelcomeMsg(peerid *util.PeerID) *TransportTcpWelcomeMsg {
}
}
// String returns a human-readable representation of the message.
func (m *TransportTcpWelcomeMsg) String() string {
return fmt.Sprintf("TransportTcpWelcomeMsg{peer=%s}", m.PeerID)
}
@ -40,6 +45,59 @@ func (msg *TransportTcpWelcomeMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}
//----------------------------------------------------------------------
// TRANSPORT_PING
//
// Message used to ask a peer to validate receipt (to check an address
// from a HELLO). Followed by the address we are trying to validate,
// or an empty address if we are just sending a PING to confirm that a
// connection which the receiver (of the PING) initiated is still valid.
//----------------------------------------------------------------------
// TransportPingMsg
type TransportPingMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_PING (372)
Challenge uint32 // Challenge code (to ensure fresh reply)
Target *util.PeerID // EdDSA public key (long-term) of target peer
Address []byte `size:"*"` // encoded address
}
// TransportPingMsg creates a new message for given peer with an address to
// be validated.
func NewTransportPingMsg(target *util.PeerID, a *util.Address) *TransportPingMsg {
if target == nil {
target = util.NewPeerID(nil)
}
m := &TransportPingMsg{
MsgSize: uint16(40),
MsgType: TRANSPORT_PING,
Challenge: util.RndUInt32(),
Target: target,
Address: nil,
}
if a != nil {
if addrData, err := data.Marshal(a); err == nil {
m.Address = addrData
m.MsgSize += uint16(len(addrData))
}
}
return m
}
// String returns a human-readable representation of the message.
func (m *TransportPingMsg) String() string {
a := new(util.Address)
data.Unmarshal(a, m.Address)
return fmt.Sprintf("TransportPingMsg{target=%s,addr=%s,challenge=%d}",
m.Target, a, m.Challenge)
}
// Header returns the message header in a separate instance.
func (msg *TransportPingMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}
//----------------------------------------------------------------------
// TRANSPORT_PONG
//
@ -53,29 +111,33 @@ func (msg *TransportTcpWelcomeMsg) Header() *MessageHeader {
// a connection that we initiated).
//----------------------------------------------------------------------
// SignedAddress is the signed block of data representing a node address
type SignedAddress struct {
SignLength uint32 `order:"big"` // Length of signed block
Purpose uint32 `order:"big"` // SIG_TRANSPORT_PONG_OWN
ExpireOn util.AbsoluteTime // usec epoch
AddrSize uint32 `order:"big"` // size of address
Address []byte `size:"AddrSize"` // address
Purpose *crypto.SignaturePurpose // SIG_TRANSPORT_PONG_OWN
ExpireOn util.AbsoluteTime // usec epoch
AddrSize uint32 `order:"big"` // size of address
Address []byte `size:"AddrSize"` // address
}
// NewSignedAddress creates a new (signable) data block from an address.
func NewSignedAddress(a *util.Address) *SignedAddress {
// serialize address
addrData, _ := data.Marshal(a)
alen := len(addrData)
addr := &SignedAddress{
SignLength: uint32(alen + 20),
Purpose: enums.SIG_TRANSPORT_PONG_OWN,
ExpireOn: util.AbsoluteTimeNow().Add(12 * time.Hour),
AddrSize: uint32(alen),
Address: make([]byte, alen),
Purpose: &crypto.SignaturePurpose{
Size: uint32(alen + 20),
Purpose: enums.SIG_TRANSPORT_PONG_OWN,
},
ExpireOn: util.AbsoluteTimeNow().Add(12 * time.Hour),
AddrSize: uint32(alen),
Address: make([]byte, alen),
}
copy(addr.Address, addrData)
return addr
}
// TransportPongMsg
type TransportPongMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_PING (372)
@ -84,6 +146,8 @@ type TransportPongMsg struct {
SignedBlock *SignedAddress // signed block of data
}
// NewTransportPongMsg creates a reponse message with an address the replying
// peer wants to be reached.
func NewTransportPongMsg(challenge uint32, a *util.Address) *TransportPongMsg {
m := &TransportPongMsg{
MsgSize: 72,
@ -94,12 +158,13 @@ func NewTransportPongMsg(challenge uint32, a *util.Address) *TransportPongMsg {
}
if a != nil {
sa := NewSignedAddress(a)
m.MsgSize += uint16(sa.SignLength)
m.MsgSize += uint16(sa.Purpose.Size)
m.SignedBlock = sa
}
return m
}
// String returns a human-readable representation of the message.
func (m *TransportPongMsg) String() string {
a := new(util.Address)
if err := data.Unmarshal(a, m.SignedBlock.Address); err == nil {
@ -114,6 +179,7 @@ func (msg *TransportPongMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}
// Sign the address block of a pong message.
func (m *TransportPongMsg) Sign(prv *ed25519.PrivateKey) error {
data, err := data.Marshal(m.SignedBlock)
if err != nil {
@ -127,6 +193,7 @@ func (m *TransportPongMsg) Sign(prv *ed25519.PrivateKey) error {
return nil
}
// Verify the address block of a pong message
func (m *TransportPongMsg) Verify(pub *ed25519.PublicKey) (bool, error) {
data, err := data.Marshal(m.SignedBlock)
if err != nil {
@ -139,55 +206,6 @@ func (m *TransportPongMsg) Verify(pub *ed25519.PublicKey) (bool, error) {
return pub.EdVerify(data, sig)
}
//----------------------------------------------------------------------
// TRANSPORT_PING
//
// Message used to ask a peer to validate receipt (to check an address
// from a HELLO). Followed by the address we are trying to validate,
// or an empty address if we are just sending a PING to confirm that a
// connection which the receiver (of the PING) initiated is still valid.
//----------------------------------------------------------------------
type TransportPingMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_PING (372)
Challenge uint32 // Challenge code (to ensure fresh reply)
Target *util.PeerID // EdDSA public key (long-term) of target peer
Address []byte `size:"*"` // encoded address
}
func NewTransportPingMsg(target *util.PeerID, a *util.Address) *TransportPingMsg {
if target == nil {
target = util.NewPeerID(nil)
}
m := &TransportPingMsg{
MsgSize: uint16(40),
MsgType: TRANSPORT_PING,
Challenge: util.RndUInt32(),
Target: target,
Address: nil,
}
if a != nil {
if addrData, err := data.Marshal(a); err == nil {
m.Address = addrData
m.MsgSize += uint16(len(addrData))
}
}
return m
}
func (m *TransportPingMsg) String() string {
a := new(util.Address)
data.Unmarshal(a, m.Address)
return fmt.Sprintf("TransportPingMsg{target=%s,addr=%s,challenge=%d}",
m.Target, a, m.Challenge)
}
// Header returns the message header in a separate instance.
func (msg *TransportPingMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}
//----------------------------------------------------------------------
// HELLO
//
@ -202,6 +220,7 @@ func (msg *TransportPingMsg) Header() *MessageHeader {
// 4) address (address-length bytes)
//----------------------------------------------------------------------
// HelloAddress
type HelloAddress struct {
Transport string // Name of transport
AddrSize uint16 `order:"big"` // Size of address entry
@ -209,6 +228,7 @@ type HelloAddress struct {
Address []byte `size:"AddrSize"` // Address specification
}
// NewHelloAddress create a new HELLO address from the given address
func NewAddress(a *util.Address) *HelloAddress {
addr := &HelloAddress{
Transport: a.Transport,
@ -220,11 +240,13 @@ func NewAddress(a *util.Address) *HelloAddress {
return addr
}
// String returns a human-readable representation of the message.
func (a *HelloAddress) String() string {
return fmt.Sprintf("Address{%s,expire=%s}",
util.AddressString(a.Transport, a.Address), a.ExpireOn)
}
// HelloMsg
type HelloMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // HELLO (17)
@ -233,6 +255,7 @@ type HelloMsg struct {
Addresses []*HelloAddress `size:"*"` // List of end-point addressess
}
// NewHelloMsg creates a new HELLO msg for a given peer.
func NewHelloMsg(peerid *util.PeerID) *HelloMsg {
if peerid == nil {
peerid = util.NewPeerID(nil)
@ -246,11 +269,13 @@ func NewHelloMsg(peerid *util.PeerID) *HelloMsg {
}
}
// String returns a human-readable representation of the message.
func (m *HelloMsg) String() string {
return fmt.Sprintf("HelloMsg{peer=%s,friendsonly=%d,addr=%v}",
m.PeerID, m.FriendOnly, m.Addresses)
}
// AddAddress adds a new address to the HELLO message.
func (m *HelloMsg) AddAddress(a *HelloAddress) {
m.Addresses = append(m.Addresses, a)
m.MsgSize += uint16(len(a.Transport)) + a.AddrSize + 11
@ -265,11 +290,13 @@ func (msg *HelloMsg) Header() *MessageHeader {
// TRANSPORT_SESSION_ACK
//----------------------------------------------------------------------
// SessionAckMsg
type SessionAckMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_ACK (377)
}
// NewSessionAckMsg creates an new message (no body required).
func NewSessionAckMsg() *SessionAckMsg {
return &SessionAckMsg{
MsgSize: 16,
@ -277,6 +304,7 @@ func NewSessionAckMsg() *SessionAckMsg {
}
}
// String returns a human-readable representation of the message.
func (m *SessionAckMsg) String() string {
return "SessionAck{}"
}
@ -290,6 +318,7 @@ func (msg *SessionAckMsg) Header() *MessageHeader {
// TRANSPORT_SESSION_SYN
//----------------------------------------------------------------------
// SessionSynMsg
type SessionSynMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_SYN (375)
@ -297,6 +326,7 @@ type SessionSynMsg struct {
Timestamp util.AbsoluteTime // usec epoch
}
// NewSessionSynMsg creates a SYN request for the a session
func NewSessionSynMsg() *SessionSynMsg {
return &SessionSynMsg{
MsgSize: 16,
@ -306,6 +336,7 @@ func NewSessionSynMsg() *SessionSynMsg {
}
}
// String returns a human-readable representation of the message.
func (m *SessionSynMsg) String() string {
return fmt.Sprintf("SessionSyn{timestamp=%s}", m.Timestamp)
}
@ -319,6 +350,7 @@ func (msg *SessionSynMsg) Header() *MessageHeader {
// TRANSPORT_SESSION_SYN_ACK
//----------------------------------------------------------------------
// SessionSynAckMsg
type SessionSynAckMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_SYN_ACK (376)
@ -326,6 +358,7 @@ type SessionSynAckMsg struct {
Timestamp util.AbsoluteTime // usec epoch
}
// NewSessionSynAckMsg is an ACK for a SYN request
func NewSessionSynAckMsg() *SessionSynAckMsg {
return &SessionSynAckMsg{
MsgSize: 16,
@ -335,6 +368,7 @@ func NewSessionSynAckMsg() *SessionSynAckMsg {
}
}
// String returns a human-readable representation of the message.
func (m *SessionSynAckMsg) String() string {
return fmt.Sprintf("SessionSynAck{timestamp=%s}", m.Timestamp)
}
@ -348,12 +382,14 @@ func (msg *SessionSynAckMsg) Header() *MessageHeader {
// TRANSPORT_SESSION_QUOTA
//----------------------------------------------------------------------
// SessionQuotaMsg
type SessionQuotaMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_QUOTA (379)
Quota uint32 `order:"big"` // Quota in bytes per second
}
// NewSessionQuotaMsg announces a session quota to the other end of the session.
func NewSessionQuotaMsg(quota uint32) *SessionQuotaMsg {
m := new(SessionQuotaMsg)
if quota > 0 {
@ -364,6 +400,7 @@ func NewSessionQuotaMsg(quota uint32) *SessionQuotaMsg {
return m
}
// String returns a human-readable representation of the message.
func (m *SessionQuotaMsg) String() string {
return fmt.Sprintf("SessionQuotaMsg{%sB/s}", util.Scale1024(uint64(m.Quota)))
}
@ -374,57 +411,63 @@ func (msg *SessionQuotaMsg) Header() *MessageHeader {
}
//----------------------------------------------------------------------
// TRANSPORT_SESSION_KEEPALIVE_RESPONSE
// TRANSPORT_SESSION_KEEPALIVE
//----------------------------------------------------------------------
type SessionKeepAliveRespMsg struct {
// SessionKeepAliveMsg
type SessionKeepAliveMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_KEEPALIVE_RESPONSE (382)
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_KEEPALIVE (381)
Nonce uint32
}
func NewSessionKeepAliveRespMsg(nonce uint32) *SessionKeepAliveRespMsg {
m := &SessionKeepAliveRespMsg{
// NewSessionKeepAliveMsg creates a new request to keep a session.
func NewSessionKeepAliveMsg() *SessionKeepAliveMsg {
m := &SessionKeepAliveMsg{
MsgSize: 8,
MsgType: TRANSPORT_SESSION_KEEPALIVE_RESPONSE,
Nonce: nonce,
MsgType: TRANSPORT_SESSION_KEEPALIVE,
Nonce: util.RndUInt32(),
}
return m
}
func (m *SessionKeepAliveRespMsg) String() string {
return fmt.Sprintf("SessionKeepAliveRespMsg{%d}", m.Nonce)
// String returns a human-readable representation of the message.
func (m *SessionKeepAliveMsg) String() string {
return fmt.Sprintf("SessionKeepAliveMsg{%d}", m.Nonce)
}
// Header returns the message header in a separate instance.
func (msg *SessionKeepAliveRespMsg) Header() *MessageHeader {
func (msg *SessionKeepAliveMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}
//----------------------------------------------------------------------
// TRANSPORT_SESSION_KEEPALIVE
// TRANSPORT_SESSION_KEEPALIVE_RESPONSE
//----------------------------------------------------------------------
type SessionKeepAliveMsg struct {
// SessionKeepAliveRespMsg
type SessionKeepAliveRespMsg struct {
MsgSize uint16 `order:"big"` // total size of message
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_KEEPALIVE (381)
MsgType uint16 `order:"big"` // TRANSPORT_SESSION_KEEPALIVE_RESPONSE (382)
Nonce uint32
}
func NewSessionKeepAliveMsg() *SessionKeepAliveMsg {
m := &SessionKeepAliveMsg{
// NewSessionKeepAliveRespMsg is a response message for a "keep session" request.
func NewSessionKeepAliveRespMsg(nonce uint32) *SessionKeepAliveRespMsg {
m := &SessionKeepAliveRespMsg{
MsgSize: 8,
MsgType: TRANSPORT_SESSION_KEEPALIVE,
Nonce: util.RndUInt32(),
MsgType: TRANSPORT_SESSION_KEEPALIVE_RESPONSE,
Nonce: nonce,
}
return m
}
func (m *SessionKeepAliveMsg) String() string {
return fmt.Sprintf("SessionKeepAliveMsg{%d}", m.Nonce)
// String returns a human-readable representation of the message.
func (m *SessionKeepAliveRespMsg) String() string {
return fmt.Sprintf("SessionKeepAliveRespMsg{%d}", m.Nonce)
}
// Header returns the message header in a separate instance.
func (msg *SessionKeepAliveMsg) Header() *MessageHeader {
func (msg *SessionKeepAliveRespMsg) Header() *MessageHeader {
return &MessageHeader{msg.MsgSize, msg.MsgType}
}

+ 2
- 1
src/gnunet/service/client.go View File

@ -1,9 +1,10 @@
package service
import (
"github.com/bfix/gospel/logger"
"gnunet/message"
"gnunet/transport"
"github.com/bfix/gospel/logger"
)
// Client


+ 2
- 1
src/gnunet/service/service.go View File

@ -3,8 +3,9 @@ package service
import (
"fmt"
"github.com/bfix/gospel/logger"
"gnunet/transport"
"github.com/bfix/gospel/logger"
)
// Service is an interface for GNUnet services. Every service has one channel


+ 1
- 0
src/gnunet/transport/channel.go View File

@ -11,6 +11,7 @@ import (
"gnunet/message"
)
// Error codes
var (
ErrChannelNotImplemented = fmt.Errorf("Protocol not implemented")
ErrChannelNotOpened = fmt.Errorf("Channel not opened")


+ 28
- 11
src/gnunet/transport/channel_netw.go View File

@ -14,11 +14,12 @@ import (
// NetworkChannel
type NetworkChannel struct {
network string
conn net.Conn
network string // network protocol identifier ("tcp", "unix", ...)
conn net.Conn // associated connection
}
// NewNetworkChannel
// NewNetworkChannel creates a new channel for a given network protocol.
// The channel is in pending state and need to be opened before use.
func NewNetworkChannel(netw string) Channel {
return &NetworkChannel{
network: netw,
@ -26,7 +27,11 @@ func NewNetworkChannel(netw string) Channel {
}
}
// Open
// Open a network channel based on specification:
// The specification is a string separated into parts by the '+' delimiter
// (e.g. "unix+/tmp/gnunet-service-gns-go.sock+perm=0770"). The network
// identifier (first part) must match the network specification of the
// underlaying NetworkChannel instance.
func (c *NetworkChannel) Open(spec string) (err error) {
parts := strings.Split(spec, "+")
// check for correct protocol
@ -38,7 +43,7 @@ func (c *NetworkChannel) Open(spec string) (err error) {
return
}
// Close
// Close a network channel
func (c *NetworkChannel) Close() error {
if c.conn != nil {
return c.conn.Close()
@ -46,7 +51,8 @@ func (c *NetworkChannel) Close() error {
return ErrChannelNotOpened
}
// Read
// Read bytes from a network channel into buffer: Returns the number of read
// bytes and an error code. Only works on open channels ;)
func (c *NetworkChannel) Read(buf []byte) (int, error) {
if c.conn == nil {
return 0, ErrChannelNotOpened
@ -54,7 +60,8 @@ func (c *NetworkChannel) Read(buf []byte) (int, error) {
return c.conn.Read(buf)
}
// Write
// Write buffer to a network channel: Returns the number of written bytes and
// an error code.
func (c *NetworkChannel) Write(buf []byte) (int, error) {
if c.conn == nil {
return 0, ErrChannelNotOpened
@ -67,8 +74,8 @@ func (c *NetworkChannel) Write(buf []byte) (int, error) {
// NetworkChannelServer
type NetworkChannelServer struct {
network string
listener net.Listener
network string // network protocol to listen on
listener net.Listener // reference to listener object
}
// NewNetworkChannelServer
@ -79,7 +86,9 @@ func NewNetworkChannelServer(netw string) ChannelServer {
}
}
// Open
// Open a network channel server (= start running it) based on the given
// specification. For every client connection to the server, the associated
// network channel for the connection is send via the hdlr channel.
func (s *NetworkChannelServer) Open(spec string, hdlr chan<- Channel) (err error) {
parts := strings.Split(spec, "+")
// check for correct protocol
@ -136,7 +145,7 @@ func (s *NetworkChannelServer) Open(spec string, hdlr chan<- Channel) (err error
return nil
}
// Close
// Close a network channel server (= stop the server)
func (s *NetworkChannelServer) Close() error {
if s.listener != nil {
err := s.listener.Close()
@ -147,27 +156,35 @@ func (s *NetworkChannelServer) Close() error {
}
////////////////////////////////////////////////////////////////////////
// helper functions to instantiate network channels and servers for
// common network protocols
// NewSocketChannel: Unix Domain Socket connection
func NewSocketChannel() Channel {
return NewNetworkChannel("unix")
}
// NewTCPChannel: TCP connection
func NewTCPChannel() Channel {
return NewNetworkChannel("tcp")
}
// NewUDPChannel: UDP connection
func NewUDPChannel() Channel {
return NewNetworkChannel("udp")
}
// NewSocketChannelServer: Unix Domain Socket listener
func NewSocketChannelServer() ChannelServer {
return NewNetworkChannelServer("unix")
}
// NewTCPChannelServer: TCP listener
func NewTCPChannelServer() ChannelServer {
return NewNetworkChannelServer("tcp")
}
// NewUDPChannelServer: UDP listener
func NewUDPChannelServer() ChannelServer {
return NewNetworkChannelServer("udp")
}

+ 8
- 1
src/gnunet/transport/connection.go View File

@ -5,7 +5,6 @@ import (
"gnunet/message"
)
////////////////////////////////////////////////////////////////////////
// Connection for communicating peers
type Connection struct {
from, to *core.Peer
@ -17,6 +16,8 @@ type Connection struct {
shared []byte
}
// NewConnection instanciates a new connection between peers communicating
// over a message channel (Connections are authenticated and secured).
func NewConnection(ch *MsgChannel, from, to *core.Peer) *Connection {
return &Connection{
from: from,
@ -26,27 +27,33 @@ func NewConnection(ch *MsgChannel, from, to *core.Peer) *Connection {
}
}
// SharedSecret computes the shared secret the two endpoints of a connection.
func (c *Connection) SharedSecret(secret []byte) {
c.shared = make([]byte, len(secret))
copy(c.shared, secret)
}
// GetState returns the current state of the connection.
func (c *Connection) GetState() int {
return c.state
}
// SetBandwidth to control transfer rates on the connection
func (c *Connection) SetBandwidth(bw uint32) {
c.bandwidth = bw
}
// Close connection between two peers.
func (c *Connection) Close() error {
return c.ch.Close()
}
// Send a message on the connection
func (c *Connection) Send(msg message.Message) error {
return c.ch.Send(msg)
}
// Receive a message on the connection
func (c *Connection) Receive() (message.Message, error) {
return c.ch.Receive()
}

+ 1
- 2
src/gnunet/transport/session.go View File

@ -1,7 +1,6 @@
package transport
import ()
// Session states
const (
KX_STATE_DOWN = iota // No handshake yet.
KX_STATE_KEY_SENT // We've sent our session key.


+ 38
- 17
src/gnunet/util/address.go View File

@ -1,29 +1,19 @@
package util
import (
"encoding/hex"
"fmt"
"net"
)
type IPAddress struct {
Host []byte `size:"*-2"`
Port uint16 `order:"big"`
}
func NewIPAddress(host []byte, port uint16) *IPAddress {
ip := &IPAddress{
Host: make([]byte, len(host)),
Port: port,
}
copy(ip.Host, host)
return ip
}
// Address specifies how a peer is reachable on the network.
type Address struct {
Transport string
Options uint32 `order:"big"`
Address []byte `size:"*"`
Transport string // transport protocol
Options uint32 `order:"big"` // address options
Address []byte `size:"*"` // address data (protocol-dependent)
}
// NewAddress returns a new Address for the given transport and specs
func NewAddress(transport string, addr []byte) *Address {
a := &Address{
Transport: transport,
@ -34,6 +24,37 @@ func NewAddress(transport string, addr []byte) *Address {
return a
}
// String returns a human-readable representation of an address.
func (a *Address) String() string {
return fmt.Sprintf("Address{%s}", AddressString(a.Transport, a.Address))
}
//----------------------------------------------------------------------
// AddressString returns a string representaion of an address.
func AddressString(transport string, addr []byte) string {
if transport == "tcp" || transport == "udp" {
alen := len(addr)
port := uint(addr[alen-2])*256 + uint(addr[alen-1])
return fmt.Sprintf("%s:%s:%d", transport, net.IP(addr[:alen-2]).String(), port)
}
return fmt.Sprintf("%s:%s", transport, hex.EncodeToString(addr))
}
//----------------------------------------------------------------------
// IP address (can be IPv4 or IPv6 or a DNS name)
type IPAddress struct {
Host []byte `size:"*-2"`
Port uint16 `order:"big"`
}
// NewIPAddress creates a new instance for a given host and port.
func NewIPAddress(host []byte, port uint16) *IPAddress {
ip := &IPAddress{
Host: make([]byte, len(host)),
Port: port,
}
copy(ip.Host, host)
return ip
}

+ 2
- 11
src/gnunet/util/format.go View File

@ -1,22 +1,13 @@
package util
import (
"encoding/hex"
"fmt"
"net"
)
func AddressString(transport string, addr []byte) string {
if transport == "tcp" || transport == "udp" {
alen := len(addr)
port := uint(addr[alen-2])*256 + uint(addr[alen-1])
return fmt.Sprintf("%s:%s:%d", transport, net.IP(addr[:alen-2]).String(), port)
}
return fmt.Sprintf("%s:%s", transport, hex.EncodeToString(addr))
}
var scale = " kMGTPEO"
// Scale1024 returns an integer value (e.g. a size) as a human-readable
// string with scales: a size of 183467245 would result in "174,967M"
func Scale1024(n uint64) string {
v := float64(n)
var i int


+ 2
- 1
src/gnunet/util/id.go View File

@ -4,7 +4,8 @@ var (
_id = 0
)
// generate next unique identifier (unique in the running process/application)
func NextID() int {
_id += 1
_id++
return _id
}

+ 0
- 3
src/gnunet/util/msg_queue.go View File

@ -1,3 +0,0 @@
package util
import ()

+ 3
- 0
src/gnunet/util/peer_id.go View File

@ -1,9 +1,11 @@
package util
// PeerID is the 32-byte binary representation od a Ed25519 key
type PeerID struct {
Key []byte `size:"32"`
}
// NewPeerID creates a new object from the data.
func NewPeerID(data []byte) *PeerID {
if data == nil {
data = make([]byte, 32)
@ -22,6 +24,7 @@ func NewPeerID(data []byte) *PeerID {
}
}
// String returns a human-readable representation of a peer id.
func (p *PeerID) String() string {
return EncodeBinaryToString(p.Key)
}

+ 8
- 0
src/gnunet/util/rnd.go View File

@ -6,16 +6,19 @@ import (
"encoding/binary"
)
// RndArray fills a buffer with random content
func RndArray(b []byte) {
rand.Read(b)
}
// NewRndArray creates a new buffer of given size; filled with random content.
func NewRndArray(size int) []byte {
b := make([]byte, size)
rand.Read(b)
return b
}
// RndUInt64 returns a new 64-bit unsigned random integer.
func RndUInt64() uint64 {
b := make([]byte, 8)
RndArray(b)
@ -25,22 +28,27 @@ func RndUInt64() uint64 {
return v
}
// RndInt64 returns a new 64-bit signed random integer.
func RndInt64() int64 {
return int64(RndUInt64())
}
// RndUInt32 returns a new 32-bit unsigned random integer.
func RndUInt32() uint32 {
return uint32(RndUInt64())
}
// RndInt32 returns a new 32-bit signed random integer.
func RndInt32() int32 {
return int32(RndUInt64())
}
// RndUInt16 returns a new 16-bit unsigned random integer.
func RndUInt16() uint16 {
return uint16(RndUInt64())
}
// RndInt16 returns a new 16-bit signed random integer.
func RndInt16() int16 {
return int16(RndUInt64())
}

Loading…
Cancel
Save