Explorar el Código

move sending of servicefaults from securechannel to server.
return UA_STATUSCODE_BADREQUESTTOOLARGE in the client when the message is bigger than the recv buffer of the server.
(no chunking supported so far)

Julius Pfrommer hace 10 años
padre
commit
b44a64a8fc
Se han modificado 4 ficheros con 31 adiciones y 25 borrados
  1. 5 3
      examples/networklayer_tcp.c
  2. 4 1
      src/client/ua_client.c
  3. 17 10
      src/server/ua_server_binary.c
  4. 5 11
      src/ua_securechannel.c

+ 5 - 3
examples/networklayer_tcp.c

@@ -67,6 +67,7 @@ static UA_StatusCode socket_recv(UA_Connection *connection, UA_ByteString *respo
         return UA_STATUSCODE_BADOUTOFMEMORY;
     struct timeval tmptv = {0, timeout * 1000};
     if(0 != setsockopt(connection->sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmptv, sizeof(struct timeval))){
+		UA_free(response->data);
         return UA_STATUSCODE_BADINTERNALERROR;
     }
     int ret = recv(connection->sockfd, (char*)response->data, connection->localConf.recvBufferSize, 0);
@@ -75,16 +76,17 @@ static UA_StatusCode socket_recv(UA_Connection *connection, UA_ByteString *respo
 		connection->close(connection);
 		return UA_STATUSCODE_BADCONNECTIONCLOSED;
 	} else if(ret < 0) {
+        UA_free(response->data);
 #ifdef _WIN32
 		if(WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK) {
 #else
 		if (errno == EAGAIN) {
 #endif
             return UA_STATUSCODE_BADCOMMUNICATIONERROR;
+        } else {
+            connection->close(connection);
+            return UA_STATUSCODE_BADCONNECTIONCLOSED;
         }
-		UA_free(response->data);
-		connection->close(connection);
-        return UA_STATUSCODE_BADCONNECTIONCLOSED;
     }
     response->length = ret;
     *response = UA_Connection_completeMessages(connection, *response);

+ 4 - 1
src/client/ua_client.c

@@ -239,7 +239,10 @@ static void synchronousRequest(UA_Client *client, void *request, const UA_DataTy
                                                               request, requestType);
     UA_ResponseHeader *respHeader = (UA_ResponseHeader*)response;
     if(retval) {
-        respHeader->serviceResult = retval;
+        if(retval == UA_STATUSCODE_BADENCODINGERROR)
+            respHeader->serviceResult = UA_STATUSCODE_BADREQUESTTOOLARGE;
+        else
+            respHeader->serviceResult = retval;
         return;
     }
 

+ 17 - 10
src/server/ua_server_binary.c

@@ -148,8 +148,8 @@ static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r
 }
 
 /* The request/response are casted to the header (first element of their struct) */
-static void invoke_service(UA_Server *server, UA_SecureChannel *channel,
-                           UA_UInt32 requestId, UA_RequestHeader *request, const UA_DataType *responseType,
+static void invoke_service(UA_Server *server, UA_SecureChannel *channel, UA_UInt32 requestId,
+                           UA_RequestHeader *request, const UA_DataType *responseType,
                            void (*service)(UA_Server*, UA_Session*, void*, void*)) {
     UA_ResponseHeader *response = UA_alloca(responseType->memSize);
     UA_init(response, responseType);
@@ -170,7 +170,14 @@ static void invoke_service(UA_Server *server, UA_SecureChannel *channel,
         UA_Session_updateLifetime(session);
         service(server, session, request, response);
     }
-    UA_SecureChannel_sendBinaryMessage(channel, requestId, response, responseType);
+    UA_StatusCode retval = UA_SecureChannel_sendBinaryMessage(channel, requestId, response, responseType);
+    if(retval != UA_STATUSCODE_GOOD) {
+        if(retval == UA_STATUSCODE_BADENCODINGERROR)
+            response->serviceResult = UA_STATUSCODE_BADRESPONSETOOLARGE;
+        else
+            response->serviceResult = retval;
+        UA_SecureChannel_sendBinaryMessage(channel, requestId, response, &UA_TYPES[UA_TYPES_SERVICEFAULT]);
+    }
     UA_deleteMembers(response, responseType);
 }
 
@@ -316,20 +323,20 @@ static void processMSG(UA_Connection *connection, UA_Server *server, const UA_By
             UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "Unknown request: NodeId(ns=%d, i=%d)",
                         requestType.namespaceIndex, requestType.identifier.numeric);
         UA_RequestHeader p;
-        UA_ServiceFault r;
+        UA_ResponseHeader r;
         if(UA_RequestHeader_decodeBinary(msg, pos, &p) != UA_STATUSCODE_GOOD)
             return;
-        UA_ServiceFault_init(&r);
-        init_response_header(&p, &r.responseHeader);
-        r.responseHeader.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
+        UA_ResponseHeader_init(&r);
+        init_response_header(&p, &r);
+        r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
 #ifdef EXTENSION_STATELESS
         if(retval != UA_STATUSCODE_GOOD)
             r.serviceResult = retval;
 #endif
+        UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r,
+                                           &UA_TYPES[UA_TYPES_SERVICEFAULT]);
         UA_RequestHeader_deleteMembers(&p);
-        UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId,
-            &r, &UA_TYPES[UA_TYPES_SERVICEFAULT]);
-        UA_ServiceFault_deleteMembers(&r);
+        UA_ResponseHeader_deleteMembers(&r);
         break;
     }
     }

+ 5 - 11
src/ua_securechannel.c

@@ -120,16 +120,9 @@ UA_StatusCode UA_SecureChannel_sendBinaryMessage(UA_SecureChannel *channel, UA_U
     retval |= UA_NodeId_encodeBinary(&typeId, &message, &messagePos);
     retval |= UA_encodeBinary(content, contentType, &message, &messagePos);
 
-    /* write a failure message if necessary */
     if(retval != UA_STATUSCODE_GOOD) {
-        UA_ServiceFault r;
-        UA_ServiceFault_init(&r);
-        r.responseHeader = *(const UA_ResponseHeader*)content;
-        r.responseHeader.serviceResult = UA_STATUSCODE_BADRESPONSETOOLARGE;
-        size_t messagePos = 24;
-        UA_NodeId_encodeBinary(&UA_TYPES[UA_TYPES_SERVICEFAULT].typeId, &message, &messagePos);
-        UA_encodeBinary(&r, &UA_TYPES[UA_TYPES_SERVICEFAULT], &message, &messagePos);
-        UA_ServiceFault_init(&r);
+        connection->releaseBuffer(connection, &message);
+        return retval;
     }
 
     /* now write the header with the size */
@@ -145,7 +138,8 @@ UA_StatusCode UA_SecureChannel_sendBinaryMessage(UA_SecureChannel *channel, UA_U
     UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&symSecHeader, &message, &messagePos);
     UA_SequenceHeader_encodeBinary(&seqHeader, &message, &messagePos);
     
-    if(connection->write(connection, &message, respHeader.messageHeader.messageSize) != UA_STATUSCODE_GOOD)
+    retval = connection->write(connection, &message, respHeader.messageHeader.messageSize);
+    if(retval != UA_STATUSCODE_GOOD)
         connection->releaseBuffer(connection, &message);
-    return UA_STATUSCODE_GOOD;
+    return retval;
 }