mirror of
https://github.com/go-i2p/go-i2cp.git
synced 2025-06-08 01:09:15 -04:00
The whole thing compiles now, writing tests and fixing bugs
This commit is contained in:
37
client.go
37
client.go
@ -78,9 +78,9 @@ type RouterInfo struct {
|
|||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
logger *LoggerCallbacks // TODO idk wat this is for
|
logger *LoggerCallbacks // TODO idk wat this is for
|
||||||
callbacks ClientCallBacks
|
callbacks *ClientCallBacks
|
||||||
properties [NR_OF_I2CP_CLIENT_PROPERTIES]string
|
properties [NR_OF_I2CP_CLIENT_PROPERTIES]string
|
||||||
tcp *Tcp
|
tcp Tcp
|
||||||
outputStream *Stream
|
outputStream *Stream
|
||||||
messageStream *Stream
|
messageStream *Stream
|
||||||
router RouterInfo
|
router RouterInfo
|
||||||
@ -98,17 +98,18 @@ type Client struct {
|
|||||||
var defaultConfigFile = "/.i2cp.conf"
|
var defaultConfigFile = "/.i2cp.conf"
|
||||||
|
|
||||||
// NewClient creates a new i2p client with the specified callbacks
|
// NewClient creates a new i2p client with the specified callbacks
|
||||||
func NewClient(callbacks ClientCallBacks) (c *Client) {
|
func NewClient(callbacks *ClientCallBacks) (c *Client) {
|
||||||
c = new(Client)
|
c = new(Client)
|
||||||
c.callbacks = callbacks
|
c.callbacks = callbacks
|
||||||
LogInit(nil, ERROR)
|
LogInit(nil, ERROR)
|
||||||
c.outputStream = bytes.NewBuffer(make([]byte, 0, I2CP_MESSAGE_SIZE))
|
c.outputStream = NewStream(make([]byte, 0, I2CP_MESSAGE_SIZE))
|
||||||
c.messageStream = bytes.NewBuffer(make([]byte, 0, I2CP_MESSAGE_SIZE))
|
c.messageStream = NewStream(make([]byte, 0, I2CP_MESSAGE_SIZE))
|
||||||
c.setDefaultProperties()
|
c.setDefaultProperties()
|
||||||
c.lookup = make(map[string]uint32, 1000)
|
c.lookup = make(map[string]uint32, 1000)
|
||||||
c.lookupReq = make(map[uint32]LookupEntry, 1000)
|
c.lookupReq = make(map[uint32]LookupEntry, 1000)
|
||||||
c.sessions = make(map[uint16]*Session)
|
c.sessions = make(map[uint16]*Session)
|
||||||
c.outputQueue = make([]*Stream, 0)
|
c.outputQueue = make([]*Stream, 0)
|
||||||
|
c.tcp.Init()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,20 +268,21 @@ func (c *Client) onMsgPayload(stream *Stream) {
|
|||||||
var protocol uint8
|
var protocol uint8
|
||||||
var sessionId, srcPort, destPort uint16
|
var sessionId, srcPort, destPort uint16
|
||||||
var messageId, payloadSize uint32
|
var messageId, payloadSize uint32
|
||||||
var out Stream
|
|
||||||
var err error
|
var err error
|
||||||
var ret int
|
var ret int
|
||||||
Debug(TAG|PROTOCOL, "Received PayloadMessage message")
|
Debug(TAG|PROTOCOL, "Received PayloadMessage message")
|
||||||
sessionId, err = stream.ReadUint16()
|
sessionId, err = stream.ReadUint16()
|
||||||
messageId, err = stream.ReadUint32()
|
messageId, err = stream.ReadUint32()
|
||||||
|
_ = messageId // currently unused
|
||||||
session, ok := c.sessions[sessionId]
|
session, ok := c.sessions[sessionId]
|
||||||
if !ok {
|
if !ok {
|
||||||
Fatal(TAG|FATAL, "Session id %d does not match any of our currently initiated sessions by %p", sessionId, c)
|
Fatal(TAG|FATAL, "Session id %d does not match any of our currently initiated sessions by %p", sessionId, c)
|
||||||
}
|
}
|
||||||
payloadSize, err = stream.ReadUint32()
|
payloadSize, err = stream.ReadUint32()
|
||||||
|
_ = payloadSize // currently unused
|
||||||
// validate gzip header
|
// validate gzip header
|
||||||
var msgStream = bytes.NewBuffer(stream.Bytes())
|
var msgStream = bytes.NewBuffer(stream.Bytes())
|
||||||
ret, err = stream.Read(testHeader[:])
|
_, err = stream.Read(testHeader[:])
|
||||||
if testHeader != gzipHeader {
|
if testHeader != gzipHeader {
|
||||||
Warning(TAG, "Payload validation failed, skipping payload")
|
Warning(TAG, "Payload validation failed, skipping payload")
|
||||||
return
|
return
|
||||||
@ -298,9 +300,10 @@ func (c *Client) onMsgPayload(stream *Stream) {
|
|||||||
destPort, err = stream.ReadUint16()
|
destPort, err = stream.ReadUint16()
|
||||||
_, err = stream.ReadByte()
|
_, err = stream.ReadByte()
|
||||||
protocol, err = stream.ReadByte()
|
protocol, err = stream.ReadByte()
|
||||||
session.dispatchMessage(protocol, srcPort, destPort, payload)
|
session.dispatchMessage(protocol, srcPort, destPort, &Stream{payload})
|
||||||
}
|
}
|
||||||
|
_ = err // currently unused
|
||||||
|
_ = ret // currently unused
|
||||||
}
|
}
|
||||||
func (c *Client) onMsgStatus(stream *Stream) {
|
func (c *Client) onMsgStatus(stream *Stream) {
|
||||||
var status uint8
|
var status uint8
|
||||||
@ -313,6 +316,7 @@ func (c *Client) onMsgStatus(stream *Stream) {
|
|||||||
status, err = stream.ReadByte()
|
status, err = stream.ReadByte()
|
||||||
size, err = stream.ReadUint32()
|
size, err = stream.ReadUint32()
|
||||||
nonce, err = stream.ReadUint32()
|
nonce, err = stream.ReadUint32()
|
||||||
|
_ = err // currently unused
|
||||||
Debug(TAG|PROTOCOL, "Message status; session id %d, message id %d, status %d, size %d, nonce %d", sessionId, messageId, status, size, nonce)
|
Debug(TAG|PROTOCOL, "Message status; session id %d, message id %d, status %d, size %d, nonce %d", sessionId, messageId, status, size, nonce)
|
||||||
}
|
}
|
||||||
func (c *Client) onMsgDestReply(stream *Stream) {
|
func (c *Client) onMsgDestReply(stream *Stream) {
|
||||||
@ -354,7 +358,8 @@ func (c *Client) onMsgSessionStatus(stream *Stream) {
|
|||||||
Debug(TAG|PROTOCOL, "Received SessionStatus message.")
|
Debug(TAG|PROTOCOL, "Received SessionStatus message.")
|
||||||
sessionID, err = stream.ReadUint16()
|
sessionID, err = stream.ReadUint16()
|
||||||
sessionStatus, err = stream.ReadByte()
|
sessionStatus, err = stream.ReadByte()
|
||||||
if sessionStatus == I2CP_SESSION_STATUS_CREATED {
|
_ = err // currently unused
|
||||||
|
if SessionStatus(sessionStatus) == I2CP_SESSION_STATUS_CREATED {
|
||||||
if c.currentSession == nil {
|
if c.currentSession == nil {
|
||||||
Error(TAG, "Received session status created without waiting for it %p", c)
|
Error(TAG, "Received session status created without waiting for it %p", c)
|
||||||
return
|
return
|
||||||
@ -367,11 +372,10 @@ func (c *Client) onMsgSessionStatus(stream *Stream) {
|
|||||||
if sess == nil {
|
if sess == nil {
|
||||||
Fatal(TAG|FATAL, "Session with id %d doesn't exists in client instance %p.", sessionID, c)
|
Fatal(TAG|FATAL, "Session with id %d doesn't exists in client instance %p.", sessionID, c)
|
||||||
} else {
|
} else {
|
||||||
sess.dispatchStatus(sessionStatus)
|
sess.dispatchStatus(SessionStatus(sessionStatus))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (c *Client) onMsgReqVariableLease(stream *Stream) {
|
func (c *Client) onMsgReqVariableLease(stream *Stream) {
|
||||||
var t int
|
|
||||||
var sessionId uint16
|
var sessionId uint16
|
||||||
var tunnels uint8
|
var tunnels uint8
|
||||||
var sess *Session
|
var sess *Session
|
||||||
@ -386,9 +390,10 @@ func (c *Client) onMsgReqVariableLease(stream *Stream) {
|
|||||||
}
|
}
|
||||||
leases = make([]*Lease, tunnels)
|
leases = make([]*Lease, tunnels)
|
||||||
for i := uint8(0); i < tunnels; i++ {
|
for i := uint8(0); i < tunnels; i++ {
|
||||||
leases[i] = NewLeaseFromStream(stream)
|
leases[i], err = NewLeaseFromStream(stream)
|
||||||
}
|
}
|
||||||
c.msgCreateLeaseSet(sess, tunnels, leases, true)
|
c.msgCreateLeaseSet(sess, tunnels, leases, true)
|
||||||
|
_ = err // currently unused
|
||||||
}
|
}
|
||||||
func (c *Client) onMsgHostReply(stream *Stream) {
|
func (c *Client) onMsgHostReply(stream *Stream) {
|
||||||
var result uint8
|
var result uint8
|
||||||
@ -407,6 +412,7 @@ func (c *Client) onMsgHostReply(stream *Stream) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal(TAG|FATAL, "Failed to construct destination from stream.")
|
Fatal(TAG|FATAL, "Failed to construct destination from stream.")
|
||||||
}
|
}
|
||||||
|
dest = &dst
|
||||||
}
|
}
|
||||||
sess = c.sessions[sessionId]
|
sess = c.sessions[sessionId]
|
||||||
if sess == nil {
|
if sess == nil {
|
||||||
@ -415,6 +421,7 @@ func (c *Client) onMsgHostReply(stream *Stream) {
|
|||||||
lup = c.lookupReq[requestId]
|
lup = c.lookupReq[requestId]
|
||||||
delete(c.lookupReq, requestId)
|
delete(c.lookupReq, requestId)
|
||||||
sess.dispatchDestination(requestId, lup.address, dest)
|
sess.dispatchDestination(requestId, lup.address, dest)
|
||||||
|
_ = err // currently unused
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) configFileParseCallback(name, value string) {
|
func (c *Client) configFileParseCallback(name, value string) {
|
||||||
@ -571,7 +578,6 @@ func (c *Client) Connect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) CreateSession(sess *Session) {
|
func (c *Client) CreateSession(sess *Session) {
|
||||||
var config *SessionConfig
|
|
||||||
if c.n_sessions == I2CP_MAX_SESSIONS_PER_CLIENT {
|
if c.n_sessions == I2CP_MAX_SESSIONS_PER_CLIENT {
|
||||||
Warning(TAG, "Maximum number of session per client connection reached.")
|
Warning(TAG, "Maximum number of session per client connection reached.")
|
||||||
return
|
return
|
||||||
@ -621,8 +627,7 @@ func (c *Client) DestinationLookup(session *Session, address string) (requestId
|
|||||||
Debug(TAG, "Lookup of b32 address detected, decode and use hash for faster lookup.")
|
Debug(TAG, "Lookup of b32 address detected, decode and use hash for faster lookup.")
|
||||||
host := address[:strings.Index(address, ".")]
|
host := address[:strings.Index(address, ".")]
|
||||||
in.Write([]byte(host))
|
in.Write([]byte(host))
|
||||||
dout, _ := GetCryptoInstance().DecodeStream(CODEC_BASE32, in)
|
out, _ = GetCryptoInstance().DecodeStream(CODEC_BASE32, in)
|
||||||
out = &dout
|
|
||||||
if out.Len() == 0 {
|
if out.Len() == 0 {
|
||||||
Warning(TAG, "Failed to decode hash of address '%s'", address)
|
Warning(TAG, "Failed to decode hash of address '%s'", address)
|
||||||
}
|
}
|
||||||
|
11
client_test.go
Normal file
11
client_test.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package go_i2cp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClient(t *testing.T) {
|
||||||
|
client := NewClient(nil)
|
||||||
|
client.Connect()
|
||||||
|
client.Disconnect()
|
||||||
|
}
|
23
crypto.go
23
crypto.go
@ -7,6 +7,7 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -171,6 +172,19 @@ func (c *Crypto) SignatureKeyPairFromStream(stream *Stream) (sgk SignatureKeyPai
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Crypto) PublicKeyFromStream(keyType uint32, stream *Stream) (key *big.Int, err error) {
|
||||||
|
if keyType == DSA_SHA1 {
|
||||||
|
key = &big.Int{}
|
||||||
|
keyBytes := make([]byte, 128)
|
||||||
|
_, err = stream.Read(keyBytes)
|
||||||
|
key.SetBytes(keyBytes)
|
||||||
|
return key, err
|
||||||
|
} else {
|
||||||
|
Fatal(CRYPTO, "Unknown signature algorithm")
|
||||||
|
return nil, errors.New("Unknown signature algorithm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a signature keypair
|
// Generate a signature keypair
|
||||||
func (c *Crypto) SignatureKeygen(algorithmTyp uint32) (sgk SignatureKeyPair, err error) {
|
func (c *Crypto) SignatureKeygen(algorithmTyp uint32) (sgk SignatureKeyPair, err error) {
|
||||||
var pkey dsa.PrivateKey
|
var pkey dsa.PrivateKey
|
||||||
@ -193,22 +207,27 @@ func (c *Crypto) HashStream(algorithmTyp uint8, src *Stream) *Stream {
|
|||||||
return NewStream(c.sh256.Sum(src.Bytes()))
|
return NewStream(c.sh256.Sum(src.Bytes()))
|
||||||
} else {
|
} else {
|
||||||
Fatal(tAG|FATAL, "Request of unsupported hash algorithm.")
|
Fatal(tAG|FATAL, "Request of unsupported hash algorithm.")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (c *Crypto) EncodeStream(algorithmTyp uint8, src *Stream) (dst Stream) {
|
func (c *Crypto) EncodeStream(algorithmTyp uint8, src *Stream) (dst *Stream) {
|
||||||
switch algorithmTyp {
|
switch algorithmTyp {
|
||||||
case CODEC_BASE32:
|
case CODEC_BASE32:
|
||||||
|
dst = NewStream(make([]byte, c.b32.EncodedLen(src.Len())))
|
||||||
c.b32.Encode(dst.Bytes(), src.Bytes())
|
c.b32.Encode(dst.Bytes(), src.Bytes())
|
||||||
case CODEC_BASE64:
|
case CODEC_BASE64:
|
||||||
|
dst = NewStream(make([]byte, c.b64.EncodedLen(src.Len())))
|
||||||
c.b64.Encode(dst.Bytes(), src.Bytes())
|
c.b64.Encode(dst.Bytes(), src.Bytes())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (c *Crypto) DecodeStream(algorithmTyp uint8, src *Stream) (dst Stream, err error) {
|
func (c *Crypto) DecodeStream(algorithmTyp uint8, src *Stream) (dst *Stream, err error) {
|
||||||
switch algorithmTyp {
|
switch algorithmTyp {
|
||||||
case CODEC_BASE32:
|
case CODEC_BASE32:
|
||||||
|
dst = NewStream(make([]byte, c.b32.DecodedLen(src.Len())))
|
||||||
_, err = c.b32.Decode(dst.Bytes(), src.Bytes())
|
_, err = c.b32.Decode(dst.Bytes(), src.Bytes())
|
||||||
case CODEC_BASE64:
|
case CODEC_BASE64:
|
||||||
|
dst = NewStream(make([]byte, c.b64.DecodedLen(src.Len())))
|
||||||
_, err = c.b64.Decode(dst.Bytes(), src.Bytes())
|
_, err = c.b64.Decode(dst.Bytes(), src.Bytes())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -2,6 +2,7 @@ package go_i2cp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -16,7 +17,7 @@ type Destination struct {
|
|||||||
cert *Certificate
|
cert *Certificate
|
||||||
sgk SignatureKeyPair
|
sgk SignatureKeyPair
|
||||||
signPubKey *big.Int
|
signPubKey *big.Int
|
||||||
pubKey []byte
|
pubKey [PUB_KEY_SIZE]byte
|
||||||
digest [DIGEST_SIZE]byte
|
digest [DIGEST_SIZE]byte
|
||||||
b32 string
|
b32 string
|
||||||
b64 string
|
b64 string
|
||||||
@ -26,21 +27,29 @@ func NewDestination() (dest Destination, err error) {
|
|||||||
nullCert := NewCertificate(CERTIFICATE_NULL)
|
nullCert := NewCertificate(CERTIFICATE_NULL)
|
||||||
dest.cert = &nullCert
|
dest.cert = &nullCert
|
||||||
dest.sgk, err = GetCryptoInstance().SignatureKeygen(DSA_SHA1)
|
dest.sgk, err = GetCryptoInstance().SignatureKeygen(DSA_SHA1)
|
||||||
|
dest.signPubKey = dest.sgk.pub.Y
|
||||||
dest.generateB32()
|
dest.generateB32()
|
||||||
dest.generateB64()
|
dest.generateB64()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO ensure that this function not setting dest.sgk is the right thing to do
|
|
||||||
func NewDestinationFromMessage(stream *Stream) (dest Destination, err error) {
|
func NewDestinationFromMessage(stream *Stream) (dest Destination, err error) {
|
||||||
signPubKey := make([]byte, 128)
|
_, err = stream.Read(dest.pubKey[:])
|
||||||
pubKey := make([]byte, PUB_KEY_SIZE)
|
if err != nil {
|
||||||
_, err = stream.Read(pubKey)
|
return
|
||||||
_, err = stream.Read(signPubKey)
|
}
|
||||||
dest.pubKey = pubKey
|
dest.signPubKey, err = GetCryptoInstance().PublicKeyFromStream(DSA_SHA1, stream)
|
||||||
dest.signPubKey.SetBytes(signPubKey)
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dest.sgk = SignatureKeyPair{}
|
||||||
|
dest.sgk.priv.Y = dest.signPubKey
|
||||||
|
dest.sgk.pub.Y = dest.signPubKey
|
||||||
var cert Certificate
|
var cert Certificate
|
||||||
cert, err = NewCertificateFromMessage(stream)
|
cert, err = NewCertificateFromMessage(stream)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
dest.cert = &cert
|
dest.cert = &cert
|
||||||
dest.generateB32()
|
dest.generateB32()
|
||||||
dest.generateB64()
|
dest.generateB64()
|
||||||
@ -57,9 +66,7 @@ func NewDestinationFromStream(stream *Stream) (dest Destination, err error) {
|
|||||||
if pubKeyLen != PUB_KEY_SIZE {
|
if pubKeyLen != PUB_KEY_SIZE {
|
||||||
Fatal(tag, "Failed to load pub key len, %d != %d", pubKeyLen, PUB_KEY_SIZE)
|
Fatal(tag, "Failed to load pub key len, %d != %d", pubKeyLen, PUB_KEY_SIZE)
|
||||||
}
|
}
|
||||||
pubKey := make([]byte, PUB_KEY_SIZE)
|
_, err = stream.Read(dest.pubKey[:])
|
||||||
_, err = stream.Read(pubKey)
|
|
||||||
dest.pubKey = pubKey
|
|
||||||
dest.generateB32()
|
dest.generateB32()
|
||||||
dest.generateB64()
|
dest.generateB64()
|
||||||
return
|
return
|
||||||
@ -79,9 +86,9 @@ func NewDestinationFromBase64(base64 string) (dest Destination, err error) {
|
|||||||
replaced = strings.Replace(base64, "~", "/", -1)
|
replaced = strings.Replace(base64, "~", "/", -1)
|
||||||
replaced = strings.Replace(replaced, "-", "+", -1)
|
replaced = strings.Replace(replaced, "-", "+", -1)
|
||||||
stream := NewStream([]byte(replaced))
|
stream := NewStream([]byte(replaced))
|
||||||
var decoded Stream
|
var decoded *Stream
|
||||||
decoded, err = GetCryptoInstance().DecodeStream(CODEC_BASE64, stream)
|
decoded, err = GetCryptoInstance().DecodeStream(CODEC_BASE64, stream)
|
||||||
return NewDestinationFromMessage(&decoded)
|
return NewDestinationFromMessage(decoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDestinationFromFile(file *os.File) (dest Destination, err error) {
|
func NewDestinationFromFile(file *os.File) (dest Destination, err error) {
|
||||||
@ -92,7 +99,7 @@ func NewDestinationFromFile(file *os.File) (dest Destination, err error) {
|
|||||||
func (dest *Destination) Copy() (newDest Destination) {
|
func (dest *Destination) Copy() (newDest Destination) {
|
||||||
newDest.cert = dest.cert
|
newDest.cert = dest.cert
|
||||||
newDest.signPubKey = dest.signPubKey
|
newDest.signPubKey = dest.signPubKey
|
||||||
copy(newDest.pubKey, dest.pubKey)
|
newDest.pubKey = dest.pubKey
|
||||||
newDest.sgk = dest.sgk
|
newDest.sgk = dest.sgk
|
||||||
newDest.b32 = dest.b32
|
newDest.b32 = dest.b32
|
||||||
newDest.b64 = dest.b64
|
newDest.b64 = dest.b64
|
||||||
@ -100,48 +107,59 @@ func (dest *Destination) Copy() (newDest Destination) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (dest *Destination) WriteToFile(filename string) (err error) {
|
func (dest *Destination) WriteToFile(filename string) (err error) {
|
||||||
stream := NewStream(make([]byte, DEST_SIZE))
|
stream := NewStream(make([]byte, 0, DEST_SIZE))
|
||||||
dest.WriteToStream(stream)
|
dest.WriteToStream(stream)
|
||||||
var file *os.File
|
var file *os.File
|
||||||
file, err = os.Open(filename)
|
file, err = os.Open(filename)
|
||||||
stream.WriteTo(file)
|
stream.WriteTo(file)
|
||||||
file.Close()
|
file.Close()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
func (dest *Destination) WriteToMessage(stream *Stream) (err error) {
|
func (dest *Destination) WriteToMessage(stream *Stream) (err error) {
|
||||||
_, err = stream.Write(dest.pubKey)
|
lena := len(dest.pubKey)
|
||||||
|
_ = lena
|
||||||
|
_, err = stream.Write(dest.pubKey[:])
|
||||||
_, err = stream.Write(dest.signPubKey.Bytes()) //GetCryptoInstance().WriteSignatureToStream(&dest.sgk, stream)
|
_, err = stream.Write(dest.signPubKey.Bytes()) //GetCryptoInstance().WriteSignatureToStream(&dest.sgk, stream)
|
||||||
err = dest.cert.WriteToMessage(stream)
|
err = dest.cert.WriteToMessage(stream)
|
||||||
|
lenb := stream.Len()
|
||||||
|
_ = lenb
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (dest *Destination) WriteToStream(stream *Stream) (err error) {
|
func (dest *Destination) WriteToStream(stream *Stream) (err error) {
|
||||||
err = dest.cert.WriteToStream(stream)
|
err = dest.cert.WriteToStream(stream)
|
||||||
err = GetCryptoInstance().WriteSignatureToStream(&dest.sgk, stream)
|
err = GetCryptoInstance().WriteSignatureToStream(&dest.sgk, stream)
|
||||||
err = stream.WriteUint16(PUB_KEY_SIZE)
|
err = stream.WriteUint16(PUB_KEY_SIZE)
|
||||||
_, err = stream.Write(dest.pubKey)
|
_, err = stream.Write(dest.pubKey[:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Doesn't seem to be used anywhere??
|
//Doesn't seem to be used anywhere??
|
||||||
func (dest *Destination) Verify() (verified bool, err error) {
|
func (dest *Destination) Verify() (verified bool, err error) {
|
||||||
stream := NewStream(make([]byte, DEST_SIZE))
|
stream := NewStream(make([]byte, 0, DEST_SIZE))
|
||||||
dest.WriteToMessage(stream)
|
dest.WriteToMessage(stream)
|
||||||
stream.Write(dest.digest[:])
|
stream.Write(dest.digest[:])
|
||||||
return GetCryptoInstance().VerifyStream(&dest.sgk, stream)
|
return GetCryptoInstance().VerifyStream(&dest.sgk, stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dest *Destination) generateB32() {
|
func (dest *Destination) generateB32() {
|
||||||
stream := NewStream(make([]byte, DEST_SIZE))
|
stream := NewStream(make([]byte, 0, DEST_SIZE))
|
||||||
dest.WriteToMessage(stream)
|
dest.WriteToMessage(stream)
|
||||||
cpt := GetCryptoInstance()
|
cpt := GetCryptoInstance()
|
||||||
hash := cpt.HashStream(HASH_SHA256, stream)
|
hash := cpt.HashStream(HASH_SHA256, stream)
|
||||||
b32 := cpt.EncodeStream(CODEC_BASE32, hash)
|
b32 := cpt.EncodeStream(CODEC_BASE32, hash)
|
||||||
dest.b32 = string(b32.Bytes()) + ".b32.i2p"
|
length := b32.Len()
|
||||||
|
_ = length
|
||||||
|
dest.b32 = string(b32.Bytes())
|
||||||
|
dest.b32 += ".b32.i2p"
|
||||||
Debug(tag, "New destination %s", dest.b32)
|
Debug(tag, "New destination %s", dest.b32)
|
||||||
}
|
}
|
||||||
func (dest *Destination) generateB64() {
|
func (dest *Destination) generateB64() {
|
||||||
stream := NewStream(make([]byte, DEST_SIZE))
|
stream := NewStream(make([]byte, 0, DEST_SIZE))
|
||||||
dest.WriteToMessage(stream)
|
dest.WriteToMessage(stream)
|
||||||
cpt := GetCryptoInstance()
|
cpt := GetCryptoInstance()
|
||||||
|
if stream.Len() > 0 {
|
||||||
|
fmt.Printf("Stream len %d \n", stream.Len())
|
||||||
|
}
|
||||||
b64B := cpt.EncodeStream(CODEC_BASE64, stream)
|
b64B := cpt.EncodeStream(CODEC_BASE64, stream)
|
||||||
replaced := strings.Replace(string(b64B.Bytes()), "/", "~", -1)
|
replaced := strings.Replace(string(b64B.Bytes()), "/", "~", -1)
|
||||||
replaced = strings.Replace(replaced, "/", "~", -1)
|
replaced = strings.Replace(replaced, "/", "~", -1)
|
||||||
|
55
destination_test.go
Normal file
55
destination_test.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package go_i2cp
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestRandomDestination(t *testing.T) {
|
||||||
|
var destOne, destTwo Destination
|
||||||
|
var err error
|
||||||
|
destOne, err = NewDestination()
|
||||||
|
var stream = NewStream(make([]byte, 4096))
|
||||||
|
destOne.WriteToStream(stream)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not create first test destination with error %s", err.Error())
|
||||||
|
}
|
||||||
|
destTwo, err = NewDestination()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not create second test destination with error %s", err.Error())
|
||||||
|
}
|
||||||
|
if destOne.b32 == destTwo.b32 {
|
||||||
|
t.Fatal("Random destOne == random destTwo")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDestinationFromMessage(t *testing.T) {
|
||||||
|
stream := NewStream(make([]byte, 0, 4096))
|
||||||
|
randDest, err := NewDestination()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not create random destination.")
|
||||||
|
}
|
||||||
|
initialB32 := randDest.b32
|
||||||
|
randDest.WriteToMessage(stream)
|
||||||
|
secDest, err := NewDestinationFromMessage(stream)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create destination from message: '%s'", err.Error())
|
||||||
|
}
|
||||||
|
finalB32 := secDest.b32
|
||||||
|
if initialB32 != finalB32 {
|
||||||
|
t.Fatalf("Recreated destination base32 addresses do not match %s != %s", initialB32, finalB32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDestinationFromBase64(t *testing.T) {
|
||||||
|
randDest, err := NewDestination()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not create random destination.")
|
||||||
|
}
|
||||||
|
initialB64 := randDest.b64
|
||||||
|
secDest, err := NewDestinationFromBase64(initialB64)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create destination from message: '%s'", err.Error())
|
||||||
|
}
|
||||||
|
finalB64 := secDest.b64
|
||||||
|
if initialB64 != finalB64 {
|
||||||
|
t.Fatalf("Recreated destination base64 addresses do not match %s != %s", initialB64, finalB64)
|
||||||
|
}
|
||||||
|
}
|
48
logger.go
48
logger.go
@ -3,31 +3,31 @@ package go_i2cp
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PROTOCOL = (1 << 0)
|
PROTOCOL = 1 << 0
|
||||||
LOGIC = (1 << 1)
|
LOGIC = 1 << 1
|
||||||
|
|
||||||
DEBUG = (1 << 4)
|
DEBUG = 1 << 4
|
||||||
INFO = (1 << 5)
|
INFO = 1 << 5
|
||||||
WARNING = (1 << 6)
|
WARNING = 1 << 6
|
||||||
ERROR = (1 << 7)
|
ERROR = 1 << 7
|
||||||
FATAL = (1 << 8)
|
FATAL = 1 << 8
|
||||||
|
|
||||||
STRINGMAP = (1 << 9)
|
STRINGMAP = 1 << 9
|
||||||
INTMAP = (1 << 10)
|
INTMAP = 1 << 10
|
||||||
QUEUE = (1 << 11)
|
QUEUE = 1 << 11
|
||||||
STREAM = (1 << 12)
|
STREAM = 1 << 12
|
||||||
CRYPTO = (1 << 13)
|
CRYPTO = 1 << 13
|
||||||
TCP = (1 << 14)
|
TCP = 1 << 14
|
||||||
CLIENT = (1 << 15)
|
CLIENT = 1 << 15
|
||||||
CERTIFICATE = (1 << 16)
|
CERTIFICATE = 1 << 16
|
||||||
LEASE = (1 << 17)
|
LEASE = 1 << 17
|
||||||
DESTINATION = (1 << 18)
|
DESTINATION = 1 << 18
|
||||||
SESSION = (1 << 19)
|
SESSION = 1 << 19
|
||||||
SESSION_CONFIG = (1 << 20)
|
SESSION_CONFIG = 1 << 20
|
||||||
TEST = (1 << 21)
|
TEST = 1 << 21
|
||||||
DATAGRAM = (1 << 22)
|
DATAGRAM = 1 << 22
|
||||||
CONFIG_FILE = (1 << 23)
|
CONFIG_FILE = 1 << 23
|
||||||
VERSION = (1 << 24)
|
VERSION = 1 << 24
|
||||||
|
|
||||||
TAG_MASK = 0x0000000f
|
TAG_MASK = 0x0000000f
|
||||||
LEVEL_MASK = 0x000001f0
|
LEVEL_MASK = 0x000001f0
|
||||||
@ -46,7 +46,7 @@ type Logger struct {
|
|||||||
logLevel int
|
logLevel int
|
||||||
}
|
}
|
||||||
|
|
||||||
var logInstance *Logger
|
var logInstance = &Logger{}
|
||||||
|
|
||||||
// TODO filter
|
// TODO filter
|
||||||
func LogInit(callbacks *LoggerCallbacks, level int) {
|
func LogInit(callbacks *LoggerCallbacks, level int) {
|
||||||
|
@ -85,7 +85,7 @@ func NewSessionConfigFromDestinationFile(filename string) (config SessionConfig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.destination == nil {
|
if config.destination == nil {
|
||||||
dest, err := NewDestination()
|
dest, _ := NewDestination()
|
||||||
config.destination = &dest
|
config.destination = &dest
|
||||||
}
|
}
|
||||||
if len(filename) > 0 {
|
if len(filename) > 0 {
|
||||||
@ -113,14 +113,14 @@ func (config *SessionConfig) writeMappingToMessage(stream *Stream) (err error) {
|
|||||||
count := 0
|
count := 0
|
||||||
for i := 0; i < int(NR_OF_SESSION_CONFIG_PROPERTIES); i++ {
|
for i := 0; i < int(NR_OF_SESSION_CONFIG_PROPERTIES); i++ {
|
||||||
var option string
|
var option string
|
||||||
if sc.properties[i] == "" {
|
if config.properties[i] == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
option = sc.configOptLookup(SessionConfigProperty(i))
|
option = config.configOptLookup(SessionConfigProperty(i))
|
||||||
if option == "" {
|
if option == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
is.Write([]byte(option + "=" + sc.properties[i] + ";"))
|
is.Write([]byte(option + "=" + config.properties[i] + ";"))
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
Debug(SESSION_CONFIG, "Writing %d options to mapping table", count)
|
Debug(SESSION_CONFIG, "Writing %d options to mapping table", count)
|
||||||
|
@ -6,10 +6,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Stream = bytes.Buffer
|
type Stream struct {
|
||||||
|
*bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
func NewStream(buf []byte) *Stream {
|
func NewStream(buf []byte) (s *Stream) {
|
||||||
return bytes.NewBuffer(buf)
|
return &Stream{bytes.NewBuffer(buf)}
|
||||||
}
|
}
|
||||||
func (s *Stream) ReadUint16() (r uint16, err error) {
|
func (s *Stream) ReadUint16() (r uint16, err error) {
|
||||||
bts := make([]byte, 2)
|
bts := make([]byte, 2)
|
||||||
|
4
tcp.go
4
tcp.go
@ -30,15 +30,15 @@ func (tcp *Tcp) Init() (err error) {
|
|||||||
|
|
||||||
func (tcp *Tcp) Connect() (err error) {
|
func (tcp *Tcp) Connect() (err error) {
|
||||||
if USE_TLS {
|
if USE_TLS {
|
||||||
roots, err := x509.SystemCertPool()
|
roots, _ := x509.SystemCertPool()
|
||||||
tcp.tlsConn, err = tls.Dial("tcp", tcp.address.String(), &tls.Config{RootCAs: roots})
|
tcp.tlsConn, err = tls.Dial("tcp", tcp.address.String(), &tls.Config{RootCAs: roots})
|
||||||
err = tcp.tlsConn.Handshake()
|
|
||||||
} else {
|
} else {
|
||||||
tcp.conn, err = net.DialTCP("tcp", nil, tcp.address)
|
tcp.conn, err = net.DialTCP("tcp", nil, tcp.address)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = tcp.conn.SetKeepAlive(true)
|
err = tcp.conn.SetKeepAlive(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ = err // currently unused
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
version.go
16
version.go
@ -1,7 +1,6 @@
|
|||||||
package go_i2cp
|
package go_i2cp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -12,28 +11,23 @@ type Version struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseVersion(str string) Version {
|
func parseVersion(str string) Version {
|
||||||
var err error
|
var v = Version{}
|
||||||
var v Version = Version{}
|
|
||||||
segments := strings.Split(str, ".")
|
segments := strings.Split(str, ".")
|
||||||
n := len(segments)
|
n := len(segments)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
var i int
|
i, _ := strconv.Atoi(segments[0])
|
||||||
i, err = strconv.Atoi(segments[0])
|
|
||||||
v.major = uint16(i)
|
v.major = uint16(i)
|
||||||
}
|
}
|
||||||
if n > 1 {
|
if n > 1 {
|
||||||
var i int
|
i, _ := strconv.Atoi(segments[1])
|
||||||
i, err = strconv.Atoi(segments[1])
|
|
||||||
v.minor = uint16(i)
|
v.minor = uint16(i)
|
||||||
}
|
}
|
||||||
if n > 2 {
|
if n > 2 {
|
||||||
var i int
|
i, _ := strconv.Atoi(segments[2])
|
||||||
i, err = strconv.Atoi(segments[2])
|
|
||||||
v.micro = uint16(i)
|
v.micro = uint16(i)
|
||||||
}
|
}
|
||||||
if n > 3 {
|
if n > 3 {
|
||||||
var i int
|
i, _ := strconv.Atoi(segments[3])
|
||||||
i, err = strconv.Atoi(segments[3])
|
|
||||||
v.qualifier = uint16(i)
|
v.qualifier = uint16(i)
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
|
Reference in New Issue
Block a user