mirror of
https://github.com/go-i2p/go-i2cp.git
synced 2025-07-01 09:06:16 -04:00
Starting to add tests
This commit is contained in:
9
.idea/go.imports.xml
generated
Normal file
9
.idea/go.imports.xml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GoImports">
|
||||||
|
<option name="groupStdlibImports" value="true" />
|
||||||
|
<option name="importSorting" value="GOFMT" />
|
||||||
|
<option name="moveAllImportsInOneDeclaration" value="true" />
|
||||||
|
<option name="moveAllStdlibImportsInOneGroup" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
157
client.go
157
client.go
@ -11,7 +11,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const I2CP_CLIENT_VERSION = "0.9.11"
|
const I2CP_CLIENT_VERSION = "0.9.33"
|
||||||
const TAG = CLIENT
|
const TAG = CLIENT
|
||||||
const I2CP_PROTOCOL_INIT uint8 = 0x2a
|
const I2CP_PROTOCOL_INIT uint8 = 0x2a
|
||||||
const I2CP_MESSAGE_SIZE = 0xffff
|
const I2CP_MESSAGE_SIZE = 0xffff
|
||||||
@ -61,6 +61,26 @@ const (
|
|||||||
HOST_LOOKUP_TYPE_HOST = iota
|
HOST_LOOKUP_TYPE_HOST = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var defaultProperties = map[string]string{
|
||||||
|
"i2cp.password": "",
|
||||||
|
"i2cp.username": "",
|
||||||
|
"i2cp.closeIdleTime": "",
|
||||||
|
"i2cp.closeOnIdle": "",
|
||||||
|
"i2cp.encryptLeaseSet": "",
|
||||||
|
"i2cp.fastReceive": "",
|
||||||
|
"i2cp.gzip": "",
|
||||||
|
"i2cp.leaseSetKey": "",
|
||||||
|
"i2cp.leaseSetPrivateKey": "",
|
||||||
|
"i2cp.leaseSetSigningPrivateKey": "",
|
||||||
|
"i2cp.messageReliability": "",
|
||||||
|
"i2cp.reduceIdleTime": "",
|
||||||
|
"i2cp.reduceOnIdle": "",
|
||||||
|
"i2cp.reduceQuantity": "",
|
||||||
|
"i2cp.SSL": "",
|
||||||
|
"i2cp.tcp.host": "127.0.0.1",
|
||||||
|
"i2cp.tcp.port": "7654",
|
||||||
|
}
|
||||||
|
|
||||||
type ClientCallBacks struct {
|
type ClientCallBacks struct {
|
||||||
opaque *interface{}
|
opaque *interface{}
|
||||||
onDisconnect func(*Client, string, *interface{})
|
onDisconnect func(*Client, string, *interface{})
|
||||||
@ -79,7 +99,7 @@ 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 map[string]string
|
||||||
tcp Tcp
|
tcp Tcp
|
||||||
outputStream *Stream
|
outputStream *Stream
|
||||||
messageStream *Stream
|
messageStream *Stream
|
||||||
@ -114,59 +134,25 @@ func NewClient(callbacks *ClientCallBacks) (c *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) setDefaultProperties() {
|
func (c *Client) setDefaultProperties() {
|
||||||
c.properties[CLIENT_PROP_ROUTER_ADDRESS] = "127.0.0.1"
|
c.properties = defaultProperties
|
||||||
c.properties[CLIENT_PROP_ROUTER_PORT] = "7654"
|
|
||||||
home := os.Getenv("HOME")
|
home := os.Getenv("HOME")
|
||||||
if len(home) == 0 {
|
if len(home) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config := home + defaultConfigFile
|
config := home + defaultConfigFile
|
||||||
Debug(CLIENT, "Loading config file %s", config)
|
Debug(CLIENT, "Loading config file %s", config)
|
||||||
ParseConfig(config, func(name, value string) {
|
ParseConfig(config, c.SetProperty)
|
||||||
if prop := c.propFromString(name); prop >= 0 {
|
|
||||||
c.SetProperty(prop, value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) propFromString(name string) ClientProperty {
|
|
||||||
for i := 0; ClientProperty(i) < NR_OF_I2CP_CLIENT_PROPERTIES; i++ {
|
|
||||||
if sessionOptions[i] == name {
|
|
||||||
return ClientProperty(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ClientProperty(-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) messageGetDate(queue bool) {
|
|
||||||
Debug(PROTOCOL, "Sending GetDateMessage")
|
|
||||||
c.messageStream.Reset()
|
|
||||||
c.messageStream.WriteString(I2CP_CLIENT_VERSION)
|
|
||||||
/* write new 0.9.10 auth mapping if username property is set */
|
|
||||||
if c.properties[CLIENT_PROP_USERNAME] != "" {
|
|
||||||
auth := NewStream(make([]byte, 0, 512))
|
|
||||||
auth.WriteString("i2cp.password")
|
|
||||||
auth.WriteByte('=')
|
|
||||||
auth.WriteString(c.properties[CLIENT_PROP_PASSWORD])
|
|
||||||
auth.WriteByte(';')
|
|
||||||
auth.WriteString("i2cp.username")
|
|
||||||
auth.WriteByte('=')
|
|
||||||
auth.WriteString(c.properties[CLIENT_PROP_USERNAME])
|
|
||||||
auth.WriteByte(';')
|
|
||||||
c.messageStream.WriteUint16(uint16(auth.Len()))
|
|
||||||
c.messageStream.Write(auth.Bytes())
|
|
||||||
auth.Reset()
|
|
||||||
}
|
|
||||||
if err := c.sendMessage(I2CP_MSG_GET_DATE, c.messageStream, queue); err != nil {
|
|
||||||
Error(0, "%s", "error while sending GetDateMessage.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) sendMessage(typ uint8, stream *Stream, queue bool) (err error) {
|
func (c *Client) sendMessage(typ uint8, stream *Stream, queue bool) (err error) {
|
||||||
send := NewStream(make([]byte, stream.Len()+4+1))
|
send := NewStream(make([]byte, 0, stream.Len()+4+1))
|
||||||
err = send.WriteUint32(uint32(stream.Len()))
|
err = send.WriteUint32(uint32(stream.Len()))
|
||||||
err = send.WriteByte(typ)
|
err = send.WriteByte(typ)
|
||||||
|
lenb := stream.Len()
|
||||||
|
_ = lenb
|
||||||
_, err = send.Write(stream.Bytes())
|
_, err = send.Write(stream.Bytes())
|
||||||
|
lenc := send.Len()
|
||||||
|
_ = lenc
|
||||||
if queue {
|
if queue {
|
||||||
Debug(PROTOCOL, "Putting %d bytes message on the output queue.", send.Len())
|
Debug(PROTOCOL, "Putting %d bytes message on the output queue.", send.Len())
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
@ -190,16 +176,15 @@ func (c *Client) recvMessage(typ uint8, stream *Stream, dispatch bool) (err erro
|
|||||||
length, err = firstFive.ReadUint32()
|
length, err = firstFive.ReadUint32()
|
||||||
msgType, err = firstFive.ReadByte()
|
msgType, err = firstFive.ReadByte()
|
||||||
if (typ == I2CP_MSG_SET_DATE) && (length > 0xffff) {
|
if (typ == I2CP_MSG_SET_DATE) && (length > 0xffff) {
|
||||||
Fatal(PROTOCOL, "Unexpected response, your router is probably configured to use SSL")
|
Fatal(PROTOCOL, "Unexpected response, check that your router SSL settings match the ~/.i2cp.conf configuration")
|
||||||
}
|
}
|
||||||
if length > 0xffff {
|
if length > 0xffff && typ != I2CP_MSG_DISCONNECT {
|
||||||
Fatal(PROTOCOL, "unexpected message length, length > 0xffff")
|
Fatal(PROTOCOL, "unexpected message length, length > 0xffff")
|
||||||
}
|
}
|
||||||
if (typ != 0) && (msgType != typ) {
|
if (typ != 0) && (msgType != typ) {
|
||||||
Error(PROTOCOL, "expected message type %d, received %d", typ, msgType)
|
Error(PROTOCOL, "expected message type %d, received %d", typ, msgType)
|
||||||
}
|
}
|
||||||
// receive rest
|
// receive rest
|
||||||
stream.ChLen(int(length))
|
|
||||||
i, err = c.tcp.Receive(stream)
|
i, err = c.tcp.Receive(stream)
|
||||||
|
|
||||||
if dispatch {
|
if dispatch {
|
||||||
@ -241,7 +226,7 @@ func (c *Client) onMsgSetDate(stream *Stream) {
|
|||||||
version := make([]byte, verLength)
|
version := make([]byte, verLength)
|
||||||
_, err = stream.Read(version)
|
_, err = stream.Read(version)
|
||||||
c.router.version = parseVersion(string(version))
|
c.router.version = parseVersion(string(version))
|
||||||
Debug(TAG|PROTOCOL, "Router version %s, date %ld", string(version), c.router.date)
|
Debug(TAG|PROTOCOL, "Router version %s, date %d", string(version), c.router.date)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Error(TAG|PROTOCOL, "Could not read SetDate correctly data")
|
Error(TAG|PROTOCOL, "Could not read SetDate correctly data")
|
||||||
}
|
}
|
||||||
@ -250,18 +235,22 @@ func (c *Client) onMsgSetDate(stream *Stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (c *Client) onMsgDisconnect(stream *Stream) {
|
func (c *Client) onMsgDisconnect(stream *Stream) {
|
||||||
var size uint8
|
|
||||||
var err error
|
var err error
|
||||||
Debug(TAG|PROTOCOL, "Received Disconnect message")
|
Debug(TAG|PROTOCOL, "Received Disconnect message")
|
||||||
size, err = stream.ReadByte()
|
//size, err = stream.ReadByte()
|
||||||
strbuf := make([]byte, size)
|
strbuf := make([]byte, stream.Len())
|
||||||
|
lens := stream.Len()
|
||||||
|
_ = lens
|
||||||
_, err = stream.Read(strbuf)
|
_, err = stream.Read(strbuf)
|
||||||
|
|
||||||
Debug(TAG|PROTOCOL, "Received Disconnect message with reason %s", string(strbuf))
|
Debug(TAG|PROTOCOL, "Received Disconnect message with reason %s", string(strbuf))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Error(TAG|PROTOCOL, "Could not read msgDisconnect correctly data")
|
Error(TAG|PROTOCOL, "Could not read msgDisconnect correctly data")
|
||||||
}
|
}
|
||||||
|
if c.callbacks != nil && c.callbacks.onDisconnect != nil {
|
||||||
c.callbacks.onDisconnect(c, string(strbuf), nil)
|
c.callbacks.onDisconnect(c, string(strbuf), nil)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
func (c *Client) onMsgPayload(stream *Stream) {
|
func (c *Client) onMsgPayload(stream *Stream) {
|
||||||
var gzipHeader = [3]byte{0x1f, 0x8b, 0x08}
|
var gzipHeader = [3]byte{0x1f, 0x8b, 0x08}
|
||||||
var testHeader [3]byte
|
var testHeader [3]byte
|
||||||
@ -321,7 +310,7 @@ func (c *Client) onMsgStatus(stream *Stream) {
|
|||||||
}
|
}
|
||||||
func (c *Client) onMsgDestReply(stream *Stream) {
|
func (c *Client) onMsgDestReply(stream *Stream) {
|
||||||
var b32 string
|
var b32 string
|
||||||
var destination Destination
|
var destination *Destination
|
||||||
var lup LookupEntry
|
var lup LookupEntry
|
||||||
var err error
|
var err error
|
||||||
var requestId uint32
|
var requestId uint32
|
||||||
@ -344,7 +333,7 @@ func (c *Client) onMsgDestReply(stream *Stream) {
|
|||||||
if lup == (LookupEntry{}) {
|
if lup == (LookupEntry{}) {
|
||||||
Warning(TAG, "No sesssion for destination lookup of address '%s'", b32)
|
Warning(TAG, "No sesssion for destination lookup of address '%s'", b32)
|
||||||
} else {
|
} else {
|
||||||
lup.session.dispatchDestination(requestId, b32, &destination)
|
lup.session.dispatchDestination(requestId, b32, destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (c *Client) onMsgBandwithLimit(stream *Stream) {
|
func (c *Client) onMsgBandwithLimit(stream *Stream) {
|
||||||
@ -408,11 +397,10 @@ func (c *Client) onMsgHostReply(stream *Stream) {
|
|||||||
requestId, err = stream.ReadUint32()
|
requestId, err = stream.ReadUint32()
|
||||||
result, err = stream.ReadByte()
|
result, err = stream.ReadByte()
|
||||||
if result == 0 {
|
if result == 0 {
|
||||||
dst, err := NewDestinationFromMessage(stream)
|
dest, err = NewDestinationFromMessage(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 {
|
||||||
@ -424,22 +412,6 @@ func (c *Client) onMsgHostReply(stream *Stream) {
|
|||||||
_ = err // currently unused
|
_ = err // currently unused
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) configFileParseCallback(name, value string) {
|
|
||||||
switch name {
|
|
||||||
case "i2cp.tcp.host":
|
|
||||||
c.properties[CLIENT_PROP_ROUTER_ADDRESS] = value
|
|
||||||
case "i2cp.tcp.port":
|
|
||||||
c.properties[CLIENT_PROP_ROUTER_PORT] = value
|
|
||||||
case "i2cp.tcp.SSL":
|
|
||||||
c.properties[CLIENT_PROP_ROUTER_USE_TLS] = value
|
|
||||||
case "i2cp.tcp.username":
|
|
||||||
c.properties[CLIENT_PROP_USERNAME] = value
|
|
||||||
case "i2cp.tcp.password":
|
|
||||||
c.properties[CLIENT_PROP_PASSWORD] = value
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (c *Client) msgCreateLeaseSet(session *Session, tunnels uint8, leases []*Lease, queue bool) {
|
func (c *Client) msgCreateLeaseSet(session *Session, tunnels uint8, leases []*Lease, queue bool) {
|
||||||
var err error
|
var err error
|
||||||
var nullbytes [256]byte
|
var nullbytes [256]byte
|
||||||
@ -476,22 +448,17 @@ func (c *Client) msgCreateLeaseSet(session *Session, tunnels uint8, leases []*Le
|
|||||||
}
|
}
|
||||||
func (c *Client) msgGetDate(queue bool) {
|
func (c *Client) msgGetDate(queue bool) {
|
||||||
var err error
|
var err error
|
||||||
var auth *Stream
|
|
||||||
Debug(TAG|PROTOCOL, "Sending GetDateMessage")
|
Debug(TAG|PROTOCOL, "Sending GetDateMessage")
|
||||||
c.messageStream.Reset()
|
c.messageStream.Reset()
|
||||||
c.messageStream.Write([]byte(I2CP_CLIENT_VERSION))
|
c.messageStream.WriteLenPrefixedString(I2CP_CLIENT_VERSION)
|
||||||
if len(c.properties[CLIENT_PROP_USERNAME]) > 0 {
|
if len(c.properties["i2cp.username"]) > 0 {
|
||||||
auth = NewStream(make([]byte, 0, 512))
|
authInfo := map[string]string{
|
||||||
auth.Write([]byte("i2cp.password="))
|
"i2cp.username": c.properties["i2cp.username"],
|
||||||
auth.Write([]byte(c.properties[CLIENT_PROP_PASSWORD]))
|
"i2cp.password": c.properties["i2cp.password"],
|
||||||
auth.Write([]byte(";"))
|
|
||||||
auth.Write([]byte("i2cp.username="))
|
|
||||||
auth.Write([]byte(c.properties[CLIENT_PROP_USERNAME]))
|
|
||||||
auth.Write([]byte(";"))
|
|
||||||
c.messageStream.WriteUint16(uint16(auth.Len()))
|
|
||||||
c.messageStream.Write(auth.Bytes())
|
|
||||||
}
|
}
|
||||||
if err = c.sendMessage(I2CP_MSG_SET_DATE, c.messageStream, queue); err != nil {
|
c.messageStream.WriteMapping(authInfo)
|
||||||
|
}
|
||||||
|
if err = c.sendMessage(I2CP_MSG_GET_DATE, c.messageStream, queue); err != nil {
|
||||||
Error(TAG, "Error while sending GetDateMessage")
|
Error(TAG, "Error while sending GetDateMessage")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,7 +531,7 @@ func (c *Client) msgSendMessage(sess *Session, dest *Destination, protocol uint8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (c *Client) Connect() {
|
func (c *Client) Connect() {
|
||||||
Info(0, "Client connecting to i2cp at %s:%s", c.properties[CLIENT_PROP_ROUTER_ADDRESS], c.properties[CLIENT_PROP_ROUTER_PORT])
|
Info(0, "Client connecting to i2cp at %s:%s", c.properties["i2cp.tcp.host"], c.properties["i2cp.tcp.host"])
|
||||||
err := c.tcp.Connect()
|
err := c.tcp.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -654,20 +621,18 @@ func (c *Client) Disconnect() {
|
|||||||
c.tcp.Disconnect()
|
c.tcp.Disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) SetProperty(property ClientProperty, value string) {
|
func (c *Client) SetProperty(name, value string) {
|
||||||
c.properties[property] = value
|
if _, ok := c.properties[name]; ok {
|
||||||
switch property {
|
c.properties[name] = value
|
||||||
case CLIENT_PROP_ROUTER_ADDRESS:
|
switch name {
|
||||||
c.tcp.SetProperty(TCP_PROP_ADDRESS, c.properties[CLIENT_PROP_ROUTER_ADDRESS])
|
case "i2cp.tcp.host":
|
||||||
case CLIENT_PROP_ROUTER_PORT:
|
c.tcp.SetProperty(TCP_PROP_ADDRESS, c.properties[name])
|
||||||
c.tcp.SetProperty(TCP_PROP_PORT, c.properties[CLIENT_PROP_ROUTER_PORT])
|
case "i2cp.tcp.port":
|
||||||
case CLIENT_PROP_ROUTER_USE_TLS:
|
c.tcp.SetProperty(TCP_PROP_PORT, c.properties[name])
|
||||||
c.tcp.SetProperty(TCP_PROP_USE_TLS, c.properties[CLIENT_PROP_ROUTER_USE_TLS])
|
case "i2cp.SSL":
|
||||||
|
c.tcp.SetProperty(TCP_PROP_USE_TLS, c.properties[name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetProperty(property ClientProperty) string {
|
|
||||||
return c.properties[property]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) IsConnected() bool {
|
func (c *Client) IsConnected() bool {
|
||||||
|
@ -9,3 +9,25 @@ func TestClient(t *testing.T) {
|
|||||||
client.Connect()
|
client.Connect()
|
||||||
client.Disconnect()
|
client.Disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClient_CreateSession(t *testing.T) {
|
||||||
|
client := NewClient(nil)
|
||||||
|
client.Connect()
|
||||||
|
session := NewSession(client, SessionCallbacks{
|
||||||
|
onDestination: func(session *Session, requestId uint32, address string, dest *Destination) {
|
||||||
|
|
||||||
|
},
|
||||||
|
onStatus: func(session *Session, status SessionStatus) {
|
||||||
|
|
||||||
|
},
|
||||||
|
onMessage: func(session *Session, protocol uint8, srcPort, destPort uint16, payload *Stream) {
|
||||||
|
|
||||||
|
},
|
||||||
|
})
|
||||||
|
session.config.SetProperty(SESSION_CONFIG_PROP_I2CP_FAST_RECEIVE, "true")
|
||||||
|
session.config.SetProperty(SESSION_CONFIG_PROP_OUTBOUND_NICKNAME, "test-i2cp")
|
||||||
|
session.config.SetProperty(SESSION_CONFIG_PROP_OUTBOUND_QUANTITY, "4")
|
||||||
|
session.config.destination, _ = NewDestinationFromBase64("r2zbc34IQSzOIF4N0enKf0xXkJKgsj9yTGGspRnstKZf~4UoAljZOW5aFZywGo-NlaXwt~tIyj4NC0Til0vl1D5N9ip7OMYUCajNNgiXEH~FN33yl-AcJbeTlB-FychSmVfYciTQj6yd19~6wICwkdpy6AYo90bAejSVGpvtFeP5P2pnSwPmcB8m79wyq~C2XjQCe5UcBxnfYolWKgr3uDFrgbhqBVCCkO7zTiARwOWZLVOvZsvKZR4WvYAmQI6CQaxnmT5n1FKO6NBb-HOxVw4onERq86Sc6EQ5d48719Yk-73wq1Mxmr7Y2UwmL~FCnY33rT1FJY2KzUENICL1uEuiVmr9N924CT9RbtldOUUcXmM1gaHlPS40-Hz4AvPxFXHynbyySktN3hBLPwfwhyIQw95ezSNuiBB0xPcujazCw02103n2CO-59rMDmWpttLjpLMggP9IwsAPa9FVLnBqfuCn3NrC4fia50RDwfR41AD1GOOWiUT0avYzbbOdsAAAA")
|
||||||
|
client.CreateSession(session)
|
||||||
|
client.Disconnect()
|
||||||
|
}
|
||||||
|
@ -23,7 +23,8 @@ type Destination struct {
|
|||||||
b64 string
|
b64 string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDestination() (dest Destination, err error) {
|
func NewDestination() (dest *Destination, err error) {
|
||||||
|
dest = &Destination{}
|
||||||
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)
|
||||||
@ -33,7 +34,8 @@ func NewDestination() (dest Destination, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDestinationFromMessage(stream *Stream) (dest Destination, err error) {
|
func NewDestinationFromMessage(stream *Stream) (dest *Destination, err error) {
|
||||||
|
dest = &Destination{}
|
||||||
_, err = stream.Read(dest.pubKey[:])
|
_, err = stream.Read(dest.pubKey[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -53,12 +55,13 @@ func NewDestinationFromMessage(stream *Stream) (dest Destination, err error) {
|
|||||||
dest.cert = &cert
|
dest.cert = &cert
|
||||||
dest.generateB32()
|
dest.generateB32()
|
||||||
dest.generateB64()
|
dest.generateB64()
|
||||||
return
|
return dest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDestinationFromStream(stream *Stream) (dest Destination, err error) {
|
func NewDestinationFromStream(stream *Stream) (dest *Destination, err error) {
|
||||||
var cert Certificate
|
var cert Certificate
|
||||||
var pubKeyLen uint16
|
var pubKeyLen uint16
|
||||||
|
dest = &Destination{}
|
||||||
cert, err = NewCertificateFromStream(stream)
|
cert, err = NewCertificateFromStream(stream)
|
||||||
dest.cert = &cert
|
dest.cert = &cert
|
||||||
dest.sgk, err = GetCryptoInstance().SignatureKeyPairFromStream(stream)
|
dest.sgk, err = GetCryptoInstance().SignatureKeyPairFromStream(stream)
|
||||||
@ -72,7 +75,7 @@ func NewDestinationFromStream(stream *Stream) (dest Destination, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDestinationFromBase64(base64 string) (dest Destination, err error) {
|
func NewDestinationFromBase64(base64 string) (dest *Destination, err error) {
|
||||||
/* Same as decode, except from a filesystem / URL friendly set of characters,
|
/* Same as decode, except from a filesystem / URL friendly set of characters,
|
||||||
* replacing / with ~, and + with -
|
* replacing / with ~, and + with -
|
||||||
*/
|
*/
|
||||||
@ -91,7 +94,7 @@ func NewDestinationFromBase64(base64 string) (dest Destination, err error) {
|
|||||||
return NewDestinationFromMessage(decoded)
|
return NewDestinationFromMessage(decoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDestinationFromFile(file *os.File) (dest Destination, err error) {
|
func NewDestinationFromFile(file *os.File) (*Destination, error) {
|
||||||
var stream Stream
|
var stream Stream
|
||||||
stream.loadFile(file)
|
stream.loadFile(file)
|
||||||
return NewDestinationFromStream(&stream)
|
return NewDestinationFromStream(&stream)
|
||||||
|
@ -3,7 +3,7 @@ package go_i2cp
|
|||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestRandomDestination(t *testing.T) {
|
func TestRandomDestination(t *testing.T) {
|
||||||
var destOne, destTwo Destination
|
var destOne, destTwo *Destination
|
||||||
var err error
|
var err error
|
||||||
destOne, err = NewDestination()
|
destOne, err = NewDestination()
|
||||||
var stream = NewStream(make([]byte, 4096))
|
var stream = NewStream(make([]byte, 4096))
|
||||||
|
@ -71,7 +71,7 @@ func Fatal(tags LoggerTags, message string, args ...interface{}) {
|
|||||||
|
|
||||||
func (l *Logger) log(tags LoggerTags, format string, args ...interface{}) {
|
func (l *Logger) log(tags LoggerTags, format string, args ...interface{}) {
|
||||||
if l.callbacks == nil {
|
if l.callbacks == nil {
|
||||||
fmt.Printf(format, args)
|
fmt.Printf(format+"\n", args)
|
||||||
} else {
|
} else {
|
||||||
l.callbacks.onLog(l, tags, fmt.Sprintf(format, args))
|
l.callbacks.onLog(l, tags, fmt.Sprintf(format, args))
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,11 @@ type Session struct {
|
|||||||
callbacks *SessionCallbacks
|
callbacks *SessionCallbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSession(client *Client, callbacks SessionCallbacks, destFilename string) (sess *Session) {
|
func NewSession(client *Client, callbacks SessionCallbacks) (sess *Session) {
|
||||||
sess = &Session{}
|
sess = &Session{}
|
||||||
sess.client = client
|
sess.client = client
|
||||||
sess.config = &SessionConfig{}
|
dest, _ := NewDestination()
|
||||||
|
sess.config = &SessionConfig{destination: dest}
|
||||||
sess.callbacks = &callbacks
|
sess.callbacks = &callbacks
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -78,15 +78,13 @@ type SessionConfig struct {
|
|||||||
func NewSessionConfigFromDestinationFile(filename string) (config SessionConfig) {
|
func NewSessionConfigFromDestinationFile(filename string) (config SessionConfig) {
|
||||||
var home string
|
var home string
|
||||||
if file, err := os.Open(filename); err == nil {
|
if file, err := os.Open(filename); err == nil {
|
||||||
dest, err := NewDestinationFromFile(file)
|
config.destination, err = NewDestinationFromFile(file)
|
||||||
config.destination = &dest
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warning(SESSION_CONFIG, "Failed to load destination from file '%s', a new destination will be generated.", filename)
|
Warning(SESSION_CONFIG, "Failed to load destination from file '%s', a new destination will be generated.", filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.destination == nil {
|
if config.destination == nil {
|
||||||
dest, _ := NewDestination()
|
config.destination, _ = NewDestination()
|
||||||
config.destination = &dest
|
|
||||||
}
|
}
|
||||||
if len(filename) > 0 {
|
if len(filename) > 0 {
|
||||||
config.destination.WriteToFile(filename)
|
config.destination.WriteToFile(filename)
|
||||||
@ -105,12 +103,11 @@ func NewSessionConfigFromDestinationFile(filename string) (config SessionConfig)
|
|||||||
func (config *SessionConfig) writeToMessage(stream *Stream) {
|
func (config *SessionConfig) writeToMessage(stream *Stream) {
|
||||||
config.destination.WriteToMessage(stream)
|
config.destination.WriteToMessage(stream)
|
||||||
config.writeMappingToMessage(stream)
|
config.writeMappingToMessage(stream)
|
||||||
stream.WriteUint64(uint64(time.Now().Unix()))
|
stream.WriteUint64(uint64(time.Now().Unix() * 1000))
|
||||||
GetCryptoInstance().WriteSignatureToStream(&config.destination.sgk, stream)
|
GetCryptoInstance().WriteSignatureToStream(&config.destination.sgk, stream)
|
||||||
}
|
}
|
||||||
func (config *SessionConfig) writeMappingToMessage(stream *Stream) (err error) {
|
func (config *SessionConfig) writeMappingToMessage(stream *Stream) (err error) {
|
||||||
is := NewStream(make([]byte, 0xffff))
|
m := make(map[string]string)
|
||||||
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 config.properties[i] == "" {
|
if config.properties[i] == "" {
|
||||||
@ -120,15 +117,10 @@ func (config *SessionConfig) writeMappingToMessage(stream *Stream) (err error) {
|
|||||||
if option == "" {
|
if option == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
is.Write([]byte(option + "=" + config.properties[i] + ";"))
|
m[option] = config.properties[i]
|
||||||
count++
|
|
||||||
}
|
}
|
||||||
Debug(SESSION_CONFIG, "Writing %d options to mapping table", count)
|
Debug(SESSION_CONFIG, "Writing %d options to mapping table", len(m))
|
||||||
err = stream.WriteUint16(uint16(is.Len()))
|
return stream.WriteMapping(m)
|
||||||
if is.Len() > 0 {
|
|
||||||
_, err = stream.Write(is.Bytes())
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
func (config *SessionConfig) configOptLookup(property SessionConfigProperty) string {
|
func (config *SessionConfig) configOptLookup(property SessionConfigProperty) string {
|
||||||
return sessionOptions[property]
|
return sessionOptions[property]
|
||||||
|
1
session_test.go
Normal file
1
session_test.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package go_i2cp
|
41
stream.go
41
stream.go
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Stream struct {
|
type Stream struct {
|
||||||
@ -16,40 +17,68 @@ func NewStream(buf []byte) (s *Stream) {
|
|||||||
func (s *Stream) ReadUint16() (r uint16, err error) {
|
func (s *Stream) ReadUint16() (r uint16, err error) {
|
||||||
bts := make([]byte, 2)
|
bts := make([]byte, 2)
|
||||||
_, err = s.Read(bts)
|
_, err = s.Read(bts)
|
||||||
r = binary.LittleEndian.Uint16(bts)
|
r = binary.BigEndian.Uint16(bts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *Stream) ReadUint32() (r uint32, err error) {
|
func (s *Stream) ReadUint32() (r uint32, err error) {
|
||||||
bts := make([]byte, 4)
|
bts := make([]byte, 4)
|
||||||
_, err = s.Read(bts)
|
_, err = s.Read(bts)
|
||||||
r = binary.LittleEndian.Uint32(bts)
|
r = binary.BigEndian.Uint32(bts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *Stream) ReadUint64() (r uint64, err error) {
|
func (s *Stream) ReadUint64() (r uint64, err error) {
|
||||||
bts := make([]byte, 8)
|
bts := make([]byte, 8)
|
||||||
_, err = s.Read(bts)
|
_, err = s.Read(bts)
|
||||||
r = binary.LittleEndian.Uint64(bts)
|
r = binary.BigEndian.Uint64(bts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) WriteUint16(i uint16) (err error) {
|
func (s *Stream) WriteUint16(i uint16) (err error) {
|
||||||
bts := make([]byte, 2)
|
bts := make([]byte, 2)
|
||||||
binary.LittleEndian.PutUint16(bts, i)
|
binary.BigEndian.PutUint16(bts, i)
|
||||||
_, err = s.Write(bts)
|
_, err = s.Write(bts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *Stream) WriteUint32(i uint32) (err error) {
|
func (s *Stream) WriteUint32(i uint32) (err error) {
|
||||||
bts := make([]byte, 4)
|
bts := make([]byte, 4)
|
||||||
binary.LittleEndian.PutUint32(bts, i)
|
binary.BigEndian.PutUint32(bts, i)
|
||||||
_, err = s.Write(bts)
|
_, err = s.Write(bts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *Stream) WriteUint64(i uint64) (err error) {
|
func (s *Stream) WriteUint64(i uint64) (err error) {
|
||||||
bts := make([]byte, 8)
|
bts := make([]byte, 8)
|
||||||
binary.LittleEndian.PutUint64(bts, i)
|
binary.BigEndian.PutUint64(bts, i)
|
||||||
_, err = s.Write(bts)
|
_, err = s.Write(bts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (stream *Stream) WriteLenPrefixedString(s string) (err error) {
|
||||||
|
err = stream.WriteByte(uint8(len(s)))
|
||||||
|
_, err = stream.WriteString(s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stream *Stream) WriteMapping(m map[string]string) (err error) {
|
||||||
|
buf := NewStream(make([]byte, 0))
|
||||||
|
keys := make([]string, len(m))
|
||||||
|
for k := range m {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
for _, key := range keys {
|
||||||
|
if key == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf.WriteLenPrefixedString(key)
|
||||||
|
buf.WriteByte(byte('='))
|
||||||
|
buf.WriteLenPrefixedString(m[key])
|
||||||
|
buf.WriteByte(byte(';'))
|
||||||
|
}
|
||||||
|
err = stream.WriteUint16(uint16(buf.Len()))
|
||||||
|
_, err = stream.Write(buf.Bytes())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Stream) loadFile(f *os.File) (err error) {
|
func (s *Stream) loadFile(f *os.File) (err error) {
|
||||||
_, err = f.Read(s.Bytes())
|
_, err = f.Read(s.Bytes())
|
||||||
return
|
return
|
||||||
|
2
tcp.go
2
tcp.go
@ -21,7 +21,7 @@ const (
|
|||||||
var CAFile = "/etc/ssl/certs/ca-certificates.crt"
|
var CAFile = "/etc/ssl/certs/ca-certificates.crt"
|
||||||
var defaultRouterAddress = "127.0.0.1:7654"
|
var defaultRouterAddress = "127.0.0.1:7654"
|
||||||
|
|
||||||
const USE_TLS = true
|
const USE_TLS = false
|
||||||
|
|
||||||
func (tcp *Tcp) Init() (err error) {
|
func (tcp *Tcp) Init() (err error) {
|
||||||
tcp.address, err = net.ResolveTCPAddr("tcp", defaultRouterAddress)
|
tcp.address, err = net.ResolveTCPAddr("tcp", defaultRouterAddress)
|
||||||
|
Reference in New Issue
Block a user