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