diff --git a/MQTTSNGateway/GatewayTester/src/LGwProxy.cpp b/MQTTSNGateway/GatewayTester/src/LGwProxy.cpp index 4a8a283..728f896 100644 --- a/MQTTSNGateway/GatewayTester/src/LGwProxy.cpp +++ b/MQTTSNGateway/GatewayTester/src/LGwProxy.cpp @@ -202,14 +202,19 @@ int LGwProxy::getConnectResponce(void) _gwId = _mqttsnMsg[1]; #if defined(DTLS) || defined(DTLS6) - if (_network.sslConnect() < 0) + for (int i = 0; i < MQTTSN_RETRY_COUNT; i++) { - DISPLAY( - "\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce Can't connect the Gateway via SSL.\033[0m\033[0;37m\n\n"); - return 0; + if (_network.sslConnect() > 0) + { + _status = GW_CONNECTING; + DISPLAY( + "\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce Can't connect the Gateway via SSL.\033[0m\033[0;37m\n\n"); + break; + } } -#endif +#else _status = GW_CONNECTING; +#endif } else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ) { diff --git a/MQTTSNGateway/GatewayTester/src/LMqttsnClient.cpp b/MQTTSNGateway/GatewayTester/src/LMqttsnClient.cpp index 0126a3e..c27ee8a 100644 --- a/MQTTSNGateway/GatewayTester/src/LMqttsnClient.cpp +++ b/MQTTSNGateway/GatewayTester/src/LMqttsnClient.cpp @@ -52,15 +52,15 @@ int main(int argc, char** argv) printf("\n%s", PAHO_COPYRIGHT4); printf("\n%s", PAHO_COPYRIGHT0); #if defined(UDP) - printf(" UDP\n"); + printf("UDP ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo); #elif defined(UDP6) - printf(" UDP6\n"); -#elif defined(RFCOMM) - printf(" RFCOMM\n"); + printf("UDP6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo); #elif defined(DTLS) - printf(" DTLS\n"); + printf("DTLS ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo); #elif defined(DTLS6) - printf(" DTLS6\n"); + printf("DTLS6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo); +#elif defined(RFCOMM) + printf("RFCOMM ClientId:%s channel:%d\n", theNetcon.clientId, theNetcon.channel); #else printf("\n"); #endif diff --git a/MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp b/MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp index d861814..2d6f3f2 100644 --- a/MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp +++ b/MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp @@ -471,6 +471,7 @@ int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo) int reuse = 1; if (_ssl != 0) { + D_NWLOG("LDtlsPort::sslConnect SSL exists.\n"); SSL_shutdown(_ssl); SSL_free(_ssl); _sockfdSsl = 0; @@ -489,7 +490,7 @@ int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo) D_NWLOG("LDtlsPort::sslConnect Can't create a socket\n"); return -1; } - setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR || SO_REUSEPORT, &reuse, sizeof(reuse)); + setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); struct sockaddr_in addr; addr.sin_family = AF_INET; @@ -497,6 +498,8 @@ int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo) addr.sin_addr.s_addr = INADDR_ANY; if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0) { + ::close(_sockfdSsl); + _sockfdSsl = 0; D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n"); return -1; } @@ -514,6 +517,12 @@ int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo) SSL_set_bio(_ssl, cbio, cbio); D_NWLOG("LDtlsPort::sslConnect connect to %-15s:%-6u\n", inet_ntoa(dest.sin_addr), htons(dest.sin_port)); + + timeval timeout; + timeout.tv_sec = 5; + timeout.tv_usec = 0; + BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); + int stat = SSL_connect(_ssl); if (stat != 1) { @@ -522,6 +531,7 @@ int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo) } else { + rc = 1; D_NWLOG("SSL connected\n"); } return rc; diff --git a/MQTTSNGateway/gateway.conf b/MQTTSNGateway/gateway.conf index 77efab6..b3ad2a4 100644 --- a/MQTTSNGateway/gateway.conf +++ b/MQTTSNGateway/gateway.conf @@ -77,7 +77,6 @@ MulticastHops=1 DtlsCertsKey=/etc/ssl/certs/gateway.pem DtlsPrivKey=/etc/ssl/private/privkey.pem -DtlsSSLPortNo=10001 # # XBee diff --git a/MQTTSNGateway/src/MQTTSNGateway.h b/MQTTSNGateway/src/MQTTSNGateway.h index a2798ad..3bd9b1f 100644 --- a/MQTTSNGateway/src/MQTTSNGateway.h +++ b/MQTTSNGateway/src/MQTTSNGateway.h @@ -27,7 +27,7 @@ namespace MQTTSNGW /*================================= * Starting prompt ==================================*/ -#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway" +#define PAHO_COPYRIGHT0 " * " #define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse" #define PAHO_COPYRIGHT2 " * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)" #define PAHO_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI" diff --git a/MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp b/MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp index 407a0b7..77f23b5 100644 --- a/MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp +++ b/MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp @@ -405,8 +405,6 @@ int Connections::getSockClient(int index) void Connections::close(int index) { - _mutex.lock(); - int idx = index + POLL_SSL; _mutex.lock(); int sock = _pollfds[idx].fd; @@ -415,9 +413,9 @@ void Connections::close(int index) for (; idx < _numfds; idx++) { - _ssls[index] = _ssls[idx + 1]; - _pollfds[index] = _pollfds[idx + 1]; - _clientAddr[index] = _clientAddr[idx + 1]; + _ssls[idx] = _ssls[idx + 1]; + _pollfds[idx] = _pollfds[idx + 1]; + _clientAddr[idx] = _clientAddr[idx + 1]; if (_ssls[idx + 1] == 0) { @@ -434,7 +432,7 @@ void Connections::close(int index) } if (sock > 0) { - close(sock); + ::close(sock); } if (addr != nullptr) { @@ -498,9 +496,9 @@ int Connections::searchClient(SensorNetAddress *addr) read( ) is used by MQTTSNPacket::recv( ) ================================================================*/ -#define PACKET_CLIENTHELLO 10000 -#define PACKET_APPL 10001 -#define PACKET_OTHERS 10002 +#define DTLS_CLIENTHELLO 22 +#define DTLS_APPL 23 +#define DTLS_OTHERS 100 /* Certificate verification. Returns 1 if trusted, else 0 */ int verify_cert(int ok, X509_STORE_CTX *ctx); @@ -607,7 +605,7 @@ int SensorNetwork::read(uint8_t *buf, uint16_t bufLen) struct sockaddr_in6 s6; } client_addr; - // Ccheck sockets + // Check POLL_IN int cnt = _conns->poll(2000); // Timeout 2secs if (cnt == 0) { @@ -668,13 +666,9 @@ ListenClient_hello: return 0; } -// if (clientIndex != -1) -// { -// _conns->close(clientIndex); -// } - - // SSL Accept + // Handle client connection #ifndef DTLS6 + // DTLS over IPv4 int client_fd = socket(AF_INET, SOCK_DGRAM, 0); setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &optval, sizeof(optval)); // Bind to Dtls PortNo @@ -695,8 +689,7 @@ ListenClient_hello: BIO_set_fd(cbio, client_fd, BIO_NOCLOSE); BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &client_addr); - D_NWSTACK("Accept SSL\n"); - + // Finish handshake int ret = SSL_accept(ssl); if (ret <= 0) { @@ -708,17 +701,17 @@ ListenClient_hello: } else { - // add ssl & socket to Connections instance int index = _conns->addClientSSL(ssl, client_fd); // save SensorNetworkAddress of Client client.setIndex(index); _senderAddr = &client; - +#ifdef DEBUG_NW char clientaddrBuf[128]; client.sprint(clientaddrBuf); - WRITELOG("Client %s SSL Accepted. idx=%d\n", clientaddrBuf, index); + D_NWSTACK("Client %s SSL Accepted. idx=%d\n", clientaddrBuf, index); +#endif } _mutex.unlock(); } @@ -741,15 +734,21 @@ ListenClient_hello: if (dtls > 0) { - D_NWSTACK("DTLT type=%d\n", dtls); - if (dtls == PACKET_CLIENTHELLO) + if (dtls == DTLS_CLIENTHELLO) { + // Received packet is ClientHello #ifdef DEBUG_NW char clientaddrBuf[128]; client.sprint(clientaddrBuf); D_NWSTACK("Client %s SSL reconnect. idx=%d\n", clientaddrBuf, i); #endif + // Delete current connection. clientIndex = i; + D_NWSTACK("Close current connections\n"); + _mutex.unlock(); + _conns->close(clientIndex); // DEBUG + return 0; + sockListen = _conns->getSockClient(i); goto ListenClient_hello; } @@ -759,12 +758,13 @@ ListenClient_hello: int len = SSL_read_ex(ssl, (void*) buf, (size_t) bufLen, &recvlen); if (SSL_get_error(ssl, len) >= 0) { - _senderAddr = &client; - _senderAddr->setIndex(i); - +#ifdef DEBUG_NW char clientaddrBuf[128]; client.sprint(clientaddrBuf); D_NWSTACK("Client %s SSL Accepted. idx=%d\n", clientaddrBuf, i); +#endif + _senderAddr = &client; + _senderAddr->setIndex(i); } else { @@ -787,7 +787,6 @@ void SensorNetwork::initialize(void) char errmsg[256]; uint16_t multicastPortNo = 0; uint16_t unicastPortNo = 0; - uint16_t dtlsPortNo = 0; SensorNetAddress add; sockaddr_in6 soadd; @@ -815,12 +814,6 @@ void SensorNetwork::initialize(void) _description += ", Gateway PortNo:"; _description += param; } - if (theProcess->getParam("DtlsPortNo", param) == 0) - { - dtlsPortNo = atoi(param); - _description += ", SSL PortNo:"; - _description += param; - } if (theProcess->getParam("MulticastTTL", param) == 0) { ttl = atoi(param); @@ -850,12 +843,6 @@ void SensorNetwork::initialize(void) _description += ", Gateway PortNo:"; _description += param; } - if (theProcess->getParam("DtlsPortNo", param) == 0) - { - dtlsPortNo = atoi(param); - _description += ", SSL PortNo:"; - _description += param; - } if (theProcess->getParam("MulticastIPv6If", param) == 0) { interface = param; @@ -914,12 +901,12 @@ void SensorNetwork::initialize(void) /* Prepare UDP and UDP6 sockets for Multicasting and unicasting */ #ifndef DTLS6 - if (openV4(&ip, multicastPortNo, unicastPortNo, dtlsPortNo, ttl) < 0) + if (openV4(&ip, multicastPortNo, unicastPortNo, ttl) < 0) { throw EXCEPTION("Can't open a UDP4", errno); } #else - if (openV6(&ip6, &interface, multicastPortNo, unicastPortNo, dtlsPortNo, hops) < 0) + if (openV6(&ip6, &interface, multicastPortNo, unicastPortNo, hops) < 0) { throw EXCEPTION("Can't open a UDP6", errno); } @@ -936,7 +923,7 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void) return _senderAddr; } -int SensorNetwork::openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, uint16_t dtlsPortNo, uint32_t ttl) +int SensorNetwork::openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, uint32_t ttl) { int optval = 0; int rc = -1; @@ -961,23 +948,17 @@ int SensorNetwork::openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniP optval = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(uniPortNo); - addr.sin_addr.s_addr = INADDR_ANY; + _serverAddr4.sin_family = AF_INET; + _serverAddr4.sin_port = htons(uniPortNo); + _serverAddr4.sin_addr.s_addr = INADDR_ANY; - if (::bind(sock, (sockaddr*) &addr, sizeof(addr)) < 0) + if (::bind(sock, (sockaddr*) &_serverAddr4, sizeof(_serverAddr4)) < 0) { D_NWSTACK("can't bind unicast socket in UDP4_6Port::openV4 error %d %s\n", errno, strerror(errno)); return -1; } _conns->setSockUnicast(sock); - /*------ Set SSL socket address --------*/ - _serverAddr4.sin_family = AF_INET; - _serverAddr4.sin_port = htons(uniPortNo); - _serverAddr4.sin_addr.s_addr = INADDR_ANY; - /*------ Create Multicast socket --------*/ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) @@ -1032,8 +1013,7 @@ int SensorNetwork::openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniP return 0; } -int SensorNetwork::openV6(string *ipAddress, string *interface, uint16_t multiPortNo, uint16_t uniPortNo, uint16_t dtlsPortNo, - uint32_t hops) +int SensorNetwork::openV6(string *ipAddress, string *interface, uint16_t multiPortNo, uint16_t uniPortNo, uint32_t hops) { int optval = 0; int sock = 0; @@ -1048,7 +1028,7 @@ int SensorNetwork::openV6(string *ipAddress, string *interface, uint16_t multiPo } _multicastAddr->setPort(multiPortNo); - _unicastAddr->setPort(dtlsPortNo); + _unicastAddr->setPort(uniPortNo); if (_multicastAddr->setIpAddress(ipAddress) < 0) { @@ -1075,13 +1055,12 @@ int SensorNetwork::openV6(string *ipAddress, string *interface, uint16_t multiPo return -1; } - sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(uniPortNo); - addr.sin6_addr = in6addr_any; + memset(&_serverAddr6, 0, sizeof(_serverAddr6)); + _serverAddr6.sin6_family = AF_INET6; + _serverAddr6.sin6_port = htons(uniPortNo); + _serverAddr6.sin6_addr = in6addr_any; - if (::bind(sock, (sockaddr*) &addr, sizeof(addr)) < 0) + if (::bind(sock, (sockaddr*) &_serverAddr6, sizeof(_serverAddr6)) < 0) { D_NWSTACK("can't bind unicast socket in SensorNetwork::openV6 error %s\n", strerror(errno)); return -1; @@ -1097,27 +1076,6 @@ int SensorNetwork::openV6(string *ipAddress, string *interface, uint16_t multiPo #endif } - /*------ Set SSL socket address --------*/ - _serverAddr6.sin6_family = AF_INET6; - _serverAddr6.sin6_port = htons(uniPortNo); - _serverAddr6.sin6_addr = in6addr_any; - - if (::bind(sock, (sockaddr*) &_serverAddr6, sizeof(_serverAddr6)) < 0) - { - D_NWSTACK("can't bind listen socket in SensorNetwork::openV6 error %s\n", strerror(errno)); - return -1; - } - - if (interface->size() > 0) - { -#ifdef __APPLE__ - setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, interface->size()); -#else - setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface->c_str(), interface->size()); -#endif - } - - // Create Multicast socket sock = socket(AF_INET6, SOCK_DGRAM, 0); if (sock < 0) @@ -1245,7 +1203,7 @@ int SensorNetwork::getSenderAddress(int sock, SensorNetAddress *addr) sockaddr_in sender4 = { 0 }; socklen_t addrlen4 = sizeof(sender4); char buf[16]; - int rc = PACKET_OTHERS; + int rc = DTLS_OTHERS; len = ::recvfrom(sock, buf, 15, MSG_PEEK, (sockaddr*) &sender4, &addrlen4); @@ -1259,17 +1217,12 @@ int SensorNetwork::getSenderAddress(int sock, SensorNetAddress *addr) D_NWSTACK("SensorNetwork::getSenderAddress recved from %s:%d length = %d\n", inet_ntoa(sender4.sin_addr), ntohs(sender4.sin_port), len); -// if (len >= 13) + if (len >= 13) { - if (buf[0] == 22) + if (buf[0] == DTLS_CLIENTHELLO || buf[0] == DTLS_APPL) { - rc = PACKET_CLIENTHELLO; + rc = buf[0]; } - else if (buf[0] == 23) - { - rc = PACKET_APPL; - } - D_NWSTACK("getSenderAddress len=%d Packet type=%d\n", len, buf[0]); } return rc; diff --git a/MQTTSNGateway/src/linux/dtls/SensorNetwork.h b/MQTTSNGateway/src/linux/dtls/SensorNetwork.h index 8f8680c..d84d5a5 100644 --- a/MQTTSNGateway/src/linux/dtls/SensorNetwork.h +++ b/MQTTSNGateway/src/linux/dtls/SensorNetwork.h @@ -138,9 +138,8 @@ public: void close(); private: - int openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, uint16_t listenPortNo, uint32_t ttl); - int openV6(string *ipAddress, string *interface, uint16_t multiPortNo, uint16_t uniPortNo, uint16_t listenPortNo, - uint32_t hops); + int openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, uint32_t ttl); + int openV6(string *ipAddress, string *interface, uint16_t multiPortNo, uint16_t uniPortNo, uint32_t hops); int multicastRecv(uint8_t *buf, uint16_t len); int getSendClient(int index, SensorNetAddress *addr); int getSenderAddress(int sock, SensorNetAddress *addr);