diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | crypto.go | 94 | ||||
-rw-r--r-- | network.go | 88 | ||||
m--------- | salticidae | 0 | ||||
-rw-r--r-- | stream.go | 53 | ||||
-rw-r--r-- | test_msgnet/main.go | 12 | ||||
-rw-r--r-- | test_msgnet_tls/alice.pem | 83 | ||||
-rw-r--r-- | test_msgnet_tls/bob.pem | 83 | ||||
-rw-r--r-- | test_msgnet_tls/main.go | 171 | ||||
-rw-r--r-- | test_p2p_stress/main.go | 18 |
10 files changed, 568 insertions, 39 deletions
@@ -1,6 +1,6 @@ .PHONY: all clean -all: build/test_msgnet build/test_p2p_stress +all: build/test_msgnet build/test_p2p_stress build/test_msgnet_tls salticidae/libsalticidae.so: @@ -13,6 +13,9 @@ build: build/test_msgnet: salticidae/libsalticidae.so test_msgnet/main.go make -C salticidae/ go build -o $@ github.com/Determinant/salticidae-go/test_msgnet +build/test_msgnet_tls: salticidae/libsalticidae.so test_msgnet_tls/main.go + make -C salticidae/ + go build -o $@ github.com/Determinant/salticidae-go/test_msgnet_tls build/test_p2p_stress: salticidae/libsalticidae.so test_p2p_stress/main.go make -C salticidae/ go build -o $@ github.com/Determinant/salticidae-go/test_p2p_stress diff --git a/crypto.go b/crypto.go new file mode 100644 index 0000000..528be5c --- /dev/null +++ b/crypto.go @@ -0,0 +1,94 @@ +package salticidae + +// #include <stdlib.h> +// #include "salticidae/crypto.h" +import "C" +import "runtime" + +// The C pointer type for a X509 handle. +type CX509 = *C.x509_t +type x509 struct { inner CX509 } +// The handle for a X509 certificate. +type X509 = *x509 + +func NewX509FromPemFile(fname string, passwd *string, err *Error) X509 { + fname_c_str := C.CString(fname) + passwd_c_str := (*C.char)(nil) + if passwd != nil { + passwd_c_str = C.CString(*passwd) + } + res := &x509{ inner: C.x509_new_from_pem_file(fname_c_str, passwd_c_str, err) } + if res != nil { + runtime.SetFinalizer(res, func(self X509) { self.free() }) + } + C.free(rawptr_t(fname_c_str)) + if passwd_c_str != nil { + C.free(rawptr_t(passwd_c_str)) + } + return res +} + +func NewX509FromDer(der ByteArray, err *Error) X509 { + res := &x509{ inner: C.x509_new_from_der(der.inner, err) } + if res != nil { + runtime.SetFinalizer(res, func(self X509) { self.free() }) + } + return res +} + +func (self X509) free() { C.x509_free(self.inner) } +func (self X509) GetPubKey() PKey { + res := &pKey{ inner: C.x509_get_pubkey(self.inner) } + runtime.SetFinalizer(res, func(self PKey) { self.free() }) + return res +} + +func (self X509) GetDer() ByteArray { + res := &byteArray{ inner: C.x509_get_der(self.inner) } + runtime.SetFinalizer(res, func(self ByteArray) { self.free() }) + return res +} + +// The C pointer type for a PKey handle. +type CPKey = *C.pkey_t +type pKey struct { inner CPKey } +// The handle for an OpenSSL EVP_PKEY. +type PKey = *pKey + +func NewPrivKeyFromPemFile(fname string, passwd *string, err *Error) PKey { + fname_c_str := C.CString(fname) + passwd_c_str := (*C.char)(nil) + if passwd != nil { + passwd_c_str = C.CString(*passwd) + } + res := &pKey{ inner: C.pkey_new_privkey_from_pem_file(fname_c_str, passwd_c_str, err) } + if res != nil { + runtime.SetFinalizer(res, func(self PKey) { self.free() }) + } + C.free(rawptr_t(fname_c_str)) + if passwd_c_str != nil { + C.free(rawptr_t(passwd_c_str)) + } + return res +} + +func NewPrivKeyFromDer(der ByteArray, err *Error) PKey { + res := &pKey{ inner: C.pkey_new_privkey_from_der(der.inner, err) } + if res != nil { + runtime.SetFinalizer(res, func(self PKey) { self.free() }) + } + return res +} + +func (self PKey) free() { C.pkey_free(self.inner) } +func (self PKey) GetPubKeyDer() ByteArray { + res := &byteArray{ inner: C.pkey_get_pubkey_der(self.inner) } + runtime.SetFinalizer(res, func(self ByteArray) { self.free() }) + return res +} + +func (self PKey) GetPrivKeyDer() ByteArray { + res := &byteArray{ inner: C.pkey_get_privkey_der(self.inner) } + runtime.SetFinalizer(res, func(self ByteArray) { self.free() }) + return res +} @@ -1,5 +1,6 @@ package salticidae +// #include <stdlib.h> // #include "salticidae/network.h" import "C" import "runtime" @@ -59,6 +60,13 @@ func (self MsgNetworkConn) GetAddr() NetAddr { return NetAddrFromC(C.msgnetwork_conn_get_addr(self.inner)) } +// Get the certificate of the remote end of this connection. Use Copy() to make a +// copy of the certificate if you want to use the certificate object beyond the +// lifetime of the connection. +func (self MsgNetworkConn) GetPeerCert() X509 { + return &x509{ inner: C.msgnetwork_conn_get_peer_cert(self.inner) } +} + // Make a copy of the object. This is required if you want to keep the // connection passed as a callback parameter by other salticidae methods (such // like MsgNetwork/PeerNetwork). @@ -95,36 +103,76 @@ func (self MsgNetworkConfig) BurstSize(size int) { C.msgnetwork_config_burst_size(self.inner, C.size_t(size)) } -// Maximum backlogs (see POSIX TCP backlog). +// Set the maximum backlogs (see POSIX TCP backlog). func (self MsgNetworkConfig) MaxListenBacklog(backlog int) { C.msgnetwork_config_max_listen_backlog(self.inner, C.int(backlog)) } -// The timeout for connecting to the remote (in seconds). +// Set the timeout for connecting to the remote (in seconds). func (self MsgNetworkConfig) ConnServerTimeout(timeout float64) { C.msgnetwork_config_conn_server_timeout(self.inner, C.double(timeout)) } -// The size for an inbound data chunk (per read() syscall). +// Set the size for an inbound data chunk (per read() syscall). func (self MsgNetworkConfig) SegBuffSize(size int) { C.msgnetwork_config_seg_buff_size(self.inner, C.size_t(size)) } -// The number of worker threads. +// Set the number of worker threads. func (self MsgNetworkConfig) NWorker(nworker int) { C.msgnetwork_config_nworker(self.inner, C.size_t(nworker)) } -// The capacity of the send buffer. +// Set the capacity of the send buffer. func (self MsgNetworkConfig) QueueCapacity(capacity int) { C.msgnetwork_config_queue_capacity(self.inner, C.size_t(capacity)) } +// Specify whether to use SSL/TLS. When this flag is enabled, MsgNetwork uses +// TLSKey (or TLSKeyFile) or TLSCert (or TLSCertFile) to setup the underlying +// OpenSSL. +func (self MsgNetworkConfig) EnableTLS(enabled bool) { + C.msgnetwork_config_enable_tls(self.inner, C.bool(enabled)) +} + +// Load the TLS key from a file. The file should be an unencrypted PEM file. +// Use TLSKey() instead for more complex usage. +func (self MsgNetworkConfig) TLSKeyFile(fname string) { + c_str := C.CString(fname) + C.msgnetwork_config_tls_key_file(self.inner, c_str) + C.free(rawptr_t(c_str)) +} + +// Load the TLS certificate from a file. The file should be an unencrypted +// (X509) PEM file. Use TLSCert() instead for more complex usage. +func (self MsgNetworkConfig) TLSCertFile(fname string) { + c_str := C.CString(fname) + C.msgnetwork_config_tls_cert_file(self.inner, c_str) + C.free(rawptr_t(c_str)) +} + +// Use the given TLS key. This overrides TLSKeyFile(). pkey will be moved and +// kept by the library. Thus, no methods of msg involving the payload should be +// called afterwards. +func (self MsgNetworkConfig) TLSKeyByMove(pkey PKey) { + C.msgnetwork_config_tls_key_by_move(self.inner, pkey.inner) +} + +//// Load the TLS certificate from a file. The file should be an unencrypted +//// (X509) PEM file. Use TLSCert() instead for more complex usage. +//func (self MsgNetworkConfig) TLSCert(fname string) { +// c_str := C.CString(fname) +// C.msgnetwork_config_tls_cert(self.inner, c_str) +// C.free(rawptr_t(c_str)) +//} + // Create a message network handle which is attached to given event loop. -func NewMsgNetwork(ec EventContext, config MsgNetworkConfig) MsgNetwork { - res := MsgNetworkFromC(C.msgnetwork_new(ec.inner, config.inner)) - ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self MsgNetwork) { self.free() }) +func NewMsgNetwork(ec EventContext, config MsgNetworkConfig, err *Error) MsgNetwork { + res := MsgNetworkFromC(C.msgnetwork_new(ec.inner, config.inner, err)) + if res != nil { + ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self MsgNetwork) { self.free() }) + } return res } @@ -155,9 +203,11 @@ func (self MsgNetwork) SendMsgDeferredByMove(msg Msg, conn MsgNetworkConn) { // Try to connect to a remote address. The connection handle is returned. The // returned connection handle could be kept in your program. -func (self MsgNetwork) Connect(addr NetAddr, err *Error) MsgNetworkConn { - res := MsgNetworkConnFromC(C.msgnetwork_connect(self.inner, addr.inner, err)) - runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.free() }) +func (self MsgNetwork) Connect(addr NetAddr, blocking bool, err *Error) MsgNetworkConn { + res := MsgNetworkConnFromC(C.msgnetwork_connect(self.inner, addr.inner, C.bool(blocking), err)) + if res != nil { + runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.free() }) + } return res } @@ -269,10 +319,12 @@ func (self PeerNetworkConfig) AsMsgNetworkConfig() MsgNetworkConfig { } // Create a peer-to-peer message network handle. -func NewPeerNetwork(ec EventContext, config PeerNetworkConfig) PeerNetwork { - res := PeerNetworkFromC(C.peernetwork_new(ec.inner, config.inner)) - ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self PeerNetwork) { self.free() }) +func NewPeerNetwork(ec EventContext, config PeerNetworkConfig, err *Error) PeerNetwork { + res := PeerNetworkFromC(C.peernetwork_new(ec.inner, config.inner, err)) + if res != nil { + ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self PeerNetwork) { self.free() }) + } return res } @@ -290,7 +342,9 @@ func (self PeerNetwork) HasPeer(paddr NetAddr) bool { return bool(C.peernetwork_ // returned connection handle could be kept in your program. func (self PeerNetwork) GetPeerConn(paddr NetAddr, err *Error) PeerNetworkConn { res := PeerNetworkConnFromC(C.peernetwork_get_peer_conn(self.inner, paddr.inner, err)) - runtime.SetFinalizer(res, func(self PeerNetworkConn) { self.free() }) + if res != nil { + runtime.SetFinalizer(res, func(self PeerNetworkConn) { self.free() }) + } return res } diff --git a/salticidae b/salticidae -Subproject ff904b23147e72db4f7f77f8269242d9a5a0859 +Subproject da9410b41cf56340fd4a3e5148df704c9c0e139 @@ -30,6 +30,14 @@ func NewByteArrayMovedFromDataStream(src DataStream) ByteArray { return res } +func NewByteArrayFromHex(hex string) ByteArray { + c_str := C.CString(hex) + res := &byteArray{ inner: C.bytearray_new_from_hex(c_str) } + C.free(rawptr_t(c_str)) + runtime.SetFinalizer(res, func(self ByteArray) { self.free() }) + return res +} + // The C pointer to a DataStream object. type CDataStream = *C.datastream_t type dataStream struct { @@ -47,11 +55,17 @@ func DataStreamFromC(ptr CDataStream) DataStream { } } +func dataStreamSetFinalizer(res DataStream) DataStream { + if res != nil { + runtime.SetFinalizer(res, func(self DataStream) { self.free() }) + } + return res +} + // Create an empty DataStream. func NewDataStream() DataStream { res := DataStreamFromC(C.datastream_new()) - runtime.SetFinalizer(res, func(self DataStream) { self.free() }) - return res + return dataStreamSetFinalizer(res) } // Create a DataStream with data copied from bytes. @@ -63,7 +77,20 @@ func NewDataStreamFromBytes(bytes []byte) (res DataStream) { } else { res = DataStreamFromC(C.datastream_new()) } - runtime.SetFinalizer(res, func(self DataStream) { self.free() }) + return dataStreamSetFinalizer(res) +} + +// Create a DataStream with content moved from a ByteArray. +func NewDataStreamMovedFromByteArray(bytes ByteArray) (res DataStream) { + res = DataStreamFromC(C.datastream_new_moved_from_bytearray(bytes.inner)) + dataStreamSetFinalizer(res) + return +} + +// Create a DataStream with content copied from a ByteArray. +func NewDataStreamFromByteArray(bytes ByteArray) (res DataStream) { + res = DataStreamFromC(C.datastream_new_from_bytearray(bytes.inner)) + dataStreamSetFinalizer(res) return } @@ -75,8 +102,7 @@ func (self DataStream) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr) // Make a copy of the object. func (self DataStream) Copy() DataStream { res := DataStreamFromC(C.datastream_copy(self.inner)) - runtime.SetFinalizer(res, func(self DataStream) { self.free() }) - return res + return dataStreamSetFinalizer(res) } // TODO: datastream_data @@ -166,7 +192,17 @@ type UInt256 = *uint256 // Create a 256-bit integer. func NewUInt256() UInt256 { res := &uint256{ inner: C.uint256_new() } - runtime.SetFinalizer(res, func(self UInt256) { self.free() }) + if res != nil { + runtime.SetFinalizer(res, func(self UInt256) { self.free() }) + } + return res +} + +func NewUInt256FromByteArray(bytes ByteArray) UInt256 { + res := &uint256{ inner: C.uint256_new_from_bytearray(bytes.inner) } + if res != nil { + runtime.SetFinalizer(res, func(self UInt256) { self.free() }) + } return res } @@ -191,6 +227,11 @@ func (self DataStream) GetHash() UInt256 { return res } +// Get the Sha256 hash of the given ByteArray content. +func (self ByteArray) GetHash() UInt256 { + return NewDataStreamFromByteArray(self).GetHash() +} + // Get hexadicemal string representation of the given DataStream content // (without consuming the stream). func (self DataStream) GetHex() string { diff --git a/test_msgnet/main.go b/test_msgnet/main.go index 66d7287..065b773 100644 --- a/test_msgnet/main.go +++ b/test_msgnet/main.go @@ -113,7 +113,7 @@ func connHandler(_conn *C.struct_msgnetwork_conn_t, connected C.bool, _ unsafe.P } else { fmt.Printf("[%s] Disconnected, retrying.\n", name) err := salticidae.NewError() - net.Connect(conn.GetAddr(), &err) + net.Connect(conn.GetAddr(), false, &err) } } @@ -127,20 +127,18 @@ func errorHandler(_err *C.struct_SalticidaeCError, fatal C.bool, _ unsafe.Pointe func genMyNet(ec salticidae.EventContext, name string, myAddr salticidae.NetAddr, otherAddr salticidae.NetAddr) MyNet { + err := salticidae.NewError() netconfig := salticidae.NewMsgNetworkConfig() - n := MyNet { - net: salticidae.NewMsgNetwork(ec, netconfig), - name: name, - } + net := salticidae.NewMsgNetwork(ec, netconfig, &err); checkError(&err) + n := MyNet { net: net, name: name } n.net.RegHandler(MSG_OPCODE_HELLO, salticidae.MsgNetworkMsgCallback(C.onReceiveHello), nil) n.net.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), nil) n.net.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), nil) n.net.RegErrorHandler(salticidae.MsgNetworkErrorCallback(C.errorHandler), nil) n.net.Start() - err := salticidae.NewError() n.net.Listen(myAddr, &err); checkError(&err) - n.net.Connect(otherAddr, &err); checkError(&err) + n.net.Connect(otherAddr, false, &err); checkError(&err) return n } diff --git a/test_msgnet_tls/alice.pem b/test_msgnet_tls/alice.pem new file mode 100644 index 0000000..6efe00f --- /dev/null +++ b/test_msgnet_tls/alice.pem @@ -0,0 +1,83 @@ +-----BEGIN PRIVATE KEY----- +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 +THSAjGzVtLewAwo0qkl141+539oWDw== +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIUFitZjQ11n2jQiX7GPH5RtQorw1gwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA2MjEwMjU5MThaFw0xOTA3 +MjEwMjU5MThaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDZFKh7iaGPvfvh6qYrQN0Twq9nnpukjHYG+Zjuq/6T +/JgMVezRXDA6e6nPH1va6tRzi+MsJ4Ues7alm6ddnxNgUOI2ROl9G6Gmx68Y75BG +R1vKMUw7ujz8flaXYFO5mASSbE87pI5F/Hm/7k0Ke47rEE6Ke1iARcv0pW9loFT8 +y00NBXg/IQSUSb1riDXOHVK3fY8xHN5w5/pXwaLNpqTByKOPcBCQhJBWh83n09vY +ysDEFzJC3QUvNWNCUttbgexqY8hJO4jP5SD+DmSiPw+6gNiyJdPdvmY+VgDXtd1d +1ApihkiLlSa3EhQAMbS6ajM3NuwS5ikpnZ5cNDvGuBS4XQx8R+X93Q1xyeclNVkd +2bFj0rdjfIxyurl8Nziq2/NM/AVCtBXCdGDO8aFnivPlA/FtfKbfuhhNVWts0ODL +HR8dd5AZpGjtgZBJiXW97XQOeG0hDp8WwBNns0UFEewkMOMX1ByA7ZWeOSiJHe+l +cmVEs7RaUcEhs5OK/sgAo3Ig+4mO0z6VH8gp/WxP8ce+5xA6cTao2wJn3N1ux4Oq +4fqZXR3rPh7IcEkHCyBKL1jxiUmPlIXvmED2PzyWSxyoDTm9w1TBLamD0Usdd1P9 +9Rclgri3erhr6kT4YnWV0WMqrsP3ZserGTkm3Gsi6s6X9sTdu3Yi/P4N2nvRPZOB +0wIDAQABo1MwUTAdBgNVHQ4EFgQU/dKIin9ueRiA5tqyKmD9w0g4TVAwHwYDVR0j +BBgwFoAU/dKIin9ueRiA5tqyKmD9w0g4TVAwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEANGM+fUoMyYkbdSRhocIJ/WZo3fb96289SsDmVrwQyazn +4O0MPlgz2y6RXQf0rDr0xQ9jj0hv6UEpVcaUdVrgRYJzW7YviN6x/urqsJNtVUJb +t6xF+IS+ibT4OulJlQyJlYX0opQQzVQGgKW8jwetPdBNVtoH5j7AZaCYhlOnOz6r +JpA07sI3fSuVb0NjDuHPgzR139r1IlpBLP/OmkG4LH19tP9Ad78Dehl7K/TA2Rwr +i3wZk77Wvbz7u5ZMqHxxdS4opUWYnpyApeudFNiXRS1ls7R7lJZE3+9OKT9EcVd+ +GwJzWJVvtqXotOqfjYVWj4EFebH9MAdb34l7F1OgyKQ3Nmw7BzuQ7XdoKn5/DL5Q +b9PeRSnWpzgaSEj341GlZL1fs2IY+KYxHB3XeptDgAIPRP7+Q39/FRKGyuxTX2l/ +7a1jIN7xRF15mqpEzbICch+RXv9hMMHqMr7H8psQXKbQTFZkZatwPneho1T6E58o +JLjQME1bOMR++forya9rZZCl11io3OitFbzewBmMdPCcA5fJS13MW7jJ6x41L/lw +d6qBH3eG2paTc+aVRIaJhhwR/ommpILiU8X/kXq6StLGB1YD5Jm0KvREyME/o0U7 +sT/91lpmMtRtwqaIOTZbUn1vEmS3aHZKS5q+Vs/eYZm3exF/L+Bzy40vn9wxU0I= +-----END CERTIFICATE----- diff --git a/test_msgnet_tls/bob.pem b/test_msgnet_tls/bob.pem new file mode 100644 index 0000000..8f8afcc --- /dev/null +++ b/test_msgnet_tls/bob.pem @@ -0,0 +1,83 @@ +-----BEGIN PRIVATE KEY----- +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 +HHHAbLi3XqeKbfEWQL0METvL2SBhlAA= +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIUTfDNmCzLkU+iC/fDlcG2P7Z2iXMwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA2MjEwMzI4MjVaFw0xOTA3 +MjEwMzI4MjVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDfnQZzGUUL/pQN4g3U7fI6DHsvy6AztawB89m5nbXO +FA9YGiFpzTGByZ6xAJRRnoz5HtbwjbkAYiUcG+sbGF7RSDAchAOC0EYKK8YQd/kG +YzD/mIFzyzRSk1Kpc/SSIDKmuO9iFWfNSOqIzfkE8M0hV2vwbZ/tZfi/ToP8nH7Z +llpa6E2SQhQRDsojMPSyMkP2uYvBL9CjRbZzgsVPaHItfQkP5c3+oNTgTNbv6HwI +98h2xXYIAL8MKg7B/xj8BXczf9KGhWNCcRn/ci+wME08e9+FZUH1JYIQgRAu1Q7e +Gp5JhGl4Tls9/YTH7FFVTbpZZaoRj95mMKVTzrXOlSdiQcAuAnfKvSm733tK9VL/ +JFFWfrscWaWONKUEogW988hQ7xg+0VQ5BBd3/S6yT/0fUjVLwM2hoJguQFtNkuBd +eT7Bp+cVO0uI+g1sPFV3+0XC0Z5MytwedS+0BSq3KBheQ/FBTDZ8wHk9H1fPbNX4 +va1dj4bw2D5vuQL1gYTSIV5yUARakt78qH9s9+gkUfJGjtiI8FBbF5p4AhbBpKD0 +dhy7Pbkzw3zaWGCxOATUXTxiB9qgLwjancaxx1XegMB8ZhjoNjUzX1iBh11Sejmq +v0Sv1PLdAgzxlIVfaIkf/wyQwX/GGbqN7ne/J+lk2DIe3ynxn6FmIdvtfrFbbCGp +xQIDAQABo1MwUTAdBgNVHQ4EFgQUX/c1vXnm9tkgHTZndvy5PzgoupIwHwYDVR0j +BBgwFoAUX/c1vXnm9tkgHTZndvy5PzgoupIwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAhUik2ITFpR8s571Ds1jNr/kvM3j1dwG1qCIN7GuE4XuV +0vS6W2FCeBfB/WPvf9HCQFNR9l9npPI27BJA1J853ywlzj6WyfiA9Fv517aOMCs+ +PaySYcM23Hyyi3sSAdNYWlnQg0JUI1kdIMb3dileleDz2Eh6IxIugpvZ3s+7bOiN +H2FkOrzMq/w8aJ+kUk8IyGToxtBVvmjbINRK0bgANHJOifzp5ASYqvEZAcggot1n +pvVToqGDxtuuVd4qX8/DXPCVooOJ0RAcGZ44+hXfN1T5icPmnqMLuoPx9qiUZO+T +PIHg2DknmZSEunyy4LO5SiEsQVBzL3v8voYIqoobBuB5A2wyG9BXT5c3OM2rxDkX +UfXjxMdiGu3+iOaGE0KePXVY6oy3vgbmaowh5n8ZN6sN8aJPty3ZdpYpRPXKJsft +DtTH5sITHiisU2+rV2kJMKyASrxPWJAxkelahbUacOzid83TG+uqBCUJY0YPLRsF +TCvZ/jqJ8PNXFiZWnfyVkH3qFNjzQ595xMLe5fE5p/pCEV7aqHI0Ds9VYy82IJAT +070s/gtoLj5DussTetb9rh7Nt9ndJ5T7vvL9aeSmulRs2Z1j6u7rTvo4TjAbLbxx +bCR8r/T+5G0F9qLC6o4C2kFfZSiogxtM8n6tCJzzpWnpMwVad0a+GuH4tdNFsQA= +-----END CERTIFICATE----- diff --git a/test_msgnet_tls/main.go b/test_msgnet_tls/main.go new file mode 100644 index 0000000..c45cfdf --- /dev/null +++ b/test_msgnet_tls/main.go @@ -0,0 +1,171 @@ +package main + +// #cgo CFLAGS: -I${SRCDIR}/../salticidae/include/ +// #include <stdlib.h> +// #include "salticidae/network.h" +// void onTerm(int sig, void *); +// void onReceiveHello(msg_t *, msgnetwork_conn_t *, void *); +// void onReceiveAck(msg_t *, msgnetwork_conn_t *, void *); +// bool connHandler(msgnetwork_conn_t *, bool, void *); +// void errorHandler(SalticidaeCError *, bool, void *); +import "C" + +import ( + "encoding/binary" + "os" + "fmt" + "unsafe" + "github.com/Determinant/salticidae-go" +) + +const ( + MSG_OPCODE_HELLO salticidae.Opcode = iota + MSG_OPCODE_ACK +) + +func msgHelloSerialize(name string, text string) salticidae.Msg { + serialized := salticidae.NewDataStream() + t := make([]byte, 4) + binary.LittleEndian.PutUint32(t, uint32(len(name))) + serialized.PutData(t) + serialized.PutData([]byte(name)) + serialized.PutData([]byte(text)) + return salticidae.NewMsgMovedFromByteArray( + MSG_OPCODE_HELLO, salticidae.NewByteArrayMovedFromDataStream(serialized)) +} + +func msgHelloUnserialize(msg salticidae.Msg) (name string, text string) { + p := msg.GetPayloadByMove() + t := p.GetDataInPlace(4); length := binary.LittleEndian.Uint32(t.Get()); t.Release() + t = p.GetDataInPlace(int(length)); name = string(t.Get()); t.Release() + t = p.GetDataInPlace(p.Size()); text = string(t.Get()); t.Release() + return +} + +func msgAckSerialize() salticidae.Msg { + return salticidae.NewMsgMovedFromByteArray(MSG_OPCODE_ACK, salticidae.NewByteArray()) +} + +func checkError(err *salticidae.Error) { + if err.GetCode() != 0 { + fmt.Printf("error during a sync call: %s\n", salticidae.StrError(err.GetCode())) + os.Exit(1) + } +} + +type MyNet struct { + net salticidae.MsgNetwork + name string + peerCert salticidae.UInt256 + cname *C.char +} + +var ( + alice, bob MyNet + ec salticidae.EventContext +) + +//export onTerm +func onTerm(_ C.int, _ unsafe.Pointer) { + ec.Stop() +} + +//export onReceiveHello +func onReceiveHello(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, userdata unsafe.Pointer) { + msg := salticidae.MsgFromC(salticidae.CMsg(_msg)) + conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn)) + net := conn.GetNet() + name, text := msgHelloUnserialize(msg) + myName := C.GoString((*C.char)(userdata)) + fmt.Printf("[%s] %s says %s\n", myName, name, text) + ack := msgAckSerialize() + net.SendMsg(ack, conn) +} + +//export onReceiveAck +func onReceiveAck(_ *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, userdata unsafe.Pointer) { + myName := C.GoString((*C.char)(userdata)) + fmt.Printf("[%s] the peer knows\n", myName) +} + +//export connHandler +func connHandler(_conn *C.struct_msgnetwork_conn_t, connected C.bool, userdata unsafe.Pointer) C.bool { + conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn)) + net := conn.GetNet() + myName := C.GoString((*C.char)(userdata)) + n := alice + if myName == "bob" { n = bob } + res := true + if connected { + certHash := conn.GetPeerCert().GetDer().GetHash() + res = certHash.IsEq(n.peerCert) + if conn.GetMode() == salticidae.CONN_MODE_ACTIVE { + fmt.Printf("[%s] Connected, sending hello.\n", myName) + hello := msgHelloSerialize(myName, "Hello there!") + n.net.SendMsg(hello, conn) + } else { + status := "fail" + if res { status = "ok" } + fmt.Printf("[%s] Accepted, waiting for greetings.\n" + + "The peer certificate footprint is %s (%s)\n", + myName, certHash.GetHex(), status) + } + } else { + fmt.Printf("[%s] Disconnected, retrying.\n", myName) + err := salticidae.NewError() + net.Connect(conn.GetAddr(), false, &err) + } + return C.bool(res) +} + +//export errorHandler +func errorHandler(_err *C.struct_SalticidaeCError, fatal C.bool, _ unsafe.Pointer) { + err := (*salticidae.Error)(unsafe.Pointer(_err)) + s := "recoverable" + if fatal { s = "fatal" } + fmt.Printf("Captured %s error during an async call: %s\n", s, salticidae.StrError(err.GetCode())) +} + +func genMyNet(ec salticidae.EventContext, + name string, peerCert string, + myAddr salticidae.NetAddr, otherAddr salticidae.NetAddr) MyNet { + err := salticidae.NewError() + netconfig := salticidae.NewMsgNetworkConfig() + netconfig.EnableTLS(true) + netconfig.TLSKeyFile(name + ".pem") + netconfig.TLSCertFile(name + ".pem") + net := salticidae.NewMsgNetwork(ec, netconfig, &err); checkError(&err) + _peerCert := salticidae.NewUInt256FromByteArray(salticidae.NewByteArrayFromHex(peerCert)) + cname := C.CString(name) + n := MyNet { net: net, name: name, peerCert: _peerCert, cname: cname } + n.net.RegHandler(MSG_OPCODE_HELLO, salticidae.MsgNetworkMsgCallback(C.onReceiveHello), unsafe.Pointer(cname)) + n.net.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), unsafe.Pointer(cname)) + n.net.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), unsafe.Pointer(cname)) + n.net.RegErrorHandler(salticidae.MsgNetworkErrorCallback(C.errorHandler), unsafe.Pointer(cname)) + + n.net.Start() + n.net.Listen(myAddr, &err); checkError(&err) + n.net.Connect(otherAddr, false, &err); checkError(&err) + return n +} + +func main() { + ec = salticidae.NewEventContext() + + aliceAddr := salticidae.NewAddrFromIPPortString("127.0.0.1:12345") + bobAddr := salticidae.NewAddrFromIPPortString("127.0.0.1:12346") + + alice = genMyNet(ec, "alice", "ed5a9a8c7429dcb235a88244bc69d43d16b35008ce49736b27aaa3042a674043", aliceAddr, bobAddr) + bob = genMyNet(ec, "bob", "ef3bea4e72f4d0e85da7643545312e2ff6dded5e176560bdffb1e53b1cef4896", bobAddr, aliceAddr) + + ev_int := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(C.onTerm), nil) + ev_int.Add(salticidae.SIGINT) + ev_term := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(C.onTerm), nil) + ev_term.Add(salticidae.SIGTERM) + + ec.Dispatch() + alice.net.Stop() + bob.net.Stop() + C.free(unsafe.Pointer(alice.cname)) + C.free(unsafe.Pointer(bob.cname)) +} diff --git a/test_p2p_stress/main.go b/test_p2p_stress/main.go index 9e0757f..69f9d6c 100644 --- a/test_p2p_stress/main.go +++ b/test_p2p_stress/main.go @@ -240,6 +240,7 @@ func onTerm(_ C.int, _ unsafe.Pointer) { func main() { ec = salticidae.NewEventContext() + err := salticidae.NewError() var addrs []salticidae.NetAddr for i := 0; i < 5; i++ { @@ -256,22 +257,23 @@ func main() { ids = make([](*C.int), len(addrs)) for i, addr := range addrs { ec := salticidae.NewEventContext() + net := salticidae.NewPeerNetwork(ec, netconfig, &err); checkError(&err) apps[i] = AppContext { addr: addr, ec: ec, - net: salticidae.NewPeerNetwork(ec, netconfig), + net: net, tcall: salticidae.NewThreadCall(ec), tc: make(map[uint64] *TestContext), } ids[i] = (*C.int)(C.malloc(C.sizeof_int)) *ids[i] = C.int(i) _i := unsafe.Pointer(ids[i]) - net := apps[i].net.AsMsgNetwork() - net.RegHandler(MSG_OPCODE_RAND, salticidae.MsgNetworkMsgCallback(C.onReceiveRand), _i) - net.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), _i) - net.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), _i) - net.RegErrorHandler(salticidae.MsgNetworkErrorCallback(C.errorHandler), _i) - net.Start() + mnet := net.AsMsgNetwork() + mnet.RegHandler(MSG_OPCODE_RAND, salticidae.MsgNetworkMsgCallback(C.onReceiveRand), _i) + mnet.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), _i) + mnet.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), _i) + mnet.RegErrorHandler(salticidae.MsgNetworkErrorCallback(C.errorHandler), _i) + mnet.Start() } threads.Add(len(apps)) @@ -280,7 +282,7 @@ func main() { go func() { err := salticidae.NewError() a := &apps[app_id] - a.net.Listen(a.addr, &err) + a.net.Listen(a.addr, &err); checkError(&err) for _, addr := range addrs { if !addr.IsEq(a.addr) { a.net.AddPeer(addr) |