{"id":19164184,"url":"https://github.com/ichishino/coldforce","last_synced_at":"2025-06-12T18:32:37.502Z","repository":{"id":38347382,"uuid":"203282584","full_name":"Ichishino/coldforce","owner":"Ichishino","description":"Networking Library for C/C++","archived":false,"fork":false,"pushed_at":"2024-01-09T02:35:47.000Z","size":1267,"stargazers_count":7,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-07T11:39:52.248Z","etag":null,"topics":["async","c","client","dtls","event-driven","http","http2","nonblocking-sockets","openssl","server","ssl","tcp","tls","udp","websocket","wolfssl"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ichishino.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-20T02:13:27.000Z","updated_at":"2024-11-25T11:13:09.000Z","dependencies_parsed_at":"2023-11-14T08:43:07.101Z","dependency_job_id":"88ad6000-56ea-45e1-b521-49db3a3a414e","html_url":"https://github.com/Ichishino/coldforce","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Ichishino/coldforce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ichishino%2Fcoldforce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ichishino%2Fcoldforce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ichishino%2Fcoldforce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ichishino%2Fcoldforce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ichishino","download_url":"https://codeload.github.com/Ichishino/coldforce/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ichishino%2Fcoldforce/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259519256,"owners_count":22870327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","c","client","dtls","event-driven","http","http2","nonblocking-sockets","openssl","server","ssl","tcp","tls","udp","websocket","wolfssl"],"created_at":"2024-11-09T09:19:16.276Z","updated_at":"2025-06-12T18:32:37.449Z","avatar_url":"https://github.com/Ichishino.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Coldforce\n\n[![Build](https://github.com/Ichishino/coldforce/actions/workflows/build.yml/badge.svg)](https://github.com/Ichishino/coldforce/actions/workflows/build.yml)\n\nColdforce is a library written in C that supports various network protocols.\nWith the asynchronous API of this library\nYou can easily develop event-driven network applications.\nThe currently supported protocols are as follows.\nAll of these support clients and servers (multi-client, C10K).\n\n* TCP/UDP (IPv4/IPv6)\n* TLS/DTLS (OpenSSL or wolfSSL) (Sorry, DTLS doesn't work on windows)\n* HTTP/1.1 (http/https, pipelining, basic/digest authentication)\n* HTTP/2 (server push)\n* WebSocket (ws/wss, over http2)\n\n## Platforms\n\n* Windows\n* Linux\n* macOS\n\n## Requirements\n\n* C99 or later\n* Use `-pthread` `-lm`\n* OpenSSL or wolfSSL (only when using TLS, https and wss)\n\n  wolfSSL build options\n\n  ```shellsession\n  IDE\n\n  #define OPENSSL_EXTRA\n  #define OPENSSL_ALL\n  #define HAVE_ALPN\n  #define HAVE_SNI\n  #define WOLFSSL_SYS_CA_CERTS\n  #define WOLFSSL_DTLS\n  #define WOLFSSL_DTLS13\n\n  mkdir inc/wolfssl\n  copy your user_settings.h to inc/wolfssl/.\n  ```\n\n  ```shellsession\n  configure\n\n  --enable-opensslextra --enable-opensslall --enable-alpn --enable-sni --enable-sys-ca-certs --enable-dtls --enable-dtls13\n  ```\n\n## Modules\n\n* Coldforce core : `co_core.dll` / `libco_core.a`\n* Network core (TCP,UDP) : `co_net.dll` / `libco_net.a`\n* TLS/DTLS : `co_tls.dll` / `libco_tls.a`\n* HTTP/1.1 : `co_http.dll` / `libco_http.a`\n* HTTP/2 : `co_http2.dll` / `libco_http2.a`\n* WebSocket : `co_ws.dll`, `co_ws_http2.dll` / `libco_ws.a`, `libco_ws_http2.a`\n\n## Builds\n\n* Windows\nVisual Studio ([prj/msvc/coldforce.sln](https://github.com/Ichishino/coldforce/tree/master/prj/msvc))\n\n  for wolfSSL\n  Add `CO_USE_WOLFSSL` to `C/C++ Preprocessor Definitions` in both co_tls and your project property.\n\n* Linux\n  cmake\n\n  ```shellsession\n  cd build\n  cmake ..\n  make\n  ```\n\n  for wolfSSL\n\n  ```shellsession\n  ...\n  cmake .. -DTLS_LIB=wolfssl\n  ...\n  ```\n\n* macOS\n  cmake (same way as Linux)\n\n## Code Examples\n\n* WebSocket client\n\n  ```C++\n  #include \u003ccoldforce.h\u003e\n\n  #include \u003cstdio.h\u003e\n  #include \u003cstdlib.h\u003e\n  #include \u003cstring.h\u003e\n\n  typedef struct {\n      co_app_t base_app;\n      co_ws_client_t* ws_client;\n      co_url_st* url;\n  } app_st;\n\n  void\n  app_on_ws_receive_frame(\n      app_st* self,\n      co_ws_client_t* ws_client,\n      const co_ws_frame_t* frame,\n      int error_code\n  )\n  {\n      if (error_code == 0)\n      {\n          bool fin = co_ws_frame_get_fin(frame);\n          uint8_t opcode = co_ws_frame_get_opcode(frame);\n          size_t data_size = (size_t)co_ws_frame_get_payload_size(frame);\n          const uint8_t* data = co_ws_frame_get_payload_data(frame);\n\n          switch (opcode)\n          {\n          case CO_WS_OPCODE_TEXT:\n          {\n              printf(\"receive text(%d): %*.*s\\n\", fin,\n                  (int)data_size, (int)data_size, (char*)data);\n              break;\n          }\n          case CO_WS_OPCODE_BINARY:\n          {\n              printf(\"receive binary(%d): %zu bytes\\n\",\n                  fin, data_size);\n              break;\n          }\n          case CO_WS_OPCODE_CONTINUATION:\n          {\n              printf(\"receive continuation(%d): %zu bytes\\n\",\n                  fin, data_size);\n              break;\n          }\n          default:\n          {\n              co_ws_default_handler(ws_client, frame);\n              break;\n          }\n          }\n      }\n      else\n      {\n          co_ws_client_destroy(ws_client);\n          self-\u003ews_client = NULL;\n      }\n  }\n\n  void\n  app_on_ws_close(\n      app_st* self,\n      co_ws_client_t* ws_client\n  )\n  {\n      co_ws_client_destroy(ws_client);\n      self-\u003ews_client = NULL;\n\n      co_app_stop();\n  }\n\n  void\n  app_on_ws_upgrade(\n      app_st* self,\n      co_ws_client_t* ws_client,\n      const co_http_response_t* response,\n      int error_code\n  )\n  {\n      if (error_code == 0)\n      {\n          co_ws_send_text(ws_client, \"hello\");\n      }\n      else\n      {\n          co_ws_client_destroy(ws_client);\n          self-\u003ews_client = NULL;\n\n          co_app_stop();\n      }\n  }\n\n  void\n  app_on_ws_connect(\n      app_st* self,\n      co_ws_client_t* ws_client,\n      int error_code\n  )\n  {\n      if (error_code == 0)\n      {\n          co_http_request_t* request =\n              co_http_request_create_ws_upgrade(self-\u003eurl-\u003epath_and_query, NULL, NULL);\n\n          co_ws_send_upgrade_request(self-\u003ews_client, request);\n      }\n      else\n      {\n          co_ws_client_destroy(ws_client);\n          self-\u003ews_client = NULL;\n\n          co_app_stop();\n      }\n  }\n\n  bool\n  app_on_create(\n      app_st* self\n  )\n  {\n      self-\u003eurl = co_url_create(\"ws://127.0.0.1:8080/\");\n\n      co_net_addr_t local_net_addr = { 0 };\n      co_net_addr_set_family(\u0026local_net_addr, CO_NET_ADDR_FAMILY_IPV4);\n\n      self-\u003ews_client = co_ws_client_create(self-\u003eurl-\u003eorigin, \u0026local_net_addr, NULL);\n\n      if (self-\u003ews_client == NULL)\n      {\n          return false;\n      }\n\n      co_ws_callbacks_st* callbacks = co_ws_get_callbacks(self-\u003ews_client);\n      callbacks-\u003eon_connect = (co_ws_connect_fn)app_on_ws_connect;\n      callbacks-\u003eon_upgrade = (co_ws_upgrade_fn)app_on_ws_upgrade;\n      callbacks-\u003eon_receive_frame = (co_ws_receive_frame_fn)app_on_ws_receive_frame;\n      callbacks-\u003eon_close = (co_ws_close_fn)app_on_ws_close;\n\n      co_ws_start_connect(self-\u003ews_client);\n\n      return true;\n  }\n\n  void\n  app_on_destroy(\n      app_st* self\n  )\n  {\n      co_ws_client_destroy(self-\u003ews_client);\n      co_url_destroy(self-\u003eurl);\n  }\n\n  int\n  main(\n      int argc,\n      char* argv[]\n  )\n  {\n      app_st self = { 0 };\n\n      return co_net_app_start(\n          (co_app_t*)\u0026self, \"ws-client-app\",\n          (co_app_create_fn)app_on_create,\n          (co_app_destroy_fn)app_on_destroy,\n          argc, argv);\n  }\n  ```\n\n* WebSocket echo server -\u003e ws://127.0.0.1:8080\n\n  ```C++\n  #include \u003ccoldforce.h\u003e\n\n  typedef struct {\n      co_app_t base_app;\n      co_tcp_server_t* tcp_server;\n      co_list_t* ws_clients;\n  } app_st;\n\n  void\n  app_on_ws_receive_frame(\n      app_st* self,\n      co_ws_client_t* ws_client,\n      const co_ws_frame_t* frame,\n      int error_code\n  )\n  {\n      if (error_code == 0)\n      {\n          bool fin = co_ws_frame_get_fin(frame);\n          uint8_t opcode = co_ws_frame_get_opcode(frame);\n          size_t data_size = (size_t)co_ws_frame_get_payload_size(frame);\n          const uint8_t* data = co_ws_frame_get_payload_data(frame);\n\n          switch (opcode)\n          {\n          case CO_WS_OPCODE_TEXT:\n          case CO_WS_OPCODE_BINARY:\n          case CO_WS_OPCODE_CONTINUATION:\n          {\n              co_ws_send(ws_client, fin, opcode, data, data_size);\n\n              break;\n          }\n          default:\n          {\n              co_ws_default_handler(ws_client, frame);\n\n              break;\n          }\n          }\n      }\n      else\n      {\n          co_list_remove(self-\u003ews_clients, ws_client);\n      }\n  }\n\n  void\n  app_on_ws_close(\n      app_st* self,\n      co_ws_client_t* ws_client\n  )\n  {\n      co_list_remove(self-\u003ews_clients, ws_client);\n  }\n\n  void\n  app_on_ws_upgrade(\n      app_st* self,\n      co_ws_client_t* ws_client,\n      const co_http_request_t* http_request,\n      int error_code\n  )\n  {\n      if (error_code == 0)\n      {\n          co_http_response_t* http_response =\n              co_http_response_create_ws_upgrade(http_request, NULL, NULL);\n\n          co_http_connection_send_response(\n              (co_http_connection_t*)ws_client, http_response);\n\n          co_http_response_destroy(http_response);\n      }\n      else\n      {\n          co_list_remove(self-\u003ews_clients, ws_client);\n      }\n  }\n\n  void\n  app_on_tcp_accept(\n      app_st* self,\n      co_tcp_server_t* tcp_server,\n      co_tcp_client_t* tcp_client\n  )\n  {\n      co_tcp_accept((co_thread_t*)self, tcp_client);\n\n      co_ws_client_t* ws_client = co_tcp_upgrade_to_ws(tcp_client, NULL);\n\n      co_ws_callbacks_st* callbacks = co_ws_get_callbacks(ws_client);\n      callbacks-\u003eon_upgrade = (co_ws_upgrade_fn)app_on_ws_upgrade;\n      callbacks-\u003eon_receive_frame = (co_ws_receive_frame_fn)app_on_ws_receive_frame;\n      callbacks-\u003eon_close = (co_ws_close_fn)app_on_ws_close;\n\n      co_list_add_tail(self-\u003ews_clients, ws_client);\n  }\n\n  bool\n  app_on_create(\n    app_st* self\n  )\n  {\n      uint16_t port = 8080;\n\n      co_list_ctx_st list_ctx = { 0 };\n      list_ctx.destroy_value = (co_item_destroy_fn)co_ws_client_destroy;\n      self-\u003ews_clients = co_list_create(\u0026list_ctx);\n\n      co_net_addr_t local_net_addr = { 0 };\n      co_net_addr_set_family(\u0026local_net_addr, CO_NET_ADDR_FAMILY_IPV4);\n      co_net_addr_set_port(\u0026local_net_addr, port);\n\n      self-\u003etcp_server = co_tcp_server_create(\u0026local_net_addr);\n\n      co_socket_option_set_reuse_addr(\n          co_tcp_server_get_socket(self-\u003etcp_server), true);\n\n      co_tcp_server_callbacks_st* callbacks =\n          co_tcp_server_get_callbacks(self-\u003etcp_server);\n      callbacks-\u003eon_accept = (co_tcp_accept_fn)app_on_tcp_accept;\n\n      return co_tcp_server_start(self-\u003etcp_server, SOMAXCONN);\n  }\n\n  void\n  app_on_destroy(\n      app_st* self\n  )\n  {\n      co_tcp_server_destroy(self-\u003etcp_server);\n      co_list_destroy(self-\u003ews_clients);\n  }\n\n  int\n  main(\n      int argc,\n      char* argv[]\n  )\n  {\n      app_st self = { 0 };\n\n      return co_net_app_start(\n          (co_app_t*)\u0026self, \"ws-server-app\",\n          (co_app_create_fn)app_on_create,\n          (co_app_destroy_fn)app_on_destroy,\n          argc, argv);\n  }\n  ```\n\n* [more examples here](https://github.com/Ichishino/coldforce/tree/master/examples)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fichishino%2Fcoldforce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fichishino%2Fcoldforce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fichishino%2Fcoldforce/lists"}