|
@@ -1,3 +1,5 @@
|
|
|
+#include <stdio.h>
|
|
|
+
|
|
|
#include "ua_server_internal.h"
|
|
|
#include "ua_services.h"
|
|
|
#include "ua_statuscodes.h"
|
|
@@ -6,6 +8,9 @@
|
|
|
#include "ua_session_manager.h"
|
|
|
#include "ua_util.h"
|
|
|
|
|
|
+/** Max size of messages that are allocated on the stack */
|
|
|
+#define MAX_STACK_MESSAGE 65536
|
|
|
+
|
|
|
static UA_StatusCode UA_ByteStringArray_deleteMembers(UA_ByteStringArray *stringarray) {
|
|
|
if(!stringarray)
|
|
|
return UA_STATUSCODE_BADINTERNALERROR;
|
|
@@ -18,15 +23,15 @@ static void processHello(UA_Connection *connection, const UA_ByteString *msg,
|
|
|
UA_UInt32 *pos) {
|
|
|
UA_TcpHelloMessage helloMessage;
|
|
|
if(UA_TcpHelloMessage_decodeBinary(msg, pos, &helloMessage) != UA_STATUSCODE_GOOD) {
|
|
|
- connection->close(connection->callbackHandle);
|
|
|
+ connection->close(connection);
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount;
|
|
|
connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize;
|
|
|
connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
|
|
|
connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
|
|
|
connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
|
|
|
-
|
|
|
connection->state = UA_CONNECTION_ESTABLISHED;
|
|
|
|
|
|
// build acknowledge response
|
|
@@ -43,21 +48,22 @@ static void processHello(UA_Connection *connection, const UA_ByteString *msg,
|
|
|
ackHeader.messageSize = UA_TcpAcknowledgeMessage_calcSizeBinary(&ackMessage) +
|
|
|
UA_TcpMessageHeader_calcSizeBinary(&ackHeader);
|
|
|
|
|
|
- UA_ByteString ack_msg;
|
|
|
+ // 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_UInt32 tmpPos = 0;
|
|
|
- UA_ByteString_newMembers(&ack_msg, ackHeader.messageSize);
|
|
|
UA_TcpMessageHeader_encodeBinary(&ackHeader, &ack_msg, &tmpPos);
|
|
|
UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &ack_msg, &tmpPos);
|
|
|
UA_ByteStringArray answer_buf = { .stringsSize = 1, .strings = &ack_msg };
|
|
|
- connection->write(connection->callbackHandle, answer_buf); // the string is freed internall in the (asynchronous) write
|
|
|
+ // the string is freed internall in the (asynchronous) write
|
|
|
+ connection->write(connection, answer_buf);
|
|
|
UA_TcpHelloMessage_deleteMembers(&helloMessage);
|
|
|
}
|
|
|
|
|
|
-static void processOpen(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
|
|
|
+static void processOpen(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg,
|
|
|
+ UA_UInt32 *pos) {
|
|
|
if(connection->state != UA_CONNECTION_ESTABLISHED) {
|
|
|
- // was hello exchanged before?
|
|
|
- if(connection->state == UA_CONNECTION_OPENING)
|
|
|
- connection->close(connection->callbackHandle);
|
|
|
+ connection->close(connection);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -89,7 +95,7 @@ static void processOpen(UA_Connection *connection, UA_Server *server, const UA_B
|
|
|
UA_TcpMessageHeader respHeader;
|
|
|
respHeader.messageType = UA_MESSAGETYPE_OPN;
|
|
|
respHeader.isFinal = 'F';
|
|
|
- respHeader.messageSize = 8+4; //header + securechannelid
|
|
|
+ respHeader.messageSize = 8;
|
|
|
|
|
|
UA_ExpandedNodeId responseType = UA_EXPANDEDNODEIDS[UA_OPENSECURECHANNELRESPONSE];
|
|
|
responseType.nodeId.identifier.numeric += UA_ENCODINGOFFSET_BINARY;
|
|
@@ -100,8 +106,16 @@ static void processOpen(UA_Connection *connection, UA_Server *server, const UA_B
|
|
|
respHeader.messageSize += UA_OpenSecureChannelResponse_calcSizeBinary(&p);
|
|
|
|
|
|
UA_ByteString resp_msg;
|
|
|
+ UA_Boolean onStack = UA_FALSE;
|
|
|
+
|
|
|
+ if(respHeader.messageSize <= MAX_STACK_MESSAGE) {
|
|
|
+ onStack = UA_TRUE;
|
|
|
+ resp_msg = (UA_ByteString){.length = respHeader.messageSize,
|
|
|
+ .data = UA_alloca(respHeader.messageSize)};
|
|
|
+ } else
|
|
|
+ UA_ByteString_newMembers(&resp_msg, respHeader.messageSize);
|
|
|
+
|
|
|
UA_UInt32 tmpPos = 0;
|
|
|
- UA_ByteString_newMembers(&resp_msg, respHeader.messageSize);
|
|
|
UA_TcpMessageHeader_encodeBinary(&respHeader, &resp_msg, &tmpPos);
|
|
|
UA_UInt32_encodeBinary(&p.securityToken.channelId, &resp_msg, &tmpPos);
|
|
|
UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&asymHeader, &resp_msg, &tmpPos); // just mirror back
|
|
@@ -112,9 +126,9 @@ static void processOpen(UA_Connection *connection, UA_Server *server, const UA_B
|
|
|
UA_OpenSecureChannelRequest_deleteMembers(&r);
|
|
|
UA_OpenSecureChannelResponse_deleteMembers(&p);
|
|
|
UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymHeader);
|
|
|
-
|
|
|
- UA_ByteStringArray answer_buf = { .stringsSize = 1, .strings = &resp_msg };
|
|
|
- connection->write(connection->callbackHandle, answer_buf);
|
|
|
+ connection->write(connection, (UA_ByteStringArray){ .stringsSize = 1, .strings = &resp_msg });
|
|
|
+ if(!onStack)
|
|
|
+ UA_free(resp_msg.data);
|
|
|
}
|
|
|
|
|
|
static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r) {
|
|
@@ -130,21 +144,30 @@ static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r
|
|
|
return; \
|
|
|
} } while(0)
|
|
|
|
|
|
-#define INVOKE_SERVICE(TYPE) do { \
|
|
|
- UA_##TYPE##Request p; \
|
|
|
- UA_##TYPE##Response r; \
|
|
|
- CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),; ); \
|
|
|
- UA_##TYPE##Response_init(&r); \
|
|
|
- init_response_header(&p.requestHeader, &r.responseHeader); \
|
|
|
- DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE)); \
|
|
|
- Service_##TYPE(server, channel->session, &p, &r); \
|
|
|
- DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE)); \
|
|
|
- UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
|
|
|
- UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset); \
|
|
|
- UA_##TYPE##Request_deleteMembers(&p); \
|
|
|
- UA_##TYPE##Response_deleteMembers(&r); \
|
|
|
- responseType = requestType.nodeId.identifier.numeric + 3; \
|
|
|
-} while(0)
|
|
|
+// if the message is small enough, we allocate it on the stack and save a malloc
|
|
|
+#define ALLOC_MESSAGE(MESSAGE, SIZE) do { \
|
|
|
+ UA_UInt32 messageSize = SIZE; \
|
|
|
+ if(messageSize <= MAX_STACK_MESSAGE) { \
|
|
|
+ messageOnStack = UA_TRUE; \
|
|
|
+ *MESSAGE = (UA_ByteString){.length = messageSize, \
|
|
|
+ .data = UA_alloca(messageSize)}; \
|
|
|
+ } else \
|
|
|
+ UA_ByteString_newMembers(MESSAGE, messageSize); \
|
|
|
+ } while(0)
|
|
|
+
|
|
|
+#define INVOKE_SERVICE(TYPE) do { \
|
|
|
+ UA_##TYPE##Request p; \
|
|
|
+ UA_##TYPE##Response r; \
|
|
|
+ CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),;); \
|
|
|
+ UA_##TYPE##Response_init(&r); \
|
|
|
+ init_response_header(&p.requestHeader, &r.responseHeader); \
|
|
|
+ Service_##TYPE(server, channel->session, &p, &r); \
|
|
|
+ ALLOC_MESSAGE(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
|
|
|
+ UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset); \
|
|
|
+ UA_##TYPE##Request_deleteMembers(&p); \
|
|
|
+ UA_##TYPE##Response_deleteMembers(&r); \
|
|
|
+ responseType = requestType.nodeId.identifier.numeric + 3; \
|
|
|
+ } while(0)
|
|
|
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
#define INVOKE_STATELESS_SERVICE(TYPE) do { \
|
|
@@ -153,9 +176,7 @@ static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r
|
|
|
CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),; ); \
|
|
|
UA_##TYPE##Response_init(&r); \
|
|
|
init_response_header(&p.requestHeader, &r.responseHeader); \
|
|
|
- DBG_VERBOSE(printf("Anonymous Invoke Service: %s\n", # TYPE)); \
|
|
|
Service_##TYPE(server, &anonymousSession, &p, &r); \
|
|
|
- DBG_VERBOSE(printf("Finished Anonymous Service: %s\n", # TYPE)); \
|
|
|
UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
|
|
|
UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset); \
|
|
|
UA_##TYPE##Request_deleteMembers(&p); \
|
|
@@ -173,7 +194,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
if(connection->channel != UA_NULL && secureChannelId != 0){
|
|
|
#endif
|
|
|
- UA_SecureChannelManager_get(&server->secureChannelManager, secureChannelId, &channel);
|
|
|
+ channel = UA_SecureChannelManager_get(&server->secureChannelManager, secureChannelId);
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
}
|
|
|
#endif
|
|
@@ -185,7 +206,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
CHECK_PROCESS(UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader),; );
|
|
|
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
- if(connection->channel != UA_NULL && secureChannelId != 0){
|
|
|
+ if(connection->channel != UA_NULL && secureChannelId != 0) {
|
|
|
#endif
|
|
|
channel->sequenceNumber = sequenceHeader.sequenceNumber;
|
|
|
channel->requestId = sequenceHeader.requestId;
|
|
@@ -200,7 +221,8 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
UA_ExpandedNodeId requestType;
|
|
|
CHECK_PROCESS(UA_ExpandedNodeId_decodeBinary(msg, pos, &requestType),; );
|
|
|
if(requestType.nodeId.identifierType != UA_NODEIDTYPE_NUMERIC) {
|
|
|
- UA_ExpandedNodeId_deleteMembers(&requestType); // if the nodeidtype is numeric, we do not have to free anything
|
|
|
+ // if the nodeidtype is numeric, we do not have to free anything
|
|
|
+ UA_ExpandedNodeId_deleteMembers(&requestType);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -209,28 +231,29 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
UA_UInt32 responseType;
|
|
|
UA_ByteString *header = &responseBufs[0];
|
|
|
UA_ByteString *message = &responseBufs[1];
|
|
|
+ UA_Boolean messageOnStack = UA_FALSE;
|
|
|
|
|
|
UA_UInt32 sendOffset = 0;
|
|
|
+
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
- if(connection->channel == UA_NULL && secureChannelId == 0){
|
|
|
- //stateless service calls - will pass UA_NULL as session
|
|
|
- //fixme: maybe we need to pass a magic number instead of UA_NULL e.g. just a 42
|
|
|
- switch(requestType.nodeId.identifier.numeric - 2) {
|
|
|
- case UA_READREQUEST_NS0:
|
|
|
+ if(connection->channel == UA_NULL && secureChannelId == 0) {
|
|
|
+ //stateless service calls - will pass UA_NULL as session
|
|
|
+ //fixme: maybe we need to pass a magic number instead of UA_NULL e.g. just a 42
|
|
|
+ switch(requestType.nodeId.identifier.numeric - 2) {
|
|
|
+ case UA_READREQUEST_NS0:
|
|
|
INVOKE_STATELESS_SERVICE(Read);
|
|
|
break;
|
|
|
-
|
|
|
- case UA_WRITEREQUEST_NS0:
|
|
|
+ case UA_WRITEREQUEST_NS0:
|
|
|
INVOKE_STATELESS_SERVICE(Write);
|
|
|
break;
|
|
|
-
|
|
|
- case UA_BROWSEREQUEST_NS0:
|
|
|
+ case UA_BROWSEREQUEST_NS0:
|
|
|
INVOKE_STATELESS_SERVICE(Browse);
|
|
|
break;
|
|
|
- }
|
|
|
- //FIXME: a copy-pasted default case, but I did not want any duplications
|
|
|
- }else{
|
|
|
+}
|
|
|
+ //FIXME: a copy-pasted default case, but I did not want any duplications
|
|
|
+}else{
|
|
|
#endif
|
|
|
+
|
|
|
//subtract UA_ENCODINGOFFSET_BINARY for binary encoding
|
|
|
switch(requestType.nodeId.identifier.numeric - UA_ENCODINGOFFSET_BINARY) {
|
|
|
case UA_GETENDPOINTSREQUEST_NS0: {
|
|
@@ -240,7 +263,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
UA_GetEndpointsResponse_init(&r);
|
|
|
init_response_header(&p.requestHeader, &r.responseHeader);
|
|
|
Service_GetEndpoints(server, &p, &r);
|
|
|
- UA_ByteString_newMembers(message, UA_GetEndpointsResponse_calcSizeBinary(&r));
|
|
|
+ ALLOC_MESSAGE(message, UA_GetEndpointsResponse_calcSizeBinary(&r));
|
|
|
UA_GetEndpointsResponse_encodeBinary(&r, message, &sendOffset);
|
|
|
UA_GetEndpointsRequest_deleteMembers(&p);
|
|
|
UA_GetEndpointsResponse_deleteMembers(&r);
|
|
@@ -255,7 +278,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
UA_CreateSessionResponse_init(&r);
|
|
|
init_response_header(&p.requestHeader, &r.responseHeader);
|
|
|
Service_CreateSession(server, channel, &p, &r);
|
|
|
- UA_ByteString_newMembers(message, UA_CreateSessionResponse_calcSizeBinary(&r));
|
|
|
+ ALLOC_MESSAGE(message, UA_CreateSessionResponse_calcSizeBinary(&r));
|
|
|
UA_CreateSessionResponse_encodeBinary(&r, message, &sendOffset);
|
|
|
UA_CreateSessionRequest_deleteMembers(&p);
|
|
|
UA_CreateSessionResponse_deleteMembers(&r);
|
|
@@ -269,9 +292,8 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
CHECK_PROCESS(UA_ActivateSessionRequest_decodeBinary(msg, pos, &p),; );
|
|
|
UA_ActivateSessionResponse_init(&r);
|
|
|
init_response_header(&p.requestHeader, &r.responseHeader);
|
|
|
-
|
|
|
Service_ActivateSession(server, channel, &p, &r);
|
|
|
- UA_ByteString_newMembers(message, UA_ActivateSessionResponse_calcSizeBinary(&r));
|
|
|
+ ALLOC_MESSAGE(message, UA_ActivateSessionResponse_calcSizeBinary(&r));
|
|
|
UA_ActivateSessionResponse_encodeBinary(&r, message, &sendOffset);
|
|
|
UA_ActivateSessionRequest_deleteMembers(&p);
|
|
|
UA_ActivateSessionResponse_deleteMembers(&r);
|
|
@@ -285,9 +307,8 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
CHECK_PROCESS(UA_CloseSessionRequest_decodeBinary(msg, pos, &p),; );
|
|
|
UA_CloseSessionResponse_init(&r);
|
|
|
init_response_header(&p.requestHeader, &r.responseHeader);
|
|
|
-
|
|
|
Service_CloseSession(server, &p, &r);
|
|
|
- UA_ByteString_newMembers(message, UA_CloseSessionResponse_calcSizeBinary(&r));
|
|
|
+ ALLOC_MESSAGE(message, UA_CloseSessionResponse_calcSizeBinary(&r));
|
|
|
UA_CloseSessionResponse_encodeBinary(&r, message, &sendOffset);
|
|
|
UA_CloseSessionRequest_deleteMembers(&p);
|
|
|
UA_CloseSessionResponse_deleteMembers(&r);
|
|
@@ -295,8 +316,10 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- case UA_READREQUEST_NS0:
|
|
|
+ case UA_READREQUEST_NS0: {
|
|
|
INVOKE_SERVICE(Read);
|
|
|
+ }
|
|
|
+ //INVOKE_SERVICE(Read);
|
|
|
break;
|
|
|
|
|
|
case UA_WRITEREQUEST_NS0:
|
|
@@ -338,7 +361,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
UA_ResponseHeader_init(&r);
|
|
|
r.requestHandle = p.requestHandle;
|
|
|
r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
|
|
|
- UA_ByteString_newMembers(message, UA_ResponseHeader_calcSizeBinary(&r));
|
|
|
+ ALLOC_MESSAGE(message, UA_ResponseHeader_calcSizeBinary(&r));
|
|
|
UA_ResponseHeader_encodeBinary(&r, message, &sendOffset);
|
|
|
UA_RequestHeader_deleteMembers(&p);
|
|
|
UA_ResponseHeader_deleteMembers(&r);
|
|
@@ -347,35 +370,32 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
break;
|
|
|
}
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
- }
|
|
|
+}
|
|
|
#endif
|
|
|
// 5) Build the header
|
|
|
UA_NodeId response_nodeid = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
|
|
|
.identifier.numeric = responseType }; // add 2 for binary encoding
|
|
|
|
|
|
- UA_ByteString_newMembers(header,
|
|
|
- 8 + 16 + // message header + 4*32bit secure channel information
|
|
|
- UA_NodeId_calcSizeBinary(&response_nodeid));
|
|
|
+ UA_UInt32 headerSize = 8 + 16 + // message header + 4*32bit secure channel information
|
|
|
+ UA_NodeId_calcSizeBinary(&response_nodeid); // the nodeid of a service is always numeric
|
|
|
+ *header = (UA_ByteString){.length = headerSize, .data = UA_alloca(headerSize)};
|
|
|
|
|
|
// header
|
|
|
UA_TcpMessageHeader respHeader;
|
|
|
respHeader.messageType = UA_MESSAGETYPE_MSG;
|
|
|
respHeader.isFinal = 'F';
|
|
|
respHeader.messageSize = header->length + message->length;
|
|
|
+
|
|
|
UA_UInt32 rpos = 0;
|
|
|
UA_TcpMessageHeader_encodeBinary(&respHeader, header, &rpos);
|
|
|
|
|
|
-
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
if(connection->channel != UA_NULL && secureChannelId != 0){
|
|
|
#endif
|
|
|
-
|
|
|
UA_UInt32_encodeBinary(&channel->securityToken.channelId, header, &rpos); // channel id
|
|
|
UA_UInt32_encodeBinary(&channel->securityToken.tokenId, header, &rpos); // algorithm security header
|
|
|
-
|
|
|
UA_UInt32_encodeBinary(&channel->sequenceNumber, header, &rpos); // encode sequence header
|
|
|
- UA_UInt32_encodeBinary(&channel->requestId, header, &rpos);
|
|
|
-
|
|
|
+ UA_UInt32_encodeBinary(&channel->requestId, header, &rpos); // request id
|
|
|
UA_NodeId_encodeBinary(&response_nodeid, header, &rpos); // add payload type
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
}else{
|
|
@@ -394,12 +414,15 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
|
|
|
UA_ByteStringArray responseBufArray;
|
|
|
responseBufArray.strings = responseBufs; // the content is deleted in the write function (asynchronous)
|
|
|
responseBufArray.stringsSize = 2;
|
|
|
- connection->write(connection->callbackHandle, responseBufArray);
|
|
|
+ connection->write(connection, responseBufArray);
|
|
|
+
|
|
|
+ if(!messageOnStack)
|
|
|
+ UA_free(message->data);
|
|
|
}
|
|
|
|
|
|
-static void processClose(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
|
|
|
+static void processClose(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg,
|
|
|
+ UA_UInt32 *pos) {
|
|
|
// just read in the sequenceheader
|
|
|
-
|
|
|
UA_UInt32 secureChannelId;
|
|
|
UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
|
|
|
|
|
@@ -408,63 +431,53 @@ static void processClose(UA_Connection *connection, UA_Server *server, const UA_
|
|
|
}
|
|
|
|
|
|
void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {
|
|
|
- UA_Int32 retval = UA_STATUSCODE_GOOD;
|
|
|
UA_UInt32 pos = 0;
|
|
|
UA_TcpMessageHeader tcpMessageHeader;
|
|
|
- // todo: test how far pos advanced must be equal to what is said in the messageheader
|
|
|
do {
|
|
|
- retval = UA_TcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader);
|
|
|
- if(tcpMessageHeader.messageSize < 8){
|
|
|
- printf("The announced size of the message is illegal (smaller than 8), skipping the whole packet\n");
|
|
|
- return;
|
|
|
+ if(UA_TcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader) != UA_STATUSCODE_GOOD) {
|
|
|
+ printf("ERROR: decoding of header failed \n");
|
|
|
+ connection->close(connection);
|
|
|
+ break;
|
|
|
}
|
|
|
+
|
|
|
UA_UInt32 targetpos = pos - 8 + tcpMessageHeader.messageSize;
|
|
|
- if(retval == UA_STATUSCODE_GOOD) {
|
|
|
- // none of the process-functions returns an error its all contained inside.
|
|
|
- switch(tcpMessageHeader.messageType) {
|
|
|
- case UA_MESSAGETYPE_HEL:
|
|
|
- processHello(connection, msg, &pos);
|
|
|
- break;
|
|
|
-
|
|
|
- case UA_MESSAGETYPE_OPN:
|
|
|
- processOpen(connection, server, msg, &pos);
|
|
|
- break;
|
|
|
-
|
|
|
- case UA_MESSAGETYPE_MSG:
|
|
|
- //no break
|
|
|
- // if this fails, the connection is closed (no break on the case)
|
|
|
- if(connection->state == UA_CONNECTION_ESTABLISHED &&
|
|
|
- connection->channel != UA_NULL) {
|
|
|
- processMessage(connection, server, msg, &pos);
|
|
|
- break;
|
|
|
- }
|
|
|
+ switch(tcpMessageHeader.messageType) {
|
|
|
+ case UA_MESSAGETYPE_HEL:
|
|
|
+ processHello(connection, msg, &pos);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UA_MESSAGETYPE_OPN:
|
|
|
+ processOpen(connection, server, msg, &pos);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UA_MESSAGETYPE_MSG:
|
|
|
+ if(connection->state == UA_CONNECTION_ESTABLISHED && connection->channel != UA_NULL)
|
|
|
+ processMessage(connection, server, msg, &pos);
|
|
|
+ else {
|
|
|
#ifdef EXTENSION_STATELESS
|
|
|
//process messages with session zero
|
|
|
if(connection->state == UA_CONNECTION_OPENING &&
|
|
|
connection->channel == UA_NULL) {
|
|
|
processMessage(connection, server, msg, &pos);
|
|
|
//fixme: we need to think about keepalive
|
|
|
- connection->close(connection->callbackHandle);
|
|
|
+ connection->close(connection);
|
|
|
break;
|
|
|
}
|
|
|
+#else
|
|
|
+ connection->close(connection);
|
|
|
#endif
|
|
|
-
|
|
|
- case UA_MESSAGETYPE_CLO:
|
|
|
- connection->state = UA_CONNECTION_CLOSING;
|
|
|
- processClose(connection, server, msg, &pos);
|
|
|
- connection->close(connection->callbackHandle);
|
|
|
- return;
|
|
|
}
|
|
|
- UA_TcpMessageHeader_deleteMembers(&tcpMessageHeader);
|
|
|
- } else {
|
|
|
- printf("TL_Process - ERROR: decoding of header failed \n");
|
|
|
- connection->state = UA_CONNECTION_CLOSING;
|
|
|
- //processClose(connection, server, msg, &pos);
|
|
|
- connection->close(connection->callbackHandle);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UA_MESSAGETYPE_CLO:
|
|
|
+ processClose(connection, server, msg, &pos);
|
|
|
+ connection->close(connection);
|
|
|
+ return;
|
|
|
}
|
|
|
- // todo: more than one message at once..
|
|
|
+
|
|
|
+ UA_TcpMessageHeader_deleteMembers(&tcpMessageHeader);
|
|
|
if(pos != targetpos) {
|
|
|
- printf("The message size was not as announced or an error occurred while processing, skipping to the end of the message.\n");
|
|
|
+ printf("The message size was not as announced or the message could not be processed, skipping to the end of the message.\n");
|
|
|
pos = targetpos;
|
|
|
}
|
|
|
} while(msg->length > (UA_Int32)pos);
|