diff --git a/CHANGELOG.md b/CHANGELOG.md index 02bd146c..7ab3a464 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # history +* Revision 598 + * [changed] test/udpserver2 (udp server on network_server) + * [added] multiplexer_event_type_t::mux_dgram, typeof_socket + * [changed] tcp_server_socket, udp_server_socket inherits from server_socket + * [changed] tcp_client_socket, udp_client_socket inherits from client_socket + * [changed] network_server, network_session, network_stream, network_stream_data + * Revision 595 * [changed] rename cmdline_t to t_cmdline_t * [changed] rename cmdarg_t to t_cmdarg_t @@ -55,6 +62,9 @@ * [changed] parser::psearch, parser::context::psearch changed return type * rename std::multimap to std::multimap +* Revision 573 + * [changed] t_aho_corasick support wildcard single (?) + * Revision 568 * [added] print_pair * [added] empty, occupied (stream_t, bufferio, basic_stream, ansi_string, wide_string, file_stream) @@ -67,6 +77,9 @@ * Revision 567 * [added] datetime::gettime, datetime::gmtime_to_timespec, timespan_m, timespan_s +* Revision 566 + * [changed] float_from_fp16, double_from_fp16, ieee754_exp, ieee754_typeof + * Revision 565 * [added] double_from_fp16 * [changed] rename fp16_from_fp32 to fp16_from_float @@ -117,6 +130,7 @@ * Revision 536 * [added] parser + * [added] The Knuth-Morris-Pratt Algorithm * Revision 535 * [changed] rename convert to tostring/tobin @@ -149,6 +163,9 @@ * Revision 514 * [added] enable_alpn_h2 +* Revision 511 + * [changed] HTTP/2 hello world + * Revision 510 * [added] hpack_encoder @@ -156,7 +173,7 @@ * [added] http_server_builder, hpack_session * Revision 506 - * [changed] HPACK + * [changed] HPACK (RFC 7541) * Revision 504 * [added] huffman_coding @@ -190,6 +207,9 @@ * Revision 479 * [added] Authorization Code Grant (RFC 6749 4.1) +* Revision 478 + * [changed] RFC 6749 4.1 Authorization Code Grant + * Revision 476 * [added] error_advisor @@ -230,6 +250,27 @@ * [added] crypto_key::generate_nid, crypto_key::generate_cose * [added] ES256K (RFC8812) +* Revision 434 + * [changed] COSE encrypt, sign, createmac + +* Revision 433 + * [changed] COSE untagged message + +* Revision 433 + * [changed] COSE untagged message + +* Revision 431 + * [added] variant + +* Revision 428 + * [changed] cose_countersigns + +* Revision 426 + * [changed] cose_key OKP + +* Revision 418 + * [changed] ChaCha20/Poly1305(24) not supported + * Revision 416 * [changed] openssl_chacha20_iv @@ -248,15 +289,51 @@ * Revision 399 * [changed] preserve leading zero (JKW, CWK) +* Revision 393 + * [changed] AES-CBC-MAC + * Revision 392 * [changed] mingw terminal delay fixed +* Revision 389, 390 + * [changed] COSE example, debug + +* Revision 381 + * [changed] RFC 8152 C.5.2 C.5.4 + +* Revision 379 + * [changed] COSE decrypt + +* Revision 378 + * [changed] COSE verify_sign + +* Revision 377 + * [changed] COSE verify_mac + +* Revision 369 + * [changed] aes_cbc_hmac_sha2_encrypt/decrypt + +* Revision 364 + * [changed] Authenticated Encryption with AES-CBC and HMAC-SHA + +* Revision 363 + * [changed] AEAD_AES_128_CBC_HMAC_SHA_256 + +* Revision 358 + * [changed] partial_iv + +* Revision 357 + * [changed] COSE AES KEYWRAP + * Revision 354 * [added] kdf_ckdf, ckdf_extract, ckdf_expand * Revision 353 * [added] hkdf_extract, hkdf_expand +* Revision 350 + * [changed] COSE ECDH-ES/SS+AES KEYWRAP + * Revision 348 * [changed] COSE RSA-OAEP @@ -272,6 +349,9 @@ * Revision 340 * [changed] COSE AES-CCM, AES-GCM +* Revision 339 + * [changed] Fedora Core 4 TESTED + * Revision 335 * [changed] RFC 8152 C.3.2 C.4.1 C.4.2 decryption @@ -285,7 +365,7 @@ * [added] [COSE examples](https://github.com/cose-wg/Examples) * Revision 305 - * [added] elliptic curves B-163, K-163, P-192 + * [added] elliptic curves B-163, K-163, P-192 * Revision 303 * [changed] ECDSA NIST CAVP - tested (truncated sha) @@ -318,15 +398,24 @@ * Revision 249 * [changed] cbor_web_key +* Revision 224 + * [added] json_web_key + * Revision 211 * [added] RFC 8152 examples (.cbor, .diag) * Revision 205 * [added] fp16_from_fp32, fp16_ieee_from_fp32_value, ieee754_format_as_small_as_possible +* Revision 171 + * [added] openssl_chacha20_iv + * Revision 164 * [added] CCM (Block cipher mode of operation) +* Revision 128 + * [added] windows_registry, windows_version + * Revision 125 * [added] obfuscate_string, test_case_notimecheck @@ -357,10 +446,14 @@ * Revision 21 * [changed] precompiled header +* Revision 11 + * [changed] namespace hotplace + * Revision 9 * [changed] bufferio * Revision 5 * [added] t_shared_instance - +* Revision 2 + * [added] console_color diff --git a/README.md b/README.md index 27536b3e..67470fa1 100644 --- a/README.md +++ b/README.md @@ -1,284 +1,292 @@ # hotplace - * Research on personal interests - * ![cmake workflow](https://github.com/princeb612/hotplace/actions/workflows/build.yml/badge.svg) - * ![codeql workflow](https://github.com/princeb612/hotplace/actions/workflows/codeql.yml/badge.svg) - * powered by - * ![openssl](https://img.shields.io/badge/openssl-1.1.1/3.0/3.1/3.2-green) - * ![jansson](https://img.shields.io/badge/jansson-latest-green) - * ![zlib](https://img.shields.io/badge/zlb-latest-green) - * badge - * ![c++11](https://img.shields.io/badge/c++11-green) ![gcc](https://img.shields.io/badge/gcc-green) ![cmake](https://img.shields.io/badge/cmake-green) - * ![mingw64](https://img.shields.io/badge/mingw64-green) ![ubuntu](https://img.shields.io/badge/ubuntu-green) ![RHEL](https://img.shields.io/badge/RHEL-green) - * status - * JOSE ![implemented](https://img.shields.io/badge/implemented-green) - * CBOR ![implemented](https://img.shields.io/badge/implemented-green) - * COSE ![implemented](https://img.shields.io/badge/implemented-green) - * HTTP/1.1,2,3 ![studying](https://img.shields.io/badge/studying-magenta) - * ASN.1 ![studying](https://img.shields.io/badge/studying-magenta) - * link - * [changelog](CHANGELOG.md) - * [implemented](#implemented) - * [applied](#applied) - * [not applied](#not-applied) - * [studying](#studying) - * [next time](#next-time) - * [build](#build) - * [custom toolchain](#custom-toolchain) - * [link](#link) +* Research on personal interests +* ![cmake workflow](https://github.com/princeb612/hotplace/actions/workflows/build.yml/badge.svg) +* ![codeql workflow](https://github.com/princeb612/hotplace/actions/workflows/codeql.yml/badge.svg) +* powered by + * ![openssl](https://img.shields.io/badge/openssl-1.1.1/3.0/3.1/3.2-green) + * ![jansson](https://img.shields.io/badge/jansson-latest-green) + * ![zlib](https://img.shields.io/badge/zlb-latest-green) +* badge + * ![c++11](https://img.shields.io/badge/c++11-green) ![gcc](https://img.shields.io/badge/gcc-green) ![cmake](https://img.shields.io/badge/cmake-green) + * ![mingw64](https://img.shields.io/badge/mingw64-green) ![ubuntu](https://img.shields.io/badge/ubuntu-green) ![RHEL](https://img.shields.io/badge/RHEL-green) +* status + * JOSE ![implemented](https://img.shields.io/badge/implemented-green) + * CBOR ![implemented](https://img.shields.io/badge/implemented-green) + * COSE ![implemented](https://img.shields.io/badge/implemented-green) + * HTTP/1.1,2,3 ![studying](https://img.shields.io/badge/studying-magenta) + * ASN.1 ![studying](https://img.shields.io/badge/studying-magenta) +* link + * [changelog](CHANGELOG.md) + * [implemented](#implemented) + * [applied](#applied) + * [not applied](#not-applied) + * [studying](#studying) + * [next time](#next-time) + * [build](#build) + * [custom toolchain](#custom-toolchain) + * [link](#link) ## implemented - * Authenticode (1. for Digital Certificate verification 2. plugin_msi, plugin_cabinet not included) - * sdk/crypto/authenticode/ - * test/authenticode/ - - * RFC 7049 Concise Binary Object Representation (CBOR) - * RFC 8949 Concise Binary Object Representation (CBOR) - * sdk/io/cbor/ - * test/cbor/ - - * RFC 7515 JSON Web Signature (JWS) - * RFC 7516 JSON Web Encryption (JWE) - * RFC 7517 JSON Web Key (JWK) - * RFC 7518 JSON Web Algorithms (JWA) - * RFC 7520 Examples of Protecting Content Using JSON Object Signing and Encryption (JOSE) - * RFC 8037 CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE) - * sdk/crypto/jose/ - * test/jose/ - - * RFC 8152 CBOR Object Signing and Encryption (COSE) - * RFC 8230 Using RSA Algorithms with CBOR Object Signing and Encryption (COSE) Messages - * RFC 8392 CBOR Web Token (CWT) - * RFC 8812 CBOR Object Signing and Encryption (COSE) and JSON Object Signing and Encryption (JOSE) Registrations for Web Authentication (WebAuthn) Algorithms - * RFC 9052 CBOR Object Signing and Encryption (COSE): Structures and Process - * RFC 9053 CBOR Object Signing and Encryption (COSE): Initial Algorithms - * RFC 9338 CBOR Object Signing and Encryption (COSE): Countersignatures - * sdk/crypto/cose/ - * test/cose/ - - * RFC 7541 HPACK: Header Compression for HTTP/2 - * sdk/net/http/http2 - * test/hpack - * test/httpserver2 +* CBOR + * RFC 7049 Concise Binary Object Representation (CBOR) + * RFC 8949 Concise Binary Object Representation (CBOR) + * sdk/io/cbor/ + * test/cbor/ +* COSE + * RFC 8152 CBOR Object Signing and Encryption (COSE) + * RFC 8230 Using RSA Algorithms with CBOR Object Signing and Encryption (COSE) Messages + * RFC 8392 CBOR Web Token (CWT) + * RFC 8812 CBOR Object Signing and Encryption (COSE) and JSON Object Signing and Encryption (JOSE) Registrations for Web Authentication (WebAuthn) Algorithms + * RFC 9052 CBOR Object Signing and Encryption (COSE): Structures and Process + * RFC 9053 CBOR Object Signing and Encryption (COSE): Initial Algorithms + * RFC 9338 CBOR Object Signing and Encryption (COSE): Countersignatures + * sdk/crypto/cose/ + * test/cose/ +* JOSE + * RFC 7515 JSON Web Signature (JWS) + * RFC 7516 JSON Web Encryption (JWE) + * RFC 7517 JSON Web Key (JWK) + * RFC 7518 JSON Web Algorithms (JWA) + * RFC 7520 Examples of Protecting Content Using JSON Object Signing and Encryption (JOSE) + * RFC 8037 CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE) + * sdk/crypto/jose/ + * test/jose/ +* HTTP/1.1 + * RFC 1951 DEFLATE Compressed Data Format Specification version 1.3 + * RFC 1952 GZIP file format specification version 4.3 + * RFC 1945 Hypertext Transfer Protocol -- HTTP/1.0 + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2069 An Extension to HTTP : Digest Access Authentication + * RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication + * RFC 6749 OAuth 2.0 + * RFC 6750 The OAuth 2.0 Authorization Framework: Bearer Token Usage + * RFC 7616 HTTP Digest Access Authentication + * sdk/net/http/ + * test/httpserver/ + * test/httpauth/ + * test/httptest/ +* HTTP/2 + * RFC 7541 HPACK: Header Compression for HTTP/2 + * sdk/net/http/http2 + * test/hpack + * test/httpserver2 + * RFC 7540 Hypertext Transfer Protocol Version 2 (HTTP/2) + * RFC 7301 Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension + * RFC 9113 HTTP/2 + * sdk/net/http/http2/ + * sdk/net/tls/ + * test/payload/ + * test/hpack/ + * test/httpserver2/ +* BASE16, BASE64, BASE64URL + * RFC 4648 The Base16, Base32, and Base64 Data Encodings + * sdk/io/basic/ + * test/encode/ +* HOTP, TOTP + * RFC 4226 HOTP: An HMAC-Based One-Time Password Algorithm + * RFC 6238 TOTP: Time-Based One-Time Password Algorithm + * sdk/crypto/basic/ + * test/hash/ + * test/sign/ +* Pattern Search + * KMP algorithm, Trie, Suffix Tree, Ukkonen algorithm, Aho-Corasick algorithm + * sdk/base/nostd/ + * test/pattern/ + * test/parser/ +* Graph + * BFS, DFS, Djkstra + * sdk/base/nostd/ + * test/graph/ +* Authenticode + * Digital Certificate verification (plugin_msi, plugin_cabinet excluded) + * sdk/crypto/authenticode/ + * test/authenticode/ ## applied - * Pattern Search (KMP algorithm, Trie, Suffix Tree, Ukkonen algorithm, Aho-Corasick algorithm) - * sdk/base/nostd/ - * test/pattern/ - * test/parser/ - - * RFC 4648 The Base16, Base32, and Base64 Data Encodings - * sdk/io/basic/ - * test/encode/ - - * RFC 2144 The CAST-128 Encryption Algorithm (May 1997) - * RFC 2612 The CAST-256 Encryption Algorithm (June 1999) - * RFC 3217 Triple-DES and RC2 Key Wrapping (December 2001) - * RFC 3394 Advanced Encryption Standard (AES) Key Wrap Algorithm (September 2002) - * RFC 3610 Counter with CBC-MAC (CCM) - * RFC 4615 The Advanced Encryption Standard-Cipher-based Message Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) Algorithm for the Internet Key Exchange Protocol (IKE) - * RFC 4772 Security Implications of Using the Data Encryption Standard (DES) (December 2006) - * RFC 5649 Advanced Encryption Starndard (AES) Key Wrap with Padding Algorithm (September 2009) - * RFC 5794 A Description of the ARIA Encryption Algorithm (March 2010) - * RFC 5869 HMAC-based Extract-and-Expand Key Derivation Function (HKDF) - * RFC 6070 PKCS #5: Password-Based Key Derivation Function 2 (PBKDF2) Test Vectors - * RFC 7539 ChaCha20 and Poly1305 for IETF Protocols - * RFC 7914 The scrypt Password-Based Key Derivation Function - * RFC 8017 PKCS #1: RSA Cryptography Specifications Version 2.2 - * RFC 8439 ChaCha20 and Poly1305 for IETF Protocols - * RFC 9106 Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications - * [Authenticated Encryption with AES-CBC and HMAC-SHA](https://www.ietf.org/archive/id/draft-mcgrew-aead-aes-cbc-hmac-sha2-05.txt) - * sdk/crypto/basic/ - * test/crypto/ - * test/kdf/ - - * RFC 2104 HMAC: Keyed-Hashing for Message Authentication - * RFC 4226 HOTP: An HMAC-Based One-Time Password Algorithm - * RFC 4231 HMAC-SHA Identifiers and Test Vectors December 2005 - * RFC 4493 The AES-CMAC Algorithm - * RFC 6238 TOTP: Time-Based One-Time Password Algorithm - * RFC 6979 Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) - * [NIST CAVP (Cryptographic Algorithm Validation Program) ECDSA](https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/digital-signatures) - * sdk/crypto/basic/ - * test/hash/ - * test/sign/ - - * RFC 1951 DEFLATE Compressed Data Format Specification version 1.3 - * RFC 1952 GZIP file format specification version 4.3 - * RFC 1945 Hypertext Transfer Protocol -- HTTP/1.0 - * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 - * RFC 2069 An Extension to HTTP : Digest Access Authentication - * RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax - * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 - * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication - * RFC 6749 OAuth 2.0 - * RFC 6750 The OAuth 2.0 Authorization Framework: Bearer Token Usage - * RFC 7616 HTTP Digest Access Authentication - * sdk/net/http/ - * test/httpserver/ - * test/httpauth/ - * test/httptest/ - - * RFC 7540 Hypertext Transfer Protocol Version 2 (HTTP/2) - * RFC 7301 Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension - * RFC 9113 HTTP/2 - * sdk/net/http/http2/ - * sdk/net/tls/ - * test/payload/ - * test/hpack/ - * test/httpserver2/ - - * RFC 7638 3.1. Example JWK Thumbprint Computation - * test/jose/ - - * RFC 8446 The Transport Layer Security (TLS) Protocol Version 1.3 - * RFC 8996 Deprecating TLS 1.0 and TLS 1.1 - * sdk/net/tls/ - * test/tlsserver/ - - * IEEE 754 - * test/ieee754/ +* OpenSSL + * RFC 2144 The CAST-128 Encryption Algorithm (May 1997) + * RFC 2612 The CAST-256 Encryption Algorithm (June 1999) + * RFC 3217 Triple-DES and RC2 Key Wrapping (December 2001) + * RFC 3394 Advanced Encryption Standard (AES) Key Wrap Algorithm (September 2002) + * RFC 3610 Counter with CBC-MAC (CCM) + * RFC 4615 The Advanced Encryption Standard-Cipher-based Message Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) Algorithm for the Internet Key Exchange Protocol (IKE) + * RFC 4772 Security Implications of Using the Data Encryption Standard (DES) (December 2006) + * RFC 5649 Advanced Encryption Starndard (AES) Key Wrap with Padding Algorithm (September 2009) + * RFC 5794 A Description of the ARIA Encryption Algorithm (March 2010) + * RFC 5869 HMAC-based Extract-and-Expand Key Derivation Function (HKDF) + * RFC 6070 PKCS #5: Password-Based Key Derivation Function 2 (PBKDF2) Test Vectors + * RFC 7539 ChaCha20 and Poly1305 for IETF Protocols + * RFC 7914 The scrypt Password-Based Key Derivation Function + * RFC 8017 PKCS #1: RSA Cryptography Specifications Version 2.2 + * RFC 8439 ChaCha20 and Poly1305 for IETF Protocols + * RFC 9106 Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications + * [Authenticated Encryption with AES-CBC and HMAC-SHA](https://www.ietf.org/archive/id/draft-mcgrew-aead-aes-cbc-hmac-sha2-05.txt) + * sdk/crypto/basic/ + * test/crypto/ + * test/kdf/ + + * RFC 2104 HMAC: Keyed-Hashing for Message Authentication + * RFC 4231 HMAC-SHA Identifiers and Test Vectors December 2005 + * RFC 4493 The AES-CMAC Algorithm + * RFC 6979 Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) + * [NIST CAVP (Cryptographic Algorithm Validation Program) ECDSA](https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/digital-signatures) + * sdk/crypto/basic/ + * test/hash/ + * test/sign/ + +* JOSE + * RFC 7638 3.1. Example JWK Thumbprint Computation + * test/jose/ +* TLS + * RFC 8446 The Transport Layer Security (TLS) Protocol Version 1.3 + * RFC 8996 Deprecating TLS 1.0 and TLS 1.1 + * sdk/net/tls/ + * test/tlsserver/ +* IEEE 754 + * half/single/double precision floating point + * test/ieee754/ ## not applied ## studying - * RFC 2817 Upgrading to TLS Within HTTP/1.1 - - * RFC 4347 Datagram Transport Layer Security - * RFC 6347 Datagram Transport Layer Security Version 1.2 - * RFC 9147 The Datagram Transport Layer Security (DTLS) Protocol Version 1.3 - - * RFC 9204 QPACK: Field Compression for HTTP/3 - * RFC 9114 HTTP/3 - - * ITU-T X.680-X.699 - * [X.680-X.693 : Information Technology - Abstract Syntax Notation One (ASN.1) & ASN.1 encoding rules](https://www.itu.int/rec/T-REC-X.680-X.693-202102-I/en) - * Recommendation X.680-X.693 (02/21) - * [ASN.1 (Abstract Syntax Notation One) is the international standard for representing data types and structures.](https://obj-sys.com/asn1tutorial/asn1only.html) - * ITU-T X.680 ISO/IEC 8824-1 Abstract Syntax Notation One (ASN.1): Specification of basic notation - * ITU-T X.681 ISO/IEC 8824-2 Abstract Syntax Notation One (ASN.1): Information object specification - * ITU-T X.682 ISO/IEC 8824-3 Abstract Syntax Notation One (ASN.1): Constraint specification - * ITU-T X.683 ISO/IEC 8824-4 Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications - * ITU-T X.690 ISO/IEC 8825-1 ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER) - * ITU-T X.691 ISO/IEC 8825-2 ASN.1 encoding rules: Specification of Packed Encoding Rules (PER) - * ITU-T X.692 ISO/IEC 8825-3 ASN.1 encoding rules: Specification of Encoding Control Notation (ECN) - * ITU-T X.693 ISO/IEC 8825-4 ASN.1 encoding rules: XML Encoding Rules (XER) - - * Neural Networks / Machine Learning - * sketch repository (private, spin off, in progress) +* HTTP/1.1 + * RFC 2817 Upgrading to TLS Within HTTP/1.1 +* HTTP/3 + * RFC 4347 Datagram Transport Layer Security + * RFC 6347 Datagram Transport Layer Security Version 1.2 + * RFC 9147 The Datagram Transport Layer Security (DTLS) Protocol Version 1.3 + * RFC 9204 QPACK: Field Compression for HTTP/3 + * RFC 9114 HTTP/3 +* ASN.1 + * ITU-T X.680-X.699 + * [X.680-X.693 : Information Technology - Abstract Syntax Notation One (ASN.1) & ASN.1 encoding rules](https://www.itu.int/rec/T-REC-X.680-X.693-202102-I/en) + * Recommendation X.680-X.693 (02/21) + * [ASN.1 (Abstract Syntax Notation One) is the international standard for representing data types and structures.](https://obj-sys.com/asn1tutorial/asn1only.html) + * ITU-T X.680 ISO/IEC 8824-1 Abstract Syntax Notation One (ASN.1): Specification of basic notation + * ITU-T X.681 ISO/IEC 8824-2 Abstract Syntax Notation One (ASN.1): Information object specification + * ITU-T X.682 ISO/IEC 8824-3 Abstract Syntax Notation One (ASN.1): Constraint specification + * ITU-T X.683 ISO/IEC 8824-4 Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications + * ITU-T X.690 ISO/IEC 8825-1 ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER) + * ITU-T X.691 ISO/IEC 8825-2 ASN.1 encoding rules: Specification of Packed Encoding Rules (PER) + * ITU-T X.692 ISO/IEC 8825-3 ASN.1 encoding rules: Specification of Encoding Control Notation (ECN) + * ITU-T X.693 ISO/IEC 8825-4 ASN.1 encoding rules: XML Encoding Rules (XER) +* Neural Networks / Machine Learning + * sketch repository (private, spin off, in progress) ## next time - * RFC 1951 DEFLATE Compressed Data Format Specification version 1.3 - * RFC 1952 GZIP file format specification version 4.3 - * RFC 7932 Brotli Compressed Data Format - * RFC 8478 Zstandard Compression and the application/zstd Media Type - * RFC 8878 Zstandard Compression and the 'application/zstd' Media Type - - * RFC 9114 HTTP/3 - - * RFC 8778 Use of the HSS/LMS Hash-Based Signature Algorithm with CBOR Object Signing and Encryption (COSE) - * RFC 9021 Use of the Walnut Digital Signature Algorithm with CBOR Object Signing and Encryption (COSE) - * RFC 9054 CBOR Object Signing and Encryption (COSE): Hash Algorithms - * RFC 9360 CBOR Object Signing and Encryption (COSE): Header Parameters for Carrying and Referencing X.509 Certificates +* Compression + * RFC 1951 DEFLATE Compressed Data Format Specification version 1.3 + * RFC 1952 GZIP file format specification version 4.3 + * RFC 7932 Brotli Compressed Data Format + * RFC 8478 Zstandard Compression and the application/zstd Media Type + * RFC 8878 Zstandard Compression and the 'application/zstd' Media Type +* COSE + * RFC 8778 Use of the HSS/LMS Hash-Based Signature Algorithm with CBOR Object Signing and Encryption (COSE) + * RFC 9021 Use of the Walnut Digital Signature Algorithm with CBOR Object Signing and Encryption (COSE) + * RFC 9054 CBOR Object Signing and Encryption (COSE): Hash Algorithms + * RFC 9360 CBOR Object Signing and Encryption (COSE): Header Parameters for Carrying and Referencing X.509 Certificates ## build - * platform support - mingw, linux - * packages to install - * gcc, g++, binutils, cmake, gdb - * openssl-devel jansson-devel zlib-devel unixodbc (MINGW) - * openssl-devel jansson zlib-devel unixodbc-devel (Rocky/CentOS/RHEL) - * libssl-dev libjansson-dev zlib1g-dev unixodbc-dev (ubuntu) - * valgrind (linux) - * clang-tools-extra - * build script - * cd hotplace - * ./make.sh debug pch - * os support - * tested - * RHEL 7 and newer, (including CentOS, Rocky Linux) - * ubuntu 20.04 and newer - * mingw - * Fedora Core release 4 (Stentz) w/ custom toolchain (GCC 4.8) +* platform support - mingw, linux +* packages to install + * gcc, g++, binutils, cmake, gdb + * openssl-devel jansson-devel zlib-devel unixodbc (MINGW) + * openssl-devel jansson zlib-devel unixodbc-devel (Rocky/CentOS/RHEL) + * libssl-dev libjansson-dev zlib1g-dev unixodbc-dev (ubuntu) + * valgrind (linux) + * clang-tools-extra +* build script + * cd hotplace + * ./make.sh debug pch +* os support + * tested + * RHEL 7 and newer, (including CentOS, Rocky Linux) + * ubuntu 20.04 and newer + * mingw + * Fedora Core release 4 (Stentz) w/ custom toolchain (GCC 4.8) ## custom toolchain ### openssl - * important - * openssl 1.1.1 or newer - * RSA-OAEP-256 - * Ed25519 Ed448 X25519 X448 - * sha3 - * openssl 3.0, 3.1 - * EVP_CIPHER_fetch/EVP_CIPHER_free, EVP_MD_fetch/EVP_MD_free - * truncated sha ("sha2-512/224", "sha2-512/256") - * failed to load PEM file containing HMAC private key - * openssl 3.2 - * argon2d, argon2i, argon2id - * custom build required in RHEL (RHEL, centos, rocky) and older version - * -fPIC required - * algoritm test, random SEGV, ctr_update SEGV (older linux), ... - - * how to custom build - * build custom openssl (example) - * install perl - * $ sudo yum install perl - * download openssl - * $ wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz - * extract and unzip - * $ tar xvfz openssl-1.1.1w.tar.gz - * cd - * $ cd openssl-1.1.1v - * prefix variable - * **never overwrite system libraries (must not set install_dir=/usr)** - * *RHEL openssl package customized (krb, kdf ??)* - * $ install_dir=somewhere/thirdparty - * configure linux ex. - * $ ./Configure linux-x86_64 enable-idea enable-bf enable-seed --prefix=${install_dir} --with-rand-seed=devrandom -D__USE_UNIX98=1 -D_GNU_SOURCE=1 no-egd shared - * configure mingw ex. - * $ ./Configure mingw64 enable-idea enable-bf enable-seed --prefix=${install_dir} --with-rand-seed=os -D__USE_UNIX98=1 -D_GNU_SOURCE=1 no-egd shared - * make - * $ make - * openssl SEGV ctr_update - FC4, centos5 - * $ touch crypto/rand/drbg_ctr.c - * $ make - * no thanks man pages - * $ make install_sw install_ssldirs +* important + * openssl 1.1.1 or newer + * RSA-OAEP-256 + * Ed25519 Ed448 X25519 X448 + * sha3 + * openssl 3.0, 3.1 + * EVP_CIPHER_fetch/EVP_CIPHER_free, EVP_MD_fetch/EVP_MD_free + * truncated sha ("sha2-512/224", "sha2-512/256") + * failed to load PEM file containing HMAC private key + * openssl 3.2 + * argon2d, argon2i, argon2id + * custom build required in RHEL (RHEL, centos, rocky) and older version + * -fPIC required + * algoritm test, random SEGV, ctr_update SEGV (older linux), ... + +* how to custom build + * build custom openssl (example) + * install perl + * $ sudo yum install perl + * download openssl + * $ wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz + * extract and unzip + * $ tar xvfz openssl-1.1.1w.tar.gz + * cd + * $ cd openssl-1.1.1v + * prefix variable + * **never overwrite system libraries (must not set install_dir=/usr)** + * *RHEL openssl package customized (krb, kdf ??)* + * $ install_dir=somewhere/thirdparty + * configure linux ex. + * $ ./Configure linux-x86_64 enable-idea enable-bf enable-seed --prefix=${install_dir} --with-rand-seed=devrandom -D__USE_UNIX98=1 -D_GNU_SOURCE=1 no-egd shared + * configure mingw ex. + * $ ./Configure mingw64 enable-idea enable-bf enable-seed --prefix=${install_dir} --with-rand-seed=os -D__USE_UNIX98=1 -D_GNU_SOURCE=1 no-egd shared + * make + * $ make + * openssl SEGV ctr_update - FC4, centos5 + * $ touch crypto/rand/drbg_ctr.c + * $ make + * no thanks man pages + * $ make install_sw install_ssldirs ### jansson - * build custom jansson (example) - * see https://github.com/akheron/jansson - * aclocal; autoheader; autoconf; - * libtoolize --automake --copy --force - * automake --foreign --copy --add-missing - * $ install_dir=somewhere/thirdparty - * ./configure --prefix=${install_dir} --enable-static --enable-shared CPPFLAGS="-fPIC" - * make - * make install +* build custom jansson (example) + * see https://github.com/akheron/jansson + * aclocal; autoheader; autoconf; + * libtoolize --automake --copy --force + * automake --foreign --copy --add-missing + * $ install_dir=somewhere/thirdparty + * ./configure --prefix=${install_dir} --enable-static --enable-shared CPPFLAGS="-fPIC" + * make + * make install ### FC4 custom toolchain - * toolchain dependencies - * cmake (2.8.10.2) - * perl (5.10.0) - * m4 (1.4.13) - * autoconf (2.65) - * automake (1.16.4) - * libtool (1.5.2) - * make (3.80) - * gmp (4.3.2) - * mpfr (2.4.2) - * mpc (1.0.3) - * isl (0.10) - * binutils (2.18) - * gcc (4.8.5) +* toolchain dependencies + * cmake (2.8.10.2) + * perl (5.10.0) + * m4 (1.4.13) + * autoconf (2.65) + * automake (1.16.4) + * libtool (1.5.2) + * make (3.80) + * gmp (4.3.2) + * mpfr (2.4.2) + * mpc (1.0.3) + * isl (0.10) + * binutils (2.18) + * gcc (4.8.5) # link diff --git a/sdk/base/basic/base64.cpp b/sdk/base/basic/base64.cpp index 082a21f5..c1208afb 100644 --- a/sdk/base/basic/base64.cpp +++ b/sdk/base/basic/base64.cpp @@ -113,6 +113,7 @@ return_t base64_encode(const byte_t* source, size_t source_size, byte_t* buffer, const byte_t* table = MIME_BASE64_ENCODE; if (base64_encoding_t::base64url_encoding == encoding) { + // RFC 7515 Appendix C. Notes on Implementing base64url Encoding without Padding table = MIME_BASE64URL_ENCODE; } @@ -144,6 +145,7 @@ return_t base64_encode(const byte_t* source, size_t source_size, byte_t* buffer, buffer[j + 2] = table[temp.e2]; buffer[j + 3] = table[temp.e1]; + // RFC 7515 Appendix C. Notes on Implementing base64url Encoding without Padding if (base64_encoding_t::base64_encoding == encoding) { if ((i + 2) > source_size) { buffer[j + 2] = '='; diff --git a/sdk/base/system/linux/thread.cpp b/sdk/base/system/linux/thread.cpp index 788eb665..14914634 100644 --- a/sdk/base/system/linux/thread.cpp +++ b/sdk/base/system/linux/thread.cpp @@ -41,6 +41,8 @@ return_t thread::start() { ret = errorcode_t::failed; } pthread_attr_destroy(&attr); + } else { + ret = errorcode_t::already_assigned; } return ret; } diff --git a/sdk/base/system/windows/thread.cpp b/sdk/base/system/windows/thread.cpp index e43247e9..4a52eca5 100644 --- a/sdk/base/system/windows/thread.cpp +++ b/sdk/base/system/windows/thread.cpp @@ -32,6 +32,8 @@ return_t thread::start() { if (nullptr == _tid) { ret = GetLastError(); } + } else { + ret = errorcode_t::already_assigned; } return ret; } diff --git a/sdk/crypto/basic/crypto_advisor.cpp b/sdk/crypto/basic/crypto_advisor.cpp index 67284b43..f71d7414 100644 --- a/sdk/crypto/basic/crypto_advisor.cpp +++ b/sdk/crypto/basic/crypto_advisor.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace hotplace { @@ -1107,5 +1108,16 @@ bool crypto_advisor::at_least_openssl_version(unsigned long osslver) { return (ver >= osslver) ? true : false; } +void crypto_advisor::get_cookie_secret(uint8 key, size_t secret_size, binary_t& secret) { + auto iter = _cookie_secret.find(key); + if (_cookie_secret.end() == iter) { + openssl_prng prng; + prng.random(secret, secret_size); + _cookie_secret.insert({key, secret}); + } else { + secret = iter->second; + } +} + } // namespace crypto } // namespace hotplace diff --git a/sdk/crypto/basic/crypto_advisor.hpp b/sdk/crypto/basic/crypto_advisor.hpp index e946bf40..ef21dcb4 100644 --- a/sdk/crypto/basic/crypto_advisor.hpp +++ b/sdk/crypto/basic/crypto_advisor.hpp @@ -534,6 +534,17 @@ class crypto_advisor { bool query_feature(const char* feature, uint32 spec = 0); bool at_least_openssl_version(unsigned long osslver); + /** + * @brief cookie secret + * @param uint8 key [in] + * @param size_t secret_size [in] + * @param binary_t& secret [out] + * @example + * advisor->get_cookie_secret(0, 16, secret); // generate 16 bytes + * advisor->get_cookie_secret(0, 16, secret); // read generated secret, secret_size ignored + */ + void get_cookie_secret(uint8 key, size_t secret_size, binary_t& secret); + protected: return_t build_if_necessary(); return_t cleanup(); @@ -612,6 +623,8 @@ class crypto_advisor { std::map _features; std::map _versions; + + std::map _cookie_secret; }; extern const hint_cipher_t evp_cipher_methods[]; diff --git a/sdk/crypto/cose/cbor_object_encryption.cpp b/sdk/crypto/cose/cbor_object_encryption.cpp index 34c9e830..b446d066 100644 --- a/sdk/crypto/cose/cbor_object_encryption.cpp +++ b/sdk/crypto/cose/cbor_object_encryption.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cbor_object_signing.cpp b/sdk/crypto/cose/cbor_object_signing.cpp index 2ae3932b..2a5295f4 100644 --- a/sdk/crypto/cose/cbor_object_signing.cpp +++ b/sdk/crypto/cose/cbor_object_signing.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cbor_object_signing_encryption.cpp b/sdk/crypto/cose/cbor_object_signing_encryption.cpp index 220b2494..5c7e2196 100644 --- a/sdk/crypto/cose/cbor_object_signing_encryption.cpp +++ b/sdk/crypto/cose/cbor_object_signing_encryption.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description @@ -408,6 +409,7 @@ return_t cbor_object_signing_encryption::process(cose_context_t* handle, crypto_ results.insert(check); } + // RFC 8152 4.5. Computing Counter Signatures cose_countersigns* countersigns1 = body.get_countersigns0(); if (countersigns1) { if (cose_flag_t::cose_flag_allow_debug & handle->flags) { diff --git a/sdk/crypto/cose/cbor_web_key.cpp b/sdk/crypto/cose/cbor_web_key.cpp index abcb8912..724fc040 100644 --- a/sdk/crypto/cose/cbor_web_key.cpp +++ b/sdk/crypto/cose/cbor_web_key.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_binary.cpp b/sdk/crypto/cose/cose_binary.cpp index a0675a8f..f94dc82f 100644 --- a/sdk/crypto/cose/cose_binary.cpp +++ b/sdk/crypto/cose/cose_binary.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_composer.cpp b/sdk/crypto/cose/cose_composer.cpp index 1cefbd79..8c7f8c48 100644 --- a/sdk/crypto/cose/cose_composer.cpp +++ b/sdk/crypto/cose/cose_composer.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_data.cpp b/sdk/crypto/cose/cose_data.cpp index 637f92e7..d841b763 100644 --- a/sdk/crypto/cose/cose_data.cpp +++ b/sdk/crypto/cose/cose_data.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_key.cpp b/sdk/crypto/cose/cose_key.cpp index 8fdf2c10..f3a0c9d4 100644 --- a/sdk/crypto/cose/cose_key.cpp +++ b/sdk/crypto/cose/cose_key.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_protected.cpp b/sdk/crypto/cose/cose_protected.cpp index 3b9e2375..2e9af5e1 100644 --- a/sdk/crypto/cose/cose_protected.cpp +++ b/sdk/crypto/cose/cose_protected.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_recipient.cpp b/sdk/crypto/cose/cose_recipient.cpp index 040e1a72..0eff7a41 100644 --- a/sdk/crypto/cose/cose_recipient.cpp +++ b/sdk/crypto/cose/cose_recipient.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_recipients.cpp b/sdk/crypto/cose/cose_recipients.cpp index 5ff22d3e..03144f66 100644 --- a/sdk/crypto/cose/cose_recipients.cpp +++ b/sdk/crypto/cose/cose_recipients.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_unprotected.cpp b/sdk/crypto/cose/cose_unprotected.cpp index c2fa318d..a7d6bd33 100644 --- a/sdk/crypto/cose/cose_unprotected.cpp +++ b/sdk/crypto/cose/cose_unprotected.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/cose/cose_unsent.cpp b/sdk/crypto/cose/cose_unsent.cpp index 11897ed7..ddfb4335 100644 --- a/sdk/crypto/cose/cose_unsent.cpp +++ b/sdk/crypto/cose/cose_unsent.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 8152 CBOR Object Signing and Encryption (COSE) * * Revision History * Date Name Description diff --git a/sdk/crypto/jose/json_object_encryption.cpp b/sdk/crypto/jose/json_object_encryption.cpp index 2a3f3abb..9a2a9516 100644 --- a/sdk/crypto/jose/json_object_encryption.cpp +++ b/sdk/crypto/jose/json_object_encryption.cpp @@ -180,6 +180,7 @@ return_t json_object_encryption::decrypt(jose_context_t *handle, const std::stri ret_test = dodecrypt(handle, enc, alg, kid.c_str(), item.datamap[crypt_item_t::item_ciphertext], output); } if ((errorcode_t::success == ret_test) && zip.size() && (0 == memcmp(&zip[0], "DEF", 3))) { + // RFC 7520 5.9. Compressed Content binary_t inflated; zlib_inflate(zlib_windowbits_t::windowbits_deflate, output, inflated); output = inflated; @@ -290,10 +291,6 @@ return_t json_object_encryption::doencrypt(jose_context_t *handle, jwe_t enc, jw * RFC7518 4.4. Key Wrapping with AES Key Wrap * RFC7520 5.8. Key Wrap Using AES-KeyWrap with AES-GCM */ - // crypt_context_t* handle_kw = nullptr; - // crypt.open(&handle_kw, alg_crypt_alg, alg_crypt_mode, &oct[0], - // oct.size(), &kw_iv[0], kw_iv.size()); ret = crypt.encrypt(handle_kw, - // &cek[0], cek.size(), encrypted_key); crypt.close(handle_kw); ret = crypt.encrypt(alg_crypt_alg, alg_crypt_mode, oct, kw_iv, cek, encrypted_key); } else if (jwa_group_t::jwa_group_dir == alg_group) { /* @@ -328,10 +325,8 @@ return_t json_object_encryption::doencrypt(jose_context_t *handle, jwe_t enc, jw * RFC7518 4.6. Key Agreement with Elliptic Curve Diffie-Hellman * Ephemeral Static (ECDH-ES) * 2. as a symmetric key used to wrap the CEK with the "A128KW", - * "A192KW", or "A256KW" algorithms, in the Key Agreement with Key - * Wrapping mode. - * RFC7520 5.4. Key Agreement with Key Wrapping Using ECDH-ES and - * AES-KeyWrap with AES-GCM + * "A192KW", or "A256KW" algorithms, in the Key Agreement with Key Wrapping mode. + * RFC7520 5.4. Key Agreement with Key Wrapping Using ECDH-ES and AES-KeyWrap with AES-GCM */ binary_t derived_key; const EVP_PKEY *epk = item.recipients[alg].epk; @@ -342,11 +337,6 @@ return_t json_object_encryption::doencrypt(jose_context_t *handle, jwe_t enc, jw } ret = ecdh_es(epk, pkey, alg_hint->alg_name, "", "", keylen, derived_key); - // crypt_context_t* handle_kw = nullptr; - // crypt.open(&handle_kw, alg_crypt_alg, alg_crypt_mode, - // &derived_key[0], derived_key.size(), &kw_iv[0], kw_iv.size()); ret = - // crypt.encrypt(handle_kw, &cek[0], cek.size(), encrypted_key); - // crypt.close(handle_kw); ret = crypt.encrypt(alg_crypt_alg, alg_crypt_mode, derived_key, kw_iv, cek, encrypted_key); } else if (jwa_group_t::jwa_group_aesgcmkw == alg_group) { /* @@ -356,14 +346,8 @@ return_t json_object_encryption::doencrypt(jose_context_t *handle, jwe_t enc, jw */ binary_t iv1 = item.recipients[alg].datamap[crypt_item_t::item_iv]; binary_t aad1; // empty - binary_t &tag1 = item.recipients[alg].datamap[crypt_item_t::item_tag]; // compute authencation tag - // here - - // crypt_context_t* handle_crypt = nullptr; - // crypt.open(&handle_crypt, alg_crypt_alg, alg_crypt_mode, &oct[0], - // oct.size(), &iv1[0], iv1.size()); ret = crypt.encrypt2(handle_crypt, - // &cek[0], cek.size(), encrypted_key, &aad1, &tag1); - // crypt.close(handle_crypt); + binary_t &tag1 = item.recipients[alg].datamap[crypt_item_t::item_tag]; // compute authencation tag here + ret = crypt.encrypt(alg_crypt_alg, alg_crypt_mode, oct, iv1, cek, encrypted_key, aad1, tag1); /* @@ -402,22 +386,8 @@ return_t json_object_encryption::doencrypt(jose_context_t *handle, jwe_t enc, jw * derived_key = PKCS5_PBKDF2_HMAC(passphrase, salt, iteration_count = * p2c, hash) */ - // oct.resize(0); binary_t pbkdf2_derived_key; - // pbkdf2_derived_key.resize (alg_keysize); - // const EVP_MD* alg_evp_md = (const EVP_MD*) advisor->find_evp_md - // (alg_hash_alg); PKCS5_PBKDF2_HMAC ((char *) &oct[0], oct.size (), - // &salt[0], salt.size (), p2c, alg_evp_md, - // pbkdf2_derived_key.size (), - // &pbkdf2_derived_key[0]); kdf.pbkdf2(pbkdf2_derived_key, alg_hash_alg, alg_keysize, tostring(oct), salt, p2c); - - // crypt_context_t* crypt_handle = nullptr; - // crypt.open(&crypt_handle, alg_crypt_alg, alg_crypt_mode, - // &pbkdf2_derived_key[0], pbkdf2_derived_key.size(), &kw_iv[0], - // kw_iv.size()); - // ret = crypt.encrypt(crypt_handle, &cek[0], cek.size(), - // encrypted_key); crypt.close(crypt_handle); ret = crypt.encrypt(alg_crypt_alg, alg_crypt_mode, pbkdf2_derived_key, kw_iv, cek, encrypted_key); } } @@ -438,12 +408,6 @@ return_t json_object_encryption::doencrypt(jose_context_t *handle, jwe_t enc, jw openssl_aead aead; ret = aead.aes_cbc_hmac_sha2_encrypt(enc_crypt_alg, enc_crypt_mode, enc_hash_alg, cek, iv, aad, input, ciphertext, tag); } else if (jwe_group_t::jwe_group_aesgcm == enc_group) { - // crypt_context_t* handle_crypt = nullptr; - // crypt.open(&handle_crypt, enc_crypt_alg, enc_crypt_mode, &cek[0], - // cek.size(), &iv[0], iv.size()); - // /* Content Encryption */ - // ret = crypt.encrypt2(handle_crypt, &input[0], input.size(), - // ciphertext, &aad, &tag); crypt.close(handle_crypt); ret = crypt.encrypt(enc_crypt_alg, enc_crypt_mode, cek, iv, input, ciphertext, aad, tag); } } @@ -531,11 +495,6 @@ return_t json_object_encryption::dodecrypt(jose_context_t *handle, jwe_t enc, jw } if (crypto_kty_t::kty_oct == alg_hint->kty) { - /* EVP_KEY_HMAC key data and length */ - // size_t key_length = 0; - // EVP_PKEY_get_raw_private_key(pkey, nullptr, &key_length); - // oct.resize(key_length); - // EVP_PKEY_get_raw_private_key(pkey, &oct[0], &key_length); crypto_kty_t kty; crypto_key::get_privkey(pkey, kty, oct, true); } @@ -558,11 +517,6 @@ return_t json_object_encryption::dodecrypt(jose_context_t *handle, jwe_t enc, jw * RFC7518 4.4. Key Wrapping with AES Key Wrap * RFC7520 5.8. Key Wrap Using AES-KeyWrap with AES-GCM */ - // crypt_context_t* handle_kw = nullptr; - // crypt.open(&handle_kw, alg_crypt_alg, alg_crypt_mode, &oct[0], - // oct.size(), &kw_iv[0], kw_iv.size()); ret = crypt.decrypt(handle_kw, - // &encrypted_key[0], encrypted_key.size(), cek); - // crypt.close(handle_kw); ret = crypt.decrypt(alg_crypt_alg, alg_crypt_mode, oct, kw_iv, encrypted_key, cek); } else if (jwa_group_t::jwa_group_dir == alg_group) { /* @@ -608,11 +562,6 @@ return_t json_object_encryption::dodecrypt(jose_context_t *handle, jwe_t enc, jw } ret = ecdh_es(pkey, epk, alg_hint->alg_name, "", "", keylen, derived_key); - // crypt_context_t* handle_kw = nullptr; - // crypt.open(&handle_kw, alg_crypt_alg, alg_crypt_mode, - // &derived_key[0], derived_key.size(), &kw_iv[0], kw_iv.size()); ret = - // crypt.decrypt(handle_kw, &encrypted_key[0], encrypted_key.size(), - // cek); crypt.close(handle_kw); ret = crypt.decrypt(alg_crypt_alg, alg_crypt_mode, derived_key, kw_iv, encrypted_key, cek); } else if (jwa_group_t::jwa_group_aesgcmkw == alg_group) { /* @@ -624,12 +573,6 @@ return_t json_object_encryption::dodecrypt(jose_context_t *handle, jwe_t enc, jw binary_t aad1; // empty binary_t tag1 = item.recipients[alg].datamap[crypt_item_t::item_tag]; - /* cek, aad(null), tag = AESGCM (HMAC.key, iv).decrypt (encryted_key) */ - // crypt_context_t* handle_crypt = nullptr; - // crypt.open(&handle_crypt, alg_crypt_alg, alg_crypt_mode, &oct[0], - // oct.size(), &iv1[0], iv1.size()); ret = crypt.decrypt2(handle_crypt, - // &encrypted_key[0], encrypted_key.size(), cek, &aad1, &tag1); - // crypt.close(handle_crypt); ret = crypt.decrypt(alg_crypt_alg, alg_crypt_mode, oct, iv1, encrypted_key, cek, aad1, tag1); } else if (jwa_group_t::jwa_group_pbes_hs_aeskw == alg_group) { /* @@ -653,19 +596,7 @@ return_t json_object_encryption::dodecrypt(jose_context_t *handle, jwe_t enc, jw * p2c, hash) */ binary_t pbkdf2_derived_key; - // pbkdf2_derived_key.resize (alg_keysize); - // const EVP_MD* alg_evp_md = (const EVP_MD*) advisor->find_evp_md - // (alg_hash_alg); PKCS5_PBKDF2_HMAC ((char *) &oct[0], oct.size (), - // &salt[0], salt.size (), p2c, alg_evp_md, - // pbkdf2_derived_key.size (), - // &pbkdf2_derived_key[0]); kdf.pbkdf2(pbkdf2_derived_key, alg_hash_alg, alg_keysize, tostring(oct), salt, p2c); - - // crypt_context_t* crypt_handle = nullptr; - // crypt.open(&crypt_handle, alg_crypt_alg, alg_crypt_mode, - // &pbkdf2_derived_key[0], pbkdf2_derived_key.size(), &kw_iv[0], - // kw_iv.size()); ret = crypt.decrypt(crypt_handle, &encrypted_key[0], - // encrypted_key.size(), cek); crypt.close(crypt_handle); ret = crypt.decrypt(alg_crypt_alg, alg_crypt_mode, pbkdf2_derived_key, kw_iv, encrypted_key, cek); } } @@ -686,12 +617,6 @@ return_t json_object_encryption::dodecrypt(jose_context_t *handle, jwe_t enc, jw openssl_aead aead; ret = aead.aes_cbc_hmac_sha2_decrypt(enc_crypt_alg, enc_crypt_mode, enc_hash_alg, cek, iv, aad, ciphertext, output, tag); } else if (jwe_group_t::jwe_group_aesgcm == enc_group) { - // crypt_context_t* handle_crypt = nullptr; - // crypt.open(&handle_crypt, enc_crypt_alg, enc_crypt_mode, &cek[0], - // cek.size(), &iv[0], iv.size()); - // /* Content Encryption */ - // ret = crypt.decrypt2(handle_crypt, &ciphertext[0], ciphertext.size(), - // output, &aad, &tag); crypt.close(handle_crypt); ret = crypt.decrypt(enc_crypt_alg, enc_crypt_mode, cek, iv, ciphertext, output, aad, tag); } } @@ -1106,8 +1031,6 @@ return_t json_object_encryption::composer::docompose_encryption_header_parameter json_header = json_object(); if (jose_compose_t::jose_enc_only & flag) { - // const hint_jose_encryption_t* enc_hint = - // advisor->hintof_jose_encryption(enc); if (nullptr == enc_value) { ret = errorcode_t::invalid_parameter; __leave2; @@ -1162,6 +1085,7 @@ return_t json_object_encryption::composer::docompose_encryption_header_parameter } } if (flags & jose_flag_t::jose_deflate) { + // RFC 7520 5.9. Compressed Content json_object_set_new(json_header, "zip", json_string("DEF")); } diff --git a/sdk/crypto/jose/json_object_signing.cpp b/sdk/crypto/jose/json_object_signing.cpp index b5f16660..981e8ca7 100644 --- a/sdk/crypto/jose/json_object_signing.cpp +++ b/sdk/crypto/jose/json_object_signing.cpp @@ -239,22 +239,32 @@ return_t json_object_signing::dosign(crypto_key* key, jws_t sig, const binary_t& } SIGN_TABLE; SIGN_TABLE sign_table[] = { + // RFC 7515 A.1. Example JWS Using HMAC SHA-256 + // RFC 7520 4.4. HMAC-SHA2 Integrity Protection { jws_group_t::jws_group_hmac, &openssl_sign::sign_hmac, }, + // RFC 7515 A.2. Example JWS Using RSASSA-PKCS1-v1_5 SHA-256 + // RFC 7520 4.1. RSA v1.5 Signature { jws_group_t::jws_group_rsassa_pkcs15, &openssl_sign::sign_rsassa_pkcs15, }, + // RFC 7515 A.3. Example JWS Using ECDSA P-256 SHA-256 + // RFC 7515 A.4. Example JWS Using ECDSA P-521 SHA-512 + // RFC 7520 4.3. ECDSA Signature { jws_group_t::jws_group_ecdsa, &openssl_sign::sign_ecdsa, }, + // RFC 7520 4.2. RSA-PSS Signature { jws_group_t::jws_group_rsassa_pss, &openssl_sign::sign_rsassa_pss, }, + // RFC 8037 A.4. Ed25519 Signing + // RFC 8037 A.5. Ed25519 Validation { jws_group_t::jws_group_eddsa, &openssl_sign::sign_eddsa, @@ -269,7 +279,6 @@ return_t json_object_signing::dosign(crypto_key* key, jws_t sig, const binary_t& } int group = hint->group; -#if __cplusplus >= 201103L // c++11 const SIGN_TABLE* item = std::find_if(std::begin(sign_table), std::end(sign_table), [group](const SIGN_TABLE& item) { return item.group == group; }); if (std::end(sign_table) != item) { signer = item->signer; @@ -277,19 +286,6 @@ return_t json_object_signing::dosign(crypto_key* key, jws_t sig, const binary_t& ret = errorcode_t::not_supported; __leave2; } -#else - for (size_t k = 0; k < RTL_NUMBER_OF(sign_table); k++) { - SIGN_TABLE* item = sign_table + k; - if (item->group == group) { - signer = item->signer; - break; - } - } - if (nullptr == signer) { - ret = errorcode_t::not_supported; - __leave2; - } -#endif const EVP_PKEY* pkey = nullptr; pkey = key->select(kid, sig, crypto_use_t::use_sig); @@ -340,22 +336,32 @@ return_t json_object_signing::doverify(crypto_key* key, const char* kid, jws_t s } SIGN_TABLE; SIGN_TABLE sign_table[] = { + // RFC 7515 A.1. Example JWS Using HMAC SHA-256 + // RFC 7520 4.4. HMAC-SHA2 Integrity Protection { jws_group_t::jws_group_hmac, &openssl_sign::verify_hmac, }, + // RFC 7515 A.2. Example JWS Using RSASSA-PKCS1-v1_5 SHA-256 + // RFC 7520 4.1. RSA v1.5 Signature { jws_group_t::jws_group_rsassa_pkcs15, &openssl_sign::verify_digest, }, + // RFC 7515 A.3. Example JWS Using ECDSA P-256 SHA-256 + // RFC 7515 A.4. Example JWS Using ECDSA P-521 SHA-512 + // RFC 7520 4.3. ECDSA Signature { jws_group_t::jws_group_ecdsa, &openssl_sign::verify_ecdsa, }, + // RFC 7520 4.2. RSA-PSS Signature { jws_group_t::jws_group_rsassa_pss, &openssl_sign::verify_rsassa_pss, }, + // RFC 8037 A.4. Ed25519 Signing + // RFC 8037 A.5. Ed25519 Validation { jws_group_t::jws_group_eddsa, &openssl_sign::verify_eddsa, @@ -370,7 +376,6 @@ return_t json_object_signing::doverify(crypto_key* key, const char* kid, jws_t s } int group = hint->group; -#if __cplusplus >= 201103L // c++11 const SIGN_TABLE* item = std::find_if(std::begin(sign_table), std::end(sign_table), [group](const SIGN_TABLE& item) { return item.group == group; }); if (std::end(sign_table) != item) { verifier = item->verifier; @@ -378,19 +383,6 @@ return_t json_object_signing::doverify(crypto_key* key, const char* kid, jws_t s ret = errorcode_t::not_supported; __leave2; } -#else - for (size_t k = 0; k < RTL_NUMBER_OF(sign_table); k++) { - SIGN_TABLE* item = sign_table + k; - if (item->group == group) { - verifier = item->verifier; - break; - } - } - if (nullptr == verifier) { - ret = errorcode_t::not_supported; - __leave2; - } -#endif const EVP_PKEY* pkey = nullptr; pkey = key->find(kid, sig, crypto_use_t::use_sig); @@ -674,8 +666,10 @@ return_t json_object_signing::composer::compose_signature(jose_context_t* handle jose_sign_t item = handle->signs.front(); if (jose_serialization_t::jose_compact == type) { + // 7.1. JWS Compact Serialization signature = format("%s.%s.%s", item.header.c_str(), item.payload.c_str(), item.signature.c_str()); } else if (jose_serialization_t::jose_flatjson == type) { + // 7.2.2. Flattened JWS JSON Serialization Syntax json_t* json_serialization = nullptr; __try2 { json_serialization = json_object(); @@ -704,6 +698,7 @@ return_t json_object_signing::composer::compose_signature(jose_context_t* handle } } } else if (jose_serialization_t::jose_json == type) { + // 7.2.1. General JWS JSON Serialization Syntax json_t* json_serialization = nullptr; json_t* json_signatures = nullptr; json_t* json_signature = nullptr; diff --git a/sdk/io.hpp b/sdk/io.hpp index c9eb792e..dcb795c5 100644 --- a/sdk/io.hpp +++ b/sdk/io.hpp @@ -20,8 +20,8 @@ #include #include #include -#include #include +#include /* CBOR */ #include diff --git a/sdk/io/cbor/README.md b/sdk/io/cbor/README.md index 2d386b9b..29eebc8d 100644 --- a/sdk/io/cbor/README.md +++ b/sdk/io/cbor/README.md @@ -1,4 +1,4 @@ -## CBOR +## RFC 8949 CBOR Appendix A. Examples of Encoded CBOR Data Items | Diagnostic | Encoded | |-- |-- | diff --git a/sdk/io/cbor/cbor_data.cpp b/sdk/io/cbor/cbor_data.cpp index 9608c7f7..3694c1ba 100644 --- a/sdk/io/cbor/cbor_data.cpp +++ b/sdk/io/cbor/cbor_data.cpp @@ -72,6 +72,7 @@ void cbor_data::represent(stream_t* s) { case cbor_tag_t::cbor_tag_positive_bignum: case cbor_tag_t::cbor_tag_negative_bignum: // RFC 8949 Concise Binary Object Representation (CBOR) + // 3.4.3. Bignums // Decoders that understand these tags MUST be able to decode bignums that do have leading zeroes. if ((TYPE_BINARY == vt.type) && (vt.size <= 16)) { cbor_bignum_int128 bn; diff --git a/sdk/io/cbor/cbor_encode.cpp b/sdk/io/cbor/cbor_encode.cpp index 0c6f575c..51c1a5b8 100644 --- a/sdk/io/cbor/cbor_encode.cpp +++ b/sdk/io/cbor/cbor_encode.cpp @@ -111,6 +111,7 @@ return_t cbor_encode::encode(binary_t& bin, bool value) { } return_t cbor_encode::encode(binary_t& bin, int8 value) { + // 4.2.1. Core Deterministic Encoding Requirements return_t ret = errorcode_t::success; __try2 { @@ -153,6 +154,7 @@ return_t cbor_encode::encode(binary_t& bin, cbor_major_t major, uint8 value) { } return_t cbor_encode::encode(binary_t& target, int16 value) { + // 4.2.1. Core Deterministic Encoding Requirements return_t ret = errorcode_t::success; __try2 { @@ -201,6 +203,7 @@ return_t cbor_encode::encode(binary_t& target, cbor_major_t major, uint16 value) } return_t cbor_encode::encode(binary_t& target, int32 value) { + // 4.2.1. Core Deterministic Encoding Requirements return_t ret = errorcode_t::success; __try2 { @@ -256,6 +259,7 @@ return_t cbor_encode::encode(binary_t& target, cbor_major_t major, uint32 value) } return_t cbor_encode::encode(binary_t& target, int64 value) { + // 4.2.1. Core Deterministic Encoding Requirements return_t ret = errorcode_t::success; __try2 { @@ -428,6 +432,7 @@ return_t cbor_encode::encodefp16(binary_t& target, uint16 value) { } return_t cbor_encode::encode(binary_t& target, float value) { + // 4.2.2. Additional Deterministic Encoding Considerations return_t ret = errorcode_t::success; __try2 { @@ -456,6 +461,7 @@ return_t cbor_encode::encode(binary_t& target, float value) { } return_t cbor_encode::encode(binary_t& target, double value) { + // 4.2.2. Additional Deterministic Encoding Considerations return_t ret = errorcode_t::success; __try2 { diff --git a/sdk/io/cbor/cbor_publisher.cpp b/sdk/io/cbor/cbor_publisher.cpp index a8ce24a5..1c2266dc 100644 --- a/sdk/io/cbor/cbor_publisher.cpp +++ b/sdk/io/cbor/cbor_publisher.cpp @@ -22,6 +22,7 @@ cbor_publisher::cbor_publisher() { } return_t cbor_publisher::publish(cbor_object* object, binary_t* b) { + // 8. Diagnostic Notation return_t ret = errorcode_t::success; __try2 { diff --git a/sdk/io/string/url.cpp b/sdk/io/string/url.cpp index 4002d5a6..d9268897 100644 --- a/sdk/io/string/url.cpp +++ b/sdk/io/string/url.cpp @@ -111,6 +111,9 @@ return_t unescape_url(const char* url, stream_t* s) { return ret; } +// RFC 2068 3.2 Uniform Resource Identifiers +// 3.2.1 General Syntax +// 3.2.2 http URL return_t split_url(const char* src, url_info_t* info) { return_t ret = errorcode_t::success; diff --git a/sdk/io/system/linux/multiplexer_epoll.cpp b/sdk/io/system/linux/multiplexer_epoll.cpp index b3ab5a78..a67a93d3 100644 --- a/sdk/io/system/linux/multiplexer_epoll.cpp +++ b/sdk/io/system/linux/multiplexer_epoll.cpp @@ -18,6 +18,7 @@ #include #include +#include namespace hotplace { namespace io { @@ -207,10 +208,9 @@ return_t multiplexer_epoll::event_loop_run(multiplexer_context_t* handle, handle __leave2; } - int optval = 0; - socklen_t optlen = sizeof(optval); - getsockopt(listenfd, SOL_SOCKET, SO_TYPE, (char*)&optval, &optlen); - bool is_udp = (SOCK_DGRAM == optval); + int socktype = 0; + typeof_socket((socket_t)listenfd, socktype); + bool is_dgram = (SOCK_DGRAM == socktype); while (true) { bool ret_event_loop_test_broken = controller.event_loop_test_broken(context->handle_controller, token_handle); @@ -239,7 +239,7 @@ return_t multiplexer_epoll::event_loop_run(multiplexer_context_t* handle, handle data_vector[1] = (void*)(arch_t)context->events[i].data.fd; if (context->events[i].data.fd == listenfd) { - multiplexer_event_type_t type = (is_udp ? multiplexer_event_type_t::mux_read : multiplexer_event_type_t::mux_connect); + multiplexer_event_type_t type = (is_dgram ? multiplexer_event_type_t::mux_dgram : multiplexer_event_type_t::mux_connect); event_callback_routine(type, 2, data_vector, &callback_control, parameter); } else if (context->events[i].events & EPOLLIN) { event_callback_routine(multiplexer_event_type_t::mux_read, 2, data_vector, &callback_control, parameter); diff --git a/sdk/io/system/linux/netlink.cpp b/sdk/io/system/linux/netlink.cpp index 477298fa..885ac900 100644 --- a/sdk/io/system/linux/netlink.cpp +++ b/sdk/io/system/linux/netlink.cpp @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include namespace hotplace { namespace io { diff --git a/sdk/io/system/multiplexer.hpp b/sdk/io/system/multiplexer.hpp index c48a0766..e7274b0f 100644 --- a/sdk/io/system/multiplexer.hpp +++ b/sdk/io/system/multiplexer.hpp @@ -28,10 +28,11 @@ enum multiplexer_type_t { enum multiplexer_event_type_t { mux_tryconnect = 0, /* try to sslaccept */ - mux_connect = 1, /* connected */ - mux_read = 2, /* read */ - mux_write = 3, /* send */ - mux_disconnect = 4, /* closed */ + mux_connect = 1, /* stream connected */ + mux_read = 2, /* stream read */ + mux_write = 3, /* stream send, reserved */ + mux_disconnect = 4, /* stream closed */ + mux_dgram = 5, /* datagram read */ }; typedef struct { diff --git a/sdk/io/basic/sdk.cpp b/sdk/io/system/socket.cpp similarity index 98% rename from sdk/io/basic/sdk.cpp rename to sdk/io/system/socket.cpp index 3e7a01c0..ddd0baad 100644 --- a/sdk/io/basic/sdk.cpp +++ b/sdk/io/system/socket.cpp @@ -8,7 +8,7 @@ * Date Name Description */ -#include +#include namespace hotplace { namespace io { @@ -514,5 +514,13 @@ return_t addr_to_sockaddr(sockaddr_storage_t* storage, const char* address, uint return ret; } +return_t typeof_socket(socket_t sock, int& type) { + return_t ret = errorcode_t::success; + socklen_t optlen = sizeof(type); + int rc = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&type, &optlen); + ret = get_lasterror(rc); + return ret; +} + } // namespace io } // namespace hotplace diff --git a/sdk/io/basic/sdk.hpp b/sdk/io/system/socket.hpp similarity index 90% rename from sdk/io/basic/sdk.hpp rename to sdk/io/system/socket.hpp index c1329dd0..b33c4a97 100644 --- a/sdk/io/basic/sdk.hpp +++ b/sdk/io/system/socket.hpp @@ -8,8 +8,8 @@ * Date Name Description */ -#ifndef __HOTPLACE_SDK_IO_BASIC_SDK__ -#define __HOTPLACE_SDK_IO_BASIC_SDK__ +#ifndef __HOTPLACE_SDK_IO_BASIC_SOCKET__ +#define __HOTPLACE_SDK_IO_BASIC_SOCKET__ #include @@ -108,6 +108,18 @@ return_t set_sock_nbio(socket_t sock, uint32 nbio_mode); */ return_t addr_to_sockaddr(sockaddr_storage_t* storage, const char* address, uint16 port); +/** + * @brief type of socket + * @param socket_t sock [in] + * @param int& type [out] + * @sample + * int socktype = 0; + * typeof_socket(listenfd, socktype); + * bool is_stream = (SOCK_STREAM == socktype); + * bool is_dgram = (SOCK_DGRAM == socktype); + */ +return_t typeof_socket(socket_t sock, int& type); + #if defined _WIN32 || defined _WIN64 return_t winsock_startup(); void winsock_cleanup(); diff --git a/sdk/io/system/windows/multiplexer_iocp.cpp b/sdk/io/system/windows/multiplexer_iocp.cpp index 84549a6a..0689466a 100644 --- a/sdk/io/system/windows/multiplexer_iocp.cpp +++ b/sdk/io/system/windows/multiplexer_iocp.cpp @@ -9,6 +9,7 @@ */ #include +#include namespace hotplace { namespace io { @@ -147,6 +148,10 @@ return_t multiplexer_iocp::event_loop_run(multiplexer_context_t* handle, handle_ ret = controller.event_loop_new(pContext->handle_controller, &token_handle); + int socktype = 0; + typeof_socket((socket_t)listenfd, socktype); + bool is_dgram = (SOCK_DGRAM == socktype); + BOOL bRet = TRUE; while (true) { bool broken = controller.event_loop_test_broken(pContext->handle_controller, token_handle); @@ -186,7 +191,7 @@ return_t multiplexer_iocp::event_loop_run(multiplexer_context_t* handle, handle_ if (0 == size_transfered) { type = multiplexer_event_type_t::mux_disconnect; } else { - type = multiplexer_event_type_t::mux_read; + type = (is_dgram ? multiplexer_event_type_t::mux_dgram : multiplexer_event_type_t::mux_read); } event_callback_routine(type, 4, data_vector, nullptr, parameter); diff --git a/sdk/io/basic/windows/winsock.cpp b/sdk/io/system/windows/winsock.cpp similarity index 94% rename from sdk/io/basic/windows/winsock.cpp rename to sdk/io/system/windows/winsock.cpp index 39556c1d..222f754b 100644 --- a/sdk/io/basic/windows/winsock.cpp +++ b/sdk/io/system/windows/winsock.cpp @@ -8,7 +8,7 @@ * Date Name Description */ -#include +#include namespace hotplace { namespace io { diff --git a/sdk/net.hpp b/sdk/net.hpp index b0d8007d..e1dbd33f 100644 --- a/sdk/net.hpp +++ b/sdk/net.hpp @@ -18,9 +18,11 @@ #include /* basic */ -#include #include -#include +#include +#include +#include +#include /* http */ #include @@ -62,10 +64,12 @@ #include /* TLS */ +#include +#include #include #include -#include -#include +#include +#include #include #endif diff --git a/sdk/net/basic/client_socket.cpp b/sdk/net/basic/client_socket.cpp deleted file mode 100644 index ca8551ad..00000000 --- a/sdk/net/basic/client_socket.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ -/** - * @file {file} - * @author Soo Han, Kim (princeb612.kr@gmail.com) - * @desc - * - * Revision History - * Date Name Description - */ - -#include -#include - -namespace hotplace { -using namespace io; -namespace net { - -tcp_client_socket::tcp_client_socket() : _wto(1000) { - // do nothing -} - -tcp_client_socket::~tcp_client_socket() { - // do nothing -} - -return_t tcp_client_socket::connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout) { - return_t ret = errorcode_t::success; - - __try2 { ret = connect_socket(sock, SOCK_STREAM, address, port, timeout); } - __finally2 { - // do nothing - } - return ret; -} - -return_t tcp_client_socket::close(socket_t sock, tls_context_t* tls_handle) { - return_t ret = errorcode_t::success; - - __try2 { - if (INVALID_SOCKET == sock) { - ret = errorcode_t::invalid_parameter; - __leave2; - } -#if defined __linux__ - ::close(sock); -#elif defined _WIN32 || defined _WIN64 - closesocket(sock); -#endif - } - __finally2 { - // do nothing - } - return ret; -} - -return_t tcp_client_socket::read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read) { - return_t ret = errorcode_t::success; - - ret = wait_socket(sock, _wto, SOCK_WAIT_READABLE); - if (errorcode_t::success == ret) { -#if defined __linux__ - int ret_recv = recv(sock, ptr_data, size_data, 0); -#elif defined _WIN32 || defined _WIN64 - int ret_recv = recv(sock, ptr_data, (int)size_data, 0); -#endif - if (-1 == ret_recv) { - ret = get_lasterror(ret_recv); - } else if (0 == ret_recv) { - ret = errorcode_t::closed; - } - - if (nullptr != size_read) { - *size_read = ret_recv; - } - if (size_data == ret_recv) { - ret = errorcode_t::more_data; - } - } - return ret; -} - -return_t tcp_client_socket::more(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread) { - return_t ret = errorcode_t::success; - ret = read(sock, tls_handle, ptr_data, size_data, cbread); - return ret; -} - -return_t tcp_client_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent) { - return_t ret = errorcode_t::success; - - __try2 { -#if defined __linux__ - int ret_send = ::send(sock, ptr_data, size_data, 0); -#elif defined _WIN32 || defined _WIN64 - int ret_send = ::send(sock, ptr_data, (int)size_data, 0); -#endif - if (-1 == ret_send) { - ret = get_lasterror(ret_send); - } - if (nullptr != size_sent) { - *size_sent = ret_send; - } - } - __finally2 { - // do nothing - } - return ret; -} - -bool tcp_client_socket::support_tls() { return false; } - -tcp_client_socket& tcp_client_socket::set_wto(uint32 milliseconds) { - if (milliseconds) { - _wto = milliseconds; - } - return *this; -} - -uint32 tcp_client_socket::get_wto() { return _wto; } - -udp_client_socket::udp_client_socket() : _wto(1000) {} - -udp_client_socket::~udp_client_socket() {} - -return_t udp_client_socket::open(socket_t* sock, tls_context_t* tls_handle, const char* address, uint16 port) { - return_t ret = errorcode_t::success; - __try2 { ret = create_socket(sock, &_sock_storage, SOCK_DGRAM, address, port); } - __finally2 { - // do something - } - return ret; -} - -return_t udp_client_socket::close(socket_t sock, tls_context_t* tls_handle) { - return_t ret = errorcode_t::success; - __try2 { - if (INVALID_SOCKET == sock) { - ret = errorcode_t::invalid_parameter; - __leave2; - } - - close_socket(sock, true, 0); - } - __finally2 { - // do something - } - return ret; -} - -return_t udp_client_socket::read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read) { - return_t ret = errorcode_t::success; - __try2 { - ret = wait_socket(sock, _wto, SOCK_WAIT_READABLE); - if (errorcode_t::success == ret) { -#if 1 - int size_peek = recvfrom(sock, ptr_data, size_data, MSG_PEEK, nullptr, nullptr); - if (size_data < size_peek) { - ret = errorcode_t::insufficient_buffer; - __leave2; - } -#endif - -#if defined __linux__ - int ret_recv = recvfrom(sock, ptr_data, size_data, 0, nullptr, nullptr); -#elif defined _WIN32 || defined _WIN64 - int ret_recv = recvfrom(sock, ptr_data, (int)size_data, 0, nullptr, nullptr); -#endif - if (-1 == ret_recv) { - ret = get_lasterror(ret_recv); - } else if (0 == ret_recv) { - ret = errorcode_t::closed; - } - - if (nullptr != size_read) { - *size_read = ret_recv; - } - } - } - __finally2 { - // do something - } - return ret; -} - -return_t udp_client_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent) { - return_t ret = errorcode_t::success; - __try2 { -#if defined __linux__ - int ret_send = ::sendto(sock, ptr_data, size_data, 0, (const struct sockaddr*)&_sock_storage, sizeof(sockaddr_storage_t)); -#elif defined _WIN32 || defined _WIN64 - int ret_send = ::sendto(sock, ptr_data, (int)size_data, 0, (const struct sockaddr*)&_sock_storage, sizeof(sockaddr_storage_t)); -#endif - if (-1 == ret_send) { - ret = get_lasterror(ret_send); - } else if (0 == ret_send) { - // - } - } - __finally2 { - // do something - } - return ret; -} - -return_t udp_client_socket::sendto(socket_t sock, tls_context_t* tls_handle, sockaddr_storage_t* sock_storage, const char* ptr_data, size_t size_data, - size_t* size_sent) { - return_t ret = errorcode_t::success; - __try2 { -#if defined __linux__ - int ret_send = ::sendto(sock, ptr_data, size_data, 0, (const struct sockaddr*)&sock_storage, sizeof(sockaddr_storage_t)); -#elif defined _WIN32 || defined _WIN64 - int ret_send = ::sendto(sock, ptr_data, (int)size_data, 0, (const struct sockaddr*)&sock_storage, sizeof(sockaddr_storage_t)); -#endif - if (-1 == ret_send) { - ret = get_lasterror(ret_send); - } else if (0 == ret_send) { - // - } - } - __finally2 { - // do something - } - return ret; -} - -bool udp_client_socket::support_tls() { return false; } - -udp_client_socket& udp_client_socket::set_wto(uint32 milliseconds) { - if (milliseconds) { - _wto = milliseconds; - } - return *this; -} - -uint32 udp_client_socket::get_wto() { return _wto; } - -} // namespace net -} // namespace hotplace diff --git a/sdk/net/basic/client_socket.hpp b/sdk/net/basic/client_socket.hpp index 20ee5ebb..32516c69 100644 --- a/sdk/net/basic/client_socket.hpp +++ b/sdk/net/basic/client_socket.hpp @@ -11,19 +11,20 @@ #ifndef __HOTPLACE_SDK_NET_BASIC_CLIENTSOCKET__ #define __HOTPLACE_SDK_NET_BASIC_CLIENTSOCKET__ +#include #include namespace hotplace { +using namespace io; namespace net { /** * @brief client socket - * @sa class tls_client_socket : public tcp_client_socket */ -class tcp_client_socket { +class client_socket { public: - tcp_client_socket(); - virtual ~tcp_client_socket(); + client_socket() : _wto(1000) {} + virtual ~client_socket() {} /** * @brief connect @@ -34,14 +35,28 @@ class tcp_client_socket { * @param uint32 timeout [IN] * @return error code (see error.hpp) */ - virtual return_t connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout); + virtual return_t connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout) { return errorcode_t::success; } /** * @brief close * @param socket_t sock [IN] see connect * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket * @return error code (see error.hpp) */ - virtual return_t close(socket_t sock, tls_context_t* tls_handle); + virtual return_t close(socket_t sock, tls_context_t* tls_handle) { + return_t ret = errorcode_t::success; + + __try2 { + if (INVALID_SOCKET == sock) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + ret = close_socket(sock, true, 0); + } + __finally2 { + // do nothing + } + return ret; + } /** * @brief read @@ -52,62 +67,8 @@ class tcp_client_socket { * @param size_t* cbread [OUT] * @return error code (see error.hpp) */ - virtual return_t read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread); - virtual return_t more(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread); - /** - * @brief send - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket - * @param const char* ptr_data [IN] - * @param size_t size_data [IN] - * @param size_t* size_sent [OUT] - * @return error code (see error.hpp) - */ - virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent); - - bool support_tls(); - - tcp_client_socket& set_wto(uint32 milliseconds); - uint32 get_wto(); - - private: - uint32 _wto; // msec, default 1,000 msec (1 sec) -}; - -/** - * @brief client socket - */ -class udp_client_socket { - public: - udp_client_socket(); - virtual ~udp_client_socket(); + virtual return_t read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread) { return errorcode_t::success; } - /** - * @brief open - * @param socket_t* sock [out] - * @param tls_context_t* tls_handle [out] ignore, see tls_client_socket - * @param const char* address [in] - * @param uint16 port [in] - * @return error code (see error.hpp) - */ - virtual return_t open(socket_t* sock, tls_context_t* tls_handle, const char* address, uint16 port); - /** - * @brief close - * @param socket_t sock [IN] see connect - * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket - * @return error code (see error.hpp) - */ - virtual return_t close(socket_t sock, tls_context_t* tls_handle); - /** - * @brief read - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket - * @param char* ptr_data [OUT] - * @param size_t size_data [IN] - * @param size_t* size_read [OUT] - * @return error code (see error.hpp) - */ - virtual return_t read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read); /** * @brief send * @param socket_t sock [IN] @@ -117,18 +78,19 @@ class udp_client_socket { * @param size_t* size_sent [OUT] * @return error code (see error.hpp) */ - virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent); - virtual return_t sendto(socket_t sock, tls_context_t* tls_handle, sockaddr_storage_t* sock_storage, const char* ptr_data, size_t size_data, - size_t* size_sent); + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent) { return errorcode_t::success; } - bool support_tls(); + bool support_tls() { return false; } - udp_client_socket& set_wto(uint32 milliseconds); - uint32 get_wto(); + void set_wto(uint32 milliseconds) { + if (milliseconds) { + _wto = milliseconds; + } + } + uint32 get_wto() { return _wto; } - private: + protected: uint32 _wto; // msec, default 1,000 msec (1 sec) - sockaddr_storage_t _sock_storage; }; } // namespace net diff --git a/sdk/net/basic/server_socket.cpp b/sdk/net/basic/server_socket.cpp deleted file mode 100644 index 0b46a16b..00000000 --- a/sdk/net/basic/server_socket.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ -/** - * @file {file} - * @author Soo Han, Kim (princeb612.kr@gmail.com) - * @desc - * - * Revision History - * Date Name Description - */ - -#include -#include - -namespace hotplace { -using namespace io; -namespace net { - -tcp_server_socket::tcp_server_socket() { - // do nothing -} - -tcp_server_socket::~tcp_server_socket() { - // do nothing -} - -return_t tcp_server_socket::open(socket_t* sock, unsigned int family, uint16 port) { - return_t ret = errorcode_t::success; - - __try2 { - if (nullptr == sock) { - ret = errorcode_t::invalid_parameter; - __leave2; - } - - ret = create_listener(1, &family, sock, IPPROTO_TCP, port); - if (errorcode_t::success != ret) { - __leave2; - } - } - __finally2 { - // do nothing - } - return ret; -} - -return_t tcp_server_socket::close(socket_t sock, tls_context_t* tls_handle) { - return_t ret = errorcode_t::success; - - __try2 { - if (INVALID_SOCKET == sock) { - ret = errorcode_t::invalid_parameter; - __leave2; - } -#if defined __linux__ - ::close(sock); -#elif defined _WIN32 || defined _WIN64 - closesocket(sock); -#endif - } - __finally2 { - // do nothing - } - return ret; -} - -return_t tcp_server_socket::accept(socket_t sock, socket_t* clisock, struct sockaddr* addr, socklen_t* addrlen) { - return_t ret = errorcode_t::success; - - __try2 { - if ((nullptr == clisock) || (nullptr == addr) || (nullptr == addrlen)) { - ret = errorcode_t::invalid_parameter; - __leave2; - } - - socket_t cli_socket = INVALID_SOCKET; - - cli_socket = ::accept(sock, addr, addrlen); - if (INVALID_SOCKET == cli_socket) { - ret = get_lasterror(cli_socket); - __leave2; - } - - *clisock = cli_socket; - } - __finally2 { - // do nothing - } - return ret; -} - -return_t tcp_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_handle) { - return_t ret = errorcode_t::success; - - // do nothing - return ret; -} - -return_t tcp_server_socket::tls_stop_accept() { - return_t ret = errorcode_t::success; - - // do nothing - return ret; -} - -return_t tcp_server_socket::read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread) { - return_t ret = errorcode_t::success; - - __try2 { -#if defined _WIN32 || defined _WIN64 - int ret_routine = ::recv(sock, ptr_data, (int)size_data, 0); -#elif defined __linux__ - int ret_routine = ::recv(sock, ptr_data, size_data, 0); -#endif - if (-1 == ret_routine) { - ret = get_lasterror(ret_routine); - } else if (0 == ret_routine) { - ret = errorcode_t::closed; - } - if (nullptr != cbread) { - *cbread = ret_routine; - } - } - __finally2 { - // do nothing - } - return ret; -} - -return_t tcp_server_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent) { - return_t ret = errorcode_t::success; - - __try2 { -#if defined _WIN32 || defined _WIN64 - int ret_routine = ::send(sock, ptr_data, (int)size_data, 0); -#elif defined __linux__ - int ret_routine = ::send(sock, ptr_data, size_data, 0); -#endif - if (-1 == ret_routine) { - ret = get_lasterror(ret_routine); - } else if (0 == ret_routine) { - // closed - } - if (nullptr != cbsent) { - *cbsent = ret_routine; - } - } - __finally2 { - // do nothing - } - - return ret; -} - -bool tcp_server_socket::support_tls() { return false; } - -udp_server_socket::udp_server_socket() {} - -udp_server_socket::~udp_server_socket() {} - -return_t udp_server_socket::open(socket_t* sock, unsigned int family, uint16 port) { - return_t ret = errorcode_t::success; - - __try2 { - if (nullptr == sock) { - ret = errorcode_t::invalid_parameter; - __leave2; - } - - ret = create_listener(1, &family, sock, IPPROTO_UDP, port); - if (errorcode_t::success != ret) { - __leave2; - } - } - __finally2 { - // do nothing - } - return ret; -} - -return_t udp_server_socket::close(socket_t sock, tls_context_t* tls_handle) { - return_t ret = errorcode_t::success; - - __try2 { - if (INVALID_SOCKET == sock) { - ret = errorcode_t::invalid_parameter; - __leave2; - } -#if defined __linux__ - ::close(sock); -#elif defined _WIN32 || defined _WIN64 - closesocket(sock); -#endif - } - __finally2 { - // do nothing - } - return ret; -} - -return_t udp_server_socket::tls_listen(socket_t* sock, unsigned int family, uint16 port) { - return_t ret = errorcode_t::success; - // do nothing - return ret; -} - -return_t udp_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_handle) { - return_t ret = errorcode_t::success; - // do nothing - return ret; -} - -return_t udp_server_socket::tls_stop_accept() { - return_t ret = errorcode_t::success; - return ret; -} - -return_t udp_server_socket::read(socket_t sock, tls_context_t* tls_handle, int mode, struct sockaddr* addr, socklen_t* addrlen, char* ptr_data, - size_t size_data, size_t* size_read) { - return_t ret = errorcode_t::success; - __try2 { -#if 0 - int size_peek = recvfrom(sock, ptr_data, size_data, MSG_PEEK, nullptr, nullptr); - if (size_data < size_peek) { - ret = errorcode_t::insufficient_buffer; - __leave2; - } -#endif - -#if defined __linux__ - int ret_recv = recvfrom(sock, ptr_data, size_data, 0, addr, addrlen); -#elif defined _WIN32 || defined _WIN64 - int ret_recv = recvfrom(sock, ptr_data, (int)size_data, 0, addr, addrlen); -#endif - if (-1 == ret_recv) { - ret = get_lasterror(ret_recv); - } else if (0 == ret_recv) { - ret = errorcode_t::closed; - } - - if (nullptr != size_read) { - *size_read = ret_recv; - } - if (size_data == ret_recv) { - ret = errorcode_t::more_data; - } - } - __finally2 { - // do something - } - return ret; -} - -return_t udp_server_socket::send(socket_t sock, tls_context_t* tls_handle, const struct sockaddr* addr, socklen_t addrlen, const char* ptr_data, - size_t size_data, size_t* cbsent) { - return_t ret = errorcode_t::success; - __try2 { -#if defined __linux__ - int ret_send = ::sendto(sock, ptr_data, size_data, 0, addr, addrlen); -#elif defined _WIN32 || defined _WIN64 - int ret_send = ::sendto(sock, ptr_data, (int)size_data, 0, addr, addrlen); -#endif - if (-1 == ret_send) { - ret = get_lasterror(ret_send); - } else if (0 == ret_send) { - // - } - } - __finally2 { - // do something - } - return ret; -} - -bool udp_server_socket::support_tls() { return false; } - -} // namespace net -} // namespace hotplace diff --git a/sdk/net/basic/server_socket.hpp b/sdk/net/basic/server_socket.hpp index 7bfa2792..13beadb5 100644 --- a/sdk/net/basic/server_socket.hpp +++ b/sdk/net/basic/server_socket.hpp @@ -11,19 +11,17 @@ #ifndef __HOTPLACE_SDK_NET_BASIC_SERVERSOCKET__ #define __HOTPLACE_SDK_NET_BASIC_SERVERSOCKET__ +#include #include namespace hotplace { +using namespace io; namespace net { -/** - * @brief tcp_server_socket - * @sa class transport_layer_security_server : public tcp_server_socket - */ -class tcp_server_socket { +class server_socket { public: - tcp_server_socket(); - virtual ~tcp_server_socket(); + server_socket() { _shared.make_share(this); } + virtual ~server_socket() {} /** * @brief listen @@ -32,7 +30,7 @@ class tcp_server_socket { * @param uint16 port [IN] * @return error code (see error.hpp) */ - virtual return_t open(socket_t* sock, unsigned int family, uint16 port); + virtual return_t open(socket_t* sock, unsigned int family, uint16 port) { return errorcode_t::success; } /** * @brief close * @param socket_t sock [IN] @@ -45,8 +43,20 @@ class tcp_server_socket { * // socket closed * tls_svr_sock.close (cli_socket, tls_context); */ - virtual return_t close(socket_t sock, tls_context_t* tls_handle); - + virtual return_t close(socket_t sock, tls_context_t* tls_handle) { + return_t ret = errorcode_t::success; + __try2 { + if (INVALID_SOCKET == sock) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + close_socket(sock, true, 0); + } + __finally2 { + // do nothing + } + return ret; + } /** * @brief accept * @param socket_t sock [IN] listen socket @@ -55,98 +65,29 @@ class tcp_server_socket { * @param socklen_t* addrlen [IN] * @return error code (see error.hpp) */ - virtual return_t accept(socket_t sock, socket_t* clisock, struct sockaddr* addr, socklen_t* addrlen); - /** - * @brief Tls accept - * @param socket_t clisock [IN] client socket - * @param tls_context_t** tls_handle [OUT] Tls context - * @return error code (see error.hpp) - * @remarks - * do nothing, return errorcode_t::success - */ - virtual return_t tls_accept(socket_t clisock, tls_context_t** tls_handle); - virtual return_t tls_stop_accept(); - /** - * @brief read - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] nullptr - * @param int mode [IN] ignore, it defines operation mode. see also transport_layer_security_server. - * @param char* ptr_data [OUT] - * @param size_t size_data [IN] - * @param size_t* cbread [OUT] - * @return error code (see error.hpp) - * @remarks - * ERROR_CONNECTION_CLOSED - */ - virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread); - /** - * @brief send - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] - * @param const char* ptr_data [IN] - * @param size_t size_data [IN] - * @param size_t* cbsent [OUT] - * @return error code (see error.hpp) - */ - virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent); - - virtual bool support_tls(); - - protected: -}; - -class udp_server_socket { - public: - udp_server_socket(); - ~udp_server_socket(); - - /** - * @brief open - * @param socket_t* sock [OUT] listen socket - * @param unsigned int family [IN] AF_INET, AF_INET6 - * @param uint16 port [IN] - * @return error code (see error.hpp) - */ - virtual return_t open(socket_t* sock, unsigned int family, uint16 port); + virtual return_t accept(socket_t sock, socket_t* clisock, struct sockaddr* addr, socklen_t* addrlen) { return errorcode_t::success; } /** - * @brief close - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] - * @return error code (see error.hpp) - * @remarks - * tls_svr_sock.accept (listen_socket, &cli_socket, &tls_context, &sockaddr, &sockaddrlen); - * // client connection established... - * // ... - * // socket closed - * tls_svr_sock.close (cli_socket, tls_context); - */ - virtual return_t close(socket_t sock, tls_context_t* tls_handle); - - /** - * @brief listen - * @param socket_t* sock [OUT] listen socket - * @param unsigned int family [IN] AF_INET, AF_INET6 - * @param uint16 port [IN] - * @return error code (see error.hpp) + * @brief DTLSv1_listen */ - virtual return_t tls_listen(socket_t* sock, unsigned int family, uint16 port); + virtual return_t dtls_listen(socket_t sock, struct sockaddr* addr, socklen_t addrlen, tls_context_t** tls_handle) { return errorcode_t::success; } /** - * @brief Tls accept + * @brief tls accept * @param socket_t clisock [IN] client socket * @param tls_context_t** tls_handle [OUT] Tls context * @return error code (see error.hpp) * @remarks * do nothing, return errorcode_t::success */ - virtual return_t tls_accept(socket_t clisock, tls_context_t** tls_handle); - virtual return_t tls_stop_accept(); + virtual return_t tls_accept(socket_t clisock, tls_context_t** tls_handle) { return errorcode_t::not_supported; } + /** + * @brief tls_stop_accept + */ + virtual return_t tls_stop_accept() { return errorcode_t::success; } /** * @brief read * @param socket_t sock [IN] * @param tls_context_t* tls_handle [IN] nullptr * @param int mode [IN] ignore, it defines operation mode. see also transport_layer_security_server. - * @param struct sockaddr* addr [in] - * @param socklen_t* addrlen [in] * @param char* ptr_data [OUT] * @param size_t size_data [IN] * @param size_t* cbread [OUT] @@ -154,23 +95,25 @@ class udp_server_socket { * @remarks * ERROR_CONNECTION_CLOSED */ - virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, struct sockaddr* addr, socklen_t* addrlen, char* ptr_data, size_t size_data, - size_t* cbread); + virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread) { return errorcode_t::success; } /** * @brief send * @param socket_t sock [IN] * @param tls_context_t* tls_handle [IN] - * @param const struct sockaddr* addr [in] - * @param socklen_t* addrlen [in] * @param const char* ptr_data [IN] * @param size_t size_data [IN] * @param size_t* cbsent [OUT] * @return error code (see error.hpp) */ - virtual return_t send(socket_t sock, tls_context_t* tls_handle, const struct sockaddr* addr, socklen_t addrlen, const char* ptr_data, size_t size_data, - size_t* cbsent); + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent) { return errorcode_t::success; } - virtual bool support_tls(); + virtual bool support_tls() { return false; } + virtual int socket_type() { return 0; } /* override */ + int addref() { return _shared.addref(); } + int release() { return _shared.delref(); } + + protected: + t_shared_reference _shared; }; } // namespace net diff --git a/sdk/net/basic/tcp_client_socket.cpp b/sdk/net/basic/tcp_client_socket.cpp new file mode 100644 index 00000000..d36a6ba0 --- /dev/null +++ b/sdk/net/basic/tcp_client_socket.cpp @@ -0,0 +1,89 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#include +#include + +namespace hotplace { +using namespace io; +namespace net { + +tcp_client_socket::tcp_client_socket() : client_socket() { + // do nothing +} + +return_t tcp_client_socket::connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout) { + return_t ret = errorcode_t::success; + + __try2 { ret = connect_socket(sock, SOCK_STREAM, address, port, timeout); } + __finally2 { + // do nothing + } + return ret; +} + +return_t tcp_client_socket::read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read) { + return_t ret = errorcode_t::success; + + ret = wait_socket(sock, _wto, SOCK_WAIT_READABLE); + if (errorcode_t::success == ret) { +#if defined __linux__ + int ret_recv = recv(sock, ptr_data, size_data, 0); +#elif defined _WIN32 || defined _WIN64 + int ret_recv = recv(sock, ptr_data, (int)size_data, 0); +#endif + if (-1 == ret_recv) { + ret = get_lasterror(ret_recv); + } else if (0 == ret_recv) { + ret = errorcode_t::closed; + } + + if (nullptr != size_read) { + *size_read = ret_recv; + } + if (size_data == ret_recv) { + ret = errorcode_t::more_data; + } + } + return ret; +} + +return_t tcp_client_socket::more(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread) { + return_t ret = errorcode_t::success; + ret = read(sock, tls_handle, ptr_data, size_data, cbread); + return ret; +} + +return_t tcp_client_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent) { + return_t ret = errorcode_t::success; + + __try2 { +#if defined __linux__ + int ret_send = ::send(sock, ptr_data, size_data, 0); +#elif defined _WIN32 || defined _WIN64 + int ret_send = ::send(sock, ptr_data, (int)size_data, 0); +#endif + if (-1 == ret_send) { + ret = get_lasterror(ret_send); + } + if (nullptr != size_sent) { + *size_sent = ret_send; + } + } + __finally2 { + // do nothing + } + return ret; +} + +int tcp_client_socket::socket_type() { return SOCK_STREAM; } + +} // namespace net +} // namespace hotplace diff --git a/sdk/net/basic/tcp_client_socket.hpp b/sdk/net/basic/tcp_client_socket.hpp new file mode 100644 index 00000000..c1ab1fe2 --- /dev/null +++ b/sdk/net/basic/tcp_client_socket.hpp @@ -0,0 +1,68 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#ifndef __HOTPLACE_SDK_NET_BASIC_TCPCLIENTSOCKET__ +#define __HOTPLACE_SDK_NET_BASIC_TCPCLIENTSOCKET__ + +#include +#include +#include + +namespace hotplace { +namespace net { + +/** + * @brief client socket + * @sa class tls_client_socket : public tcp_client_socket + */ +class tcp_client_socket : public client_socket { + public: + tcp_client_socket(); + + /** + * @brief connect + * @param socket_t* sock [OUT] + * @param tls_context_t** tls_handle [OUT] ignore, see tls_client_socket + * @param const char* address [IN] + * @param uint16 port [IN] + * @param uint32 timeout [IN] + * @return error code (see error.hpp) + */ + virtual return_t connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout); + + /** + * @brief read + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket + * @param char* ptr_data [OUT] + * @param size_t size_data [IN] + * @param size_t* cbread [OUT] + * @return error code (see error.hpp) + */ + virtual return_t read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread); + virtual return_t more(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread); + /** + * @brief send + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket + * @param const char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* size_sent [OUT] + * @return error code (see error.hpp) + */ + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent); + + virtual int socket_type(); +}; + +} // namespace net +} // namespace hotplace + +#endif diff --git a/sdk/net/basic/tcp_server_socket.cpp b/sdk/net/basic/tcp_server_socket.cpp new file mode 100644 index 00000000..acd1a11a --- /dev/null +++ b/sdk/net/basic/tcp_server_socket.cpp @@ -0,0 +1,121 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#include +#include + +namespace hotplace { +using namespace io; +namespace net { + +tcp_server_socket::tcp_server_socket() : server_socket() { + // do nothing +} + +return_t tcp_server_socket::open(socket_t* sock, unsigned int family, uint16 port) { + return_t ret = errorcode_t::success; + + __try2 { + if (nullptr == sock) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + + ret = create_listener(1, &family, sock, IPPROTO_TCP, port); + if (errorcode_t::success != ret) { + __leave2; + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t tcp_server_socket::accept(socket_t sock, socket_t* clisock, struct sockaddr* addr, socklen_t* addrlen) { + return_t ret = errorcode_t::success; + + __try2 { + if ((nullptr == clisock) || (nullptr == addr) || (nullptr == addrlen)) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + + socket_t cli_socket = INVALID_SOCKET; + + cli_socket = ::accept(sock, addr, addrlen); + if (INVALID_SOCKET == cli_socket) { + ret = get_lasterror(cli_socket); + __leave2; + } + + *clisock = cli_socket; + } + __finally2 { + // do nothing + } + return ret; +} + +return_t tcp_server_socket::read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread) { + return_t ret = errorcode_t::success; + + __try2 { +#if defined _WIN32 || defined _WIN64 + int ret_routine = ::recv(sock, ptr_data, (int)size_data, 0); +#elif defined __linux__ + int ret_routine = ::recv(sock, ptr_data, size_data, 0); +#endif + if (-1 == ret_routine) { + ret = get_lasterror(ret_routine); + } else if (0 == ret_routine) { + ret = errorcode_t::closed; + } + if (nullptr != cbread) { + *cbread = ret_routine; + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t tcp_server_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent) { + return_t ret = errorcode_t::success; + + __try2 { +#if defined _WIN32 || defined _WIN64 + int ret_routine = ::send(sock, ptr_data, (int)size_data, 0); +#elif defined __linux__ + int ret_routine = ::send(sock, ptr_data, size_data, 0); +#endif + if (-1 == ret_routine) { + ret = get_lasterror(ret_routine); + } else if (0 == ret_routine) { + // closed + } + if (nullptr != cbsent) { + *cbsent = ret_routine; + } + } + __finally2 { + // do nothing + } + + return ret; +} + +bool tcp_server_socket::support_tls() { return false; } + +int tcp_server_socket::socket_type() { return SOCK_STREAM; } + +} // namespace net +} // namespace hotplace diff --git a/sdk/net/basic/tcp_server_socket.hpp b/sdk/net/basic/tcp_server_socket.hpp new file mode 100644 index 00000000..d180333b --- /dev/null +++ b/sdk/net/basic/tcp_server_socket.hpp @@ -0,0 +1,78 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#ifndef __HOTPLACE_SDK_NET_BASIC_TCPSERVERSOCKET__ +#define __HOTPLACE_SDK_NET_BASIC_TCPSERVERSOCKET__ + +#include +#include + +namespace hotplace { +namespace net { + +/** + * @brief tcp_server_socket + * @sa class tls_server_socket : public tcp_server_socket + */ +class tcp_server_socket : public server_socket { + public: + tcp_server_socket(); + + /** + * @brief listen + * @param socket_t* sock [OUT] listen socket + * @param unsigned int family [IN] AF_INET, AF_INET6 + * @param uint16 port [IN] + * @return error code (see error.hpp) + */ + virtual return_t open(socket_t* sock, unsigned int family, uint16 port); + /** + * @brief accept + * @param socket_t sock [IN] listen socket + * @param socket_t* clisock [OUT] client socket + * @param struct sockaddr* addr [OUT] + * @param socklen_t* addrlen [IN] + * @return error code (see error.hpp) + */ + virtual return_t accept(socket_t sock, socket_t* clisock, struct sockaddr* addr, socklen_t* addrlen); + /** + * @brief read + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] nullptr + * @param int mode [IN] ignore, it defines operation mode. see also transport_layer_security_server. + * @param char* ptr_data [OUT] + * @param size_t size_data [IN] + * @param size_t* cbread [OUT] + * @return error code (see error.hpp) + * @remarks + * ERROR_CONNECTION_CLOSED + */ + virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread); + /** + * @brief send + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @param const char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* cbsent [OUT] + * @return error code (see error.hpp) + */ + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent); + + virtual bool support_tls(); + virtual int socket_type(); + + protected: +}; + +} // namespace net +} // namespace hotplace + +#endif diff --git a/sdk/net/basic/udp_client_socket.cpp b/sdk/net/basic/udp_client_socket.cpp new file mode 100644 index 00000000..7fb59feb --- /dev/null +++ b/sdk/net/basic/udp_client_socket.cpp @@ -0,0 +1,108 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#include +#include + +namespace hotplace { +using namespace io; +namespace net { + +udp_client_socket::udp_client_socket() : client_socket() {} + +return_t udp_client_socket::open(socket_t* sock, tls_context_t* tls_handle, const char* address, uint16 port) { + return_t ret = errorcode_t::success; + __try2 { ret = create_socket(sock, &_sock_storage, SOCK_DGRAM, address, port); } + __finally2 { + // do something + } + return ret; +} + +return_t udp_client_socket::read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read) { + return_t ret = errorcode_t::success; + __try2 { + ret = wait_socket(sock, _wto, SOCK_WAIT_READABLE); + if (errorcode_t::success == ret) { +#if 0 + int size_peek = recvfrom(sock, ptr_data, size_data, MSG_PEEK, nullptr, nullptr); + if (size_data < size_peek) { + ret = errorcode_t::insufficient_buffer; + __leave2; + } +#endif + +#if defined __linux__ + int ret_recv = recvfrom(sock, ptr_data, size_data, 0, nullptr, nullptr); +#elif defined _WIN32 || defined _WIN64 + int ret_recv = recvfrom(sock, ptr_data, (int)size_data, 0, nullptr, nullptr); +#endif + if (-1 == ret_recv) { + ret = get_lasterror(ret_recv); + } else if (0 == ret_recv) { + ret = errorcode_t::closed; + } + + if (nullptr != size_read) { + *size_read = ret_recv; + } + } + } + __finally2 { + // do something + } + return ret; +} + +return_t udp_client_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent) { + return_t ret = errorcode_t::success; + __try2 { +#if defined __linux__ + int ret_send = ::sendto(sock, ptr_data, size_data, 0, (const struct sockaddr*)&_sock_storage, sizeof(sockaddr_storage_t)); +#elif defined _WIN32 || defined _WIN64 + int ret_send = ::sendto(sock, ptr_data, (int)size_data, 0, (const struct sockaddr*)&_sock_storage, sizeof(sockaddr_storage_t)); +#endif + if (-1 == ret_send) { + ret = get_lasterror(ret_send); + } else if (0 == ret_send) { + // + } + } + __finally2 { + // do something + } + return ret; +} + +return_t udp_client_socket::sendto(socket_t sock, tls_context_t* tls_handle, sockaddr_storage_t* sock_storage, const char* ptr_data, size_t size_data, + size_t* size_sent) { + return_t ret = errorcode_t::success; + __try2 { +#if defined __linux__ + int ret_send = ::sendto(sock, ptr_data, size_data, 0, (const struct sockaddr*)&sock_storage, sizeof(sockaddr_storage_t)); +#elif defined _WIN32 || defined _WIN64 + int ret_send = ::sendto(sock, ptr_data, (int)size_data, 0, (const struct sockaddr*)&sock_storage, sizeof(sockaddr_storage_t)); +#endif + if (-1 == ret_send) { + ret = get_lasterror(ret_send); + } else if (0 == ret_send) { + // + } + } + __finally2 { + // do something + } + return ret; +} + +int udp_client_socket::socket_type() { return SOCK_DGRAM; } + +} // namespace net +} // namespace hotplace diff --git a/sdk/net/basic/udp_client_socket.hpp b/sdk/net/basic/udp_client_socket.hpp new file mode 100644 index 00000000..597216cb --- /dev/null +++ b/sdk/net/basic/udp_client_socket.hpp @@ -0,0 +1,72 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#ifndef __HOTPLACE_SDK_NET_BASIC_UDPCLIENTSOCKET__ +#define __HOTPLACE_SDK_NET_BASIC_UDPCLIENTSOCKET__ + +#include +#include +#include + +namespace hotplace { +namespace net { + +/** + * @brief client socket + */ +class udp_client_socket : public client_socket { + public: + udp_client_socket(); + + /** + * @brief open + * @param socket_t* sock [out] + * @param tls_context_t* tls_handle [out] ignore, see tls_client_socket + * @param const char* address [in] + * @param uint16 port [in] + * @return error code (see error.hpp) + */ + virtual return_t open(socket_t* sock, tls_context_t* tls_handle, const char* address, uint16 port); + /** + * @brief read + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket + * @param char* ptr_data [OUT] + * @param size_t size_data [IN] + * @param size_t* size_read [OUT] + * @return error code (see error.hpp) + */ + virtual return_t read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read); + /** + * @brief send + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] ignore, see tls_client_socket + * @param const char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* size_sent [OUT] + * @return error code (see error.hpp) + */ + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent); + /** + * @brief sendto + */ + virtual return_t sendto(socket_t sock, tls_context_t* tls_handle, sockaddr_storage_t* sock_storage, const char* ptr_data, size_t size_data, + size_t* size_sent); + + virtual int socket_type(); + + private: + sockaddr_storage_t _sock_storage; +}; + +} // namespace net +} // namespace hotplace + +#endif diff --git a/sdk/net/basic/udp_server_socket.cpp b/sdk/net/basic/udp_server_socket.cpp new file mode 100644 index 00000000..52bebfeb --- /dev/null +++ b/sdk/net/basic/udp_server_socket.cpp @@ -0,0 +1,114 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#include +#include + +namespace hotplace { +using namespace io; +namespace net { + +udp_server_socket::udp_server_socket() : server_socket() {} + +udp_server_socket::~udp_server_socket() {} + +return_t udp_server_socket::open(socket_t* sock, unsigned int family, uint16 port) { + return_t ret = errorcode_t::success; + + __try2 { + if (nullptr == sock) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + + ret = create_listener(1, &family, sock, IPPROTO_UDP, port); + if (errorcode_t::success != ret) { + __leave2; + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t udp_server_socket::close(socket_t sock, tls_context_t* tls_handle) { + return_t ret = errorcode_t::success; + + __try2 { + // do not close socket + } + __finally2 { + // do nothing + } + return ret; +} + +return_t udp_server_socket::read(socket_t sock, tls_context_t* tls_handle, int mode, struct sockaddr* addr, socklen_t* addrlen, char* ptr_data, + size_t size_data, size_t* size_read) { + return_t ret = errorcode_t::success; + __try2 { +#if 0 + int size_peek = recvfrom(sock, ptr_data, size_data, MSG_PEEK, nullptr, nullptr); + if (size_data < size_peek) { + ret = errorcode_t::insufficient_buffer; + __leave2; + } +#endif + +#if defined __linux__ + int ret_recv = recvfrom(sock, ptr_data, size_data, 0, addr, addrlen); +#elif defined _WIN32 || defined _WIN64 + int ret_recv = recvfrom(sock, ptr_data, (int)size_data, 0, addr, addrlen); +#endif + if (-1 == ret_recv) { + ret = get_lasterror(ret_recv); + } else if (0 == ret_recv) { + ret = errorcode_t::closed; + } + + if (nullptr != size_read) { + *size_read = ret_recv; + } + if (size_data == ret_recv) { + ret = errorcode_t::more_data; + } + } + __finally2 { + // do something + } + return ret; +} + +return_t udp_server_socket::send(socket_t sock, tls_context_t* tls_handle, const struct sockaddr* addr, socklen_t addrlen, const char* ptr_data, + size_t size_data, size_t* cbsent) { + return_t ret = errorcode_t::success; + __try2 { +#if defined __linux__ + int ret_send = ::sendto(sock, ptr_data, size_data, 0, addr, addrlen); +#elif defined _WIN32 || defined _WIN64 + int ret_send = ::sendto(sock, ptr_data, (int)size_data, 0, addr, addrlen); +#endif + if (-1 == ret_send) { + ret = get_lasterror(ret_send); + } else if (0 == ret_send) { + // + } + } + __finally2 { + // do something + } + return ret; +} + +int udp_server_socket::socket_type() { return SOCK_DGRAM; } + +} // namespace net +} // namespace hotplace diff --git a/sdk/net/basic/udp_server_socket.hpp b/sdk/net/basic/udp_server_socket.hpp new file mode 100644 index 00000000..2632083f --- /dev/null +++ b/sdk/net/basic/udp_server_socket.hpp @@ -0,0 +1,86 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#ifndef __HOTPLACE_SDK_NET_BASIC_UDPSERVERSOCKET__ +#define __HOTPLACE_SDK_NET_BASIC_UDPSERVERSOCKET__ + +#include +#include + +namespace hotplace { +namespace net { + +/** + * @brief udp_server_socket + * @sa class dtls_server_socket : public udp_server_socket + */ +class udp_server_socket : public server_socket { + public: + udp_server_socket(); + ~udp_server_socket(); + + /** + * @brief open + * @param socket_t* sock [OUT] listen socket + * @param unsigned int family [IN] AF_INET, AF_INET6 + * @param uint16 port [IN] + * @return error code (see error.hpp) + */ + virtual return_t open(socket_t* sock, unsigned int family, uint16 port); + /** + * @brief close + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @return error code (see error.hpp) + * @remarks + * tls_svr_sock.accept(listen_socket, &cli_socket, &tls_context, &sockaddr, &sockaddrlen); + * // client connection established... + * // ... + * // socket closed + * tls_svr_sock.close(cli_socket, tls_context); + */ + virtual return_t close(socket_t sock, tls_context_t* tls_handle); + /** + * @brief read + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] nullptr + * @param int mode [IN] ignore, it defines operation mode. see also transport_layer_security_server. + * @param struct sockaddr* addr [in] + * @param socklen_t* addrlen [in] + * @param char* ptr_data [OUT] + * @param size_t size_data [IN] + * @param size_t* cbread [OUT] + * @return error code (see error.hpp) + * @remarks + * ERROR_CONNECTION_CLOSED + */ + virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, struct sockaddr* addr, socklen_t* addrlen, char* ptr_data, size_t size_data, + size_t* cbread); + /** + * @brief send + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @param const struct sockaddr* addr [in] + * @param socklen_t* addrlen [in] + * @param const char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* cbsent [OUT] + * @return error code (see error.hpp) + */ + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const struct sockaddr* addr, socklen_t addrlen, const char* ptr_data, size_t size_data, + size_t* cbsent); + + virtual int socket_type(); +}; + +} // namespace net +} // namespace hotplace + +#endif diff --git a/sdk/net/http/auth/basic_authentication_provider.cpp b/sdk/net/http/auth/basic_authentication_provider.cpp index 6bd2ff61..e66f9789 100644 --- a/sdk/net/http/auth/basic_authentication_provider.cpp +++ b/sdk/net/http/auth/basic_authentication_provider.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication + * RFC 7617 The 'Basic' HTTP Authentication Scheme * * Revision History * Date Name Description @@ -53,6 +55,7 @@ return_t basic_authentication_provider::request_auth(network_session* session, h __leave2; } + // RFC 2617 2 Basic Authentication Scheme response->get_http_header().add("WWW-Authenticate", format("Basic realm=\"%s\"", _realm.c_str())); int status_code = 401; diff --git a/sdk/net/http/auth/basic_credentials.cpp b/sdk/net/http/auth/basic_credentials.cpp index 3ad94b02..a2adc887 100644 --- a/sdk/net/http/auth/basic_credentials.cpp +++ b/sdk/net/http/auth/basic_credentials.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication + * RFC 7617 The 'Basic' HTTP Authentication Scheme * * Revision History * Date Name Description @@ -21,6 +23,7 @@ namespace net { basic_credentials::basic_credentials() {} basic_credentials& basic_credentials::add(const std::string& username, const std::string& password) { + // RFC 2617 2 Basic Authentication Scheme basic_stream bs; bs << username << ":" << password; diff --git a/sdk/net/http/auth/digest_access_authentication_provider.cpp b/sdk/net/http/auth/digest_access_authentication_provider.cpp index e941f7ee..505e9afa 100644 --- a/sdk/net/http/auth/digest_access_authentication_provider.cpp +++ b/sdk/net/http/auth/digest_access_authentication_provider.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication + * RFC 7616 HTTP Digest Access Authentication * * Revision History * Date Name Description @@ -80,12 +82,13 @@ return_t digest_access_authentication_provider::request_auth(network_session* se session->get_session_data()->set("nonce", nonce); // should be uniquely generated each time a 401 response is made session->get_session_data()->set("opaque", opaque); // should be returned by the client unchanged in the Authorization header of subsequent requests + valist va; basic_stream cred; - cred << "Digest realm=\"" << get_realm() << "\""; + va << get_realm() << get_qop() << nonce << opaque; + cred.vprintf(R"(Digest realm="%s", qop="%s", nonce="%s", opaque="%s")", va.get()); if (false == get_algorithm().empty()) { cred << ", algorithm=" << get_algorithm(); } - cred << ", qop=\"" << get_qop() << "\", nonce=\"" << nonce << "\", opaque=\"" << opaque << "\""; if (get_userhash()) { cred << ", userhash=true"; } diff --git a/sdk/net/http/auth/digest_credentials.cpp b/sdk/net/http/auth/digest_credentials.cpp index 026a05f8..0c4d3c4f 100644 --- a/sdk/net/http/auth/digest_credentials.cpp +++ b/sdk/net/http/auth/digest_credentials.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication + * RFC 7616 HTTP Digest Access Authentication * * Revision History * Date Name Description diff --git a/sdk/net/http/auth/oauth2.cpp b/sdk/net/http/auth/oauth2.cpp index f188b878..67563c1b 100644 --- a/sdk/net/http/auth/oauth2.cpp +++ b/sdk/net/http/auth/oauth2.cpp @@ -3,7 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc - * RFC 6749 OAuth 2.0 + * RFC 6749 The OAuth 2.0 Authorization Framework * * Revision History * Date Name Description @@ -40,6 +40,10 @@ oauth2_authorization_code_grant_provider::~oauth2_authorization_code_grant_provi void oauth2_authorization_code_grant_provider::authorization_handler(network_session* session, http_request* request, http_response* response, http_router* router) { + // 4.1. Authorization Code Grant + // 4.1.1. Authorization Request + // 4.1.2. Authorization Response + skey_value& kv = request->get_http_uri().get_query_keyvalue(); std::string client_id = kv.get("client_id"); @@ -70,6 +74,10 @@ void oauth2_authorization_code_grant_provider::authorization_handler(network_ses } void oauth2_authorization_code_grant_provider::token_handler(network_session* session, http_request* request, http_response* response, http_router* router) { + // 4.1. Authorization Code Grant + // 4.1.3. Access Token Request + // 4.1.4. Access Token Response + skey_value& kv = request->get_http_uri().get_query_keyvalue(); basic_stream body; json_t* root = nullptr; @@ -88,6 +96,7 @@ void oauth2_authorization_code_grant_provider::token_handler(network_session* se std::string code = kv.get("code"); return_t test = router->get_authenticate_resolver().get_oauth2_credentials().verify_grant_code(code); if (errorcode_t::success == test) { + // 5.1. Successful Response router->get_authenticate_resolver().get_oauth2_credentials().grant(access_token, refresh_token, kv.get("client_id"), expire); response->get_http_header().clear().add("Cache-Control", "no-store").add("Pragma", "no-cache"); @@ -97,6 +106,7 @@ void oauth2_authorization_code_grant_provider::token_handler(network_session* se json_object_set_new(root, "refresh_token", json_string(refresh_token.c_str())); json_object_set_new(root, "example_parameter", json_string("example_value")); } else { + // 5.2. Error Response json_object_set_new(root, "error", json_string("invalid_request")); } } @@ -109,7 +119,7 @@ void oauth2_authorization_code_grant_provider::token_handler(network_session* se } json_decref(root); } else { - body << "{\"error\":\"server_error\"}"; + body << R"({"error":"server_error"})"; } } @@ -127,6 +137,10 @@ oauth2_implicit_grant_provider::oauth2_implicit_grant_provider() : oauth2_grant_ oauth2_implicit_grant_provider::~oauth2_implicit_grant_provider() {} void oauth2_implicit_grant_provider::authorization_handler(network_session* session, http_request* request, http_response* response, http_router* router) { + // 4.2. Implicit Grant + // 4.2.1. Authorization Request + // 4.2.2. Access Token Response + skey_value& kv = request->get_http_uri().get_query_keyvalue(); std::string client_id = kv.get("client_id"); @@ -166,6 +180,11 @@ oauth2_resource_owner_password_credentials_grant_provider::~oauth2_resource_owne void oauth2_resource_owner_password_credentials_grant_provider::token_handler(network_session* session, http_request* request, http_response* response, http_router* router) { + // 4.3. Resource Owner Password Credentials Grant + // 4.3.1. Authorization Request and Response + // 4.3.2. Access Token Request + // 4.3.3. Access Token Response + skey_value& kv = request->get_http_uri().get_query_keyvalue(); basic_stream body; json_t* root = nullptr; @@ -186,6 +205,7 @@ void oauth2_resource_owner_password_credentials_grant_provider::token_handler(ne bool test = router->get_authenticate_resolver().get_custom_credentials().verify(nullptr, username, password); if (test) { + // 5.1. Successful Response router->get_authenticate_resolver().get_oauth2_credentials().grant(access_token, refresh_token, kv.get("client_id"), expire); response->get_http_header().clear().add("Cache-Control", "no-store").add("Pragma", "no-cache"); @@ -195,6 +215,7 @@ void oauth2_resource_owner_password_credentials_grant_provider::token_handler(ne json_object_set_new(root, "refresh_token", json_string(refresh_token.c_str())); json_object_set_new(root, "example_parameter", json_string("example_value")); } else { + // 5.2. Error Response json_object_set_new(root, "error", json_string("access_denied")); } } @@ -207,7 +228,7 @@ void oauth2_resource_owner_password_credentials_grant_provider::token_handler(ne } json_decref(root); } else { - body << "{\"error\":\"server_error\"}"; + body << R"({"error":"server_error"})"; } } @@ -223,6 +244,11 @@ oauth2_client_credentials_grant_provider::oauth2_client_credentials_grant_provid oauth2_client_credentials_grant_provider::~oauth2_client_credentials_grant_provider() {} void oauth2_client_credentials_grant_provider::token_handler(network_session* session, http_request* request, http_response* response, http_router* router) { + // 4.4. Client Credentials Grant + // 4.4.1. Authorization Request and Response + // 4.4.2. Access Token Request + // 4.4.3. Access Token Response + skey_value& kv = request->get_http_uri().get_query_keyvalue(); basic_stream body; json_t* root = nullptr; @@ -256,7 +282,7 @@ void oauth2_client_credentials_grant_provider::token_handler(network_session* se } json_decref(root); } else { - body << "{\"error\":\"server_error\"}"; + body << R"({"error":"server_error"})"; } } @@ -308,7 +334,7 @@ void oauth2_unsupported_provider::token_handler(network_session* session, http_r } json_decref(root); } else { - body << "{\"error\":\"server_error\"}"; + body << R"({"error":"server_error"})"; } } diff --git a/sdk/net/http/auth/oauth2_credentials.cpp b/sdk/net/http/auth/oauth2_credentials.cpp index c08d151d..e74b6325 100644 --- a/sdk/net/http/auth/oauth2_credentials.cpp +++ b/sdk/net/http/auth/oauth2_credentials.cpp @@ -3,7 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc - * RFC 6749 OAuth 2.0 + * RFC 6749 The OAuth 2.0 Authorization Framework * * Revision History * Date Name Description @@ -337,6 +337,7 @@ return_t oauth2_credentials::isvalid(const std::string& access_token) { } return_t oauth2_credentials::refresh(std::string& next_access_token, std::string& next_refresh_token, const std::string& refresh_token, uint16 expire) { + // 6. Refreshing an Access Token return_t ret = errorcode_t::success; __try2 { critical_section_guard guard(_lock); diff --git a/sdk/net/http/auth/rfc2617_digest.cpp b/sdk/net/http/auth/rfc2617_digest.cpp index 63e61cb4..661f5f16 100644 --- a/sdk/net/http/auth/rfc2617_digest.cpp +++ b/sdk/net/http/auth/rfc2617_digest.cpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication * * Revision History * Date Name Description @@ -59,7 +60,7 @@ rfc2617_digest& rfc2617_digest::digest(const std::string& algorithm) { openssl_digest dgst; std::string digest_value; - // RFC 7616 + // RFC 7616 6.1. Hash Algorithms for HTTP Digest Authentication // MD5, SHA-512-256, SHA-256 // MD5-sess, SHA-512-256-sess, SHA-256-sess std::map algmap; diff --git a/sdk/net/http/http2/http2_session.cpp b/sdk/net/http/http2/http2_session.cpp index d7136675..dd727ef3 100644 --- a/sdk/net/http/http2/http2_session.cpp +++ b/sdk/net/http/http2/http2_session.cpp @@ -44,17 +44,17 @@ http2_session& http2_session::consume(uint32 type, uint32 data_count, void* data switch (type) { case mux_connect: - bs.printf("[h2] connect %i\n", session_socket->cli_socket); + bs.printf("[h2] connect %i\n", session_socket->event_socket); break; case mux_read: { - bs.printf("[h2] read %i\n", session_socket->cli_socket); + bs.printf("[h2] read %i\n", session_socket->event_socket); byte_t* buf = (byte_t*)data_array[1]; size_t bufsize = (size_t)data_array[2]; dump_memory((byte_t*)buf, bufsize, &bs, 16, 2, 0, dump_memory_flag_t::dump_notrunc); bs.printf("\n"); } break; case mux_disconnect: - bs.printf("[h2] disconnect %i\n", session_socket->cli_socket); + bs.printf("[h2] disconnect %i\n", session_socket->event_socket); break; default: break; diff --git a/sdk/net/http/http_client.hpp b/sdk/net/http/http_client.hpp index 83f7c630..8d8b6040 100644 --- a/sdk/net/http/http_client.hpp +++ b/sdk/net/http/http_client.hpp @@ -25,11 +25,13 @@ #include #include #include -#include +#include +#include #include #include #include -#include +#include +#include namespace hotplace { using namespace io; diff --git a/sdk/net/http/http_header.cpp b/sdk/net/http/http_header.cpp index b26abf79..6fa402d5 100644 --- a/sdk/net/http/http_header.cpp +++ b/sdk/net/http/http_header.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 * * Revision History * Date Name Description diff --git a/sdk/net/http/http_protocol.cpp b/sdk/net/http/http_protocol.cpp index 9bd192d5..abbf92b3 100644 --- a/sdk/net/http/http_protocol.cpp +++ b/sdk/net/http/http_protocol.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 * * Revision History * Date Name Description diff --git a/sdk/net/http/http_request.cpp b/sdk/net/http/http_request.cpp index 95c06bd9..2a4e0e31 100644 --- a/sdk/net/http/http_request.cpp +++ b/sdk/net/http/http_request.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 * * Revision History * Date Name Description @@ -112,6 +114,8 @@ return_t http_request::open(const char* request, size_t size_request, uint32 fla _uri.open(get_http_header().get(":path")); } + // RFC 2616 3.7 Media Types + // RFC 2616 14.17 Content-Type constexpr char constexpr_content_type[] = "Content-Type"; constexpr char constexpr_url_encoded[] = "application/x-www-form-urlencoded"; if (_content.empty()) { @@ -173,6 +177,13 @@ http_header& http_request::get_http_header() { return _header; } http_uri& http_request::get_http_uri() { return _uri; } std::string http_request::get_method() { + // RFC 2616 + // 9.3 GET + // 9.4 HEAD + // 9.5 POST + // 9.6 PUT + // 9.7 DELETE + // 9.8 TRACE std::string m; if (1 == _version) { m = _method; @@ -188,6 +199,7 @@ http_request& http_request::compose(http_method_t method, const std::string& uri basic_stream stream; stream << resource->get_method(method) << " " << uri << " " << get_version() << "\r\n"; + // RFC 2616 14.13 Content-Length if (body.size()) { stream << "Content-Length: " << body.size() << "\r\n"; } @@ -204,6 +216,7 @@ std::string http_request::get_content() { return _content; } http_request& http_request::get_request(basic_stream& bs) { if (1 == _version) { + // RFC 2616 14.13 Content-Length std::string headers; bs.clear(); get_http_header().add("Content-Length", format("%zi", _content.size())).add("Connection", "Keep-Alive").get_headers(headers); @@ -214,7 +227,7 @@ http_request& http_request::get_request(basic_stream& bs) { } std::string http_request::get_version_str() { - constexpr char ver1[] = "HTTP/1.1"; + constexpr char ver1[] = "HTTP/1.1"; // RFC 2616 3.1 HTTP Version constexpr char ver2[] = "HTTP/2"; return (1 == _version) ? ver1 : ver2; diff --git a/sdk/net/http/http_resource.cpp b/sdk/net/http/http_resource.cpp index 08f57dca..de5037a1 100644 --- a/sdk/net/http/http_resource.cpp +++ b/sdk/net/http/http_resource.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 * * Revision History * Date Name Description @@ -27,8 +29,10 @@ void http_resource::load_resources() { // RFC 2616 HTTP/1.1 // 6.1.1 Status Code and Reason Phrase if (_status_codes.empty()) { + // 10.1 Informational 1xx _status_codes.insert(std::make_pair(100, "Continue")); _status_codes.insert(std::make_pair(101, "Switching Protocols")); + // 10.2 Successful 2xx _status_codes.insert(std::make_pair(200, "OK")); _status_codes.insert(std::make_pair(201, "Created")); _status_codes.insert(std::make_pair(202, "Accepted")); @@ -36,6 +40,7 @@ void http_resource::load_resources() { _status_codes.insert(std::make_pair(204, "No Content")); _status_codes.insert(std::make_pair(205, "Reset Content")); _status_codes.insert(std::make_pair(206, "Partial Content")); + // 10.3 Redirection 3xx _status_codes.insert(std::make_pair(300, "Multiple Choices")); _status_codes.insert(std::make_pair(301, "Moved Permanently")); _status_codes.insert(std::make_pair(302, "Found")); @@ -43,6 +48,7 @@ void http_resource::load_resources() { _status_codes.insert(std::make_pair(304, "Not Modified")); _status_codes.insert(std::make_pair(305, "Use Proxy")); _status_codes.insert(std::make_pair(307, "Temporary Redirect")); + // 10.4 Client Error 4xx _status_codes.insert(std::make_pair(400, "Bad Request")); _status_codes.insert(std::make_pair(401, "Unauthorized")); _status_codes.insert(std::make_pair(402, "Payment Required")); @@ -62,6 +68,7 @@ void http_resource::load_resources() { _status_codes.insert(std::make_pair(416, "Requested Range Not Satisfiable")); _status_codes.insert(std::make_pair(417, "Expectation Failed")); _status_codes.insert(std::make_pair(426, "Upgrade Required")); + // 10.5 Server Error 5xx _status_codes.insert(std::make_pair(500, "Internal Server Error")); _status_codes.insert(std::make_pair(501, "Not Implemented")); _status_codes.insert(std::make_pair(502, "Bad Gateway")); diff --git a/sdk/net/http/http_response.cpp b/sdk/net/http/http_response.cpp index e1233692..463a19f2 100644 --- a/sdk/net/http/http_response.cpp +++ b/sdk/net/http/http_response.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 * * Revision History * Date Name Description @@ -115,6 +117,8 @@ return_t http_response::open(const char* response, size_t size_response) { byte_t* content = (byte_t*)response + epos; size_t content_size = size_response - epos; + // RFC 2616 3.5 Content Codings + // RFC 2616 14.11 Content-Encoding std::string encoding = get_http_header().get("Content-Encoding"); if ("deflate" == encoding) { basic_stream inflated; @@ -129,6 +133,8 @@ return_t http_response::open(const char* response, size_t size_response) { } } + // RFC 2616 3.7 Media Types + // RFC 2616 14.17 Content-Type _header.get("Content-Type", _content_type); } __finally2 { @@ -244,6 +250,8 @@ http_response& http_response::get_response(basic_stream& bs) { std::string accept_encoding; basic_stream method; if (_request) { + // RFC 2616 3.5 Content Codings + // RFC 2616 14.3 Accept-Encoding _request->get_http_header().get("Accept-Encoding", accept_encoding); method = _request->get_method(); } @@ -252,14 +260,19 @@ http_response& http_response::get_response(basic_stream& bs) { std::string headers; if (_content_type.size() && content_size()) { + // RFC 2616 3.7 Media Types + // RFC 2616 14.17 Content-Type get_http_header().add("Content-Type", content_type()); } get_http_header().add("Connection", "Keep-Alive"); + // RFC 2616 5.1.1 Method if (0 == strcmp("HEAD", method.c_str())) { get_http_header().add("Content-Length", "0").get_headers(headers); bs << get_version_str() << " " << status_code() << " " << resource->load(status_code()) << "\r\n" << headers << "\r\n"; } else { + // RFC 2616 3.5 Content Codings + // RFC 2616 14.11 Content-Encoding if (std::string::npos != accept_encoding.find("deflate")) { basic_stream encoded; zlib_deflate(zlib_windowbits_t::windowbits_deflate, (byte_t*)content(), content_size(), &encoded); @@ -301,11 +314,13 @@ http_response& http_response::response_h2(network_session* session) { binary_t encoded; bool header_only = false; + // RFC 2616 5.1.1 Method if (0 == strcmp("HEAD", method.c_str())) { header_only = true; } else if (content_size()) { header_only = false; + // RFC 2616 3.5 Content Codings if (std::string::npos != accept_encoding.find("deflate")) { encoding = "deflate"; } else if (std::string::npos != accept_encoding.find("gzip")) { @@ -343,6 +358,7 @@ http_response& http_response::response_h2(network_session* session) { if (encoding.empty()) { data.get_data().insert(data.get_data().end(), content(), content() + content_size()); } else { + // RFC 2616 3.5 Content Codings if ("deflate" == encoding) { zlib_deflate(zlib_windowbits_t::windowbits_deflate, (byte_t*)content(), content_size(), data.get_data()); } else if ("gzip" == encoding) { @@ -396,7 +412,7 @@ http_response& http_response::response_h2(network_session* session) { } std::string http_response::get_version_str() { - constexpr char ver1[] = "HTTP/1.1"; + constexpr char ver1[] = "HTTP/1.1"; // RFC 2616 3.1 HTTP Version constexpr char ver2[] = "HTTP/2"; return (1 == _version) ? ver1 : ver2; diff --git a/sdk/net/http/http_server.hpp b/sdk/net/http/http_server.hpp index 00e4e091..afff3272 100644 --- a/sdk/net/http/http_server.hpp +++ b/sdk/net/http/http_server.hpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include // ws2tcpip.h first namespace hotplace { diff --git a/sdk/net/http/http_uri.cpp b/sdk/net/http/http_uri.cpp index 6e0a148d..6f426f01 100644 --- a/sdk/net/http/http_uri.cpp +++ b/sdk/net/http/http_uri.cpp @@ -3,6 +3,8 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1 + * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 * * Revision History * Date Name Description diff --git a/sdk/net/server/network_server.cpp b/sdk/net/server/network_server.cpp index fe3ec592..c86d278f 100644 --- a/sdk/net/server/network_server.cpp +++ b/sdk/net/server/network_server.cpp @@ -3,6 +3,28 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * UDP not supported + * + * bind socket and multiplexr.handle + * TCP/TLS DTLS + * epoll O O + * IOCP - O + * bind client socket and multiplexr.handle + * TCP/TLS DTLS + * epoll O - + * IOCP O - + * accept + * TCP/TLS DTLS + * epoll - - + * IOCP O - + * + * mux type accept_queue.push + * 1) epoll tcp/tls network_routine.mux_connect->accept_routine + * 2) epoll dtls ... + * 3) epoll udp N/A + * 4) iocp tcp/tls accept_routine + * 5) iocp dtls ... + * 6) iocp udp N/A * * Revision History * Date Name Description @@ -40,11 +62,10 @@ typedef struct _network_multiplexer_context_t { void* callback_param; socket_t listen_sock; - tcp_server_socket* stream_socket; - udp_server_socket* dgram_socket; + server_socket* svr_socket; semaphore tls_accept_mutex; - semaphore cleanup_mutex; + // semaphore cleanup_mutex; semaphore consumer_mutex; signalwait_threads network_threads; #if defined _WIN32 || defined _WIN64 @@ -63,6 +84,8 @@ typedef struct _network_multiplexer_context_t { ACCEPT_CONTROL_CALLBACK_ROUTINE accept_control_handler; + net_dgram_t dgram; + std::function df; _network_multiplexer_context_t() @@ -72,8 +95,7 @@ typedef struct _network_multiplexer_context_t { callback_routine(nullptr), callback_param(nullptr), listen_sock(INVALID_SOCKET), - stream_socket(nullptr), - dgram_socket(nullptr), + svr_socket(nullptr), accept_control_handler(nullptr) {} } network_multiplexer_context_t; @@ -81,7 +103,7 @@ network_server::network_server() {} network_server::~network_server() {} -return_t network_server::open(network_multiplexer_context_t** handle, unsigned int family, uint16 port, tcp_server_socket* stream_socket, server_conf* conf, +return_t network_server::open(network_multiplexer_context_t** handle, unsigned int family, uint16 port, server_socket* svr_socket, server_conf* conf, TYPE_CALLBACK_HANDLEREXV callback_routine, void* callback_param) { return_t ret = errorcode_t::success; @@ -89,21 +111,15 @@ return_t network_server::open(network_multiplexer_context_t** handle, unsigned i socket_t sock = INVALID_SOCKET; multiplexer_context_t* mplexer_handle = nullptr; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { - if (nullptr == handle || nullptr == callback_routine || nullptr == stream_socket) { + if (nullptr == handle || nullptr == callback_routine || nullptr == svr_socket) { ret = errorcode_t::invalid_parameter; __leave2; } - ret = stream_socket->open(&sock, family, port); + // TCP/TLS socket.stream-bind-listen + // DTLS socket.dgram-bind + ret = svr_socket->open(&sock, family, port); if (errorcode_t::success != ret) { __leave2; } @@ -120,21 +136,18 @@ return_t network_server::open(network_multiplexer_context_t** handle, unsigned i __try_new_catch(context, new network_multiplexer_context_t, ret, __leave2); + int socktype = 0; + typeof_socket(sock, socktype); + if (SOCK_STREAM == socktype) { #if defined __linux__ - - // (epoll) bind server socket - mplexer.bind(mplexer_handle, sock, nullptr); - // (epoll) and then (see multiplexer_epoll::event_loop_run) - // if (fd == listen_socket) { - // event_callback_routine(multiplexer_event_type_t::mux_connect(...); - // } - + // (epoll) bind tcp.socket + mplexer.bind(mplexer_handle, sock, nullptr); #endif - #if defined _WIN32 || defined _WIN64 - // use dummy signal handler ... just call CloseListener first, and signal_and_wait_all - context->accept_threads.set(1, accept_thread, signalwait_threads::dummy_signal, context); + // use dummy signal handler ... just call CloseListener first, and signal_and_wait_all + context->accept_threads.set(1, accept_thread, signalwait_threads::dummy_signal, context); #endif + } context->tls_accept_threads.set(concurrent_tls_accept, tls_accept_thread, tls_accept_signal, context); context->network_threads.set(concurrent_network, network_thread, network_signal, context); @@ -146,111 +159,24 @@ return_t network_server::open(network_multiplexer_context_t** handle, unsigned i context->callback_param = callback_param; context->listen_sock = sock; - context->stream_socket = stream_socket; + context->svr_socket = svr_socket; context->accept_control_handler = nullptr; context->signature = NETWORK_MULTIPLEXER_CONTEXT_SIGNATURE; + if (SOCK_STREAM == socktype) { #if defined _WIN32 || defined _WIN64 - context->accept_threads.create(); - // (iocp) and then bind client socket after accept + context->accept_threads.create(); + // (iocp) and then bind client socket after accept #endif - if (stream_socket->support_tls()) { - context->tls_accept_threads.create(); - } - - *handle = context; - } - __finally2 { - if (errorcode_t::success != ret) { - if (nullptr != mplexer_handle) { - mplexer.close(mplexer_handle); - } - if (INVALID_SOCKET != sock) { - if (stream_socket) { - stream_socket->close(sock, nullptr); - } - } - if (nullptr != context) { - delete context; + if (svr_socket->support_tls()) { + // (tls) tls_accept + context->tls_accept_threads.create(); } } - } - - return ret; -} - -return_t network_server::open(network_multiplexer_context_t** handle, unsigned int family, uint16 port, udp_server_socket* dgram_socket, server_conf* conf, - TYPE_CALLBACK_HANDLEREXV callback_routine, void* callback_param) { - return_t ret = errorcode_t::success; - - network_multiplexer_context_t* context = nullptr; - socket_t sock = INVALID_SOCKET; - multiplexer_context_t* mplexer_handle = nullptr; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - - __try2 { - if (nullptr == handle || nullptr == callback_routine || nullptr == dgram_socket) { - ret = errorcode_t::invalid_parameter; - __leave2; - } - - ret = dgram_socket->open(&sock, family, port); - if (errorcode_t::success != ret) { - __leave2; - } - - uint16 concurrent = conf ? conf->get(netserver_config_t::serverconf_concurrent_event) : 1024; - uint16 concurrent_tls_accept = conf ? conf->get(netserver_config_t::serverconf_concurrent_tls_accept) : 1; - uint16 concurrent_network = conf ? conf->get(netserver_config_t::serverconf_concurrent_network) : 1; - uint16 concurrent_consume = conf ? conf->get(netserver_config_t::serverconf_concurrent_consume) : 2; - - ret = mplexer.open(&mplexer_handle, concurrent); - if (errorcode_t::success != ret) { - __leave2; - } - - __try_new_catch(context, new network_multiplexer_context_t, ret, __leave2); - - /* [linux, windows] bind datagram server socket */ - mplexer.bind(mplexer_handle, (handle_t)sock, nullptr); - -#if defined _WIN32 || defined _WIN64 - // use dummy signal handler ... just call CloseListener first, and signal_and_wait_all - // context->accept_threads.set(1, accept_thread, signalwait_threads::dummy_signal, context); -#endif - - context->tls_accept_threads.set(concurrent_tls_accept, tls_accept_thread, tls_accept_signal, context); - context->network_threads.set(concurrent_network, network_thread, network_signal, context); - context->consumer_threads.set(concurrent_consume, consumer_thread, consumer_signal, context); - - context->mplexer_handle = mplexer_handle; - context->concurrent = concurrent; - context->callback_routine = callback_routine; - context->callback_param = callback_param; - - context->listen_sock = sock; - context->dgram_socket = dgram_socket; - - context->accept_control_handler = nullptr; - - context->signature = NETWORK_MULTIPLEXER_CONTEXT_SIGNATURE; - -#if defined _WIN32 || defined _WIN64 - context->accept_threads.create(); - // (iocp) and then bind client socket after accept -#endif - if (dgram_socket->support_tls()) { - context->tls_accept_threads.create(); - } + svr_socket->addref(); *handle = context; } @@ -260,8 +186,8 @@ return_t network_server::open(network_multiplexer_context_t** handle, unsigned i mplexer.close(mplexer_handle); } if (INVALID_SOCKET != sock) { - if (dgram_socket) { - dgram_socket->close(sock, nullptr); + if (svr_socket) { + svr_socket->close(sock, nullptr); } } if (nullptr != context) { @@ -374,8 +300,8 @@ return_t network_server::tls_accept_loop_run(network_multiplexer_context_t* hand __leave2; } - tcp_server_socket* stream_socket = handle->stream_socket; - if (stream_socket->support_tls()) { + server_socket* svr_socket = handle->svr_socket; + if (svr_socket->support_tls()) { for (uint32 i = 0; i < concurrent_loop; i++) { handle->tls_accept_threads.create(); } @@ -429,6 +355,12 @@ return_t network_server::event_loop_run(network_multiplexer_context_t* handle, u for (uint32 i = 0; i < concurrent_loop; i++) { handle->network_threads.create(); } + + if (SOCK_DGRAM == handle->svr_socket->socket_type()) { + // (epoll, iocp) bind udp.socket - mplexer.bind(mplexer_handle, (handle_t)sock, session_object); + // (windows) async read + dgram_start(handle); + } } __finally2 { // do nothing @@ -440,14 +372,6 @@ return_t network_server::event_loop_run(network_multiplexer_context_t* handle, u return_t network_server::event_loop_break(network_multiplexer_context_t* handle, uint32 concurrent_loop) { return_t ret = errorcode_t::success; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { if (nullptr == handle) { ret = errorcode_t::invalid_parameter; @@ -524,14 +448,6 @@ return_t network_server::consumer_loop_break(network_multiplexer_context_t* hand return_t network_server::close(network_multiplexer_context_t* handle) { return_t ret = errorcode_t::success; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { if (nullptr == handle) { ret = errorcode_t::invalid_parameter; @@ -542,8 +458,8 @@ return_t network_server::close(network_multiplexer_context_t* handle) { __leave2; } - tcp_server_socket* stream_socket = handle->stream_socket; - stream_socket->close(handle->listen_sock, nullptr); + server_socket* svr_socket = handle->svr_socket; + svr_socket->close(handle->listen_sock, nullptr); /* stop all threads */ #if defined _WIN32 || defined _WIN64 @@ -556,6 +472,8 @@ return_t network_server::close(network_multiplexer_context_t* handle) { handle->protocol_group.clear(); + svr_socket->release(); + mplexer.close(handle->mplexer_handle); handle->signature = 0; @@ -595,17 +513,10 @@ return_t network_server::accept_thread(void* user_context) { } return_t network_server::accept_routine(network_multiplexer_context_t* handle) { + // iocp tcp only return_t ret = errorcode_t::success; network_server svr; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { if (nullptr == handle) { ret = errorcode_t::invalid_parameter; @@ -613,20 +524,22 @@ return_t network_server::accept_routine(network_multiplexer_context_t* handle) { } socket_t listen_sock = (socket_t)handle->listen_sock; - tcp_server_socket* stream_socket = handle->stream_socket; + server_socket* svr_socket = handle->svr_socket; + if (nullptr == svr_socket) { + __leave2; + } accept_context_t accpt_ctx; accpt_ctx.mplexer_context = handle; - ret = stream_socket->accept(listen_sock, &accpt_ctx.cli_socket, (struct sockaddr*)&accpt_ctx.client_addr, &accpt_ctx.client_addr_len); + ret = svr_socket->accept(listen_sock, &accpt_ctx.cli_socket, (struct sockaddr*)&accpt_ctx.client_addr, &accpt_ctx.client_addr_len); if (INVALID_SOCKET == accpt_ctx.cli_socket) { - /* mingw environments GetLastError () return 0 */ #if defined __MINGW32__ + /* mingw environments GetLastError () return 0 */ ret = errorcode_t::canceled; #else ret = get_lasterror(ret); #endif - __leave2; } @@ -644,14 +557,14 @@ return_t network_server::accept_routine(network_multiplexer_context_t* handle) { /* * it can be accomplished by using follows... * - * stream_socket->tls_accept(cli_socket, &tls_handle); + * svr_socket->tls_accept(cli_socket, &tls_handle); * ret = svr.session_accepted(handle, tls_handle, (handle_t)cli_socket, &client_addr); * * sometimes it takes long time by calling ssl_accept * so, separate thread to improve accept performance */ - if (stream_socket->support_tls()) { + if (svr_socket->support_tls()) { /* prepare for ssl_accept delay */ { critical_section_guard guard(handle->accept_queue_lock); @@ -670,7 +583,8 @@ return_t network_server::accept_routine(network_multiplexer_context_t* handle) { return ret; } -return_t network_server::try_connect(network_multiplexer_context_t* handle, socket_t cli_socket, sockaddr_storage_t* client_addr) { +return_t network_server::try_connect(network_multiplexer_context_t* handle, socket_t event_socket, sockaddr_storage_t* client_addr) { + // see accept_routine return_t ret = errorcode_t::success; __try2 { @@ -686,7 +600,7 @@ return_t network_server::try_connect(network_multiplexer_context_t* handle, sock void* dispatch_data[4] = { nullptr, }; - dispatch_data[0] = (void*)(arch_t)cli_socket; + dispatch_data[0] = (void*)(arch_t)event_socket; dispatch_data[1] = client_addr; handle->callback_routine(multiplexer_event_type_t::mux_tryconnect, 4, dispatch_data, nullptr, handle->callback_param); } @@ -697,6 +611,7 @@ return_t network_server::try_connect(network_multiplexer_context_t* handle, sock } return_t network_server::tls_accept_ready(network_multiplexer_context_t* handle, bool* ready) { + // see tls_accept_thread return_t ret = errorcode_t::success; __try2 { @@ -704,9 +619,7 @@ return_t network_server::tls_accept_ready(network_multiplexer_context_t* handle, ret = errorcode_t::invalid_parameter; __leave2; } - bool ret_value = false; - ret_value = handle->accept_queue.empty() ? false : true; - *ready = ret_value; + *ready = handle->accept_queue.empty() ? false : true; } __finally2 { // do nothing @@ -715,6 +628,7 @@ return_t network_server::tls_accept_ready(network_multiplexer_context_t* handle, } return_t network_server::tls_accept_thread(void* user_context) { + // tls, dtls return_t ret = errorcode_t::success; network_multiplexer_context_t* handle = reinterpret_cast(user_context); @@ -745,7 +659,7 @@ return_t network_server::tls_accept_thread(void* user_context) { } // openssl_thread_end (); // ssl23_accept memory leak, call for each thread - handle->stream_socket->tls_stop_accept(); + handle->svr_socket->tls_stop_accept(); } __finally2 { // do nothing @@ -755,6 +669,7 @@ return_t network_server::tls_accept_thread(void* user_context) { } return_t network_server::tls_accept_routine(network_multiplexer_context_t* handle) { + // see tls_accept_thread return_t ret = errorcode_t::success; __try2 { @@ -778,12 +693,29 @@ return_t network_server::tls_accept_routine(network_multiplexer_context_t* handl __leave2; } + socket_t listen_sock = (socket_t)handle->listen_sock; + + int socktype = 0; + typeof_socket(listen_sock, socktype); + bool is_stream = (SOCK_STREAM == socktype); + bool is_dgram = (SOCK_DGRAM == socktype); + network_server svr; - tcp_server_socket* stream_socket = handle->stream_socket; + server_socket* svr_socket = handle->svr_socket; tls_context_t* tls_handle = nullptr; - return_t dwResult = stream_socket->tls_accept(accpt_ctx.cli_socket, &tls_handle); - if (errorcode_t::success == dwResult) { + return_t test = errorcode_t::success; + + // if (is_dgram) { + // test = svr_socket->dtls_listen(listen_sock, (sockaddr*)&accpt_ctx.client_addr, sizeof(accpt_ctx.client_addr), &tls_handle); + // if (errorcode_t::success == test) { + // svr.try_connect(handle, listen_sock, &accpt_ctx.client_addr); + // svr.session_accepted(handle, tls_handle, (handle_t)listen_sock, &accpt_ctx.client_addr); + // } + // } + + test = svr_socket->tls_accept(accpt_ctx.cli_socket, &tls_handle); + if (errorcode_t::success == test) { svr.session_accepted(handle, tls_handle, (handle_t)accpt_ctx.cli_socket, &accpt_ctx.client_addr); /* tls_handle is release in session_closed member. */ } else { @@ -798,6 +730,7 @@ return_t network_server::tls_accept_routine(network_multiplexer_context_t* handl } return_t network_server::tls_accept_signal(void* user_context) { + // tls, dtls return_t ret = errorcode_t::success; network_multiplexer_context_t* handle = reinterpret_cast(user_context); @@ -817,6 +750,7 @@ return_t network_server::tls_accept_signal(void* user_context) { } return_t network_server::cleanup_tls_accept(network_multiplexer_context_t* handle) { + // see close return_t ret = errorcode_t::success; __try2 { @@ -848,14 +782,6 @@ return_t network_server::network_thread(void* user_context) { return_t ret = errorcode_t::success; network_multiplexer_context_t* handle = reinterpret_cast(user_context); -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { if (nullptr == handle) { ret = errorcode_t::invalid_parameter; @@ -866,7 +792,8 @@ return_t network_server::network_thread(void* user_context) { __leave2; } - ret = mplexer.event_loop_run(handle->mplexer_handle, (handle_t)handle->listen_sock, network_routine, handle); + network_server svr; + ret = svr.mplexer.event_loop_run(handle->mplexer_handle, (handle_t)handle->listen_sock, network_routine, handle); } __finally2 { // do nothing @@ -876,40 +803,12 @@ return_t network_server::network_thread(void* user_context) { } return_t network_server::network_routine(uint32 type, uint32 data_count, void* data_array[], CALLBACK_CONTROL* callback_control, void* user_context) { + // see network_thread return_t ret = errorcode_t::success; network_multiplexer_context_t* context = static_cast(user_context); network_server svr; #if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - // tcp_server_socket* serversocket = context->stream_socket; - -#if defined _WIN32 || defined _WIN64 - - uint32 transferred = (uint32)(arch_t)data_array[1]; - network_session* session_object = (network_session*)data_array[2]; - - __try2 { - if (multiplexer_event_type_t::mux_read == type) { - /* consumer_routine (decrease), close_if_not_referenced (delete) */ - session_object->produce(&context->event_queue, (byte_t*)session_object->wsabuf_read()->buf, transferred); - /* asynchronous write */ - session_object->ready_to_read(); - } - if (multiplexer_event_type_t::mux_disconnect == type) { - svr.session_closed(context, session_object->socket_info()->cli_socket); - } - } - __finally2 { - // do nothing - } - -#elif defined __linux__ // void* handle = data_array[0]; @@ -932,9 +831,30 @@ return_t network_server::network_routine(uint32 type, uint32 data_count, void* d svr.session_closed(context, sockcli); /* call session_object->release() inside of closed */ } } + } else if (multiplexer_event_type_t::mux_dgram == type) { + // } // else if (multiplexer_event_type_t::mux_disconnect == type) /* no event catchable */ +#elif defined _WIN32 || defined _WIN64 + + uint32 transferred = (uint32)(arch_t)data_array[1]; + network_session* session_object = (network_session*)data_array[2]; + if (multiplexer_event_type_t::mux_read == type) { + /* consumer_routine (decrease), close_if_not_referenced (delete) */ + session_object->produce(&context->event_queue, (byte_t*)session_object->wsabuf_read()->buf, transferred); + /* asynchronous write */ + session_object->ready_to_read(); + } else if (multiplexer_event_type_t::mux_disconnect == type) { + svr.session_closed(context, session_object->socket_info()->event_socket); + } else if (multiplexer_event_type_t::mux_dgram) { + // socket_t listen_sock = context->listen_sock; + net_dgram_wsabuf_t& wsabuf_read = context->dgram.wsabuf_pair.r; + sockaddr_storage_t& addr = context->dgram.netsock.cli_addr; + session_object->produce(&context->event_queue, (byte_t*)wsabuf_read.buffer, transferred, &addr); + svr.dgram_ready_to_read(context); + } + #endif return ret; @@ -944,20 +864,13 @@ return_t network_server::network_signal(void* user_context) { return_t ret = errorcode_t::success; network_multiplexer_context_t* handle = reinterpret_cast(user_context); -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { if (nullptr == handle) { ret = errorcode_t::invalid_parameter; __leave2; } - mplexer.event_loop_break_concurrent(handle->mplexer_handle, 1); /* call event_loop_break just 1 time */ + network_server svr; + svr.mplexer.event_loop_break_concurrent(handle->mplexer_handle, 1); /* call event_loop_break just 1 time */ } __finally2 { // do nothing @@ -996,6 +909,7 @@ return_t network_server::consumer_thread(void* user_context) { } return_t network_server::consumer_routine(network_multiplexer_context_t* handle) { + // see consumer_thread return_t ret = errorcode_t::success; if (handle->event_queue.size()) { @@ -1006,53 +920,28 @@ return_t network_server::consumer_routine(network_multiplexer_context_t* handle) // re-order by stream priority network_stream_data* buffer_object = nullptr; session_object->consume(&handle->protocol_group, &buffer_object); // set stream priority while processing network_protocol::read_stream + sockaddr_storage_t addr; -#if 0 - t_mlfq pri_queue; while (buffer_object) { - pri_queue.post(buffer_object->get_priority(), buffer_object); - - network_stream_data* temp = buffer_object; - buffer_object = buffer_object->next(); - temp->release(); - } + buffer_object->get_sockaddr(&addr); - // process by stream priority - while (true) { - return_t test = pri_queue.pop(&priority, &buffer_object, 1); - if (errorcode_t::success != test) { - break; - } - - void* dispatch_data[4] = { - nullptr, - }; - dispatch_data[0] = session_object->socket_info(); /* netserver_cb_type_t::netserver_cb_socket */ - dispatch_data[1] = buffer_object->content(); /* netserver_cb_type_t::netserver_cb_dataptr */ - dispatch_data[2] = (void*)buffer_object->size(); /* netserver_cb_type_t::netserver_cb_datasize */ - dispatch_data[3] = session_object; /* netserver_cb_type_t::netserver_cb_session */ - - handle->callback_routine(multiplexer_event_type_t::mux_read, 4, dispatch_data, nullptr, handle->callback_param); - - buffer_object->release(); - } -#else - while (buffer_object) { - void* dispatch_data[4] = { + void* dispatch_data[6] = { nullptr, }; dispatch_data[0] = session_object->socket_info(); /* netserver_cb_type_t::netserver_cb_socket */ dispatch_data[1] = buffer_object->content(); /* netserver_cb_type_t::netserver_cb_dataptr */ dispatch_data[2] = (void*)buffer_object->size(); /* netserver_cb_type_t::netserver_cb_datasize */ dispatch_data[3] = session_object; /* netserver_cb_type_t::netserver_cb_session */ + dispatch_data[5] = &addr; /* netserver_cb_type_t::netserver_cb_sockaddr */ - handle->callback_routine(multiplexer_event_type_t::mux_read, 4, dispatch_data, nullptr, handle->callback_param); + int socktype = session_object->get_server_socket()->socket_type(); + auto muxtype = (SOCK_STREAM == socktype) ? multiplexer_event_type_t::mux_read : multiplexer_event_type_t::mux_dgram; + handle->callback_routine(muxtype, RTL_NUMBER_OF(dispatch_data), dispatch_data, nullptr, handle->callback_param); network_stream_data* temp = buffer_object; buffer_object = buffer_object->next(); temp->release(); } -#endif session_object->release(); } @@ -1081,20 +970,13 @@ return_t network_server::consumer_signal(void* user_context) { return ret; } -return_t network_server::session_accepted(network_multiplexer_context_t* handle, tls_context_t* tls_handle, handle_t cli_socket, +return_t network_server::session_accepted(network_multiplexer_context_t* handle, tls_context_t* tls_handle, handle_t event_socket, sockaddr_storage_t* client_addr) { + // see accept_routine, tls_accept_routine return_t ret = errorcode_t::success; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; -#endif - __try2 { - if ((nullptr == handle) || (INVALID_SOCKET == (socket_t)cli_socket) || (nullptr == client_addr)) { + if ((nullptr == handle) || (INVALID_SOCKET == (socket_t)event_socket) || (nullptr == client_addr)) { ret = errorcode_t::invalid_parameter; __leave2; } @@ -1104,7 +986,7 @@ return_t network_server::session_accepted(network_multiplexer_context_t* handle, } network_session* session_object; - ret = handle->session_manager.connected(cli_socket, client_addr, handle->stream_socket, tls_handle, &session_object); + ret = handle->session_manager.connected(event_socket, client_addr, handle->svr_socket, tls_handle, &session_object); if (errorcode_t::success != ret) { __leave2; } @@ -1114,7 +996,7 @@ return_t network_server::session_accepted(network_multiplexer_context_t* handle, } /* associate with multiplex object (iocp, epoll) */ - mplexer.bind(handle->mplexer_handle, cli_socket, session_object); + mplexer.bind(handle->mplexer_handle, event_socket, session_object); #if defined _WIN32 || defined _WIN64 /* asynchronous */ session_object->ready_to_read(); @@ -1133,19 +1015,39 @@ return_t network_server::session_accepted(network_multiplexer_context_t* handle, return ret; } -return_t network_server::session_closed(network_multiplexer_context_t* handle, handle_t cli_socket) { +return_t network_server::dgram_start(network_multiplexer_context_t* handle) { return_t ret = errorcode_t::success; -#if defined __linux__ - multiplexer_epoll mplexer; -#elif defined __APPLE__ - multiplexer_kqueue mplexer; -#elif defined _WIN32 || defined _WIN64 - multiplexer_iocp mplexer; + socket_t listen_sock = handle->listen_sock; + network_session* session_object = nullptr; + handle->session_manager.dgram_start((handle_t)listen_sock, handle->svr_socket, nullptr, &session_object); + mplexer.bind(handle->mplexer_handle, (handle_t)listen_sock, session_object); +#if defined _WIN32 || defined _WIN64 + dgram_ready_to_read(handle); #endif + return ret; +} + +return_t network_server::dgram_ready_to_read(network_multiplexer_context_t* handle) { + return_t ret = errorcode_t::success; + socket_t listen_sock = handle->listen_sock; +#if defined _WIN32 || defined _WIN64 + net_dgram_wsabuf_t& wsabuf_read = handle->dgram.wsabuf_pair.r; + sockaddr_storage_t& addr = handle->dgram.netsock.cli_addr; + uint32 flags = 0; + wsabuf_read.init(); + int addrlen = sizeof(sockaddr_storage_t); + WSARecvFrom(listen_sock, &wsabuf_read.wsabuf, 1, nullptr, &flags, (sockaddr*)&addr, &addrlen, &wsabuf_read.overlapped, nullptr); +#endif + return ret; +} + +return_t network_server::session_closed(network_multiplexer_context_t* handle, handle_t event_socket) { + // see network_routine + return_t ret = errorcode_t::success; __try2 { - if (nullptr == handle || INVALID_SOCKET == (socket_t)cli_socket) { + if (nullptr == handle || INVALID_SOCKET == (socket_t)event_socket) { ret = errorcode_t::invalid_parameter; __leave2; } @@ -1156,10 +1058,10 @@ return_t network_server::session_closed(network_multiplexer_context_t* handle, h network_session* session_object = nullptr; /* remove from session manager, prevent double free(concurrent epoll_wait) */ - ret = handle->session_manager.ready_to_close(cli_socket, &session_object); + ret = handle->session_manager.ready_to_close(event_socket, &session_object); if (errorcode_t::success == ret) { /* no more associated, control_delete */ - mplexer.unbind(handle->mplexer_handle, session_object->socket_info()->cli_socket, nullptr); + mplexer.unbind(handle->mplexer_handle, session_object->socket_info()->event_socket, nullptr); void* dispatch_data[4] = { nullptr, diff --git a/sdk/net/server/network_server.hpp b/sdk/net/server/network_server.hpp index 5fc94ab6..1ad6323f 100644 --- a/sdk/net/server/network_server.hpp +++ b/sdk/net/server/network_server.hpp @@ -16,13 +16,15 @@ #include #include #include -#include +#include +#include #include #include #include #include namespace hotplace { +using namespace io; namespace net { enum netserver_config_t { @@ -61,6 +63,7 @@ enum netserver_cb_type_t { netserver_cb_datasize = 2, // size_t netserver_cb_session = 3, // network_session* netserver_cb_http_request = 4, // http_request* + netserver_cb_sockaddr = 5, // sockaddr_storage_t*, udp client address }; typedef return_t (*ACCEPT_CONTROL_CALLBACK_ROUTINE)(socket_t socket, sockaddr_storage_t* client_addr, CALLBACK_CONTROL* control, void* parameter); @@ -135,7 +138,7 @@ class network_server { * @param network_multiplexer_context_t** handle [OUT] handle * @param unsigned int family [IN] AF_INET for ipv4, AF_INET6 for ipv6 * @param uint16 port [IN] port - * @param tcp_server_socket* svr_socket [IN] socket layer (see also tcp_server_socket, tls_server_socket) + * @param server_socket* svr_socket [IN] socket * @param server_conf* conf [inopt] * * serverconf_concurrent_event default 1024 @@ -161,6 +164,9 @@ class network_server { * equivalant data_array[netserver_cb_type_t::netserver_cb_datasize] * data_array[3] network_session* * equivalant data_array[netserver_cb_type_t::netserver_cb_session] + * data_array[5] sockaddr_storage_t* + * equivalant data_array[netserver_cb_type_t::netserver_cb_sockaddr] + * * parameter 4 * CALLBACK_CONTROL* is always null * parameter 5 @@ -180,9 +186,7 @@ class network_server { * It'll be automatically created 1 tls_accept_thread, if server_socketis an instance of tls_server_socket class. * see tls_accept_loop_run/tls_accept_loop_break */ - return_t open(network_multiplexer_context_t** handle, unsigned int family, uint16 port, tcp_server_socket* svr_socket, server_conf* conf, - TYPE_CALLBACK_HANDLEREXV callback_routine, void* callback_param); - return_t open(network_multiplexer_context_t** handle, unsigned int family, uint16 port, udp_server_socket* svr_socket, server_conf* conf, + return_t open(network_multiplexer_context_t** handle, unsigned int family, uint16 port, server_socket* svr_socket, server_conf* conf, TYPE_CALLBACK_HANDLEREXV callback_routine, void* callback_param); /** @@ -375,6 +379,18 @@ class network_server { * @return error code (see error.hpp) */ return_t session_closed(network_multiplexer_context_t* handle, handle_t cli_socket); + + return_t dgram_start(network_multiplexer_context_t* handle); + return_t dgram_ready_to_read(network_multiplexer_context_t* handle); + + private: +#if defined __linux__ + multiplexer_epoll mplexer; +#elif defined __APPLE__ + multiplexer_kqueue mplexer; +#elif defined _WIN32 || defined _WIN64 + multiplexer_iocp mplexer; +#endif }; } // namespace net diff --git a/sdk/net/server/network_session.cpp b/sdk/net/server/network_session.cpp index 49313f59..b065e2dc 100644 --- a/sdk/net/server/network_session.cpp +++ b/sdk/net/server/network_session.cpp @@ -13,25 +13,35 @@ namespace hotplace { namespace net { -network_session::network_session(tcp_server_socket* serversocket) { +network_session::network_session(server_socket* serversocket) { _shared.make_share(this); + serversocket->addref(); _session.svr_socket = serversocket; } network_session::~network_session() { - get_server_socket()->close((socket_t)_session.netsock.cli_socket, _session.tls_handle); - // do nothing + get_server_socket()->close((socket_t)_session.netsock.event_socket, _session.tls_handle); + _session.svr_socket->release(); } -return_t network_session::connected(handle_t client_socket, sockaddr_storage_t* sockaddr, tls_context_t* tls_handle) { +return_t network_session::connected(handle_t event_socket, sockaddr_storage_t* sockaddr, tls_context_t* tls_handle) { return_t ret = errorcode_t::success; - _session.netsock.cli_socket = client_socket; + _session.netsock.event_socket = event_socket; memcpy(&(_session.netsock.cli_addr), sockaddr, sizeof(sockaddr_storage_t)); _session.tls_handle = tls_handle; return ret; } +return_t network_session::dgram_start(handle_t listen_sock) { + return_t ret = errorcode_t::success; + + _session.netsock.event_socket = listen_sock; + memset(&(_session.netsock.cli_addr), 0, sizeof(sockaddr_storage_t)); + // _session.tls_handle = nullptr; + return ret; +} + return_t network_session::ready_to_read() { return_t ret = errorcode_t::success; @@ -40,7 +50,8 @@ return_t network_session::ready_to_read() { DWORD dwFlags = 0; DWORD dwRecvBytes = 0; - WSARecv((socket_t)_session.netsock.cli_socket, &(_session.wsabuf_pair.r.wsabuf), 1, &dwRecvBytes, &dwFlags, &(_session.wsabuf_pair.r.overlapped), nullptr); + WSARecv((socket_t)_session.netsock.event_socket, &(_session.wsabuf_pair.r.wsabuf), 1, &dwRecvBytes, &dwFlags, &(_session.wsabuf_pair.r.overlapped), + nullptr); #endif return ret; } @@ -54,7 +65,7 @@ return_t network_session::send(const char* data_ptr, size_t size_data) { __leave2; } size_t cbsent = 0; - ret = get_server_socket()->send((socket_t)_session.netsock.cli_socket, _session.tls_handle, data_ptr, size_data, &cbsent); + ret = get_server_socket()->send((socket_t)_session.netsock.event_socket, _session.tls_handle, data_ptr, size_data, &cbsent); } __finally2 { // do nothing @@ -82,7 +93,7 @@ int network_session::addref() { return _shared.addref(); } int network_session::release() { return _shared.delref(); } -return_t network_session::produce(t_mlfq* q, byte_t* buf_read, size_t size_buf_read) { +return_t network_session::produce(t_mlfq* q, byte_t* buf_read, size_t size_buf_read, const sockaddr_storage_t* addr) { return_t ret = errorcode_t::success; critical_section_guard guard(_lock); @@ -100,6 +111,8 @@ return_t network_session::produce(t_mlfq* q, byte_t* buf_read, buf_read = (byte_t*)_session.buffer; #endif + // int socktype = get_server_socket()->socket_type(); + return_t result = errorcode_t::success; if (_session.tls_handle) { /* TLS */ @@ -111,16 +124,16 @@ return_t network_session::produce(t_mlfq* q, byte_t* buf_read, #elif defined _WIN32 || defined _WIN64 mode = tls_io_flag_t::read_iocp; #endif - ret = get_server_socket()->read((socket_t)_session.netsock.cli_socket, _session.tls_handle, mode, (char*)buf_read, size_buf_read, nullptr); + ret = get_server_socket()->read((socket_t)_session.netsock.event_socket, _session.tls_handle, mode, (char*)buf_read, size_buf_read, nullptr); if (errorcode_t::success != ret) { __leave2; } while (true) { - result = get_server_socket()->read((socket_t)_session.netsock.cli_socket, _session.tls_handle, tls_io_flag_t::read_ssl_read, (char*)buf_read, + result = get_server_socket()->read((socket_t)_session.netsock.event_socket, _session.tls_handle, tls_io_flag_t::read_ssl_read, (char*)buf_read, size_buf_read, &cbread); /*SSL_read */ if (errorcode_t::success == result || errorcode_t::more_data == result) { - getstream()->produce(buf_read, cbread); + getstream()->produce(buf_read, cbread, addr); data_ready = true; @@ -131,7 +144,7 @@ return_t network_session::produce(t_mlfq* q, byte_t* buf_read, dt.getlocaltime(&t); bs.printf("%04d-%02d-%02d %02d:%02d:%02d.%03d ", t.year, t.month, t.day, t.hour, t.minute, t.second, t.milliseconds); - bs << "[ns] read " << (socket_t)_session.netsock.cli_socket << "\n"; + bs << "[ns] read " << (socket_t)_session.netsock.event_socket << "\n"; dump_memory(buf_read, cbread, &bs, 16, 2, 0, dump_notrunc); bs << "\n"; _df(&bs); @@ -148,14 +161,14 @@ return_t network_session::produce(t_mlfq* q, byte_t* buf_read, } else { /* wo TLS */ size_t cbread = 0; #if defined __linux__ - ret = get_server_socket()->read((socket_t)_session.netsock.cli_socket, _session.tls_handle, 0, (char*)buf_read, size_buf_read, &cbread); + ret = get_server_socket()->read((socket_t)_session.netsock.event_socket, _session.tls_handle, 0, (char*)buf_read, size_buf_read, &cbread); if (errorcode_t::success == ret) { - getstream()->produce(buf_read, cbread); + getstream()->produce(buf_read, cbread, addr); q->push(get_priority(), this); } #elif defined _WIN32 || defined _WIN64 cbread = size_buf_read; - getstream()->produce(buf_read, size_buf_read); + getstream()->produce(buf_read, size_buf_read, addr); q->push(get_priority(), this); #endif @@ -166,7 +179,7 @@ return_t network_session::produce(t_mlfq* q, byte_t* buf_read, dt.getlocaltime(&t); bs.printf("%04d-%02d-%02d %02d:%02d:%02d.%03d ", t.year, t.month, t.day, t.hour, t.minute, t.second, t.milliseconds); - bs << "[ns] read " << (socket_t)_session.netsock.cli_socket << "\n"; + bs << "[ns] read " << (socket_t)_session.netsock.event_socket << "\n"; dump_memory(buf_read, cbread, &bs, 16, 2, 0, dump_notrunc); bs << "\n"; _df(&bs); @@ -187,7 +200,7 @@ return_t network_session::consume(network_protocol_group* protocol_group, networ return ret; } -tcp_server_socket* network_session::get_server_socket() { return _session.svr_socket; } +server_socket* network_session::get_server_socket() { return _session.svr_socket; } network_session_data* network_session::get_session_data() { return &_session_data; } @@ -202,11 +215,9 @@ network_session_manager::network_session_manager() { // do nothing } -network_session_manager::~network_session_manager() { - // do nothing -} +network_session_manager::~network_session_manager() { shutdown(); } -return_t network_session_manager::connected(handle_t client_socket, sockaddr_storage_t* sockaddr, tcp_server_socket* svr_socket, tls_context_t* tls_handle, +return_t network_session_manager::connected(handle_t event_socket, sockaddr_storage_t* sockaddr, server_socket* svr_socket, tls_context_t* tls_handle, network_session** ptr_session_object) { return_t ret = errorcode_t::success; network_session_map_pib_t pairib; @@ -215,11 +226,11 @@ return_t network_session_manager::connected(handle_t client_socket, sockaddr_sto __try2 { critical_section_guard guard(_session_lock); - pairib = _session_map.insert(std::make_pair(client_socket, (network_session*)nullptr)); + pairib = _session_map.insert(std::make_pair(event_socket, (network_session*)nullptr)); if (true == pairib.second) { session_object = new network_session(svr_socket); pairib.first->second = session_object; - session_object->connected(client_socket, sockaddr, tls_handle); + session_object->connected(event_socket, sockaddr, tls_handle); *ptr_session_object = session_object; } else { ret = errorcode_t::already_assigned; @@ -232,7 +243,38 @@ return_t network_session_manager::connected(handle_t client_socket, sockaddr_sto return ret; } -return_t network_session_manager::find(handle_t client_socket, network_session** ptr_session_object) { +return_t network_session_manager::dgram_start(handle_t listen_sock, server_socket* svr_socket, tls_context_t* tls_handle, + network_session** ptr_session_object) { + return_t ret = errorcode_t::success; + network_session_map_pib_t pairib; + network_session* session_object = nullptr; + + __try2 { + critical_section_guard guard(_session_lock); + + pairib = _session_map.insert(std::make_pair(listen_sock, (network_session*)nullptr)); + if (true == pairib.second) { + session_object = new network_session(svr_socket); + pairib.first->second = session_object; + session_object->dgram_start(listen_sock); + *ptr_session_object = session_object; + } else { + *ptr_session_object = pairib.first->second; + } + } + __finally2 { + // do nothing + } + + return ret; +} + +return_t network_session_manager::dtls_start(handle_t listen_sock) { + return_t ret = errorcode_t::success; + return ret; +} + +return_t network_session_manager::find(handle_t event_socket, network_session** ptr_session_object) { return_t ret = errorcode_t::success; __try2 { @@ -242,7 +284,7 @@ return_t network_session_manager::find(handle_t client_socket, network_session** } critical_section_guard guard(_session_lock); - network_session_map_t::iterator iter = _session_map.find(client_socket); + network_session_map_t::iterator iter = _session_map.find(event_socket); if (_session_map.end() == iter) { ret = errorcode_t::not_found; } else { @@ -258,14 +300,14 @@ return_t network_session_manager::find(handle_t client_socket, network_session** return ret; } -network_session* network_session_manager::operator[](handle_t client_socket) { +network_session* network_session_manager::operator[](handle_t event_socket) { network_session* ptr_session_object = nullptr; - find(client_socket, &ptr_session_object); + find(event_socket, &ptr_session_object); return ptr_session_object; } -return_t network_session_manager::ready_to_close(handle_t client_socket, network_session** ptr_session_object) { +return_t network_session_manager::ready_to_close(handle_t event_socket, network_session** ptr_session_object) { return_t ret = errorcode_t::success; __try2 { @@ -275,7 +317,7 @@ return_t network_session_manager::ready_to_close(handle_t client_socket, network } critical_section_guard guard(_session_lock); - network_session_map_t::iterator iter = _session_map.find(client_socket); + network_session_map_t::iterator iter = _session_map.find(event_socket); if (_session_map.end() == iter) { ret = errorcode_t::not_found; } else { @@ -292,5 +334,13 @@ return_t network_session_manager::ready_to_close(handle_t client_socket, network return ret; } +void network_session_manager::shutdown() { + critical_section_guard guard(_session_lock); + for (auto item : _session_map) { + item.second->release(); + } + _session_map.clear(); +} + } // namespace net } // namespace hotplace diff --git a/sdk/net/server/network_session.hpp b/sdk/net/server/network_session.hpp index 47dbdf0a..b754fb57 100644 --- a/sdk/net/server/network_session.hpp +++ b/sdk/net/server/network_session.hpp @@ -3,6 +3,7 @@ * @file {file} * @author Soo Han, Kim (princeb612.kr@gmail.com) * @desc + * OVERLAPPED * * Revision History * Date Name Description @@ -12,7 +13,8 @@ #define __HOTPLACE_SDK_NET_SERVER_NETWORKSESSION__ #include -#include +#include +#include #include #include #include @@ -25,10 +27,11 @@ namespace net { /* windows overlapped */ #if defined _WIN32 || defined _WIN64 +// assign per socket typedef struct _net_session_wsabuf_t { OVERLAPPED overlapped; WSABUF wsabuf; - char buffer[1 << 10]; + char buffer[1 << 7]; _net_session_wsabuf_t() { memset(&overlapped, 0, sizeof(OVERLAPPED)); @@ -39,19 +42,18 @@ typedef struct _net_session_wsabuf_t { typedef struct _net_session_wsabuf_pair_t { net_session_wsabuf_t r; - net_session_wsabuf_t w; + // net_session_wsabuf_t w; } net_session_wsabuf_pair_t; #endif typedef struct _net_session_socket_t { - handle_t cli_socket; + handle_t event_socket; sockaddr_storage_t cli_addr; // both ipv4 and ipv6 - _net_session_socket_t() : cli_socket((handle_t)INVALID_SOCKET) {} + _net_session_socket_t() : event_socket((handle_t)INVALID_SOCKET) {} } net_session_socket_t; -class tcp_server_socket; typedef struct _net_session_t { net_session_socket_t netsock; void* mplexer_handle; @@ -59,10 +61,10 @@ typedef struct _net_session_t { #if defined _WIN32 || defined _WIN64 net_session_wsabuf_pair_t wsabuf_pair; #elif defined __linux__ - char buffer[1 << 10]; + char buffer[1 << 7]; #endif - tcp_server_socket* svr_socket; + server_socket* svr_socket; tls_context_t* tls_handle; int priority; reference_counter refcount; @@ -86,18 +88,22 @@ class network_session { friend class network_server; public: - network_session(tcp_server_socket* svr_socket); + network_session(server_socket* svr_socket); virtual ~network_session(); /** * @brief connect handler - * @param handle_t client_socket [IN] - * @param sockaddr_storage_t* sockaddr [IN] - * @param tls_context_t* tls_handle [IN] + * @param handle_t event_socket [IN] + * @param sockaddr_storage_t* sockaddr [IN] + * @param tls_context_t* tls_handle [IN] * @return error code (see error.hpp) * @remarks copy socket and address */ - return_t connected(handle_t client_socket, sockaddr_storage_t* sockaddr, tls_context_t* tls_handle); + return_t connected(handle_t event_socket, sockaddr_storage_t* sockaddr, tls_context_t* tls_handle); + /** + * @brief handle udp data without cookie secret + */ + return_t dgram_start(handle_t listen_sock); /** * @brief in windows call wsarecv to read asynchronously * @return error code (see error.hpp) @@ -152,9 +158,10 @@ class network_session { * @param t_mlfq* q [IN] * @param byte_t* buf_read [IN] * @param size_t size_buf_read [IN] + * @param const sockaddr_storage_t* addr [inopt] * @remarks */ - return_t produce(t_mlfq* q, byte_t* buf_read, size_t size_buf_read); + return_t produce(t_mlfq* q, byte_t* buf_read, size_t size_buf_read, const sockaddr_storage_t* addr = nullptr); /** * @brief consume from stream and put into request, then read stream buffer list from request * @param network_protocol_group* protocol_group [IN] @@ -162,7 +169,7 @@ class network_session { */ return_t consume(network_protocol_group* protocol_group, network_stream_data** ptr_network_stream_buffer); - tcp_server_socket* get_server_socket(); + server_socket* get_server_socket(); network_session_data* get_session_data(); http2_session& get_http2_session(); @@ -192,49 +199,60 @@ class network_session_manager { /** * @brief new network_session - * @param handle_t client_socket [IN] - * @param sockaddr_storage_t* sockaddr [IN] - * @param tcp_server_socket* svr_socket [IN] - * @param tls_context_t* tls_handle [IN] + * @param handle_t event_socket [IN] + * @param sockaddr_storage_t* sockaddr [IN] + * @param server_socket* svr_socket [IN] + * @param tls_context_t* tls_handle [IN] * @param network_session** ptr_session_object [OUT] use release to free * @return error code (see error.hpp) */ - return_t connected(handle_t client_socket, sockaddr_storage_t* sockaddr, tcp_server_socket* svr_socket, tls_context_t* tls_handle, + return_t connected(handle_t event_socket, sockaddr_storage_t* sockaddr, server_socket* svr_socket, tls_context_t* tls_handle, network_session** ptr_session_object); + /** + * @brief handle udp data without cookie secret + */ + return_t dgram_start(handle_t listen_sock, server_socket* svr_socket, tls_context_t* tls_handle, network_session** ptr_session_object); + /** + * @brief handle udp data with cookie secret + * @remarks TODO + */ + return_t dtls_start(handle_t listen_sock); /** * @brief find a network session - * @param handle_t client_socket [IN] + * @param handle_t event_socket [IN] * @param network_session** ptr_session_object [OUT] referenced, call release * @return error code (see error.hpp) * @example - * network_session* session = session_manager.find (client_socket); + * network_session* session = session_manager.find (event_socket); * if (nullptr != session) * { * session->release (); // decrease reference counter * } */ - return_t find(handle_t client_socket, network_session** ptr_session_object); + return_t find(handle_t event_socket, network_session** ptr_session_object); /** * @brief operator[socket] * @return error code (see error.hpp) * @remarks * @example - * network_session* session = session_manager[client_socket]; + * network_session* session = session_manager[event_socket]; * if (nullptr != session) * { * session->release (); // decrease reference counter * } */ - network_session* operator[](handle_t client_socket); + network_session* operator[](handle_t event_socket); /** * @brief remove from session list - * @param handle_t client_socket [IN] + * @param handle_t event_socket [IN] * @param network_session** ptr_session_object [OUT] * @return error code (see error.hpp) */ - return_t ready_to_close(handle_t client_socket, network_session** ptr_session_object); + return_t ready_to_close(handle_t event_socket, network_session** ptr_session_object); protected: + void shutdown(); + typedef std::map network_session_map_t; typedef std::pair network_session_map_pib_t; @@ -242,6 +260,53 @@ class network_session_manager { network_session_map_t _session_map; }; +/* windows overlapped */ +#if defined _WIN32 || defined _WIN64 +typedef struct _net_dgram_wsabuf_t { + OVERLAPPED overlapped; + WSABUF wsabuf; + char buffer[1 << 16]; + + _net_dgram_wsabuf_t() { init(); } + void init() { + memset(&overlapped, 0, sizeof(OVERLAPPED)); + wsabuf.len = RTL_NUMBER_OF(buffer); + wsabuf.buf = buffer; + } +} net_dgram_wsabuf_t; + +typedef struct _net_dgram_wsabuf_pair_t { + net_dgram_wsabuf_t r; + // net_session_wsabuf_t w; +} net_dgram_wsabuf_pair_t; + +#endif + +typedef struct _net_dgram_socket_t { + handle_t listen_sock; + sockaddr_storage_t cli_addr; // both ipv4 and ipv6 + + _net_dgram_socket_t() : listen_sock((handle_t)INVALID_SOCKET) {} +} net_dgram_socket_t; + +typedef struct _net_dgram_t { + net_dgram_socket_t netsock; + void* mplexer_handle; + +#if defined _WIN32 || defined _WIN64 + net_dgram_wsabuf_pair_t wsabuf_pair; +#elif defined __linux__ + char buffer[1 << 16]; +#endif + + server_socket* svr_socket; + tls_context_t* tls_handle; + int priority; + // reference_counter refcount; + + _net_dgram_t() : mplexer_handle(nullptr), svr_socket(nullptr), tls_handle(nullptr), priority(0) {} +} net_dgram_t; + } // namespace net } // namespace hotplace diff --git a/sdk/net/server/network_stream.cpp b/sdk/net/server/network_stream.cpp index a65a7073..c9f88bbe 100644 --- a/sdk/net/server/network_stream.cpp +++ b/sdk/net/server/network_stream.cpp @@ -23,7 +23,7 @@ network_stream::~network_stream() { // do nothing } -return_t network_stream::produce(byte_t* buf_read, size_t size_buf_read) { +return_t network_stream::produce(byte_t* buf_read, size_t size_buf_read, const sockaddr_storage_t* addr) { return_t ret = errorcode_t::success; network_stream_data* buffer_object = nullptr; @@ -32,6 +32,9 @@ return_t network_stream::produce(byte_t* buf_read, size_t size_buf_read) { __try_new_catch(buffer_object, new network_stream_data, ret, __leave2); buffer_object->assign(buf_read, size_buf_read); + if (addr) { + buffer_object->set_sockaddr(addr); + } critical_section_guard guard(_lock); _queue.push_back(buffer_object); @@ -149,7 +152,7 @@ return_t network_stream::do_write(network_stream* target) { while (false == _queue.empty()) { buffer_object = _queue.front(); - target->produce(buffer_object->content(), buffer_object->size()); + target->produce(buffer_object->content(), buffer_object->size(), buffer_object->get_sockaddr()); buffer_object->release(); _queue.pop_front(); @@ -195,7 +198,7 @@ return_t network_stream::do_writep(network_protocol_group* protocol_group, netwo protocol->read_stream(&bufstream, &message_size, &state, &priority); switch (state) { case protocol_state_t::protocol_state_complete: - target->produce(bufstream.data(), message_size); + target->produce(bufstream.data(), message_size, buffer_object->get_sockaddr()); _run = false; break; case protocol_state_t::protocol_state_forged: @@ -265,12 +268,15 @@ return_t network_stream::do_writep(network_protocol_group* protocol_group, netwo return ret; } -network_stream_data::network_stream_data() : _ptr(nullptr), _size(0), _next(nullptr), _priority(0) { _instance.make_share(this); } +network_stream_data::network_stream_data() : _ptr(nullptr), _size(0), _next(nullptr), _priority(0), _addr(nullptr) { _instance.make_share(this); } network_stream_data::~network_stream_data() { - if (nullptr != _ptr) { + if (_ptr) { free(_ptr); } + if (_addr) { + free(_addr); + } } return_t network_stream_data::assign(byte_t* ptr, size_t size) { @@ -309,5 +315,26 @@ int network_stream_data::addref() { return _instance.addref(); } int network_stream_data::release() { return _instance.delref(); } +void network_stream_data::set_sockaddr(const sockaddr_storage_t* cliaddr) { + // store recvfrom sockaddr + if (cliaddr) { + if (nullptr == _addr) { + _addr = (sockaddr_storage_t*)malloc(sizeof(sockaddr_storage_t)); + } + if (_addr) { + memcpy(_addr, cliaddr, sizeof(sockaddr_storage_t)); + } + } +} + +void network_stream_data::get_sockaddr(sockaddr_storage_t* cliaddr) { + if (cliaddr && _addr) { + // get recvfrom sockaddr + memcpy(cliaddr, _addr, sizeof(sockaddr_storage_t)); + } +} + +const sockaddr_storage_t* network_stream_data::get_sockaddr() { return _addr; } + } // namespace net } // namespace hotplace diff --git a/sdk/net/server/network_stream.hpp b/sdk/net/server/network_stream.hpp index 562bafe9..d3ee3aa4 100644 --- a/sdk/net/server/network_stream.hpp +++ b/sdk/net/server/network_stream.hpp @@ -60,12 +60,20 @@ class network_stream_data { */ int release(); + /* + * udp client address + */ + void set_sockaddr(const sockaddr_storage_t* cliaddr); + void get_sockaddr(sockaddr_storage_t* cliaddr); + const sockaddr_storage_t* get_sockaddr(); + protected: t_shared_reference _instance; byte_t* _ptr; size_t _size; network_stream_data* _next; int _priority; + sockaddr_storage_t* _addr; // udp }; /** @@ -79,10 +87,11 @@ class network_stream { /** * @brief produce - * @param byte_t* buf_read [IN] - * @param size_t size_buf_read [IN] + * @param byte_t* buf_read [IN] + * @param size_t size_buf_read [IN] + * @param const sockaddr_storage_t* addr [inopt] */ - return_t produce(byte_t* buf_read, size_t size_buf_read); + return_t produce(byte_t* buf_read, size_t size_buf_read, const sockaddr_storage_t* addr = nullptr); /** * @brief data ready */ diff --git a/sdk/net/tls/dtls_client_socket.cpp b/sdk/net/tls/dtls_client_socket.cpp new file mode 100644 index 00000000..f7dd78d4 --- /dev/null +++ b/sdk/net/tls/dtls_client_socket.cpp @@ -0,0 +1,111 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#include +#include + +namespace hotplace { +using namespace io; +namespace net { + +dtls_client_socket::dtls_client_socket(transport_layer_security* tls) : udp_client_socket(), _tls(tls) { + if (nullptr == tls) { + throw errorcode_t::insufficient; + } + tls->addref(); + _shared.make_share(this); +} + +dtls_client_socket::~dtls_client_socket() { _tls->release(); } + +int dtls_client_socket::addref() { return _shared.addref(); } + +int dtls_client_socket::release() { return _shared.delref(); } + +return_t dtls_client_socket::connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout) { + return_t ret = errorcode_t::success; + + __try2 { + if (nullptr == sock || nullptr == tls_handle || nullptr == address) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + tls_context_t* handle = nullptr; + std::string addr = address; + ret = _tls->connect(&handle, SOCK_DGRAM, addr.c_str(), port, timeout); + if (errorcode_t::success == ret) { + *sock = _tls->get_socket(handle); + *tls_handle = handle; + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t dtls_client_socket::close(socket_t sock, tls_context_t* tls_handle) { + return_t ret = errorcode_t::success; + + __try2 { + if (nullptr != tls_handle) { + _tls->close(tls_handle); + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t dtls_client_socket::read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread) { + return_t ret = errorcode_t::success; + + /* + * case ... server sent 10 bytes, and client recv buffer size 8 + * recv 8 (SSL_read SSL_ERROR_WANT_READ) + * recv 2 (SSL_read SUCCESS) + * in case read 8 bytes and 2 bytes remains, return errorcode_t::more_data + */ + while (true) { + ret = wait_socket(sock, get_wto(), SOCK_WAIT_READABLE); + if (errorcode_t::success == ret) { + ret = _tls->read(tls_handle, tls_io_flag_t::read_ssl_read | tls_io_flag_t::read_bio_write | tls_io_flag_t::read_socket_recv, ptr_data, size_data, + cbread); + if (errorcode_t::pending == ret) { + continue; + } else { + break; + } + } else { + break; + } + } + return ret; +} + +return_t dtls_client_socket::more(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread) { + return_t ret = errorcode_t::success; + + ret = _tls->read(tls_handle, tls_io_flag_t::read_ssl_read, ptr_data, size_data, cbread); + return ret; +} + +return_t dtls_client_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent) { + return_t ret = errorcode_t::success; + + ret = _tls->send(tls_handle, tls_io_flag_t::send_all, ptr_data, size_data, cbsent); + return ret; +} + +bool dtls_client_socket::support_tls() { return true; } + +} // namespace net +} // namespace hotplace diff --git a/sdk/net/tls/dtls_client_socket.hpp b/sdk/net/tls/dtls_client_socket.hpp new file mode 100644 index 00000000..58eef087 --- /dev/null +++ b/sdk/net/tls/dtls_client_socket.hpp @@ -0,0 +1,96 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#ifndef __HOTPLACE_SDK_NET_TLS_DTLSCLIENTSOCKET__ +#define __HOTPLACE_SDK_NET_TLS_DTLSCLIENTSOCKET__ + +#include +#include +#include + +namespace hotplace { +namespace net { + +class dtls_client_socket : public udp_client_socket { + public: + dtls_client_socket(transport_layer_security* tls); + virtual ~dtls_client_socket(); + + /** + * @brief connect + * @param socket_t* sock [OUT] + * @param tls_context_t** tls_handle [OUT] + * @param const char* address [IN] + * @param uint16 port [IN] + * @param uint32 timeout [IN] + * @return error code (see error.hpp) + */ + virtual return_t connect(socket_t* sock, tls_context_t** tls_handle, const char* address, uint16 port, uint32 timeout); + /** + * @brief close + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @return error code (see error.hpp) + */ + virtual return_t close(socket_t sock, tls_context_t* tls_handle); + /** + * @brief read + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @param char* ptr_data [OUT] + * @param size_t size_data [IN] + * @param size_t* cbread [OUT] + * @return error code (see error.hpp) + * if return errorcode_t::more_data, call more member function + * ret = cli.read (sock, handle, buf, sizeof (buf), &sizeread); + * printf ("%.*s\n", (int) sizeread, buf); + * while (errorcode_t::more_data == ret) { + * ret = cli.more (sock, handle, buf, sizeof (buf), &sizeread); + * printf ("%.*s\n", (int) sizeread, buf); + * } + */ + virtual return_t read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread); + /** + * @brief read more + * @param socket_t sock + * @param tls_context_t* tls_handle + * @param char* ptr_data + * @param size_t size_data + * @param size_t* cbread + * @return + * errorcode_t::pending no data ready + * errorcode_t::more_data more data + */ + virtual return_t more(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* cbread); + /** + * @brief send + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @param const char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* cbsent [OUT] + * @return error code (see error.hpp) + */ + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent); + + virtual bool support_tls(); + + int addref(); + int release(); + + protected: + transport_layer_security* _tls; + t_shared_reference _shared; +}; + +} // namespace net +} // namespace hotplace + +#endif diff --git a/sdk/net/tls/tls_server.cpp b/sdk/net/tls/dtls_server_socket.cpp similarity index 53% rename from sdk/net/tls/tls_server.cpp rename to sdk/net/tls/dtls_server_socket.cpp index 2f507c86..d12ee4d6 100644 --- a/sdk/net/tls/tls_server.cpp +++ b/sdk/net/tls/dtls_server_socket.cpp @@ -9,13 +9,13 @@ */ #include -#include +#include namespace hotplace { using namespace crypto; namespace net { -tls_server_socket::tls_server_socket(transport_layer_security* tls) : _tls(tls) { +dtls_server_socket::dtls_server_socket(transport_layer_security* tls) : udp_server_socket(), _tls(tls) { if (nullptr == tls) { throw errorcode_t::insufficient; } @@ -23,20 +23,16 @@ tls_server_socket::tls_server_socket(transport_layer_security* tls) : _tls(tls) _shared.make_share(this); } -tls_server_socket::~tls_server_socket() { _tls->release(); } - -int tls_server_socket::addref() { return _shared.addref(); } - -int tls_server_socket::release() { return _shared.delref(); } +dtls_server_socket::~dtls_server_socket() { _tls->release(); } -return_t tls_server_socket::close(socket_t sock, tls_context_t* tls_handle) { +return_t dtls_server_socket::close(socket_t sock, tls_context_t* tls_handle) { return_t ret = errorcode_t::success; __try2 { if (nullptr != tls_handle) { _tls->close(tls_handle); } - tcp_server_socket::close(sock, tls_handle); + // do not close socket } __finally2 { // do nothing @@ -44,11 +40,11 @@ return_t tls_server_socket::close(socket_t sock, tls_context_t* tls_handle) { return ret; } -return_t tls_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_handle) { +return_t dtls_server_socket::dtls_listen(socket_t sock, struct sockaddr* addr, socklen_t addrlen, tls_context_t** tls_handle) { return_t ret = errorcode_t::success; __try2 { - ret = _tls->accept(tls_handle, clisock); /* new TLS_CONTEXT, to release see close member */ + ret = _tls->dtls_listen(tls_handle, sock, addr, addrlen); if (errorcode_t::success != ret) { __leave2; } @@ -59,64 +55,6 @@ return_t tls_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_han return ret; } -return_t tls_server_socket::tls_stop_accept() { - return_t ret = errorcode_t::success; - - openssl_thread_end(); // ssl23_accept memory leak, call for each thread - return ret; -} - -return_t tls_server_socket::read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread) { - return_t ret = errorcode_t::success; - - __try2 { ret = _tls->read(tls_handle, mode, ptr_data, size_data, cbread); } - __finally2 { - // do nothing - } - return ret; -} - -return_t tls_server_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent) { - return_t ret = errorcode_t::success; - - __try2 { ret = _tls->send(tls_handle, tls_io_flag_t::send_all, ptr_data, size_data, cbsent); } - __finally2 { - // do nothing - } - return ret; -} - -bool tls_server_socket::support_tls() { return true; } - -dtls_server_socket::dtls_server_socket(transport_layer_security* tls) : _tls(tls) { - if (nullptr == tls) { - throw errorcode_t::insufficient; - } - tls->addref(); - _shared.make_share(this); -} - -dtls_server_socket::~dtls_server_socket() { _tls->release(); } - -int dtls_server_socket::addref() { return _shared.addref(); } - -int dtls_server_socket::release() { return _shared.delref(); } - -return_t dtls_server_socket::close(socket_t sock, tls_context_t* tls_handle) { - return_t ret = errorcode_t::success; - - __try2 { - if (nullptr != tls_handle) { - _tls->close(tls_handle); - } - udp_server_socket::close(sock, tls_handle); - } - __finally2 { - // do nothing - } - return ret; -} - return_t dtls_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_handle) { return_t ret = errorcode_t::success; @@ -134,7 +72,6 @@ return_t dtls_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_ha return_t dtls_server_socket::tls_stop_accept() { return_t ret = errorcode_t::success; - openssl_thread_end(); // ssl23_accept memory leak, call for each thread return ret; } diff --git a/sdk/net/tls/dtls_server_socket.hpp b/sdk/net/tls/dtls_server_socket.hpp new file mode 100644 index 00000000..96ea7376 --- /dev/null +++ b/sdk/net/tls/dtls_server_socket.hpp @@ -0,0 +1,83 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#ifndef __HOTPLACE_SDK_NET_TLS_DTLSSERVERSOCKET__ +#define __HOTPLACE_SDK_NET_TLS_DTLSSERVERSOCKET__ + +#include +#include +#include + +namespace hotplace { +namespace net { + +class dtls_server_socket : public udp_server_socket { + public: + dtls_server_socket(transport_layer_security* tls); + virtual ~dtls_server_socket(); + /** + * @brief close + */ + return_t close(socket_t sock, tls_context_t* tls_handle); + /** + * @brief dtls listen + * @param socket_t clisock [IN] client socket + * @param struct sockaddr* addr [out] sockaddr* + * @param socklen_t addrlen [in] + * @param tls_context_t** tls_handle [OUT] tls context + * @return error code (see error.hpp) + */ + return_t dtls_listen(socket_t sock, struct sockaddr* addr, socklen_t addrlen, tls_context_t** tls_handle); + /** + * @brief tls accept + * @param socket_t clisock [IN] client socket + * @param tls_context_t** tls_handle [OUT] tls context + * @return error code (see error.hpp) + */ + virtual return_t tls_accept(socket_t clisock, tls_context_t** tls_handle); + /** + * @brief tls_stop_accept + */ + virtual return_t tls_stop_accept(); + /** + * @brief read + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @param int mode [IN] + * 2 recv + * 1 bio_write + * 0 ssl_read + * @param char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* cbread [OUT] + * @return error code (see error.hpp) + */ + virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread); + /** + * @brief send + * @param socket_t sock [IN] + * @param tls_context_t* tls_handle [IN] + * @param const char* ptr_data [IN] + * @param size_t size_data [IN] + * @param size_t* cbsent [OUT] + * @return error code (see error.hpp) + */ + virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent); + + virtual bool support_tls(); + + protected: + transport_layer_security* _tls; +}; + +} // namespace net +} // namespace hotplace + +#endif diff --git a/sdk/net/tls/sdk.cpp b/sdk/net/tls/sdk.cpp index 8b731ec0..66f114a0 100644 --- a/sdk/net/tls/sdk.cpp +++ b/sdk/net/tls/sdk.cpp @@ -9,9 +9,10 @@ */ #include -#include +#include namespace hotplace { +using namespace crypto; using namespace io; namespace net { @@ -37,13 +38,12 @@ return_t tls_connect(socket_t sock, SSL* ssl, uint32 dwSeconds, uint32 nbio) { /* * openssl-1.0.1i - * 1) blocking io 방식에서 SSL_connect 멈추는 현상 발생 - * -> non-blocking io 방식으로 변경 + * 1) SSL_connect block issue, make SSL_connect non-blocking * 2) SSL_connect crash * ; X509_LOOKUP_by_subject 에서 발생 - * X509_LOOKUP *lu; // 초기화되지 않음 - * lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); // sk_X509_LOOKUP_value 실패시 잘못된 주소 공간 - * j=X509_LOOKUP_by_subject(lu,type,name,&stmp); // crash 발생 + * X509_LOOKUP *lu; // uninitialized + * lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); // if sk_X509_LOOKUP_value fails + * j=X509_LOOKUP_by_subject(lu,type,name,&stmp); // crash */ try { int ret_connect = 0; @@ -91,5 +91,63 @@ return_t tls_connect(socket_t sock, SSL* ssl, uint32 dwSeconds, uint32 nbio) { return ret; } +return_t BIO_ADDR_to_sockaddr(BIO_ADDR* bio_addr, struct sockaddr* sockaddr, socklen_t addrlen) { + return_t ret = errorcode_t::success; + __try2 { + size_t socklen4 = sizeof(struct sockaddr_in); + size_t socklen6 = sizeof(struct sockaddr_in6); + + if ((nullptr == bio_addr) || (nullptr == sockaddr) || (addrlen < socklen4)) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + + auto family = BIO_ADDR_family(bio_addr); + struct sockaddr_in* addr4 = (struct sockaddr_in*)sockaddr; + addr4->sin_family = family; + switch (family) { + case AF_INET: { + BIO_ADDR_rawaddress(bio_addr, &addr4->sin_addr, nullptr); + addr4->sin_port = BIO_ADDR_rawport(bio_addr); + } break; + case AF_INET6: + if (addrlen >= socklen6) { + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sockaddr; + BIO_ADDR_rawaddress(bio_addr, &addr6->sin6_addr, nullptr); + addr6->sin6_port = BIO_ADDR_rawport(bio_addr); + } else { + ret = errorcode_t::insufficient_buffer; + } + break; + default: + ret = errorcode_t::unknown; + break; + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t SSL_to_sockaddr(SSL* ssl, struct sockaddr* sockaddr, socklen_t addrlen) { + return_t ret = errorcode_t::success; + BIO_ADDR* bio_addr = nullptr; + __try2 { + if ((nullptr == ssl) || (nullptr == sockaddr)) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + BIO_dgram_get_peer(SSL_get_rbio(ssl), bio_addr); + BIO_ADDR_to_sockaddr(bio_addr, sockaddr, addrlen); + } + __finally2 { + if (bio_addr) { + BIO_ADDR_free(bio_addr); + } + } + return ret; +} + } // namespace net } // namespace hotplace diff --git a/sdk/net/tls/sdk.hpp b/sdk/net/tls/sdk.hpp index c48b8388..a00f0123 100644 --- a/sdk/net/tls/sdk.hpp +++ b/sdk/net/tls/sdk.hpp @@ -26,6 +26,16 @@ namespace net { */ return_t tls_connect(socket_t sock, SSL* ssl, uint32 dwSeconds, uint32 nbio); +/** + * @brief BIO_ADDR* + */ +return_t BIO_ADDR_to_sockaddr(BIO_ADDR* bio_addr, struct sockaddr* sockaddr, socklen_t addrlen); +/** + * @brief BIO_ADDR* + * @remarks BIO_dgram_get_peer(ssl) + */ +return_t SSL_to_sockaddr(SSL* ssl, struct sockaddr* sockaddr, socklen_t addrlen); + } // namespace net } // namespace hotplace diff --git a/sdk/net/tls/tls.cpp b/sdk/net/tls/tls.cpp index b4907925..7790f2e7 100644 --- a/sdk/net/tls/tls.cpp +++ b/sdk/net/tls/tls.cpp @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include @@ -30,6 +30,8 @@ typedef struct _tls_context_t { SSL* _ssl; BIO* _sbio_read; BIO* _sbio_write; + + _tls_context_t() : _signature(0), _flags(0), _socket(-1), _ssl(nullptr), _sbio_read(nullptr), _sbio_write(nullptr) {} } tls_context_t; transport_layer_security::transport_layer_security(SSL_CTX* x509) : _x509(x509) { @@ -60,7 +62,7 @@ return_t transport_layer_security::connect(tls_context_t** handle, int type, con __leave2; } - ret = create_socket(&sock, &sockaddr_address, SOCK_STREAM, address, port); + ret = create_socket(&sock, &sockaddr_address, type, address, port); if (errorcode_t::success != ret) { __leave2; } @@ -108,8 +110,6 @@ return_t transport_layer_security::connect(tls_context_t** handle, socket_t sock __try_new_catch(context, new tls_context_t, ret, __leave2); - memset(context, 0, sizeof(tls_context_t)); - ssl = SSL_new(tls_ctx); if (nullptr == ssl) { ret = errorcode_t::internal_error; @@ -171,8 +171,6 @@ return_t transport_layer_security::accept(tls_context_t** handle, socket_t fd) { __try_new_catch(context, new tls_context_t, ret, __leave2); - memset(context, 0, sizeof(tls_context_t)); - /* SSL_accept */ ssl = SSL_new(tls_ctx); SSL_set_fd(ssl, (int)fd); @@ -229,7 +227,7 @@ return_t transport_layer_security::accept(tls_context_t** handle, socket_t fd) { set_sock_nbio(fd, 0); if (status < 0) { - ret = errorcode_t::internal_error; + ret = get_lasterror(status); __leave2; } @@ -271,6 +269,76 @@ return_t transport_layer_security::accept(tls_context_t** handle, socket_t fd) { return ret; } +return_t transport_layer_security::dtls_listen(tls_context_t** handle, socket_t fd, struct sockaddr* addr, socklen_t addrlen) { + return_t ret = errorcode_t::success; + + BIO* sbio_read = nullptr; + BIO* sbio_write = nullptr; + SSL* ssl = nullptr; + tls_context_t* context = nullptr; + BIO_ADDR* bio_addr = nullptr; + + __try2 { + if (nullptr == handle) { + ret = errorcode_t::invalid_parameter; + __leave2; + } + + if (nullptr == _x509) { + ret = errorcode_t::invalid_context; + __leave2; + } + SSL_CTX* tls_ctx = _x509; + + __try_new_catch(context, new tls_context_t, ret, __leave2); + + /* SSL_accept */ + ssl = SSL_new(tls_ctx); + SSL_set_fd(ssl, (int)fd); + + int status = -1; + bio_addr = BIO_ADDR_new(); + status = DTLSv1_listen(ssl, bio_addr); + if (status < 0) { + ret = get_lasterror(status); + __leave2; + } + BIO_ADDR_to_sockaddr(bio_addr, addr, addrlen); + + /* SSL_set_bio */ + sbio_read = BIO_new(BIO_s_mem()); + sbio_write = BIO_new(BIO_s_mem()); + SSL_set_bio(ssl, sbio_read, sbio_write); + + /* compose the context */ + context->_socket = fd; + context->_ssl = ssl; + + context->_sbio_read = sbio_read; + context->_sbio_write = sbio_write; + context->_signature = TLS_CONTEXT_SIGNATURE; + + *handle = context; + } + __finally2 { + if (bio_addr) { + BIO_ADDR_free(bio_addr); + } + if (errorcode_t::success != ret) { + if (nullptr != ssl) { + // SSL_shutdown(ssl); + SSL_free(ssl); + } + if (nullptr != context) { + context->_signature = 0; + delete context; + } + } + } + + return ret; +} + return_t transport_layer_security::close(tls_context_t* handle) { return_t ret = errorcode_t::success; tls_context_t* context = nullptr; diff --git a/sdk/net/tls/tls.hpp b/sdk/net/tls/tls.hpp index 92c5547a..a36cdda2 100644 --- a/sdk/net/tls/tls.hpp +++ b/sdk/net/tls/tls.hpp @@ -69,6 +69,10 @@ class transport_layer_security { * ret = ssl->accept (handle, cli_socket); // handshake */ return_t accept(tls_context_t** handle, socket_t sock); + /** + * @brief DTLSv1_listen + */ + return_t dtls_listen(tls_context_t** handle, socket_t sock, struct sockaddr* addr, socklen_t addrlen); /** * @brief close * @param tls_context_t* handle [IN] diff --git a/sdk/net/tls/tls_client.cpp b/sdk/net/tls/tls_client_socket.cpp similarity index 97% rename from sdk/net/tls/tls_client.cpp rename to sdk/net/tls/tls_client_socket.cpp index 235b9ff4..a4b369d6 100644 --- a/sdk/net/tls/tls_client.cpp +++ b/sdk/net/tls/tls_client_socket.cpp @@ -8,8 +8,8 @@ * Date Name Description */ -#include -#include +#include +#include namespace hotplace { using namespace io; diff --git a/sdk/net/tls/tls_client.hpp b/sdk/net/tls/tls_client_socket.hpp similarity index 97% rename from sdk/net/tls/tls_client.hpp rename to sdk/net/tls/tls_client_socket.hpp index 04e86ab9..3b38e480 100644 --- a/sdk/net/tls/tls_client.hpp +++ b/sdk/net/tls/tls_client_socket.hpp @@ -8,10 +8,10 @@ * Date Name Description */ -#ifndef __HOTPLACE_SDK_NET_TLS_TLSCLIENT__ -#define __HOTPLACE_SDK_NET_TLS_TLSCLIENT__ +#ifndef __HOTPLACE_SDK_NET_TLS_TLSCLIENTSOCKET__ +#define __HOTPLACE_SDK_NET_TLS_TLSCLIENTSOCKET__ -#include +#include #include #include diff --git a/sdk/net/tls/tls_server_socket.cpp b/sdk/net/tls/tls_server_socket.cpp new file mode 100644 index 00000000..0cef6b28 --- /dev/null +++ b/sdk/net/tls/tls_server_socket.cpp @@ -0,0 +1,82 @@ +/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ +/** + * @file {file} + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * + * Revision History + * Date Name Description + */ + +#include +#include + +namespace hotplace { +using namespace crypto; +namespace net { + +tls_server_socket::tls_server_socket(transport_layer_security* tls) : tcp_server_socket(), _tls(tls) { + if (nullptr == tls) { + throw errorcode_t::insufficient; + } + tls->addref(); +} + +tls_server_socket::~tls_server_socket() { _tls->release(); } + +return_t tls_server_socket::close(socket_t sock, tls_context_t* tls_handle) { + return_t ret = errorcode_t::success; + __try2 { + if (_tls) { + _tls->close(tls_handle); + } + close_socket(sock, true, 0); + } + __finally2 { + // do nothing + } + return ret; +} + +return_t tls_server_socket::tls_accept(socket_t clisock, tls_context_t** tls_handle) { + return_t ret = errorcode_t::success; + __try2 { + ret = _tls->accept(tls_handle, clisock); /* new TLS_CONTEXT, to release see close member */ + if (errorcode_t::success != ret) { + __leave2; + } + } + __finally2 { + // do nothing + } + return ret; +} + +return_t tls_server_socket::tls_stop_accept() { + return_t ret = errorcode_t::success; + openssl_thread_end(); // ssl23_accept memory leak, call for each thread + return ret; +} + +return_t tls_server_socket::read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread) { + return_t ret = errorcode_t::success; + __try2 { ret = _tls->read(tls_handle, mode, ptr_data, size_data, cbread); } + __finally2 { + // do nothing + } + return ret; +} + +return_t tls_server_socket::send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent) { + return_t ret = errorcode_t::success; + __try2 { ret = _tls->send(tls_handle, tls_io_flag_t::send_all, ptr_data, size_data, cbsent); } + __finally2 { + // do nothing + } + return ret; +} + +bool tls_server_socket::support_tls() { return true; } + +} // namespace net +} // namespace hotplace diff --git a/sdk/net/tls/tls_server.hpp b/sdk/net/tls/tls_server_socket.hpp similarity index 51% rename from sdk/net/tls/tls_server.hpp rename to sdk/net/tls/tls_server_socket.hpp index 1abfbe45..6ee19cd8 100644 --- a/sdk/net/tls/tls_server.hpp +++ b/sdk/net/tls/tls_server_socket.hpp @@ -8,10 +8,10 @@ * Date Name Description */ -#ifndef __HOTPLACE_SDK_NET_TLS_TLSSERVER__ -#define __HOTPLACE_SDK_NET_TLS_TLSSERVER__ +#ifndef __HOTPLACE_SDK_NET_TLS_TLSSERVERSOCKET__ +#define __HOTPLACE_SDK_NET_TLS_TLSSERVERSOCKET__ -#include +#include #include #include @@ -44,68 +44,9 @@ class tls_server_socket : public tcp_server_socket { * @return error code (see error.hpp) */ virtual return_t tls_accept(socket_t clisock, tls_context_t** tls_handle); - virtual return_t tls_stop_accept(); - /** - * @brief read - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] - * @param int mode [IN] - * 2 recv - * 1 bio_write - * 0 ssl_read - * @param char* ptr_data [IN] - * @param size_t size_data [IN] - * @param size_t* cbread [OUT] - * @return error code (see error.hpp) - */ - virtual return_t read(socket_t sock, tls_context_t* tls_handle, int mode, char* ptr_data, size_t size_data, size_t* cbread); /** - * @brief send - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] - * @param const char* ptr_data [IN] - * @param size_t size_data [IN] - * @param size_t* cbsent [OUT] - * @return error code (see error.hpp) + * @brief tls_stop_accept */ - virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* cbsent); - - virtual bool support_tls(); - - int addref(); - int release(); - - protected: - transport_layer_security* _tls; - t_shared_reference _shared; -}; - -class dtls_server_socket : public udp_server_socket { - public: - dtls_server_socket(transport_layer_security* tls); - virtual ~dtls_server_socket(); - - /** - * @brief close - * @param socket_t sock [IN] - * @param tls_context_t* tls_handle [IN] - * @return error code (see error.hpp) - * @remarks - * tls_svr_sock.accept(listen_socket, &cli_socket, &tls_context, &sockaddr, &sockaddrlen); - * // client connection established... - * // ... - * // socket closed - * tls_svr_sock.close(cli_socket, tls_context); - */ - virtual return_t close(socket_t sock, tls_context_t* tls_handle); - - /** - * @brief Tls accept - * @param socket_t clisock [IN] client socket - * @param tls_context_t** tls_handle [OUT] Tls context - * @return error code (see error.hpp) - */ - virtual return_t tls_accept(socket_t clisock, tls_context_t** tls_handle); virtual return_t tls_stop_accept(); /** * @brief read @@ -134,12 +75,8 @@ class dtls_server_socket : public udp_server_socket { virtual bool support_tls(); - int addref(); - int release(); - protected: transport_layer_security* _tls; - t_shared_reference _shared; }; } // namespace net diff --git a/sdk/net/tls/x509.cpp b/sdk/net/tls/x509.cpp index 68aa62c7..b60b0ebe 100644 --- a/sdk/net/tls/x509.cpp +++ b/sdk/net/tls/x509.cpp @@ -8,15 +8,39 @@ * Date Name Description */ +#include #include #include #include #include namespace hotplace { +using namespace crypto; using namespace io; namespace net { +static int set_cookie_generate_callback_routine(SSL* ssl, unsigned char* cookie, unsigned int* cookie_len) { + crypto_advisor* advisor = crypto_advisor::get_instance(); + binary_t bin; + unsigned cookie_size = 16; + advisor->get_cookie_secret(0, cookie_size, bin); + memcpy(cookie, &bin[0], cookie_size); + *cookie_len = cookie_size; + return 1; +} + +static int set_cookie_verify_callback_routine(SSL* ssl, const unsigned char* cookie, unsigned int cookie_len) { + int ret = 0; + crypto_advisor* advisor = crypto_advisor::get_instance(); + binary_t bin; + unsigned cookie_size = 16; + advisor->get_cookie_secret(0, cookie_size, bin); + if ((cookie_len == cookie_size) && (cookie_len == bin.size()) && (0 == memcmp(cookie, &bin[0], cookie_len))) { + ret = 1; + } + return ret; +} + return_t x509_open_simple(uint32 flag, SSL_CTX** context) { return_t ret = errorcode_t::success; SSL_CTX* ssl_ctx = nullptr; @@ -68,8 +92,8 @@ return_t x509_open_simple(uint32 flag, SSL_CTX** context) { option_flags = (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); /* TLS 1.2 and above */ } else if (x509cert_flag_dtls == flag) { option_flags = SSL_OP_NO_DTLSv1; - // SSL_CTX_set_cookie_generate_cb - // SSL_CTX_set_cookie_verify_cb + SSL_CTX_set_cookie_generate_cb(ssl_ctx, &set_cookie_generate_callback_routine); + SSL_CTX_set_cookie_verify_cb(ssl_ctx, &set_cookie_verify_callback_routine); } SSL_CTX_set_options(ssl_ctx, option_flags); SSL_CTX_set_verify(ssl_ctx, 0, nullptr); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1e237d33..7d5b6c7d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -42,12 +42,12 @@ add_subdirectory (ipaddr) add_subdirectory (tcpserver1) add_subdirectory (tcpserver2) add_subdirectory (tlsserver) -add_subdirectory (httpserver) +add_subdirectory (httpserver1) add_subdirectory (httpauth) add_subdirectory (httptest) add_subdirectory (hpack) add_subdirectory (httpserver2) -add_subdirectory (udpserver) +add_subdirectory (udpserver1) add_subdirectory (udpserver2) add_subdirectory (dtlsserver) diff --git a/test/dtlsserver/CMakeLists.txt b/test/dtlsserver/CMakeLists.txt index dd42c631..fe9ce62a 100644 --- a/test/dtlsserver/CMakeLists.txt +++ b/test/dtlsserver/CMakeLists.txt @@ -7,4 +7,7 @@ set (module dtlsserver) file (GLOB SOURCE_FILES *.cpp) +file (GLOB DATA_FILES *.crt *.key) +file (COPY ${DATA_FILES} DESTINATION ${PROJECT_SOURCE_DIR}/build/test/${module}/) + maketest (${module} SOURCE_FILES PROJECT_SDK_MODULE_DEPENDENCIES PROJECT_SDK_PLATFORM_DEPENDENCIES 0) diff --git a/test/dtlsserver/sample.cpp b/test/dtlsserver/sample.cpp index 5d278901..c0b10632 100644 --- a/test/dtlsserver/sample.cpp +++ b/test/dtlsserver/sample.cpp @@ -1,9 +1,10 @@ /* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ /** * @file {file} - * @author Soo Han, Kim (princeb612.kr@gmail.com) - * @desc see etc/dtlsclient - * @sa See in the following order : udpserver, udpserver2, dtlsserver + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc + * openssl s_client -dtls1_2 -connect 127.0.0.1:9000 + * @sa See in the following order : udpserver1, dtlsserver * * Revision History * Date Name Description @@ -34,13 +35,118 @@ t_shared_instance> _cmdline; #define FILENAME_RUN _T (".run") +return_t consume_routine(uint32 type, uint32 data_count, void* data_array[], CALLBACK_CONTROL* callback_control, void* user_context) { + return_t ret = errorcode_t::success; + net_session_socket_t* session_socket = (net_session_socket_t*)data_array[0]; + network_session* session = (network_session*)data_array[3]; + byte_t* buf = (byte_t*)data_array[1]; + size_t bufsize = (size_t)data_array[2]; + + basic_stream bs; + std::string message; + + switch (type) { + case mux_connect: + _logger->writeln("connect %d", session_socket->cli_socket); + break; + case mux_read: + case mux_dgram: + _logger->writeln("read %d msg [%.*s]", session_socket->cli_socket, (unsigned)bufsize, buf); + // dump_memory (buf, bufsize, &bs, 16, 4); + // std::cout << bs << std::endl; + session->send((char*)buf, bufsize); + break; + case mux_disconnect: + _logger->writeln("disconnect %d", session_socket->cli_socket); + break; + } + return ret; +} + return_t echo_server(void*) { return_t ret = errorcode_t::success; - // todo + const OPTION& option = _cmdline->value(); + + network_server netserver; + network_multiplexer_context_t* handle_ipv4 = nullptr; + network_multiplexer_context_t* handle_ipv6 = nullptr; + uint16 port = option.port; + + FILE* fp = fopen(FILENAME_RUN, "w"); + + fclose(fp); + + SSL_CTX* x509 = nullptr; + // http_protocol* http_prot = nullptr; + transport_layer_security* tls = nullptr; + dtls_server_socket* tls_socket = nullptr; + + __try2 { + // part of ssl certificate + ret = x509cert_open(x509cert_flag_tls, &x509, "server.crt", "server.key"); + _test_case.test(ret, __FUNCTION__, "x509"); + + SSL_CTX_set_cipher_list(x509, + "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256"); + // SSL_CTX_set_cipher_list (x509, + // "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256:!aNULL:!eNULL:!LOW:!EXP:!RC4"); + SSL_CTX_set_verify(x509, 0, nullptr); + + __try_new_catch(tls, new transport_layer_security(x509), ret, __leave2); + //__try_new_catch (http_prot, new http_protocol, ret, __leave2); + __try_new_catch(tls_socket, new dtls_server_socket(tls), ret, __leave2); + + server_conf conf; + conf.set(netserver_config_t::serverconf_concurrent_event, 1024) // concurrent (linux epoll concerns, windows ignore) + .set(netserver_config_t::serverconf_concurrent_tls_accept, 1) + .set(netserver_config_t::serverconf_concurrent_network, 2) + .set(netserver_config_t::serverconf_concurrent_consume, 2); + + // start server + netserver.open(&handle_ipv4, AF_INET, port, tls_socket, &conf, consume_routine, nullptr); + netserver.open(&handle_ipv6, AF_INET6, port, tls_socket, &conf, consume_routine, nullptr); + // netserver.add_protocol(handle_ipv4, http_prot); + + netserver.consumer_loop_run(handle_ipv4, 2); + netserver.consumer_loop_run(handle_ipv6, 2); + netserver.event_loop_run(handle_ipv4, 2); + netserver.event_loop_run(handle_ipv6, 2); + + while (true) { + msleep(1000); + +#if defined __linux__ + int chk = access(FILENAME_RUN, F_OK); + if (errorcode_t::success != chk) { + break; + } +#elif defined _WIN32 || defined _WIN64 + uint32 dwAttrib = GetFileAttributes(FILENAME_RUN); + if (INVALID_FILE_ATTRIBUTES == dwAttrib) { + break; + } +#endif + } + + netserver.event_loop_break(handle_ipv4, 2); + netserver.event_loop_break(handle_ipv6, 2); + netserver.consumer_loop_break(handle_ipv4, 2); + netserver.consumer_loop_break(handle_ipv6, 2); + } + __finally2 { + netserver.close(handle_ipv4); + netserver.close(handle_ipv6); + + // http_prot->release (); + tls_socket->release(); + tls->release(); + SSL_CTX_free(x509); + } + return ret; } -void test_dtlsserver() { +void run_server() { thread thread1(echo_server, nullptr); return_t ret = errorcode_t::success; @@ -74,7 +180,7 @@ int main(int argc, char** argv) { openssl_startup(); openssl_thread_setup(); - test_dtlsserver(); + run_server(); openssl_thread_end(); openssl_cleanup(); diff --git a/test/etc/udpclient.cpp b/test/etc/udpclient.cpp index 56b8efea..98d8c352 100644 --- a/test/etc/udpclient.cpp +++ b/test/etc/udpclient.cpp @@ -62,8 +62,10 @@ void client() { size_t cbread = 0; ret = cli.read(sock, nullptr, buffer, BUFFER_SIZE, &cbread); - bs.write(buffer, cbread); - _logger->writeln("received response: %s", bs.c_str()); + if (errorcode_t::success == ret) { + bs.write(buffer, cbread); + _logger->writeln("received response: %s", bs.c_str()); + } } __finally2 { cli.close(sock, nullptr); diff --git a/test/httpauth/sample.cpp b/test/httpauth/sample.cpp index ba5756d4..f14fccaa 100644 --- a/test/httpauth/sample.cpp +++ b/test/httpauth/sample.cpp @@ -119,7 +119,7 @@ return_t consume_routine(uint32 type, uint32 data_count, void* data_array[], CAL return ret; } -return_t echo_server(void*) { +return_t simple_http_server(void*) { const OPTION& option = _cmdline->value(); return_t ret = errorcode_t::success; @@ -287,8 +287,8 @@ return_t echo_server(void*) { return ret; } -void test_tlsserver() { - thread thread1(echo_server, nullptr); +void run_server() { + thread thread1(simple_http_server, nullptr); return_t ret = errorcode_t::success; __try2 { @@ -323,7 +323,7 @@ int main(int argc, char** argv) { openssl_startup(); openssl_thread_setup(); - test_tlsserver(); + run_server(); openssl_thread_end(); openssl_cleanup(); diff --git a/test/httpserver/CMakeLists.txt b/test/httpserver1/CMakeLists.txt similarity index 93% rename from test/httpserver/CMakeLists.txt rename to test/httpserver1/CMakeLists.txt index 334228d5..7331ad6b 100644 --- a/test/httpserver/CMakeLists.txt +++ b/test/httpserver1/CMakeLists.txt @@ -4,7 +4,7 @@ # Date Name Description # -set (module httpserver) +set (module httpserver1) file (GLOB SOURCE_FILES *.cpp) file (GLOB DATA_FILES *.crt *.key *.html) diff --git a/test/httpserver/index.html b/test/httpserver1/index.html similarity index 100% rename from test/httpserver/index.html rename to test/httpserver1/index.html diff --git a/test/httpserver/sample.cpp b/test/httpserver1/sample.cpp similarity index 98% rename from test/httpserver/sample.cpp rename to test/httpserver1/sample.cpp index ee8d9efd..a44e0762 100644 --- a/test/httpserver/sample.cpp +++ b/test/httpserver1/sample.cpp @@ -122,7 +122,7 @@ return_t consume_routine(uint32 type, uint32 data_count, void *data_array[], CAL return ret; } -return_t echo_server(void *) { +return_t simple_http_server(void *) { const OPTION &option = _cmdline->value(); return_t ret = errorcode_t::success; @@ -209,8 +209,8 @@ return_t echo_server(void *) { return ret; } -void test_tlsserver() { - thread thread1(echo_server, nullptr); +void run_server() { + thread thread1(simple_http_server, nullptr); return_t ret = errorcode_t::success; __try2 { @@ -245,7 +245,7 @@ int main(int argc, char **argv) { openssl_startup(); openssl_thread_setup(); - test_tlsserver(); + run_server(); openssl_thread_end(); openssl_cleanup(); diff --git a/test/httpserver/server.crt b/test/httpserver1/server.crt similarity index 100% rename from test/httpserver/server.crt rename to test/httpserver1/server.crt diff --git a/test/httpserver/server.key b/test/httpserver1/server.key similarity index 100% rename from test/httpserver/server.key rename to test/httpserver1/server.key diff --git a/test/httpserver2/sample.cpp b/test/httpserver2/sample.cpp index fe4fa461..1e275bd7 100644 --- a/test/httpserver2/sample.cpp +++ b/test/httpserver2/sample.cpp @@ -113,7 +113,7 @@ return_t consume_routine(uint32 type, uint32 data_count, void* data_array[], CAL return ret; } -return_t echo_server(void*) { +return_t simple_http2_server(void*) { const OPTION& option = _cmdline->value(); return_t ret = errorcode_t::success; @@ -291,8 +291,8 @@ return_t echo_server(void*) { return ret; } -void test_tlsserver() { - thread thread1(echo_server, nullptr); +void run_server() { + thread thread1(simple_http2_server, nullptr); return_t ret = errorcode_t::success; __try2 { @@ -327,7 +327,7 @@ int main(int argc, char** argv) { openssl_startup(); openssl_thread_setup(); - test_tlsserver(); + run_server(); openssl_thread_end(); openssl_cleanup(); diff --git a/test/httpserver3/CMakeLists.txt b/test/httpserver3/CMakeLists.txt index 8db68548..9d7d1c8f 100644 --- a/test/httpserver3/CMakeLists.txt +++ b/test/httpserver3/CMakeLists.txt @@ -7,4 +7,7 @@ set (module httpserver3) file (GLOB SOURCE_FILES *.cpp) +file (GLOB DATA_FILES *.crt *.key) +file (COPY ${DATA_FILES} DESTINATION ${PROJECT_SOURCE_DIR}/build/test/${module}/) + maketest (${module} SOURCE_FILES PROJECT_SDK_MODULE_DEPENDENCIES PROJECT_SDK_PLATFORM_DEPENDENCIES 0) diff --git a/test/httptest/sample.cpp b/test/httptest/sample.cpp index f179d797..75a23b69 100644 --- a/test/httptest/sample.cpp +++ b/test/httptest/sample.cpp @@ -566,7 +566,7 @@ void test_digest_access_authentication(const char *alg = nullptr, unsigned long ret = test_resolver("user", "password"); _test_case.assert((errorcode_t::success == ret), __FUNCTION__, "Digest Access Authentication Scheme (positive case) algorithm=%s", alg ? alg : ""); } else { - _test_case.test(errorcode_t::not_supported, __FUNCTION__, "%s require openssl-3.0"); + _test_case.test(errorcode_t::not_supported, __FUNCTION__, "require OpenSSL_version_num %08x", *ossl_minver); } } @@ -604,7 +604,7 @@ void test_rfc_digest_example() { http_request request; - // RFC 2617 "Circle Of Life" + // RFC 2617 3.5 Example "Circle Of Life" { digest_access_authentication_provider provider("testrealm@host.com"); const char *value = R"(Digest username="Mufasa", realm="testrealm@host.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", @@ -650,6 +650,7 @@ void test_rfc_digest_example() { // select user from digest_credentials where username = ''; #if 0 + // RFC 7616 3.9.2. Example with SHA-512-256, Charset, and Userhash // part of SHA-512-256 { // result mismatch ... what I missed ?? diff --git a/test/stream/sample.cpp b/test/stream/sample.cpp index f6399e08..62684adc 100644 --- a/test/stream/sample.cpp +++ b/test/stream/sample.cpp @@ -266,7 +266,7 @@ void test_vprintf() { _test_case.test(ret, __FUNCTION__, "vprintf (Ts... args)"); #else - _test_case.test(errorcode_t::not_supported, __FUNCTION__, "skip c++14"); + _test_case.test(errorcode_t::not_supported, __FUNCTION__, "at least c++14 required"); #endif } diff --git a/test/string/sample.cpp b/test/string/sample.cpp index 0ff3c81b..fc3153d4 100644 --- a/test/string/sample.cpp +++ b/test/string/sample.cpp @@ -143,7 +143,7 @@ void test_constexpr_obf() { _test_case.assert(true, __FUNCTION__, "obfuscate a string at compile time"); #else - _test_case.test(errorcode_t::not_supported, __FUNCTION__, "at least c++14 needed"); + _test_case.test(errorcode_t::not_supported, __FUNCTION__, "at least c++14 required"); #endif } diff --git a/test/tlsserver/sample.cpp b/test/tlsserver/sample.cpp index bf87623f..9755095f 100644 --- a/test/tlsserver/sample.cpp +++ b/test/tlsserver/sample.cpp @@ -80,7 +80,7 @@ return_t echo_server(void*) { SSL_CTX* x509 = nullptr; // http_protocol* http_prot = nullptr; transport_layer_security* tls = nullptr; - tls_server_socket* tls_server = nullptr; + tls_server_socket* tls_socket = nullptr; __try2 { // part of ssl certificate @@ -95,7 +95,7 @@ return_t echo_server(void*) { __try_new_catch(tls, new transport_layer_security(x509), ret, __leave2); //__try_new_catch (http_prot, new http_protocol, ret, __leave2); - __try_new_catch(tls_server, new tls_server_socket(tls), ret, __leave2); + __try_new_catch(tls_socket, new tls_server_socket(tls), ret, __leave2); server_conf conf; conf.set(netserver_config_t::serverconf_concurrent_event, 1024) // concurrent (linux epoll concerns, windows ignore) @@ -104,8 +104,8 @@ return_t echo_server(void*) { .set(netserver_config_t::serverconf_concurrent_consume, 2); // start server - netserver.open(&handle_ipv4, AF_INET, port, tls_server, &conf, consume_routine, nullptr); - netserver.open(&handle_ipv6, AF_INET6, port, tls_server, &conf, consume_routine, nullptr); + netserver.open(&handle_ipv4, AF_INET, port, tls_socket, &conf, consume_routine, nullptr); + netserver.open(&handle_ipv6, AF_INET6, port, tls_socket, &conf, consume_routine, nullptr); // netserver.add_protocol(handle_ipv4, http_prot); netserver.consumer_loop_run(handle_ipv4, 2); @@ -139,7 +139,7 @@ return_t echo_server(void*) { netserver.close(handle_ipv6); // http_prot->release (); - tls_server->release(); + tls_socket->release(); tls->release(); SSL_CTX_free(x509); } @@ -147,7 +147,7 @@ return_t echo_server(void*) { return ret; } -void test_tlsserver() { +void run_server() { thread thread1(echo_server, nullptr); return_t ret = errorcode_t::success; @@ -181,7 +181,7 @@ int main(int argc, char** argv) { openssl_startup(); openssl_thread_setup(); - test_tlsserver(); + run_server(); openssl_thread_end(); openssl_cleanup(); diff --git a/test/udpserver/CMakeLists.txt b/test/udpserver1/CMakeLists.txt similarity index 91% rename from test/udpserver/CMakeLists.txt rename to test/udpserver1/CMakeLists.txt index 54fd5714..55e21511 100644 --- a/test/udpserver/CMakeLists.txt +++ b/test/udpserver1/CMakeLists.txt @@ -4,7 +4,7 @@ # Date Name Description # -set (module udpserver) +set (module udpserver1) file (GLOB SOURCE_FILES *.cpp) maketest (${module} SOURCE_FILES PROJECT_SDK_MODULE_DEPENDENCIES PROJECT_SDK_PLATFORM_DEPENDENCIES 0) diff --git a/test/udpserver/sample.cpp b/test/udpserver1/sample.cpp similarity index 99% rename from test/udpserver/sample.cpp rename to test/udpserver1/sample.cpp index 9d3e653b..dacfb457 100644 --- a/test/udpserver/sample.cpp +++ b/test/udpserver1/sample.cpp @@ -83,7 +83,7 @@ return_t consume_routine(uint32 type, uint32 data_count, void* data_array[], CAL accept_context_t* accept_context = (accept_context_t*)user_context; return_t ret = errorcode_t::success; - if (mux_read == type) { + if (mux_dgram == type) { #if defined __linux__ multiplexer_context_t* handle = (multiplexer_context_t*)data_array[0]; int svr_cli = (int)(long)data_array[1]; diff --git a/test/udpserver2/sample.cpp b/test/udpserver2/sample.cpp index 578c3c69..b9dbfd84 100644 --- a/test/udpserver2/sample.cpp +++ b/test/udpserver2/sample.cpp @@ -1,9 +1,8 @@ /* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab smarttab : */ /** * @file {file} - * @author Soo Han, Kim (princeb612.kr@gmail.com) - * @desc see etc/udpclient - * @sa See in the following order : udpserver, udpserver2, dtlsserver + * @author Soo Han, Kim (princeb612.kr@gmail.com) + * @desc * * Revision History * Date Name Description @@ -34,11 +33,96 @@ t_shared_instance> _cmdline; #define FILENAME_RUN _T (".run") +ipaddr_acl acl; + +return_t accept_handler(socket_t socket, sockaddr_storage_t* client_addr, CALLBACK_CONTROL* control, void* parameter) { + return_t ret = errorcode_t::success; + bool result = false; + + acl.determine(client_addr, result); + if (control) { + *control = result ? CONTINUE_CONTROL : STOP_CONTROL; + } + return ret; +} + +return_t consume_routine(uint32 type, uint32 data_count, void* data_array[], CALLBACK_CONTROL* callback_control, void* user_context) { + return_t ret = errorcode_t::success; + net_session_socket_t* network_session = (net_session_socket_t*)data_array[0]; + + char* buf = (char*)data_array[1]; + size_t bufsize = (size_t)data_array[2]; + sockaddr_storage_t* addr = (sockaddr_storage_t*)data_array[5]; + switch (type) { + case multiplexer_event_type_t::mux_dgram: + _logger->writeln("read %d msg [%.*s]", network_session->event_socket, (unsigned)bufsize, buf); + sendto((socket_t)network_session->event_socket, buf, bufsize, 0, (sockaddr*)addr, sizeof(sockaddr_storage_t)); + break; + } + return ret; +} + return_t echo_server(void* param) { return_t ret = errorcode_t::success; const OPTION& option = _cmdline->value(); - // todo + network_server network_server; + network_multiplexer_context_t* handle_ipv4 = nullptr; + network_multiplexer_context_t* handle_ipv6 = nullptr; + udp_server_socket svr_sock; + uint16 port = option.port; + + FILE* fp = fopen(FILENAME_RUN, "w"); + + fclose(fp); + + __try2 { + acl.add_rule("127.0.0.1", true); + acl.add_rule("::1", true); + acl.setmode(ipaddr_acl_t::whitelist); + + server_conf conf; + conf.set(netserver_config_t::serverconf_concurrent_event, 1024) // concurrent (linux epoll concerns, windows ignore) + .set(netserver_config_t::serverconf_concurrent_tls_accept, 1) + .set(netserver_config_t::serverconf_concurrent_network, 2) + .set(netserver_config_t::serverconf_concurrent_consume, 2); + + network_server.open(&handle_ipv4, AF_INET, port, &svr_sock, &conf, consume_routine, nullptr); + network_server.open(&handle_ipv6, AF_INET6, port, &svr_sock, &conf, consume_routine, nullptr); + + network_server.set_accept_control_handler(handle_ipv4, accept_handler); + network_server.set_accept_control_handler(handle_ipv6, accept_handler); + + network_server.consumer_loop_run(handle_ipv4, 2); + network_server.consumer_loop_run(handle_ipv6, 2); + network_server.event_loop_run(handle_ipv4, 1); + network_server.event_loop_run(handle_ipv6, 1); + + while (true) { + msleep(1000); + +#if defined __linux__ + int chk = access(FILENAME_RUN, F_OK); + if (errorcode_t::success != chk) { + break; + } +#elif defined _WIN32 || defined _WIN64 + uint32 dwAttrib = GetFileAttributes(FILENAME_RUN); + if (INVALID_FILE_ATTRIBUTES == dwAttrib) { + break; + } +#endif + } + + network_server.event_loop_break(handle_ipv4, 1); + network_server.event_loop_break(handle_ipv6, 1); + network_server.consumer_loop_break(handle_ipv4, 2); + network_server.consumer_loop_break(handle_ipv6, 2); + } + __finally2 { + network_server.close(handle_ipv4); + network_server.close(handle_ipv6); + } return ret; }