Browse Source

refactor: UA_Connection_init as memset-zero; small cleanups

Julius Pfrommer 8 years ago
parent
commit
b3aaa1ceea
5 changed files with 49 additions and 85 deletions
  1. 0 1
      include/ua_connection.h
  2. 19 28
      plugins/ua_network_tcp.c
  3. 3 13
      src/client/ua_client.c
  4. 3 18
      src/ua_connection.c
  5. 24 25
      src/ua_securechannel.c

+ 0 - 1
include/ua_connection.h

@@ -114,7 +114,6 @@ struct UA_Connection {
     void (*close)(UA_Connection *connection);
 };
 
-void UA_EXPORT UA_Connection_init(UA_Connection *connection);
 void UA_EXPORT UA_Connection_deleteMembers(UA_Connection *connection);
 
 /**

+ 19 - 28
plugins/ua_network_tcp.c

@@ -125,8 +125,7 @@ socket_recv(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeou
 # ifdef __APPLE__
         struct timeval tmptv = {(long int)(timeout_usec / 1000000), timeout_usec % 1000000};
 # else
-        struct timeval tmptv = {(long int)(timeout_usec / 1000000),
-                                (long int)(timeout_usec % 1000000)};
+        struct timeval tmptv = {(long int)(timeout_usec / 1000000), (long int)(timeout_usec % 1000000)};
 # endif
         int ret = setsockopt(connection->sockfd, SOL_SOCKET, SO_RCVTIMEO,
                              (const char *)&tmptv, sizeof(struct timeval));
@@ -143,23 +142,16 @@ socket_recv(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeou
     }
 
 #ifdef __CYGWIN__
-    /* WORKAROUND for https://cygwin.com/ml/cygwin/2013-07/msg00107.html */
+    /* Workaround for https://cygwin.com/ml/cygwin/2013-07/msg00107.html */
     ssize_t ret;
-
-    if (timeout > 0) {
+    if(timeout > 0) {
         fd_set fdset;
+        FD_ZERO(&fdset);
+        UA_fd_set(connection->sockfd, &fdset);
         UA_UInt32 timeout_usec = timeout * 1000;
-    #ifdef __APPLE__
-        struct timeval tmptv = {(long int)(timeout_usec / 1000000), timeout_usec % 1000000};
-    #else
         struct timeval tmptv = {(long int)(timeout_usec / 1000000),
                                 (long int)(timeout_usec % 1000000)};
-    #endif
-        UA_Int32 retval;
-
-        FD_ZERO(&fdset);
-        UA_fd_set(connection->sockfd, &fdset);
-        retval = select(connection->sockfd+1, &fdset, NULL, NULL, &tmptv);
+        int retval = select(connection->sockfd+1, &fdset, NULL, NULL, &tmptv);
         if(retval && UA_fd_isset(connection->sockfd, &fdset)) {
             ret = recv(connection->sockfd, (char*)response->data,
                        connection->localConf.recvBufferSize, 0);
@@ -183,14 +175,12 @@ socket_recv(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeou
     } else if(ret < 0) {
         UA_ByteString_deleteMembers(response);
 #ifdef _WIN32
-        const int last_error = WSAGetLastError();
-        #define TEST_RETRY (last_error == WSAEINTR || (timeout > 0) ? \
-                            0 : (last_error == WSAEWOULDBLOCK))
-#else
-        #define TEST_RETRY (errno == EINTR || (timeout > 0) ? \
-                            0 : (errno == EAGAIN || errno == EWOULDBLOCK))
+        const int errno = WSAGetLastError();
+        #define EINTR WSAEINTR
+        #define EWOULDBLOCK WSAEWOULDBLOCK
 #endif
-        if (TEST_RETRY)
+        if(errno == EINTR || (timeout > 0) ?
+           false : (errno == EAGAIN || errno == EWOULDBLOCK))
             return UA_STATUSCODE_GOOD; /* retry */
         else {
             socket_close(connection);
@@ -345,10 +335,11 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd) {
                        "Connection %i | New connection over TCP, "
                        "getpeername failed with errno %i", newsockfd, errno);
     }
-    UA_Connection_init(c);
+    memset(c, 0, sizeof(UA_Connection));
     c->sockfd = newsockfd;
     c->handle = layer;
     c->localConf = layer->conf;
+    c->remoteConf = layer->conf;
     c->send = socket_write;
     c->close = ServerNetworkLayerTCP_closeConnection;
     c->getSendBuffer = ServerNetworkLayerGetSendBuffer;
@@ -622,9 +613,10 @@ UA_ClientConnectionTCP(UA_ConnectionConfig localConf, const char *endpointUrl,
 #endif
 
     UA_Connection connection;
-    UA_Connection_init(&connection);
+    memset(&connection, 0, sizeof(UA_Connection));
+    connection.state = UA_CONNECTION_OPENING;
     connection.localConf = localConf;
-
+    connection.remoteConf = localConf;
     connection.send = socket_write;
     connection.recv = socket_recv;
     connection.close = ClientNetworkLayerClose;
@@ -658,11 +650,11 @@ UA_ClientConnectionTCP(UA_ConnectionConfig localConf, const char *endpointUrl,
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_family = AF_INET;
     char portStr[6];
-    #ifndef _MSC_VER
+#ifndef _MSC_VER
     snprintf(portStr, 6, "%d", port);
-    #else
+#else
     _snprintf_s(portStr, 6, _TRUNCATE, "%d", port);
-    #endif
+#endif
     int error = getaddrinfo(hostname, portStr, &hints, &server);
     if(error != 0 || !server) {
         UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
@@ -684,7 +676,6 @@ UA_ClientConnectionTCP(UA_ConnectionConfig localConf, const char *endpointUrl,
     }
 
     /* Connect to the server */
-    connection.state = UA_CONNECTION_OPENING;
     connection.sockfd = (UA_Int32)clientsockfd; /* cast for win32 */
     error = connect(clientsockfd, server->ai_addr, WIN32_INT server->ai_addrlen);
     freeaddrinfo(server);

+ 3 - 13
src/client/ua_client.c

@@ -35,27 +35,17 @@ Connection_receiveChunk(UA_Connection *connection, UA_ByteString * UA_RESTRICT m
 /*********************/
 
 static void UA_Client_init(UA_Client* client, UA_ClientConfig config) {
+    memset(client, 0, sizeof(UA_Client));
+
     client->state = UA_CLIENTSTATE_READY;
     client->connection = UA_malloc(sizeof(UA_Connection));
-    UA_Connection_init(client->connection);
+    memset(client->connection, 0, sizeof(UA_Connection));
     client->channel = UA_malloc(sizeof(UA_SecureChannel));
     UA_SecureChannel_init(client->channel);
     client->channel->connection = client->connection;
-    UA_String_init(&client->endpointUrl);
-    client->requestId = 0;
-
     client->authenticationMethod = UA_CLIENTAUTHENTICATION_NONE;
-    UA_String_init(&client->username);
-    UA_String_init(&client->password);
-
-    UA_NodeId_init(&client->authenticationToken);
-    client->requestHandle = 0;
-
     client->config = config;
-    client->scRenewAt = 0;
-
 #ifdef UA_ENABLE_SUBSCRIPTIONS
-    client->monitoredItemHandles = 0;
     LIST_INIT(&client->pendingNotificationsAcks);
     LIST_INIT(&client->subscriptions);
 #endif

+ 3 - 18
src/ua_connection.c

@@ -5,22 +5,6 @@
 #include "ua_types_generated_handling.h"
 #include "ua_securechannel.h"
 
-void UA_Connection_init(UA_Connection *connection) {
-    connection->state = UA_CONNECTION_CLOSED;
-    connection->localConf = UA_ConnectionConfig_standard;
-    connection->remoteConf = UA_ConnectionConfig_standard;
-    connection->channel = NULL;
-    connection->sockfd = 0;
-    connection->handle = NULL;
-    UA_ByteString_init(&connection->incompleteMessage);
-    connection->send = NULL;
-    connection->recv = NULL;
-    connection->close = NULL;
-    connection->getSendBuffer = NULL;
-    connection->releaseSendBuffer = NULL;
-    connection->releaseRecvBuffer = NULL;
-}
-
 void UA_Connection_deleteMembers(UA_Connection *connection) {
     UA_ByteString_deleteMembers(&connection->incompleteMessage);
 }
@@ -149,7 +133,9 @@ void UA_Connection_detachSecureChannel(UA_Connection *connection) {
 #endif
 }
 
-void UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *channel) {
+void
+UA_Connection_attachSecureChannel(UA_Connection *connection,
+                                  UA_SecureChannel *channel) {
 #ifdef UA_ENABLE_MULTITHREADING
     if(uatomic_cmpxchg(&channel->connection, NULL, connection) == NULL)
         uatomic_set((void**)&connection->channel, (void*)channel);
@@ -282,7 +268,6 @@ UA_EndpointUrl_split(const char *endpointUrl, char *hostname,
     return UA_STATUSCODE_GOOD;
 }
 
-
 size_t UA_readNumber(UA_Byte *buf, size_t buflen, UA_UInt32 *number) {
     if (!buf)
         return 0;

+ 24 - 25
src/ua_securechannel.c

@@ -10,16 +10,7 @@
 #define UA_SECURE_MESSAGE_HEADER_LENGTH 24
 
 void UA_SecureChannel_init(UA_SecureChannel *channel) {
-    UA_MessageSecurityMode_init(&channel->securityMode);
-    UA_ChannelSecurityToken_init(&channel->securityToken);
-    UA_ChannelSecurityToken_init(&channel->nextSecurityToken);
-    UA_AsymmetricAlgorithmSecurityHeader_init(&channel->clientAsymAlgSettings);
-    UA_AsymmetricAlgorithmSecurityHeader_init(&channel->serverAsymAlgSettings);
-    UA_ByteString_init(&channel->clientNonce);
-    UA_ByteString_init(&channel->serverNonce);
-    channel->receiveSequenceNumber = 0;
-    channel->sendSequenceNumber = 0;
-    channel->connection = NULL;
+    memset(channel, 0, sizeof(UA_SecureChannel));
     LIST_INIT(&channel->sessions);
     LIST_INIT(&channel->chunks);
 }
@@ -125,7 +116,8 @@ void UA_SecureChannel_revolveTokens(UA_SecureChannel *channel) {
         return;
 
     //FIXME: not thread-safe
-    memcpy(&channel->securityToken, &channel->nextSecurityToken, sizeof(UA_ChannelSecurityToken));
+    memcpy(&channel->securityToken, &channel->nextSecurityToken,
+           sizeof(UA_ChannelSecurityToken));
     UA_ChannelSecurityToken_init(&channel->nextSecurityToken);
 }
 
@@ -145,9 +137,11 @@ UA_SecureChannel_sendChunk(UA_ChunkInfo *ci, UA_ByteString *dst, size_t offset)
     dst->length += UA_SECURE_MESSAGE_HEADER_LENGTH;
     offset += UA_SECURE_MESSAGE_HEADER_LENGTH;
 
-    if(ci->messageSizeSoFar + offset > connection->remoteConf.maxMessageSize && connection->remoteConf.maxMessageSize > 0)
+    if(ci->messageSizeSoFar + offset > connection->remoteConf.maxMessageSize &&
+       connection->remoteConf.maxMessageSize > 0)
         ci->errorCode = UA_STATUSCODE_BADRESPONSETOOLARGE;
-    if(++ci->chunksSoFar > connection->remoteConf.maxChunkCount && connection->remoteConf.maxChunkCount > 0)
+    if(++ci->chunksSoFar > connection->remoteConf.maxChunkCount &&
+       connection->remoteConf.maxChunkCount > 0)
         ci->errorCode = UA_STATUSCODE_BADRESPONSETOOLARGE;
 
     /* Prepare the chunk headers */
@@ -193,7 +187,8 @@ UA_SecureChannel_sendChunk(UA_ChunkInfo *ci, UA_ByteString *dst, size_t offset)
 
     /* Replace with the buffer for the next chunk */
     if(!ci->final) {
-        UA_StatusCode retval = connection->getSendBuffer(connection, connection->localConf.sendBufferSize, dst);
+        UA_StatusCode retval =
+            connection->getSendBuffer(connection, connection->localConf.sendBufferSize, dst);
         if(retval != UA_STATUSCODE_GOOD)
             return retval;
         /* Hide the header of the buffer, so that the ensuing encoding does not overwrite anything */
@@ -204,15 +199,16 @@ UA_SecureChannel_sendChunk(UA_ChunkInfo *ci, UA_ByteString *dst, size_t offset)
 }
 
 UA_StatusCode
-UA_SecureChannel_sendBinaryMessage(UA_SecureChannel *channel, UA_UInt32 requestId, const void *content,
-                                   const UA_DataType *contentType) {
+UA_SecureChannel_sendBinaryMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
+                                   const void *content, const UA_DataType *contentType) {
     UA_Connection *connection = channel->connection;
     if(!connection)
         return UA_STATUSCODE_BADINTERNALERROR;
 
     /* Allocate the message buffer */
     UA_ByteString message;
-    UA_StatusCode retval = connection->getSendBuffer(connection, connection->localConf.sendBufferSize, &message);
+    UA_StatusCode retval =
+        connection->getSendBuffer(connection, connection->localConf.sendBufferSize, &message);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
@@ -239,7 +235,8 @@ UA_SecureChannel_sendBinaryMessage(UA_SecureChannel *channel, UA_UInt32 requestI
         ci.messageType = UA_MESSAGETYPE_OPN;
     else if(typeId.identifier.numeric == 452 || typeId.identifier.numeric == 455)
         ci.messageType = UA_MESSAGETYPE_CLO;
-    retval = UA_encodeBinary(content, contentType, (UA_exchangeEncodeBuffer)UA_SecureChannel_sendChunk,
+    retval = UA_encodeBinary(content, contentType,
+                             (UA_exchangeEncodeBuffer)UA_SecureChannel_sendChunk,
                              &ci, &message, &messagePos);
 
     /* Encoding failed, release the message */
@@ -366,15 +363,17 @@ UA_SecureChannel_processSequenceNumber(UA_SecureChannel *channel, UA_UInt32 Sequ
 UA_StatusCode
 UA_SecureChannel_processChunks(UA_SecureChannel *channel, const UA_ByteString *chunks,
                                UA_ProcessMessageCallback callback, void *application) {
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
     size_t offset= 0;
     do {
+        /* Store the initial offset to compute the header length */
         size_t initial_offset = offset;
-        
+
         /* Decode header */
         UA_SecureConversationMessageHeader header;
-        UA_StatusCode retval = UA_SecureConversationMessageHeader_decodeBinary(chunks, &offset, &header);
+        retval = UA_SecureConversationMessageHeader_decodeBinary(chunks, &offset, &header);
         if(retval != UA_STATUSCODE_GOOD)
-            return retval;
+            break;
 
         /* Is the channel attached to connection? */
         if(header.secureChannelId != channel->securityToken.channelId) {
@@ -416,15 +415,15 @@ UA_SecureChannel_processChunks(UA_SecureChannel *channel, const UA_ByteString *c
                                          header.messageHeader.messageSize - processed_header);
             break;
         case UA_CHUNKTYPE_FINAL: {
-            UA_Boolean deleteMessage = false;
+            UA_Boolean realloced = false;
             UA_ByteString message =
                 UA_SecureChannel_finalizeChunk(channel, sequenceHeader.requestId, chunks, offset,
                                                header.messageHeader.messageSize - processed_header,
-                                               &deleteMessage);
+                                               &realloced);
             if(message.length > 0) {
                 callback(application, channel, header.messageHeader.messageTypeAndChunkType & 0x00ffffff,
                          sequenceHeader.requestId, &message);
-                if(deleteMessage)
+                if(realloced)
                     UA_ByteString_deleteMembers(&message);
             }
             break; }
@@ -439,5 +438,5 @@ UA_SecureChannel_processChunks(UA_SecureChannel *channel, const UA_ByteString *c
         offset += (header.messageHeader.messageSize - processed_header);
     } while(chunks->length > offset);
 
-    return UA_STATUSCODE_GOOD;
+    return retval;
 }