21#include <winpr/config.h>
24#include <winpr/environment.h>
25#include <winpr/winsock.h>
33 struct sockaddr targetAddr;
38static BOOL WLog_UdpAppender_Open(WINPR_ATTR_UNUSED wLog* log, wLogAppender* appender)
40 wLogUdpAppender* udpAppender =
nullptr;
41 char addressString[256] = WINPR_C_ARRAY_INIT;
42 struct addrinfo hints = WINPR_C_ARRAY_INIT;
43 struct addrinfo* result = WINPR_C_ARRAY_INIT;
45 char* colonPos =
nullptr;
50 udpAppender = (wLogUdpAppender*)appender;
52 if (udpAppender->targetAddrLen)
55 colonPos = strchr(udpAppender->host,
':');
60 const size_t addrLen = WINPR_ASSERTING_INT_CAST(
size_t, (colonPos - udpAppender->host));
61 memcpy(addressString, udpAppender->host, addrLen);
62 addressString[addrLen] =
'\0';
63 hints.ai_family = AF_INET;
64 hints.ai_socktype = SOCK_DGRAM;
65 status = getaddrinfo(addressString, colonPos + 1, &hints, &result);
70 if (result->ai_addrlen >
sizeof(udpAppender->targetAddr))
76 memcpy(&udpAppender->targetAddr, result->ai_addr, result->ai_addrlen);
77 udpAppender->targetAddrLen = (int)result->ai_addrlen;
82static BOOL WLog_UdpAppender_Close(wLog* log, wLogAppender* appender)
84 return !(!log || !appender);
87static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender,
90 if (!log || !appender || !cmessage)
93 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
95 char prefix[WLOG_MAX_PREFIX_SIZE] = WINPR_C_ARRAY_INIT;
96 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix,
sizeof(prefix));
98 (void)_sendto(udpAppender->sock, prefix, (
int)strnlen(prefix, ARRAYSIZE(prefix)), 0,
99 &udpAppender->targetAddr, udpAppender->targetAddrLen);
100 (void)_sendto(udpAppender->sock, cmessage->TextString,
101 (
int)strnlen(cmessage->TextString, INT_MAX), 0, &udpAppender->targetAddr,
102 udpAppender->targetAddrLen);
103 (void)_sendto(udpAppender->sock,
"\n", 1, 0, &udpAppender->targetAddr,
104 udpAppender->targetAddrLen);
108static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
111 return !(!log || !appender || !message);
114static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
117 return !(!log || !appender || !message);
120static BOOL WLog_UdpAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
122 const char target[] =
"target";
123 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
126 if (!value || (strnlen(value, 2) == 0))
129 if (strncmp(target, setting,
sizeof(target)) != 0)
132 udpAppender->targetAddrLen = 0;
134 if (udpAppender->host)
135 free(udpAppender->host);
137 udpAppender->host = _strdup((
const char*)value);
138 return (udpAppender->host !=
nullptr) && WLog_UdpAppender_Open(
nullptr, appender);
141static void WLog_UdpAppender_Free(wLogAppender* appender)
143 wLogUdpAppender* udpAppender =
nullptr;
147 udpAppender = (wLogUdpAppender*)appender;
149 if (udpAppender->sock != INVALID_SOCKET)
151 closesocket(udpAppender->sock);
152 udpAppender->sock = INVALID_SOCKET;
155 free(udpAppender->host);
160wLogAppender* WLog_UdpAppender_New(wLog* log)
163 LPCSTR name =
nullptr;
164 wLogUdpAppender* appender = (wLogUdpAppender*)calloc(1,
sizeof(wLogUdpAppender));
169 appender->common.Type = WLOG_APPENDER_UDP;
170 appender->common.Open = WLog_UdpAppender_Open;
171 appender->common.Close = WLog_UdpAppender_Close;
172 appender->common.WriteMessage = WLog_UdpAppender_WriteMessage;
173 appender->common.WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
174 appender->common.WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
175 appender->common.Free = WLog_UdpAppender_Free;
176 appender->common.Set = WLog_UdpAppender_Set;
177 appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
179 if (appender->sock == INVALID_SOCKET)
182 name =
"WLOG_UDP_TARGET";
183 nSize = GetEnvironmentVariableA(name,
nullptr, 0);
187 appender->host = (LPSTR)malloc(nSize);
192 if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
195 if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
200 appender->host = _strdup(
"127.0.0.1:20000");
206 return &appender->common;
208 free(appender->host);
209 closesocket(appender->sock);