socket.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. socket.c
  5. Abstract:
  6. This module implements support for socket-based communication in user mode.
  7. Author:
  8. Evan Green 3-May-2013
  9. Environment:
  10. User Mode
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "osbasep.h"
  16. //
  17. // ---------------------------------------------------------------- Definitions
  18. //
  19. //
  20. // ------------------------------------------------------ Data Type Definitions
  21. //
  22. //
  23. // ----------------------------------------------- Internal Function Prototypes
  24. //
  25. //
  26. // -------------------------------------------------------------------- Globals
  27. //
  28. //
  29. // ------------------------------------------------------------------ Functions
  30. //
  31. OS_API
  32. KSTATUS
  33. OsSocketCreatePair (
  34. NET_DOMAIN_TYPE Domain,
  35. NET_SOCKET_TYPE Type,
  36. ULONG Protocol,
  37. ULONG OpenFlags,
  38. HANDLE Sockets[2]
  39. )
  40. /*++
  41. Routine Description:
  42. This routine creates a pair of sockets that are connected to each other.
  43. Arguments:
  44. Domain - Supplies the network domain to use on the socket.
  45. Type - Supplies the socket connection type.
  46. Protocol - Supplies the raw protocol value used on the network.
  47. OpenFlags - Supplies an optional bitfield of open flags for the new socket.
  48. Only SYS_OPEN_FLAG_NON_BLOCKING and SYS_OPEN_FLAG_CLOSE_ON_EXECUTE
  49. are accepted.
  50. Sockets - Supplies an array where the two handles to the connected
  51. sockets will be returned on success.
  52. Return Value:
  53. Status code.
  54. --*/
  55. {
  56. SYSTEM_CALL_SOCKET_CREATE_PAIR Parameters;
  57. Parameters.Domain = Domain;
  58. Parameters.Type = Type;
  59. Parameters.Protocol = Protocol;
  60. Parameters.OpenFlags = OpenFlags;
  61. OsSystemCall(SystemCallSocketCreatePair, &Parameters);
  62. Sockets[0] = Parameters.Socket1;
  63. Sockets[1] = Parameters.Socket2;
  64. return Parameters.Status;
  65. }
  66. OS_API
  67. KSTATUS
  68. OsSocketCreate (
  69. NET_DOMAIN_TYPE Domain,
  70. NET_SOCKET_TYPE Type,
  71. ULONG Protocol,
  72. ULONG OpenFlags,
  73. PHANDLE Socket
  74. )
  75. /*++
  76. Routine Description:
  77. This routine creates a new socket for communication.
  78. Arguments:
  79. Domain - Supplies the network domain to use for the socket.
  80. Type - Supplies the socket type.
  81. Protocol - Supplies the raw protocol value to use for the socket. This is
  82. network specific.
  83. OpenFlags - Supplies an optional bitfield of open flags for the new socket.
  84. Only SYS_OPEN_FLAG_NON_BLOCKING and SYS_OPEN_FLAG_CLOSE_ON_EXECUTE
  85. are accepted.
  86. Socket - Supplies a pointer where the new socket handle will be returned on
  87. success.
  88. Return Value:
  89. Status code.
  90. --*/
  91. {
  92. SYSTEM_CALL_SOCKET_CREATE Request;
  93. Request.Domain = Domain;
  94. Request.Type = Type;
  95. Request.Protocol = Protocol;
  96. Request.OpenFlags = OpenFlags;
  97. OsSystemCall(SystemCallSocketCreate, &Request);
  98. *Socket = Request.Socket;
  99. return Request.Status;
  100. }
  101. OS_API
  102. KSTATUS
  103. OsSocketBind (
  104. HANDLE Socket,
  105. PNETWORK_ADDRESS Address,
  106. PSTR Path,
  107. UINTN PathSize
  108. )
  109. /*++
  110. Routine Description:
  111. This routine binds a newly created socket to a local address.
  112. Arguments:
  113. Socket - Supplies a handle to the fresh socket.
  114. Address - Supplies a pointer to the local network address to bind to.
  115. Path - Supplies a pointer to the path to bind to in the case that this is
  116. a local (Unix) socket.
  117. PathSize - Supplies the size of the path in bytes including the null
  118. terminator.
  119. Return Value:
  120. Status code.
  121. --*/
  122. {
  123. SYSTEM_CALL_SOCKET_BIND Request;
  124. Request.Socket = Socket;
  125. RtlCopyMemory(&(Request.Address), Address, sizeof(NETWORK_ADDRESS));
  126. Request.Path = Path;
  127. Request.PathSize = PathSize;
  128. OsSystemCall(SystemCallSocketBind, &Request);
  129. return Request.Status;
  130. }
  131. OS_API
  132. KSTATUS
  133. OsSocketListen (
  134. HANDLE Socket,
  135. ULONG SuggestedBacklog
  136. )
  137. /*++
  138. Routine Description:
  139. This routine activates a socket, making it eligible to accept new
  140. incoming connections.
  141. Arguments:
  142. Socket - Supplies the socket to activate.
  143. SuggestedBacklog - Supplies a suggestion to the kernel as to the number of
  144. un-accepted incoming connections to queue up before incoming
  145. connections are refused.
  146. Return Value:
  147. Status code.
  148. --*/
  149. {
  150. SYSTEM_CALL_SOCKET_LISTEN Request;
  151. Request.Socket = Socket;
  152. Request.BacklogCount = SuggestedBacklog;
  153. OsSystemCall(SystemCallSocketListen, &Request);
  154. return Request.Status;
  155. }
  156. OS_API
  157. KSTATUS
  158. OsSocketAccept (
  159. HANDLE Socket,
  160. PHANDLE NewSocket,
  161. PNETWORK_ADDRESS Address,
  162. PSTR RemotePath,
  163. PUINTN RemotePathSize,
  164. ULONG OpenFlags
  165. )
  166. /*++
  167. Routine Description:
  168. This routine accepts an incoming connection on a listening socket and spins
  169. it off into a new socket. This routine will block until an incoming
  170. connection request is received.
  171. Arguments:
  172. Socket - Supplies the listening socket to accept a new connection from.
  173. NewSocket - Supplies a pointer where a new socket representing the
  174. incoming connection will be returned on success.
  175. Address - Supplies an optional pointer where the address of the remote host
  176. will be returned.
  177. RemotePath - Supplies a pointer where the remote path of the client socket
  178. will be copied on success. This only applies to local sockets.
  179. RemotePathSize - Supplies a pointer that on input contains the size of the
  180. remote path buffer. On output, contains the true size of the remote
  181. path, even if it was bigger than the input.
  182. OpenFlags - Supplies an optional bitfield of open flags for the new socket.
  183. Only SYS_OPEN_FLAG_NON_BLOCKING and SYS_OPEN_FLAG_CLOSE_ON_EXECUTE
  184. are accepted.
  185. Return Value:
  186. Status code.
  187. --*/
  188. {
  189. SYSTEM_CALL_SOCKET_ACCEPT Request;
  190. Request.Socket = Socket;
  191. Request.NewSocket = INVALID_HANDLE;
  192. Request.RemotePath = RemotePath;
  193. Request.RemotePathSize = 0;
  194. if (RemotePathSize != NULL) {
  195. Request.RemotePathSize = *RemotePathSize;
  196. }
  197. Request.OpenFlags = OpenFlags;
  198. OsSystemCall(SystemCallSocketAccept, &Request);
  199. *NewSocket = Request.NewSocket;
  200. if (Address != NULL) {
  201. RtlCopyMemory(Address, &(Request.Address), sizeof(NETWORK_ADDRESS));
  202. }
  203. if (RemotePathSize != NULL) {
  204. *RemotePathSize = Request.RemotePathSize;
  205. }
  206. return Request.Status;
  207. }
  208. OS_API
  209. KSTATUS
  210. OsSocketConnect (
  211. HANDLE Socket,
  212. PNETWORK_ADDRESS Address,
  213. PSTR RemotePath,
  214. UINTN RemotePathSize
  215. )
  216. /*++
  217. Routine Description:
  218. This routine attempts to establish a new outgoing connection on a socket.
  219. Arguments:
  220. Socket - Supplies a handle to the fresh socket to use to establish the
  221. connection.
  222. Address - Supplies a pointer to the destination socket address.
  223. RemotePath - Supplies a pointer to the path to connect to, if this is a
  224. local socket.
  225. RemotePathSize - Supplies the size of the remote path buffer in bytes,
  226. including the null terminator.
  227. Return Value:
  228. Status code.
  229. --*/
  230. {
  231. SYSTEM_CALL_SOCKET_CONNECT Request;
  232. Request.Socket = Socket;
  233. RtlCopyMemory(&(Request.Address), Address, sizeof(NETWORK_ADDRESS));
  234. Request.RemotePath = RemotePath;
  235. Request.RemotePathSize = RemotePathSize;
  236. OsSystemCall(SystemCallSocketConnect, &Request);
  237. return Request.Status;
  238. }
  239. OS_API
  240. KSTATUS
  241. OsSocketPerformIo (
  242. HANDLE Socket,
  243. PSOCKET_IO_PARAMETERS Parameters,
  244. PVOID Buffer
  245. )
  246. /*++
  247. Routine Description:
  248. This routine performs I/O on an open handle.
  249. Arguments:
  250. Socket - Supplies a pointer to the socket.
  251. Parameters - Supplies a pointer to the socket I/O request details.
  252. Buffer - Supplies a pointer to the buffer containing the data to write or
  253. where the read data should be returned, depending on the operation.
  254. Return Value:
  255. Status code.
  256. --*/
  257. {
  258. SYSTEM_CALL_SOCKET_PERFORM_IO Request;
  259. Request.Socket = Socket;
  260. Request.Parameters = Parameters;
  261. Request.Buffer = Buffer;
  262. OsSystemCall(SystemCallSocketPerformIo, &Request);
  263. return Request.Status;
  264. }
  265. OS_API
  266. KSTATUS
  267. OsSocketPerformVectoredIo (
  268. HANDLE Socket,
  269. PSOCKET_IO_PARAMETERS Parameters,
  270. PIO_VECTOR VectorArray,
  271. UINTN VectorCount
  272. )
  273. /*++
  274. Routine Description:
  275. This routine performs vectored I/O on an open handle.
  276. Arguments:
  277. Socket - Supplies a pointer to the socket.
  278. Parameters - Supplies a pointer to the socket I/O request details.
  279. VectorArray - Supplies an array of I/O vector structures to do I/O to/from.
  280. VectorCount - Supplies the number of elements in the vector array.
  281. Return Value:
  282. Status code.
  283. --*/
  284. {
  285. SYSTEM_CALL_SOCKET_PERFORM_VECTORED_IO Request;
  286. Request.Socket = Socket;
  287. Request.Parameters = Parameters;
  288. Request.VectorArray = VectorArray;
  289. Request.VectorCount = VectorCount;
  290. OsSystemCall(SystemCallSocketPerformVectoredIo, &Request);
  291. return Request.Status;
  292. }
  293. OS_API
  294. KSTATUS
  295. OsSocketGetSetInformation (
  296. HANDLE Socket,
  297. SOCKET_INFORMATION_TYPE InformationType,
  298. UINTN Option,
  299. PVOID Data,
  300. PUINTN DataSize,
  301. BOOL Set
  302. )
  303. /*++
  304. Routine Description:
  305. This routine gets or sets socket information.
  306. Arguments:
  307. Socket - Supplies the socket handle.
  308. InformationType - Supplies the socket information type category to which
  309. specified option belongs.
  310. Option - Supplies the option to get or set, which is specific to the
  311. information type. The type of this value is generally
  312. SOCKET_<information_type>_OPTION.
  313. Data - Supplies a pointer to the data buffer where the data is either
  314. returned for a get operation or given for a set operation. If the
  315. buffer is too small for a get request, the truncated data will be
  316. returned and the routine will fail with STATUS_BUFFER_TOO_SMALL.
  317. DataSize - Supplies a pointer that on input contains the size of the data
  318. buffer. On output, this contains the required size of the data buffer.
  319. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  320. a set operation (TRUE).
  321. Return Value:
  322. Status code.
  323. --*/
  324. {
  325. SYSTEM_CALL_SOCKET_GET_SET_INFORMATION Request;
  326. Request.Socket = Socket;
  327. Request.InformationType = InformationType;
  328. Request.Option = Option;
  329. Request.Data = Data;
  330. Request.DataSize = *DataSize;
  331. Request.Set = Set;
  332. OsSystemCall(SystemCallSocketGetSetInformation, &Request);
  333. *DataSize = Request.DataSize;
  334. return Request.Status;
  335. }
  336. OS_API
  337. KSTATUS
  338. OsSocketShutdown (
  339. HANDLE Socket,
  340. ULONG ShutdownType
  341. )
  342. /*++
  343. Routine Description:
  344. This routine shuts down communication with a given socket.
  345. Arguments:
  346. Socket - Supplies the socket handle.
  347. ShutdownType - Supplies the shutdown type to perform. See the
  348. SOCKET_SHUTDOWN_* definitions. These are NOT the same as the C library
  349. definitions.
  350. Return Value:
  351. STATUS_SUCCESS on success.
  352. STATUS_NOT_A_SOCKET if the given handle wasn't a socket.
  353. Other error codes on failure.
  354. --*/
  355. {
  356. SYSTEM_CALL_SOCKET_SHUTDOWN Parameters;
  357. Parameters.Socket = Socket;
  358. Parameters.ShutdownType = ShutdownType;
  359. OsSystemCall(SystemCallSocketShutdown, &Parameters);
  360. return Parameters.Status;
  361. }
  362. //
  363. // --------------------------------------------------------- Internal Functions
  364. //