/lwraft/common/networkutiluniximpl.c

https://github.com/vmware/lightwave · C · 347 lines · 285 code · 49 blank · 13 comment · 56 complexity · a544caca324de2b49315fd8ce7682d52 MD5 · raw file

  1. /*
  2. * Copyright © 2012-2015 VMware, Inc. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the “License”); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an “AS IS” BASIS, without
  10. * warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
  11. * License for the specific language governing permissions and limitations
  12. * under the License.
  13. */
  14. #include "includes.h"
  15. #include <sys/socket.h>
  16. #include <sys/un.h>
  17. #include <sys/ioctl.h>
  18. #include <sys/types.h>
  19. #include <unistd.h>
  20. DWORD
  21. VmDirOpenServerConnectionImpl(
  22. PVM_DIR_CONNECTION *ppConnection
  23. )
  24. {
  25. DWORD dwError = 0;
  26. int socket_fd = -1, on = 1;
  27. struct sockaddr_un address = {0};
  28. PVM_DIR_CONNECTION pConnection = NULL;
  29. socket_fd = socket(PF_UNIX,SOCK_STREAM, 0);
  30. if (socket_fd < 0){
  31. dwError = LwErrnoToWin32Error(errno);
  32. BAIL_ON_VMDIR_ERROR(dwError);
  33. }
  34. if( setsockopt( socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0){
  35. dwError = LwErrnoToWin32Error(errno);
  36. BAIL_ON_VMDIR_ERROR(dwError);
  37. }
  38. unlink (SOCKET_FILE_PATH);
  39. address.sun_family = AF_UNIX;
  40. snprintf (address.sun_path, sizeof(SOCKET_FILE_PATH), SOCKET_FILE_PATH);
  41. if (bind (socket_fd, (struct sockaddr *)&address, sizeof(struct sockaddr_un)) < 0){
  42. dwError = LwErrnoToWin32Error(errno);
  43. BAIL_ON_VMDIR_ERROR(dwError);
  44. }
  45. if (listen (socket_fd, 5) < 0){
  46. dwError = LwErrnoToWin32Error(errno);
  47. BAIL_ON_VMDIR_ERROR(dwError);
  48. }
  49. dwError = VmDirAllocateMemory(sizeof(VM_DIR_CONNECTION), (PVOID *)&pConnection);
  50. BAIL_ON_VMDIR_ERROR(dwError);
  51. pConnection->fd = socket_fd;
  52. *ppConnection = pConnection;
  53. cleanup:
  54. return dwError;
  55. error:
  56. if (ppConnection != NULL){
  57. *ppConnection = NULL;
  58. }
  59. if (socket_fd >=0 ){
  60. close (socket_fd);
  61. }
  62. VMDIR_SAFE_FREE_MEMORY (pConnection);
  63. goto cleanup;
  64. }
  65. VOID
  66. VmDirCloseServerConnectionImpl(
  67. PVM_DIR_CONNECTION pConnection
  68. )
  69. {
  70. if (pConnection->fd >= 0 ){
  71. close (pConnection->fd);
  72. pConnection->fd = -1;
  73. }
  74. }
  75. VOID
  76. VmDirShutdownServerConnectionImpl(
  77. PVM_DIR_CONNECTION pConnection
  78. )
  79. {
  80. VmDirCloseServerConnectionImpl(pConnection);
  81. }
  82. DWORD
  83. VmDirOpenClientConnectionImpl(
  84. PVM_DIR_CONNECTION *ppConnection
  85. )
  86. {
  87. DWORD dwError = 0;
  88. int socket_fd = 0;
  89. struct sockaddr_un address;
  90. PVM_DIR_CONNECTION pConnection = NULL;
  91. socket_fd = socket (PF_UNIX, SOCK_STREAM, 0);
  92. if (socket_fd < 0){
  93. dwError = LwErrnoToWin32Error(errno);
  94. BAIL_ON_VMDIR_ERROR(dwError);
  95. }
  96. memset (&address, 0, sizeof(struct sockaddr_un));
  97. address.sun_family = AF_UNIX;
  98. snprintf (address.sun_path, sizeof(SOCKET_FILE_PATH), SOCKET_FILE_PATH);
  99. if (connect(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) <0)
  100. {
  101. if (errno == ENOENT || errno == ECONNREFUSED)
  102. {
  103. dwError = VMDIR_ERROR_CANNOT_CONNECT_VMDIR;
  104. }
  105. else if (errno == EACCES)
  106. {
  107. dwError = ERROR_ACCESS_DENIED;
  108. }
  109. else
  110. {
  111. dwError = LwErrnoToWin32Error (errno);
  112. }
  113. BAIL_ON_VMDIR_ERROR(dwError);
  114. }
  115. dwError = VmDirAllocateMemory (sizeof(VM_DIR_CONNECTION),(PVOID *)&pConnection);
  116. BAIL_ON_VMDIR_ERROR(dwError);
  117. pConnection->fd = socket_fd;
  118. *ppConnection = pConnection;
  119. cleanup:
  120. return dwError;
  121. error:
  122. if (ppConnection != NULL){
  123. *ppConnection = NULL;
  124. }
  125. if (socket_fd >= 0){
  126. close (socket_fd);
  127. }
  128. VMDIR_SAFE_FREE_MEMORY(pConnection);
  129. goto cleanup;
  130. }
  131. VOID
  132. VmDirCloseClientConnectionImpl(
  133. PVM_DIR_CONNECTION pConnection
  134. )
  135. {
  136. if (pConnection->fd > -1){
  137. close(pConnection->fd);
  138. pConnection->fd = -1;
  139. }
  140. }
  141. DWORD
  142. VmDirAcceptConnectionImpl(
  143. PVM_DIR_CONNECTION pConnection,
  144. PVM_DIR_CONNECTION *ppConnection
  145. )
  146. {
  147. DWORD dwError = 0;
  148. PVM_DIR_CONNECTION pTempConnection = NULL;
  149. int connection_fd = 0;
  150. struct sockaddr_un address = {0};
  151. socklen_t address_length = 0;
  152. connection_fd = accept(pConnection->fd,(struct sockaddr *)&address, &address_length);
  153. if (connection_fd < 0){
  154. dwError = LwErrnoToWin32Error(errno);
  155. BAIL_ON_VMDIR_ERROR(dwError);
  156. }
  157. dwError = VmDirAllocateMemory(sizeof(VM_DIR_CONNECTION),(PVOID *)&pTempConnection);
  158. BAIL_ON_VMDIR_ERROR(dwError);
  159. pTempConnection->fd = connection_fd;
  160. *ppConnection = pTempConnection;
  161. cleanup:
  162. return dwError;
  163. error:
  164. if (pTempConnection){
  165. VMDIR_SAFE_FREE_MEMORY(pTempConnection);
  166. }
  167. if (ppConnection){
  168. *ppConnection = NULL;
  169. }
  170. if (connection_fd >= 0){
  171. close (connection_fd);
  172. }
  173. goto cleanup;
  174. }
  175. DWORD
  176. VmDirReadDataImpl(
  177. PVM_DIR_CONNECTION pConnection,
  178. PBYTE *ppResponse,
  179. PDWORD pdwResponseSize
  180. )
  181. {
  182. DWORD dwError = 0;
  183. ssize_t dwBytesRead = 0;
  184. PBYTE pResponse = NULL;
  185. PBYTE pResponseCursor = NULL;
  186. DWORD dwBytesSent = 0;
  187. DWORD dwTotalBytesRead = 0;
  188. do
  189. {
  190. dwBytesRead = read(pConnection->fd, (PVOID)&dwBytesSent, sizeof (DWORD));
  191. }while (dwBytesRead == -1 && errno == EINTR);
  192. if (dwBytesRead < sizeof (DWORD))
  193. {
  194. dwError = LwErrnoToWin32Error(errno);
  195. BAIL_ON_VMDIR_ERROR (dwError);
  196. }
  197. dwBytesRead = 0;
  198. dwError = VmDirAllocateMemory(
  199. dwBytesSent,
  200. (PVOID *) &pResponse
  201. );
  202. BAIL_ON_VMDIR_ERROR (dwError);
  203. pResponseCursor = pResponse;
  204. while (dwTotalBytesRead < dwBytesSent)
  205. {
  206. DWORD dwBytesToRead = VMDIR_IPC_PACKET_SIZE<(dwBytesSent-dwTotalBytesRead)?
  207. VMDIR_IPC_PACKET_SIZE:
  208. dwBytesSent-dwTotalBytesRead;
  209. do {
  210. dwBytesRead = read(pConnection->fd,pResponseCursor,dwBytesToRead);
  211. }while (dwBytesRead == -1 && errno == EINTR);
  212. if (dwBytesRead == -1)
  213. {
  214. dwError = LwErrnoToWin32Error(errno);
  215. BAIL_ON_VMDIR_ERROR (dwError);
  216. }
  217. else if (dwBytesRead == 0)
  218. {
  219. break;
  220. }
  221. dwTotalBytesRead += dwBytesRead;
  222. pResponseCursor += dwBytesRead;
  223. }
  224. if (dwTotalBytesRead < dwBytesSent){
  225. dwError = ERROR_IO_INCOMPLETE;
  226. BAIL_ON_VMDIR_ERROR(dwError);
  227. }
  228. *pdwResponseSize = dwBytesRead;
  229. *ppResponse = pResponse;
  230. cleanup:
  231. return dwError;
  232. error:
  233. if (ppResponse != NULL){
  234. *ppResponse = NULL;
  235. }
  236. if (pdwResponseSize != NULL){
  237. *pdwResponseSize = 0;
  238. }
  239. VMDIR_SAFE_FREE_MEMORY(pResponse);
  240. goto cleanup;
  241. }
  242. DWORD
  243. VmDirWriteDataImpl(
  244. PVM_DIR_CONNECTION pConnection,
  245. PBYTE pRequest,
  246. DWORD dwRequestSize
  247. )
  248. {
  249. DWORD dwError = 0;
  250. ssize_t dwBytesWritten = 0;
  251. DWORD dwTotalBytesWritten = 0;
  252. PBYTE pRequestCursor = pRequest;
  253. DWORD dwActualRequestSize = dwRequestSize;
  254. do
  255. {
  256. dwBytesWritten = write(pConnection->fd, (PVOID)&dwRequestSize, sizeof (DWORD));
  257. }while (dwBytesWritten == -1 && errno == EINTR);
  258. if (dwBytesWritten < sizeof (DWORD))
  259. {
  260. dwError = LwErrnoToWin32Error(errno);
  261. BAIL_ON_VMDIR_ERROR (dwError);
  262. }
  263. dwBytesWritten = 0;
  264. while (dwRequestSize > 0)
  265. {
  266. DWORD dwBytesToWrite = VMDIR_IPC_PACKET_SIZE<dwRequestSize?VMDIR_IPC_PACKET_SIZE:dwRequestSize;
  267. do
  268. {
  269. dwBytesWritten = write(pConnection->fd,pRequestCursor,dwBytesToWrite);
  270. }while (dwBytesWritten == -1 && errno == EINTR);
  271. if (dwBytesWritten == -1)
  272. {
  273. dwError = LwErrnoToWin32Error(errno);
  274. BAIL_ON_VMDIR_ERROR(dwError);
  275. }
  276. dwTotalBytesWritten += dwBytesWritten;
  277. pRequestCursor += dwBytesWritten;
  278. dwRequestSize -= dwBytesWritten;
  279. }
  280. if (dwActualRequestSize != dwTotalBytesWritten){
  281. dwError = ERROR_IO_INCOMPLETE;
  282. BAIL_ON_VMDIR_ERROR(dwError);
  283. }
  284. cleanup:
  285. return dwError;
  286. error:
  287. goto cleanup;
  288. }
  289. VOID
  290. VmDirFreeConnectionImpl(
  291. PVM_DIR_CONNECTION pConnection
  292. )
  293. {
  294. if (pConnection->fd >= 0){
  295. close(pConnection->fd);
  296. }
  297. VMDIR_SAFE_FREE_MEMORY (pConnection);
  298. }