|
@@ -323,6 +323,7 @@ typedef struct ConnectionEntry {
|
|
|
} ConnectionEntry;
|
|
|
|
|
|
typedef struct {
|
|
|
+ UA_Logger logger;
|
|
|
UA_ConnectionConfig conf;
|
|
|
UA_UInt16 port;
|
|
|
UA_Int32 serverSockets[FD_SETSIZE];
|
|
@@ -357,7 +358,7 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
|
|
|
if(setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY,
|
|
|
(const char *)&dummy, sizeof(dummy)) < 0) {
|
|
|
UA_LOG_SOCKET_ERRNO_WRAP(
|
|
|
- UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Cannot set socket option TCP_NODELAY. Error: %s",
|
|
|
errno_str));
|
|
|
return UA_STATUSCODE_BADUNEXPECTEDERROR;
|
|
@@ -371,11 +372,11 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
|
|
|
remote_name, sizeof(remote_name),
|
|
|
NULL, 0, NI_NUMERICHOST);
|
|
|
if(res == 0) {
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | New connection over TCP from %s",
|
|
|
(int)newsockfd, remote_name);
|
|
|
} else {
|
|
|
- UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | New connection over TCP, "
|
|
|
"getnameinfo failed with error: %s",
|
|
|
(int)newsockfd, errno_str));
|
|
@@ -418,7 +419,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
|
|
|
if(newsock < 0)
|
|
|
#endif
|
|
|
{
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Error opening the server socket");
|
|
|
return;
|
|
|
}
|
|
@@ -432,7 +433,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
|
|
|
if(ai->ai_family == AF_INET6 &&
|
|
|
setsockopt(newsock, IPPROTO_IPV6, IPV6_V6ONLY,
|
|
|
(const char*)&optval, sizeof(optval)) == -1) {
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Could not set an IPv6 socket to IPv6 only");
|
|
|
CLOSESOCKET(newsock);
|
|
|
return;
|
|
@@ -440,7 +441,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
|
|
|
#endif
|
|
|
if(setsockopt(newsock, SOL_SOCKET, SO_REUSEADDR,
|
|
|
(const char *)&optval, sizeof(optval)) == -1) {
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Could not make the socket reusable");
|
|
|
CLOSESOCKET(newsock);
|
|
|
return;
|
|
@@ -448,7 +449,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
|
|
|
|
|
|
|
|
|
if(socket_set_nonblocking(newsock) != UA_STATUSCODE_GOOD) {
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Could not set the server socket to nonblocking");
|
|
|
CLOSESOCKET(newsock);
|
|
|
return;
|
|
@@ -457,7 +458,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
|
|
|
/* Bind socket to address */
|
|
|
if(bind(newsock, ai->ai_addr, WIN32_INT ai->ai_addrlen) < 0) {
|
|
|
UA_LOG_SOCKET_ERRNO_WRAP(
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Error binding a server socket: %s", errno_str));
|
|
|
CLOSESOCKET(newsock);
|
|
|
return;
|
|
@@ -466,7 +467,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
|
|
|
/* Start listening */
|
|
|
if(listen(newsock, MAXBACKLOG) < 0) {
|
|
|
UA_LOG_SOCKET_ERRNO_WRAP(
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Error listening on server socket: %s", errno_str));
|
|
|
CLOSESOCKET(newsock);
|
|
|
return;
|
|
@@ -550,7 +551,7 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
|
|
|
addServerSocket(layer, ai);
|
|
|
freeaddrinfo(res);
|
|
|
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"TCP network layer listening on %.*s",
|
|
|
(int)nl->discoveryUrl.length, nl->discoveryUrl.data);
|
|
|
return UA_STATUSCODE_GOOD;
|
|
@@ -593,7 +594,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
|
|
|
struct timeval tmptv = {0, timeout * 1000};
|
|
|
if (select(highestfd+1, &fdset, NULL, &errset, &tmptv) < 0) {
|
|
|
UA_LOG_SOCKET_ERRNO_WRAP(
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Socket select failed with %s", errno_str));
|
|
|
// we will retry, so do not return bad
|
|
|
return UA_STATUSCODE_GOOD;
|
|
@@ -615,7 +616,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
|
|
|
#endif
|
|
|
continue;
|
|
|
|
|
|
- UA_LOG_TRACE(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | New TCP connection on server socket %i",
|
|
|
(int)newsockfd, layer->serverSockets[i]);
|
|
|
|
|
@@ -628,7 +629,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
|
|
|
LIST_FOREACH_SAFE(e, &layer->connections, pointers, e_tmp) {
|
|
|
if ((e->connection.state == UA_CONNECTION_OPENING) &&
|
|
|
(now > (e->connection.openingDate + (NOHELLOTIMEOUT * UA_DATETIME_MSEC)))){
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | Closed by the server (no Hello Message)",
|
|
|
e->connection.sockfd);
|
|
|
LIST_REMOVE(e, pointers);
|
|
@@ -641,7 +642,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
|
|
|
!UA_fd_isset(e->connection.sockfd, &fdset))
|
|
|
continue;
|
|
|
|
|
|
- UA_LOG_TRACE(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | Activity on the socket",
|
|
|
e->connection.sockfd);
|
|
|
|
|
@@ -655,11 +656,11 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
|
|
|
} else if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) {
|
|
|
/* The socket is shutdown but not closed */
|
|
|
if(e->connection.state != UA_CONNECTION_CLOSED) {
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | Closed by the client",
|
|
|
e->connection.sockfd);
|
|
|
} else {
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection %i | Closed by the server",
|
|
|
e->connection.sockfd);
|
|
|
}
|
|
@@ -674,7 +675,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
|
|
|
static void
|
|
|
ServerNetworkLayerTCP_stop(UA_ServerNetworkLayer *nl, UA_Server *server) {
|
|
|
ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle;
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Shutting down the TCP network layer");
|
|
|
|
|
|
/* Close the server sockets */
|
|
@@ -718,7 +719,7 @@ ServerNetworkLayerTCP_deleteMembers(UA_ServerNetworkLayer *nl) {
|
|
|
}
|
|
|
|
|
|
UA_ServerNetworkLayer
|
|
|
-UA_ServerNetworkLayerTCP(UA_ConnectionConfig conf, UA_UInt16 port) {
|
|
|
+UA_ServerNetworkLayerTCP(UA_ConnectionConfig conf, UA_UInt16 port, UA_Logger logger) {
|
|
|
UA_ServerNetworkLayer nl;
|
|
|
memset(&nl, 0, sizeof(UA_ServerNetworkLayer));
|
|
|
ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP*)
|
|
@@ -726,6 +727,7 @@ UA_ServerNetworkLayerTCP(UA_ConnectionConfig conf, UA_UInt16 port) {
|
|
|
if(!layer)
|
|
|
return nl;
|
|
|
|
|
|
+ layer->logger = (logger != NULL ? logger : UA_Log_Stdout);
|
|
|
layer->conf = conf;
|
|
|
layer->port = port;
|
|
|
|
|
@@ -752,7 +754,8 @@ ClientNetworkLayerTCP_close(UA_Connection *connection) {
|
|
|
|
|
|
UA_Connection
|
|
|
UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
- const char *endpointUrl, const UA_UInt32 timeout) {
|
|
|
+ const char *endpointUrl, const UA_UInt32 timeout,
|
|
|
+ UA_Logger logger) {
|
|
|
#ifdef _WIN32
|
|
|
WORD wVersionRequested;
|
|
|
WSADATA wsaData;
|
|
@@ -760,6 +763,10 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
WSAStartup(wVersionRequested, &wsaData);
|
|
|
#endif
|
|
|
|
|
|
+ if(logger == NULL) {
|
|
|
+ logger = UA_Log_Stdout;
|
|
|
+ }
|
|
|
+
|
|
|
UA_Connection connection;
|
|
|
memset(&connection, 0, sizeof(UA_Connection));
|
|
|
connection.state = UA_CONNECTION_CLOSED;
|
|
@@ -783,7 +790,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
UA_parseEndpointUrl(&endpointUrlString, &hostnameString,
|
|
|
&port, &pathString);
|
|
|
if(parse_retval != UA_STATUSCODE_GOOD || hostnameString.length > 511) {
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Server url is invalid: %s", endpointUrl);
|
|
|
return connection;
|
|
|
}
|
|
@@ -792,7 +799,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
|
|
|
if(port == 0) {
|
|
|
port = 4840;
|
|
|
- UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_INFO(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"No port defined, using default port %d", port);
|
|
|
}
|
|
|
|
|
@@ -812,12 +819,12 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
int error = getaddrinfo(hostname, portStr, &hints, &server);
|
|
|
if(error != 0 || !server) {
|
|
|
#if !defined(UA_FREERTOS)
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
|
|
|
"DNS lookup of %s failed with error %s",
|
|
|
hostname, gai_strerror(error));
|
|
|
#else
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"DNS lookup of %s failed with error",
|
|
|
hostname);
|
|
|
#endif
|
|
@@ -842,7 +849,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
#else
|
|
|
if(clientsockfd < 0) {
|
|
|
#endif
|
|
|
- UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Could not create client socket: %s", errno_str));
|
|
|
freeaddrinfo(server);
|
|
|
return connection;
|
|
@@ -855,7 +862,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
|
|
|
/* Non blocking connect to be able to timeout */
|
|
|
if (socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) {
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Could not set the client socket to nonblocking");
|
|
|
ClientNetworkLayerTCP_close(&connection);
|
|
|
freeaddrinfo(server);
|
|
@@ -868,7 +875,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
if ((error == -1) && (errno__ != ERR_CONNECTION_PROGRESS)) {
|
|
|
ClientNetworkLayerTCP_close(&connection);
|
|
|
UA_LOG_SOCKET_ERRNO_WRAP(
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection to %s failed with error: %s",
|
|
|
endpointUrl, errno_str));
|
|
|
freeaddrinfo(server);
|
|
@@ -908,7 +915,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
/* connection refused happens on localhost or local ip without timeout */
|
|
|
if (so_error != ECONNREFUSED) {
|
|
|
ClientNetworkLayerTCP_close(&connection);
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Connection to %s failed with error: %s",
|
|
|
endpointUrl, strerror(ret == 0 ? so_error : errno__));
|
|
|
freeaddrinfo(server);
|
|
@@ -937,7 +944,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
/* connection timeout */
|
|
|
if (connection.state != UA_CONNECTION_CLOSED)
|
|
|
ClientNetworkLayerTCP_close(&connection);
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Trying to connect to %s timed out",
|
|
|
endpointUrl);
|
|
|
return connection;
|
|
@@ -946,7 +953,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
|
|
|
/* We are connected. Reset socket to blocking */
|
|
|
if(socket_set_blocking(clientsockfd) != UA_STATUSCODE_GOOD) {
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Could not set the client socket to blocking");
|
|
|
ClientNetworkLayerTCP_close(&connection);
|
|
|
return connection;
|
|
@@ -957,7 +964,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
|
|
|
int sso_result = setsockopt(connection.sockfd, SOL_SOCKET,
|
|
|
SO_NOSIGPIPE, (void*)&val, sizeof(val));
|
|
|
if(sso_result < 0)
|
|
|
- UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
|
|
|
+ UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
|
|
|
"Couldn't set SO_NOSIGPIPE");
|
|
|
#endif
|
|
|
|