Exemplo n.º 1
0
/* Takes the raw message from the network layer */
void
UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection,
                               const UA_ByteString *message) {
    UA_SecureChannel *channel = connection->channel;
    if(channel) {
        /* Assemble chunks in the securechannel and process complete messages */
        UA_StatusCode retval = 
            UA_SecureChannel_processChunks(channel, message,
                 (UA_ProcessMessageCallback*)UA_Server_processSecureChannelMessage, server);
        if(retval != UA_STATUSCODE_GOOD)
            UA_LOG_TRACE_CHANNEL(server->config.logger, channel,
                                 "Procesing chunkgs resulted in error code 0x%08x", retval);
    } else {
        /* Process messages without a channel and no chunking */
        size_t offset = 0;
        UA_TcpMessageHeader tcpMessageHeader;
        UA_StatusCode retval = UA_TcpMessageHeader_decodeBinary(message, &offset, &tcpMessageHeader);
        if(retval != UA_STATUSCODE_GOOD) {
            connection->close(connection);
            return;
        }

        /* Dispatch according to the message type */
        switch(tcpMessageHeader.messageTypeAndChunkType & 0x00ffffff) {
        case UA_MESSAGETYPE_HEL:
            UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
                         "Connection %i | Process HEL message", connection->sockfd);
            processHEL(connection, message, &offset);
            break;
        case UA_MESSAGETYPE_OPN: {
            UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
                         "Connection %i | Process OPN message", connection->sockfd);
            UA_UInt32 channelId = 0;
            retval = UA_UInt32_decodeBinary(message, &offset, &channelId);
            if(retval != UA_STATUSCODE_GOOD)
                connection->close(connection);
            UA_ByteString offsetMessage = (UA_ByteString){
                .data = message->data + 12, .length = message->length - 12};
            processOPN(server, connection, channelId, &offsetMessage);
            break; }
        case UA_MESSAGETYPE_MSG:
            UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
                         "Connection %i | Processing a MSG message not possible "
                         "without a SecureChannel", connection->sockfd);
            connection->close(connection);
            break;
        case UA_MESSAGETYPE_CLO:
            UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
                         "Connection %i | Processing a CLO message not possible "
                         "without a SecureChannel", connection->sockfd);
            connection->close(connection);
            break;
        default:
            UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
                         "Connection %i | Unknown message type", connection->sockfd);
            connection->close(connection);
        }
    }
}
Exemplo n.º 2
0
UA_StatusCode
UA_Client_connect_iterate(UA_Client *client) {
    UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT,
                 "Client connect iterate");
    if (client->connection.state == UA_CONNECTION_ESTABLISHED){
        if(client->state < UA_CLIENTSTATE_WAITING_FOR_ACK) {
            client->connectStatus = sendHELMessage(client);
            if(client->connectStatus == UA_STATUSCODE_GOOD) {
                setClientState(client, UA_CLIENTSTATE_WAITING_FOR_ACK);
            } else {
                client->connection.close(&client->connection);
                client->connection.free(&client->connection);
            }
            return client->connectStatus;
        }
    }

    /* If server is not connected */
    if(client->connection.state == UA_CONNECTION_CLOSED) {
        client->connectStatus = UA_STATUSCODE_BADCONNECTIONCLOSED;
        UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK,
                     "No connection to server.");
    }

    if(client->connectStatus != UA_STATUSCODE_GOOD) {
        client->connection.close(&client->connection);
        client->connection.free(&client->connection);
    }

    return client->connectStatus;
}
Exemplo n.º 3
0
UA_StatusCode
UA_Client_connect_async(UA_Client *client, const char *endpointUrl,
                        UA_ClientAsyncServiceCallback callback,
                        void *userdata) {
    UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT,
                 "Client internal async");

    if(client->state >= UA_CLIENTSTATE_WAITING_FOR_ACK)
        return UA_STATUSCODE_GOOD;

    UA_ChannelSecurityToken_init(&client->channel.securityToken);
    client->channel.state = UA_SECURECHANNELSTATE_FRESH;
    client->endpointsHandshake = true;
    client->channel.sendSequenceNumber = 0;
    client->requestId = 0;

    UA_String_deleteMembers(&client->endpointUrl);
    client->endpointUrl = UA_STRING_ALLOC(endpointUrl);

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    client->connection =
        client->config.initConnectionFunc(client->config.localConnectionConfig,
                                          client->endpointUrl,
                                          client->config.timeout, &client->config.logger);
    if(client->connection.state != UA_CONNECTION_OPENING) {
        UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT,
                     "Could not init async connection");
        retval = UA_STATUSCODE_BADCONNECTIONCLOSED;
        goto cleanup;
    }

    /* Set the channel SecurityMode if not done so far */
    if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID)
        client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE;

    /* Set the channel SecurityPolicy if not done so far */
    if(!client->channel.securityPolicy) {
        UA_SecurityPolicy *sp =
            getSecurityPolicy(client, UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"));
        if(!sp) {
            retval = UA_STATUSCODE_BADINTERNALERROR;
            goto cleanup;
        }
        UA_ByteString remoteCertificate = UA_BYTESTRING_NULL;
        retval = UA_SecureChannel_setSecurityPolicy(&client->channel, sp,
                                                    &remoteCertificate);
        if(retval != UA_STATUSCODE_GOOD)
            goto cleanup;
    }

    client->asyncConnectCall.callback = callback;
    client->asyncConnectCall.userdata = userdata;

    if(!client->connection.connectCallbackID) {
        UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT,
                     "Adding async connection callback");
        retval = UA_Client_addRepeatedCallback(
                     client, client->config.pollConnectionFunc, &client->connection, 100.0,
                     &client->connection.connectCallbackID);
        if(retval != UA_STATUSCODE_GOOD)
            goto cleanup;
    }

    retval = UA_SecureChannel_generateLocalNonce(&client->channel);
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    /* Delete async service. TODO: Move this from connect to the disconnect/cleanup phase */
    UA_Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSHUTDOWN);

#ifdef UA_ENABLE_SUBSCRIPTIONS
    client->currentlyOutStandingPublishRequests = 0;
#endif

    UA_NodeId_deleteMembers(&client->authenticationToken);

    /* Generate new local and remote key */
    retval = UA_SecureChannel_generateNewKeys(&client->channel);
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    return retval;

 cleanup:
    UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT,
                 "Failure during async connect");
    UA_Client_disconnect(client);
    return retval;
}