Baselib_RegisteredNetwork.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. #pragma once
  2. #include "Baselib_ErrorState.h"
  3. #include "Baselib_Memory.h"
  4. #include "Baselib_NetworkAddress.h"
  5. #include "Internal/Baselib_EnumSizeCheck.h"
  6. #include <stdint.h>
  7. #ifdef __cplusplus
  8. BASELIB_C_INTERFACE
  9. {
  10. #endif
  11. // ------------------------------------------------------------------------------------------------
  12. // Network buffers
  13. // Implementation defined internal buffer id.
  14. typedef void* Baselib_RegisteredNetwork_Buffer_Id;
  15. static const Baselib_RegisteredNetwork_Buffer_Id Baselib_RegisteredNetwork_Buffer_Id_Invalid = 0;
  16. // Network buffer structure.
  17. // One buffer can contain multiple packets and endpoints.
  18. typedef struct Baselib_RegisteredNetwork_Buffer
  19. {
  20. Baselib_RegisteredNetwork_Buffer_Id id;
  21. Baselib_Memory_PageAllocation allocation;
  22. } Baselib_RegisteredNetwork_Buffer;
  23. // Create a network buffer from a set of previously allocated memory pages.
  24. //
  25. // Possible error codes:
  26. // - InvalidAddressRange: if pageAllocation is invalid
  27. //
  28. // \returns A network buffer. If registration fails, then buffer id is set to Baselib_RegisteredNetwork_Buffer_Id_Invalid.
  29. BASELIB_API Baselib_RegisteredNetwork_Buffer Baselib_RegisteredNetwork_Buffer_Register(
  30. Baselib_Memory_PageAllocation pageAllocation,
  31. Baselib_ErrorState* errorState
  32. );
  33. // Deregister network buffer. Disassociate memory pages and buffer representation.
  34. //
  35. // Allocated pages will stay allocated and can now be used for something else.
  36. // Passing an invalid buffer results in a no-op.
  37. BASELIB_API void Baselib_RegisteredNetwork_Buffer_Deregister(
  38. Baselib_RegisteredNetwork_Buffer buffer
  39. );
  40. // ------------------------------------------------------------------------------------------------
  41. // Network buffers slices
  42. // Slice of a network buffer.
  43. typedef struct Baselib_RegisteredNetwork_BufferSlice
  44. {
  45. Baselib_RegisteredNetwork_Buffer_Id id;
  46. void* data; // data of the slice
  47. uint32_t size; // size of the slice in bytes
  48. uint32_t offset; // offset in main buffer
  49. } Baselib_RegisteredNetwork_BufferSlice;
  50. // Creates slice from network buffer
  51. //
  52. // \param buffer Buffer to create slice from.
  53. // \param offset Offset in buffer in bytes.
  54. // \param size Size of the slice in bytes.
  55. BASELIB_API Baselib_RegisteredNetwork_BufferSlice Baselib_RegisteredNetwork_BufferSlice_Create(
  56. Baselib_RegisteredNetwork_Buffer buffer,
  57. uint32_t offset,
  58. uint32_t size
  59. );
  60. // Create empty slice that doesn't point to anything
  61. //
  62. // Guaranteed to reference Baselib_RegisteredNetwork_Buffer_Id_Invalid and have all other values zeroed out.
  63. BASELIB_API Baselib_RegisteredNetwork_BufferSlice Baselib_RegisteredNetwork_BufferSlice_Empty(void);
  64. // ------------------------------------------------------------------------------------------------
  65. // Network endpoints are platform defined representation (sockaddr_in-like) of network address (family, ip, port).
  66. typedef struct Baselib_RegisteredNetwork_Endpoint { Baselib_RegisteredNetwork_BufferSlice slice; } Baselib_RegisteredNetwork_Endpoint;
  67. static const uint32_t Baselib_RegisteredNetwork_Endpoint_MaxSize = 28; // in bytes
  68. // Place network address into the network buffer.
  69. //
  70. // Destination must be able to accommodate Baselib_RegisteredNetwork_Endpoint_MaxSize bytes.
  71. //
  72. // \param srcAddress Network address to use, pass nullptr to create an empty endpoint.
  73. // \param dstSlice Where to write encoded data.
  74. //
  75. // Possible error codes:
  76. // - InvalidArgument: if dstSlice is invalid
  77. // - InvalidBufferSize: if dstSlice is smaller than Baselib_RegisteredNetwork_Endpoint_MaxSize
  78. //
  79. // \returns Endpoint or Endpoint_Empty in case of failure.
  80. BASELIB_API Baselib_RegisteredNetwork_Endpoint Baselib_RegisteredNetwork_Endpoint_Create(
  81. const Baselib_NetworkAddress* srcAddress,
  82. Baselib_RegisteredNetwork_BufferSlice dstSlice,
  83. Baselib_ErrorState* errorState
  84. );
  85. // Return empty endpoint that doesn't point to anything
  86. //
  87. // Guaranteed to contain Baselib_RegisteredNetwork_BufferSlice_Empty
  88. BASELIB_API Baselib_RegisteredNetwork_Endpoint Baselib_RegisteredNetwork_Endpoint_Empty(void);
  89. // Decode endpoint.
  90. //
  91. // \param endpoint Endpoint to be converted.
  92. // \param dstAddress Pointer to address to write data to.
  93. //
  94. // Possible error codes:
  95. // - InvalidArgument: if endpoint is invalid or dstAddress is null
  96. BASELIB_API void Baselib_RegisteredNetwork_Endpoint_GetNetworkAddress(
  97. Baselib_RegisteredNetwork_Endpoint endpoint,
  98. Baselib_NetworkAddress* dstAddress,
  99. Baselib_ErrorState* errorState
  100. );
  101. // ------------------------------------------------------------------------------------------------
  102. // Request & Completion
  103. // Send/receive request.
  104. typedef struct Baselib_RegisteredNetwork_Request
  105. {
  106. Baselib_RegisteredNetwork_BufferSlice payload;
  107. // for sending: remote address to which the payload is sent (required for UDP)
  108. // for receiving: address from which the data was sent (optional)
  109. Baselib_RegisteredNetwork_Endpoint remoteEndpoint;
  110. // TODO: Not support yet. (We would also need to support this in Baselib_Socket first)
  111. // for sending: unused
  112. // for receiving: local address on which the data was received (optional)
  113. //Baselib_RegisteredNetwork_Endpoint localEndpoint;
  114. void* requestUserdata;
  115. } Baselib_RegisteredNetwork_Request;
  116. // Success or failure of a Baselib_RegisteredNetwork_CompletionResult.
  117. typedef enum Baselib_RegisteredNetwork_CompletionStatus
  118. {
  119. // Networking request failed.
  120. Baselib_RegisteredNetwork_CompletionStatus_Failed = 0,
  121. // Networking request successfully finished.
  122. Baselib_RegisteredNetwork_CompletionStatus_Success = 1,
  123. } Baselib_RegisteredNetwork_CompletionStatus;
  124. BASELIB_ENUM_ENSURE_ABI_COMPATIBILITY(Baselib_RegisteredNetwork_CompletionStatus);
  125. // Result of a previously scheduled send/receive
  126. //
  127. // When a networking request is completed, this is placed into an internal completion queue.
  128. typedef struct Baselib_RegisteredNetwork_CompletionResult
  129. {
  130. Baselib_RegisteredNetwork_CompletionStatus status;
  131. uint32_t bytesTransferred;
  132. void* requestUserdata;
  133. } Baselib_RegisteredNetwork_CompletionResult;
  134. // ------------------------------------------------------------------------------------------------
  135. // UDP connectionless socket.
  136. typedef struct Baselib_RegisteredNetwork_Socket_UDP { struct Baselib_RegisteredNetwork_Socket_UDP_Impl* handle; } Baselib_RegisteredNetwork_Socket_UDP;
  137. static const Baselib_RegisteredNetwork_Socket_UDP Baselib_RegisteredNetwork_Socket_UDP_Invalid = { NULL };
  138. // Creates an UDP socket with internal request and completion queues.
  139. //
  140. // \param bindAddress Address to bind socket to, in connectionless UDP every socket has to be bound.
  141. // \param endpointReuse Allows multiple sockets to be bound to the same address/port if set to AddressReuse_Allow,
  142. // All sockets bound to the same address/port need to have this flag set.
  143. // \param sendQueueSize Send queue size in amount of entries.
  144. // \param recvQueueSize Receive queue size in amount of entries.
  145. //
  146. // Known issues (behavior may change in the future):
  147. // - Some platforms do not support sending zero sized UDP packets.
  148. //
  149. // Possible error codes:
  150. // - InvalidArgument: if bindAddress pointer is null or incompatible or both sendQueueSize and recvQueueSize are zero
  151. // - EndpointInUse: endpoint is already in use
  152. // - AddressFamilyNotSupported: if the requested address family is not available.
  153. // - OutOfSystemResources: if network session limit was exceeded
  154. //
  155. // \returns A UDP socket. If socket creation fails, socket holds a Baselib_RegisteredNetwork_Socket_UDP_InvalidHandle.
  156. BASELIB_API Baselib_RegisteredNetwork_Socket_UDP Baselib_RegisteredNetwork_Socket_UDP_Create(
  157. const Baselib_NetworkAddress* bindAddress,
  158. Baselib_NetworkAddress_AddressReuse endpointReuse,
  159. uint32_t sendQueueSize,
  160. uint32_t recvQueueSize,
  161. Baselib_ErrorState* errorState
  162. );
  163. // Schedules receive requests.
  164. //
  165. // \param socket Socket to be used.
  166. // \param requests Array of pointers to requests. No-op if null.
  167. // Request objects can be freed after the function call.
  168. // \param requestsCount Amount of requests in the array. No-op if zero.
  169. //
  170. // If requests is null or requestsCount is zero, this operation is a no-op.
  171. // Note that actual receiving may be deferred until you call Baselib_RegisteredNetwork_Socket_UDP_ProcessRecv.
  172. // UDP message data that doesn't fit a message buffer is silently discarded.
  173. //
  174. // Known issues (behavior may change in the future):
  175. // - Some platforms does not support receiving zero sized UDP packets.
  176. //
  177. // Possible error codes:
  178. // - InvalidArgument: if socket is invalid
  179. //
  180. // \returns The number of scheduled items. If scheduling fails this function return zero.
  181. BASELIB_API uint32_t Baselib_RegisteredNetwork_Socket_UDP_ScheduleRecv(
  182. Baselib_RegisteredNetwork_Socket_UDP socket,
  183. const Baselib_RegisteredNetwork_Request* requests,
  184. uint32_t requestsCount,
  185. Baselib_ErrorState* errorState
  186. );
  187. // Schedules send requests.
  188. //
  189. // \param socket Socket to be used.
  190. // \param requests Array of pointers to requests. No-op if null.
  191. // Request objects can be freed after the function call.
  192. // \param requestsCount Amount of requests in the array. No-op if zero.
  193. //
  194. // If requests is null or requestsCount is zero, this operation is a no-op.
  195. // Note that actual receiving may be deferred until you call Baselib_RegisteredNetwork_Socket_UDP_ProcessSend.
  196. //
  197. // Possible error codes:
  198. // - InvalidArgument: if socket is invalid
  199. //
  200. // \returns The number of scheduled items. If scheduling fails this function return zero.
  201. BASELIB_API uint32_t Baselib_RegisteredNetwork_Socket_UDP_ScheduleSend(
  202. Baselib_RegisteredNetwork_Socket_UDP socket,
  203. const Baselib_RegisteredNetwork_Request* requests,
  204. uint32_t requestsCount,
  205. Baselib_ErrorState* errorState
  206. );
  207. // Status of processing send/recv.
  208. typedef enum Baselib_RegisteredNetwork_ProcessStatus
  209. {
  210. // No further items to process.
  211. //
  212. // Note that this does not imply that all requests have been fully processed at any moment in time.
  213. Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately = 0,
  214. // deprecated, same as Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately
  215. Baselib_RegisteredNetwork_ProcessStatus_Done
  216. COMPILER_DEPRECATED_ENUM_VALUE("Use Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately instead (equivalent)") = 0,
  217. // Should call again, there is more workload to process.
  218. Baselib_RegisteredNetwork_ProcessStatus_Pending = 1,
  219. } Baselib_RegisteredNetwork_ProcessStatus;
  220. BASELIB_ENUM_ENSURE_ABI_COMPATIBILITY(Baselib_RegisteredNetwork_ProcessStatus);
  221. // Processes the receive queue on a socket.
  222. //
  223. // Needs to be called periodically to ensure requests are processed.
  224. // You should call this in loop until either your time budget is exceed or the function returns false.
  225. //
  226. // Platforms emulating RIO behavior with sockets, perform one receive per call until there are no more receive requests in the queue.
  227. // Requests failed due to empty socket receive buffer are requeued and processed at the next call to Baselib_RegisteredNetwork_Socket_UDP_ProcessRecv.
  228. // In that case Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately is returned since an immediate retry will not have any effect.
  229. //
  230. // Possible error codes:
  231. // - InvalidArgument: if socket is invalid
  232. //
  233. // \returns Baselib_RegisteredNetwork_ProcessStatus_Pending if there is more workload to process immediately, Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately if otherwise
  234. BASELIB_API Baselib_RegisteredNetwork_ProcessStatus Baselib_RegisteredNetwork_Socket_UDP_ProcessRecv(
  235. Baselib_RegisteredNetwork_Socket_UDP socket,
  236. Baselib_ErrorState* errorState
  237. );
  238. // Processes the send queue on a socket.
  239. //
  240. // Needs to be called periodically to ensure requests are processed.
  241. // You should call this in loop until either your time budget is exceed or the function returns false.
  242. //
  243. // Platforms emulating RIO behavior with sockets, perform one send per call until there are no more send requests in the queue.
  244. // Requests failed due to full socket send buffer are requeued processed at the next call to Baselib_RegisteredNetwork_Socket_UDP_ProcessSend.
  245. // In that case Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately is returned since an immediate retry will not have any effect.
  246. //
  247. // Possible error codes:
  248. // - InvalidArgument: if socket is invalid
  249. //
  250. // \returns Baselib_RegisteredNetwork_ProcessStatus_Pending if there is more workload to process immediately, Baselib_RegisteredNetwork_ProcessStatus_NonePendingImmediately if otherwise
  251. BASELIB_API Baselib_RegisteredNetwork_ProcessStatus Baselib_RegisteredNetwork_Socket_UDP_ProcessSend(
  252. Baselib_RegisteredNetwork_Socket_UDP socket,
  253. Baselib_ErrorState* errorState
  254. );
  255. // Status of a recv/send completion queue.
  256. typedef enum Baselib_RegisteredNetwork_CompletionQueueStatus
  257. {
  258. // No results are ready for dequeing.
  259. Baselib_RegisteredNetwork_CompletionQueueStatus_NoResultsAvailable = 0,
  260. // Results are available for dequeing.
  261. Baselib_RegisteredNetwork_CompletionQueueStatus_ResultsAvailable = 1,
  262. } Baselib_RegisteredNetwork_CompletionQueueStatus;
  263. BASELIB_ENUM_ENSURE_ABI_COMPATIBILITY(Baselib_RegisteredNetwork_CompletionQueueStatus);
  264. // Wait until results appears for a previously scheduled receive.
  265. //
  266. // \param timeoutInMilliseconds Wait timeout.
  267. //
  268. // Possible error codes:
  269. // - InvalidArgument: if socket is invalid
  270. //
  271. // \returns Baselib_RegisteredNetwork_CompletionQueueStatus_ResultsAvailable if results are available for dequeue, Baselib_RegisteredNetwork_CompletionQueueStatus_NoResultsAvailable otherwise
  272. BASELIB_API Baselib_RegisteredNetwork_CompletionQueueStatus Baselib_RegisteredNetwork_Socket_UDP_WaitForCompletedRecv(
  273. Baselib_RegisteredNetwork_Socket_UDP socket,
  274. uint32_t timeoutInMilliseconds,
  275. Baselib_ErrorState* errorState
  276. );
  277. // Wait until results appears for a previously scheduled send.
  278. //
  279. // \param timeoutInMilliseconds Wait timeout.
  280. //
  281. // Possible error codes:
  282. // - InvalidArgument: if socket is invalid
  283. //
  284. // \returns Baselib_RegisteredNetwork_CompletionQueueStatus_ResultsAvailable if results are available for dequeue, Baselib_RegisteredNetwork_CompletionQueueStatus_NoResultsAvailable otherwise
  285. BASELIB_API Baselib_RegisteredNetwork_CompletionQueueStatus Baselib_RegisteredNetwork_Socket_UDP_WaitForCompletedSend(
  286. Baselib_RegisteredNetwork_Socket_UDP socket,
  287. uint32_t timeoutInMilliseconds,
  288. Baselib_ErrorState* errorState
  289. );
  290. // Dequeue receive result.
  291. //
  292. // \param results Results array. No-op if null.
  293. // \param resultsCount Amount of elements in results array. No-op if zero.
  294. //
  295. // If you're calling this method on multiple threads for the same completion queue in parallel, it may spuriously return 0.
  296. //
  297. // Possible error codes:
  298. // - InvalidArgument: if socket is invalid
  299. //
  300. // \returns number of dequeued entries
  301. BASELIB_API uint32_t Baselib_RegisteredNetwork_Socket_UDP_DequeueRecv(
  302. Baselib_RegisteredNetwork_Socket_UDP socket,
  303. Baselib_RegisteredNetwork_CompletionResult results[],
  304. uint32_t resultsCount,
  305. Baselib_ErrorState* errorState
  306. );
  307. // Dequeue send result.
  308. //
  309. // \param results Results array. No-op if null.
  310. // \param resultsCount Amount of elements in results array. No-op if zero.
  311. //
  312. // If you're calling this method on multiple threads for the same completion queue in parallel, it may spuriously return 0.
  313. //
  314. // Possible error codes:
  315. // - InvalidArgument: if socket is invalid
  316. //
  317. // \returns number of dequeued entries
  318. BASELIB_API uint32_t Baselib_RegisteredNetwork_Socket_UDP_DequeueSend(
  319. Baselib_RegisteredNetwork_Socket_UDP socket,
  320. Baselib_RegisteredNetwork_CompletionResult results[],
  321. uint32_t resultsCount,
  322. Baselib_ErrorState* errorState
  323. );
  324. // Get bind address of udp socket.
  325. //
  326. // \param socket Socket to be used.
  327. // \param dstAddress Pointer to address to write data to.
  328. //
  329. // Possible error codes:
  330. // - InvalidArgument: if socket is invalid or if dstAddress is null
  331. BASELIB_API void Baselib_RegisteredNetwork_Socket_UDP_GetNetworkAddress(
  332. Baselib_RegisteredNetwork_Socket_UDP socket,
  333. Baselib_NetworkAddress* dstAddress,
  334. Baselib_ErrorState* errorState
  335. );
  336. // Closes UDP socket.
  337. //
  338. // Passing an invalid socket handle result in a no-op.
  339. //
  340. // \param socket Socket to be closed.
  341. BASELIB_API void Baselib_RegisteredNetwork_Socket_UDP_Close(
  342. Baselib_RegisteredNetwork_Socket_UDP socket
  343. );
  344. // ------------------------------------------------------------------------------------------------
  345. #ifdef __cplusplus
  346. }
  347. #endif