FreeRDP
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 
29 typedef struct
30 {
31  WLOG_APPENDER_COMMON();
32  char* host;
33  struct sockaddr targetAddr;
34  int targetAddrLen;
35  SOCKET sock;
36 } wLogUdpAppender;
37 
38 static BOOL WLog_UdpAppender_Open(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 
82 static BOOL WLog_UdpAppender_Close(wLog* log, wLogAppender* appender)
83 {
84  if (!log || !appender)
85  return FALSE;
86 
87  return TRUE;
88 }
89 
90 static 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 
112 static 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 
121 static 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 
130 static 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 
151 static 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 
170 wLogAppender* 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;
218 error_open:
219  free(appender->host);
220  closesocket(appender->sock);
221 error_sock:
222  free(appender);
223  return NULL;
224 }