FreeRDP
Loading...
Searching...
No Matches
UdpAppender.c
1
21#include <winpr/config.h>
22
23#include <winpr/crt.h>
24#include <winpr/environment.h>
25#include <winpr/winsock.h>
26
27#include "wlog.h"
28
29typedef struct
30{
31 WLOG_APPENDER_COMMON();
32 char* host;
33 struct sockaddr targetAddr;
34 int targetAddrLen;
35 SOCKET sock;
36} wLogUdpAppender;
37
38static BOOL WLog_UdpAppender_Open(WINPR_ATTR_UNUSED wLog* log, wLogAppender* appender)
39{
40 wLogUdpAppender* udpAppender = NULL;
41 char addressString[256] = { 0 };
42 struct addrinfo hints = { 0 };
43 struct addrinfo* result = { 0 };
44 int status = 0;
45 char* colonPos = NULL;
46
47 if (!appender)
48 return FALSE;
49
50 udpAppender = (wLogUdpAppender*)appender;
51
52 if (udpAppender->targetAddrLen) /* already opened */
53 return TRUE;
54
55 colonPos = strchr(udpAppender->host, ':');
56
57 if (!colonPos)
58 return FALSE;
59
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);
66
67 if (status != 0)
68 return FALSE;
69
70 if (result->ai_addrlen > sizeof(udpAppender->targetAddr))
71 {
72 freeaddrinfo(result);
73 return FALSE;
74 }
75
76 memcpy(&udpAppender->targetAddr, result->ai_addr, result->ai_addrlen);
77 udpAppender->targetAddrLen = (int)result->ai_addrlen;
78 freeaddrinfo(result);
79 return TRUE;
80}
81
82static BOOL WLog_UdpAppender_Close(wLog* log, wLogAppender* appender)
83{
84 if (!log || !appender)
85 return FALSE;
86
87 return TRUE;
88}
89
90static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
91{
92 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
93 wLogUdpAppender* udpAppender = NULL;
94
95 if (!log || !appender || !message)
96 return FALSE;
97
98 udpAppender = (wLogUdpAppender*)appender;
99 message->PrefixString = prefix;
100 WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
101 (void)_sendto(udpAppender->sock, message->PrefixString,
102 (int)strnlen(message->PrefixString, INT_MAX), 0, &udpAppender->targetAddr,
103 udpAppender->targetAddrLen);
104 (void)_sendto(udpAppender->sock, message->TextString,
105 (int)strnlen(message->TextString, INT_MAX), 0, &udpAppender->targetAddr,
106 udpAppender->targetAddrLen);
107 (void)_sendto(udpAppender->sock, "\n", 1, 0, &udpAppender->targetAddr,
108 udpAppender->targetAddrLen);
109 return TRUE;
110}
111
112static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
113 wLogMessage* message)
114{
115 if (!log || !appender || !message)
116 return FALSE;
117
118 return TRUE;
119}
120
121static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
122 wLogMessage* message)
123{
124 if (!log || !appender || !message)
125 return FALSE;
126
127 return TRUE;
128}
129
130static BOOL WLog_UdpAppender_Set(wLogAppender* appender, const char* setting, void* value)
131{
132 const char target[] = "target";
133 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
134
135 /* Just check the value string is not empty */
136 if (!value || (strnlen(value, 2) == 0))
137 return FALSE;
138
139 if (strncmp(target, setting, sizeof(target)) != 0)
140 return FALSE;
141
142 udpAppender->targetAddrLen = 0;
143
144 if (udpAppender->host)
145 free(udpAppender->host);
146
147 udpAppender->host = _strdup((const char*)value);
148 return (udpAppender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
149}
150
151static void WLog_UdpAppender_Free(wLogAppender* appender)
152{
153 wLogUdpAppender* udpAppender = NULL;
154
155 if (appender)
156 {
157 udpAppender = (wLogUdpAppender*)appender;
158
159 if (udpAppender->sock != INVALID_SOCKET)
160 {
161 closesocket(udpAppender->sock);
162 udpAppender->sock = INVALID_SOCKET;
163 }
164
165 free(udpAppender->host);
166 free(udpAppender);
167 }
168}
169
170wLogAppender* WLog_UdpAppender_New(wLog* log)
171{
172 wLogUdpAppender* appender = NULL;
173 DWORD nSize = 0;
174 LPCSTR name = NULL;
175 appender = (wLogUdpAppender*)calloc(1, sizeof(wLogUdpAppender));
176
177 if (!appender)
178 return NULL;
179
180 appender->Type = WLOG_APPENDER_UDP;
181 appender->Open = WLog_UdpAppender_Open;
182 appender->Close = WLog_UdpAppender_Close;
183 appender->WriteMessage = WLog_UdpAppender_WriteMessage;
184 appender->WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
185 appender->WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
186 appender->Free = WLog_UdpAppender_Free;
187 appender->Set = WLog_UdpAppender_Set;
188 appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
189
190 if (appender->sock == INVALID_SOCKET)
191 goto error_sock;
192
193 name = "WLOG_UDP_TARGET";
194 nSize = GetEnvironmentVariableA(name, NULL, 0);
195
196 if (nSize)
197 {
198 appender->host = (LPSTR)malloc(nSize);
199
200 if (!appender->host)
201 goto error_open;
202
203 if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
204 goto error_open;
205
206 if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
207 goto error_open;
208 }
209 else
210 {
211 appender->host = _strdup("127.0.0.1:20000");
212
213 if (!appender->host)
214 goto error_open;
215 }
216
217 return (wLogAppender*)appender;
218error_open:
219 free(appender->host);
220 closesocket(appender->sock);
221error_sock:
222 free(appender);
223 return NULL;
224}