Browse Source

properly concat half-received messages in the server

Julius Pfrommer 10 years ago
parent
commit
7d7036cebe

+ 2 - 0
examples/networklayer_tcp.c

@@ -114,6 +114,7 @@ static UA_StatusCode setNonBlocking(int sockid) {
 }
 
 static void freeConnectionCallback(UA_Server *server, TCPConnection *connection) {
+    UA_ByteString_deleteMembers(&connection->connection.incompleteMessage);
     free(connection);
 }
 
@@ -145,6 +146,7 @@ static UA_StatusCode ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_
     c->connection.channel = (void*)0;
     c->connection.close = (void (*)(void*))closeConnection;
     c->connection.write = (void (*)(void*, UA_ByteStringArray))writeCallback;
+    UA_ByteString_init(&c->connection.incompleteMessage);
 
     layer->conLinks = realloc(layer->conLinks, sizeof(ConnectionLink)*(layer->conLinksSize+1));
 	if(!layer->conLinks) {

+ 7 - 6
src/server/ua_server_binary.c

@@ -47,15 +47,12 @@ static void processHEL(UA_Connection *connection, const UA_ByteString *msg, size
         UA_TcpMessageHeader_calcSizeBinary(&ackHeader);
 
     // The message is on the stack. That's ok since ack is very small.
-    UA_ByteString ack_msg = (UA_ByteString){
-        .length = ackHeader.messageSize,
-            .data = UA_alloca(ackHeader.messageSize)
-    };
+    UA_ByteString ack_msg = (UA_ByteString){ .length = ackHeader.messageSize,
+                                             .data = UA_alloca(ackHeader.messageSize) };
     size_t tmpPos = 0;
     UA_TcpMessageHeader_encodeBinary(&ackHeader, &ack_msg, &tmpPos);
     UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &ack_msg, &tmpPos);
     UA_ByteStringArray answer_buf = { .stringsSize = 1, .strings = &ack_msg };
-    // the string is freed internall in the (asynchronous) write
     connection->write(connection, answer_buf);
     UA_TcpHelloMessage_deleteMembers(&helloMessage);
 }
@@ -415,7 +412,11 @@ static void processCLO(UA_Connection *connection, UA_Server *server, const UA_By
     Service_CloseSecureChannel(server, secureChannelId);
 }
 
-void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {
+void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, UA_ByteString *msg) {
+    *msg = UA_Connection_completeMessages(connection, *msg);
+    if(msg->length <= 0)
+        return;
+
     size_t pos = 0;
     UA_TcpMessageHeader tcpMessageHeader;
     do {

+ 1 - 1
src/server/ua_server_internal.h

@@ -59,7 +59,7 @@ struct UA_Server {
     UA_DateTime buildDate;
 };
 
-void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
+void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, UA_ByteString *msg);
 
 UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *session, UA_Node *node,
                                                const UA_ExpandedNodeId *parentNodeId,

+ 2 - 2
src/server/ua_server_worker.c

@@ -17,9 +17,9 @@
 #define MAXTIMEOUT 50000 // max timeout in usec until the next main loop iteration
 #define BATCHSIZE 20 // max size of worklists that are dispatched to workers
 
-static void processWork(UA_Server *server, const UA_WorkItem *work, UA_Int32 workSize) {
+static void processWork(UA_Server *server, UA_WorkItem *work, UA_Int32 workSize) {
     for(UA_Int32 i = 0;i<workSize;i++) {
-        const UA_WorkItem *item = &work[i];
+        UA_WorkItem *item = &work[i];
         switch(item->type) {
         case UA_WORKITEMTYPE_BINARYNETWORKMESSAGE:
             UA_Server_processBinaryMessage(server, item->work.binaryNetworkMessage.connection,