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 = NULL;
41 char addressString[256] = { 0 };
42 struct addrinfo hints = { 0 };
43 struct addrinfo* result = { 0 };
45 char* colonPos = NULL;
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 if (!log || !appender)
90static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender,
93 if (!log || !appender || !cmessage)
96 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
98 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
99 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix,
sizeof(prefix));
101 (void)_sendto(udpAppender->sock, prefix, (
int)strnlen(prefix, ARRAYSIZE(prefix)), 0,
102 &udpAppender->targetAddr, udpAppender->targetAddrLen);
103 (void)_sendto(udpAppender->sock, cmessage->TextString,
104 (
int)strnlen(cmessage->TextString, INT_MAX), 0, &udpAppender->targetAddr,
105 udpAppender->targetAddrLen);
106 (void)_sendto(udpAppender->sock,
"\n", 1, 0, &udpAppender->targetAddr,
107 udpAppender->targetAddrLen);
111static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
114 if (!log || !appender || !message)
120static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
123 if (!log || !appender || !message)
129static BOOL WLog_UdpAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
131 const char target[] =
"target";
132 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
135 if (!value || (strnlen(value, 2) == 0))
138 if (strncmp(target, setting,
sizeof(target)) != 0)
141 udpAppender->targetAddrLen = 0;
143 if (udpAppender->host)
144 free(udpAppender->host);
146 udpAppender->host = _strdup((
const char*)value);
147 return (udpAppender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
150static void WLog_UdpAppender_Free(wLogAppender* appender)
152 wLogUdpAppender* udpAppender = NULL;
156 udpAppender = (wLogUdpAppender*)appender;
158 if (udpAppender->sock != INVALID_SOCKET)
160 closesocket(udpAppender->sock);
161 udpAppender->sock = INVALID_SOCKET;
164 free(udpAppender->host);
169wLogAppender* WLog_UdpAppender_New(wLog* log)
173 wLogUdpAppender* appender = (wLogUdpAppender*)calloc(1,
sizeof(wLogUdpAppender));
178 appender->common.Type = WLOG_APPENDER_UDP;
179 appender->common.Open = WLog_UdpAppender_Open;
180 appender->common.Close = WLog_UdpAppender_Close;
181 appender->common.WriteMessage = WLog_UdpAppender_WriteMessage;
182 appender->common.WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
183 appender->common.WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
184 appender->common.Free = WLog_UdpAppender_Free;
185 appender->common.Set = WLog_UdpAppender_Set;
186 appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
188 if (appender->sock == INVALID_SOCKET)
191 name =
"WLOG_UDP_TARGET";
192 nSize = GetEnvironmentVariableA(name, NULL, 0);
196 appender->host = (LPSTR)malloc(nSize);
201 if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
204 if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
209 appender->host = _strdup(
"127.0.0.1:20000");
215 return &appender->common;
217 free(appender->host);
218 closesocket(appender->sock);