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 wLogAppender 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,
91 const wLogMessage* cmessage)
92{
93 if (!log || !appender || !cmessage)
94 return FALSE;
95
96 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
97
98 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
99 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix, sizeof(prefix));
100
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);
108 return TRUE;
109}
110
111static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
112 const wLogMessage* message)
113{
114 if (!log || !appender || !message)
115 return FALSE;
116
117 return TRUE;
118}
119
120static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
121 const wLogMessage* message)
122{
123 if (!log || !appender || !message)
124 return FALSE;
125
126 return TRUE;
127}
128
129static BOOL WLog_UdpAppender_Set(wLogAppender* appender, const char* setting, void* value)
130{
131 const char target[] = "target";
132 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
133
134 /* Just check the value string is not empty */
135 if (!value || (strnlen(value, 2) == 0))
136 return FALSE;
137
138 if (strncmp(target, setting, sizeof(target)) != 0)
139 return FALSE;
140
141 udpAppender->targetAddrLen = 0;
142
143 if (udpAppender->host)
144 free(udpAppender->host);
145
146 udpAppender->host = _strdup((const char*)value);
147 return (udpAppender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
148}
149
150static void WLog_UdpAppender_Free(wLogAppender* appender)
151{
152 wLogUdpAppender* udpAppender = NULL;
153
154 if (appender)
155 {
156 udpAppender = (wLogUdpAppender*)appender;
157
158 if (udpAppender->sock != INVALID_SOCKET)
159 {
160 closesocket(udpAppender->sock);
161 udpAppender->sock = INVALID_SOCKET;
162 }
163
164 free(udpAppender->host);
165 free(udpAppender);
166 }
167}
168
169wLogAppender* WLog_UdpAppender_New(wLog* log)
170{
171 DWORD nSize = 0;
172 LPCSTR name = NULL;
173 wLogUdpAppender* appender = (wLogUdpAppender*)calloc(1, sizeof(wLogUdpAppender));
174
175 if (!appender)
176 return NULL;
177
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);
187
188 if (appender->sock == INVALID_SOCKET)
189 goto error_sock;
190
191 name = "WLOG_UDP_TARGET";
192 nSize = GetEnvironmentVariableA(name, NULL, 0);
193
194 if (nSize)
195 {
196 appender->host = (LPSTR)malloc(nSize);
197
198 if (!appender->host)
199 goto error_open;
200
201 if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
202 goto error_open;
203
204 if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
205 goto error_open;
206 }
207 else
208 {
209 appender->host = _strdup("127.0.0.1:20000");
210
211 if (!appender->host)
212 goto error_open;
213 }
214
215 return &appender->common;
216error_open:
217 free(appender->host);
218 closesocket(appender->sock);
219error_sock:
220 free(appender);
221 return NULL;
222}