diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index 545d6e1875..891d7cba52 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -28,11 +28,10 @@ if(SERVERS) add_subdirectory(mysql) add_subdirectory(readline) add_subdirectory(gsoap) - add_subdirectory(libzmq) - add_subdirectory(zmqpp) add_subdirectory(rapidjson) add_subdirectory(efsw) add_subdirectory(short_alloc) + add_subdirectory(argon2) endif() if(TOOLS) diff --git a/dep/PackageList.txt b/dep/PackageList.txt index f988ba2b48..20b512ce32 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -40,10 +40,6 @@ libMPQ (a library for reading MPQ files) https://github.com/mbroemme/libmpq/ Version: d59b4cf1d107b5f6a0f67d6bc545c6c6ebef3d74 -libzmq (ZeroMQ core engine in C++, implements ZMTP/3.1) - https://github.com/zeromq/libzmq - Version: 4.2.3 stable - MariaDB: https://mariadb.org/ Version: external @@ -77,10 +73,10 @@ zlib (A Massively Spiffy Yet Delicately Unobtrusive Compression Library) http://www.zlib.net/ Version: 1.2.12 -zmqpp (C++ binding for 0mq/zmq is a 'high-level' library that hides most of the c-style interface core 0mq provides.) - https://github.com/zeromq/zmqpp - Version: 3.2.0 17e9f6afa98f56ecac1e3f3eecbfc112357a6732 - MinHook (The Minimalistic x86/x64 API Hooking Library for Windows) https://github.com/TsudaKageyu/minhook Version: 0f25a2449b3cf878bcbdbf91b693c38149ecf029 + +argon2 + https://github.com/P-H-C/phc-winner-argon2 + Version: 62358ba diff --git a/dep/zmqpp/CMakeLists.txt b/dep/argon2/CMakeLists.txt similarity index 53% rename from dep/zmqpp/CMakeLists.txt rename to dep/argon2/CMakeLists.txt index 5eba9cb70e..e3a5dfa0eb 100644 --- a/dep/zmqpp/CMakeLists.txt +++ b/dep/argon2/CMakeLists.txt @@ -8,28 +8,34 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -file(GLOB_RECURSE sources_zmqpp zmqpp/*.cpp zmqpp/*.hpp zmqpp/*.h) +file(GLOB_RECURSE sources *.c) -add_library(zmqpp STATIC ${sources_zmqpp}) +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + list(REMOVE_ITEM sources + ${CMAKE_CURRENT_SOURCE_DIR}/argon2/opt.c) +else() + list(REMOVE_ITEM sources + ${CMAKE_CURRENT_SOURCE_DIR}/argon2/ref.c) +endif() -target_include_directories(zmqpp +add_library(argon2 STATIC + ${sources}) + +target_compile_definitions(argon2 + PRIVATE + -DARGON2_NO_THREADS) + +set_target_properties(argon2 PROPERTIES LINKER_LANGUAGE CXX) + +target_include_directories(argon2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(zmqpp +target_link_libraries(argon2 PRIVATE - trinity-dependency-interface - PUBLIC - libzmq) - -set_target_properties(zmqpp + trinity-dependency-interface) + +set_target_properties(argon2 PROPERTIES FOLDER "dep") - -target_compile_definitions(zmqpp - PRIVATE - -DBUILD_VERSION_MAJOR=3 - -DBUILD_VERSION_MINOR=2 - -DBUILD_VERSION_REVISION=0 - -DBUILD_VERSION="3.2.0") diff --git a/dep/argon2/LICENSE b/dep/argon2/LICENSE new file mode 100644 index 0000000000..fa611f7ac8 --- /dev/null +++ b/dep/argon2/LICENSE @@ -0,0 +1,314 @@ +Argon2 reference source code package - reference C implementations + +Copyright 2015 +Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + +You may use this work under the terms of a Creative Commons CC0 1.0 +License/Waiver or the Apache Public License 2.0, at your option. The terms of +these licenses can be found at: + +- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 +- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + +The terms of the licenses are reproduced below. + +-------------------------------------------------------------------------------- + +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +-------------------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/dep/argon2/argon2/argon2.c b/dep/argon2/argon2/argon2.c new file mode 100644 index 0000000000..795b429e71 --- /dev/null +++ b/dep/argon2/argon2/argon2.c @@ -0,0 +1,452 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "encoding.h" +#include "core.h" + +const char *argon2_type2string(argon2_type type, int uppercase) { + switch (type) { + case Argon2_d: + return uppercase ? "Argon2d" : "argon2d"; + case Argon2_i: + return uppercase ? "Argon2i" : "argon2i"; + case Argon2_id: + return uppercase ? "Argon2id" : "argon2id"; + } + + return NULL; +} + +int argon2_ctx(argon2_context *context, argon2_type type) { + /* 1. Validate all inputs */ + int result = validate_inputs(context); + uint32_t memory_blocks, segment_length; + argon2_instance_t instance; + + if (ARGON2_OK != result) { + return result; + } + + if (Argon2_d != type && Argon2_i != type && Argon2_id != type) { + return ARGON2_INCORRECT_TYPE; + } + + /* 2. Align memory size */ + /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ + memory_blocks = context->m_cost; + + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { + memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; + } + + segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); + /* Ensure that all segments have equal length */ + memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); + + instance.version = context->version; + instance.memory = NULL; + instance.passes = context->t_cost; + instance.memory_blocks = memory_blocks; + instance.segment_length = segment_length; + instance.lane_length = segment_length * ARGON2_SYNC_POINTS; + instance.lanes = context->lanes; + instance.threads = context->threads; + instance.type = type; + + if (instance.threads > instance.lanes) { + instance.threads = instance.lanes; + } + + /* 3. Initialization: Hashing inputs, allocating memory, filling first + * blocks + */ + result = initialize(&instance, context); + + if (ARGON2_OK != result) { + return result; + } + + /* 4. Filling memory */ + result = fill_memory_blocks(&instance); + + if (ARGON2_OK != result) { + return result; + } + /* 5. Finalization */ + finalize(context, &instance); + + return ARGON2_OK; +} + +int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version){ + + argon2_context context; + int result; + uint8_t *out; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (saltlen > ARGON2_MAX_SALT_LENGTH) { + return ARGON2_SALT_TOO_LONG; + } + + if (hashlen > ARGON2_MAX_OUTLEN) { + return ARGON2_OUTPUT_TOO_LONG; + } + + if (hashlen < ARGON2_MIN_OUTLEN) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + out = malloc(hashlen); + if (!out) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + context.out = (uint8_t *)out; + context.outlen = (uint32_t)hashlen; + context.pwd = CONST_CAST(uint8_t *)pwd; + context.pwdlen = (uint32_t)pwdlen; + context.salt = CONST_CAST(uint8_t *)salt; + context.saltlen = (uint32_t)saltlen; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.t_cost = t_cost; + context.m_cost = m_cost; + context.lanes = parallelism; + context.threads = parallelism; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = ARGON2_DEFAULT_FLAGS; + context.version = version; + + result = argon2_ctx(&context, type); + + if (result != ARGON2_OK) { + clear_internal_memory(out, hashlen); + free(out); + return result; + } + + /* if raw hash requested, write it */ + if (hash) { + memcpy(hash, out, hashlen); + } + + /* if encoding requested, write it */ + if (encoded && encodedlen) { + if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) { + clear_internal_memory(out, hashlen); /* wipe buffers if error */ + clear_internal_memory(encoded, encodedlen); + free(out); + return ARGON2_ENCODING_FAIL; + } + } + clear_internal_memory(out, hashlen); + free(out); + + return ARGON2_OK; +} + +int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_i, + ARGON2_VERSION_NUMBER); +} + +int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER); +} + +int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_d, + ARGON2_VERSION_NUMBER); +} + +int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER); +} + +int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_id, + ARGON2_VERSION_NUMBER); +} + +int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen) { + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_id, + ARGON2_VERSION_NUMBER); +} + +static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) { + size_t i; + uint8_t d = 0U; + + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (int)((1 & ((d - 1) >> 8)) - 1); +} + +int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type) { + + argon2_context ctx; + uint8_t *desired_result = NULL; + + int ret = ARGON2_OK; + + size_t encoded_len; + uint32_t max_field_len; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (encoded == NULL) { + return ARGON2_DECODING_FAIL; + } + + encoded_len = strlen(encoded); + if (encoded_len > UINT32_MAX) { + return ARGON2_DECODING_FAIL; + } + + /* No field can be longer than the encoded length */ + max_field_len = (uint32_t)encoded_len; + + ctx.saltlen = max_field_len; + ctx.outlen = max_field_len; + + ctx.salt = malloc(ctx.saltlen); + ctx.out = malloc(ctx.outlen); + if (!ctx.salt || !ctx.out) { + ret = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + ctx.pwd = (uint8_t *)pwd; + ctx.pwdlen = (uint32_t)pwdlen; + + ret = decode_string(&ctx, encoded, type); + if (ret != ARGON2_OK) { + goto fail; + } + + /* Set aside the desired result, and get a new buffer. */ + desired_result = ctx.out; + ctx.out = malloc(ctx.outlen); + if (!ctx.out) { + ret = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + ret = argon2_verify_ctx(&ctx, (char *)desired_result, type); + if (ret != ARGON2_OK) { + goto fail; + } + +fail: + free(ctx.salt); + free(ctx.out); + free(desired_result); + + return ret; +} + +int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_i); +} + +int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_d); +} + +int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_id); +} + +int argon2d_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_d); +} + +int argon2i_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_i); +} + +int argon2id_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_id); +} + +int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type) { + int ret = argon2_ctx(context, type); + if (ret != ARGON2_OK) { + return ret; + } + + if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) { + return ARGON2_VERIFY_MISMATCH; + } + + return ARGON2_OK; +} + +int argon2d_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_d); +} + +int argon2i_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_i); +} + +int argon2id_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_id); +} + +const char *argon2_error_message(int error_code) { + switch (error_code) { + case ARGON2_OK: + return "OK"; + case ARGON2_OUTPUT_PTR_NULL: + return "Output pointer is NULL"; + case ARGON2_OUTPUT_TOO_SHORT: + return "Output is too short"; + case ARGON2_OUTPUT_TOO_LONG: + return "Output is too long"; + case ARGON2_PWD_TOO_SHORT: + return "Password is too short"; + case ARGON2_PWD_TOO_LONG: + return "Password is too long"; + case ARGON2_SALT_TOO_SHORT: + return "Salt is too short"; + case ARGON2_SALT_TOO_LONG: + return "Salt is too long"; + case ARGON2_AD_TOO_SHORT: + return "Associated data is too short"; + case ARGON2_AD_TOO_LONG: + return "Associated data is too long"; + case ARGON2_SECRET_TOO_SHORT: + return "Secret is too short"; + case ARGON2_SECRET_TOO_LONG: + return "Secret is too long"; + case ARGON2_TIME_TOO_SMALL: + return "Time cost is too small"; + case ARGON2_TIME_TOO_LARGE: + return "Time cost is too large"; + case ARGON2_MEMORY_TOO_LITTLE: + return "Memory cost is too small"; + case ARGON2_MEMORY_TOO_MUCH: + return "Memory cost is too large"; + case ARGON2_LANES_TOO_FEW: + return "Too few lanes"; + case ARGON2_LANES_TOO_MANY: + return "Too many lanes"; + case ARGON2_PWD_PTR_MISMATCH: + return "Password pointer is NULL, but password length is not 0"; + case ARGON2_SALT_PTR_MISMATCH: + return "Salt pointer is NULL, but salt length is not 0"; + case ARGON2_SECRET_PTR_MISMATCH: + return "Secret pointer is NULL, but secret length is not 0"; + case ARGON2_AD_PTR_MISMATCH: + return "Associated data pointer is NULL, but ad length is not 0"; + case ARGON2_MEMORY_ALLOCATION_ERROR: + return "Memory allocation error"; + case ARGON2_FREE_MEMORY_CBK_NULL: + return "The free memory callback is NULL"; + case ARGON2_ALLOCATE_MEMORY_CBK_NULL: + return "The allocate memory callback is NULL"; + case ARGON2_INCORRECT_PARAMETER: + return "Argon2_Context context is NULL"; + case ARGON2_INCORRECT_TYPE: + return "There is no such version of Argon2"; + case ARGON2_OUT_PTR_MISMATCH: + return "Output pointer mismatch"; + case ARGON2_THREADS_TOO_FEW: + return "Not enough threads"; + case ARGON2_THREADS_TOO_MANY: + return "Too many threads"; + case ARGON2_MISSING_ARGS: + return "Missing arguments"; + case ARGON2_ENCODING_FAIL: + return "Encoding failed"; + case ARGON2_DECODING_FAIL: + return "Decoding failed"; + case ARGON2_THREAD_FAIL: + return "Threading failure"; + case ARGON2_DECODING_LENGTH_FAIL: + return "Some of encoded parameters are too long or too short"; + case ARGON2_VERIFY_MISMATCH: + return "The password does not match the supplied hash"; + default: + return "Unknown error code"; + } +} + +size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism, + uint32_t saltlen, uint32_t hashlen, argon2_type type) { + return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + + numlen(t_cost) + numlen(m_cost) + numlen(parallelism) + + b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1; +} diff --git a/dep/argon2/argon2/argon2.h b/dep/argon2/argon2/argon2.h new file mode 100644 index 0000000000..fc8682c2db --- /dev/null +++ b/dep/argon2/argon2/argon2.h @@ -0,0 +1,437 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_H +#define ARGON2_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Symbols visibility control */ +#ifdef A2_VISCTL +#define ARGON2_PUBLIC __attribute__((visibility("default"))) +#define ARGON2_LOCAL __attribute__ ((visibility ("hidden"))) +#elif _MSC_VER +#define ARGON2_PUBLIC __declspec(dllexport) +#define ARGON2_LOCAL +#else +#define ARGON2_PUBLIC +#define ARGON2_LOCAL +#endif + +/* + * Argon2 input parameter restrictions + */ + +/* Minimum and maximum number of lanes (degree of parallelism) */ +#define ARGON2_MIN_LANES UINT32_C(1) +#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) + +/* Minimum and maximum number of threads */ +#define ARGON2_MIN_THREADS UINT32_C(1) +#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) + +/* Number of synchronization points between lanes per pass */ +#define ARGON2_SYNC_POINTS UINT32_C(4) + +/* Minimum and maximum digest size in bytes */ +#define ARGON2_MIN_OUTLEN UINT32_C(4) +#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ +#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ + +#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) + +/* Minimum and maximum number of passes */ +#define ARGON2_MIN_TIME UINT32_C(1) +#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum password length in bytes */ +#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) +#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum associated data length in bytes */ +#define ARGON2_MIN_AD_LENGTH UINT32_C(0) +#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum salt length in bytes */ +#define ARGON2_MIN_SALT_LENGTH UINT32_C(8) +#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum key length in bytes */ +#define ARGON2_MIN_SECRET UINT32_C(0) +#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) + +/* Flags to determine which fields are securely wiped (default = no wipe). */ +#define ARGON2_DEFAULT_FLAGS UINT32_C(0) +#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) + +/* Global flag to determine if we are wiping internal memory buffers. This flag + * is defined in core.c and defaults to 1 (wipe internal memory). */ +extern int FLAG_clear_internal_memory; + +/* Error codes */ +typedef enum Argon2_ErrorCodes { + ARGON2_OK = 0, + + ARGON2_OUTPUT_PTR_NULL = -1, + + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + + ARGON2_OUT_PTR_MISMATCH = -27, + + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + + ARGON2_MISSING_ARGS = -30, + + ARGON2_ENCODING_FAIL = -31, + + ARGON2_DECODING_FAIL = -32, + + ARGON2_THREAD_FAIL = -33, + + ARGON2_DECODING_LENGTH_FAIL = -34, + + ARGON2_VERIFY_MISMATCH = -35 +} argon2_error_codes; + +/* Memory allocator types --- for external allocation */ +typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); +typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); + +/* Argon2 external data structures */ + +/* + ***** + * Context: structure to hold Argon2 inputs: + * output array and its length, + * password and its length, + * salt and its length, + * secret and its length, + * associated data and its length, + * number of passes, amount of used memory (in KBytes, can be rounded up a bit) + * number of parallel threads that will be run. + * All the parameters above affect the output hash value. + * Additionally, two function pointers can be provided to allocate and + * deallocate the memory (if NULL, memory will be allocated internally). + * Also, three flags indicate whether to erase password, secret as soon as they + * are pre-hashed (and thus not needed anymore), and the entire memory + ***** + * Simplest situation: you have output array out[8], password is stored in + * pwd[32], salt is stored in salt[16], you do not have keys nor associated + * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with + * 4 parallel lanes. + * You want to erase the password, but you're OK with last pass not being + * erased. You want to use the default memory allocator. + * Then you initialize: + Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) + */ +typedef struct Argon2_Context { + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + + uint32_t version; /* version number */ + + allocate_fptr allocate_cbk; /* pointer to memory allocator */ + deallocate_fptr free_cbk; /* pointer to memory deallocator */ + + uint32_t flags; /* array of bool options */ +} argon2_context; + +/* Argon2 primitive type */ +typedef enum Argon2_type { + Argon2_d = 0, + Argon2_i = 1, + Argon2_id = 2 +} argon2_type; + +/* Version of the algorithm */ +typedef enum Argon2_version { + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 +} argon2_version; + +/* + * Function that gives the string representation of an argon2_type. + * @param type The argon2_type that we want the string for + * @param uppercase Whether the string should have the first letter uppercase + * @return NULL if invalid type, otherwise the string representation. + */ +ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); + +/* + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ +ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); + +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +/** + * Hashes a password with Argon2i, producing a raw hash at @hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash - updated by the function + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, + const size_t pwdlen, argon2_type type); + +/** + * Argon2d: Version of Argon2 that picks memory blocks depending + * on the password and salt. Only for side-channel-free + * environment!! + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_ctx(argon2_context *context); + +/** + * Argon2i: Version of Argon2 that picks memory blocks + * independent on the password and salt. Good for side-channels, + * but worse w.r.t. tradeoff attacks if only one pass is used. + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_ctx(argon2_context *context); + +/** + * Argon2id: Version of Argon2 where the first half-pass over memory is + * password-independent, the rest are password-dependent (on the password and + * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and + * better with w.r.t. tradeoff attacks (similar to Argon2d). + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_ctx(argon2_context *context); + +/** + * Verify if a given password is correct for Argon2d hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2i hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2id hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context, + const char *hash); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type); + +/** + * Get the associated error message for given error code + * @return The error message associated with the given error code + */ +ARGON2_PUBLIC const char *argon2_error_message(int error_code); + +/** + * Returns the encoded hash length for the given input parameters + * @param t_cost Number of iterations + * @param m_cost Memory usage in kibibytes + * @param parallelism Number of threads; used to compute lanes + * @param saltlen Salt size in bytes + * @param hashlen Hash size in bytes + * @param type The argon2_type that we want the encoded length for + * @return The encoded hash length in bytes + */ +ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, + uint32_t parallelism, uint32_t saltlen, + uint32_t hashlen, argon2_type type); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/dep/argon2/argon2/blake2/blake2-impl.h b/dep/argon2/argon2/blake2/blake2-impl.h new file mode 100644 index 0000000000..241f0beb3b --- /dev/null +++ b/dep/argon2/argon2/blake2/blake2-impl.h @@ -0,0 +1,156 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef PORTABLE_BLAKE2_IMPL_H +#define PORTABLE_BLAKE2_IMPL_H + +#include +#include + +#if defined(_MSC_VER) +#define BLAKE2_INLINE __inline +#elif defined(__GNUC__) || defined(__clang__) +#define BLAKE2_INLINE __inline__ +#else +#define BLAKE2_INLINE +#endif + +/* Argon2 Team - Begin Code */ +/* + Not an exhaustive list, but should cover the majority of modern platforms + Additionally, the code will always be correct---this is only a performance + tweak. +*/ +#if (defined(__BYTE_ORDER__) && \ + (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \ + defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \ + defined(_M_ARM) +#define NATIVE_LITTLE_ENDIAN +#endif +/* Argon2 Team - End Code */ + +static BLAKE2_INLINE uint32_t load32(const void *src) { +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *)src; + uint32_t w = *p++; + w |= (uint32_t)(*p++) << 8; + w |= (uint32_t)(*p++) << 16; + w |= (uint32_t)(*p++) << 24; + return w; +#endif +} + +static BLAKE2_INLINE uint64_t load64(const void *src) { +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *)src; + uint64_t w = *p++; + w |= (uint64_t)(*p++) << 8; + w |= (uint64_t)(*p++) << 16; + w |= (uint64_t)(*p++) << 24; + w |= (uint64_t)(*p++) << 32; + w |= (uint64_t)(*p++) << 40; + w |= (uint64_t)(*p++) << 48; + w |= (uint64_t)(*p++) << 56; + return w; +#endif +} + +static BLAKE2_INLINE void store32(void *dst, uint32_t w) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +#endif +} + +static BLAKE2_INLINE void store64(void *dst, uint64_t w) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +#endif +} + +static BLAKE2_INLINE uint64_t load48(const void *src) { + const uint8_t *p = (const uint8_t *)src; + uint64_t w = *p++; + w |= (uint64_t)(*p++) << 8; + w |= (uint64_t)(*p++) << 16; + w |= (uint64_t)(*p++) << 24; + w |= (uint64_t)(*p++) << 32; + w |= (uint64_t)(*p++) << 40; + return w; +} + +static BLAKE2_INLINE void store48(void *dst, uint64_t w) { + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +} + +static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) { + return (w >> c) | (w << (32 - c)); +} + +static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) { + return (w >> c) | (w << (64 - c)); +} + +void clear_internal_memory(void *v, size_t n); + +#endif diff --git a/dep/argon2/argon2/blake2/blake2.h b/dep/argon2/argon2/blake2/blake2.h new file mode 100644 index 0000000000..9f97e1c1b3 --- /dev/null +++ b/dep/argon2/argon2/blake2/blake2.h @@ -0,0 +1,89 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef PORTABLE_BLAKE2_H +#define PORTABLE_BLAKE2_H + +#include "../argon2.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +enum blake2b_constant { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; + +#pragma pack(push, 1) +typedef struct __blake2b_param { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint64_t node_offset; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +} blake2b_param; +#pragma pack(pop) + +typedef struct __blake2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + unsigned buflen; + unsigned outlen; + uint8_t last_node; +} blake2b_state; + +/* Ensure param structs have not been wrongly padded */ +/* Poor man's static_assert */ +enum { + blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), + blake2_size_check_2 = + 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) +}; + +/* Streaming API */ +ARGON2_LOCAL int blake2b_init(blake2b_state *S, size_t outlen); +ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, + size_t keylen); +ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P); +ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, size_t inlen); +ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, size_t outlen); + +/* Simple API */ +ARGON2_LOCAL int blake2b(void *out, size_t outlen, const void *in, size_t inlen, + const void *key, size_t keylen); + +/* Argon2 Team - Begin Code */ +ARGON2_LOCAL int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); +/* Argon2 Team - End Code */ + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/dep/argon2/argon2/blake2/blake2b.c b/dep/argon2/argon2/blake2/blake2b.c new file mode 100644 index 0000000000..ca05df598d --- /dev/null +++ b/dep/argon2/argon2/blake2/blake2b.c @@ -0,0 +1,390 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = { + UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), + UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), + UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), + UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)}; + +static const unsigned int blake2b_sigma[12][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, +}; + +static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) { + S->f[1] = (uint64_t)-1; +} + +static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) { + if (S->last_node) { + blake2b_set_lastnode(S); + } + S->f[0] = (uint64_t)-1; +} + +static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S, + uint64_t inc) { + S->t[0] += inc; + S->t[1] += (S->t[0] < inc); +} + +static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) { + clear_internal_memory(S, sizeof(*S)); /* wipe */ + blake2b_set_lastblock(S); /* invalidate for further use */ +} + +static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) { + memset(S, 0, sizeof(*S)); + memcpy(S->h, blake2b_IV, sizeof(S->h)); +} + +int blake2b_init_param(blake2b_state *S, const blake2b_param *P) { + const unsigned char *p = (const unsigned char *)P; + unsigned int i; + + if (NULL == P || NULL == S) { + return -1; + } + + blake2b_init0(S); + /* IV XOR Parameter Block */ + for (i = 0; i < 8; ++i) { + S->h[i] ^= load64(&p[i * sizeof(S->h[i])]); + } + S->outlen = P->digest_length; + return 0; +} + +/* Sequential blake2b initialization */ +int blake2b_init(blake2b_state *S, size_t outlen) { + blake2b_param P; + + if (S == NULL) { + return -1; + } + + if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { + blake2b_invalidate_state(S); + return -1; + } + + /* Setup Parameter Block for unkeyed BLAKE2 */ + P.digest_length = (uint8_t)outlen; + P.key_length = 0; + P.fanout = 1; + P.depth = 1; + P.leaf_length = 0; + P.node_offset = 0; + P.node_depth = 0; + P.inner_length = 0; + memset(P.reserved, 0, sizeof(P.reserved)); + memset(P.salt, 0, sizeof(P.salt)); + memset(P.personal, 0, sizeof(P.personal)); + + return blake2b_init_param(S, &P); +} + +int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, + size_t keylen) { + blake2b_param P; + + if (S == NULL) { + return -1; + } + + if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { + blake2b_invalidate_state(S); + return -1; + } + + if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) { + blake2b_invalidate_state(S); + return -1; + } + + /* Setup Parameter Block for keyed BLAKE2 */ + P.digest_length = (uint8_t)outlen; + P.key_length = (uint8_t)keylen; + P.fanout = 1; + P.depth = 1; + P.leaf_length = 0; + P.node_offset = 0; + P.node_depth = 0; + P.inner_length = 0; + memset(P.reserved, 0, sizeof(P.reserved)); + memset(P.salt, 0, sizeof(P.salt)); + memset(P.personal, 0, sizeof(P.personal)); + + if (blake2b_init_param(S, &P) < 0) { + blake2b_invalidate_state(S); + return -1; + } + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); + blake2b_update(S, block, BLAKE2B_BLOCKBYTES); + /* Burn the key from stack */ + clear_internal_memory(block, BLAKE2B_BLOCKBYTES); + } + return 0; +} + +static void blake2b_compress(blake2b_state *S, const uint8_t *block) { + uint64_t m[16]; + uint64_t v[16]; + unsigned int i, r; + + for (i = 0; i < 16; ++i) { + m[i] = load64(block + i * sizeof(m[i])); + } + + for (i = 0; i < 8; ++i) { + v[i] = S->h[i]; + } + + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ S->t[0]; + v[13] = blake2b_IV[5] ^ S->t[1]; + v[14] = blake2b_IV[6] ^ S->f[0]; + v[15] = blake2b_IV[7] ^ S->f[1]; + +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while ((void)0, 0) + + for (r = 0; r < 12; ++r) { + ROUND(r); + } + + for (i = 0; i < 8; ++i) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } + +#undef G +#undef ROUND +} + +int blake2b_update(blake2b_state *S, const void *in, size_t inlen) { + const uint8_t *pin = (const uint8_t *)in; + + if (inlen == 0) { + return 0; + } + + /* Sanity check */ + if (S == NULL || in == NULL) { + return -1; + } + + /* Is this a reused state? */ + if (S->f[0] != 0) { + return -1; + } + + if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) { + /* Complete current block */ + size_t left = S->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + memcpy(&S->buf[left], pin, fill); + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); + S->buflen = 0; + inlen -= fill; + pin += fill; + /* Avoid buffer copies when possible */ + while (inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, pin); + inlen -= BLAKE2B_BLOCKBYTES; + pin += BLAKE2B_BLOCKBYTES; + } + } + memcpy(&S->buf[S->buflen], pin, inlen); + S->buflen += (unsigned int)inlen; + return 0; +} + +int blake2b_final(blake2b_state *S, void *out, size_t outlen) { + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + unsigned int i; + + /* Sanity checks */ + if (S == NULL || out == NULL || outlen < S->outlen) { + return -1; + } + + /* Is this a reused state? */ + if (S->f[0] != 0) { + return -1; + } + + blake2b_increment_counter(S, S->buflen); + blake2b_set_lastblock(S); + memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ + blake2b_compress(S, S->buf); + + for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ + store64(buffer + sizeof(S->h[i]) * i, S->h[i]); + } + + memcpy(out, buffer, S->outlen); + clear_internal_memory(buffer, sizeof(buffer)); + clear_internal_memory(S->buf, sizeof(S->buf)); + clear_internal_memory(S->h, sizeof(S->h)); + return 0; +} + +int blake2b(void *out, size_t outlen, const void *in, size_t inlen, + const void *key, size_t keylen) { + blake2b_state S; + int ret = -1; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + goto fail; + } + + if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) { + goto fail; + } + + if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) { + goto fail; + } + + if (keylen > 0) { + if (blake2b_init_key(&S, outlen, key, keylen) < 0) { + goto fail; + } + } else { + if (blake2b_init(&S, outlen) < 0) { + goto fail; + } + } + + if (blake2b_update(&S, in, inlen) < 0) { + goto fail; + } + ret = blake2b_final(&S, out, outlen); + +fail: + clear_internal_memory(&S, sizeof(S)); + return ret; +} + +/* Argon2 Team - Begin Code */ +int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { + uint8_t *out = (uint8_t *)pout; + blake2b_state blake_state; + uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; + int ret = -1; + + if (outlen > UINT32_MAX) { + goto fail; + } + + /* Ensure little-endian byte order! */ + store32(outlen_bytes, (uint32_t)outlen); + +#define TRY(statement) \ + do { \ + ret = statement; \ + if (ret < 0) { \ + goto fail; \ + } \ + } while ((void)0, 0) + + if (outlen <= BLAKE2B_OUTBYTES) { + TRY(blake2b_init(&blake_state, outlen)); + TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); + TRY(blake2b_update(&blake_state, in, inlen)); + TRY(blake2b_final(&blake_state, out, outlen)); + } else { + uint32_t toproduce; + uint8_t out_buffer[BLAKE2B_OUTBYTES]; + uint8_t in_buffer[BLAKE2B_OUTBYTES]; + TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); + TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); + TRY(blake2b_update(&blake_state, in, inlen)); + TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); + memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; + + while (toproduce > BLAKE2B_OUTBYTES) { + memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); + TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, + BLAKE2B_OUTBYTES, NULL, 0)); + memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + toproduce -= BLAKE2B_OUTBYTES / 2; + } + + memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); + TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL, + 0)); + memcpy(out, out_buffer, toproduce); + } +fail: + clear_internal_memory(&blake_state, sizeof(blake_state)); + return ret; +#undef TRY +} +/* Argon2 Team - End Code */ diff --git a/dep/argon2/argon2/blake2/blamka-round-opt.h b/dep/argon2/argon2/blake2/blamka-round-opt.h new file mode 100644 index 0000000000..2c8942e316 --- /dev/null +++ b/dep/argon2/argon2/blake2/blamka-round-opt.h @@ -0,0 +1,471 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef BLAKE_ROUND_MKA_OPT_H +#define BLAKE_ROUND_MKA_OPT_H + +#include "blake2-impl.h" + +#include +#if defined(__SSSE3__) +#include /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */ +#endif + +#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__)) +#include +#endif + +#if !defined(__AVX512F__) +#if !defined(__AVX2__) +#if !defined(__XOP__) +#if defined(__SSSE3__) +#define r16 \ + (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define r24 \ + (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) +#else /* defined(__SSE2__) */ +#define _mm_roti_epi64(r, c) \ + _mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c)))) +#endif +#else +#endif + +static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) { + const __m128i z = _mm_mul_epu32(x, y); + return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -32); \ + D1 = _mm_roti_epi64(D1, -32); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -24); \ + B1 = _mm_roti_epi64(B1, -24); \ + } while ((void)0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -16); \ + D1 = _mm_roti_epi64(D1, -16); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -63); \ + B1 = _mm_roti_epi64(B1, -63); \ + } while ((void)0, 0) + +#if defined(__SSSE3__) +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ + __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D1, D0, 8); \ + t1 = _mm_alignr_epi8(D0, D1, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ + __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D0, D1, 8); \ + t1 = _mm_alignr_epi8(D1, D0, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void)0, 0) +#else /* SSE2 */ +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = D0; \ + __m128i t1 = B0; \ + D0 = C0; \ + C0 = C1; \ + C1 = D0; \ + D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \ + D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \ + B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \ + B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0, t1; \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + t0 = B0; \ + t1 = D0; \ + B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \ + B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \ + D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \ + D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \ + } while ((void)0, 0) +#endif + +#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) +#else /* __AVX2__ */ + +#include + +#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) +#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x))) + +#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr32(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr24(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr32(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr24(B1); \ + } while((void)0, 0); + +#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr16(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr63(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr16(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr63(B1); \ + } while((void)0, 0); + +#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while((void)0, 0); + +#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while(0); + +#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while((void)0, 0); + +#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while((void)0, 0); + +#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + } while((void)0, 0); + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + } while((void)0, 0); + +#endif /* __AVX2__ */ + +#else /* __AVX512F__ */ + +#include + +#define ror64(x, n) _mm512_ror_epi64((x), (n)) + +static __m512i muladd(__m512i x, __m512i y) +{ + __m512i z = _mm512_mul_epu32(x, y); + return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ +\ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ +\ + D0 = ror64(D0, 32); \ + D1 = ror64(D1, 32); \ +\ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ +\ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ +\ + B0 = ror64(B0, 24); \ + B1 = ror64(B1, 24); \ + } while ((void)0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ +\ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ +\ + D0 = ror64(D0, 16); \ + D1 = ror64(D1, 16); \ +\ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ +\ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ +\ + B0 = ror64(B0, 63); \ + B1 = ror64(B1, 63); \ + } while ((void)0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ +\ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ +\ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ +\ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ +\ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) + +#define SWAP_HALVES(A0, A1) \ + do { \ + __m512i t0, t1; \ + t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \ + t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \ + A0 = t0; \ + A1 = t1; \ + } while((void)0, 0) + +#define SWAP_QUARTERS(A0, A1) \ + do { \ + SWAP_HALVES(A0, A1); \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + } while((void)0, 0) + +#define UNSWAP_QUARTERS(A0, A1) \ + do { \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + SWAP_HALVES(A0, A1); \ + } while((void)0, 0) + +#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \ + do { \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + SWAP_QUARTERS(A0, A1); \ + SWAP_QUARTERS(B0, B1); \ + SWAP_QUARTERS(C0, C1); \ + SWAP_QUARTERS(D0, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + UNSWAP_QUARTERS(A0, A1); \ + UNSWAP_QUARTERS(B0, B1); \ + UNSWAP_QUARTERS(C0, C1); \ + UNSWAP_QUARTERS(D0, D1); \ + } while ((void)0, 0) + +#endif /* __AVX512F__ */ +#endif /* BLAKE_ROUND_MKA_OPT_H */ diff --git a/dep/argon2/argon2/blake2/blamka-round-ref.h b/dep/argon2/argon2/blake2/blamka-round-ref.h new file mode 100644 index 0000000000..b8f2cf4713 --- /dev/null +++ b/dep/argon2/argon2/blake2/blamka-round-ref.h @@ -0,0 +1,56 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef BLAKE_ROUND_MKA_H +#define BLAKE_ROUND_MKA_H + +#include "blake2.h" +#include "blake2-impl.h" + +/* designed by the Lyra PHC team */ +static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { + const uint64_t m = UINT64_C(0xFFFFFFFF); + const uint64_t xy = (x & m) * (y & m); + return x + y + 2 * xy; +} + +#define G(a, b, c, d) \ + do { \ + a = fBlaMka(a, b); \ + d = rotr64(d ^ a, 32); \ + c = fBlaMka(c, d); \ + b = rotr64(b ^ c, 24); \ + a = fBlaMka(a, b); \ + d = rotr64(d ^ a, 16); \ + c = fBlaMka(c, d); \ + b = rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ + v12, v13, v14, v15) \ + do { \ + G(v0, v4, v8, v12); \ + G(v1, v5, v9, v13); \ + G(v2, v6, v10, v14); \ + G(v3, v7, v11, v15); \ + G(v0, v5, v10, v15); \ + G(v1, v6, v11, v12); \ + G(v2, v7, v8, v13); \ + G(v3, v4, v9, v14); \ + } while ((void)0, 0) + +#endif diff --git a/dep/argon2/argon2/core.c b/dep/argon2/argon2/core.c new file mode 100644 index 0000000000..65f0537694 --- /dev/null +++ b/dep/argon2/argon2/core.c @@ -0,0 +1,648 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +/*For memory wiping*/ +#ifdef _MSC_VER +#include +#include /* For SecureZeroMemory */ +#endif +#if defined __STDC_LIB_EXT1__ +#define __STDC_WANT_LIB_EXT1__ 1 +#endif +#define VC_GE_2005(version) (version >= 1400) + +/* for explicit_bzero() on glibc */ +#define _DEFAULT_SOURCE + +#include +#include +#include + +#include "core.h" +#include "thread.h" +#include "blake2/blake2.h" +#include "blake2/blake2-impl.h" + +#ifdef GENKAT +#include "genkat.h" +#endif + +#if defined(__clang__) +#if __has_attribute(optnone) +#define NOT_OPTIMIZED __attribute__((optnone)) +#endif +#elif defined(__GNUC__) +#define GCC_VERSION \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#if GCC_VERSION >= 40400 +#define NOT_OPTIMIZED __attribute__((optimize("O0"))) +#endif +#endif +#ifndef NOT_OPTIMIZED +#define NOT_OPTIMIZED +#endif + +/***************Instance and Position constructors**********/ +void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); } + +void copy_block(block *dst, const block *src) { + memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); +} + +void xor_block(block *dst, const block *src) { + int i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] ^= src->v[i]; + } +} + +static void load_block(block *dst, const void *input) { + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i])); + } +} + +static void store_block(void *output, const block *src) { + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); + } +} + +/***************Memory functions*****************/ + +int allocate_memory(const argon2_context *context, uint8_t **memory, + size_t num, size_t size) { + size_t memory_size = num*size; + if (memory == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + /* 1. Check for multiplication overflow */ + if (size != 0 && memory_size / size != num) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + /* 2. Try to allocate with appropriate allocator */ + if (context->allocate_cbk) { + (context->allocate_cbk)(memory, memory_size); + } else { + *memory = malloc(memory_size); + } + + if (*memory == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + return ARGON2_OK; +} + +void free_memory(const argon2_context *context, uint8_t *memory, + size_t num, size_t size) { + size_t memory_size = num*size; + clear_internal_memory(memory, memory_size); + if (context->free_cbk) { + (context->free_cbk)(memory, memory_size); + } else { + free(memory); + } +} + +#if defined(__OpenBSD__) +#define HAVE_EXPLICIT_BZERO 1 +#elif defined(__GLIBC__) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2,25) +#define HAVE_EXPLICIT_BZERO 1 +#endif +#endif + +void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) { +#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER) + SecureZeroMemory(v, n); +#elif defined memset_s + memset_s(v, n, 0, n); +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(v, n); +#else + static void *(*const volatile memset_sec)(void *, int, size_t) = &memset; + memset_sec(v, 0, n); +#endif +} + +/* Memory clear flag defaults to true. */ +int FLAG_clear_internal_memory = 1; +void clear_internal_memory(void *v, size_t n) { + if (FLAG_clear_internal_memory && v) { + secure_wipe_memory(v, n); + } +} + +void finalize(const argon2_context *context, argon2_instance_t *instance) { + if (context != NULL && instance != NULL) { + block blockhash; + uint32_t l; + + copy_block(&blockhash, instance->memory + instance->lane_length - 1); + + /* XOR the last blocks */ + for (l = 1; l < instance->lanes; ++l) { + uint32_t last_block_in_lane = + l * instance->lane_length + (instance->lane_length - 1); + xor_block(&blockhash, instance->memory + last_block_in_lane); + } + + /* Hash the result */ + { + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + store_block(blockhash_bytes, &blockhash); + blake2b_long(context->out, context->outlen, blockhash_bytes, + ARGON2_BLOCK_SIZE); + /* clear blockhash and blockhash_bytes */ + clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE); + clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); + } + +#ifdef GENKAT + print_tag(context->out, context->outlen); +#endif + + free_memory(context, (uint8_t *)instance->memory, + instance->memory_blocks, sizeof(block)); + } +} + +uint32_t index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane) { + /* + * Pass 0: + * This lane : all already finished segments plus already constructed + * blocks in this segment + * Other lanes : all already finished segments + * Pass 1+: + * This lane : (SYNC_POINTS - 1) last segments plus already constructed + * blocks in this segment + * Other lanes : (SYNC_POINTS - 1) last segments + */ + uint32_t reference_area_size; + uint64_t relative_position; + uint32_t start_position, absolute_position; + + if (0 == position->pass) { + /* First pass */ + if (0 == position->slice) { + /* First slice */ + reference_area_size = + position->index - 1; /* all but the previous */ + } else { + if (same_lane) { + /* The same lane => add current segment */ + reference_area_size = + position->slice * instance->segment_length + + position->index - 1; + } else { + reference_area_size = + position->slice * instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + } else { + /* Second pass */ + if (same_lane) { + reference_area_size = instance->lane_length - + instance->segment_length + position->index - + 1; + } else { + reference_area_size = instance->lane_length - + instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + + /* 1.2.4. Mapping pseudo_rand to 0.. and produce + * relative position */ + relative_position = pseudo_rand; + relative_position = relative_position * relative_position >> 32; + relative_position = reference_area_size - 1 - + (reference_area_size * relative_position >> 32); + + /* 1.2.5 Computing starting position */ + start_position = 0; + + if (0 != position->pass) { + start_position = (position->slice == ARGON2_SYNC_POINTS - 1) + ? 0 + : (position->slice + 1) * instance->segment_length; + } + + /* 1.2.6. Computing absolute position */ + absolute_position = (start_position + relative_position) % + instance->lane_length; /* absolute position */ + return absolute_position; +} + +/* Single-threaded version for p=1 case */ +static int fill_memory_blocks_st(argon2_instance_t *instance) { + uint32_t r, s, l; + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + for (l = 0; l < instance->lanes; ++l) { + argon2_position_t position = {r, l, (uint8_t)s, 0}; + fill_segment(instance, position); + } + } +#ifdef GENKAT + internal_kat(instance, r); /* Print all memory blocks */ +#endif + } + return ARGON2_OK; +} + +#if !defined(ARGON2_NO_THREADS) + +#ifdef _WIN32 +static unsigned __stdcall fill_segment_thr(void *thread_data) +#else +static void *fill_segment_thr(void *thread_data) +#endif +{ + argon2_thread_data *my_data = thread_data; + fill_segment(my_data->instance_ptr, my_data->pos); + argon2_thread_exit(); + return 0; +} + +/* Multi-threaded version for p > 1 case */ +static int fill_memory_blocks_mt(argon2_instance_t *instance) { + uint32_t r, s; + argon2_thread_handle_t *thread = NULL; + argon2_thread_data *thr_data = NULL; + int rc = ARGON2_OK; + + /* 1. Allocating space for threads */ + thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t)); + if (thread == NULL) { + rc = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + thr_data = calloc(instance->lanes, sizeof(argon2_thread_data)); + if (thr_data == NULL) { + rc = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + uint32_t l, ll; + + /* 2. Calling threads */ + for (l = 0; l < instance->lanes; ++l) { + argon2_position_t position; + + /* 2.1 Join a thread if limit is exceeded */ + if (l >= instance->threads) { + if (argon2_thread_join(thread[l - instance->threads])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + } + + /* 2.2 Create thread */ + position.pass = r; + position.lane = l; + position.slice = (uint8_t)s; + position.index = 0; + thr_data[l].instance_ptr = + instance; /* preparing the thread input */ + memcpy(&(thr_data[l].pos), &position, + sizeof(argon2_position_t)); + if (argon2_thread_create(&thread[l], &fill_segment_thr, + (void *)&thr_data[l])) { + /* Wait for already running threads */ + for (ll = 0; ll < l; ++ll) + argon2_thread_join(thread[ll]); + rc = ARGON2_THREAD_FAIL; + goto fail; + } + + /* fill_segment(instance, position); */ + /*Non-thread equivalent of the lines above */ + } + + /* 3. Joining remaining threads */ + for (l = instance->lanes - instance->threads; l < instance->lanes; + ++l) { + if (argon2_thread_join(thread[l])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + } + } + +#ifdef GENKAT + internal_kat(instance, r); /* Print all memory blocks */ +#endif + } + +fail: + if (thread != NULL) { + free(thread); + } + if (thr_data != NULL) { + free(thr_data); + } + return rc; +} + +#endif /* ARGON2_NO_THREADS */ + +int fill_memory_blocks(argon2_instance_t *instance) { + if (instance == NULL || instance->lanes == 0) { + return ARGON2_INCORRECT_PARAMETER; + } +#if defined(ARGON2_NO_THREADS) + return fill_memory_blocks_st(instance); +#else + return instance->threads == 1 ? + fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance); +#endif +} + +int validate_inputs(const argon2_context *context) { + if (NULL == context) { + return ARGON2_INCORRECT_PARAMETER; + } + + if (NULL == context->out) { + return ARGON2_OUTPUT_PTR_NULL; + } + + /* Validate output length */ + if (ARGON2_MIN_OUTLEN > context->outlen) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + if (ARGON2_MAX_OUTLEN < context->outlen) { + return ARGON2_OUTPUT_TOO_LONG; + } + + /* Validate password (required param) */ + if (NULL == context->pwd) { + if (0 != context->pwdlen) { + return ARGON2_PWD_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { + return ARGON2_PWD_TOO_SHORT; + } + + if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { + return ARGON2_PWD_TOO_LONG; + } + + /* Validate salt (required param) */ + if (NULL == context->salt) { + if (0 != context->saltlen) { + return ARGON2_SALT_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { + return ARGON2_SALT_TOO_SHORT; + } + + if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { + return ARGON2_SALT_TOO_LONG; + } + + /* Validate secret (optional param) */ + if (NULL == context->secret) { + if (0 != context->secretlen) { + return ARGON2_SECRET_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_SECRET > context->secretlen) { + return ARGON2_SECRET_TOO_SHORT; + } + if (ARGON2_MAX_SECRET < context->secretlen) { + return ARGON2_SECRET_TOO_LONG; + } + } + + /* Validate associated data (optional param) */ + if (NULL == context->ad) { + if (0 != context->adlen) { + return ARGON2_AD_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_AD_LENGTH > context->adlen) { + return ARGON2_AD_TOO_SHORT; + } + if (ARGON2_MAX_AD_LENGTH < context->adlen) { + return ARGON2_AD_TOO_LONG; + } + } + + /* Validate memory cost */ + if (ARGON2_MIN_MEMORY > context->m_cost) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + if (ARGON2_MAX_MEMORY < context->m_cost) { + return ARGON2_MEMORY_TOO_MUCH; + } + + if (context->m_cost < 8 * context->lanes) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + /* Validate time cost */ + if (ARGON2_MIN_TIME > context->t_cost) { + return ARGON2_TIME_TOO_SMALL; + } + + if (ARGON2_MAX_TIME < context->t_cost) { + return ARGON2_TIME_TOO_LARGE; + } + + /* Validate lanes */ + if (ARGON2_MIN_LANES > context->lanes) { + return ARGON2_LANES_TOO_FEW; + } + + if (ARGON2_MAX_LANES < context->lanes) { + return ARGON2_LANES_TOO_MANY; + } + + /* Validate threads */ + if (ARGON2_MIN_THREADS > context->threads) { + return ARGON2_THREADS_TOO_FEW; + } + + if (ARGON2_MAX_THREADS < context->threads) { + return ARGON2_THREADS_TOO_MANY; + } + + if (NULL != context->allocate_cbk && NULL == context->free_cbk) { + return ARGON2_FREE_MEMORY_CBK_NULL; + } + + if (NULL == context->allocate_cbk && NULL != context->free_cbk) { + return ARGON2_ALLOCATE_MEMORY_CBK_NULL; + } + + return ARGON2_OK; +} + +void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { + uint32_t l; + /* Make the first and second block in each lane as G(H0||0||i) or + G(H0||1||i) */ + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + for (l = 0; l < instance->lanes; ++l) { + + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->memory[l * instance->lane_length + 0], + blockhash_bytes); + + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->memory[l * instance->lane_length + 1], + blockhash_bytes); + } + clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); +} + +void initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type) { + blake2b_state BlakeHash; + uint8_t value[sizeof(uint32_t)]; + + if (NULL == context || NULL == blockhash) { + return; + } + + blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH); + + store32(&value, context->lanes); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->outlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->m_cost); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->t_cost); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->version); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, (uint32_t)type); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->pwdlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->pwd != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, + context->pwdlen); + + if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { + secure_wipe_memory(context->pwd, context->pwdlen); + context->pwdlen = 0; + } + } + + store32(&value, context->saltlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->salt != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->salt, + context->saltlen); + } + + store32(&value, context->secretlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->secret != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->secret, + context->secretlen); + + if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { + secure_wipe_memory(context->secret, context->secretlen); + context->secretlen = 0; + } + } + + store32(&value, context->adlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->ad != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->ad, + context->adlen); + } + + blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); +} + +int initialize(argon2_instance_t *instance, argon2_context *context) { + uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; + int result = ARGON2_OK; + + if (instance == NULL || context == NULL) + return ARGON2_INCORRECT_PARAMETER; + instance->context_ptr = context; + + /* 1. Memory allocation */ + result = allocate_memory(context, (uint8_t **)&(instance->memory), + instance->memory_blocks, sizeof(block)); + if (result != ARGON2_OK) { + return result; + } + + /* 2. Initial hashing */ + /* H_0 + 8 extra bytes to produce the first blocks */ + /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ + /* Hashing all inputs */ + initial_hash(blockhash, context, instance->type); + /* Zeroing 8 extra bytes */ + clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, + ARGON2_PREHASH_SEED_LENGTH - + ARGON2_PREHASH_DIGEST_LENGTH); + +#ifdef GENKAT + initial_kat(blockhash, context, instance->type); +#endif + + /* 3. Creating first blocks, we always have at least two blocks in a slice + */ + fill_first_blocks(blockhash, instance); + /* Clearing the hash */ + clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH); + + return ARGON2_OK; +} diff --git a/dep/argon2/argon2/core.h b/dep/argon2/argon2/core.h new file mode 100644 index 0000000000..78000ba9ed --- /dev/null +++ b/dep/argon2/argon2/core.h @@ -0,0 +1,228 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_CORE_H +#define ARGON2_CORE_H + +#include "argon2.h" + +#define CONST_CAST(x) (x)(uintptr_t) + +/**********************Argon2 internal constants*******************************/ + +enum argon2_core_constants { + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + + /* Number of pseudo-random values generated by one call to Blake in Argon2i + to + generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + + /* Pre-hashing digest length and its extension*/ + ARGON2_PREHASH_DIGEST_LENGTH = 64, + ARGON2_PREHASH_SEED_LENGTH = 72 +}; + +/*************************Argon2 internal data types***********************/ + +/* + * Structure for the (1KB) memory block implemented as 128 64-bit words. + * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no + * bounds checking). + */ +typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; + +/*****************Functions that work with the block******************/ + +/* Initialize each byte of the block with @in */ +void init_block_value(block *b, uint8_t in); + +/* Copy block @src to block @dst */ +void copy_block(block *dst, const block *src); + +/* XOR @src onto @dst bytewise */ +void xor_block(block *dst, const block *src); + +/* + * Argon2 instance: memory pointer, number of passes, amount of memory, type, + * and derived values. + * Used to evaluate the number and location of blocks to construct in each + * thread + */ +typedef struct Argon2_instance_t { + block *memory; /* Memory pointer */ + uint32_t version; + uint32_t passes; /* Number of passes */ + uint32_t memory_blocks; /* Number of blocks in memory */ + uint32_t segment_length; + uint32_t lane_length; + uint32_t lanes; + uint32_t threads; + argon2_type type; + int print_internals; /* whether to print the memory blocks */ + argon2_context *context_ptr; /* points back to original context */ +} argon2_instance_t; + +/* + * Argon2 position: where we construct the block right now. Used to distribute + * work between threads. + */ +typedef struct Argon2_position_t { + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; +} argon2_position_t; + +/*Struct that holds the inputs for thread handling FillSegment*/ +typedef struct Argon2_thread_data { + argon2_instance_t *instance_ptr; + argon2_position_t pos; +} argon2_thread_data; + +/*************************Argon2 core functions********************************/ + +/* Allocates memory to the given pointer, uses the appropriate allocator as + * specified in the context. Total allocated memory is num*size. + * @param context argon2_context which specifies the allocator + * @param memory pointer to the pointer to the memory + * @param size the size in bytes for each element to be allocated + * @param num the number of elements to be allocated + * @return ARGON2_OK if @memory is a valid pointer and memory is allocated + */ +int allocate_memory(const argon2_context *context, uint8_t **memory, + size_t num, size_t size); + +/* + * Frees memory at the given pointer, uses the appropriate deallocator as + * specified in the context. Also cleans the memory using clear_internal_memory. + * @param context argon2_context which specifies the deallocator + * @param memory pointer to buffer to be freed + * @param size the size in bytes for each element to be deallocated + * @param num the number of elements to be deallocated + */ +void free_memory(const argon2_context *context, uint8_t *memory, + size_t num, size_t size); + +/* Function that securely cleans the memory. This ignores any flags set + * regarding clearing memory. Usually one just calls clear_internal_memory. + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ +void secure_wipe_memory(void *v, size_t n); + +/* Function that securely clears the memory if FLAG_clear_internal_memory is + * set. If the flag isn't set, this function does nothing. + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ +void clear_internal_memory(void *v, size_t n); + +/* + * Computes absolute position of reference block in the lane following a skewed + * distribution and using a pseudo-random value as input + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rand 32-bit pseudo-random value used to determine the position + * @param same_lane Indicates if the block will be taken from the current lane. + * If so we can reference the current segment + * @pre All pointers must be valid + */ +uint32_t index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane); + +/* + * Function that validates all inputs against predefined restrictions and return + * an error code + * @param context Pointer to current Argon2 context + * @return ARGON2_OK if everything is all right, otherwise one of error codes + * (all defined in + */ +int validate_inputs(const argon2_context *context); + +/* + * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears + * password and secret if needed + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param blockhash Buffer for pre-hashing digest + * @param type Argon2 type + * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes + * allocated + */ +void initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type); + +/* + * Function creates first 2 blocks per lane + * @param instance Pointer to the current instance + * @param blockhash Pointer to the pre-hashing digest + * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values + */ +void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); + +/* + * Function allocates memory, hashes the inputs with Blake, and creates first + * two blocks. Returns the pointer to the main memory with 2 blocks per lane + * initialized + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param instance Current Argon2 instance + * @return Zero if successful, -1 if memory failed to allocate. @context->state + * will be modified if successful. + */ +int initialize(argon2_instance_t *instance, argon2_context *context); + +/* + * XORing the last block of each lane, hashing it, making the tag. Deallocates + * the memory. + * @param context Pointer to current Argon2 context (use only the out parameters + * from it) + * @param instance Pointer to current instance of Argon2 + * @pre instance->state must point to necessary amount of memory + * @pre context->out must point to outlen bytes of memory + * @pre if context->free_cbk is not NULL, it should point to a function that + * deallocates memory + */ +void finalize(const argon2_context *context, argon2_instance_t *instance); + +/* + * Function that fills the segment using previous segments also from other + * threads + * @param context current context + * @param instance Pointer to the current instance + * @param position Current position + * @pre all block pointers must be valid + */ +void fill_segment(const argon2_instance_t *instance, + argon2_position_t position); + +/* + * Function that fills the entire memory t_cost times based on the first two + * blocks in each lane + * @param instance Pointer to the current instance + * @return ARGON2_OK if successful, @context->state + */ +int fill_memory_blocks(argon2_instance_t *instance); + +#endif diff --git a/dep/argon2/argon2/encoding.c b/dep/argon2/argon2/encoding.c new file mode 100644 index 0000000000..12cfda4d05 --- /dev/null +++ b/dep/argon2/argon2/encoding.c @@ -0,0 +1,463 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include +#include +#include "encoding.h" +#include "core.h" + +/* + * Example code for a decoder and encoder of "hash strings", with Argon2 + * parameters. + * + * This code comprises three sections: + * + * -- The first section contains generic Base64 encoding and decoding + * functions. It is conceptually applicable to any hash function + * implementation that uses Base64 to encode and decode parameters, + * salts and outputs. It could be made into a library, provided that + * the relevant functions are made public (non-static) and be given + * reasonable names to avoid collisions with other functions. + * + * -- The second section is specific to Argon2. It encodes and decodes + * the parameters, salts and outputs. It does not compute the hash + * itself. + * + * The code was originally written by Thomas Pornin , + * to whom comments and remarks may be sent. It is released under what + * should amount to Public Domain or its closest equivalent; the + * following mantra is supposed to incarnate that fact with all the + * proper legal rituals: + * + * --------------------------------------------------------------------- + * This file is provided under the terms of Creative Commons CC0 1.0 + * Public Domain Dedication. To the extent possible under law, the + * author (Thomas Pornin) has waived all copyright and related or + * neighboring rights to this file. This work is published from: Canada. + * --------------------------------------------------------------------- + * + * Copyright (c) 2015 Thomas Pornin + */ + +/* ==================================================================== */ +/* + * Common code; could be shared between different hash functions. + * + * Note: the Base64 functions below assume that uppercase letters (resp. + * lowercase letters) have consecutive numerical codes, that fit on 8 + * bits. All modern systems use ASCII-compatible charsets, where these + * properties are true. If you are stuck with a dinosaur of a system + * that still defaults to EBCDIC then you already have much bigger + * interoperability issues to deal with. + */ + +/* + * Some macros for constant-time comparisons. These work over values in + * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true". + */ +#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF) +#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF) +#define GE(x, y) (GT(y, x) ^ 0xFF) +#define LT(x, y) GT(y, x) +#define LE(x, y) GE(y, x) + +/* + * Convert value x (0..63) to corresponding Base64 character. + */ +static int b64_byte_to_char(unsigned x) { + return (LT(x, 26) & (x + 'A')) | + (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | + (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') | + (EQ(x, 63) & '/'); +} + +/* + * Convert character c to the corresponding 6-bit value. If character c + * is not a Base64 character, then 0xFF (255) is returned. + */ +static unsigned b64_char_to_byte(int c) { + unsigned x; + + x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | + (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | + (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) | + (EQ(c, '/') & 63); + return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); +} + +/* + * Convert some bytes to Base64. 'dst_len' is the length (in characters) + * of the output buffer 'dst'; if that buffer is not large enough to + * receive the result (including the terminating 0), then (size_t)-1 + * is returned. Otherwise, the zero-terminated Base64 string is written + * in the buffer, and the output length (counted WITHOUT the terminating + * zero) is returned. + */ +static size_t to_base64(char *dst, size_t dst_len, const void *src, + size_t src_len) { + size_t olen; + const unsigned char *buf; + unsigned acc, acc_len; + + olen = (src_len / 3) << 2; + switch (src_len % 3) { + case 2: + olen++; + /* fall through */ + case 1: + olen += 2; + break; + } + if (dst_len <= olen) { + return (size_t)-1; + } + acc = 0; + acc_len = 0; + buf = (const unsigned char *)src; + while (src_len-- > 0) { + acc = (acc << 8) + (*buf++); + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + *dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + *dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F); + } + *dst++ = 0; + return olen; +} + +/* + * Decode Base64 chars into bytes. The '*dst_len' value must initially + * contain the length of the output buffer '*dst'; when the decoding + * ends, the actual number of decoded bytes is written back in + * '*dst_len'. + * + * Decoding stops when a non-Base64 character is encountered, or when + * the output buffer capacity is exceeded. If an error occurred (output + * buffer is too small, invalid last characters leading to unprocessed + * buffered bits), then NULL is returned; otherwise, the returned value + * points to the first non-Base64 character in the source stream, which + * may be the terminating zero. + */ +static const char *from_base64(void *dst, size_t *dst_len, const char *src) { + size_t len; + unsigned char *buf; + unsigned acc, acc_len; + + buf = (unsigned char *)dst; + len = 0; + acc = 0; + acc_len = 0; + for (;;) { + unsigned d; + + d = b64_char_to_byte(*src); + if (d == 0xFF) { + break; + } + src++; + acc = (acc << 6) + d; + acc_len += 6; + if (acc_len >= 8) { + acc_len -= 8; + if ((len++) >= *dst_len) { + return NULL; + } + *buf++ = (acc >> acc_len) & 0xFF; + } + } + + /* + * If the input length is equal to 1 modulo 4 (which is + * invalid), then there will remain 6 unprocessed bits; + * otherwise, only 0, 2 or 4 bits are buffered. The buffered + * bits must also all be zero. + */ + if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) { + return NULL; + } + *dst_len = len; + return src; +} + +/* + * Decode decimal integer from 'str'; the value is written in '*v'. + * Returned value is a pointer to the next non-decimal character in the + * string. If there is no digit at all, or the value encoding is not + * minimal (extra leading zeros), or the value does not fit in an + * 'unsigned long', then NULL is returned. + */ +static const char *decode_decimal(const char *str, unsigned long *v) { + const char *orig; + unsigned long acc; + + acc = 0; + for (orig = str;; str++) { + int c; + + c = *str; + if (c < '0' || c > '9') { + break; + } + c -= '0'; + if (acc > (ULONG_MAX / 10)) { + return NULL; + } + acc *= 10; + if ((unsigned long)c > (ULONG_MAX - acc)) { + return NULL; + } + acc += (unsigned long)c; + } + if (str == orig || (*orig == '0' && str != (orig + 1))) { + return NULL; + } + *v = acc; + return str; +} + +/* ==================================================================== */ +/* + * Code specific to Argon2. + * + * The code below applies the following format: + * + * $argon2[$v=]$m=,t=,p=$$ + * + * where is either 'd', 'id', or 'i', is a decimal integer (positive, + * fits in an 'unsigned long'), and is Base64-encoded data (no '=' padding + * characters, no newline or whitespace). + * + * The last two binary chunks (encoded in Base64) are, in that order, + * the salt and the output. Both are required. The binary salt length and the + * output length must be in the allowed ranges defined in argon2.h. + * + * The ctx struct must contain buffers large enough to hold the salt and pwd + * when it is fed into decode_string. + */ + +int decode_string(argon2_context *ctx, const char *str, argon2_type type) { + +/* check for prefix */ +#define CC(prefix) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) != 0) { \ + return ARGON2_DECODING_FAIL; \ + } \ + str += cc_len; \ + } while ((void)0, 0) + +/* optional prefix checking with supplied code */ +#define CC_opt(prefix, code) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) == 0) { \ + str += cc_len; \ + { code; } \ + } \ + } while ((void)0, 0) + +/* Decoding prefix into decimal */ +#define DECIMAL(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = dec_x; \ + } while ((void)0, 0) + + +/* Decoding prefix into uint32_t decimal */ +#define DECIMAL_U32(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL || dec_x > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = (uint32_t)dec_x; \ + } while ((void)0, 0) + + +/* Decoding base64 into a binary buffer */ +#define BIN(buf, max_len, len) \ + do { \ + size_t bin_len = (max_len); \ + str = from_base64(buf, &bin_len, str); \ + if (str == NULL || bin_len > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (len) = (uint32_t)bin_len; \ + } while ((void)0, 0) + + size_t maxsaltlen = ctx->saltlen; + size_t maxoutlen = ctx->outlen; + int validation_result; + const char* type_string; + + /* We should start with the argon2_type we are using */ + type_string = argon2_type2string(type, 0); + if (!type_string) { + return ARGON2_INCORRECT_TYPE; + } + + CC("$"); + CC(type_string); + + /* Reading the version number if the default is suppressed */ + ctx->version = ARGON2_VERSION_10; + CC_opt("$v=", DECIMAL_U32(ctx->version)); + + CC("$m="); + DECIMAL_U32(ctx->m_cost); + CC(",t="); + DECIMAL_U32(ctx->t_cost); + CC(",p="); + DECIMAL_U32(ctx->lanes); + ctx->threads = ctx->lanes; + + CC("$"); + BIN(ctx->salt, maxsaltlen, ctx->saltlen); + CC("$"); + BIN(ctx->out, maxoutlen, ctx->outlen); + + /* The rest of the fields get the default values */ + ctx->secret = NULL; + ctx->secretlen = 0; + ctx->ad = NULL; + ctx->adlen = 0; + ctx->allocate_cbk = NULL; + ctx->free_cbk = NULL; + ctx->flags = ARGON2_DEFAULT_FLAGS; + + /* On return, must have valid context */ + validation_result = validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + + /* Can't have any additional characters */ + if (*str == 0) { + return ARGON2_OK; + } else { + return ARGON2_DECODING_FAIL; + } +#undef CC +#undef CC_opt +#undef DECIMAL +#undef BIN +} + +int encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type) { +#define SS(str) \ + do { \ + size_t pp_len = strlen(str); \ + if (pp_len >= dst_len) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + memcpy(dst, str, pp_len + 1); \ + dst += pp_len; \ + dst_len -= pp_len; \ + } while ((void)0, 0) + +#define SX(x) \ + do { \ + char tmp[30]; \ + sprintf(tmp, "%lu", (unsigned long)(x)); \ + SS(tmp); \ + } while ((void)0, 0) + +#define SB(buf, len) \ + do { \ + size_t sb_len = to_base64(dst, dst_len, buf, len); \ + if (sb_len == (size_t)-1) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + dst += sb_len; \ + dst_len -= sb_len; \ + } while ((void)0, 0) + + const char* type_string = argon2_type2string(type, 0); + int validation_result = validate_inputs(ctx); + + if (!type_string) { + return ARGON2_ENCODING_FAIL; + } + + if (validation_result != ARGON2_OK) { + return validation_result; + } + + + SS("$"); + SS(type_string); + + SS("$v="); + SX(ctx->version); + + SS("$m="); + SX(ctx->m_cost); + SS(",t="); + SX(ctx->t_cost); + SS(",p="); + SX(ctx->lanes); + + SS("$"); + SB(ctx->salt, ctx->saltlen); + + SS("$"); + SB(ctx->out, ctx->outlen); + return ARGON2_OK; + +#undef SS +#undef SX +#undef SB +} + +size_t b64len(uint32_t len) { + size_t olen = ((size_t)len / 3) << 2; + + switch (len % 3) { + case 2: + olen++; + /* fall through */ + case 1: + olen += 2; + break; + } + + return olen; +} + +size_t numlen(uint32_t num) { + size_t len = 1; + while (num >= 10) { + ++len; + num = num / 10; + } + return len; +} + diff --git a/dep/argon2/argon2/encoding.h b/dep/argon2/argon2/encoding.h new file mode 100644 index 0000000000..7e83ec9285 --- /dev/null +++ b/dep/argon2/argon2/encoding.h @@ -0,0 +1,57 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ENCODING_H +#define ENCODING_H +#include "argon2.h" + +#define ARGON2_MAX_DECODED_LANES UINT32_C(255) +#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) +#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) + +/* +* encode an Argon2 hash string into the provided buffer. 'dst_len' +* contains the size, in characters, of the 'dst' buffer; if 'dst_len' +* is less than the number of required characters (including the +* terminating 0), then this function returns ARGON2_ENCODING_ERROR. +* +* on success, ARGON2_OK is returned. +*/ +int encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type); + +/* +* Decodes an Argon2 hash string into the provided structure 'ctx'. +* The only fields that must be set prior to this call are ctx.saltlen and +* ctx.outlen (which must be the maximal salt and out length values that are +* allowed), ctx.salt and ctx.out (which must be buffers of the specified +* length), and ctx.pwd and ctx.pwdlen which must hold a valid password. +* +* Invalid input string causes an error. On success, the ctx is valid and all +* fields have been initialized. +* +* Returned value is ARGON2_OK on success, other ARGON2_ codes on error. +*/ +int decode_string(argon2_context *ctx, const char *str, argon2_type type); + +/* Returns the length of the encoded byte stream with length len */ +size_t b64len(uint32_t len); + +/* Returns the length of the encoded number num */ +size_t numlen(uint32_t num); + +#endif diff --git a/dep/argon2/argon2/opt.c b/dep/argon2/argon2/opt.c new file mode 100644 index 0000000000..f6c20528e4 --- /dev/null +++ b/dep/argon2/argon2/opt.c @@ -0,0 +1,283 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "core.h" + +#include "blake2/blake2.h" +#include "blake2/blamka-round-opt.h" + +/* + * Function fills a new memory block and optionally XORs the old block over the new one. + * Memory must be initialized. + * @param state Pointer to the just produced block. Content will be updated(!) + * @param ref_block Pointer to the reference block + * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block + * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) + * @pre all block pointers must be valid + */ +#if defined(__AVX512F__) +static void fill_block(__m512i *state, const block *ref_block, + block *next_block, int with_xor) { + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i)); + block_XY[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i)); + } + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *)next_block->v + i, state[i]); + } +} +#elif defined(__AVX2__) +static void fill_block(__m256i *state, const block *ref_block, + block *next_block, int with_xor) { + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i)); + block_XY[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i)); + } + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *)next_block->v + i, state[i]); + } +} +#else +static void fill_block(__m128i *state, const block *ref_block, + block *next_block, int with_xor) { + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); + block_XY[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); + } + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *)next_block->v + i, state[i]); + } +} +#endif + +static void next_addresses(block *address_block, block *input_block) { + /*Temporary zero-initialized blocks*/ +#if defined(__AVX512F__) + __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK]; +#elif defined(__AVX2__) + __m256i zero_block[ARGON2_HWORDS_IN_BLOCK]; + __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK]; +#else + __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; + __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; +#endif + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + + /*Increasing index counter*/ + input_block->v[6]++; + + /*First iteration of G*/ + fill_block(zero_block, input_block, address_block, 0); + + /*Second iteration of G*/ + fill_block(zero2_block, address_block, address_block, 0); +} + +void fill_segment(const argon2_instance_t *instance, + argon2_position_t position) { + block *ref_block = NULL, *curr_block = NULL; + block address_block, input_block; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; +#if defined(__AVX512F__) + __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK]; +#elif defined(__AVX2__) + __m256i state[ARGON2_HWORDS_IN_BLOCK]; +#else + __m128i state[ARGON2_OWORDS_IN_BLOCK]; +#endif + int data_independent_addressing; + + if (instance == NULL) { + return; + } + + data_independent_addressing = + (instance->type == Argon2_i) || + (instance->type == Argon2_id && (position.pass == 0) && + (position.slice < ARGON2_SYNC_POINTS / 2)); + + if (data_independent_addressing) { + init_block_value(&input_block, 0); + + input_block.v[0] = position.pass; + input_block.v[1] = position.lane; + input_block.v[2] = position.slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + + /* Don't forget to generate the first block of addresses: */ + if (data_independent_addressing) { + next_addresses(&address_block, &input_block); + } + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + next_addresses(&address_block, &input_block); + } + pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } else { + pseudo_rand = instance->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = + instance->memory + instance->lane_length * ref_lane + ref_index; + curr_block = instance->memory + curr_offset; + if (ARGON2_VERSION_10 == instance->version) { + /* version 1.2.1 and earlier: overwrite, not XOR */ + fill_block(state, ref_block, curr_block, 0); + } else { + if(0 == position.pass) { + fill_block(state, ref_block, curr_block, 0); + } else { + fill_block(state, ref_block, curr_block, 1); + } + } + } +} diff --git a/dep/argon2/argon2/ref.c b/dep/argon2/argon2/ref.c new file mode 100644 index 0000000000..ad1cf461f9 --- /dev/null +++ b/dep/argon2/argon2/ref.c @@ -0,0 +1,194 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "core.h" + +#include "blake2/blamka-round-ref.h" +#include "blake2/blake2-impl.h" +#include "blake2/blake2.h" + + +/* + * Function fills a new memory block and optionally XORs the old block over the new one. + * @next_block must be initialized. + * @param prev_block Pointer to the previous block + * @param ref_block Pointer to the reference block + * @param next_block Pointer to the block to be constructed + * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) + * @pre all block pointers must be valid + */ +static void fill_block(const block *prev_block, const block *ref_block, + block *next_block, int with_xor) { + block blockR, block_tmp; + unsigned i; + + copy_block(&blockR, ref_block); + xor_block(&blockR, prev_block); + copy_block(&block_tmp, &blockR); + /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */ + if (with_xor) { + /* Saving the next block contents for XOR over: */ + xor_block(&block_tmp, next_block); + /* Now blockR = ref_block + prev_block and + block_tmp = ref_block + prev_block + next_block */ + } + + /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then + (16,17,..31)... finally (112,113,...127) */ + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND_NOMSG( + blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], + blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], + blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], + blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], + blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], + blockR.v[16 * i + 15]); + } + + /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then + (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ + for (i = 0; i < 8; i++) { + BLAKE2_ROUND_NOMSG( + blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], + blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], + blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], + blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], + blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], + blockR.v[2 * i + 113]); + } + + copy_block(next_block, &block_tmp); + xor_block(next_block, &blockR); +} + +static void next_addresses(block *address_block, block *input_block, + const block *zero_block) { + input_block->v[6]++; + fill_block(zero_block, input_block, address_block, 0); + fill_block(zero_block, address_block, address_block, 0); +} + +void fill_segment(const argon2_instance_t *instance, + argon2_position_t position) { + block *ref_block = NULL, *curr_block = NULL; + block address_block, input_block, zero_block; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index; + uint32_t i; + int data_independent_addressing; + + if (instance == NULL) { + return; + } + + data_independent_addressing = + (instance->type == Argon2_i) || + (instance->type == Argon2_id && (position.pass == 0) && + (position.slice < ARGON2_SYNC_POINTS / 2)); + + if (data_independent_addressing) { + init_block_value(&zero_block, 0); + init_block_value(&input_block, 0); + + input_block.v[0] = position.pass; + input_block.v[1] = position.lane; + input_block.v[2] = position.slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + + /* Don't forget to generate the first block of addresses: */ + if (data_independent_addressing) { + next_addresses(&address_block, &input_block, &zero_block); + } + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + next_addresses(&address_block, &input_block, &zero_block); + } + pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } else { + pseudo_rand = instance->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = + instance->memory + instance->lane_length * ref_lane + ref_index; + curr_block = instance->memory + curr_offset; + if (ARGON2_VERSION_10 == instance->version) { + /* version 1.2.1 and earlier: overwrite, not XOR */ + fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); + } else { + if(0 == position.pass) { + fill_block(instance->memory + prev_offset, ref_block, + curr_block, 0); + } else { + fill_block(instance->memory + prev_offset, ref_block, + curr_block, 1); + } + } + } +} diff --git a/dep/argon2/argon2/thread.c b/dep/argon2/argon2/thread.c new file mode 100644 index 0000000000..e099a00d21 --- /dev/null +++ b/dep/argon2/argon2/thread.c @@ -0,0 +1,57 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#if !defined(ARGON2_NO_THREADS) + +#include "thread.h" +#if defined(_WIN32) +#include +#endif + +int argon2_thread_create(argon2_thread_handle_t *handle, + argon2_thread_func_t func, void *args) { + if (NULL == handle || func == NULL) { + return -1; + } +#if defined(_WIN32) + *handle = _beginthreadex(NULL, 0, func, args, 0, NULL); + return *handle != 0 ? 0 : -1; +#else + return pthread_create(handle, NULL, func, args); +#endif +} + +int argon2_thread_join(argon2_thread_handle_t handle) { +#if defined(_WIN32) + if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) { + return CloseHandle((HANDLE)handle) != 0 ? 0 : -1; + } + return -1; +#else + return pthread_join(handle, NULL); +#endif +} + +void argon2_thread_exit(void) { +#if defined(_WIN32) + _endthreadex(0); +#else + pthread_exit(NULL); +#endif +} + +#endif /* ARGON2_NO_THREADS */ diff --git a/dep/argon2/argon2/thread.h b/dep/argon2/argon2/thread.h new file mode 100644 index 0000000000..49d88367b4 --- /dev/null +++ b/dep/argon2/argon2/thread.h @@ -0,0 +1,67 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_THREAD_H +#define ARGON2_THREAD_H + +#if !defined(ARGON2_NO_THREADS) + +/* + Here we implement an abstraction layer for the simpĺe requirements + of the Argon2 code. We only require 3 primitives---thread creation, + joining, and termination---so full emulation of the pthreads API + is unwarranted. Currently we wrap pthreads and Win32 threads. + + The API defines 2 types: the function pointer type, + argon2_thread_func_t, + and the type of the thread handle---argon2_thread_handle_t. +*/ +#if defined(_WIN32) +#include +typedef unsigned(__stdcall *argon2_thread_func_t)(void *); +typedef uintptr_t argon2_thread_handle_t; +#else +#include +typedef void *(*argon2_thread_func_t)(void *); +typedef pthread_t argon2_thread_handle_t; +#endif + +/* Creates a thread + * @param handle pointer to a thread handle, which is the output of this + * function. Must not be NULL. + * @param func A function pointer for the thread's entry point. Must not be + * NULL. + * @param args Pointer that is passed as an argument to @func. May be NULL. + * @return 0 if @handle and @func are valid pointers and a thread is successfully + * created. + */ +int argon2_thread_create(argon2_thread_handle_t *handle, + argon2_thread_func_t func, void *args); + +/* Waits for a thread to terminate + * @param handle Handle to a thread created with argon2_thread_create. + * @return 0 if @handle is a valid handle, and joining completed successfully. +*/ +int argon2_thread_join(argon2_thread_handle_t handle); + +/* Terminate the current thread. Must be run inside a thread created by + * argon2_thread_create. +*/ +void argon2_thread_exit(void); + +#endif /* ARGON2_NO_THREADS */ +#endif diff --git a/dep/libzmq/CMakeLists.txt b/dep/libzmq/CMakeLists.txt deleted file mode 100644 index a8fa5764cd..0000000000 --- a/dep/libzmq/CMakeLists.txt +++ /dev/null @@ -1,219 +0,0 @@ -# Use the bundled source on windows -set (libzmq_STAT_SRCS - src/address.cpp - src/client.cpp - src/clock.cpp - src/ctx.cpp - src/dealer.cpp - src/devpoll.cpp - src/dgram.cpp - src/dist.cpp - src/epoll.cpp - src/err.cpp - src/fq.cpp - src/io_object.cpp - src/io_thread.cpp - src/ip.cpp - src/ipc_address.cpp - src/ipc_connecter.cpp - src/ipc_listener.cpp - src/lb.cpp - src/kqueue.cpp - src/mailbox.cpp - src/mailbox_safe.cpp - src/mechanism.cpp - src/mechanism_base.cpp - src/metadata.cpp - src/msg.cpp - src/mtrie.cpp - src/object.cpp - src/options.cpp - src/own.cpp - src/null_mechanism.cpp - src/pair.cpp - src/pipe.cpp - src/plain_client.cpp - src/plain_server.cpp - src/poll.cpp - src/poller_base.cpp - src/pollset.cpp - src/proxy.cpp - src/pub.cpp - src/pull.cpp - src/push.cpp - src/random.cpp - src/raw_encoder.cpp - src/raw_decoder.cpp - src/reaper.cpp - src/rep.cpp - src/req.cpp - src/router.cpp - src/select.cpp - src/server.cpp - src/session_base.cpp - src/signaler.cpp - src/socket_base.cpp - src/socks.cpp - src/socks_connecter.cpp - src/stream.cpp - src/stream_engine.cpp - src/sub.cpp - src/tcp.cpp - src/tcp_address.cpp - src/tcp_connecter.cpp - src/tcp_listener.cpp - src/thread.cpp - src/trie.cpp - src/v1_decoder.cpp - src/v1_encoder.cpp - src/v2_decoder.cpp - src/v2_encoder.cpp - src/xpub.cpp - src/xsub.cpp - src/zmq.cpp - src/zmq_utils.cpp - src/decoder_allocators.cpp - src/socket_poller.cpp - src/timers.cpp - src/config.hpp - src/radio.cpp - src/dish.cpp - src/udp_engine.cpp - src/udp_address.cpp - src/scatter.cpp - src/gather.cpp - src/zap_client.cpp -) - -if (WIN32) - set(ZMQ_PLATFORM -DZMQ_HAVE_WINDOWS) -elseif (APPLE) - set(ZMQ_PLATFORM -DZMQ_HAVE_OSX) -elseif (UNIX) - set(ZMQ_PLATFORM -DZMQ_HAVE_LINUX) -endif() - -set (POLLER "") - -include (CheckFunctionExists) -include (CheckTypeSize) - - -if (POLLER STREQUAL "") - set (CMAKE_REQUIRED_INCLUDES sys/event.h) - check_function_exists (kqueue HAVE_KQUEUE) - set (CMAKE_REQUIRED_INCLUDES) - if (HAVE_KQUEUE) - set (POLLER "kqueue") - endif() -endif () - -if (POLLER STREQUAL "") - set (CMAKE_REQUIRED_INCLUDES sys/epoll.h) - check_function_exists (epoll_create HAVE_EPOLL) - set (CMAKE_REQUIRED_INCLUDES) - if (HAVE_EPOLL) - set (POLLER "epoll") - endif () -endif () - -if (POLLER STREQUAL "") - set (CMAKE_REQUIRED_INCLUDES sys/devpoll.h) - check_type_size ("struct pollfd" DEVPOLL) - set (CMAKE_REQUIRED_INCLUDES) - if (HAVE_DEVPOLL) - set (POLLER "devpoll") - endif () -endif () - -if (POLLER STREQUAL "") - set (CMAKE_REQUIRED_INCLUDES sys/pollset.h) - check_function_exists (pollset_create HAVE_POLLSET) - set (CMAKE_REQUIRED_INCLUDES) - if (HAVE_POLLSET) - set (POLLER "pollset") - endif() -endif () - -if (POLLER STREQUAL "") - set (CMAKE_REQUIRED_INCLUDES poll.h) - check_function_exists (poll HAVE_POLL) - set (CMAKE_REQUIRED_INCLUDES) - if (HAVE_POLL) - set (POLLER "poll") - endif () -endif () - -if (POLLER STREQUAL "") - if (WIN32) - set (CMAKE_REQUIRED_INCLUDES winsock2.h) - set (HAVE_SELECT 1) - else () - set (CMAKE_REQUIRED_INCLUDES sys/select.h) - check_function_exists (select HAVE_SELECT) - set (CMAKE_REQUIRED_INCLUDES) - endif () - if (HAVE_SELECT) - set (POLLER "select") - else () - message (FATAL_ERROR - "Could not autodetect polling method") - endif () -endif () - -if (POLLER STREQUAL "kqueue" - OR POLLER STREQUAL "epoll" - OR POLLER STREQUAL "devpoll" - OR POLLER STREQUAL "pollset" - OR POLLER STREQUAL "poll" - OR POLLER STREQUAL "select") - message (STATUS "Detected ${POLLER} polling method") - string (TOUPPER ${POLLER} UPPER_POLLER) -else () - message (FATAL_ERROR "Invalid polling method") -endif () - -include (CheckIncludeFiles) - -set(ADDITIONAL_DEFINES "") -check_include_files (ifaddrs.h HAVE_IFADDRS) -if (HAVE_IFADDRS) - list(APPEND ADDITIONAL_DEFINES -DZMQ_HAVE_IFADDRS) -endif() - -check_include_files (sys/uio.h HAVE_UIO) -if (HAVE_UIO) - list(APPEND ADDITIONAL_DEFINES -DZMQ_HAVE_UIO) -endif() - -check_include_files (sys/eventfd.h HAVE_EVENTFD) -if (HAVE_EVENTFD) - list(APPEND ADDITIONAL_DEFINES -DZMQ_HAVE_EVENTFD) -endif() - -add_library(libzmq STATIC ${libzmq_STAT_SRCS}) - -target_include_directories(libzmq - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/src) - -target_link_libraries(libzmq - PRIVATE - trinity-dependency-interface - PUBLIC - bzip2 - zlib) - -set_target_properties(libzmq - PROPERTIES - FOLDER - "dep") - -target_compile_definitions(libzmq - PUBLIC - -DZMQ_USE_${UPPER_POLLER} - -DZMQ_STATIC - ${ZMQ_PLATFORM} - ${ADDITIONAL_DEFINES}) diff --git a/dep/libzmq/include/zmq.h b/dep/libzmq/include/zmq.h deleted file mode 100644 index 89f78af36e..0000000000 --- a/dep/libzmq/include/zmq.h +++ /dev/null @@ -1,708 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . - - ************************************************************************* - NOTE to contributors. This file comprises the principal public contract - for ZeroMQ API users. Any change to this file supplied in a stable - release SHOULD not break existing applications. - In practice this means that the value of constants must not change, and - that old values may not be reused for new constants. - ************************************************************************* -*/ - -#ifndef __ZMQ_H_INCLUDED__ -#define __ZMQ_H_INCLUDED__ - -/* Version macros for compile-time API version detection */ -#define ZMQ_VERSION_MAJOR 4 -#define ZMQ_VERSION_MINOR 2 -#define ZMQ_VERSION_PATCH 3 - -#define ZMQ_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) -#define ZMQ_VERSION \ - ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH) - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined _WIN32_WCE -#include -#endif -#include -#include -#if defined _WIN32 -// Set target version to Windows Server 2008, Windows Vista or higher. -// Windows XP (0x0501) is supported but without client & server socket types. -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif - -#ifdef __MINGW32__ -// Require Windows XP or higher with MinGW for getaddrinfo(). -#if(_WIN32_WINNT >= 0x0501) -#else -#error You need at least Windows XP target -#endif -#endif -#include -#endif - -/* Handle DSO symbol visibility */ -#if defined _WIN32 -# if defined ZMQ_STATIC -# define ZMQ_EXPORT -# elif defined DLL_EXPORT -# define ZMQ_EXPORT __declspec(dllexport) -# else -# define ZMQ_EXPORT __declspec(dllimport) -# endif -#else -# if defined __SUNPRO_C || defined __SUNPRO_CC -# define ZMQ_EXPORT __global -# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER -# define ZMQ_EXPORT __attribute__ ((visibility("default"))) -# else -# define ZMQ_EXPORT -# endif -#endif - -/* Define integer types needed for event interface */ -#define ZMQ_DEFINED_STDINT 1 -#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS -# include -#elif defined _MSC_VER && _MSC_VER < 1600 -# ifndef int32_t - typedef __int32 int32_t; -# endif -# ifndef uint32_t - typedef unsigned __int32 uint32_t; -# endif -# ifndef uint16_t - typedef unsigned __int16 uint16_t; -# endif -# ifndef uint8_t - typedef unsigned __int8 uint8_t; -# endif -#else -# include -#endif - -// 32-bit AIX's pollfd struct members are called reqevents and rtnevents so it -// defines compatibility macros for them. Need to include that header first to -// stop build failures since zmq_pollset_t defines them as events and revents. -#ifdef ZMQ_HAVE_AIX - #include -#endif - - -/******************************************************************************/ -/* 0MQ errors. */ -/******************************************************************************/ - -/* A number random enough not to collide with different errno ranges on */ -/* different OSes. The assumption is that error_t is at least 32-bit type. */ -#define ZMQ_HAUSNUMERO 156384712 - -/* On Windows platform some of the standard POSIX errnos are not defined. */ -#ifndef ENOTSUP -#define ENOTSUP (ZMQ_HAUSNUMERO + 1) -#endif -#ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2) -#endif -#ifndef ENOBUFS -#define ENOBUFS (ZMQ_HAUSNUMERO + 3) -#endif -#ifndef ENETDOWN -#define ENETDOWN (ZMQ_HAUSNUMERO + 4) -#endif -#ifndef EADDRINUSE -#define EADDRINUSE (ZMQ_HAUSNUMERO + 5) -#endif -#ifndef EADDRNOTAVAIL -#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6) -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7) -#endif -#ifndef EINPROGRESS -#define EINPROGRESS (ZMQ_HAUSNUMERO + 8) -#endif -#ifndef ENOTSOCK -#define ENOTSOCK (ZMQ_HAUSNUMERO + 9) -#endif -#ifndef EMSGSIZE -#define EMSGSIZE (ZMQ_HAUSNUMERO + 10) -#endif -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11) -#endif -#ifndef ENETUNREACH -#define ENETUNREACH (ZMQ_HAUSNUMERO + 12) -#endif -#ifndef ECONNABORTED -#define ECONNABORTED (ZMQ_HAUSNUMERO + 13) -#endif -#ifndef ECONNRESET -#define ECONNRESET (ZMQ_HAUSNUMERO + 14) -#endif -#ifndef ENOTCONN -#define ENOTCONN (ZMQ_HAUSNUMERO + 15) -#endif -#ifndef ETIMEDOUT -#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16) -#endif -#ifndef EHOSTUNREACH -#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17) -#endif -#ifndef ENETRESET -#define ENETRESET (ZMQ_HAUSNUMERO + 18) -#endif - -/* Native 0MQ error codes. */ -#define EFSM (ZMQ_HAUSNUMERO + 51) -#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) -#define ETERM (ZMQ_HAUSNUMERO + 53) -#define EMTHREAD (ZMQ_HAUSNUMERO + 54) - -/* This function retrieves the errno as it is known to 0MQ library. The goal */ -/* of this function is to make the code 100% portable, including where 0MQ */ -/* compiled with certain CRT library (on Windows) is linked to an */ -/* application that uses different CRT library. */ -ZMQ_EXPORT int zmq_errno (void); - -/* Resolves system errors and 0MQ errors to human-readable string. */ -ZMQ_EXPORT const char *zmq_strerror (int errnum); - -/* Run-time API version detection */ -ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch); - -/******************************************************************************/ -/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */ -/******************************************************************************/ - -/* Context options */ -#define ZMQ_IO_THREADS 1 -#define ZMQ_MAX_SOCKETS 2 -#define ZMQ_SOCKET_LIMIT 3 -#define ZMQ_THREAD_PRIORITY 3 -#define ZMQ_THREAD_SCHED_POLICY 4 -#define ZMQ_MAX_MSGSZ 5 - -/* Default for new contexts */ -#define ZMQ_IO_THREADS_DFLT 1 -#define ZMQ_MAX_SOCKETS_DFLT 1023 -#define ZMQ_THREAD_PRIORITY_DFLT -1 -#define ZMQ_THREAD_SCHED_POLICY_DFLT -1 - -ZMQ_EXPORT void *zmq_ctx_new (void); -ZMQ_EXPORT int zmq_ctx_term (void *context); -ZMQ_EXPORT int zmq_ctx_shutdown (void *context); -ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval); -ZMQ_EXPORT int zmq_ctx_get (void *context, int option); - -/* Old (legacy) API */ -ZMQ_EXPORT void *zmq_init (int io_threads); -ZMQ_EXPORT int zmq_term (void *context); -ZMQ_EXPORT int zmq_ctx_destroy (void *context); - - -/******************************************************************************/ -/* 0MQ message definition. */ -/******************************************************************************/ - -/* Some architectures, like sparc64 and some variants of aarch64, enforce pointer - * alignment and raise sigbus on violations. Make sure applications allocate - * zmq_msg_t on addresses aligned on a pointer-size boundary to avoid this issue. - */ -typedef struct zmq_msg_t { -#if defined (__GNUC__) || defined ( __INTEL_COMPILER) || \ - (defined (__SUNPRO_C) && __SUNPRO_C >= 0x590) || \ - (defined (__SUNPRO_CC) && __SUNPRO_CC >= 0x590) - unsigned char _ [64] __attribute__ ((aligned (sizeof (void *)))); -#elif defined (_MSC_VER) && (defined (_M_X64) || defined (_M_ARM64)) - __declspec (align (8)) unsigned char _ [64]; -#elif defined (_MSC_VER) && (defined (_M_IX86) || defined (_M_ARM_ARMV7VE)) - __declspec (align (4)) unsigned char _ [64]; -#else - unsigned char _ [64]; -#endif -} zmq_msg_t; - -typedef void (zmq_free_fn) (void *data, void *hint); - -ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size); -ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data, - size_t size, zmq_free_fn *ffn, void *hint); -ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags); -ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags); -ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src); -ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src); -ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg); -ZMQ_EXPORT size_t zmq_msg_size (const zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_more (const zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_get (const zmq_msg_t *msg, int property); -ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int property, int optval); -ZMQ_EXPORT const char *zmq_msg_gets (const zmq_msg_t *msg, const char *property); - -/******************************************************************************/ -/* 0MQ socket definition. */ -/******************************************************************************/ - -/* Socket types. */ -#define ZMQ_PAIR 0 -#define ZMQ_PUB 1 -#define ZMQ_SUB 2 -#define ZMQ_REQ 3 -#define ZMQ_REP 4 -#define ZMQ_DEALER 5 -#define ZMQ_ROUTER 6 -#define ZMQ_PULL 7 -#define ZMQ_PUSH 8 -#define ZMQ_XPUB 9 -#define ZMQ_XSUB 10 -#define ZMQ_STREAM 11 - -/* Deprecated aliases */ -#define ZMQ_XREQ ZMQ_DEALER -#define ZMQ_XREP ZMQ_ROUTER - -/* Socket options. */ -#define ZMQ_AFFINITY 4 -#define ZMQ_ROUTING_ID 5 -#define ZMQ_SUBSCRIBE 6 -#define ZMQ_UNSUBSCRIBE 7 -#define ZMQ_RATE 8 -#define ZMQ_RECOVERY_IVL 9 -#define ZMQ_SNDBUF 11 -#define ZMQ_RCVBUF 12 -#define ZMQ_RCVMORE 13 -#define ZMQ_FD 14 -#define ZMQ_EVENTS 15 -#define ZMQ_TYPE 16 -#define ZMQ_LINGER 17 -#define ZMQ_RECONNECT_IVL 18 -#define ZMQ_BACKLOG 19 -#define ZMQ_RECONNECT_IVL_MAX 21 -#define ZMQ_MAXMSGSIZE 22 -#define ZMQ_SNDHWM 23 -#define ZMQ_RCVHWM 24 -#define ZMQ_MULTICAST_HOPS 25 -#define ZMQ_RCVTIMEO 27 -#define ZMQ_SNDTIMEO 28 -#define ZMQ_LAST_ENDPOINT 32 -#define ZMQ_ROUTER_MANDATORY 33 -#define ZMQ_TCP_KEEPALIVE 34 -#define ZMQ_TCP_KEEPALIVE_CNT 35 -#define ZMQ_TCP_KEEPALIVE_IDLE 36 -#define ZMQ_TCP_KEEPALIVE_INTVL 37 -#define ZMQ_IMMEDIATE 39 -#define ZMQ_XPUB_VERBOSE 40 -#define ZMQ_ROUTER_RAW 41 -#define ZMQ_IPV6 42 -#define ZMQ_MECHANISM 43 -#define ZMQ_PLAIN_SERVER 44 -#define ZMQ_PLAIN_USERNAME 45 -#define ZMQ_PLAIN_PASSWORD 46 -#define ZMQ_CURVE_SERVER 47 -#define ZMQ_CURVE_PUBLICKEY 48 -#define ZMQ_CURVE_SECRETKEY 49 -#define ZMQ_CURVE_SERVERKEY 50 -#define ZMQ_PROBE_ROUTER 51 -#define ZMQ_REQ_CORRELATE 52 -#define ZMQ_REQ_RELAXED 53 -#define ZMQ_CONFLATE 54 -#define ZMQ_ZAP_DOMAIN 55 -#define ZMQ_ROUTER_HANDOVER 56 -#define ZMQ_TOS 57 -#define ZMQ_CONNECT_ROUTING_ID 61 -#define ZMQ_GSSAPI_SERVER 62 -#define ZMQ_GSSAPI_PRINCIPAL 63 -#define ZMQ_GSSAPI_SERVICE_PRINCIPAL 64 -#define ZMQ_GSSAPI_PLAINTEXT 65 -#define ZMQ_HANDSHAKE_IVL 66 -#define ZMQ_SOCKS_PROXY 68 -#define ZMQ_XPUB_NODROP 69 -#define ZMQ_BLOCKY 70 -#define ZMQ_XPUB_MANUAL 71 -#define ZMQ_XPUB_WELCOME_MSG 72 -#define ZMQ_STREAM_NOTIFY 73 -#define ZMQ_INVERT_MATCHING 74 -#define ZMQ_HEARTBEAT_IVL 75 -#define ZMQ_HEARTBEAT_TTL 76 -#define ZMQ_HEARTBEAT_TIMEOUT 77 -#define ZMQ_XPUB_VERBOSER 78 -#define ZMQ_CONNECT_TIMEOUT 79 -#define ZMQ_TCP_MAXRT 80 -#define ZMQ_THREAD_SAFE 81 -#define ZMQ_MULTICAST_MAXTPDU 84 -#define ZMQ_VMCI_BUFFER_SIZE 85 -#define ZMQ_VMCI_BUFFER_MIN_SIZE 86 -#define ZMQ_VMCI_BUFFER_MAX_SIZE 87 -#define ZMQ_VMCI_CONNECT_TIMEOUT 88 -#define ZMQ_USE_FD 89 - -/* Message options */ -#define ZMQ_MORE 1 -#define ZMQ_SHARED 3 - -/* Send/recv options. */ -#define ZMQ_DONTWAIT 1 -#define ZMQ_SNDMORE 2 - -/* Security mechanisms */ -#define ZMQ_NULL 0 -#define ZMQ_PLAIN 1 -#define ZMQ_CURVE 2 -#define ZMQ_GSSAPI 3 - -/* RADIO-DISH protocol */ -#define ZMQ_GROUP_MAX_LENGTH 15 - -/* Deprecated options and aliases */ -#define ZMQ_IDENTITY ZMQ_ROUTING_ID -#define ZMQ_CONNECT_RID ZMQ_CONNECT_ROUTING_ID -#define ZMQ_TCP_ACCEPT_FILTER 38 -#define ZMQ_IPC_FILTER_PID 58 -#define ZMQ_IPC_FILTER_UID 59 -#define ZMQ_IPC_FILTER_GID 60 -#define ZMQ_IPV4ONLY 31 -#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE -#define ZMQ_NOBLOCK ZMQ_DONTWAIT -#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY -#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY - -/* Deprecated Message options */ -#define ZMQ_SRCFD 2 - -/******************************************************************************/ -/* 0MQ socket events and monitoring */ -/******************************************************************************/ - -/* Socket transport events (TCP, IPC and TIPC only) */ - -#define ZMQ_EVENT_CONNECTED 0x0001 -#define ZMQ_EVENT_CONNECT_DELAYED 0x0002 -#define ZMQ_EVENT_CONNECT_RETRIED 0x0004 -#define ZMQ_EVENT_LISTENING 0x0008 -#define ZMQ_EVENT_BIND_FAILED 0x0010 -#define ZMQ_EVENT_ACCEPTED 0x0020 -#define ZMQ_EVENT_ACCEPT_FAILED 0x0040 -#define ZMQ_EVENT_CLOSED 0x0080 -#define ZMQ_EVENT_CLOSE_FAILED 0x0100 -#define ZMQ_EVENT_DISCONNECTED 0x0200 -#define ZMQ_EVENT_MONITOR_STOPPED 0x0400 -#define ZMQ_EVENT_ALL 0xFFFF - -ZMQ_EXPORT void *zmq_socket (void *, int type); -ZMQ_EXPORT int zmq_close (void *s); -ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval, - size_t optvallen); -ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval, - size_t *optvallen); -ZMQ_EXPORT int zmq_bind (void *s, const char *addr); -ZMQ_EXPORT int zmq_connect (void *s, const char *addr); -ZMQ_EXPORT int zmq_unbind (void *s, const char *addr); -ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr); -ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events); - - -/******************************************************************************/ -/* Deprecated I/O multiplexing. Prefer using zmq_poller API */ -/******************************************************************************/ - -#define ZMQ_POLLIN 1 -#define ZMQ_POLLOUT 2 -#define ZMQ_POLLERR 4 -#define ZMQ_POLLPRI 8 - -typedef struct zmq_pollitem_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - short events; - short revents; -} zmq_pollitem_t; - -#define ZMQ_POLLITEMS_DFLT 16 - -ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); - -/******************************************************************************/ -/* Message proxying */ -/******************************************************************************/ - -ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture); -ZMQ_EXPORT int zmq_proxy_steerable (void *frontend, void *backend, void *capture, void *control); - -/******************************************************************************/ -/* Probe library capabilities */ -/******************************************************************************/ - -#define ZMQ_HAS_CAPABILITIES 1 -ZMQ_EXPORT int zmq_has (const char *capability); - -/* Deprecated aliases */ -#define ZMQ_STREAMER 1 -#define ZMQ_FORWARDER 2 -#define ZMQ_QUEUE 3 - -/* Deprecated methods */ -ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend); -ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags); -ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags); -struct iovec; -ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags); -ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags); - -/******************************************************************************/ -/* Encryption functions */ -/******************************************************************************/ - -/* Encode data with Z85 encoding. Returns encoded data */ -ZMQ_EXPORT char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size); - -/* Decode data with Z85 encoding. Returns decoded data */ -ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, const char *string); - -/* Generate z85-encoded public and private keypair with tweetnacl/libsodium. */ -/* Returns 0 on success. */ -ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); - -/* Derive the z85-encoded public key from the z85-encoded secret key. */ -/* Returns 0 on success. */ -ZMQ_EXPORT int zmq_curve_public (char *z85_public_key, const char *z85_secret_key); - -/******************************************************************************/ -/* Atomic utility methods */ -/******************************************************************************/ - -ZMQ_EXPORT void *zmq_atomic_counter_new (void); -ZMQ_EXPORT void zmq_atomic_counter_set (void *counter, int value); -ZMQ_EXPORT int zmq_atomic_counter_inc (void *counter); -ZMQ_EXPORT int zmq_atomic_counter_dec (void *counter); -ZMQ_EXPORT int zmq_atomic_counter_value (void *counter); -ZMQ_EXPORT void zmq_atomic_counter_destroy (void **counter_p); - - -/******************************************************************************/ -/* These functions are not documented by man pages -- use at your own risk. */ -/* If you need these to be part of the formal ZMQ API, then (a) write a man */ -/* page, and (b) write a test case in tests. */ -/******************************************************************************/ - -/* Helper functions are used by perf tests so that they don't have to care */ -/* about minutiae of time-related functions on different OS platforms. */ - -/* Starts the stopwatch. Returns the handle to the watch. */ -ZMQ_EXPORT void *zmq_stopwatch_start (void); - -/* Stops the stopwatch. Returns the number of microseconds elapsed since */ -/* the stopwatch was started. */ -ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_); - -/* Sleeps for specified number of seconds. */ -ZMQ_EXPORT void zmq_sleep (int seconds_); - -typedef void (zmq_thread_fn) (void*); - -/* Start a thread. Returns a handle to the thread. */ -ZMQ_EXPORT void *zmq_threadstart (zmq_thread_fn* func, void* arg); - -/* Wait for thread to complete then free up resources. */ -ZMQ_EXPORT void zmq_threadclose (void* thread); - - -/******************************************************************************/ -/* These functions are DRAFT and disabled in stable releases, and subject to */ -/* change at ANY time until declared stable. */ -/******************************************************************************/ - -#ifdef ZMQ_BUILD_DRAFT_API - -/* DRAFT Socket types. */ -#define ZMQ_SERVER 12 -#define ZMQ_CLIENT 13 -#define ZMQ_RADIO 14 -#define ZMQ_DISH 15 -#define ZMQ_GATHER 16 -#define ZMQ_SCATTER 17 -#define ZMQ_DGRAM 18 - -/* DRAFT Socket options. */ -#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90 -#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91 -#define ZMQ_BINDTODEVICE 92 -#define ZMQ_ZAP_ENFORCE_DOMAIN 93 - -/* DRAFT 0MQ socket events and monitoring */ -/* Unspecified system errors during handshake. Event value is an errno. */ -#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800 -/* Handshake complete successfully with successful authentication (if * - * enabled). Event value is unused. */ -#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000 -/* Protocol errors between ZMTP peers or between server and ZAP handler. * - * Event value is one of ZMQ_PROTOCOL_ERROR_* */ -#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000 -/* Failed authentication requests. Event value is the numeric ZAP status * - * code, i.e. 300, 400 or 500. */ -#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000 - -#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000 -#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001 -#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002 -#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR 0x10000015 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY 0x10000016 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME 0x10000017 -#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA 0x10000018 - -// the following two may be due to erroneous configuration of a peer -#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002 - -#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000 -#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001 -#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002 -#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003 -#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004 -#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005 - -/* DRAFT Context options */ -#define ZMQ_MSG_T_SIZE 6 -#define ZMQ_THREAD_AFFINITY_CPU_ADD 7 -#define ZMQ_THREAD_AFFINITY_CPU_REMOVE 8 -#define ZMQ_THREAD_NAME_PREFIX 9 - -/* DRAFT Socket methods. */ -ZMQ_EXPORT int zmq_join (void *s, const char *group); -ZMQ_EXPORT int zmq_leave (void *s, const char *group); - -/* DRAFT Msg methods. */ -ZMQ_EXPORT int zmq_msg_set_routing_id(zmq_msg_t *msg, uint32_t routing_id); -ZMQ_EXPORT uint32_t zmq_msg_routing_id(zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_set_group(zmq_msg_t *msg, const char *group); -ZMQ_EXPORT const char *zmq_msg_group(zmq_msg_t *msg); - -/* DRAFT Msg property names. */ -#define ZMQ_MSG_PROPERTY_ROUTING_ID "Routing-Id" -#define ZMQ_MSG_PROPERTY_SOCKET_TYPE "Socket-Type" -#define ZMQ_MSG_PROPERTY_USER_ID "User-Id" -#define ZMQ_MSG_PROPERTY_PEER_ADDRESS "Peer-Address" - -/******************************************************************************/ -/* Poller polling on sockets,fd and thread-safe sockets */ -/******************************************************************************/ - -#define ZMQ_HAVE_POLLER - -typedef struct zmq_poller_event_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - void *user_data; - short events; -} zmq_poller_event_t; - -ZMQ_EXPORT void *zmq_poller_new (void); -ZMQ_EXPORT int zmq_poller_destroy (void **poller_p); -ZMQ_EXPORT int zmq_poller_add (void *poller, void *socket, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify (void *poller, void *socket, short events); -ZMQ_EXPORT int zmq_poller_remove (void *poller, void *socket); -ZMQ_EXPORT int zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout); -ZMQ_EXPORT int zmq_poller_wait_all (void *poller, zmq_poller_event_t *events, int n_events, long timeout); - -#if defined _WIN32 -ZMQ_EXPORT int zmq_poller_add_fd (void *poller, SOCKET fd, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, SOCKET fd, short events); -ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, SOCKET fd); -#else -ZMQ_EXPORT int zmq_poller_add_fd (void *poller, int fd, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, int fd, short events); -ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, int fd); -#endif - -ZMQ_EXPORT int zmq_socket_get_peer_state (void *socket, - const void *routing_id, - size_t routing_id_size); - -/******************************************************************************/ -/* Scheduling timers */ -/******************************************************************************/ - -#define ZMQ_HAVE_TIMERS - -typedef void (zmq_timer_fn)(int timer_id, void *arg); - -ZMQ_EXPORT void *zmq_timers_new (void); -ZMQ_EXPORT int zmq_timers_destroy (void **timers_p); -ZMQ_EXPORT int zmq_timers_add (void *timers, size_t interval, zmq_timer_fn handler, void *arg); -ZMQ_EXPORT int zmq_timers_cancel (void *timers, int timer_id); -ZMQ_EXPORT int zmq_timers_set_interval (void *timers, int timer_id, size_t interval); -ZMQ_EXPORT int zmq_timers_reset (void *timers, int timer_id); -ZMQ_EXPORT long zmq_timers_timeout (void *timers); -ZMQ_EXPORT int zmq_timers_execute (void *timers); - -/******************************************************************************/ -/* GSSAPI definitions */ -/******************************************************************************/ - -/* GSSAPI principal name types */ -#define ZMQ_GSSAPI_NT_HOSTBASED 0 -#define ZMQ_GSSAPI_NT_USER_NAME 1 -#define ZMQ_GSSAPI_NT_KRB5_PRINCIPAL 2 - -#endif // ZMQ_BUILD_DRAFT_API - - -#undef ZMQ_EXPORT - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/dep/libzmq/include/zmq_utils.h b/dep/libzmq/include/zmq_utils.h deleted file mode 100644 index f29638d553..0000000000 --- a/dep/libzmq/include/zmq_utils.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/* This file is deprecated, and all its functionality provided by zmq.h */ -/* Note that -Wpedantic compilation requires GCC to avoid using its custom - extensions such as #warning, hence the trick below. Also, pragmas for - warnings or other messages are not standard, not portable, and not all - compilers even have an equivalent concept. - So in the worst case, this include file is treated as silently empty. */ - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER) -#if defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wcpp" -#pragma GCC diagnostic ignored "-Werror" -#pragma GCC diagnostic ignored "-Wall" -#endif -#pragma message("Warning: zmq_utils.h is deprecated. All its functionality is provided by zmq.h.") -#if defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic pop -#endif -#endif diff --git a/dep/libzmq/src/address.cpp b/dep/libzmq/src/address.cpp deleted file mode 100644 index 6e3d9954df..0000000000 --- a/dep/libzmq/src/address.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "address.hpp" -#include "ctx.hpp" -#include "err.hpp" -#include "tcp_address.hpp" -#include "udp_address.hpp" -#include "ipc_address.hpp" -#include "tipc_address.hpp" - -#if defined ZMQ_HAVE_VMCI -#include "vmci_address.hpp" -#endif - -#include -#include - -zmq::address_t::address_t ( - const std::string &protocol_, const std::string &address_, ctx_t *parent_) - : protocol (protocol_), - address (address_), - parent (parent_) -{ - memset (&resolved, 0, sizeof resolved); -} - -zmq::address_t::~address_t () -{ - if (protocol == "tcp") { - if (resolved.tcp_addr) { - LIBZMQ_DELETE(resolved.tcp_addr); - } - } - if (protocol == "udp") { - if (resolved.udp_addr) { - LIBZMQ_DELETE(resolved.udp_addr); - } - } -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - else - if (protocol == "ipc") { - if (resolved.ipc_addr) { - LIBZMQ_DELETE(resolved.ipc_addr); - } - } -#endif -#if defined ZMQ_HAVE_TIPC - else - if (protocol == "tipc") { - if (resolved.tipc_addr) { - LIBZMQ_DELETE(resolved.tipc_addr); - } - } -#endif -#if defined ZMQ_HAVE_VMCI - else - if (protocol == "vmci") { - if (resolved.vmci_addr) { - LIBZMQ_DELETE(resolved.vmci_addr); - } - } -#endif -} - -int zmq::address_t::to_string (std::string &addr_) const -{ - if (protocol == "tcp") { - if (resolved.tcp_addr) - return resolved.tcp_addr->to_string (addr_); - } - if (protocol == "udp") { - if (resolved.udp_addr) - return resolved.udp_addr->to_string (addr_); - } -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - else - if (protocol == "ipc") { - if (resolved.ipc_addr) - return resolved.ipc_addr->to_string (addr_); - } -#endif -#if defined ZMQ_HAVE_TIPC - else - if (protocol == "tipc") { - if (resolved.tipc_addr) - return resolved.tipc_addr->to_string (addr_); - } -#endif -#if defined ZMQ_HAVE_VMCI - else - if (protocol == "vmci") { - if (resolved.vmci_addr) - return resolved.vmci_addr->to_string (addr_); - } -#endif - - if (!protocol.empty () && !address.empty ()) { - std::stringstream s; - s << protocol << "://" << address; - addr_ = s.str (); - return 0; - } - addr_.clear (); - return -1; -} diff --git a/dep/libzmq/src/address.hpp b/dep/libzmq/src/address.hpp deleted file mode 100644 index 61feb4287a..0000000000 --- a/dep/libzmq/src/address.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ADDRESS_HPP_INCLUDED__ -#define __ZMQ_ADDRESS_HPP_INCLUDED__ - -#include - -namespace zmq -{ - class ctx_t; - class tcp_address_t; - class udp_address_t; -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - class ipc_address_t; -#endif -#if defined ZMQ_HAVE_LINUX - class tipc_address_t; -#endif -#if defined ZMQ_HAVE_VMCI - class vmci_address_t; -#endif - struct address_t { - address_t (const std::string &protocol_, const std::string &address_, ctx_t *parent_); - - ~address_t (); - - const std::string protocol; - const std::string address; - ctx_t *parent; - - // Protocol specific resolved address - union { - tcp_address_t *tcp_addr; - udp_address_t *udp_addr; -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - ipc_address_t *ipc_addr; -#endif -#if defined ZMQ_HAVE_LINUX - tipc_address_t *tipc_addr; -#endif -#if defined ZMQ_HAVE_VMCI - vmci_address_t *vmci_addr; -#endif - } resolved; - - int to_string (std::string &addr_) const; - }; -} - -#endif diff --git a/dep/libzmq/src/array.hpp b/dep/libzmq/src/array.hpp deleted file mode 100644 index c6b5d93d7c..0000000000 --- a/dep/libzmq/src/array.hpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ARRAY_INCLUDED__ -#define __ZMQ_ARRAY_INCLUDED__ - -#include -#include - -namespace zmq -{ - // Implementation of fast arrays with O(1) access, insertion and - // removal. The array stores pointers rather than objects. - // O(1) is achieved by making items inheriting from - // array_item_t class which internally stores the position - // in the array. - // The ID template argument is used to differentiate among arrays - // and thus let an object be stored in different arrays. - - // Base class for objects stored in the array. If you want to store - // same object in multiple arrays, each of those arrays has to have - // different ID. The item itself has to be derived from instantiations of - // array_item_t template for all relevant IDs. - - template class array_item_t - { - public: - - inline array_item_t () : - array_index (-1) - { - } - - // The destructor doesn't have to be virtual. It is made virtual - // just to keep ICC and code checking tools from complaining. - inline virtual ~array_item_t () - { - } - - inline void set_array_index (int index_) - { - array_index = index_; - } - - inline int get_array_index () - { - return array_index; - } - - private: - - int array_index; - - array_item_t (const array_item_t&); - const array_item_t &operator = (const array_item_t&); - }; - - - template class array_t - { - private: - - typedef array_item_t item_t; - - public: - - typedef typename std::vector ::size_type size_type; - - inline array_t () - { - } - - inline ~array_t () - { - } - - inline size_type size () - { - return items.size (); - } - - inline bool empty () - { - return items.empty (); - } - - inline T *&operator [] (size_type index_) - { - return items [index_]; - } - - inline void push_back (T *item_) - { - if (item_) - ((item_t*) item_)->set_array_index ((int) items.size ()); - items.push_back (item_); - } - - inline void erase (T *item_) { - erase (((item_t*) item_)->get_array_index ()); - } - - inline void erase (size_type index_) { - if (items.back ()) - ((item_t*) items.back ())->set_array_index ((int) index_); - items [index_] = items.back (); - items.pop_back (); - } - - inline void swap (size_type index1_, size_type index2_) - { - if (items [index1_]) - ((item_t*) items [index1_])->set_array_index ((int) index2_); - if (items [index2_]) - ((item_t*) items [index2_])->set_array_index ((int) index1_); - std::swap (items [index1_], items [index2_]); - } - - inline void clear () - { - items.clear (); - } - - inline size_type index (T *item_) - { - return (size_type) ((item_t*) item_)->get_array_index (); - } - - private: - - typedef std::vector items_t; - items_t items; - - array_t (const array_t&); - const array_t &operator = (const array_t&); - }; - -} - -#endif - diff --git a/dep/libzmq/src/atomic_counter.hpp b/dep/libzmq/src/atomic_counter.hpp deleted file mode 100644 index 23a7c50869..0000000000 --- a/dep/libzmq/src/atomic_counter.hpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ATOMIC_COUNTER_HPP_INCLUDED__ -#define __ZMQ_ATOMIC_COUNTER_HPP_INCLUDED__ - -#include "stdint.hpp" - -#if defined ZMQ_FORCE_MUTEXES -#define ZMQ_ATOMIC_COUNTER_MUTEX -#elif defined ZMQ_HAVE_ATOMIC_INTRINSICS -#define ZMQ_ATOMIC_COUNTER_INTRINSIC -#elif (defined __cplusplus && __cplusplus >= 201103L) -#define ZMQ_ATOMIC_COUNTER_CXX11 -#elif (defined __i386__ || defined __x86_64__) && defined __GNUC__ -#define ZMQ_ATOMIC_COUNTER_X86 -#elif defined __ARM_ARCH_7A__ && defined __GNUC__ -#define ZMQ_ATOMIC_COUNTER_ARM -#elif defined ZMQ_HAVE_WINDOWS -#define ZMQ_ATOMIC_COUNTER_WINDOWS -#elif (defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_NETBSD || defined ZMQ_HAVE_GNU) -#define ZMQ_ATOMIC_COUNTER_ATOMIC_H -#elif defined __tile__ -#define ZMQ_ATOMIC_COUNTER_TILE -#else -#define ZMQ_ATOMIC_COUNTER_MUTEX -#endif - -#if defined ZMQ_ATOMIC_COUNTER_MUTEX -#include "mutex.hpp" -#elif defined ZMQ_ATOMIC_COUNTER_CXX11 -#include -#elif defined ZMQ_ATOMIC_COUNTER_WINDOWS -#include "windows.hpp" -#elif defined ZMQ_ATOMIC_COUNTER_ATOMIC_H -#include -#elif defined ZMQ_ATOMIC_COUNTER_TILE -#include -#endif - -namespace zmq -{ - - // This class represents an integer that can be incremented/decremented - // in atomic fashion. - // - // In zmq::shared_message_memory_allocator a buffer with an atomic_counter_t - // at the start is allocated. If the class does not align to pointer size, - // access to pointers in structures in the buffer will cause SIGBUS on - // architectures that do not allow mis-aligned pointers (eg: SPARC). - // Force the compiler to align to pointer size, which will cause the object - // to grow from 4 bytes to 8 bytes on 64 bit architectures (when not using - // mutexes). - -#if defined (_MSC_VER) && (defined (_M_X64) || defined (_M_ARM64)) - class __declspec (align (8)) atomic_counter_t -#elif defined (_MSC_VER) && (defined (_M_IX86) || defined (_M_ARM_ARMV7VE)) - class __declspec (align (4)) atomic_counter_t -#else - class atomic_counter_t -#endif - { - public: - - typedef uint32_t integer_t; - - inline atomic_counter_t (integer_t value_ = 0) : - value (value_) - { - } - - inline ~atomic_counter_t () - { - } - - // Set counter value (not thread-safe). - inline void set (integer_t value_) - { - value = value_; - } - - // Atomic addition. Returns the old value. - inline integer_t add (integer_t increment_) - { - integer_t old_value; - -#if defined ZMQ_ATOMIC_COUNTER_WINDOWS - old_value = InterlockedExchangeAdd ((LONG*) &value, increment_); -#elif defined ZMQ_ATOMIC_COUNTER_INTRINSIC - old_value = __atomic_fetch_add(&value, increment_, __ATOMIC_ACQ_REL); -#elif defined ZMQ_ATOMIC_COUNTER_CXX11 - old_value = value.fetch_add(increment_, std::memory_order_acq_rel); -#elif defined ZMQ_ATOMIC_COUNTER_ATOMIC_H - integer_t new_value = atomic_add_32_nv (&value, increment_); - old_value = new_value - increment_; -#elif defined ZMQ_ATOMIC_COUNTER_TILE - old_value = arch_atomic_add (&value, increment_); -#elif defined ZMQ_ATOMIC_COUNTER_X86 - __asm__ volatile ( - "lock; xadd %0, %1 \n\t" - : "=r" (old_value), "=m" (value) - : "0" (increment_), "m" (value) - : "cc", "memory"); -#elif defined ZMQ_ATOMIC_COUNTER_ARM - integer_t flag, tmp; - __asm__ volatile ( - " dmb sy\n\t" - "1: ldrex %0, [%5]\n\t" - " add %2, %0, %4\n\t" - " strex %1, %2, [%5]\n\t" - " teq %1, #0\n\t" - " bne 1b\n\t" - " dmb sy\n\t" - : "=&r"(old_value), "=&r"(flag), "=&r"(tmp), "+Qo"(value) - : "Ir"(increment_), "r"(&value) - : "cc"); -#elif defined ZMQ_ATOMIC_COUNTER_MUTEX - sync.lock (); - old_value = value; - value += increment_; - sync.unlock (); -#else -#error atomic_counter is not implemented for this platform -#endif - return old_value; - } - - // Atomic subtraction. Returns false if the counter drops to zero. - inline bool sub (integer_t decrement) - { -#if defined ZMQ_ATOMIC_COUNTER_WINDOWS - LONG delta = - ((LONG) decrement); - integer_t old = InterlockedExchangeAdd ((LONG*) &value, delta); - return old - decrement != 0; -#elif defined ZMQ_ATOMIC_COUNTER_INTRINSIC - integer_t nv = __atomic_sub_fetch(&value, decrement, __ATOMIC_ACQ_REL); - return nv != 0; -#elif defined ZMQ_ATOMIC_COUNTER_CXX11 - integer_t old = value.fetch_sub(decrement, std::memory_order_acq_rel); - return old - decrement != 0; -#elif defined ZMQ_ATOMIC_COUNTER_ATOMIC_H - int32_t delta = - ((int32_t) decrement); - integer_t nv = atomic_add_32_nv (&value, delta); - return nv != 0; -#elif defined ZMQ_ATOMIC_COUNTER_TILE - int32_t delta = - ((int32_t) decrement); - integer_t nv = arch_atomic_add (&value, delta); - return nv != 0; -#elif defined ZMQ_ATOMIC_COUNTER_X86 - integer_t oldval = -decrement; - volatile integer_t *val = &value; - __asm__ volatile ("lock; xaddl %0,%1" - : "=r" (oldval), "=m" (*val) - : "0" (oldval), "m" (*val) - : "cc", "memory"); - return oldval != decrement; -#elif defined ZMQ_ATOMIC_COUNTER_ARM - integer_t old_value, flag, tmp; - __asm__ volatile ( - " dmb sy\n\t" - "1: ldrex %0, [%5]\n\t" - " sub %2, %0, %4\n\t" - " strex %1, %2, [%5]\n\t" - " teq %1, #0\n\t" - " bne 1b\n\t" - " dmb sy\n\t" - : "=&r"(old_value), "=&r"(flag), "=&r"(tmp), "+Qo"(value) - : "Ir"(decrement), "r"(&value) - : "cc"); - return old_value - decrement != 0; -#elif defined ZMQ_ATOMIC_COUNTER_MUTEX - sync.lock (); - value -= decrement; - bool result = value ? true : false; - sync.unlock (); - return result; -#else -#error atomic_counter is not implemented for this platform -#endif - } - - inline integer_t get () const - { - return value; - } - - private: - -#if defined ZMQ_ATOMIC_COUNTER_CXX11 - std::atomic value; -#else - volatile integer_t value; -#endif - -#if defined ZMQ_ATOMIC_COUNTER_MUTEX - mutex_t sync; -#endif - -#if ! defined ZMQ_ATOMIC_COUNTER_CXX11 - atomic_counter_t (const atomic_counter_t&); - const atomic_counter_t& operator = (const atomic_counter_t&); -#endif -#if defined (__GNUC__) || defined ( __INTEL_COMPILER) || \ - (defined (__SUNPRO_C) && __SUNPRO_C >= 0x590) || \ - (defined (__SUNPRO_CC) && __SUNPRO_CC >= 0x590) - } __attribute__ ((aligned (sizeof (void *)))); -#else - }; -#endif - -} - -// Remove macros local to this file. -#undef ZMQ_ATOMIC_COUNTER_MUTEX -#undef ZMQ_ATOMIC_COUNTER_INTRINSIC -#undef ZMQ_ATOMIC_COUNTER_CXX11 -#undef ZMQ_ATOMIC_COUNTER_X86 -#undef ZMQ_ATOMIC_COUNTER_ARM -#undef ZMQ_ATOMIC_COUNTER_WINDOWS -#undef ZMQ_ATOMIC_COUNTER_ATOMIC_H -#undef ZMQ_ATOMIC_COUNTER_TILE - -#endif diff --git a/dep/libzmq/src/atomic_ptr.hpp b/dep/libzmq/src/atomic_ptr.hpp deleted file mode 100644 index 53b0d5da17..0000000000 --- a/dep/libzmq/src/atomic_ptr.hpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ATOMIC_PTR_HPP_INCLUDED__ -#define __ZMQ_ATOMIC_PTR_HPP_INCLUDED__ - -#if defined ZMQ_FORCE_MUTEXES -#define ZMQ_ATOMIC_PTR_MUTEX -#elif defined ZMQ_HAVE_ATOMIC_INTRINSICS -#define ZMQ_ATOMIC_PTR_INTRINSIC -#elif (defined __cplusplus && __cplusplus >= 201103L) -#define ZMQ_ATOMIC_PTR_CXX11 -#elif (defined __i386__ || defined __x86_64__) && defined __GNUC__ -#define ZMQ_ATOMIC_PTR_X86 -#elif defined __ARM_ARCH_7A__ && defined __GNUC__ -#define ZMQ_ATOMIC_PTR_ARM -#elif defined __tile__ -#define ZMQ_ATOMIC_PTR_TILE -#elif defined ZMQ_HAVE_WINDOWS -#define ZMQ_ATOMIC_PTR_WINDOWS -#elif (defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_NETBSD || defined ZMQ_HAVE_GNU) -#define ZMQ_ATOMIC_PTR_ATOMIC_H -#else -#define ZMQ_ATOMIC_PTR_MUTEX -#endif - -#if defined ZMQ_ATOMIC_PTR_MUTEX -#include "mutex.hpp" -#elif defined ZMQ_ATOMIC_PTR_CXX11 -#include -#elif defined ZMQ_ATOMIC_PTR_WINDOWS -#include "windows.hpp" -#elif defined ZMQ_ATOMIC_PTR_ATOMIC_H -#include -#elif defined ZMQ_ATOMIC_PTR_TILE -#include -#endif - -namespace zmq -{ - - // This class encapsulates several atomic operations on pointers. - - template class atomic_ptr_t - { - public: - - // Initialise atomic pointer - inline atomic_ptr_t () - { - ptr = NULL; - } - - // Destroy atomic pointer - inline ~atomic_ptr_t () - { - } - - // Set value of atomic pointer in a non-threadsafe way - // Use this function only when you are sure that at most one - // thread is accessing the pointer at the moment. - inline void set (T *ptr_) - { - this->ptr = ptr_; - } - - // Perform atomic 'exchange pointers' operation. Pointer is set - // to the 'val' value. Old value is returned. - inline T *xchg (T *val_) - { -#if defined ZMQ_ATOMIC_PTR_WINDOWS - return (T*) InterlockedExchangePointer ((PVOID*) &ptr, val_); -#elif defined ZMQ_ATOMIC_PTR_INTRINSIC - return (T*) __atomic_exchange_n (&ptr, val_, __ATOMIC_ACQ_REL); -#elif defined ZMQ_ATOMIC_PTR_CXX11 - return ptr.exchange(val_, std::memory_order_acq_rel); -#elif defined ZMQ_ATOMIC_PTR_ATOMIC_H - return (T*) atomic_swap_ptr (&ptr, val_); -#elif defined ZMQ_ATOMIC_PTR_TILE - return (T*) arch_atomic_exchange (&ptr, val_); -#elif defined ZMQ_ATOMIC_PTR_X86 - T *old; - __asm__ volatile ( - "lock; xchg %0, %2" - : "=r" (old), "=m" (ptr) - : "m" (ptr), "0" (val_)); - return old; -#elif defined ZMQ_ATOMIC_PTR_ARM - T* old; - unsigned int flag; - __asm__ volatile ( - " dmb sy\n\t" - "1: ldrex %1, [%3]\n\t" - " strex %0, %4, [%3]\n\t" - " teq %0, #0\n\t" - " bne 1b\n\t" - " dmb sy\n\t" - : "=&r"(flag), "=&r"(old), "+Qo"(ptr) - : "r"(&ptr), "r"(val_) - : "cc"); - return old; -#elif defined ZMQ_ATOMIC_PTR_MUTEX - sync.lock (); - T *old = (T*) ptr; - ptr = val_; - sync.unlock (); - return old; -#else -#error atomic_ptr is not implemented for this platform -#endif - } - - // Perform atomic 'compare and swap' operation on the pointer. - // The pointer is compared to 'cmp' argument and if they are - // equal, its value is set to 'val'. Old value of the pointer - // is returned. - inline T *cas (T *cmp_, T *val_) - { -#if defined ZMQ_ATOMIC_PTR_WINDOWS - return (T*) InterlockedCompareExchangePointer ( - (volatile PVOID*) &ptr, val_, cmp_); -#elif defined ZMQ_ATOMIC_PTR_INTRINSIC - T *old = cmp_; - __atomic_compare_exchange_n (&ptr, (volatile T**) &old, val_, false, - __ATOMIC_RELEASE, __ATOMIC_ACQUIRE); - return old; -#elif defined ZMQ_ATOMIC_PTR_CXX11 - ptr.compare_exchange_strong(cmp_, val_, std::memory_order_acq_rel); - return cmp_; -#elif defined ZMQ_ATOMIC_PTR_ATOMIC_H - return (T*) atomic_cas_ptr (&ptr, cmp_, val_); -#elif defined ZMQ_ATOMIC_PTR_TILE - return (T*) arch_atomic_val_compare_and_exchange (&ptr, cmp_, val_); -#elif defined ZMQ_ATOMIC_PTR_X86 - T *old; - __asm__ volatile ( - "lock; cmpxchg %2, %3" - : "=a" (old), "=m" (ptr) - : "r" (val_), "m" (ptr), "0" (cmp_) - : "cc"); - return old; -#elif defined ZMQ_ATOMIC_PTR_ARM - T *old; - unsigned int flag; - __asm__ volatile ( - " dmb sy\n\t" - "1: ldrex %1, [%3]\n\t" - " mov %0, #0\n\t" - " teq %1, %4\n\t" - " it eq\n\t" - " strexeq %0, %5, [%3]\n\t" - " teq %0, #0\n\t" - " bne 1b\n\t" - " dmb sy\n\t" - : "=&r"(flag), "=&r"(old), "+Qo"(ptr) - : "r"(&ptr), "r"(cmp_), "r"(val_) - : "cc"); - return old; -#elif defined ZMQ_ATOMIC_PTR_MUTEX - sync.lock (); - T *old = (T*) ptr; - if (ptr == cmp_) - ptr = val_; - sync.unlock (); - return old; -#else -#error atomic_ptr is not implemented for this platform -#endif - } - - private: - -#if defined ZMQ_ATOMIC_PTR_CXX11 - std::atomic ptr; -#else - volatile T *ptr; -#endif - -#if defined ZMQ_ATOMIC_PTR_MUTEX - mutex_t sync; -#endif - -#if ! defined ZMQ_ATOMIC_PTR_CXX11 - atomic_ptr_t (const atomic_ptr_t&); - const atomic_ptr_t &operator = (const atomic_ptr_t&); -#endif - }; - -} - -// Remove macros local to this file. -#undef ZMQ_ATOMIC_PTR_MUTEX -#undef ZMQ_ATOMIC_PTR_INTRINSIC -#undef ZMQ_ATOMIC_PTR_CXX11 -#undef ZMQ_ATOMIC_PTR_X86 -#undef ZMQ_ATOMIC_PTR_ARM -#undef ZMQ_ATOMIC_PTR_TILE -#undef ZMQ_ATOMIC_PTR_WINDOWS -#undef ZMQ_ATOMIC_PTR_ATOMIC_H - -#endif diff --git a/dep/libzmq/src/blob.hpp b/dep/libzmq/src/blob.hpp deleted file mode 100644 index 9e21718e75..0000000000 --- a/dep/libzmq/src/blob.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_BLOB_HPP_INCLUDED__ -#define __ZMQ_BLOB_HPP_INCLUDED__ - -#include -#include -#include - -#if __cplusplus >= 201103L || defined(_MSC_VER) && _MSC_VER >= 1700 -#define ZMQ_HAS_MOVE_SEMANTICS -#define ZMQ_MAP_INSERT_OR_EMPLACE(k, v) emplace (k,v) -#define ZMQ_PUSH_OR_EMPLACE_BACK emplace_back -#define ZMQ_MOVE(x) std::move (x) -#else -#define ZMQ_MAP_INSERT_OR_EMPLACE(k, v) insert (std::make_pair (k, v)) -#define ZMQ_PUSH_OR_EMPLACE_BACK push_back -#define ZMQ_MOVE(x) (x) -#endif - -namespace zmq -{ - struct reference_tag_t {}; - - // Object to hold dynamically allocated opaque binary data. - // On modern compilers, it will be movable but not copyable. Copies - // must be explicitly created by set_deep_copy. - // On older compilers, it is copyable for syntactical reasons. - struct blob_t - { - // Creates an empty blob_t. - blob_t () : data_ (0), size_ (0), owned_ (true) {} - - // Creates a blob_t of a given size, with uninitialized content. - blob_t (const size_t size) - : data_ ((unsigned char*)malloc (size)) - , size_ (size) - , owned_ (true) - { - } - - // Creates a blob_t of a given size, an initializes content by copying - // from another buffer. - blob_t(const unsigned char * const data, const size_t size) - : data_ ((unsigned char*)malloc (size)) - , size_ (size) - , owned_ (true) - { - memcpy(data_, data, size_); - } - - // Creates a blob_t for temporary use that only references a - // pre-allocated block of data. - // Use with caution and ensure that the blob_t will not outlive - // the referenced data. - blob_t (unsigned char * const data, const size_t size, reference_tag_t) - : data_ (data) - , size_ (size) - , owned_ (false) - { - } - - // Returns the size of the blob_t. - size_t size () const { return size_; } - - // Returns a pointer to the data of the blob_t. - const unsigned char *data() const { - return data_; - } - - // Returns a pointer to the data of the blob_t. - unsigned char *data() { - return data_; - } - - // Defines an order relationship on blob_t. - bool operator< (blob_t const &other) const { - int cmpres = memcmp (data_, other.data_, std::min (size_, other.size_)); - return cmpres < 0 || (cmpres == 0 && size_ < other.size_); - } - - // Sets a blob_t to a deep copy of another blob_t. - void set_deep_copy (blob_t const &other) - { - clear (); - data_ = (unsigned char*)malloc (other.size_); - size_ = other.size_; - owned_ = true; - memcpy (data_, other.data_, size_); - } - - // Sets a blob_t to a copy of a given buffer. - void set (const unsigned char * const data, const size_t size) - { - clear (); - data_ = (unsigned char*)malloc (size); - size_ = size; - owned_ = true; - memcpy (data_, data, size_); - } - - // Empties a blob_t. - void clear () { - if (owned_) { free (data_); } - data_ = 0; size_ = 0; - } - - ~blob_t () { - if (owned_) { free (data_); } - } - -#ifdef ZMQ_HAS_MOVE_SEMANTICS - blob_t (const blob_t &) = delete; - blob_t &operator= (const blob_t &) = delete; - - blob_t (blob_t&& other) - : data_ (other.data_) - , size_ (other.size_) - , owned_ (other.owned_) - { - other.owned_ = false; - } - blob_t &operator= (blob_t&& other) { - if (this != &other) - { - clear (); - data_ = other.data_; - size_ = other.size_; - owned_ = other.owned_; - other.owned_ = false; - } - return *this; - } -#else - blob_t (const blob_t &other) - : owned_(false) - { - set_deep_copy (other); - } - blob_t &operator= (const blob_t &other) { - if (this != &other) - { - clear (); - set_deep_copy (other); - } - return *this; - } -#endif - - private: - unsigned char *data_; - size_t size_; - bool owned_; - }; - -} - -#endif - diff --git a/dep/libzmq/src/client.cpp b/dep/libzmq/src/client.cpp deleted file mode 100644 index 61f85e1df1..0000000000 --- a/dep/libzmq/src/client.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "client.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::client_t::client_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_, true) -{ - options.type = ZMQ_CLIENT; -} - -zmq::client_t::~client_t () -{ -} - -void zmq::client_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - - fq.attach (pipe_); - lb.attach (pipe_); -} - -int zmq::client_t::xsend (msg_t *msg_) -{ - // CLIENT sockets do not allow multipart data (ZMQ_SNDMORE) - if (msg_->flags () & msg_t::more) { - errno = EINVAL; - return -1; - } - return lb.sendpipe (msg_, NULL); -} - -int zmq::client_t::xrecv (msg_t *msg_) -{ - int rc = fq.recvpipe (msg_, NULL); - - // Drop any messages with more flag - while (rc == 0 && msg_->flags () & msg_t::more) { - - // drop all frames of the current multi-frame message - rc = fq.recvpipe (msg_, NULL); - - while (rc == 0 && msg_->flags () & msg_t::more) - rc = fq.recvpipe (msg_, NULL); - - // get the new message - if (rc == 0) - rc = fq.recvpipe (msg_, NULL); - } - - return rc; -} - -bool zmq::client_t::xhas_in () -{ - return fq.has_in (); -} - -bool zmq::client_t::xhas_out () -{ - return lb.has_out (); -} - -const zmq::blob_t &zmq::client_t::get_credential () const -{ - return fq.get_credential (); -} - -void zmq::client_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::client_t::xwrite_activated (pipe_t *pipe_) -{ - lb.activated (pipe_); -} - -void zmq::client_t::xpipe_terminated (pipe_t *pipe_) -{ - fq.pipe_terminated (pipe_); - lb.pipe_terminated (pipe_); -} diff --git a/dep/libzmq/src/client.hpp b/dep/libzmq/src/client.hpp deleted file mode 100644 index 6d9be5f083..0000000000 --- a/dep/libzmq/src/client.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CLIENT_HPP_INCLUDED__ -#define __ZMQ_CLIENT_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "fq.hpp" -#include "lb.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - class io_thread_t; - class socket_base_t; - - class client_t : - public socket_base_t - { - public: - - client_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~client_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Messages are fair-queued from inbound pipes. And load-balanced to - // the outbound pipes. - fq_t fq; - lb_t lb; - - client_t (const client_t &); - const client_t &operator = (const client_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/clock.cpp b/dep/libzmq/src/clock.cpp deleted file mode 100644 index b15bd743c5..0000000000 --- a/dep/libzmq/src/clock.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "clock.hpp" -#include "likely.hpp" -#include "config.hpp" -#include "err.hpp" -#include "mutex.hpp" - -#include - -#if defined _MSC_VER -#if defined _WIN32_WCE -#include -#else -#include -#endif -#endif - -#if !defined ZMQ_HAVE_WINDOWS -#include -#endif - -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETHRTIME -#include -#endif - -#if defined ZMQ_HAVE_OSX -#include -#include -#include -#include - -int alt_clock_gettime (int clock_id, timespec *ts) -{ - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service (mach_host_self (), clock_id, &cclock); - clock_get_time (cclock, &mts); - mach_port_deallocate (mach_task_self (), cclock); - ts->tv_sec = mts.tv_sec; - ts->tv_nsec = mts.tv_nsec; - return 0; -} -#endif - -#ifdef ZMQ_HAVE_WINDOWS -typedef ULONGLONG (*f_compatible_get_tick_count64)(); - -static zmq::mutex_t compatible_get_tick_count64_mutex; - -ULONGLONG compatible_get_tick_count64() -{ -#ifdef ZMQ_HAVE_WINDOWS_UWP - const ULONGLONG result = ::GetTickCount64(); - return result; -#else - zmq::scoped_lock_t locker(compatible_get_tick_count64_mutex); - - static DWORD s_wrap = 0; - static DWORD s_last_tick = 0; - const DWORD current_tick = ::GetTickCount(); - - if (current_tick < s_last_tick) - ++s_wrap; - - s_last_tick = current_tick; - const ULONGLONG result = (static_cast(s_wrap) << 32) + static_cast(current_tick); - - return result; -#endif -} - -f_compatible_get_tick_count64 init_compatible_get_tick_count64() -{ - f_compatible_get_tick_count64 func = NULL; -#if !defined ZMQ_HAVE_WINDOWS_UWP - - HMODULE module = ::LoadLibraryA("Kernel32.dll"); - if (module != NULL) - func = reinterpret_cast(::GetProcAddress(module, "GetTickCount64")); -#endif - if (func == NULL) - func = compatible_get_tick_count64; - -#if !defined ZMQ_HAVE_WINDOWS_UWP - ::FreeLibrary(module); -#endif - - return func; -} - -static f_compatible_get_tick_count64 my_get_tick_count64 = init_compatible_get_tick_count64(); -#endif - -zmq::clock_t::clock_t () : - last_tsc (rdtsc ()), -#ifdef ZMQ_HAVE_WINDOWS - last_time (static_cast((*my_get_tick_count64)())) -#else - last_time (now_us () / 1000) -#endif -{ -} - -zmq::clock_t::~clock_t () -{ -} - -uint64_t zmq::clock_t::now_us () -{ -#if defined ZMQ_HAVE_WINDOWS - - // Get the high resolution counter's accuracy. - LARGE_INTEGER ticksPerSecond; - QueryPerformanceFrequency (&ticksPerSecond); - - // What time is it? - LARGE_INTEGER tick; - QueryPerformanceCounter (&tick); - - // Convert the tick number into the number of seconds - // since the system was started. - double ticks_div = ticksPerSecond.QuadPart / 1000000.0; - return (uint64_t) (tick.QuadPart / ticks_div); - -#elif defined HAVE_CLOCK_GETTIME && defined CLOCK_MONOTONIC - - // Use POSIX clock_gettime function to get precise monotonic time. - struct timespec tv; - -#if defined ZMQ_HAVE_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 // less than macOS 10.12 - int rc = alt_clock_gettime (SYSTEM_CLOCK, &tv); -#else - int rc = clock_gettime (CLOCK_MONOTONIC, &tv); -#endif - // Fix case where system has clock_gettime but CLOCK_MONOTONIC is not supported. - // This should be a configuration check, but I looked into it and writing an - // AC_FUNC_CLOCK_MONOTONIC seems beyond my powers. - if( rc != 0) { - // Use POSIX gettimeofday function to get precise time. - struct timeval tv; - int rc = gettimeofday (&tv, NULL); - errno_assert (rc == 0); - return (tv.tv_sec * (uint64_t) 1000000 + tv.tv_usec); - } - return (tv.tv_sec * (uint64_t) 1000000 + tv.tv_nsec / 1000); - -#elif defined HAVE_GETHRTIME - - return (gethrtime () / 1000); - -#else - - // Use POSIX gettimeofday function to get precise time. - struct timeval tv; - int rc = gettimeofday (&tv, NULL); - errno_assert (rc == 0); - return (tv.tv_sec * (uint64_t) 1000000 + tv.tv_usec); - -#endif -} - -uint64_t zmq::clock_t::now_ms () -{ - uint64_t tsc = rdtsc (); - - // If TSC is not supported, get precise time and chop off the microseconds. - if (!tsc) - { -#ifdef ZMQ_HAVE_WINDOWS - // Under Windows, now_us is not so reliable since QueryPerformanceCounter - // does not guarantee that it will use a hardware that offers a monotonic timer. - // So, lets use GetTickCount when GetTickCount64 is not available with an workaround - // to its 32 bit limitation. - return static_cast((*my_get_tick_count64)()); -#else - return now_us () / 1000; -#endif - } - - // If TSC haven't jumped back (in case of migration to a different - // CPU core) and if not too much time elapsed since last measurement, - // we can return cached time value. - if (likely (tsc - last_tsc <= (clock_precision / 2) && tsc >= last_tsc)) - return last_time; - - last_tsc = tsc; -#ifdef ZMQ_HAVE_WINDOWS - last_time = static_cast((*my_get_tick_count64)()); -#else - last_time = now_us () / 1000; -#endif - return last_time; -} - -uint64_t zmq::clock_t::rdtsc () -{ -#if (defined _MSC_VER && (defined _M_IX86 || defined _M_X64)) - return __rdtsc (); -#elif (defined __GNUC__ && (defined __i386__ || defined __x86_64__)) - uint32_t low, high; - __asm__ volatile ("rdtsc" : "=a" (low), "=d" (high)); - return (uint64_t) high << 32 | low; -#elif (defined __SUNPRO_CC && (__SUNPRO_CC >= 0x5100) && (defined __i386 || \ - defined __amd64 || defined __x86_64)) - union { - uint64_t u64val; - uint32_t u32val [2]; - } tsc; - asm("rdtsc" : "=a" (tsc.u32val [0]), "=d" (tsc.u32val [1])); - return tsc.u64val; -#elif defined(__s390__) - uint64_t tsc; - asm("\tstck\t%0\n" : "=Q" (tsc) : : "cc"); - return(tsc); -#else - struct timespec ts; - #if defined ZMQ_HAVE_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 // less than macOS 10.12 - alt_clock_gettime (SYSTEM_CLOCK, &ts); - #else - clock_gettime (CLOCK_MONOTONIC, &ts); - #endif - return (uint64_t)(ts.tv_sec) * 1000000000 + ts.tv_nsec; -#endif -} diff --git a/dep/libzmq/src/clock.hpp b/dep/libzmq/src/clock.hpp deleted file mode 100644 index ee80a9da1d..0000000000 --- a/dep/libzmq/src/clock.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CLOCK_HPP_INCLUDED__ -#define __ZMQ_CLOCK_HPP_INCLUDED__ - -#include "stdint.hpp" - -#if defined ZMQ_HAVE_OSX -#include -#include -#include -#include -int alt_clock_gettime (int clock_id, timespec *ts); -#ifndef CLOCK_REALTIME -#define CLOCK_REALTIME 0 -#endif -#ifndef HAVE_CLOCK_GETTIME -#define HAVE_CLOCK_GETTIME -#endif -#endif - -namespace zmq -{ - - class clock_t - { - public: - - clock_t (); - ~clock_t (); - - // CPU's timestamp counter. Returns 0 if it's not available. - static uint64_t rdtsc (); - - // High precision timestamp. - static uint64_t now_us (); - - // Low precision timestamp. In tight loops generating it can be - // 10 to 100 times faster than the high precision timestamp. - uint64_t now_ms (); - - private: - - // TSC timestamp of when last time measurement was made. - uint64_t last_tsc; - - // Physical time corresponding to the TSC above (in milliseconds). - uint64_t last_time; - - clock_t (const clock_t&); - const clock_t &operator = (const clock_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/command.hpp b/dep/libzmq/src/command.hpp deleted file mode 100644 index ddb46d4675..0000000000 --- a/dep/libzmq/src/command.hpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_COMMAND_HPP_INCLUDED__ -#define __ZMQ_COMMAND_HPP_INCLUDED__ - -#include -#include "stdint.hpp" - -namespace zmq -{ - - class object_t; - class own_t; - struct i_engine; - class pipe_t; - class socket_base_t; - - // This structure defines the commands that can be sent between threads. - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4324) // C4324: alignment padding warnings - __declspec(align(64)) -#endif - struct command_t - { - // Object to process the command. - zmq::object_t *destination; - - enum type_t - { - stop, - plug, - own, - attach, - bind, - activate_read, - activate_write, - hiccup, - pipe_term, - pipe_term_ack, - pipe_hwm, - term_req, - term, - term_ack, - term_endpoint, - reap, - reaped, - inproc_connected, - done - } type; - - union args_t - { - - // Sent to I/O thread to let it know that it should - // terminate itself. - struct { - } stop; - - // Sent to I/O object to make it register with its I/O thread. - struct { - } plug; - - // Sent to socket to let it know about the newly created object. - struct { - zmq::own_t *object; - } own; - - // Attach the engine to the session. If engine is NULL, it informs - // session that the connection have failed. - struct { - struct i_engine *engine; - } attach; - - // Sent from session to socket to establish pipe(s) between them. - // Caller have used inc_seqnum beforehand sending the command. - struct { - zmq::pipe_t *pipe; - } bind; - - // Sent by pipe writer to inform dormant pipe reader that there - // are messages in the pipe. - struct { - } activate_read; - - // Sent by pipe reader to inform pipe writer about how many - // messages it has read so far. - struct { - uint64_t msgs_read; - } activate_write; - - // Sent by pipe reader to writer after creating a new inpipe. - // The parameter is actually of type pipe_t::upipe_t, however, - // its definition is private so we'll have to do with void*. - struct { - void *pipe; - } hiccup; - - // Sent by pipe reader to pipe writer to ask it to terminate - // its end of the pipe. - struct { - } pipe_term; - - // Pipe writer acknowledges pipe_term command. - struct { - } pipe_term_ack; - - // Sent by one of pipe to another part for modify hwm - struct { - int inhwm; - int outhwm; - } pipe_hwm; - - // Sent by I/O object ot the socket to request the shutdown of - // the I/O object. - struct { - zmq::own_t *object; - } term_req; - - // Sent by socket to I/O object to start its shutdown. - struct { - int linger; - } term; - - // Sent by I/O object to the socket to acknowledge it has - // shut down. - struct { - } term_ack; - - // Sent by session_base (I/O thread) to socket (application thread) - // to ask to disconnect the endpoint. - struct { - std::string *endpoint; - } term_endpoint; - - // Transfers the ownership of the closed socket - // to the reaper thread. - struct { - zmq::socket_base_t *socket; - } reap; - - // Closed socket notifies the reaper that it's already deallocated. - struct { - } reaped; - - // Sent by reaper thread to the term thread when all the sockets - // are successfully deallocated. - struct { - } done; - - } args; -#ifdef _MSC_VER - }; -#pragma warning(pop) -#else - } __attribute__((aligned(64))); -#endif -} - -#endif diff --git a/dep/libzmq/src/condition_variable.hpp b/dep/libzmq/src/condition_variable.hpp deleted file mode 100644 index 6452b7814f..0000000000 --- a/dep/libzmq/src/condition_variable.hpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CONDITON_VARIABLE_HPP_INCLUDED__ -#define __ZMQ_CONDITON_VARIABLE_HPP_INCLUDED__ - -#include "clock.hpp" -#include "err.hpp" -#include "mutex.hpp" - -// Condition variable class encapsulates OS mutex in a platform-independent way. - -#ifdef ZMQ_HAVE_WINDOWS - -#include "windows.hpp" -#if defined(_MSC_VER) -#if _MSC_VER >= 1800 -#define _SUPPORT_CONDITION_VARIABLE 1 -#else -#define _SUPPORT_CONDITION_VARIABLE 0 -#endif -#else -#if _cplusplus >= 201103L -#define _SUPPORT_CONDITION_VARIABLE 1 -#else -#define _SUPPORT_CONDITION_VARIABLE 0 -#endif -#endif - -// Condition variable is supported from Windows Vista only, to use condition variable define _WIN32_WINNT to 0x0600 -#if _WIN32_WINNT < 0x0600 && !_SUPPORT_CONDITION_VARIABLE - -namespace zmq -{ - - class condition_variable_t - { - public: - inline condition_variable_t () - { - zmq_assert(false); - } - - inline ~condition_variable_t () - { - - } - - inline int wait (mutex_t* mutex_, int timeout_ ) - { - zmq_assert(false); - return -1; - } - - inline void broadcast () - { - zmq_assert(false); - } - - private: - - // Disable copy construction and assignment. - condition_variable_t (const condition_variable_t&); - void operator = (const condition_variable_t&); - }; - -} - -#else - -#if _SUPPORT_CONDITION_VARIABLE || defined(ZMQ_HAVE_WINDOWS_TARGET_XP) -#include -#include -#endif - -namespace zmq -{ - -#if !defined(ZMQ_HAVE_WINDOWS_TARGET_XP) && _WIN32_WINNT >= 0x0600 - class condition_variable_t - { - public: - inline condition_variable_t () - { - InitializeConditionVariable (&cv); - } - - inline ~condition_variable_t () - { - - } - - inline int wait (mutex_t* mutex_, int timeout_ ) - { - int rc = SleepConditionVariableCS(&cv, mutex_->get_cs (), timeout_); - - if (rc != 0) - return 0; - - rc = GetLastError(); - - if (rc != ERROR_TIMEOUT) - win_assert(rc); - - errno = EAGAIN; - return -1; - } - - inline void broadcast () - { - WakeAllConditionVariable(&cv); - } - - private: - - CONDITION_VARIABLE cv; - - // Disable copy construction and assignment. - condition_variable_t (const condition_variable_t&); - void operator = (const condition_variable_t&); - }; -#else - class condition_variable_t - { - public: - inline condition_variable_t() - { - - } - - inline ~condition_variable_t() - { - - } - - inline int wait(mutex_t* mutex_, int timeout_) - { - std::unique_lock lck(mtx); // lock mtx - mutex_->unlock(); // unlock mutex_ - int res = 0; - if(timeout_ == -1) { - cv.wait(lck); // unlock mtx and wait cv.notify_all(), lock mtx after cv.notify_all() - } else if (cv.wait_for(lck, std::chrono::milliseconds(timeout_)) == std::cv_status::timeout) { - // time expired - errno = EAGAIN; - res = -1; - } - lck.unlock(); // unlock mtx - mutex_->lock(); // lock mutex_ - return res; - } - - inline void broadcast() - { - std::unique_lock lck(mtx); // lock mtx - cv.notify_all(); - } - - private: - - std::condition_variable cv; - std::mutex mtx; - - // Disable copy construction and assignment. - condition_variable_t(const condition_variable_t&); - void operator = (const condition_variable_t&); - }; - -#endif -} - -#endif - -#else - -#include - -namespace zmq -{ - - class condition_variable_t - { - public: - inline condition_variable_t () - { - int rc = pthread_cond_init (&cond, NULL); - posix_assert (rc); - } - - inline ~condition_variable_t () - { - int rc = pthread_cond_destroy (&cond); - posix_assert (rc); - } - - inline int wait (mutex_t* mutex_, int timeout_) - { - int rc; - - if (timeout_ != -1) { - struct timespec timeout; - -#if defined ZMQ_HAVE_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 // less than macOS 10.12 - alt_clock_gettime(SYSTEM_CLOCK, &timeout); -#else - clock_gettime(CLOCK_MONOTONIC, &timeout); -#endif - - timeout.tv_sec += timeout_ / 1000; - timeout.tv_nsec += (timeout_ % 1000) * 1000000; - - if (timeout.tv_nsec > 1000000000) { - timeout.tv_sec++; - timeout.tv_nsec -= 1000000000; - } - - rc = pthread_cond_timedwait (&cond, mutex_->get_mutex (), &timeout); - } - else - rc = pthread_cond_wait(&cond, mutex_->get_mutex()); - - if (rc == 0) - return 0; - - if (rc == ETIMEDOUT){ - errno= EAGAIN; - return -1; - } - - posix_assert (rc); - return -1; - } - - inline void broadcast () - { - int rc = pthread_cond_broadcast (&cond); - posix_assert (rc); - } - - private: - - pthread_cond_t cond; - - // Disable copy construction and assignment. - condition_variable_t (const condition_variable_t&); - const condition_variable_t &operator = (const condition_variable_t&); - }; -} - -#endif - - -#endif diff --git a/dep/libzmq/src/config.hpp b/dep/libzmq/src/config.hpp deleted file mode 100644 index 0a7433a812..0000000000 --- a/dep/libzmq/src/config.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CONFIG_HPP_INCLUDED__ -#define __ZMQ_CONFIG_HPP_INCLUDED__ - -namespace zmq -{ - - // Compile-time settings. - - enum - { - // Number of new messages in message pipe needed to trigger new memory - // allocation. Setting this parameter to 256 decreases the impact of - // memory allocation by approximately 99.6% - message_pipe_granularity = 256, - - // Commands in pipe per allocation event. - command_pipe_granularity = 16, - - // Determines how often does socket poll for new commands when it - // still has unprocessed messages to handle. Thus, if it is set to 100, - // socket will process 100 inbound messages before doing the poll. - // If there are no unprocessed messages available, poll is done - // immediately. Decreasing the value trades overall latency for more - // real-time behaviour (less latency peaks). - inbound_poll_rate = 100, - - // Maximal batching size for engines with receiving functionality. - // So, if there are 10 messages that fit into the batch size, all of - // them may be read by a single 'recv' system call, thus avoiding - // unnecessary network stack traversals. - in_batch_size = 8192, - - // Maximal batching size for engines with sending functionality. - // So, if there are 10 messages that fit into the batch size, all of - // them may be written by a single 'send' system call, thus avoiding - // unnecessary network stack traversals. - out_batch_size = 8192, - - // Maximal delta between high and low watermark. - max_wm_delta = 1024, - - // Maximum number of events the I/O thread can process in one go. - max_io_events = 256, - - // Maximal delay to process command in API thread (in CPU ticks). - // 3,000,000 ticks equals to 1 - 2 milliseconds on current CPUs. - // Note that delay is only applied when there is continuous stream of - // messages to process. If not so, commands are processed immediately. - max_command_delay = 3000000, - - // Low-precision clock precision in CPU ticks. 1ms. Value of 1000000 - // should be OK for CPU frequencies above 1GHz. If should work - // reasonably well for CPU frequencies above 500MHz. For lower CPU - // frequencies you may consider lowering this value to get best - // possible latencies. - clock_precision = 1000000, - - // On some OSes the signaler has to be emulated using a TCP - // connection. In such cases following port is used. - // If 0, it lets the OS choose a free port without requiring use of a - // global mutex. The original implementation of a Windows signaler - // socket used port 5905 instead of letting the OS choose a free port. - // https://github.com/zeromq/libzmq/issues/1542 - signaler_port = 0 - }; - -} - -#endif diff --git a/dep/libzmq/src/ctx.cpp b/dep/libzmq/src/ctx.cpp deleted file mode 100644 index 59f3be987f..0000000000 --- a/dep/libzmq/src/ctx.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/* - Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#ifndef ZMQ_HAVE_WINDOWS -#include -#endif - -#include -#include -#include -#include -#include - -#include "ctx.hpp" -#include "socket_base.hpp" -#include "io_thread.hpp" -#include "reaper.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "random.hpp" - -#ifdef ZMQ_HAVE_VMCI -#include -#endif - -#define ZMQ_CTX_TAG_VALUE_GOOD 0xabadcafe -#define ZMQ_CTX_TAG_VALUE_BAD 0xdeadbeef - -int clipped_maxsocket (int max_requested) -{ - if (max_requested >= zmq::poller_t::max_fds () && zmq::poller_t::max_fds () != -1) - // -1 because we need room for the reaper mailbox. - max_requested = zmq::poller_t::max_fds () - 1; - - return max_requested; -} - -zmq::ctx_t::ctx_t () : - tag (ZMQ_CTX_TAG_VALUE_GOOD), - starting (true), - terminating (false), - reaper (NULL), - slot_count (0), - slots (NULL), - max_sockets (clipped_maxsocket (ZMQ_MAX_SOCKETS_DFLT)), - max_msgsz (INT_MAX), - io_thread_count (ZMQ_IO_THREADS_DFLT), - blocky (true), - ipv6 (false), - thread_priority (ZMQ_THREAD_PRIORITY_DFLT), - thread_sched_policy (ZMQ_THREAD_SCHED_POLICY_DFLT) -{ -#ifdef HAVE_FORK - pid = getpid(); -#endif -#ifdef ZMQ_HAVE_VMCI - vmci_fd = -1; - vmci_family = -1; -#endif - - // Initialise crypto library, if needed. - zmq::random_open (); -} - -bool zmq::ctx_t::check_tag () -{ - return tag == ZMQ_CTX_TAG_VALUE_GOOD; -} - -zmq::ctx_t::~ctx_t () -{ - // Check that there are no remaining sockets. - zmq_assert (sockets.empty ()); - - // Ask I/O threads to terminate. If stop signal wasn't sent to I/O - // thread subsequent invocation of destructor would hang-up. - for (io_threads_t::size_type i = 0; i != io_threads.size (); i++) { - io_threads [i]->stop (); - } - - // Wait till I/O threads actually terminate. - for (io_threads_t::size_type i = 0; i != io_threads.size (); i++) { - LIBZMQ_DELETE(io_threads [i]); - } - - // Deallocate the reaper thread object. - LIBZMQ_DELETE(reaper); - - // Deallocate the array of mailboxes. No special work is - // needed as mailboxes themselves were deallocated with their - // corresponding io_thread/socket objects. - free (slots); - - // De-initialise crypto library, if needed. - zmq::random_close (); - - // Remove the tag, so that the object is considered dead. - tag = ZMQ_CTX_TAG_VALUE_BAD; -} - -int zmq::ctx_t::terminate () -{ - slot_sync.lock(); - - bool saveTerminating = terminating; - terminating = false; - - // Connect up any pending inproc connections, otherwise we will hang - pending_connections_t copy = pending_connections; - for (pending_connections_t::iterator p = copy.begin (); p != copy.end (); ++p) { - zmq::socket_base_t *s = create_socket (ZMQ_PAIR); - // create_socket might fail eg: out of memory/sockets limit reached - zmq_assert (s); - s->bind (p->first.c_str ()); - s->close (); - } - terminating = saveTerminating; - - if (!starting) { - -#ifdef HAVE_FORK - if (pid != getpid ()) { - // we are a forked child process. Close all file descriptors - // inherited from the parent. - for (sockets_t::size_type i = 0; i != sockets.size (); i++) - sockets [i]->get_mailbox ()->forked (); - - term_mailbox.forked (); - } -#endif - - // Check whether termination was already underway, but interrupted and now - // restarted. - bool restarted = terminating; - terminating = true; - - // First attempt to terminate the context. - if (!restarted) { - // First send stop command to sockets so that any blocking calls - // can be interrupted. If there are no sockets we can ask reaper - // thread to stop. - for (sockets_t::size_type i = 0; i != sockets.size (); i++) - sockets [i]->stop (); - if (sockets.empty ()) - reaper->stop (); - } - slot_sync.unlock(); - - // Wait till reaper thread closes all the sockets. - command_t cmd; - int rc = term_mailbox.recv (&cmd, -1); - if (rc == -1 && errno == EINTR) - return -1; - errno_assert (rc == 0); - zmq_assert (cmd.type == command_t::done); - slot_sync.lock (); - zmq_assert (sockets.empty ()); - } - slot_sync.unlock (); - -#ifdef ZMQ_HAVE_VMCI - vmci_sync.lock (); - - VMCISock_ReleaseAFValueFd (vmci_fd); - vmci_family = -1; - vmci_fd = -1; - - vmci_sync.unlock (); -#endif - - // Deallocate the resources. - delete this; - - return 0; -} - -int zmq::ctx_t::shutdown () -{ - scoped_lock_t locker(slot_sync); - - if (!starting && !terminating) { - terminating = true; - - // Send stop command to sockets so that any blocking calls - // can be interrupted. If there are no sockets we can ask reaper - // thread to stop. - for (sockets_t::size_type i = 0; i != sockets.size (); i++) - sockets [i]->stop (); - if (sockets.empty ()) - reaper->stop (); - } - - return 0; -} - -int zmq::ctx_t::set (int option_, int optval_) -{ - int rc = 0; - if (option_ == ZMQ_MAX_SOCKETS - && optval_ >= 1 && optval_ == clipped_maxsocket (optval_)) { - scoped_lock_t locker(opt_sync); - max_sockets = optval_; - } - else - if (option_ == ZMQ_IO_THREADS && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - io_thread_count = optval_; - } - else - if (option_ == ZMQ_IPV6 && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - ipv6 = (optval_ != 0); - } - else - if (option_ == ZMQ_THREAD_PRIORITY && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - thread_priority = optval_; - } - else - if (option_ == ZMQ_THREAD_SCHED_POLICY && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - thread_sched_policy = optval_; - } - else - if (option_ == ZMQ_THREAD_AFFINITY_CPU_ADD && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - thread_affinity_cpus.insert( optval_ ); - } - else - if (option_ == ZMQ_THREAD_AFFINITY_CPU_REMOVE && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - std::set::iterator it = thread_affinity_cpus.find( optval_ ); - if (it != thread_affinity_cpus.end()) { - thread_affinity_cpus.erase( it ); - } else { - errno = EINVAL; - rc = -1; - } - } - else - if (option_ == ZMQ_THREAD_NAME_PREFIX && optval_ >= 0) { - std::ostringstream s; - s << optval_; - scoped_lock_t locker(opt_sync); - thread_name_prefix = s.str(); - } - else - if (option_ == ZMQ_BLOCKY && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - blocky = (optval_ != 0); - } - else - if (option_ == ZMQ_MAX_MSGSZ && optval_ >= 0) { - scoped_lock_t locker(opt_sync); - max_msgsz = optval_ < INT_MAX? optval_: INT_MAX; - } - else { - errno = EINVAL; - rc = -1; - } - return rc; -} - -int zmq::ctx_t::get (int option_) -{ - int rc = 0; - if (option_ == ZMQ_MAX_SOCKETS) - rc = max_sockets; - else - if (option_ == ZMQ_SOCKET_LIMIT) - rc = clipped_maxsocket (65535); - else - if (option_ == ZMQ_IO_THREADS) - rc = io_thread_count; - else - if (option_ == ZMQ_IPV6) - rc = ipv6; - else - if (option_ == ZMQ_BLOCKY) - rc = blocky; - else - if (option_ == ZMQ_MAX_MSGSZ) - rc = max_msgsz; - else - if (option_ == ZMQ_MSG_T_SIZE) - rc = sizeof (zmq_msg_t); - else { - errno = EINVAL; - rc = -1; - } - return rc; -} - -zmq::socket_base_t *zmq::ctx_t::create_socket (int type_) -{ - scoped_lock_t locker(slot_sync); - - if (unlikely (starting)) { - - starting = false; - // Initialise the array of mailboxes. Additional three slots are for - // zmq_ctx_term thread and reaper thread. - opt_sync.lock (); - int mazmq = max_sockets; - int ios = io_thread_count; - opt_sync.unlock (); - slot_count = mazmq + ios + 2; - slots = (i_mailbox **) malloc (sizeof (i_mailbox*) * slot_count); - alloc_assert (slots); - - // Initialise the infrastructure for zmq_ctx_term thread. - slots [term_tid] = &term_mailbox; - - // Create the reaper thread. - reaper = new (std::nothrow) reaper_t (this, reaper_tid); - alloc_assert (reaper); - slots [reaper_tid] = reaper->get_mailbox (); - reaper->start (); - - // Create I/O thread objects and launch them. - for (int i = 2; i != ios + 2; i++) { - io_thread_t *io_thread = new (std::nothrow) io_thread_t (this, i); - alloc_assert (io_thread); - io_threads.push_back (io_thread); - slots [i] = io_thread->get_mailbox (); - io_thread->start (); - } - - // In the unused part of the slot array, create a list of empty slots. - for (int32_t i = (int32_t) slot_count - 1; - i >= (int32_t) ios + 2; i--) { - empty_slots.push_back (i); - slots [i] = NULL; - } - } - - // Once zmq_ctx_term() was called, we can't create new sockets. - if (terminating) { - errno = ETERM; - return NULL; - } - - // If max_sockets limit was reached, return error. - if (empty_slots.empty ()) { - errno = EMFILE; - return NULL; - } - - // Choose a slot for the socket. - uint32_t slot = empty_slots.back (); - empty_slots.pop_back (); - - // Generate new unique socket ID. - int sid = ((int) max_socket_id.add (1)) + 1; - - // Create the socket and register its mailbox. - socket_base_t *s = socket_base_t::create (type_, this, slot, sid); - if (!s) { - empty_slots.push_back (slot); - return NULL; - } - sockets.push_back (s); - slots [slot] = s->get_mailbox (); - - return s; -} - -void zmq::ctx_t::destroy_socket (class socket_base_t *socket_) -{ - scoped_lock_t locker(slot_sync); - - // Free the associated thread slot. - uint32_t tid = socket_->get_tid (); - empty_slots.push_back (tid); - slots [tid] = NULL; - - // Remove the socket from the list of sockets. - sockets.erase (socket_); - - // If zmq_ctx_term() was already called and there are no more socket - // we can ask reaper thread to terminate. - if (terminating && sockets.empty ()) - reaper->stop (); -} - -zmq::object_t *zmq::ctx_t::get_reaper () -{ - return reaper; -} - -void zmq::ctx_t::start_thread (thread_t &thread_, thread_fn *tfn_, void *arg_) const -{ - static unsigned int nthreads_started = 0; - - thread_.setSchedulingParameters(thread_priority, thread_sched_policy, thread_affinity_cpus); - thread_.start(tfn_, arg_); -#ifndef ZMQ_HAVE_ANDROID - std::ostringstream s; - if (!thread_name_prefix.empty()) - s << thread_name_prefix << "/"; - s << "ZMQbg/" << nthreads_started; - thread_.setThreadName (s.str().c_str()); -#endif - nthreads_started++; -} - -void zmq::ctx_t::send_command (uint32_t tid_, const command_t &command_) -{ - slots [tid_]->send (command_); -} - -zmq::io_thread_t *zmq::ctx_t::choose_io_thread (uint64_t affinity_) -{ - if (io_threads.empty ()) - return NULL; - - // Find the I/O thread with minimum load. - int min_load = -1; - io_thread_t *selected_io_thread = NULL; - for (io_threads_t::size_type i = 0; i != io_threads.size (); i++) { - if (!affinity_ || (affinity_ & (uint64_t (1) << i))) { - int load = io_threads [i]->get_load (); - if (selected_io_thread == NULL || load < min_load) { - min_load = load; - selected_io_thread = io_threads [i]; - } - } - } - return selected_io_thread; -} - -int zmq::ctx_t::register_endpoint (const char *addr_, - const endpoint_t &endpoint_) -{ - scoped_lock_t locker(endpoints_sync); - - const bool inserted = endpoints.ZMQ_MAP_INSERT_OR_EMPLACE (addr_, - endpoint_).second; - if (!inserted) { - errno = EADDRINUSE; - return -1; - } - return 0; -} - -int zmq::ctx_t::unregister_endpoint ( - const std::string &addr_, socket_base_t *socket_) -{ - scoped_lock_t locker(endpoints_sync); - - const endpoints_t::iterator it = endpoints.find (addr_); - if (it == endpoints.end () || it->second.socket != socket_) { - errno = ENOENT; - return -1; - } - - // Remove endpoint. - endpoints.erase (it); - - return 0; -} - -void zmq::ctx_t::unregister_endpoints (socket_base_t *socket_) -{ - scoped_lock_t locker(endpoints_sync); - - endpoints_t::iterator it = endpoints.begin (); - while (it != endpoints.end ()) { - if (it->second.socket == socket_) { - endpoints_t::iterator to_erase = it; - ++it; - endpoints.erase (to_erase); - continue; - } - ++it; - } -} - -zmq::endpoint_t zmq::ctx_t::find_endpoint (const char *addr_) -{ - scoped_lock_t locker(endpoints_sync); - - endpoints_t::iterator it = endpoints.find (addr_); - if (it == endpoints.end ()) { - errno = ECONNREFUSED; - endpoint_t empty = {NULL, options_t()}; - return empty; - } - endpoint_t endpoint = it->second; - - // Increment the command sequence number of the peer so that it won't - // get deallocated until "bind" command is issued by the caller. - // The subsequent 'bind' has to be called with inc_seqnum parameter - // set to false, so that the seqnum isn't incremented twice. - endpoint.socket->inc_seqnum (); - - return endpoint; -} - -void zmq::ctx_t::pend_connection (const std::string &addr_, - const endpoint_t &endpoint_, pipe_t **pipes_) -{ - scoped_lock_t locker(endpoints_sync); - - const pending_connection_t pending_connection = {endpoint_, pipes_ [0], pipes_ [1]}; - - endpoints_t::iterator it = endpoints.find (addr_); - if (it == endpoints.end ()) { - // Still no bind. - endpoint_.socket->inc_seqnum (); - pending_connections.ZMQ_MAP_INSERT_OR_EMPLACE (addr_, pending_connection); - } else { - // Bind has happened in the mean time, connect directly - connect_inproc_sockets(it->second.socket, it->second.options, pending_connection, connect_side); - } -} - -void zmq::ctx_t::connect_pending (const char *addr_, zmq::socket_base_t *bind_socket_) -{ - scoped_lock_t locker(endpoints_sync); - - std::pair pending = pending_connections.equal_range(addr_); - for (pending_connections_t::iterator p = pending.first; p != pending.second; ++p) - connect_inproc_sockets(bind_socket_, endpoints[addr_].options, p->second, bind_side); - - pending_connections.erase(pending.first, pending.second); -} - -void zmq::ctx_t::connect_inproc_sockets (zmq::socket_base_t *bind_socket_, - options_t& bind_options, const pending_connection_t &pending_connection_, side side_) -{ - bind_socket_->inc_seqnum(); - pending_connection_.bind_pipe->set_tid (bind_socket_->get_tid ()); - - if (!bind_options.recv_routing_id) { - msg_t msg; - const bool ok = pending_connection_.bind_pipe->read (&msg); - zmq_assert (ok); - const int rc = msg.close (); - errno_assert (rc == 0); - } - - bool conflate = pending_connection_.endpoint.options.conflate && - (pending_connection_.endpoint.options.type == ZMQ_DEALER || - pending_connection_.endpoint.options.type == ZMQ_PULL || - pending_connection_.endpoint.options.type == ZMQ_PUSH || - pending_connection_.endpoint.options.type == ZMQ_PUB || - pending_connection_.endpoint.options.type == ZMQ_SUB); - - if (!conflate) { - pending_connection_.connect_pipe->set_hwms_boost(bind_options.sndhwm, bind_options.rcvhwm); - pending_connection_.bind_pipe->set_hwms_boost(pending_connection_.endpoint.options.sndhwm, pending_connection_.endpoint.options.rcvhwm); - - pending_connection_.connect_pipe->set_hwms(pending_connection_.endpoint.options.rcvhwm, pending_connection_.endpoint.options.sndhwm); - pending_connection_.bind_pipe->set_hwms(bind_options.rcvhwm, bind_options.sndhwm); - } - else { - pending_connection_.connect_pipe->set_hwms(-1, -1); - pending_connection_.bind_pipe->set_hwms(-1, -1); - } - - if (side_ == bind_side) { - command_t cmd; - cmd.type = command_t::bind; - cmd.args.bind.pipe = pending_connection_.bind_pipe; - bind_socket_->process_command (cmd); - bind_socket_->send_inproc_connected (pending_connection_.endpoint.socket); - } - else - pending_connection_.connect_pipe->send_bind (bind_socket_, pending_connection_.bind_pipe, false); - - // When a ctx is terminated all pending inproc connection will be - // connected, but the socket will already be closed and the pipe will be - // in waiting_for_delimiter state, which means no more writes can be done - // and the routing id write fails and causes an assert. Check if the socket - // is open before sending. - if (pending_connection_.endpoint.options.recv_routing_id && - pending_connection_.endpoint.socket->check_tag ()) { - msg_t routing_id; - const int rc = routing_id.init_size (bind_options.routing_id_size); - errno_assert (rc == 0); - memcpy (routing_id.data (), bind_options.routing_id, bind_options.routing_id_size); - routing_id.set_flags (msg_t::routing_id); - const bool written = pending_connection_.bind_pipe->write (&routing_id); - zmq_assert (written); - pending_connection_.bind_pipe->flush (); - } -} - -#ifdef ZMQ_HAVE_VMCI - -int zmq::ctx_t::get_vmci_socket_family () -{ - zmq::scoped_lock_t locker(vmci_sync); - - if (vmci_fd == -1) { - vmci_family = VMCISock_GetAFValueFd (&vmci_fd); - - if (vmci_fd != -1) { -#ifdef FD_CLOEXEC - int rc = fcntl (vmci_fd, F_SETFD, FD_CLOEXEC); - errno_assert (rc != -1); -#endif - } - } - - return vmci_family; -} - -#endif - -// The last used socket ID, or 0 if no socket was used so far. Note that this -// is a global variable. Thus, even sockets created in different contexts have -// unique IDs. -zmq::atomic_counter_t zmq::ctx_t::max_socket_id; diff --git a/dep/libzmq/src/ctx.hpp b/dep/libzmq/src/ctx.hpp deleted file mode 100644 index 500b75e5a7..0000000000 --- a/dep/libzmq/src/ctx.hpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CTX_HPP_INCLUDED__ -#define __ZMQ_CTX_HPP_INCLUDED__ - -#include -#include -#include -#include - -#include "mailbox.hpp" -#include "array.hpp" -#include "config.hpp" -#include "mutex.hpp" -#include "stdint.hpp" -#include "options.hpp" -#include "atomic_counter.hpp" -#include "thread.hpp" - -namespace zmq -{ - - class object_t; - class io_thread_t; - class socket_base_t; - class reaper_t; - class pipe_t; - - // Information associated with inproc endpoint. Note that endpoint options - // are registered as well so that the peer can access them without a need - // for synchronisation, handshaking or similar. - struct endpoint_t - { - socket_base_t *socket; - options_t options; - }; - - // Context object encapsulates all the global state associated with - // the library. - - class ctx_t - { - public: - - // Create the context object. - ctx_t (); - - // Returns false if object is not a context. - bool check_tag (); - - // This function is called when user invokes zmq_ctx_term. If there are - // no more sockets open it'll cause all the infrastructure to be shut - // down. If there are open sockets still, the deallocation happens - // after the last one is closed. - int terminate (); - - // This function starts the terminate process by unblocking any blocking - // operations currently in progress and stopping any more socket activity - // (except zmq_close). - // This function is non-blocking. - // terminate must still be called afterwards. - // This function is optional, terminate will unblock any current - // operations as well. - int shutdown(); - - // Set and get context properties. - int set (int option_, int optval_); - int get (int option_); - - // Create and destroy a socket. - zmq::socket_base_t *create_socket (int type_); - void destroy_socket (zmq::socket_base_t *socket_); - - // Start a new thread with proper scheduling parameters. - void start_thread (thread_t &thread_, thread_fn *tfn_, void *arg_) const; - - // Send command to the destination thread. - void send_command (uint32_t tid_, const command_t &command_); - - // Returns the I/O thread that is the least busy at the moment. - // Affinity specifies which I/O threads are eligible (0 = all). - // Returns NULL if no I/O thread is available. - zmq::io_thread_t *choose_io_thread (uint64_t affinity_); - - // Returns reaper thread object. - zmq::object_t *get_reaper (); - - // Management of inproc endpoints. - int register_endpoint (const char *addr_, const endpoint_t &endpoint_); - int unregister_endpoint (const std::string &addr_, socket_base_t *socket_); - void unregister_endpoints (zmq::socket_base_t *socket_); - endpoint_t find_endpoint (const char *addr_); - void pend_connection (const std::string &addr_, - const endpoint_t &endpoint_, pipe_t **pipes_); - void connect_pending (const char *addr_, zmq::socket_base_t *bind_socket_); - -#ifdef ZMQ_HAVE_VMCI - // Return family for the VMCI socket or -1 if it's not available. - int get_vmci_socket_family (); -#endif - - enum { - term_tid = 0, - reaper_tid = 1 - }; - - ~ctx_t (); - - private: - - struct pending_connection_t - { - endpoint_t endpoint; - pipe_t* connect_pipe; - pipe_t* bind_pipe; - }; - - // Used to check whether the object is a context. - uint32_t tag; - - // Sockets belonging to this context. We need the list so that - // we can notify the sockets when zmq_ctx_term() is called. - // The sockets will return ETERM then. - typedef array_t sockets_t; - sockets_t sockets; - - // List of unused thread slots. - typedef std::vector empty_slots_t; - empty_slots_t empty_slots; - - // If true, zmq_init has been called but no socket has been created - // yet. Launching of I/O threads is delayed. - bool starting; - - // If true, zmq_ctx_term was already called. - bool terminating; - - // Synchronisation of accesses to global slot-related data: - // sockets, empty_slots, terminating. It also synchronises - // access to zombie sockets as such (as opposed to slots) and provides - // a memory barrier to ensure that all CPU cores see the same data. - mutex_t slot_sync; - - // The reaper thread. - zmq::reaper_t *reaper; - - // I/O threads. - typedef std::vector io_threads_t; - io_threads_t io_threads; - - // Array of pointers to mailboxes for both application and I/O threads. - uint32_t slot_count; - i_mailbox **slots; - - // Mailbox for zmq_ctx_term thread. - mailbox_t term_mailbox; - - // List of inproc endpoints within this context. - typedef std::map endpoints_t; - endpoints_t endpoints; - - // List of inproc connection endpoints pending a bind - typedef std::multimap pending_connections_t; - pending_connections_t pending_connections; - - // Synchronisation of access to the list of inproc endpoints. - mutex_t endpoints_sync; - - // Maximum socket ID. - static atomic_counter_t max_socket_id; - - // Maximum number of sockets that can be opened at the same time. - int max_sockets; - - // Maximum allowed message size - int max_msgsz; - - // Number of I/O threads to launch. - int io_thread_count; - - // Does context wait (possibly forever) on termination? - bool blocky; - - // Is IPv6 enabled on this context? - bool ipv6; - - // Thread parameters. - int thread_priority; - int thread_sched_policy; - std::set thread_affinity_cpus; - std::string thread_name_prefix; - - // Synchronisation of access to context options. - mutex_t opt_sync; - - ctx_t (const ctx_t&); - const ctx_t &operator = (const ctx_t&); - -#ifdef HAVE_FORK - // the process that created this context. Used to detect forking. - pid_t pid; -#endif - enum side { connect_side, bind_side }; - void connect_inproc_sockets(zmq::socket_base_t *bind_socket_, options_t& bind_options, const pending_connection_t &pending_connection_, side side_); - -#ifdef ZMQ_HAVE_VMCI - int vmci_fd; - int vmci_family; - mutex_t vmci_sync; -#endif - }; - -} - -#endif diff --git a/dep/libzmq/src/curve_client.hpp b/dep/libzmq/src/curve_client.hpp deleted file mode 100644 index 7693ac6485..0000000000 --- a/dep/libzmq/src/curve_client.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CURVE_CLIENT_HPP_INCLUDED__ -#define __ZMQ_CURVE_CLIENT_HPP_INCLUDED__ - -#ifdef ZMQ_HAVE_CURVE - -#include "curve_mechanism_base.hpp" -#include "options.hpp" -#include "curve_client_tools.hpp" - -namespace zmq -{ - - class msg_t; - class session_base_t; - - class curve_client_t : public curve_mechanism_base_t - { - public: - - curve_client_t (session_base_t *session_, const options_t &options_); - virtual ~curve_client_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - virtual int encode (msg_t *msg_); - virtual int decode (msg_t *msg_); - virtual status_t status () const; - - private: - - enum state_t { - send_hello, - expect_welcome, - send_initiate, - expect_ready, - error_received, - connected - }; - - // Current FSM state - state_t state; - - // CURVE protocol tools - curve_client_tools_t tools; - - int produce_hello (msg_t *msg_); - int process_welcome (const uint8_t *cmd_data, size_t data_size); - int produce_initiate (msg_t *msg_); - int process_ready (const uint8_t *cmd_data, size_t data_size); - int process_error (const uint8_t *cmd_data, size_t data_size); - }; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/curve_server.hpp b/dep/libzmq/src/curve_server.hpp deleted file mode 100644 index 30efda5dcb..0000000000 --- a/dep/libzmq/src/curve_server.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_CURVE_SERVER_HPP_INCLUDED__ -#define __ZMQ_CURVE_SERVER_HPP_INCLUDED__ - -#ifdef ZMQ_HAVE_CURVE - -#include "curve_mechanism_base.hpp" -#include "options.hpp" -#include "zap_client.hpp" - -namespace zmq -{ -#ifdef _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4250) -#endif - class curve_server_t : public zap_client_common_handshake_t, - public curve_mechanism_base_t - { - public: - - curve_server_t (session_base_t *session_, - const std::string &peer_address_, - const options_t &options_); - virtual ~curve_server_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - virtual int encode (msg_t *msg_); - virtual int decode (msg_t *msg_); - - private: - - // Our secret key (s) - uint8_t secret_key [crypto_box_SECRETKEYBYTES]; - - // Our short-term public key (S') - uint8_t cn_public [crypto_box_PUBLICKEYBYTES]; - - // Our short-term secret key (s') - uint8_t cn_secret [crypto_box_SECRETKEYBYTES]; - - // Client's short-term public key (C') - uint8_t cn_client [crypto_box_PUBLICKEYBYTES]; - - // Key used to produce cookie - uint8_t cookie_key [crypto_secretbox_KEYBYTES]; - - int process_hello (msg_t *msg_); - int produce_welcome (msg_t *msg_); - int process_initiate (msg_t *msg_); - int produce_ready (msg_t *msg_); - int produce_error (msg_t *msg_) const; - - void send_zap_request (const uint8_t *key); - }; -#ifdef _MSC_VER -#pragma warning (pop) -#endif - -} - -#endif - -#endif diff --git a/dep/libzmq/src/dbuffer.hpp b/dep/libzmq/src/dbuffer.hpp deleted file mode 100644 index 0e0186e524..0000000000 --- a/dep/libzmq/src/dbuffer.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DBUFFER_HPP_INCLUDED__ -#define __ZMQ_DBUFFER_HPP_INCLUDED__ - -#include -#include -#include - -#include "mutex.hpp" -#include "msg.hpp" - -namespace zmq -{ - - // dbuffer is a single-producer single-consumer double-buffer - // implementation. - // - // The producer writes to a back buffer and then tries to swap - // pointers between the back and front buffers. If it fails, - // due to the consumer reading from the front buffer, it just - // gives up, which is ok since writes are many and redundant. - // - // The reader simply reads from the front buffer. - // - // has_msg keeps track of whether there has been a not yet read - // value written, it is used by ypipe_conflate to mimic ypipe - // functionality regarding a reader being asleep - - template class dbuffer_t; - - template <> class dbuffer_t - { - public: - - inline dbuffer_t () - : back (&storage[0]) - , front (&storage[1]) - , has_msg (false) - { - back->init (); - front->init (); - } - - inline ~dbuffer_t() - { - back->close (); - front->close (); - } - - inline void write (const msg_t &value_) - { - msg_t& xvalue = const_cast(value_); - - zmq_assert (xvalue.check ()); - back->move (xvalue); // cannot just overwrite, might leak - - zmq_assert (back->check ()); - - if (sync.try_lock ()) - { - std::swap (back, front); - has_msg = true; - - sync.unlock (); - } - } - - inline bool read (msg_t *value_) - { - if (!value_) - return false; - - { - scoped_lock_t lock (sync); - if (!has_msg) - return false; - - zmq_assert (front->check ()); - - *value_ = *front; - front->init (); // avoid double free - - has_msg = false; - return true; - } - } - - - inline bool check_read () - { - scoped_lock_t lock (sync); - - return has_msg; - } - - inline bool probe (bool (*fn)(const msg_t &)) - { - scoped_lock_t lock (sync); - return (*fn) (*front); - } - - - private: - msg_t storage[2]; - msg_t *back, *front; - - mutex_t sync; - bool has_msg; - - // Disable copying of dbuffer. - dbuffer_t (const dbuffer_t&); - const dbuffer_t &operator = (const dbuffer_t&); - }; -} - -#endif diff --git a/dep/libzmq/src/dealer.cpp b/dep/libzmq/src/dealer.cpp deleted file mode 100644 index a0f67914ec..0000000000 --- a/dep/libzmq/src/dealer.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "dealer.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::dealer_t::dealer_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - probe_router (false) -{ - options.type = ZMQ_DEALER; -} - -zmq::dealer_t::~dealer_t () -{ -} - -void zmq::dealer_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - - if (probe_router) { - msg_t probe_msg_; - int rc = probe_msg_.init (); - errno_assert (rc == 0); - - rc = pipe_->write (&probe_msg_); - // zmq_assert (rc) is not applicable here, since it is not a bug. - pipe_->flush (); - - rc = probe_msg_.close (); - errno_assert (rc == 0); - } - - fq.attach (pipe_); - lb.attach (pipe_); -} - -int zmq::dealer_t::xsetsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - bool is_int = (optvallen_ == sizeof (int)); - int value = 0; - if (is_int) memcpy(&value, optval_, sizeof (int)); - - switch (option_) { - case ZMQ_PROBE_ROUTER: - if (is_int && value >= 0) { - probe_router = (value != 0); - return 0; - } - break; - - default: - break; - } - - errno = EINVAL; - return -1; -} - -int zmq::dealer_t::xsend (msg_t *msg_) -{ - return sendpipe (msg_, NULL); -} - -int zmq::dealer_t::xrecv (msg_t *msg_) -{ - return recvpipe (msg_, NULL); -} - -bool zmq::dealer_t::xhas_in () -{ - return fq.has_in (); -} - -bool zmq::dealer_t::xhas_out () -{ - return lb.has_out (); -} - -const zmq::blob_t &zmq::dealer_t::get_credential () const -{ - return fq.get_credential (); -} - - -void zmq::dealer_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::dealer_t::xwrite_activated (pipe_t *pipe_) -{ - lb.activated (pipe_); -} - -void zmq::dealer_t::xpipe_terminated (pipe_t *pipe_) -{ - fq.pipe_terminated (pipe_); - lb.pipe_terminated (pipe_); -} - -int zmq::dealer_t::sendpipe (msg_t *msg_, pipe_t **pipe_) -{ - return lb.sendpipe (msg_, pipe_); -} - -int zmq::dealer_t::recvpipe (msg_t *msg_, pipe_t **pipe_) -{ - return fq.recvpipe (msg_, pipe_); -} diff --git a/dep/libzmq/src/dealer.hpp b/dep/libzmq/src/dealer.hpp deleted file mode 100644 index 826ca43ff2..0000000000 --- a/dep/libzmq/src/dealer.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DEALER_HPP_INCLUDED__ -#define __ZMQ_DEALER_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "fq.hpp" -#include "lb.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - class io_thread_t; - class socket_base_t; - - class dealer_t : - public socket_base_t - { - public: - - dealer_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~dealer_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsetsockopt (int option_, const void *optval_, size_t optvallen_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - // Send and recv - knowing which pipe was used. - int sendpipe (zmq::msg_t *msg_, zmq::pipe_t **pipe_); - int recvpipe (zmq::msg_t *msg_, zmq::pipe_t **pipe_); - - private: - - // Messages are fair-queued from inbound pipes. And load-balanced to - // the outbound pipes. - fq_t fq; - lb_t lb; - - // if true, send an empty message to every connected router peer - bool probe_router; - - dealer_t (const dealer_t&); - const dealer_t &operator = (const dealer_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/decoder.hpp b/dep/libzmq/src/decoder.hpp deleted file mode 100644 index c8fe5befd1..0000000000 --- a/dep/libzmq/src/decoder.hpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DECODER_HPP_INCLUDED__ -#define __ZMQ_DECODER_HPP_INCLUDED__ - -#include -#include -#include - -#include "decoder_allocators.hpp" -#include "err.hpp" -#include "i_decoder.hpp" -#include "msg.hpp" -#include "stdint.hpp" - -namespace zmq -{ - // Helper base class for decoders that know the amount of data to read - // in advance at any moment. Knowing the amount in advance is a property - // of the protocol used. 0MQ framing protocol is based size-prefixed - // paradigm, which qualifies it to be parsed by this class. - // On the other hand, XML-based transports (like XMPP or SOAP) don't allow - // for knowing the size of data to read in advance and should use different - // decoding algorithms. - // - // This class implements the state machine that parses the incoming buffer. - // Derived class should implement individual state machine actions. - // - // Buffer management is done by an allocator policy. - template - class decoder_base_t : public i_decoder - { - public: - - explicit decoder_base_t (A *allocator_) : - next (NULL), - read_pos (NULL), - to_read (0), - allocator(allocator_) - { - buf = allocator->allocate (); - } - - // The destructor doesn't have to be virtual. It is made virtual - // just to keep ICC and code checking tools from complaining. - virtual ~decoder_base_t () - { - allocator->deallocate (); - } - - // Returns a buffer to be filled with binary data. - void get_buffer (unsigned char **data_, std::size_t *size_) - { - buf = allocator->allocate (); - - // If we are expected to read large message, we'll opt for zero- - // copy, i.e. we'll ask caller to fill the data directly to the - // message. Note that subsequent read(s) are non-blocking, thus - // each single read reads at most SO_RCVBUF bytes at once not - // depending on how large is the chunk returned from here. - // As a consequence, large messages being received won't block - // other engines running in the same I/O thread for excessive - // amounts of time. - if (to_read >= allocator->size ()) { - *data_ = read_pos; - *size_ = to_read; - return; - } - - *data_ = buf; - *size_ = allocator->size (); - } - - // Processes the data in the buffer previously allocated using - // get_buffer function. size_ argument specifies number of bytes - // actually filled into the buffer. Function returns 1 when the - // whole message was decoded or 0 when more data is required. - // On error, -1 is returned and errno set accordingly. - // Number of bytes processed is returned in bytes_used_. - int decode (const unsigned char *data_, std::size_t size_, - std::size_t &bytes_used_) - { - bytes_used_ = 0; - - // In case of zero-copy simply adjust the pointers, no copying - // is required. Also, run the state machine in case all the data - // were processed. - if (data_ == read_pos) { - zmq_assert (size_ <= to_read); - read_pos += size_; - to_read -= size_; - bytes_used_ = size_; - - while (!to_read) { - const int rc = - (static_cast (this)->*next) (data_ + bytes_used_); - if (rc != 0) - return rc; - } - return 0; - } - - while (bytes_used_ < size_) { - // Copy the data from buffer to the message. - const size_t to_copy = std::min (to_read, size_ - bytes_used_); - // Only copy when destination address is different from the - // current address in the buffer. - if (read_pos != data_ + bytes_used_) { - memcpy (read_pos, data_ + bytes_used_, to_copy); - } - - read_pos += to_copy; - to_read -= to_copy; - bytes_used_ += to_copy; - // Try to get more space in the message to fill in. - // If none is available, return. - while (to_read == 0) { - // pass current address in the buffer - const int rc = - (static_cast (this)->*next) (data_ + bytes_used_); - if (rc != 0) - return rc; - } - } - - return 0; - } - - virtual void resize_buffer (std::size_t new_size) - { - allocator->resize (new_size); - } - - protected: - - // Prototype of state machine action. Action should return false if - // it is unable to push the data to the system. - typedef int (T:: *step_t) (unsigned char const *); - - // This function should be called from derived class to read data - // from the buffer and schedule next state machine action. - void next_step (void *read_pos_, std::size_t to_read_, step_t next_) - { - read_pos = static_cast (read_pos_); - to_read = to_read_; - next = next_; - } - - private: - - // Next step. If set to NULL, it means that associated data stream - // is dead. Note that there can be still data in the process in such - // case. - step_t next; - - // Where to store the read data. - unsigned char *read_pos; - - // How much data to read before taking next step. - std::size_t to_read; - - // The duffer for data to decode. - A *allocator; - unsigned char *buf; - - decoder_base_t (const decoder_base_t &); - const decoder_base_t &operator = (const decoder_base_t &); - }; -} - -#endif diff --git a/dep/libzmq/src/decoder_allocators.cpp b/dep/libzmq/src/decoder_allocators.cpp deleted file mode 100644 index c49e2696e1..0000000000 --- a/dep/libzmq/src/decoder_allocators.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "decoder_allocators.hpp" - -#include - -#include "msg.hpp" - -zmq::shared_message_memory_allocator::shared_message_memory_allocator (std::size_t bufsize_) : - buf(NULL), - bufsize(0), - max_size(bufsize_), - msg_content(NULL), - maxCounters (static_cast (std::ceil (static_cast (max_size) / static_cast (msg_t::max_vsm_size)))) -{ -} - -zmq::shared_message_memory_allocator::shared_message_memory_allocator (std::size_t bufsize_, std::size_t maxMessages) : - buf(NULL), - bufsize(0), - max_size(bufsize_), - msg_content(NULL), - maxCounters(maxMessages) -{ -} - -zmq::shared_message_memory_allocator::~shared_message_memory_allocator () -{ - deallocate(); -} - -unsigned char* zmq::shared_message_memory_allocator::allocate () -{ - if (buf) { - // release reference count to couple lifetime to messages - zmq::atomic_counter_t* c = reinterpret_cast(buf); - - // if refcnt drops to 0, there are no message using the buffer - // because either all messages have been closed or only vsm-messages - // were created - if (c->sub (1)) { - // buffer is still in use as message data. "Release" it and create a new one - // release pointer because we are going to create a new buffer - release (); - } - } - - // if buf != NULL it is not used by any message so we can re-use it for the next run - if (!buf) { - // allocate memory for reference counters together with reception buffer - std::size_t const allocationsize = - max_size + sizeof (zmq::atomic_counter_t) + - maxCounters * sizeof (zmq::msg_t::content_t); - - buf = static_cast (std::malloc (allocationsize)); - alloc_assert (buf); - - new (buf) atomic_counter_t (1); - } else { - // release reference count to couple lifetime to messages - zmq::atomic_counter_t *c = reinterpret_cast (buf); - c->set (1); - } - - bufsize = max_size; - msg_content = reinterpret_cast (buf + sizeof (atomic_counter_t) + max_size); - return buf + sizeof (zmq::atomic_counter_t); -} - -void zmq::shared_message_memory_allocator::deallocate () -{ - zmq::atomic_counter_t* c = reinterpret_cast(buf); - if (buf && !c->sub(1)) { - std::free(buf); - } - release(); -} - -unsigned char* zmq::shared_message_memory_allocator::release () -{ - unsigned char* b = buf; - buf = NULL; - bufsize = 0; - msg_content = NULL; - - return b; -} - -void zmq::shared_message_memory_allocator::inc_ref () -{ - (reinterpret_cast (buf))->add (1); -} - -void zmq::shared_message_memory_allocator::call_dec_ref(void*, void* hint) -{ - zmq_assert (hint); - unsigned char* buf = static_cast (hint); - zmq::atomic_counter_t* c = reinterpret_cast (buf); - - if (!c->sub (1)) { - c->~atomic_counter_t (); - std::free (buf); - buf = NULL; - } -} - - -std::size_t zmq::shared_message_memory_allocator::size () const -{ - return bufsize; -} - -unsigned char* zmq::shared_message_memory_allocator::data () -{ - return buf + sizeof (zmq::atomic_counter_t); -} diff --git a/dep/libzmq/src/decoder_allocators.hpp b/dep/libzmq/src/decoder_allocators.hpp deleted file mode 100644 index 30cfaf1aa5..0000000000 --- a/dep/libzmq/src/decoder_allocators.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DECODER_ALLOCATORS_HPP_INCLUDED__ -#define __ZMQ_DECODER_ALLOCATORS_HPP_INCLUDED__ - -#include -#include - -#include "atomic_counter.hpp" -#include "msg.hpp" -#include "err.hpp" - -namespace zmq -{ - // Static buffer policy. - class c_single_allocator - { - public: - explicit c_single_allocator (std::size_t bufsize_) : - bufsize(bufsize_), - buf(static_cast (std::malloc (bufsize))) - { - alloc_assert (buf); - } - - ~c_single_allocator () - { - std::free (buf); - } - - unsigned char* allocate () - { - return buf; - } - - void deallocate () - { - } - - std::size_t size () const - { - return bufsize; - } - - void resize (std::size_t new_size) - { - bufsize = new_size; - } - private: - std::size_t bufsize; - unsigned char* buf; - - c_single_allocator (c_single_allocator const&); - c_single_allocator& operator = (c_single_allocator const&); - }; - - // This allocator allocates a reference counted buffer which is used by v2_decoder_t - // to use zero-copy msg::init_data to create messages with memory from this buffer as - // data storage. - // - // The buffer is allocated with a reference count of 1 to make sure that is is alive while - // decoding messages. Otherwise, it is possible that e.g. the first message increases the count - // from zero to one, gets passed to the user application, processed in the user thread and deleted - // which would then deallocate the buffer. The drawback is that the buffer may be allocated longer - // than necessary because it is only deleted when allocate is called the next time. - class shared_message_memory_allocator - { - public: - explicit shared_message_memory_allocator (std::size_t bufsize_); - - // Create an allocator for a maximum number of messages - shared_message_memory_allocator (std::size_t bufsize_, std::size_t maxMessages); - - ~shared_message_memory_allocator (); - - // Allocate a new buffer - // - // This releases the current buffer to be bound to the lifetime of the messages - // created on this buffer. - unsigned char* allocate (); - - // force deallocation of buffer. - void deallocate (); - - // Give up ownership of the buffer. The buffer's lifetime is now coupled to - // the messages constructed on top of it. - unsigned char* release (); - - void inc_ref (); - - static void call_dec_ref (void*, void* buffer); - - std::size_t size () const; - - // Return pointer to the first message data byte. - unsigned char* data (); - - // Return pointer to the first byte of the buffer. - unsigned char* buffer () - { - return buf; - } - - void resize (std::size_t new_size) - { - bufsize = new_size; - } - - zmq::msg_t::content_t* provide_content () - { - return msg_content; - } - - void advance_content () - { - msg_content++; - } - - private: - unsigned char* buf; - std::size_t bufsize; - std::size_t max_size; - zmq::msg_t::content_t* msg_content; - std::size_t maxCounters; - }; -} - -#endif diff --git a/dep/libzmq/src/devpoll.cpp b/dep/libzmq/src/devpoll.cpp deleted file mode 100644 index 99c8277708..0000000000 --- a/dep/libzmq/src/devpoll.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "devpoll.hpp" -#if defined ZMQ_USE_DEVPOLL - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "devpoll.hpp" -#include "err.hpp" -#include "config.hpp" -#include "i_poll_events.hpp" - -zmq::devpoll_t::devpoll_t (const zmq::ctx_t &ctx_) : - ctx(ctx_), - stopping (false) -{ - devpoll_fd = open ("/dev/poll", O_RDWR); - errno_assert (devpoll_fd != -1); -} - -zmq::devpoll_t::~devpoll_t () -{ - worker.stop (); - close (devpoll_fd); -} - -void zmq::devpoll_t::devpoll_ctl (fd_t fd_, short events_) -{ - struct pollfd pfd = {fd_, events_, 0}; - ssize_t rc = write (devpoll_fd, &pfd, sizeof pfd); - zmq_assert (rc == sizeof pfd); -} - -zmq::devpoll_t::handle_t zmq::devpoll_t::add_fd (fd_t fd_, - i_poll_events *reactor_) -{ - // If the file descriptor table is too small expand it. - fd_table_t::size_type sz = fd_table.size (); - if (sz <= (fd_table_t::size_type) fd_) { - fd_table.resize (fd_ + 1); - while (sz != (fd_table_t::size_type) (fd_ + 1)) { - fd_table [sz].valid = false; - ++sz; - } - } - - zmq_assert (!fd_table [fd_].valid); - - fd_table [fd_].events = 0; - fd_table [fd_].reactor = reactor_; - fd_table [fd_].valid = true; - fd_table [fd_].accepted = false; - - devpoll_ctl (fd_, 0); - pending_list.push_back (fd_); - - // Increase the load metric of the thread. - adjust_load (1); - - return fd_; -} - -void zmq::devpoll_t::rm_fd (handle_t handle_) -{ - zmq_assert (fd_table [handle_].valid); - - devpoll_ctl (handle_, POLLREMOVE); - fd_table [handle_].valid = false; - - // Decrease the load metric of the thread. - adjust_load (-1); -} - -void zmq::devpoll_t::set_pollin (handle_t handle_) -{ - devpoll_ctl (handle_, POLLREMOVE); - fd_table [handle_].events |= POLLIN; - devpoll_ctl (handle_, fd_table [handle_].events); -} - -void zmq::devpoll_t::reset_pollin (handle_t handle_) -{ - devpoll_ctl (handle_, POLLREMOVE); - fd_table [handle_].events &= ~((short) POLLIN); - devpoll_ctl (handle_, fd_table [handle_].events); -} - -void zmq::devpoll_t::set_pollout (handle_t handle_) -{ - devpoll_ctl (handle_, POLLREMOVE); - fd_table [handle_].events |= POLLOUT; - devpoll_ctl (handle_, fd_table [handle_].events); -} - -void zmq::devpoll_t::reset_pollout (handle_t handle_) -{ - devpoll_ctl (handle_, POLLREMOVE); - fd_table [handle_].events &= ~((short) POLLOUT); - devpoll_ctl (handle_, fd_table [handle_].events); -} - -void zmq::devpoll_t::start () -{ - ctx.start_thread (worker, worker_routine, this); -} - -void zmq::devpoll_t::stop () -{ - stopping = true; -} - -int zmq::devpoll_t::max_fds () -{ - return -1; -} - -void zmq::devpoll_t::loop () -{ - while (!stopping) { - - struct pollfd ev_buf [max_io_events]; - struct dvpoll poll_req; - - for (pending_list_t::size_type i = 0; i < pending_list.size (); i ++) - fd_table [pending_list [i]].accepted = true; - pending_list.clear (); - - // Execute any due timers. - int timeout = (int) execute_timers (); - - // Wait for events. - // On Solaris, we can retrieve no more then (OPEN_MAX - 1) events. - poll_req.dp_fds = &ev_buf [0]; -#if defined ZMQ_HAVE_SOLARIS - poll_req.dp_nfds = std::min ((int) max_io_events, OPEN_MAX - 1); -#else - poll_req.dp_nfds = max_io_events; -#endif - poll_req.dp_timeout = timeout ? timeout : -1; - int n = ioctl (devpoll_fd, DP_POLL, &poll_req); - if (n == -1 && errno == EINTR) - continue; - errno_assert (n != -1); - - for (int i = 0; i < n; i ++) { - - fd_entry_t *fd_ptr = &fd_table [ev_buf [i].fd]; - if (!fd_ptr->valid || !fd_ptr->accepted) - continue; - if (ev_buf [i].revents & (POLLERR | POLLHUP)) - fd_ptr->reactor->in_event (); - if (!fd_ptr->valid || !fd_ptr->accepted) - continue; - if (ev_buf [i].revents & POLLOUT) - fd_ptr->reactor->out_event (); - if (!fd_ptr->valid || !fd_ptr->accepted) - continue; - if (ev_buf [i].revents & POLLIN) - fd_ptr->reactor->in_event (); - } - } -} - -void zmq::devpoll_t::worker_routine (void *arg_) -{ - ((devpoll_t*) arg_)->loop (); -} - -#endif diff --git a/dep/libzmq/src/devpoll.hpp b/dep/libzmq/src/devpoll.hpp deleted file mode 100644 index 3d939b5549..0000000000 --- a/dep/libzmq/src/devpoll.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DEVPOLL_HPP_INCLUDED__ -#define __ZMQ_DEVPOLL_HPP_INCLUDED__ - -// poller.hpp decides which polling mechanism to use. -#include "poller.hpp" -#if defined ZMQ_USE_DEVPOLL - -#include - -#include "ctx.hpp" -#include "fd.hpp" -#include "thread.hpp" -#include "poller_base.hpp" - -namespace zmq -{ - - struct i_poll_events; - - // Implements socket polling mechanism using the "/dev/poll" interface. - - class devpoll_t : public poller_base_t - { - public: - - typedef fd_t handle_t; - - devpoll_t (const ctx_t &ctx_); - ~devpoll_t (); - - // "poller" concept. - handle_t add_fd (fd_t fd_, zmq::i_poll_events *events_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void start (); - void stop (); - - static int max_fds (); - - private: - - // Main worker thread routine. - static void worker_routine (void *arg_); - - // Main event loop. - void loop (); - - // Reference to ZMQ context. - const ctx_t &ctx; - - // File descriptor referring to "/dev/poll" pseudo-device. - fd_t devpoll_fd; - - struct fd_entry_t - { - short events; - zmq::i_poll_events *reactor; - bool valid; - bool accepted; - }; - - typedef std::vector fd_table_t; - fd_table_t fd_table; - - typedef std::vector pending_list_t; - pending_list_t pending_list; - - // Pollset manipulation function. - void devpoll_ctl (fd_t fd_, short events_); - - // If true, thread is in the process of shutting down. - bool stopping; - - // Handle of the physical thread doing the I/O work. - thread_t worker; - - devpoll_t (const devpoll_t&); - const devpoll_t &operator = (const devpoll_t&); - }; - - typedef devpoll_t poller_t; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/dgram.cpp b/dep/libzmq/src/dgram.cpp deleted file mode 100644 index 2c1d20f779..0000000000 --- a/dep/libzmq/src/dgram.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright (c) 2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "dgram.hpp" -#include "pipe.hpp" -#include "wire.hpp" -#include "random.hpp" -#include "likely.hpp" -#include "err.hpp" - -zmq::dgram_t::dgram_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - pipe (NULL), - last_in (NULL), - more_out (false) -{ - options.type = ZMQ_DGRAM; - options.raw_socket = true; -} - -zmq::dgram_t::~dgram_t () -{ - zmq_assert (!pipe); -} - -void zmq::dgram_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED(subscribe_to_all_); - - zmq_assert (pipe_); - - // ZMQ_DGRAM socket can only be connected to a single peer. - // The socket rejects any further connection requests. - if (pipe == NULL) - pipe = pipe_; - else - pipe_->terminate (false); -} - -void zmq::dgram_t::xpipe_terminated (pipe_t *pipe_) -{ - if (pipe_ == pipe) { - if (last_in == pipe) { - saved_credential.set_deep_copy (last_in->get_credential ()); - last_in = NULL; - } - pipe = NULL; - } -} - -void zmq::dgram_t::xread_activated (pipe_t *) -{ - // There's just one pipe. No lists of active and inactive pipes. - // There's nothing to do here. -} - -void zmq::dgram_t::xwrite_activated (pipe_t *) -{ - // There's just one pipe. No lists of active and inactive pipes. - // There's nothing to do here. -} - -int zmq::dgram_t::xsend (msg_t *msg_) -{ - // If there's no out pipe, just drop it. - if (!pipe) { - int rc = msg_->close (); - errno_assert (rc == 0); - return -1; - } - - // If this is the first part of the message it's the ID of the - // peer to send the message to. - if (!more_out) { - if (!(msg_->flags () & msg_t::more)) { - errno = EINVAL; - return -1; - } - - // Expect one more message frame. - more_out = true; - } - else { - - // dgram messages are two part only, reject part if more is set - if (msg_->flags () & msg_t::more) { - errno = EINVAL; - return -1; - } - - // This is the last part of the message. - more_out = false; - } - - // Push the message into the pipe. - if (!pipe->write (msg_)) { - errno = EAGAIN; - return -1; - } - - if (!(msg_->flags () & msg_t::more)) - pipe->flush (); - - // Detach the message from the data buffer. - int rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -int zmq::dgram_t::xrecv (msg_t *msg_) -{ - // Deallocate old content of the message. - int rc = msg_->close (); - errno_assert (rc == 0); - - if (!pipe || !pipe->read (msg_)) { - // Initialise the output parameter to be a 0-byte message. - rc = msg_->init (); - errno_assert (rc == 0); - - errno = EAGAIN; - return -1; - } - last_in = pipe; - - return 0; -} - -bool zmq::dgram_t::xhas_in () -{ - if (!pipe) - return false; - - return pipe->check_read (); -} - -bool zmq::dgram_t::xhas_out () -{ - if (!pipe) - return false; - - return pipe->check_write (); -} - -const zmq::blob_t &zmq::dgram_t::get_credential () const -{ - return last_in? last_in->get_credential (): saved_credential; -} diff --git a/dep/libzmq/src/dgram.hpp b/dep/libzmq/src/dgram.hpp deleted file mode 100644 index 82980776bf..0000000000 --- a/dep/libzmq/src/dgram.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (c) 2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DGRAM_HPP_INCLUDED__ -#define __ZMQ_DGRAM_HPP_INCLUDED__ - -#include "blob.hpp" -#include "socket_base.hpp" -#include "session_base.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - class io_thread_t; - - class dgram_t : - public socket_base_t - { - public: - - dgram_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~dgram_t (); - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - zmq::pipe_t *pipe; - - zmq::pipe_t *last_in; - - blob_t saved_credential; - - // If true, more outgoing message parts are expected. - bool more_out; - - dgram_t (const dgram_t&); - const dgram_t &operator = (const dgram_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/dish.cpp b/dep/libzmq/src/dish.cpp deleted file mode 100644 index 1112926a75..0000000000 --- a/dep/libzmq/src/dish.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "macros.hpp" -#include "dish.hpp" -#include "err.hpp" - -zmq::dish_t::dish_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_, true), - has_message (false) -{ - options.type = ZMQ_DISH; - - // When socket is being closed down we don't want to wait till pending - // subscription commands are sent to the wire. - options.linger = 0; - - int rc = message.init (); - errno_assert (rc == 0); -} - -zmq::dish_t::~dish_t () -{ - int rc = message.close (); - errno_assert (rc == 0); -} - -void zmq::dish_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - fq.attach (pipe_); - dist.attach (pipe_); - - // Send all the cached subscriptions to the new upstream peer. - send_subscriptions (pipe_); -} - -void zmq::dish_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::dish_t::xwrite_activated (pipe_t *pipe_) -{ - dist.activated (pipe_); -} - -void zmq::dish_t::xpipe_terminated (pipe_t *pipe_) -{ - fq.pipe_terminated (pipe_); - dist.pipe_terminated (pipe_); -} - -void zmq::dish_t::xhiccuped (pipe_t *pipe_) -{ - // Send all the cached subscriptions to the hiccuped pipe. - send_subscriptions (pipe_); -} - -int zmq::dish_t::xjoin (const char* group_) -{ - std::string group = std::string (group_); - - if (group.length () > ZMQ_GROUP_MAX_LENGTH) { - errno = EINVAL; - return -1; - } - - subscriptions_t::iterator it = subscriptions.find (group); - - // User cannot join same group twice - if (it != subscriptions.end ()) { - errno = EINVAL; - return -1; - } - - subscriptions.insert (group); - - msg_t msg; - int rc = msg.init_join (); - errno_assert (rc == 0); - - rc = msg.set_group (group_); - errno_assert (rc == 0); - - int err = 0; - rc = dist.send_to_all (&msg); - if (rc != 0) - err = errno; - int rc2 = msg.close (); - errno_assert (rc2 == 0); - if (rc != 0) - errno = err; - return rc; -} - -int zmq::dish_t::xleave (const char* group_) -{ - std::string group = std::string (group_); - - if (group.length () > ZMQ_GROUP_MAX_LENGTH) { - errno = EINVAL; - return -1; - } - - subscriptions_t::iterator it = std::find (subscriptions.begin (), subscriptions.end (), group); - - if (it == subscriptions.end ()) { - errno = EINVAL; - return -1; - } - - subscriptions.erase (it); - - msg_t msg; - int rc = msg.init_leave (); - errno_assert (rc == 0); - - rc = msg.set_group (group_); - errno_assert (rc == 0); - - int err = 0; - rc = dist.send_to_all (&msg); - if (rc != 0) - err = errno; - int rc2 = msg.close (); - errno_assert (rc2 == 0); - if (rc != 0) - errno = err; - return rc; -} - -int zmq::dish_t::xsend (msg_t *msg_) -{ - LIBZMQ_UNUSED (msg_); - errno = ENOTSUP; - return -1; -} - -bool zmq::dish_t::xhas_out () -{ - // Subscription can be added/removed anytime. - return true; -} - -int zmq::dish_t::xrecv (msg_t *msg_) -{ - // If there's already a message prepared by a previous call to zmq_poll, - // return it straight ahead. - if (has_message) { - int rc = msg_->move (message); - errno_assert (rc == 0); - has_message = false; - return 0; - } - - while (true) { - - // Get a message using fair queueing algorithm. - int rc = fq.recv (msg_); - - // If there's no message available, return immediately. - // The same when error occurs. - if (rc != 0) - return -1; - - // Filtering non matching messages - subscriptions_t::iterator it = subscriptions.find (std::string(msg_->group ())); - if (it != subscriptions.end ()) - return 0; - } -} - -bool zmq::dish_t::xhas_in () -{ - // If there's already a message prepared by a previous call to zmq_poll, - // return straight ahead. - if (has_message) - return true; - - while (true) { - // Get a message using fair queueing algorithm. - int rc = fq.recv (&message); - - // If there's no message available, return immediately. - // The same when error occurs. - if (rc != 0) { - errno_assert (errno == EAGAIN); - return false; - } - - // Filtering non matching messages - subscriptions_t::iterator it = subscriptions.find (std::string(message.group ())); - if (it != subscriptions.end ()) { - has_message = true; - return true; - } - } -} - -const zmq::blob_t &zmq::dish_t::get_credential () const -{ - return fq.get_credential (); -} - -void zmq::dish_t::send_subscriptions (pipe_t *pipe_) -{ - for (subscriptions_t::iterator it = subscriptions.begin (); it != subscriptions.end (); ++it) { - msg_t msg; - int rc = msg.init_join (); - errno_assert (rc == 0); - - rc = msg.set_group (it->c_str()); - errno_assert (rc == 0); - - // Send it to the pipe. - pipe_->write (&msg); - msg.close (); - } - - pipe_->flush (); -} - -zmq::dish_session_t::dish_session_t (io_thread_t *io_thread_, bool connect_, - socket_base_t *socket_, const options_t &options_, - address_t *addr_) : - session_base_t (io_thread_, connect_, socket_, options_, addr_), - state (group) -{ -} - -zmq::dish_session_t::~dish_session_t () -{ -} - -int zmq::dish_session_t::push_msg (msg_t *msg_) -{ - if (state == group) { - if ((msg_->flags() & msg_t::more) != msg_t::more) { - errno = EFAULT; - return -1; - } - - if (msg_->size() > ZMQ_GROUP_MAX_LENGTH) { - errno = EFAULT; - return -1; - } - - group_msg = *msg_; - state = body; - - int rc = msg_->init (); - errno_assert (rc == 0); - return 0; - } - else { - // Set the message group - int rc = msg_->set_group ((char*)group_msg.data (), group_msg. size()); - errno_assert (rc == 0); - - // We set the group, so we don't need the group_msg anymore - rc = group_msg.close (); - errno_assert (rc == 0); - - // Thread safe socket doesn't support multipart messages - if ((msg_->flags() & msg_t::more) == msg_t::more) { - errno = EFAULT; - return -1; - } - - // Push message to dish socket - rc = session_base_t::push_msg (msg_); - - if (rc == 0) - state = group; - - return rc; - } -} - -int zmq::dish_session_t::pull_msg (msg_t *msg_) -{ - int rc = session_base_t::pull_msg (msg_); - - if (rc != 0) - return rc; - - if (!msg_->is_join () && !msg_->is_leave ()) - return rc; - else { - int group_length = (int) strlen (msg_->group ()); - - msg_t command; - int offset; - - if (msg_->is_join ()) { - rc = command.init_size (group_length + 5); - errno_assert(rc == 0); - offset = 5; - memcpy (command.data (), "\4JOIN", 5); - } - else { - rc = command.init_size (group_length + 6); - errno_assert(rc == 0); - offset = 6; - memcpy (command.data (), "\5LEAVE", 6); - } - - command.set_flags (msg_t::command); - char* command_data = (char*)command.data (); - - // Copy the group - memcpy (command_data + offset, msg_->group (), group_length); - - // Close the join message - rc = msg_->close (); - errno_assert (rc == 0); - - *msg_ = command; - - return 0; - } -} - -void zmq::dish_session_t::reset () -{ - session_base_t::reset (); - state = group; -} diff --git a/dep/libzmq/src/dish.hpp b/dep/libzmq/src/dish.hpp deleted file mode 100644 index 2dd0d2f143..0000000000 --- a/dep/libzmq/src/dish.hpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DISH_HPP_INCLUDED__ -#define __ZMQ_DISH_HPP_INCLUDED__ - -#include -#include - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "dist.hpp" -#include "fq.hpp" -#include "trie.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - class io_thread_t; - - class dish_t : - public socket_base_t - { - public: - - dish_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~dish_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xhiccuped (pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - int xjoin (const char *group_); - int xleave (const char *group_); - private: - - // Send subscriptions to a pipe - void send_subscriptions (pipe_t *pipe_); - - // Fair queueing object for inbound pipes. - fq_t fq; - - // Object for distributing the subscriptions upstream. - dist_t dist; - - // The repository of subscriptions. - typedef std::set subscriptions_t; - subscriptions_t subscriptions; - - // If true, 'message' contains a matching message to return on the - // next recv call. - bool has_message; - msg_t message; - - dish_t (const dish_t&); - const dish_t &operator = (const dish_t&); - }; - - class dish_session_t : public session_base_t - { - public: - - dish_session_t (zmq::io_thread_t *io_thread_, bool connect_, - zmq::socket_base_t *socket_, const options_t &options_, - address_t *addr_); - ~dish_session_t (); - - // Overrides of the functions from session_base_t. - int push_msg (msg_t *msg_); - int pull_msg (msg_t *msg_); - void reset (); - - private: - - enum { - group, - body - } state; - - msg_t group_msg; - - dish_session_t (const dish_session_t&); - const dish_session_t &operator = (const dish_session_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/dist.cpp b/dep/libzmq/src/dist.cpp deleted file mode 100644 index 8b306fa68c..0000000000 --- a/dep/libzmq/src/dist.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "dist.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "likely.hpp" - -zmq::dist_t::dist_t () : - matching (0), - active (0), - eligible (0), - more (false) -{ -} - -zmq::dist_t::~dist_t () -{ - zmq_assert (pipes.empty ()); -} - -void zmq::dist_t::attach (pipe_t *pipe_) -{ - // If we are in the middle of sending a message, we'll add new pipe - // into the list of eligible pipes. Otherwise we add it to the list - // of active pipes. - if (more) { - pipes.push_back (pipe_); - pipes.swap (eligible, pipes.size () - 1); - eligible++; - } - else { - pipes.push_back (pipe_); - pipes.swap (active, pipes.size () - 1); - active++; - eligible++; - } -} - -void zmq::dist_t::match (pipe_t *pipe_) -{ - // If pipe is already matching do nothing. - if (pipes.index (pipe_) < matching) - return; - - // If the pipe isn't eligible, ignore it. - if (pipes.index (pipe_) >= eligible) - return; - - // Mark the pipe as matching. - pipes.swap (pipes.index (pipe_), matching); - matching++; -} - -void zmq::dist_t::reverse_match () -{ - pipes_t::size_type prev_matching = matching; - - // Reset matching to 0 - unmatch(); - - // Mark all matching pipes as not matching and vice-versa. - // To do this, push all pipes that are eligible but not - // matched - i.e. between "matching" and "eligible" - - // to the beginning of the queue. - for (pipes_t::size_type i = prev_matching; i < eligible; ++i) { - pipes.swap(i, matching++); - } -} - -void zmq::dist_t::unmatch () -{ - matching = 0; -} - -void zmq::dist_t::pipe_terminated (pipe_t *pipe_) -{ - // Remove the pipe from the list; adjust number of matching, active and/or - // eligible pipes accordingly. - if (pipes.index (pipe_) < matching) { - pipes.swap (pipes.index (pipe_), matching - 1); - matching--; - } - if (pipes.index (pipe_) < active) { - pipes.swap (pipes.index (pipe_), active - 1); - active--; - } - if (pipes.index (pipe_) < eligible) { - pipes.swap (pipes.index (pipe_), eligible - 1); - eligible--; - } - - pipes.erase (pipe_); -} - -void zmq::dist_t::activated (pipe_t *pipe_) -{ - // Move the pipe from passive to eligible state. - if (eligible < pipes.size ()) { - pipes.swap (pipes.index (pipe_), eligible); - eligible++; - } - - // If there's no message being sent at the moment, move it to - // the active state. - if (!more && active < pipes.size ()) { - pipes.swap (eligible - 1, active); - active++; - } -} - -int zmq::dist_t::send_to_all (msg_t *msg_) -{ - matching = active; - return send_to_matching (msg_); -} - -int zmq::dist_t::send_to_matching (msg_t *msg_) -{ - // Is this end of a multipart message? - bool msg_more = msg_->flags () & msg_t::more ? true : false; - - // Push the message to matching pipes. - distribute (msg_); - - // If multipart message is fully sent, activate all the eligible pipes. - if (!msg_more) - active = eligible; - - more = msg_more; - - return 0; -} - -void zmq::dist_t::distribute (msg_t *msg_) -{ - // If there are no matching pipes available, simply drop the message. - if (matching == 0) { - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - return; - } - - if (msg_->is_vsm ()) { - for (pipes_t::size_type i = 0; i < matching; ++i) - if(!write (pipes [i], msg_)) - --i; // Retry last write because index will have been swapped - int rc = msg_->close(); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - return; - } - - // Add matching-1 references to the message. We already hold one reference, - // that's why -1. - msg_->add_refs ((int) matching - 1); - - // Push copy of the message to each matching pipe. - int failed = 0; - for (pipes_t::size_type i = 0; i < matching; ++i) - if (!write (pipes [i], msg_)) { - ++failed; - --i; // Retry last write because index will have been swapped - } - if (unlikely (failed)) - msg_->rm_refs (failed); - - // Detach the original message from the data buffer. Note that we don't - // close the message. That's because we've already used all the references. - int rc = msg_->init (); - errno_assert (rc == 0); -} - -bool zmq::dist_t::has_out () -{ - return true; -} - -bool zmq::dist_t::write (pipe_t *pipe_, msg_t *msg_) -{ - if (!pipe_->write (msg_)) { - pipes.swap (pipes.index (pipe_), matching - 1); - matching--; - pipes.swap (pipes.index (pipe_), active - 1); - active--; - pipes.swap (active, eligible - 1); - eligible--; - return false; - } - if (!(msg_->flags () & msg_t::more)) - pipe_->flush (); - return true; -} - -bool zmq::dist_t::check_hwm () -{ - for (pipes_t::size_type i = 0; i < matching; ++i) - if (!pipes [i]->check_hwm ()) - return false; - - return true; -} - - diff --git a/dep/libzmq/src/dist.hpp b/dep/libzmq/src/dist.hpp deleted file mode 100644 index 9500d87717..0000000000 --- a/dep/libzmq/src/dist.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DIST_HPP_INCLUDED__ -#define __ZMQ_DIST_HPP_INCLUDED__ - -#include - -#include "array.hpp" -#include "pipe.hpp" - -namespace zmq -{ - - class pipe_t; - class msg_t; - - // Class manages a set of outbound pipes. It sends each messages to - // each of them. - class dist_t - { - public: - - dist_t (); - ~dist_t (); - - // Adds the pipe to the distributor object. - void attach (zmq::pipe_t *pipe_); - - // Activates pipe that have previously reached high watermark. - void activated (zmq::pipe_t *pipe_); - - // Mark the pipe as matching. Subsequent call to send_to_matching - // will send message also to this pipe. - void match (zmq::pipe_t *pipe_); - - // Marks all pipes that are not matched as matched and vice-versa. - void reverse_match(); - - // Mark all pipes as non-matching. - void unmatch (); - - // Removes the pipe from the distributor object. - void pipe_terminated (zmq::pipe_t *pipe_); - - // Send the message to the matching outbound pipes. - int send_to_matching (zmq::msg_t *msg_); - - // Send the message to all the outbound pipes. - int send_to_all (zmq::msg_t *msg_); - - bool has_out (); - - // check HWM of all pipes matching - bool check_hwm (); - - private: - - // Write the message to the pipe. Make the pipe inactive if writing - // fails. In such a case false is returned. - bool write (zmq::pipe_t *pipe_, zmq::msg_t *msg_); - - // Put the message to all active pipes. - void distribute (zmq::msg_t *msg_); - - // List of outbound pipes. - typedef array_t pipes_t; - pipes_t pipes; - - // Number of all the pipes to send the next message to. - pipes_t::size_type matching; - - // Number of active pipes. All the active pipes are located at the - // beginning of the pipes array. These are the pipes the messages - // can be sent to at the moment. - pipes_t::size_type active; - - // Number of pipes eligible for sending messages to. This includes all - // the active pipes plus all the pipes that we can in theory send - // messages to (the HWM is not yet reached), but sending a message - // to them would result in partial message being delivered, ie. message - // with initial parts missing. - pipes_t::size_type eligible; - - // True if last we are in the middle of a multipart message. - bool more; - - dist_t (const dist_t&); - const dist_t &operator = (const dist_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/encoder.hpp b/dep/libzmq/src/encoder.hpp deleted file mode 100644 index 66a7adaa1d..0000000000 --- a/dep/libzmq/src/encoder.hpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ENCODER_HPP_INCLUDED__ -#define __ZMQ_ENCODER_HPP_INCLUDED__ - -#if defined(_MSC_VER) -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif - -#include -#include -#include -#include - -#include "err.hpp" -#include "msg.hpp" -#include "i_encoder.hpp" - -namespace zmq -{ - - // Helper base class for encoders. It implements the state machine that - // fills the outgoing buffer. Derived classes should implement individual - // state machine actions. - - template class encoder_base_t : public i_encoder - { - public: - - inline encoder_base_t (size_t bufsize_) : - write_pos(0), - to_write(0), - next(NULL), - new_msg_flag(false), - bufsize (bufsize_), - in_progress (NULL) - { - buf = (unsigned char*) malloc (bufsize_); - alloc_assert (buf); - } - - // The destructor doesn't have to be virtual. It is made virtual - // just to keep ICC and code checking tools from complaining. - inline virtual ~encoder_base_t () - { - free (buf); - } - - // The function returns a batch of binary data. The data - // are filled to a supplied buffer. If no buffer is supplied (data_ - // points to NULL) decoder object will provide buffer of its own. - inline size_t encode (unsigned char **data_, size_t size_) - { - unsigned char *buffer = !*data_ ? buf : *data_; - size_t buffersize = !*data_ ? bufsize : size_; - - if (in_progress == NULL) - return 0; - - size_t pos = 0; - while (pos < buffersize) { - - // If there are no more data to return, run the state machine. - // If there are still no data, return what we already have - // in the buffer. - if (!to_write) { - if (new_msg_flag) { - int rc = in_progress->close (); - errno_assert (rc == 0); - rc = in_progress->init (); - errno_assert (rc == 0); - in_progress = NULL; - break; - } - (static_cast (this)->*next) (); - } - - // If there are no data in the buffer yet and we are able to - // fill whole buffer in a single go, let's use zero-copy. - // There's no disadvantage to it as we cannot stuck multiple - // messages into the buffer anyway. Note that subsequent - // write(s) are non-blocking, thus each single write writes - // at most SO_SNDBUF bytes at once not depending on how large - // is the chunk returned from here. - // As a consequence, large messages being sent won't block - // other engines running in the same I/O thread for excessive - // amounts of time. - if (!pos && !*data_ && to_write >= buffersize) { - *data_ = write_pos; - pos = to_write; - write_pos = NULL; - to_write = 0; - return pos; - } - - // Copy data to the buffer. If the buffer is full, return. - size_t to_copy = std::min (to_write, buffersize - pos); - memcpy (buffer + pos, write_pos, to_copy); - pos += to_copy; - write_pos += to_copy; - to_write -= to_copy; - } - - *data_ = buffer; - return pos; - } - - void load_msg (msg_t *msg_) - { - zmq_assert (in_progress == NULL); - in_progress = msg_; - (static_cast (this)->*next) (); - } - - protected: - - // Prototype of state machine action. - typedef void (T::*step_t) (); - - // This function should be called from derived class to write the data - // to the buffer and schedule next state machine action. - inline void next_step (void *write_pos_, size_t to_write_, - step_t next_, bool new_msg_flag_) - { - write_pos = (unsigned char*) write_pos_; - to_write = to_write_; - next = next_; - new_msg_flag = new_msg_flag_; - } - - private: - - // Where to get the data to write from. - unsigned char *write_pos; - - // How much data to write before next step should be executed. - size_t to_write; - - // Next step. If set to NULL, it means that associated data stream - // is dead. - step_t next; - - bool new_msg_flag; - - // The buffer for encoded data. - size_t bufsize; - unsigned char *buf; - - encoder_base_t (const encoder_base_t&); - void operator = (const encoder_base_t&); - - protected: - - msg_t *in_progress; - - }; -} - -#endif - diff --git a/dep/libzmq/src/epoll.cpp b/dep/libzmq/src/epoll.cpp deleted file mode 100644 index be7ad61d83..0000000000 --- a/dep/libzmq/src/epoll.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "epoll.hpp" -#if defined ZMQ_USE_EPOLL - -#include -#include -#include -#include -#include -#include - -#include "macros.hpp" -#include "epoll.hpp" -#include "err.hpp" -#include "config.hpp" -#include "i_poll_events.hpp" - -zmq::epoll_t::epoll_t (const zmq::ctx_t &ctx_) : - ctx(ctx_), - stopping (false) -{ -#ifdef ZMQ_USE_EPOLL_CLOEXEC - // Setting this option result in sane behaviour when exec() functions - // are used. Old sockets are closed and don't block TCP ports, avoid - // leaks, etc. - epoll_fd = epoll_create1 (EPOLL_CLOEXEC); -#else - epoll_fd = epoll_create (1); -#endif - errno_assert (epoll_fd != -1); -} - -zmq::epoll_t::~epoll_t () -{ - // Wait till the worker thread exits. - worker.stop (); - - close (epoll_fd); - for (retired_t::iterator it = retired.begin (); it != retired.end (); ++it) { - LIBZMQ_DELETE(*it); - } -} - -zmq::epoll_t::handle_t zmq::epoll_t::add_fd (fd_t fd_, i_poll_events *events_) -{ - poll_entry_t *pe = new (std::nothrow) poll_entry_t; - alloc_assert (pe); - - // The memset is not actually needed. It's here to prevent debugging - // tools to complain about using uninitialised memory. - memset (pe, 0, sizeof (poll_entry_t)); - - pe->fd = fd_; - pe->ev.events = 0; - pe->ev.data.ptr = pe; - pe->events = events_; - - int rc = epoll_ctl (epoll_fd, EPOLL_CTL_ADD, fd_, &pe->ev); - errno_assert (rc != -1); - - // Increase the load metric of the thread. - adjust_load (1); - - return pe; -} - -void zmq::epoll_t::rm_fd (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - int rc = epoll_ctl (epoll_fd, EPOLL_CTL_DEL, pe->fd, &pe->ev); - errno_assert (rc != -1); - pe->fd = retired_fd; - retired_sync.lock (); - retired.push_back (pe); - retired_sync.unlock (); - - // Decrease the load metric of the thread. - adjust_load (-1); -} - -void zmq::epoll_t::set_pollin (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - pe->ev.events |= EPOLLIN; - int rc = epoll_ctl (epoll_fd, EPOLL_CTL_MOD, pe->fd, &pe->ev); - errno_assert (rc != -1); -} - -void zmq::epoll_t::reset_pollin (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - pe->ev.events &= ~((short) EPOLLIN); - int rc = epoll_ctl (epoll_fd, EPOLL_CTL_MOD, pe->fd, &pe->ev); - errno_assert (rc != -1); -} - -void zmq::epoll_t::set_pollout (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - pe->ev.events |= EPOLLOUT; - int rc = epoll_ctl (epoll_fd, EPOLL_CTL_MOD, pe->fd, &pe->ev); - errno_assert (rc != -1); -} - -void zmq::epoll_t::reset_pollout (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - pe->ev.events &= ~((short) EPOLLOUT); - int rc = epoll_ctl (epoll_fd, EPOLL_CTL_MOD, pe->fd, &pe->ev); - errno_assert (rc != -1); -} - -void zmq::epoll_t::start () -{ - ctx.start_thread (worker, worker_routine, this); -} - -void zmq::epoll_t::stop () -{ - stopping = true; -} - -int zmq::epoll_t::max_fds () -{ - return -1; -} - -void zmq::epoll_t::loop () -{ - epoll_event ev_buf [max_io_events]; - - while (!stopping) { - - // Execute any due timers. - int timeout = (int) execute_timers (); - - // Wait for events. - int n = epoll_wait (epoll_fd, &ev_buf [0], max_io_events, - timeout ? timeout : -1); - if (n == -1) { - errno_assert (errno == EINTR); - continue; - } - - for (int i = 0; i < n; i ++) { - poll_entry_t *pe = ((poll_entry_t*) ev_buf [i].data.ptr); - - if (pe->fd == retired_fd) - continue; - if (ev_buf [i].events & (EPOLLERR | EPOLLHUP)) - pe->events->in_event (); - if (pe->fd == retired_fd) - continue; - if (ev_buf [i].events & EPOLLOUT) - pe->events->out_event (); - if (pe->fd == retired_fd) - continue; - if (ev_buf [i].events & EPOLLIN) - pe->events->in_event (); - } - - // Destroy retired event sources. - retired_sync.lock (); - for (retired_t::iterator it = retired.begin (); it != retired.end (); ++it) { - LIBZMQ_DELETE(*it); - } - retired.clear (); - retired_sync.unlock (); - } -} - -void zmq::epoll_t::worker_routine (void *arg_) -{ - ((epoll_t*) arg_)->loop (); -} - -#endif diff --git a/dep/libzmq/src/epoll.hpp b/dep/libzmq/src/epoll.hpp deleted file mode 100644 index e6c08c9283..0000000000 --- a/dep/libzmq/src/epoll.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_EPOLL_HPP_INCLUDED__ -#define __ZMQ_EPOLL_HPP_INCLUDED__ - -// poller.hpp decides which polling mechanism to use. -#include "poller.hpp" -#if defined ZMQ_USE_EPOLL - -#include -#include - -#include "ctx.hpp" -#include "fd.hpp" -#include "thread.hpp" -#include "poller_base.hpp" -#include "mutex.hpp" - -namespace zmq -{ - - struct i_poll_events; - - // This class implements socket polling mechanism using the Linux-specific - // epoll mechanism. - - class epoll_t : public poller_base_t - { - public: - - typedef void* handle_t; - - epoll_t (const ctx_t &ctx_); - ~epoll_t (); - - // "poller" concept. - handle_t add_fd (fd_t fd_, zmq::i_poll_events *events_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void start (); - void stop (); - - static int max_fds (); - - private: - - // Main worker thread routine. - static void worker_routine (void *arg_); - - // Main event loop. - void loop (); - - // Reference to ZMQ context. - const ctx_t &ctx; - - // Main epoll file descriptor - fd_t epoll_fd; - - struct poll_entry_t - { - fd_t fd; - epoll_event ev; - zmq::i_poll_events *events; - }; - - // List of retired event sources. - typedef std::vector retired_t; - retired_t retired; - - // If true, thread is in the process of shutting down. - bool stopping; - - // Handle of the physical thread doing the I/O work. - thread_t worker; - - // Synchronisation of retired event sources - mutex_t retired_sync; - - epoll_t (const epoll_t&); - const epoll_t &operator = (const epoll_t&); - }; - - typedef epoll_t poller_t; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/err.cpp b/dep/libzmq/src/err.cpp deleted file mode 100644 index 4eff87646b..0000000000 --- a/dep/libzmq/src/err.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "err.hpp" - -const char *zmq::errno_to_string (int errno_) -{ - switch (errno_) { -#if defined ZMQ_HAVE_WINDOWS - case ENOTSUP: - return "Not supported"; - case EPROTONOSUPPORT: - return "Protocol not supported"; - case ENOBUFS: - return "No buffer space available"; - case ENETDOWN: - return "Network is down"; - case EADDRINUSE: - return "Address in use"; - case EADDRNOTAVAIL: - return "Address not available"; - case ECONNREFUSED: - return "Connection refused"; - case EINPROGRESS: - return "Operation in progress"; -#endif - case EFSM: - return "Operation cannot be accomplished in current state"; - case ENOCOMPATPROTO: - return "The protocol is not compatible with the socket type"; - case ETERM: - return "Context was terminated"; - case EMTHREAD: - return "No thread available"; - case EHOSTUNREACH: - return "Host unreachable"; - default: -#if defined _MSC_VER -#pragma warning (push) -#pragma warning (disable:4996) -#endif - return strerror (errno_); -#if defined _MSC_VER -#pragma warning (pop) -#endif - } -} - -void zmq::zmq_abort(const char *errmsg_) -{ -#if defined ZMQ_HAVE_WINDOWS - - // Raise STATUS_FATAL_APP_EXIT. - ULONG_PTR extra_info [1]; - extra_info [0] = (ULONG_PTR) errmsg_; - RaiseException (0x40000015, EXCEPTION_NONCONTINUABLE, 1, extra_info); -#else - (void)errmsg_; - print_backtrace(); - abort (); -#endif -} - -#ifdef ZMQ_HAVE_WINDOWS - -const char *zmq::wsa_error() -{ - return wsa_error_no (WSAGetLastError(), NULL); -} - -const char *zmq::wsa_error_no (int no_, const char * wsae_wouldblock_string) -{ - // TODO: It seems that list of Windows socket errors is longer than this. - // Investigate whether there's a way to convert it into the string - // automatically (wsaError->HRESULT->string?). - return - (no_ == WSABASEERR) ? - "No Error" : - (no_ == WSAEINTR) ? - "Interrupted system call" : - (no_ == WSAEBADF) ? - "Bad file number" : - (no_ == WSAEACCES) ? - "Permission denied" : - (no_ == WSAEFAULT) ? - "Bad address" : - (no_ == WSAEINVAL) ? - "Invalid argument" : - (no_ == WSAEMFILE) ? - "Too many open files" : - (no_ == WSAEWOULDBLOCK) ? - wsae_wouldblock_string : - (no_ == WSAEINPROGRESS) ? - "Operation now in progress" : - (no_ == WSAEALREADY) ? - "Operation already in progress" : - (no_ == WSAENOTSOCK) ? - "Socket operation on non-socket" : - (no_ == WSAEDESTADDRREQ) ? - "Destination address required" : - (no_ == WSAEMSGSIZE) ? - "Message too long" : - (no_ == WSAEPROTOTYPE) ? - "Protocol wrong type for socket" : - (no_ == WSAENOPROTOOPT) ? - "Bad protocol option" : - (no_ == WSAEPROTONOSUPPORT) ? - "Protocol not supported" : - (no_ == WSAESOCKTNOSUPPORT) ? - "Socket type not supported" : - (no_ == WSAEOPNOTSUPP) ? - "Operation not supported on socket" : - (no_ == WSAEPFNOSUPPORT) ? - "Protocol family not supported" : - (no_ == WSAEAFNOSUPPORT) ? - "Address family not supported by protocol family" : - (no_ == WSAEADDRINUSE) ? - "Address already in use" : - (no_ == WSAEADDRNOTAVAIL) ? - "Can't assign requested address" : - (no_ == WSAENETDOWN) ? - "Network is down" : - (no_ == WSAENETUNREACH) ? - "Network is unreachable" : - (no_ == WSAENETRESET) ? - "Net dropped connection or reset" : - (no_ == WSAECONNABORTED) ? - "Software caused connection abort" : - (no_ == WSAECONNRESET) ? - "Connection reset by peer" : - (no_ == WSAENOBUFS) ? - "No buffer space available" : - (no_ == WSAEISCONN) ? - "Socket is already connected" : - (no_ == WSAENOTCONN) ? - "Socket is not connected" : - (no_ == WSAESHUTDOWN) ? - "Can't send after socket shutdown" : - (no_ == WSAETOOMANYREFS) ? - "Too many references can't splice" : - (no_ == WSAETIMEDOUT) ? - "Connection timed out" : - (no_ == WSAECONNREFUSED) ? - "Connection refused" : - (no_ == WSAELOOP) ? - "Too many levels of symbolic links" : - (no_ == WSAENAMETOOLONG) ? - "File name too long" : - (no_ == WSAEHOSTDOWN) ? - "Host is down" : - (no_ == WSAEHOSTUNREACH) ? - "No Route to Host" : - (no_ == WSAENOTEMPTY) ? - "Directory not empty" : - (no_ == WSAEPROCLIM) ? - "Too many processes" : - (no_ == WSAEUSERS) ? - "Too many users" : - (no_ == WSAEDQUOT) ? - "Disc Quota Exceeded" : - (no_ == WSAESTALE) ? - "Stale NFS file handle" : - (no_ == WSAEREMOTE) ? - "Too many levels of remote in path" : - (no_ == WSASYSNOTREADY) ? - "Network SubSystem is unavailable" : - (no_ == WSAVERNOTSUPPORTED) ? - "WINSOCK DLL Version out of range" : - (no_ == WSANOTINITIALISED) ? - "Successful WSASTARTUP not yet performed" : - (no_ == WSAHOST_NOT_FOUND) ? - "Host not found" : - (no_ == WSATRY_AGAIN) ? - "Non-Authoritative Host not found" : - (no_ == WSANO_RECOVERY) ? - "Non-Recoverable errors: FORMERR REFUSED NOTIMP" : - (no_ == WSANO_DATA) ? - "Valid name no data record of requested" : - "error not defined"; -} - -void zmq::win_error (char *buffer_, size_t buffer_size_) -{ - DWORD errcode = GetLastError (); -#if defined _WIN32_WCE - DWORD rc = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode, MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), (LPWSTR)buffer_, buffer_size_ / sizeof(wchar_t), NULL); -#else - DWORD rc = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode, MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), buffer_, (DWORD) buffer_size_, NULL); -#endif - zmq_assert (rc); -} - -int zmq::wsa_error_to_errno (int errcode) -{ - switch (errcode) { -// 10004 - Interrupted system call. - case WSAEINTR: - return EINTR; -// 10009 - File handle is not valid. - case WSAEBADF: - return EBADF; -// 10013 - Permission denied. - case WSAEACCES: - return EACCES; -// 10014 - Bad address. - case WSAEFAULT: - return EFAULT; -// 10022 - Invalid argument. - case WSAEINVAL: - return EINVAL; -// 10024 - Too many open files. - case WSAEMFILE: - return EMFILE; -// 10035 - Operation would block. - case WSAEWOULDBLOCK: - return EBUSY; -// 10036 - Operation now in progress. - case WSAEINPROGRESS: - return EAGAIN; -// 10037 - Operation already in progress. - case WSAEALREADY: - return EAGAIN; -// 10038 - Socket operation on non-socket. - case WSAENOTSOCK: - return ENOTSOCK; -// 10039 - Destination address required. - case WSAEDESTADDRREQ: - return EFAULT; -// 10040 - Message too long. - case WSAEMSGSIZE: - return EMSGSIZE; -// 10041 - Protocol wrong type for socket. - case WSAEPROTOTYPE: - return EFAULT; -// 10042 - Bad protocol option. - case WSAENOPROTOOPT: - return EINVAL; -// 10043 - Protocol not supported. - case WSAEPROTONOSUPPORT: - return EPROTONOSUPPORT; -// 10044 - Socket type not supported. - case WSAESOCKTNOSUPPORT: - return EFAULT; -// 10045 - Operation not supported on socket. - case WSAEOPNOTSUPP: - return EFAULT; -// 10046 - Protocol family not supported. - case WSAEPFNOSUPPORT: - return EPROTONOSUPPORT; -// 10047 - Address family not supported by protocol family. - case WSAEAFNOSUPPORT: - return EAFNOSUPPORT; -// 10048 - Address already in use. - case WSAEADDRINUSE: - return EADDRINUSE; -// 10049 - Cannot assign requested address. - case WSAEADDRNOTAVAIL: - return EADDRNOTAVAIL; -// 10050 - Network is down. - case WSAENETDOWN: - return ENETDOWN; -// 10051 - Network is unreachable. - case WSAENETUNREACH: - return ENETUNREACH; -// 10052 - Network dropped connection on reset. - case WSAENETRESET: - return ENETRESET; -// 10053 - Software caused connection abort. - case WSAECONNABORTED: - return ECONNABORTED; -// 10054 - Connection reset by peer. - case WSAECONNRESET: - return ECONNRESET; -// 10055 - No buffer space available. - case WSAENOBUFS: - return ENOBUFS; -// 10056 - Socket is already connected. - case WSAEISCONN: - return EFAULT; -// 10057 - Socket is not connected. - case WSAENOTCONN: - return ENOTCONN; -// 10058 - Can't send after socket shutdown. - case WSAESHUTDOWN: - return EFAULT; -// 10059 - Too many references can't splice. - case WSAETOOMANYREFS: - return EFAULT; -// 10060 - Connection timed out. - case WSAETIMEDOUT: - return ETIMEDOUT; -// 10061 - Connection refused. - case WSAECONNREFUSED: - return ECONNREFUSED; -// 10062 - Too many levels of symbolic links. - case WSAELOOP: - return EFAULT; -// 10063 - File name too long. - case WSAENAMETOOLONG: - return EFAULT; -// 10064 - Host is down. - case WSAEHOSTDOWN: - return EAGAIN; -// 10065 - No route to host. - case WSAEHOSTUNREACH: - return EHOSTUNREACH; -// 10066 - Directory not empty. - case WSAENOTEMPTY: - return EFAULT; -// 10067 - Too many processes. - case WSAEPROCLIM: - return EFAULT; -// 10068 - Too many users. - case WSAEUSERS: - return EFAULT; -// 10069 - Disc Quota Exceeded. - case WSAEDQUOT: - return EFAULT; -// 10070 - Stale NFS file handle. - case WSAESTALE: - return EFAULT; -// 10071 - Too many levels of remote in path. - case WSAEREMOTE: - return EFAULT; -// 10091 - Network SubSystem is unavailable. - case WSASYSNOTREADY: - return EFAULT; -// 10092 - WINSOCK DLL Version out of range. - case WSAVERNOTSUPPORTED: - return EFAULT; -// 10093 - Successful WSASTARTUP not yet performed. - case WSANOTINITIALISED: - return EFAULT; -// 11001 - Host not found. - case WSAHOST_NOT_FOUND: - return EFAULT; -// 11002 - Non-Authoritative Host not found. - case WSATRY_AGAIN: - return EFAULT; -// 11003 - Non-Recoverable errors: FORMERR REFUSED NOTIMP. - case WSANO_RECOVERY: - return EFAULT; -// 11004 - Valid name no data record of requested. - case WSANO_DATA: - return EFAULT; - default: - wsa_assert (false); - } - // Not reachable - return 0; -} - -#endif - -#ifdef HAVE_LIBUNWIND - -#define UNW_LOCAL_ONLY -#include -#include -#include -#include "mutex.hpp" - -void zmq::print_backtrace (void) -{ - static zmq::mutex_t mtx; - mtx.lock (); - Dl_info dl_info; - unw_cursor_t cursor; - unw_context_t ctx; - unsigned frame_n = 0; - - unw_getcontext (&ctx); - unw_init_local (&cursor, &ctx); - - while (unw_step (&cursor) > 0) { - unw_word_t offset; - unw_proc_info_t p_info; - const char *file_name; - char *demangled_name; - char func_name[256] = ""; - void *addr; - int rc; - - if (unw_get_proc_info (&cursor, &p_info)) - break; - - rc = unw_get_proc_name (&cursor, func_name, 256, &offset); - if (rc == -UNW_ENOINFO) - strcpy(func_name, "?"); - - addr = (void *)(p_info.start_ip + offset); - - if (dladdr (addr, &dl_info) && dl_info.dli_fname) - file_name = dl_info.dli_fname; - else - file_name = "?"; - - demangled_name = abi::__cxa_demangle (func_name, NULL, NULL, &rc); - - printf ("#%u %p in %s (%s+0x%lx)\n", frame_n++, addr, file_name, - rc ? func_name : demangled_name, (unsigned long) offset); - free (demangled_name); - } - puts (""); - - fflush (stdout); - mtx.unlock (); -} - -#else - -void zmq::print_backtrace (void) -{ -} - -#endif diff --git a/dep/libzmq/src/err.hpp b/dep/libzmq/src/err.hpp deleted file mode 100644 index c7869f801f..0000000000 --- a/dep/libzmq/src/err.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ERR_HPP_INCLUDED__ -#define __ZMQ_ERR_HPP_INCLUDED__ - -#include -#if defined _WIN32_WCE -#include "..\builds\msvc\errno.hpp" -#else -#include -#endif -#include -#include -#include - -#ifndef ZMQ_HAVE_WINDOWS -#include -#endif - -#include "likely.hpp" - -// 0MQ-specific error codes are defined in zmq.h - -// EPROTO is not used by OpenBSD and maybe other platforms. -#ifndef EPROTO -#define EPROTO 0 -#endif - -namespace zmq -{ - const char *errno_to_string (int errno_); - void zmq_abort (const char *errmsg_); - void print_backtrace (void); -} - -#ifdef ZMQ_HAVE_WINDOWS - -namespace zmq -{ - const char *wsa_error (); - const char *wsa_error_no (int no_, const char * wsae_wouldblock_string = "Operation would block"); - void win_error (char *buffer_, size_t buffer_size_); - int wsa_error_to_errno (int errcode); -} - -// Provides convenient way to check WSA-style errors on Windows. -#define wsa_assert(x) \ - do {\ - if (unlikely (!(x))) {\ - const char *errstr = zmq::wsa_error ();\ - if (errstr != NULL) {\ - fprintf (stderr, "Assertion failed: %s (%s:%d)\n", errstr, \ - __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (errstr);\ - }\ - }\ - } while (false) - -// Provides convenient way to assert on WSA-style errors on Windows. -#define wsa_assert_no(no) \ - do {\ - const char *errstr = zmq::wsa_error_no (no);\ - if (errstr != NULL) {\ - fprintf (stderr, "Assertion failed: %s (%s:%d)\n", errstr, \ - __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (errstr);\ - }\ - } while (false) - -// Provides convenient way to check GetLastError-style errors on Windows. -#define win_assert(x) \ - do {\ - if (unlikely (!(x))) {\ - char errstr [256];\ - zmq::win_error (errstr, 256);\ - fprintf (stderr, "Assertion failed: %s (%s:%d)\n", errstr, \ - __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (errstr);\ - }\ - } while (false) - -#endif - -// This macro works in exactly the same way as the normal assert. It is used -// in its stead because standard assert on Win32 in broken - it prints nothing -// when used within the scope of JNI library. -#define zmq_assert(x) \ - do {\ - if (unlikely (!(x))) {\ - fprintf (stderr, "Assertion failed: %s (%s:%d)\n", #x, \ - __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (#x);\ - }\ - } while (false) - -// Provides convenient way to check for errno-style errors. -#define errno_assert(x) \ - do {\ - if (unlikely (!(x))) {\ - const char *errstr = strerror (errno);\ - fprintf (stderr, "%s (%s:%d)\n", errstr, __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (errstr);\ - }\ - } while (false) - -// Provides convenient way to check for POSIX errors. -#define posix_assert(x) \ - do {\ - if (unlikely (x)) {\ - const char *errstr = strerror (x);\ - fprintf (stderr, "%s (%s:%d)\n", errstr, __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (errstr);\ - }\ - } while (false) - -// Provides convenient way to check for errors from getaddrinfo. -#define gai_assert(x) \ - do {\ - if (unlikely (x)) {\ - const char *errstr = gai_strerror (x);\ - fprintf (stderr, "%s (%s:%d)\n", errstr, __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort (errstr);\ - }\ - } while (false) - -// Provides convenient way to check whether memory allocation have succeeded. -#define alloc_assert(x) \ - do {\ - if (unlikely (!x)) {\ - fprintf (stderr, "FATAL ERROR: OUT OF MEMORY (%s:%d)\n",\ - __FILE__, __LINE__);\ - fflush (stderr);\ - zmq::zmq_abort ("FATAL ERROR: OUT OF MEMORY");\ - }\ - } while (false) - -#endif - - diff --git a/dep/libzmq/src/fd.hpp b/dep/libzmq/src/fd.hpp deleted file mode 100644 index 5b3afe8515..0000000000 --- a/dep/libzmq/src/fd.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_FD_HPP_INCLUDED__ -#define __ZMQ_FD_HPP_INCLUDED__ - -#if defined _WIN32 -#include "windows.hpp" -#endif - -namespace zmq -{ -#ifdef ZMQ_HAVE_WINDOWS -#if defined _MSC_VER &&_MSC_VER <= 1400 - typedef UINT_PTR fd_t; - enum {retired_fd = (fd_t)(~0)}; -#else - typedef SOCKET fd_t; - enum {retired_fd = (fd_t)INVALID_SOCKET}; -#endif -#else - typedef int fd_t; - enum {retired_fd = -1}; -#endif -} -#endif diff --git a/dep/libzmq/src/fq.cpp b/dep/libzmq/src/fq.cpp deleted file mode 100644 index 0137b31301..0000000000 --- a/dep/libzmq/src/fq.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "fq.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::fq_t::fq_t () : - active (0), - last_in (NULL), - current (0), - more (false) -{ -} - -zmq::fq_t::~fq_t () -{ - zmq_assert (pipes.empty ()); -} - -void zmq::fq_t::attach (pipe_t *pipe_) -{ - pipes.push_back (pipe_); - pipes.swap (active, pipes.size () - 1); - active++; -} - -void zmq::fq_t::pipe_terminated (pipe_t *pipe_) -{ - const pipes_t::size_type index = pipes.index (pipe_); - - // Remove the pipe from the list; adjust number of active pipes - // accordingly. - if (index < active) { - active--; - pipes.swap (index, active); - if (current == active) - current = 0; - } - pipes.erase (pipe_); - - if (last_in == pipe_) { - saved_credential.set_deep_copy (last_in->get_credential ()); - last_in = NULL; - } -} - -void zmq::fq_t::activated (pipe_t *pipe_) -{ - // Move the pipe to the list of active pipes. - pipes.swap (pipes.index (pipe_), active); - active++; -} - -int zmq::fq_t::recv (msg_t *msg_) -{ - return recvpipe (msg_, NULL); -} - -int zmq::fq_t::recvpipe (msg_t *msg_, pipe_t **pipe_) -{ - // Deallocate old content of the message. - int rc = msg_->close (); - errno_assert (rc == 0); - - // Round-robin over the pipes to get the next message. - while (active > 0) { - - // Try to fetch new message. If we've already read part of the message - // subsequent part should be immediately available. - bool fetched = pipes [current]->read (msg_); - - // Note that when message is not fetched, current pipe is deactivated - // and replaced by another active pipe. Thus we don't have to increase - // the 'current' pointer. - if (fetched) { - if (pipe_) - *pipe_ = pipes [current]; - more = msg_->flags () & msg_t::more? true: false; - if (!more) { - last_in = pipes [current]; - current = (current + 1) % active; - } - return 0; - } - - // Check the atomicity of the message. - // If we've already received the first part of the message - // we should get the remaining parts without blocking. - zmq_assert (!more); - - active--; - pipes.swap (current, active); - if (current == active) - current = 0; - } - - // No message is available. Initialise the output parameter - // to be a 0-byte message. - rc = msg_->init (); - errno_assert (rc == 0); - errno = EAGAIN; - return -1; -} - -bool zmq::fq_t::has_in () -{ - // There are subsequent parts of the partly-read message available. - if (more) - return true; - - // Note that messing with current doesn't break the fairness of fair - // queueing algorithm. If there are no messages available current will - // get back to its original value. Otherwise it'll point to the first - // pipe holding messages, skipping only pipes with no messages available. - while (active > 0) { - if (pipes [current]->check_read ()) - return true; - - // Deactivate the pipe. - active--; - pipes.swap (current, active); - if (current == active) - current = 0; - } - - return false; -} - -const zmq::blob_t &zmq::fq_t::get_credential () const -{ - return last_in? - last_in->get_credential (): saved_credential; -} - diff --git a/dep/libzmq/src/fq.hpp b/dep/libzmq/src/fq.hpp deleted file mode 100644 index 6be74a86bf..0000000000 --- a/dep/libzmq/src/fq.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_FQ_HPP_INCLUDED__ -#define __ZMQ_FQ_HPP_INCLUDED__ - -#include "array.hpp" -#include "blob.hpp" -#include "pipe.hpp" -#include "msg.hpp" - -namespace zmq -{ - - // Class manages a set of inbound pipes. On receive it performs fair - // queueing so that senders gone berserk won't cause denial of - // service for decent senders. - - class fq_t - { - public: - - fq_t (); - ~fq_t (); - - void attach (pipe_t *pipe_); - void activated (pipe_t *pipe_); - void pipe_terminated (pipe_t *pipe_); - - int recv (msg_t *msg_); - int recvpipe (msg_t *msg_, pipe_t **pipe_); - bool has_in (); - const blob_t &get_credential () const; - - private: - - // Inbound pipes. - typedef array_t pipes_t; - pipes_t pipes; - - // Number of active pipes. All the active pipes are located at the - // beginning of the pipes array. - pipes_t::size_type active; - - // Pointer to the last pipe we received message from. - // NULL when no message has been received or the pipe - // has terminated. - pipe_t *last_in; - - // Index of the next bound pipe to read a message from. - pipes_t::size_type current; - - // If true, part of a multipart message was already received, but - // there are following parts still waiting in the current pipe. - bool more; - - // Holds credential after the last_active_pipe has terminated. - blob_t saved_credential; - - fq_t (const fq_t&); - const fq_t &operator = (const fq_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/gather.cpp b/dep/libzmq/src/gather.cpp deleted file mode 100644 index 9c57675626..0000000000 --- a/dep/libzmq/src/gather.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "gather.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "pipe.hpp" - -zmq::gather_t::gather_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_, true) -{ - options.type = ZMQ_GATHER; -} - -zmq::gather_t::~gather_t () -{ -} - -void zmq::gather_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - fq.attach (pipe_); -} - -void zmq::gather_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::gather_t::xpipe_terminated (pipe_t *pipe_) -{ - fq.pipe_terminated (pipe_); -} - -int zmq::gather_t::xrecv (msg_t *msg_) -{ - int rc = fq.recvpipe (msg_, NULL); - - // Drop any messages with more flag - while (rc == 0 && msg_->flags () & msg_t::more) { - - // drop all frames of the current multi-frame message - rc = fq.recvpipe (msg_, NULL); - - while (rc == 0 && msg_->flags () & msg_t::more) - rc = fq.recvpipe (msg_, NULL); - - // get the new message - if (rc == 0) - rc = fq.recvpipe (msg_, NULL); - } - - return rc; -} - -bool zmq::gather_t::xhas_in () -{ - return fq.has_in (); -} - -const zmq::blob_t &zmq::gather_t::get_credential () const -{ - return fq.get_credential (); -} diff --git a/dep/libzmq/src/gather.hpp b/dep/libzmq/src/gather.hpp deleted file mode 100644 index 1b3096955f..0000000000 --- a/dep/libzmq/src/gather.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_GATHER_HPP_INCLUDED__ -#define __ZMQ_GATHER_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "fq.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - class msg_t; - class io_thread_t; - - class gather_t : - public socket_base_t - { - public: - - gather_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~gather_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Fair queueing object for inbound pipes. - fq_t fq; - - gather_t (const gather_t&); - const gather_t &operator = (const gather_t&); - - }; - -} - -#endif diff --git a/dep/libzmq/src/gssapi_client.hpp b/dep/libzmq/src/gssapi_client.hpp deleted file mode 100644 index 6bfdf50cc1..0000000000 --- a/dep/libzmq/src/gssapi_client.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_GSSAPI_CLIENT_HPP_INCLUDED__ -#define __ZMQ_GSSAPI_CLIENT_HPP_INCLUDED__ - -#ifdef HAVE_LIBGSSAPI_KRB5 - -#include "gssapi_mechanism_base.hpp" - -namespace zmq -{ - - class msg_t; - class session_base_t; - - class gssapi_client_t : public gssapi_mechanism_base_t - { - public: - gssapi_client_t (session_base_t *session_, const options_t &options_); - virtual ~gssapi_client_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - virtual int encode (msg_t *msg_); - virtual int decode (msg_t *msg_); - virtual status_t status () const; - - private: - - enum state_t { - call_next_init, - send_next_token, - recv_next_token, - send_ready, - recv_ready, - connected - }; - - // Human-readable principal name of the service we are connecting to - char * service_name; - - gss_OID service_name_type; - - // Current FSM state - state_t state; - - // Points to either send_tok or recv_tok - // during context initialization - gss_buffer_desc *token_ptr; - - // The desired underlying mechanism - gss_OID_set_desc mechs; - - // True iff client considers the server authenticated - bool security_context_established; - - int initialize_context (); - int produce_next_token (msg_t *msg_); - int process_next_token (msg_t *msg_); - }; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/gssapi_server.hpp b/dep/libzmq/src/gssapi_server.hpp deleted file mode 100644 index d6fe4c8346..0000000000 --- a/dep/libzmq/src/gssapi_server.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_GSSAPI_SERVER_HPP_INCLUDED__ -#define __ZMQ_GSSAPI_SERVER_HPP_INCLUDED__ - -#ifdef HAVE_LIBGSSAPI_KRB5 - -#include "gssapi_mechanism_base.hpp" -#include "zap_client.hpp" - -namespace zmq -{ - - class msg_t; - class session_base_t; - - class gssapi_server_t - : public gssapi_mechanism_base_t, public zap_client_t - { - public: - gssapi_server_t (session_base_t *session_, - const std::string &peer_address, - const options_t &options_); - virtual ~gssapi_server_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - virtual int encode (msg_t *msg_); - virtual int decode (msg_t *msg_); - virtual int zap_msg_available (); - virtual status_t status () const; - - private: - - enum state_t { - send_next_token, - recv_next_token, - expect_zap_reply, - send_ready, - recv_ready, - connected - }; - - session_base_t * const session; - - const std::string peer_address; - - // Current FSM state - state_t state; - - // True iff server considers the client authenticated - bool security_context_established; - - // The underlying mechanism type (ignored) - gss_OID doid; - - void accept_context (); - int produce_next_token (msg_t *msg_); - int process_next_token (msg_t *msg_); - void send_zap_request (); - }; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/i_decoder.hpp b/dep/libzmq/src/i_decoder.hpp deleted file mode 100644 index e23104993d..0000000000 --- a/dep/libzmq/src/i_decoder.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_I_DECODER_HPP_INCLUDED__ -#define __ZMQ_I_DECODER_HPP_INCLUDED__ - -#include "stdint.hpp" - -namespace zmq -{ - - class msg_t; - - // Interface to be implemented by message decoder. - - class i_decoder - { - public: - virtual ~i_decoder () {} - - virtual void get_buffer (unsigned char **data_, size_t *size_) = 0; - - virtual void resize_buffer(size_t) = 0; - // Decodes data pointed to by data_. - // When a message is decoded, 1 is returned. - // When the decoder needs more data, 0 is returned. - // On error, -1 is returned and errno is set accordingly. - virtual int decode (const unsigned char *data_, size_t size_, - size_t &processed) = 0; - - virtual msg_t *msg () = 0; - - - }; - -} - -#endif diff --git a/dep/libzmq/src/i_encoder.hpp b/dep/libzmq/src/i_encoder.hpp deleted file mode 100644 index 2d5cd258b9..0000000000 --- a/dep/libzmq/src/i_encoder.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_I_ENCODER_HPP_INCLUDED__ -#define __ZMQ_I_ENCODER_HPP_INCLUDED__ - -#include "stdint.hpp" - -namespace zmq -{ - - // Forward declaration - class msg_t; - - // Interface to be implemented by message encoder. - - struct i_encoder - { - virtual ~i_encoder () {} - - // The function returns a batch of binary data. The data - // are filled to a supplied buffer. If no buffer is supplied (data_ - // is NULL) encoder will provide buffer of its own. - // Function returns 0 when a new message is required. - virtual size_t encode (unsigned char **data_, size_t size) = 0; - - // Load a new message into encoder. - virtual void load_msg (msg_t *msg_) = 0; - - }; - -} - -#endif diff --git a/dep/libzmq/src/i_engine.hpp b/dep/libzmq/src/i_engine.hpp deleted file mode 100644 index 0897606d25..0000000000 --- a/dep/libzmq/src/i_engine.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_I_ENGINE_HPP_INCLUDED__ -#define __ZMQ_I_ENGINE_HPP_INCLUDED__ - -namespace zmq -{ - - class io_thread_t; - - // Abstract interface to be implemented by various engines. - - struct i_engine - { - virtual ~i_engine () {} - - // Plug the engine to the session. - virtual void plug (zmq::io_thread_t *io_thread_, - class session_base_t *session_) = 0; - - // Terminate and deallocate the engine. Note that 'detached' - // events are not fired on termination. - virtual void terminate () = 0; - - // This method is called by the session to signalise that more - // messages can be written to the pipe. - virtual void restart_input () = 0; - - // This method is called by the session to signalise that there - // are messages to send available. - virtual void restart_output () = 0; - - virtual void zap_msg_available () = 0; - - virtual const char * get_endpoint() const = 0; - - }; - -} - -#endif diff --git a/dep/libzmq/src/i_mailbox.hpp b/dep/libzmq/src/i_mailbox.hpp deleted file mode 100644 index 4c07a036ed..0000000000 --- a/dep/libzmq/src/i_mailbox.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_I_MAILBOX_HPP_INCLUDED__ -#define __ZMQ_I_MAILBOX_HPP_INCLUDED__ - -#include "stdint.hpp" - -namespace zmq -{ - // Interface to be implemented by mailbox. - - class i_mailbox - { - public: - virtual ~i_mailbox () {} - - virtual void send (const command_t &cmd_) = 0; - virtual int recv (command_t *cmd_, int timeout_) = 0; - - -#ifdef HAVE_FORK - // close the file descriptors in the signaller. This is used in a forked - // child process to close the file descriptors so that they do not interfere - // with the context in the parent process. - virtual void forked () = 0; -#endif - - - }; - -} - -#endif diff --git a/dep/libzmq/src/i_poll_events.hpp b/dep/libzmq/src/i_poll_events.hpp deleted file mode 100644 index 1b28df8aed..0000000000 --- a/dep/libzmq/src/i_poll_events.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_I_POLL_EVENTS_HPP_INCLUDED__ -#define __ZMQ_I_POLL_EVENTS_HPP_INCLUDED__ - -namespace zmq -{ - - // Virtual interface to be exposed by object that want to be notified - // about events on file descriptors. - - struct i_poll_events - { - virtual ~i_poll_events () {} - - // Called by I/O thread when file descriptor is ready for reading. - virtual void in_event () = 0; - - // Called by I/O thread when file descriptor is ready for writing. - virtual void out_event () = 0; - - // Called when timer expires. - virtual void timer_event (int id_) = 0; - }; - -} - -#endif diff --git a/dep/libzmq/src/io_object.cpp b/dep/libzmq/src/io_object.cpp deleted file mode 100644 index 442d50bc92..0000000000 --- a/dep/libzmq/src/io_object.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "io_object.hpp" -#include "io_thread.hpp" -#include "err.hpp" - -zmq::io_object_t::io_object_t (io_thread_t *io_thread_) : - poller (NULL) -{ - if (io_thread_) - plug (io_thread_); -} - -zmq::io_object_t::~io_object_t () -{ -} - -void zmq::io_object_t::plug (io_thread_t *io_thread_) -{ - zmq_assert (io_thread_); - zmq_assert (!poller); - - // Retrieve the poller from the thread we are running in. - poller = io_thread_->get_poller (); -} - -void zmq::io_object_t::unplug () -{ - zmq_assert (poller); - - // Forget about old poller in preparation to be migrated - // to a different I/O thread. - poller = NULL; -} - -zmq::io_object_t::handle_t zmq::io_object_t::add_fd (fd_t fd_) -{ - return poller->add_fd (fd_, this); -} - -void zmq::io_object_t::rm_fd (handle_t handle_) -{ - poller->rm_fd (handle_); -} - -void zmq::io_object_t::set_pollin (handle_t handle_) -{ - poller->set_pollin (handle_); -} - -void zmq::io_object_t::reset_pollin (handle_t handle_) -{ - poller->reset_pollin (handle_); -} - -void zmq::io_object_t::set_pollout (handle_t handle_) -{ - poller->set_pollout (handle_); -} - -void zmq::io_object_t::reset_pollout (handle_t handle_) -{ - poller->reset_pollout (handle_); -} - -void zmq::io_object_t::add_timer (int timeout_, int id_) -{ - poller->add_timer (timeout_, this, id_); -} - -void zmq::io_object_t::cancel_timer (int id_) -{ - poller->cancel_timer (this, id_); -} - -void zmq::io_object_t::in_event () -{ - zmq_assert (false); -} - -void zmq::io_object_t::out_event () -{ - zmq_assert (false); -} - -void zmq::io_object_t::timer_event (int) -{ - zmq_assert (false); -} diff --git a/dep/libzmq/src/io_object.hpp b/dep/libzmq/src/io_object.hpp deleted file mode 100644 index 1f6a33491a..0000000000 --- a/dep/libzmq/src/io_object.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_IO_OBJECT_HPP_INCLUDED__ -#define __ZMQ_IO_OBJECT_HPP_INCLUDED__ - -#include - -#include "stdint.hpp" -#include "poller.hpp" -#include "i_poll_events.hpp" - -namespace zmq -{ - - class io_thread_t; - - // Simple base class for objects that live in I/O threads. - // It makes communication with the poller object easier and - // makes defining unneeded event handlers unnecessary. - - class io_object_t : public i_poll_events - { - public: - - io_object_t (zmq::io_thread_t *io_thread_ = NULL); - ~io_object_t (); - - // When migrating an object from one I/O thread to another, first - // unplug it, then migrate it, then plug it to the new thread. - void plug (zmq::io_thread_t *io_thread_); - void unplug (); - - protected: - - typedef poller_t::handle_t handle_t; - - // Methods to access underlying poller object. - handle_t add_fd (fd_t fd_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void add_timer (int timout_, int id_); - void cancel_timer (int id_); - - // i_poll_events interface implementation. - void in_event (); - void out_event (); - void timer_event (int id_); - - private: - - poller_t *poller; - - io_object_t (const io_object_t&); - const io_object_t &operator = (const io_object_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/io_thread.cpp b/dep/libzmq/src/io_thread.cpp deleted file mode 100644 index 65e1f6a3a6..0000000000 --- a/dep/libzmq/src/io_thread.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include - -#include "macros.hpp" -#include "io_thread.hpp" -#include "err.hpp" -#include "ctx.hpp" - -zmq::io_thread_t::io_thread_t (ctx_t *ctx_, uint32_t tid_) : - object_t (ctx_, tid_) -{ - poller = new (std::nothrow) poller_t (*ctx_); - alloc_assert (poller); - - mailbox_handle = poller->add_fd (mailbox.get_fd (), this); - poller->set_pollin (mailbox_handle); -} - -zmq::io_thread_t::~io_thread_t () -{ - LIBZMQ_DELETE(poller); -} - -void zmq::io_thread_t::start () -{ - // Start the underlying I/O thread. - poller->start (); -} - -void zmq::io_thread_t::stop () -{ - send_stop (); -} - -zmq::mailbox_t *zmq::io_thread_t::get_mailbox () -{ - return &mailbox; -} - -int zmq::io_thread_t::get_load () -{ - return poller->get_load (); -} - -void zmq::io_thread_t::in_event () -{ - // TODO: Do we want to limit number of commands I/O thread can - // process in a single go? - - command_t cmd; - int rc = mailbox.recv (&cmd, 0); - - while (rc == 0 || errno == EINTR) { - if (rc == 0) - cmd.destination->process_command (cmd); - rc = mailbox.recv (&cmd, 0); - } - - errno_assert (rc != 0 && errno == EAGAIN); -} - -void zmq::io_thread_t::out_event () -{ - // We are never polling for POLLOUT here. This function is never called. - zmq_assert (false); -} - -void zmq::io_thread_t::timer_event (int) -{ - // No timers here. This function is never called. - zmq_assert (false); -} - -zmq::poller_t *zmq::io_thread_t::get_poller () -{ - zmq_assert (poller); - return poller; -} - -void zmq::io_thread_t::process_stop () -{ - poller->rm_fd (mailbox_handle); - poller->stop (); -} diff --git a/dep/libzmq/src/io_thread.hpp b/dep/libzmq/src/io_thread.hpp deleted file mode 100644 index 880bedbc09..0000000000 --- a/dep/libzmq/src/io_thread.hpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_IO_THREAD_HPP_INCLUDED__ -#define __ZMQ_IO_THREAD_HPP_INCLUDED__ - -#include - -#include "stdint.hpp" -#include "object.hpp" -#include "poller.hpp" -#include "i_poll_events.hpp" -#include "mailbox.hpp" - -namespace zmq -{ - - class ctx_t; - - // Generic part of the I/O thread. Polling-mechanism-specific features - // are implemented in separate "polling objects". - - class io_thread_t : public object_t, public i_poll_events - { - public: - - io_thread_t (zmq::ctx_t *ctx_, uint32_t tid_); - - // Clean-up. If the thread was started, it's necessary to call 'stop' - // before invoking destructor. Otherwise the destructor would hang up. - ~io_thread_t (); - - // Launch the physical thread. - void start (); - - // Ask underlying thread to stop. - void stop (); - - // Returns mailbox associated with this I/O thread. - mailbox_t *get_mailbox (); - - // i_poll_events implementation. - void in_event (); - void out_event (); - void timer_event (int id_); - - // Used by io_objects to retrieve the associated poller object. - poller_t *get_poller (); - - // Command handlers. - void process_stop (); - - // Returns load experienced by the I/O thread. - int get_load (); - - private: - - // I/O thread accesses incoming commands via this mailbox. - mailbox_t mailbox; - - // Handle associated with mailbox' file descriptor. - poller_t::handle_t mailbox_handle; - - // I/O multiplexing is performed using a poller object. - poller_t *poller; - - io_thread_t (const io_thread_t&); - const io_thread_t &operator = (const io_thread_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/ip.cpp b/dep/libzmq/src/ip.cpp deleted file mode 100644 index f9c5e5dee1..0000000000 --- a/dep/libzmq/src/ip.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "ip.hpp" -#include "err.hpp" -#include "macros.hpp" - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#include -#include -#endif - -#if defined ZMQ_HAVE_OPENVMS -#include -#endif - -zmq::fd_t zmq::open_socket (int domain_, int type_, int protocol_) -{ - int rc; - - // Setting this option result in sane behaviour when exec() functions - // are used. Old sockets are closed and don't block TCP ports etc. -#if defined ZMQ_HAVE_SOCK_CLOEXEC - type_ |= SOCK_CLOEXEC; -#endif - - fd_t s = socket (domain_, type_, protocol_); -#ifdef ZMQ_HAVE_WINDOWS - if (s == INVALID_SOCKET) - return INVALID_SOCKET; -#else - if (s == -1) - return -1; -#endif - - // If there's no SOCK_CLOEXEC, let's try the second best option. Note that - // race condition can cause socket not to be closed (if fork happens - // between socket creation and this point). -#if !defined ZMQ_HAVE_SOCK_CLOEXEC && defined FD_CLOEXEC - rc = fcntl (s, F_SETFD, FD_CLOEXEC); - errno_assert (rc != -1); -#endif - - // On Windows, preventing sockets to be inherited by child processes. -#if defined ZMQ_HAVE_WINDOWS && defined HANDLE_FLAG_INHERIT - BOOL brc = SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0); - win_assert (brc); -#endif - - // Socket is not yet connected so EINVAL is not a valid networking error - rc = zmq::set_nosigpipe (s); - errno_assert (rc == 0); - - return s; -} - -void zmq::unblock_socket (fd_t s_) -{ -#if defined ZMQ_HAVE_WINDOWS - u_long nonblock = 1; - int rc = ioctlsocket (s_, FIONBIO, &nonblock); - wsa_assert (rc != SOCKET_ERROR); -#elif defined ZMQ_HAVE_OPENVMS - int nonblock = 1; - int rc = ioctl (s_, FIONBIO, &nonblock); - errno_assert (rc != -1); -#else - int flags = fcntl (s_, F_GETFL, 0); - if (flags == -1) - flags = 0; - int rc = fcntl (s_, F_SETFL, flags | O_NONBLOCK); - errno_assert (rc != -1); -#endif -} - -void zmq::enable_ipv4_mapping (fd_t s_) -{ - (void) s_; - -#if defined IPV6_V6ONLY && !defined ZMQ_HAVE_OPENBSD -#ifdef ZMQ_HAVE_WINDOWS - DWORD flag = 0; -#else - int flag = 0; -#endif - int rc = setsockopt (s_, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &flag, - sizeof (flag)); -#ifdef ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - errno_assert (rc == 0); -#endif -#endif -} - -int zmq::get_peer_ip_address (fd_t sockfd_, std::string &ip_addr_) -{ - int rc; - struct sockaddr_storage ss; - -#if defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_WINDOWS - int addrlen = static_cast (sizeof ss); -#else - socklen_t addrlen = sizeof ss; -#endif - rc = getpeername (sockfd_, (struct sockaddr*) &ss, &addrlen); -#ifdef ZMQ_HAVE_WINDOWS - if (rc == SOCKET_ERROR) { - const int last_error = WSAGetLastError(); - wsa_assert (last_error != WSANOTINITIALISED && - last_error != WSAEFAULT && - last_error != WSAEINPROGRESS && - last_error != WSAENOTSOCK); - return 0; - } -#else - if (rc == -1) { - errno_assert (errno != EBADF && - errno != EFAULT && - errno != ENOTSOCK); - return 0; - } -#endif - - char host [NI_MAXHOST]; - rc = getnameinfo ((struct sockaddr*) &ss, addrlen, host, sizeof host, - NULL, 0, NI_NUMERICHOST); - if (rc != 0) - return 0; - - ip_addr_ = host; - - union { - struct sockaddr sa; - struct sockaddr_storage sa_stor; - } u; - - u.sa_stor = ss; - return (int) u.sa.sa_family; -} - -void zmq::set_ip_type_of_service (fd_t s_, int iptos) -{ - int rc = setsockopt(s_, IPPROTO_IP, IP_TOS, reinterpret_cast(&iptos), sizeof(iptos)); - -#ifdef ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - errno_assert (rc == 0); -#endif - - // Windows and Hurd do not support IPV6_TCLASS -#if !defined (ZMQ_HAVE_WINDOWS) && defined (IPV6_TCLASS) - rc = setsockopt( - s_, - IPPROTO_IPV6, - IPV6_TCLASS, - reinterpret_cast(&iptos), - sizeof(iptos)); - - // If IPv6 is not enabled ENOPROTOOPT will be returned on Linux and - // EINVAL on OSX - if (rc == -1) { - errno_assert (errno == ENOPROTOOPT || - errno == EINVAL); - } -#endif -} - -int zmq::set_nosigpipe (fd_t s_) -{ -#ifdef SO_NOSIGPIPE - // Make sure that SIGPIPE signal is not generated when writing to a - // connection that was already closed by the peer. - // As per POSIX spec, EINVAL will be returned if the socket was valid but - // the connection has been reset by the peer. Return an error so that the - // socket can be closed and the connection retried if necessary. - int set = 1; - int rc = setsockopt (s_, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof (int)); - if (rc != 0 && errno == EINVAL) - return -1; - errno_assert (rc == 0); -#else - LIBZMQ_UNUSED (s_); -#endif - - return 0; -} - -void zmq::bind_to_device (fd_t s_, std::string &bound_device_) -{ -#ifdef ZMQ_HAVE_SO_BINDTODEVICE - int rc = setsockopt(s_, SOL_SOCKET, SO_BINDTODEVICE, bound_device_.c_str (), bound_device_.length ()); - -#ifdef ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - errno_assert (rc == 0); -#endif -#else - LIBZMQ_UNUSED (s_); - LIBZMQ_UNUSED (bound_device_); -#endif -} diff --git a/dep/libzmq/src/ip.hpp b/dep/libzmq/src/ip.hpp deleted file mode 100644 index 5c718189cb..0000000000 --- a/dep/libzmq/src/ip.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_IP_HPP_INCLUDED__ -#define __ZMQ_IP_HPP_INCLUDED__ - -#include -#include "fd.hpp" - -namespace zmq -{ - - // Same as socket(2), but allows for transparent tweaking the options. - fd_t open_socket (int domain_, int type_, int protocol_); - - // Sets the socket into non-blocking mode. - void unblock_socket (fd_t s_); - - // Enable IPv4-mapping of addresses in case it is disabled by default. - void enable_ipv4_mapping (fd_t s_); - - // Returns string representation of peer's address. - // Socket sockfd_ must be connected. Returns true iff successful. - int get_peer_ip_address (fd_t sockfd_, std::string &ip_addr_); - - // Sets the IP Type-Of-Service for the underlying socket - void set_ip_type_of_service (fd_t s_, int iptos); - - // Sets the SO_NOSIGPIPE option for the underlying socket. - // Return 0 on success, -1 if the connection has been closed by the peer - int set_nosigpipe (fd_t s_); - - // Binds the underlying socket to the given device, eg. VRF or interface - void bind_to_device (fd_t s_, std::string &bound_device_); - -} - -#endif diff --git a/dep/libzmq/src/ipc_address.cpp b/dep/libzmq/src/ipc_address.cpp deleted file mode 100644 index 137ee84959..0000000000 --- a/dep/libzmq/src/ipc_address.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "ipc_address.hpp" - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - -#include "err.hpp" - -#include -#include - -zmq::ipc_address_t::ipc_address_t () -{ - memset (&address, 0, sizeof address); -} - -zmq::ipc_address_t::ipc_address_t (const sockaddr *sa, socklen_t sa_len) -{ - zmq_assert (sa && sa_len > 0); - - memset (&address, 0, sizeof address); - if (sa->sa_family == AF_UNIX) - memcpy(&address, sa, sa_len); -} - -zmq::ipc_address_t::~ipc_address_t () -{ -} - -int zmq::ipc_address_t::resolve (const char *path_) -{ - if (strlen (path_) >= sizeof address.sun_path) { - errno = ENAMETOOLONG; - return -1; - } - if (path_ [0] == '@' && !path_ [1]) { - errno = EINVAL; - return -1; - } - - address.sun_family = AF_UNIX; - strcpy (address.sun_path, path_); - /* Abstract sockets start with '\0' */ - if (path_ [0] == '@') - *address.sun_path = '\0'; - return 0; -} - -int zmq::ipc_address_t::to_string (std::string &addr_) -{ - if (address.sun_family != AF_UNIX) { - addr_.clear (); - return -1; - } - - std::stringstream s; - s << "ipc://"; - if (!address.sun_path [0] && address.sun_path [1]) - s << "@" << address.sun_path + 1; - else - s << address.sun_path; - addr_ = s.str (); - return 0; -} - -const sockaddr *zmq::ipc_address_t::addr () const -{ - return (sockaddr*) &address; -} - -socklen_t zmq::ipc_address_t::addrlen () const -{ - if (!address.sun_path [0] && address.sun_path [1]) - return (socklen_t) strlen (address.sun_path + 1) + sizeof (sa_family_t) + 1; - return (socklen_t) sizeof address; -} - -#endif diff --git a/dep/libzmq/src/ipc_address.hpp b/dep/libzmq/src/ipc_address.hpp deleted file mode 100644 index a77b0d58b6..0000000000 --- a/dep/libzmq/src/ipc_address.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_IPC_ADDRESS_HPP_INCLUDED__ -#define __ZMQ_IPC_ADDRESS_HPP_INCLUDED__ - -#include - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - -#include -#include - -namespace zmq -{ - - class ipc_address_t - { - public: - - ipc_address_t (); - ipc_address_t (const sockaddr *sa, socklen_t sa_len); - ~ipc_address_t (); - - // This function sets up the address for UNIX domain transport. - int resolve (const char *path_); - - // The opposite to resolve() - int to_string (std::string &addr_); - - const sockaddr *addr () const; - socklen_t addrlen () const; - - private: - - struct sockaddr_un address; - - ipc_address_t (const ipc_address_t&); - const ipc_address_t &operator = (const ipc_address_t&); - }; - -} - -#endif - -#endif - - diff --git a/dep/libzmq/src/ipc_connecter.cpp b/dep/libzmq/src/ipc_connecter.cpp deleted file mode 100644 index 48793e8c4a..0000000000 --- a/dep/libzmq/src/ipc_connecter.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "ipc_connecter.hpp" - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - -#include -#include - -#include "stream_engine.hpp" -#include "io_thread.hpp" -#include "random.hpp" -#include "err.hpp" -#include "ip.hpp" -#include "address.hpp" -#include "ipc_address.hpp" -#include "session_base.hpp" - -#include -#include -#include -#include - -zmq::ipc_connecter_t::ipc_connecter_t (class io_thread_t *io_thread_, - class session_base_t *session_, const options_t &options_, - const address_t *addr_, bool delayed_start_) : - own_t (io_thread_, options_), - io_object_t (io_thread_), - addr (addr_), - s (retired_fd), - handle_valid (false), - delayed_start (delayed_start_), - timer_started (false), - session (session_), - current_reconnect_ivl(options.reconnect_ivl) -{ - zmq_assert (addr); - zmq_assert (addr->protocol == "ipc"); - addr->to_string (endpoint); - socket = session-> get_socket(); -} - -zmq::ipc_connecter_t::~ipc_connecter_t () -{ - zmq_assert (!timer_started); - zmq_assert (!handle_valid); - zmq_assert (s == retired_fd); -} - -void zmq::ipc_connecter_t::process_plug () -{ - if (delayed_start) - add_reconnect_timer (); - else - start_connecting (); -} - -void zmq::ipc_connecter_t::process_term (int linger_) -{ - if (timer_started) { - cancel_timer (reconnect_timer_id); - timer_started = false; - } - - if (handle_valid) { - rm_fd (handle); - handle_valid = false; - } - - if (s != retired_fd) - close (); - - own_t::process_term (linger_); -} - -void zmq::ipc_connecter_t::in_event () -{ - // We are not polling for incoming data, so we are actually called - // because of error here. However, we can get error on out event as well - // on some platforms, so we'll simply handle both events in the same way. - out_event (); -} - -void zmq::ipc_connecter_t::out_event () -{ - fd_t fd = connect (); - rm_fd (handle); - handle_valid = false; - - // Handle the error condition by attempt to reconnect. - if (fd == retired_fd) { - close (); - add_reconnect_timer(); - return; - } - // Create the engine object for this connection. - stream_engine_t *engine = new (std::nothrow) - stream_engine_t (fd, options, endpoint); - alloc_assert (engine); - - // Attach the engine to the corresponding session object. - send_attach (session, engine); - - // Shut the connecter down. - terminate (); - - socket->event_connected (endpoint, fd); -} - -void zmq::ipc_connecter_t::timer_event (int id_) -{ - zmq_assert (id_ == reconnect_timer_id); - timer_started = false; - start_connecting (); -} - -void zmq::ipc_connecter_t::start_connecting () -{ - // Open the connecting socket. - int rc = open (); - - // Connect may succeed in synchronous manner. - if (rc == 0) { - handle = add_fd (s); - handle_valid = true; - out_event (); - } - - // Connection establishment may be delayed. Poll for its completion. - else - if (rc == -1 && errno == EINPROGRESS) { - handle = add_fd (s); - handle_valid = true; - set_pollout (handle); - socket->event_connect_delayed (endpoint, zmq_errno()); - } - - // Handle any other error condition by eventual reconnect. - else { - if (s != retired_fd) - close (); - add_reconnect_timer (); - } -} - -void zmq::ipc_connecter_t::add_reconnect_timer() -{ - int rc_ivl = get_new_reconnect_ivl(); - add_timer (rc_ivl, reconnect_timer_id); - socket->event_connect_retried (endpoint, rc_ivl); - timer_started = true; -} - -int zmq::ipc_connecter_t::get_new_reconnect_ivl () -{ - // The new interval is the current interval + random value. - int this_interval = current_reconnect_ivl + - (generate_random () % options.reconnect_ivl); - - // Only change the current reconnect interval if the maximum reconnect - // interval was set and if it's larger than the reconnect interval. - if (options.reconnect_ivl_max > 0 && - options.reconnect_ivl_max > options.reconnect_ivl) { - - // Calculate the next interval - current_reconnect_ivl = current_reconnect_ivl * 2; - if(current_reconnect_ivl >= options.reconnect_ivl_max) { - current_reconnect_ivl = options.reconnect_ivl_max; - } - } - return this_interval; -} - -int zmq::ipc_connecter_t::open () -{ - zmq_assert (s == retired_fd); - - // Create the socket. - s = open_socket (AF_UNIX, SOCK_STREAM, 0); - if (s == -1) - return -1; - - // Set the non-blocking flag. - unblock_socket (s); - - // Connect to the remote peer. - int rc = ::connect ( - s, addr->resolved.ipc_addr->addr (), - addr->resolved.ipc_addr->addrlen ()); - - // Connect was successful immediately. - if (rc == 0) - return 0; - - // Translate other error codes indicating asynchronous connect has been - // launched to a uniform EINPROGRESS. - if (rc == -1 && errno == EINTR) { - errno = EINPROGRESS; - return -1; - } - - // Forward the error. - return -1; -} - -int zmq::ipc_connecter_t::close () -{ - zmq_assert (s != retired_fd); - int rc = ::close (s); - errno_assert (rc == 0); - socket->event_closed (endpoint, s); - s = retired_fd; - return 0; -} - -zmq::fd_t zmq::ipc_connecter_t::connect () -{ - // Following code should handle both Berkeley-derived socket - // implementations and Solaris. - int err = 0; -#if defined ZMQ_HAVE_HPUX - int len = sizeof (err); -#else - socklen_t len = sizeof (err); -#endif - int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len); - if (rc == -1) { - if (errno == ENOPROTOOPT) - errno = 0; - err = errno; - } - if (err != 0) { - - // Assert if the error was caused by 0MQ bug. - // Networking problems are OK. No need to assert. - errno = err; - errno_assert (errno == ECONNREFUSED || errno == ECONNRESET || - errno == ETIMEDOUT || errno == EHOSTUNREACH || - errno == ENETUNREACH || errno == ENETDOWN); - - return retired_fd; - } - - fd_t result = s; - s = retired_fd; - return result; -} - -#endif - diff --git a/dep/libzmq/src/ipc_connecter.hpp b/dep/libzmq/src/ipc_connecter.hpp deleted file mode 100644 index 6149d626e2..0000000000 --- a/dep/libzmq/src/ipc_connecter.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __IPC_CONNECTER_HPP_INCLUDED__ -#define __IPC_CONNECTER_HPP_INCLUDED__ - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - struct address_t; - - class ipc_connecter_t : public own_t, public io_object_t - { - public: - - // If 'delayed_start' is true connecter first waits for a while, - // then starts connection process. - ipc_connecter_t (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_, const options_t &options_, - const address_t *addr_, bool delayed_start_); - ~ipc_connecter_t (); - - private: - - // ID of the timer used to delay the reconnection. - enum {reconnect_timer_id = 1}; - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - void out_event (); - void timer_event (int id_); - - // Internal function to start the actual connection establishment. - void start_connecting (); - - // Internal function to add a reconnect timer - void add_reconnect_timer(); - - // Internal function to return a reconnect backoff delay. - // Will modify the current_reconnect_ivl used for next call - // Returns the currently used interval - int get_new_reconnect_ivl (); - - // Open IPC connecting socket. Returns -1 in case of error, - // 0 if connect was successful immediately. Returns -1 with - // EAGAIN errno if async connect was launched. - int open (); - - // Close the connecting socket. - int close (); - - // Get the file descriptor of newly created connection. Returns - // retired_fd if the connection was unsuccessful. - fd_t connect (); - - // Address to connect to. Owned by session_base_t. - const address_t *addr; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // If true file descriptor is registered with the poller and 'handle' - // contains valid value. - bool handle_valid; - - // If true, connecter is waiting a while before trying to connect. - const bool delayed_start; - - // True iff a timer has been started. - bool timer_started; - - // Reference to the session we belong to. - zmq::session_base_t *session; - - // Current reconnect ivl, updated for backoff strategy - int current_reconnect_ivl; - - // String representation of endpoint to connect to - std::string endpoint; - - // Socket - zmq::socket_base_t *socket; - - ipc_connecter_t (const ipc_connecter_t&); - const ipc_connecter_t &operator = (const ipc_connecter_t&); - }; - -} - -#endif - -#endif - diff --git a/dep/libzmq/src/ipc_listener.cpp b/dep/libzmq/src/ipc_listener.cpp deleted file mode 100644 index 40e9ecba61..0000000000 --- a/dep/libzmq/src/ipc_listener.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "ipc_listener.hpp" - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - -#include - -#include - -#include "stream_engine.hpp" -#include "ipc_address.hpp" -#include "io_thread.hpp" -#include "session_base.hpp" -#include "config.hpp" -#include "err.hpp" -#include "ip.hpp" -#include "socket_base.hpp" - -#include -#include -#include -#include -#include - -#ifdef ZMQ_HAVE_LOCAL_PEERCRED -# include -# include -#endif -#ifdef ZMQ_HAVE_SO_PEERCRED -# include -# include -# include -# if defined ZMQ_HAVE_OPENBSD -# define ucred sockpeercred -# endif -#endif - -const char *zmq::ipc_listener_t::tmp_env_vars[] = { - "TMPDIR", - "TEMPDIR", - "TMP", - 0 // Sentinel -}; - -int zmq::ipc_listener_t::create_wildcard_address(std::string& path_, - std::string& file_) -{ - std::string tmp_path; - - // If TMPDIR, TEMPDIR, or TMP are available and are directories, create - // the socket directory there. - const char **tmp_env = tmp_env_vars; - while ( tmp_path.empty() && *tmp_env != 0 ) { - char *tmpdir = getenv(*tmp_env); - struct stat statbuf; - - // Confirm it is actually a directory before trying to use - if ( tmpdir != 0 && ::stat(tmpdir, &statbuf) == 0 && S_ISDIR(statbuf.st_mode) ) { - tmp_path.assign(tmpdir); - if ( *(tmp_path.rbegin()) != '/' ) { - tmp_path.push_back('/'); - } - } - - // Try the next environment variable - ++tmp_env; - } - - // Append a directory name - tmp_path.append("tmpXXXXXX"); - - // We need room for tmp_path + trailing NUL - std::vector buffer(tmp_path.length()+1); - strcpy (&buffer[0], tmp_path.c_str ()); - -#ifdef HAVE_MKDTEMP - // Create the directory. POSIX requires that mkdtemp() creates the - // directory with 0700 permissions, meaning the only possible race - // with socket creation could be the same user. However, since - // each socket is created in a directory created by mkdtemp(), and - // mkdtemp() guarantees a unique directory name, there will be no - // collision. - if (mkdtemp (&buffer[0]) == 0) { - return -1; - } - - path_.assign (&buffer[0]); - file_.assign (path_ + "/socket"); -#else - // Silence -Wunused-parameter. #pragma and __attribute__((unused)) are not - // very portable unfortunately... - (void) path_; - int fd = mkstemp (&buffer[0]); - if (fd == -1) - return -1; - ::close (fd); - - file_.assign (&buffer[0]); -#endif - - return 0; -} - -zmq::ipc_listener_t::ipc_listener_t (io_thread_t *io_thread_, - socket_base_t *socket_, const options_t &options_) : - own_t (io_thread_, options_), - io_object_t (io_thread_), - has_file (false), - s (retired_fd), - socket (socket_) -{ -} - -zmq::ipc_listener_t::~ipc_listener_t () -{ - zmq_assert (s == retired_fd); -} - -void zmq::ipc_listener_t::process_plug () -{ - // Start polling for incoming connections. - handle = add_fd (s); - set_pollin (handle); -} - -void zmq::ipc_listener_t::process_term (int linger_) -{ - rm_fd (handle); - close (); - own_t::process_term (linger_); -} - -void zmq::ipc_listener_t::in_event () -{ - fd_t fd = accept (); - - // If connection was reset by the peer in the meantime, just ignore it. - // TODO: Handle specific errors like ENFILE/EMFILE etc. - if (fd == retired_fd) { - socket->event_accept_failed (endpoint, zmq_errno()); - return; - } - - // Create the engine object for this connection. - stream_engine_t *engine = new (std::nothrow) - stream_engine_t (fd, options, endpoint); - alloc_assert (engine); - - // Choose I/O thread to run connecter in. Given that we are already - // running in an I/O thread, there must be at least one available. - io_thread_t *io_thread = choose_io_thread (options.affinity); - zmq_assert (io_thread); - - // Create and launch a session object. - session_base_t *session = session_base_t::create (io_thread, false, socket, - options, NULL); - errno_assert (session); - session->inc_seqnum (); - launch_child (session); - send_attach (session, engine, false); - socket->event_accepted (endpoint, fd); -} - -int zmq::ipc_listener_t::get_address (std::string &addr_) -{ - struct sockaddr_storage ss; -#ifdef ZMQ_HAVE_HPUX - int sl = sizeof (ss); -#else - socklen_t sl = sizeof (ss); -#endif - int rc = getsockname (s, (sockaddr *) &ss, &sl); - if (rc != 0) { - addr_.clear (); - return rc; - } - - ipc_address_t addr ((struct sockaddr *) &ss, sl); - return addr.to_string (addr_); -} - -int zmq::ipc_listener_t::set_address (const char *addr_) -{ - // Create addr on stack for auto-cleanup - std::string addr (addr_); - - // Allow wildcard file - if (options.use_fd == -1 && addr [0] == '*') { - if ( create_wildcard_address(tmp_socket_dirname, addr) < 0 ) { - return -1; - } - } - - // Get rid of the file associated with the UNIX domain socket that - // may have been left behind by the previous run of the application. - // MUST NOT unlink if the FD is managed by the user, or it will stop - // working after the first client connects. The user will take care of - // cleaning up the file after the service is stopped. - if (options.use_fd == -1) { - ::unlink (addr.c_str()); - } - filename.clear (); - - // Initialise the address structure. - ipc_address_t address; - int rc = address.resolve (addr.c_str()); - if (rc != 0) { - if ( !tmp_socket_dirname.empty() ) { - // We need to preserve errno to return to the user - int errno_ = errno; - ::rmdir(tmp_socket_dirname.c_str ()); - tmp_socket_dirname.clear(); - errno = errno_; - } - return -1; - } - - address.to_string (endpoint); - - if (options.use_fd != -1) { - s = options.use_fd; - } else { - // Create a listening socket. - s = open_socket (AF_UNIX, SOCK_STREAM, 0); - if (s == -1) { - if ( !tmp_socket_dirname.empty() ) { - // We need to preserve errno to return to the user - int errno_ = errno; - ::rmdir(tmp_socket_dirname.c_str ()); - tmp_socket_dirname.clear(); - errno = errno_; - } - return -1; - } - - // Bind the socket to the file path. - rc = bind (s, address.addr (), address.addrlen ()); - if (rc != 0) - goto error; - - // Listen for incoming connections. - rc = listen (s, options.backlog); - if (rc != 0) - goto error; - } - - filename.assign (addr.c_str()); - has_file = true; - - socket->event_listening (endpoint, s); - return 0; - -error: - int err = errno; - close (); - errno = err; - return -1; -} - -int zmq::ipc_listener_t::close () -{ - zmq_assert (s != retired_fd); - int fd_for_event = s; - int rc = ::close (s); - errno_assert (rc == 0); - - s = retired_fd; - - if (has_file && options.use_fd == -1) { - rc = 0; - - if ( rc == 0 && !tmp_socket_dirname.empty() ) { - rc = ::rmdir(tmp_socket_dirname.c_str ()); - tmp_socket_dirname.clear(); - } - - if (rc != 0) { - socket->event_close_failed (endpoint, zmq_errno()); - return -1; - } - } - - socket->event_closed (endpoint, fd_for_event); - return 0; -} - -#if defined ZMQ_HAVE_SO_PEERCRED - -bool zmq::ipc_listener_t::filter (fd_t sock) -{ - if (options.ipc_uid_accept_filters.empty () && - options.ipc_pid_accept_filters.empty () && - options.ipc_gid_accept_filters.empty ()) - return true; - - struct ucred cred; - socklen_t size = sizeof (cred); - - if (getsockopt (sock, SOL_SOCKET, SO_PEERCRED, &cred, &size)) - return false; - if (options.ipc_uid_accept_filters.find (cred.uid) != options.ipc_uid_accept_filters.end () || - options.ipc_gid_accept_filters.find (cred.gid) != options.ipc_gid_accept_filters.end () || - options.ipc_pid_accept_filters.find (cred.pid) != options.ipc_pid_accept_filters.end ()) - return true; - - struct passwd *pw; - struct group *gr; - - if (!(pw = getpwuid (cred.uid))) - return false; - for (options_t::ipc_gid_accept_filters_t::const_iterator it = options.ipc_gid_accept_filters.begin (); - it != options.ipc_gid_accept_filters.end (); it++) { - if (!(gr = getgrgid (*it))) - continue; - for (char **mem = gr->gr_mem; *mem; mem++) { - if (!strcmp (*mem, pw->pw_name)) - return true; - } - } - return false; -} - -#elif defined ZMQ_HAVE_LOCAL_PEERCRED - -bool zmq::ipc_listener_t::filter (fd_t sock) -{ - if (options.ipc_uid_accept_filters.empty () && - options.ipc_gid_accept_filters.empty ()) - return true; - - struct xucred cred; - socklen_t size = sizeof (cred); - - if (getsockopt (sock, 0, LOCAL_PEERCRED, &cred, &size)) - return false; - if (cred.cr_version != XUCRED_VERSION) - return false; - if (options.ipc_uid_accept_filters.find (cred.cr_uid) != options.ipc_uid_accept_filters.end ()) - return true; - for (int i = 0; i < cred.cr_ngroups; i++) { - if (options.ipc_gid_accept_filters.find (cred.cr_groups[i]) != options.ipc_gid_accept_filters.end ()) - return true; - } - - return false; -} - -#endif - -zmq::fd_t zmq::ipc_listener_t::accept () -{ - // Accept one connection and deal with different failure modes. - // The situation where connection cannot be accepted due to insufficient - // resources is considered valid and treated by ignoring the connection. - zmq_assert (s != retired_fd); -#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4 - fd_t sock = ::accept4 (s, NULL, NULL, SOCK_CLOEXEC); -#else - fd_t sock = ::accept (s, NULL, NULL); -#endif - if (sock == -1) { - errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR || errno == ECONNABORTED || errno == EPROTO || - errno == ENFILE); - return retired_fd; - } - -#if (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) && defined FD_CLOEXEC - // Race condition can cause socket not to be closed (if fork happens - // between accept and this point). - int rc = fcntl (sock, F_SETFD, FD_CLOEXEC); - errno_assert (rc != -1); -#endif - - // IPC accept() filters -#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED - if (!filter (sock)) { - int rc = ::close (sock); - errno_assert (rc == 0); - return retired_fd; - } -#endif - - if (zmq::set_nosigpipe (sock)) { -#ifdef ZMQ_HAVE_WINDOWS - int rc = closesocket (sock); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = ::close (sock); - errno_assert (rc == 0); -#endif - return retired_fd; - } - - return sock; -} - -#endif diff --git a/dep/libzmq/src/ipc_listener.hpp b/dep/libzmq/src/ipc_listener.hpp deleted file mode 100644 index 29d808e045..0000000000 --- a/dep/libzmq/src/ipc_listener.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_IPC_LISTENER_HPP_INCLUDED__ -#define __ZMQ_IPC_LISTENER_HPP_INCLUDED__ - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - -#include - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" - -namespace zmq -{ - - class io_thread_t; - class socket_base_t; - - class ipc_listener_t : public own_t, public io_object_t - { - public: - - ipc_listener_t (zmq::io_thread_t *io_thread_, - zmq::socket_base_t *socket_, const options_t &options_); - ~ipc_listener_t (); - - // Set address to listen on. - int set_address (const char *addr_); - - // Get the bound address for use with wildcards - int get_address (std::string &addr_); - - private: - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - - // Close the listening socket. - int close (); - - // Create wildcard path address - static int create_wildcard_address(std::string& path_, - std::string& file_); - - // Filter new connections if the OS provides a mechanism to get - // the credentials of the peer process. Called from accept(). -# if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED - bool filter (fd_t sock); -# endif - - // Accept the new connection. Returns the file descriptor of the - // newly created connection. The function may return retired_fd - // if the connection was dropped while waiting in the listen backlog. - fd_t accept (); - - // True, if the underlying file for UNIX domain socket exists. - bool has_file; - - // Name of the temporary directory (if any) that has the - // the UNIX domain socket - std::string tmp_socket_dirname; - - // Name of the file associated with the UNIX domain address. - std::string filename; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // Socket the listener belongs to. - zmq::socket_base_t *socket; - - // String representation of endpoint to bind to - std::string endpoint; - - // Acceptable temporary directory environment variables - static const char *tmp_env_vars[]; - - ipc_listener_t (const ipc_listener_t&); - const ipc_listener_t &operator = (const ipc_listener_t&); - }; - -} - -#endif - -#endif - diff --git a/dep/libzmq/src/kqueue.cpp b/dep/libzmq/src/kqueue.cpp deleted file mode 100644 index a0ec2f1ee5..0000000000 --- a/dep/libzmq/src/kqueue.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "kqueue.hpp" -#if defined ZMQ_USE_KQUEUE - -#include -#include -#include -#include -#include -#include -#include - -#include "macros.hpp" -#include "kqueue.hpp" -#include "err.hpp" -#include "config.hpp" -#include "i_poll_events.hpp" -#include "likely.hpp" - -// NetBSD defines (struct kevent).udata as intptr_t, everyone else -// as void *. -#if defined ZMQ_HAVE_NETBSD -#define kevent_udata_t intptr_t -#else -#define kevent_udata_t void * -#endif - -zmq::kqueue_t::kqueue_t (const zmq::ctx_t &ctx_) : - ctx(ctx_), - stopping (false) -{ - // Create event queue - kqueue_fd = kqueue (); - errno_assert (kqueue_fd != -1); -#ifdef HAVE_FORK - pid = getpid(); -#endif -} - -zmq::kqueue_t::~kqueue_t () -{ - worker.stop (); - close (kqueue_fd); -} - -void zmq::kqueue_t::kevent_add (fd_t fd_, short filter_, void *udata_) -{ - struct kevent ev; - - EV_SET (&ev, fd_, filter_, EV_ADD, 0, 0, (kevent_udata_t)udata_); - int rc = kevent (kqueue_fd, &ev, 1, NULL, 0, NULL); - errno_assert (rc != -1); -} - -void zmq::kqueue_t::kevent_delete (fd_t fd_, short filter_) -{ - struct kevent ev; - - EV_SET (&ev, fd_, filter_, EV_DELETE, 0, 0, 0); - int rc = kevent (kqueue_fd, &ev, 1, NULL, 0, NULL); - errno_assert (rc != -1); -} - -zmq::kqueue_t::handle_t zmq::kqueue_t::add_fd (fd_t fd_, - i_poll_events *reactor_) -{ - poll_entry_t *pe = new (std::nothrow) poll_entry_t; - alloc_assert (pe); - - pe->fd = fd_; - pe->flag_pollin = 0; - pe->flag_pollout = 0; - pe->reactor = reactor_; - - adjust_load (1); - - return pe; -} - -void zmq::kqueue_t::rm_fd (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (pe->flag_pollin) - kevent_delete (pe->fd, EVFILT_READ); - if (pe->flag_pollout) - kevent_delete (pe->fd, EVFILT_WRITE); - pe->fd = retired_fd; - retired.push_back (pe); - - adjust_load (-1); -} - -void zmq::kqueue_t::set_pollin (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (likely (!pe->flag_pollin)) { - pe->flag_pollin = true; - kevent_add (pe->fd, EVFILT_READ, pe); - } -} - -void zmq::kqueue_t::reset_pollin (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (likely (pe->flag_pollin)) { - pe->flag_pollin = false; - kevent_delete (pe->fd, EVFILT_READ); - } -} - -void zmq::kqueue_t::set_pollout (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (likely (!pe->flag_pollout)) { - pe->flag_pollout = true; - kevent_add (pe->fd, EVFILT_WRITE, pe); - } -} - -void zmq::kqueue_t::reset_pollout (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (likely (pe->flag_pollout)) { - pe->flag_pollout = false; - kevent_delete (pe->fd, EVFILT_WRITE); - } -} - -void zmq::kqueue_t::start () -{ - ctx.start_thread (worker, worker_routine, this); -} - -void zmq::kqueue_t::stop () -{ - stopping = true; -} - -int zmq::kqueue_t::max_fds () -{ - return -1; -} - -void zmq::kqueue_t::loop () -{ - while (!stopping) { - - // Execute any due timers. - int timeout = (int) execute_timers (); - - // Wait for events. - struct kevent ev_buf [max_io_events]; - timespec ts = {timeout / 1000, (timeout % 1000) * 1000000}; - int n = kevent (kqueue_fd, NULL, 0, &ev_buf [0], max_io_events, - timeout ? &ts: NULL); -#ifdef HAVE_FORK - if (unlikely(pid != getpid())) { - //printf("zmq::kqueue_t::loop aborting on forked child %d\n", (int)getpid()); - // simply exit the loop in a forked process. - return; - } -#endif - if (n == -1) { - errno_assert (errno == EINTR); - continue; - } - - for (int i = 0; i < n; i ++) { - poll_entry_t *pe = (poll_entry_t*) ev_buf [i].udata; - - if (pe->fd == retired_fd) - continue; - if (ev_buf [i].flags & EV_EOF) - pe->reactor->in_event (); - if (pe->fd == retired_fd) - continue; - if (ev_buf [i].filter == EVFILT_WRITE) - pe->reactor->out_event (); - if (pe->fd == retired_fd) - continue; - if (ev_buf [i].filter == EVFILT_READ) - pe->reactor->in_event (); - } - - // Destroy retired event sources. - for (retired_t::iterator it = retired.begin (); it != retired.end (); ++it) { - LIBZMQ_DELETE(*it); - } - retired.clear (); - } -} - -void zmq::kqueue_t::worker_routine (void *arg_) -{ - ((kqueue_t*) arg_)->loop (); -} - -#endif diff --git a/dep/libzmq/src/kqueue.hpp b/dep/libzmq/src/kqueue.hpp deleted file mode 100644 index 27c1b15121..0000000000 --- a/dep/libzmq/src/kqueue.hpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_KQUEUE_HPP_INCLUDED__ -#define __ZMQ_KQUEUE_HPP_INCLUDED__ - -// poller.hpp decides which polling mechanism to use. -#include "poller.hpp" -#if defined ZMQ_USE_KQUEUE - -#include -#include - -#include "ctx.hpp" -#include "fd.hpp" -#include "thread.hpp" -#include "poller_base.hpp" - -namespace zmq -{ - - struct i_poll_events; - - // Implements socket polling mechanism using the BSD-specific - // kqueue interface. - - class kqueue_t : public poller_base_t - { - public: - - typedef void* handle_t; - - kqueue_t (const ctx_t &ctx_); - ~kqueue_t (); - - // "poller" concept. - handle_t add_fd (fd_t fd_, zmq::i_poll_events *events_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void start (); - void stop (); - - static int max_fds (); - - private: - - // Main worker thread routine. - static void worker_routine (void *arg_); - - // Main event loop. - void loop (); - - // Reference to ZMQ context. - const ctx_t &ctx; - - // File descriptor referring to the kernel event queue. - fd_t kqueue_fd; - - // Adds the event to the kqueue. - void kevent_add (fd_t fd_, short filter_, void *udata_); - - // Deletes the event from the kqueue. - void kevent_delete (fd_t fd_, short filter_); - - struct poll_entry_t - { - fd_t fd; - bool flag_pollin; - bool flag_pollout; - zmq::i_poll_events *reactor; - }; - - // List of retired event sources. - typedef std::vector retired_t; - retired_t retired; - - // If true, thread is in the process of shutting down. - bool stopping; - - // Handle of the physical thread doing the I/O work. - thread_t worker; - - kqueue_t (const kqueue_t&); - const kqueue_t &operator = (const kqueue_t&); - -#ifdef HAVE_FORK - // the process that created this context. Used to detect forking. - pid_t pid; -#endif - }; - - typedef kqueue_t poller_t; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/lb.cpp b/dep/libzmq/src/lb.cpp deleted file mode 100644 index c4a691783d..0000000000 --- a/dep/libzmq/src/lb.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "lb.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::lb_t::lb_t () : - active (0), - current (0), - more (false), - dropping (false) -{ -} - -zmq::lb_t::~lb_t () -{ - zmq_assert (pipes.empty ()); -} - -void zmq::lb_t::attach (pipe_t *pipe_) -{ - pipes.push_back (pipe_); - activated (pipe_); -} - -void zmq::lb_t::pipe_terminated (pipe_t *pipe_) -{ - pipes_t::size_type index = pipes.index (pipe_); - - // If we are in the middle of multipart message and current pipe - // have disconnected, we have to drop the remainder of the message. - if (index == current && more) - dropping = true; - - // Remove the pipe from the list; adjust number of active pipes - // accordingly. - if (index < active) { - active--; - pipes.swap (index, active); - if (current == active) - current = 0; - } - pipes.erase (pipe_); -} - -void zmq::lb_t::activated (pipe_t *pipe_) -{ - // Move the pipe to the list of active pipes. - pipes.swap (pipes.index (pipe_), active); - active++; -} - -int zmq::lb_t::send (msg_t *msg_) -{ - return sendpipe (msg_, NULL); -} - -int zmq::lb_t::sendpipe (msg_t *msg_, pipe_t **pipe_) -{ - // Drop the message if required. If we are at the end of the message - // switch back to non-dropping mode. - if (dropping) { - - more = msg_->flags () & msg_t::more ? true : false; - dropping = more; - - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - return 0; - } - - while (active > 0) { - if (pipes [current]->write (msg_)) - { - if (pipe_) - *pipe_ = pipes [current]; - break; - } - - // If send fails for multi-part msg rollback other - // parts sent earlier and return EAGAIN. - // Application should handle this as suitable - if (more) - { - pipes [current]->rollback (); - more = 0; - errno = EAGAIN; - return -1; - } - - active--; - if (current < active) - pipes.swap (current, active); - else - current = 0; - } - - // If there are no pipes we cannot send the message. - if (active == 0) { - errno = EAGAIN; - return -1; - } - - // If it's final part of the message we can flush it downstream and - // continue round-robining (load balance). - more = msg_->flags () & msg_t::more? true: false; - if (!more) { - pipes [current]->flush (); - - if (++current >= active) - current = 0; - } - - // Detach the message from the data buffer. - int rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -bool zmq::lb_t::has_out () -{ - // If one part of the message was already written we can definitely - // write the rest of the message. - if (more) - return true; - - while (active > 0) { - - // Check whether a pipe has room for another message. - if (pipes [current]->check_write ()) - return true; - - // Deactivate the pipe. - active--; - pipes.swap (current, active); - if (current == active) - current = 0; - } - - return false; -} diff --git a/dep/libzmq/src/lb.hpp b/dep/libzmq/src/lb.hpp deleted file mode 100644 index 90d46fc536..0000000000 --- a/dep/libzmq/src/lb.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_LB_HPP_INCLUDED__ -#define __ZMQ_LB_HPP_INCLUDED__ - -#include "array.hpp" -#include "pipe.hpp" - -namespace zmq -{ - - // This class manages a set of outbound pipes. On send it load balances - // messages fairly among the pipes. - - class lb_t - { - public: - - lb_t (); - ~lb_t (); - - void attach (pipe_t *pipe_); - void activated (pipe_t *pipe_); - void pipe_terminated (pipe_t *pipe_); - - int send (msg_t *msg_); - - // Sends a message and stores the pipe that was used in pipe_. - // It is possible for this function to return success but keep pipe_ - // unset if the rest of a multipart message to a terminated pipe is - // being dropped. For the first frame, this will never happen. - int sendpipe (msg_t *msg_, pipe_t **pipe_); - - bool has_out (); - - private: - - // List of outbound pipes. - typedef array_t pipes_t; - pipes_t pipes; - - // Number of active pipes. All the active pipes are located at the - // beginning of the pipes array. - pipes_t::size_type active; - - // Points to the last pipe that the most recent message was sent to. - pipes_t::size_type current; - - // True if last we are in the middle of a multipart message. - bool more; - - // True if we are dropping current message. - bool dropping; - - lb_t (const lb_t&); - const lb_t &operator = (const lb_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/likely.hpp b/dep/libzmq/src/likely.hpp deleted file mode 100644 index d6cb14d704..0000000000 --- a/dep/libzmq/src/likely.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_LIKELY_HPP_INCLUDED__ -#define __ZMQ_LIKELY_HPP_INCLUDED__ - -#if defined __GNUC__ -#define likely(x) __builtin_expect ((x), 1) -#define unlikely(x) __builtin_expect ((x), 0) -#else -#define likely(x) (x) -#define unlikely(x) (x) -#endif - - -#endif diff --git a/dep/libzmq/src/macros.hpp b/dep/libzmq/src/macros.hpp deleted file mode 100644 index 3bb6267bbc..0000000000 --- a/dep/libzmq/src/macros.hpp +++ /dev/null @@ -1,12 +0,0 @@ - -/******************************************************************************/ -/* 0MQ Internal Use */ -/******************************************************************************/ - -#define LIBZMQ_UNUSED(object) (void)object -#define LIBZMQ_DELETE(p_object) {\ - delete p_object; \ - p_object = 0; \ -} - -/******************************************************************************/ diff --git a/dep/libzmq/src/mailbox.cpp b/dep/libzmq/src/mailbox.cpp deleted file mode 100644 index 14633fab94..0000000000 --- a/dep/libzmq/src/mailbox.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "mailbox.hpp" -#include "err.hpp" - -zmq::mailbox_t::mailbox_t () -{ - // Get the pipe into passive state. That way, if the users starts by - // polling on the associated file descriptor it will get woken up when - // new command is posted. - const bool ok = cpipe.read (NULL); - zmq_assert (!ok); - active = false; -} - -zmq::mailbox_t::~mailbox_t () -{ - // TODO: Retrieve and deallocate commands inside the cpipe. - - // Work around problem that other threads might still be in our - // send() method, by waiting on the mutex before disappearing. - sync.lock (); - sync.unlock (); -} - -zmq::fd_t zmq::mailbox_t::get_fd () const -{ - return signaler.get_fd (); -} - -void zmq::mailbox_t::send (const command_t &cmd_) -{ - sync.lock (); - cpipe.write (cmd_, false); - const bool ok = cpipe.flush (); - sync.unlock (); - if (!ok) - signaler.send (); -} - -int zmq::mailbox_t::recv (command_t *cmd_, int timeout_) -{ - // Try to get the command straight away. - if (active) { - if (cpipe.read (cmd_)) - return 0; - - // If there are no more commands available, switch into passive state. - active = false; - } - - // Wait for signal from the command sender. - int rc = signaler.wait (timeout_); - if (rc == -1) { - errno_assert (errno == EAGAIN || errno == EINTR); - return -1; - } - - // Receive the signal. - rc = signaler.recv_failable (); - if (rc == -1) { - errno_assert (errno == EAGAIN); - return -1; - } - - // Switch into active state. - active = true; - - // Get a command. - const bool ok = cpipe.read (cmd_); - zmq_assert (ok); - return 0; -} diff --git a/dep/libzmq/src/mailbox.hpp b/dep/libzmq/src/mailbox.hpp deleted file mode 100644 index e3fcbb3122..0000000000 --- a/dep/libzmq/src/mailbox.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MAILBOX_HPP_INCLUDED__ -#define __ZMQ_MAILBOX_HPP_INCLUDED__ - -#include - -#include "signaler.hpp" -#include "fd.hpp" -#include "config.hpp" -#include "command.hpp" -#include "ypipe.hpp" -#include "mutex.hpp" -#include "i_mailbox.hpp" - -namespace zmq -{ - - class mailbox_t : public i_mailbox - { - public: - - mailbox_t (); - ~mailbox_t (); - - fd_t get_fd () const; - void send (const command_t &cmd_); - int recv (command_t *cmd_, int timeout_); - -#ifdef HAVE_FORK - // close the file descriptors in the signaller. This is used in a forked - // child process to close the file descriptors so that they do not interfere - // with the context in the parent process. - void forked () { signaler.forked (); } -#endif - - private: - - // The pipe to store actual commands. - typedef ypipe_t cpipe_t; - cpipe_t cpipe; - - // Signaler to pass signals from writer thread to reader thread. - signaler_t signaler; - - // There's only one thread receiving from the mailbox, but there - // is arbitrary number of threads sending. Given that ypipe requires - // synchronised access on both of its endpoints, we have to synchronise - // the sending side. - mutex_t sync; - - // True if the underlying pipe is active, ie. when we are allowed to - // read commands from it. - bool active; - - // Disable copying of mailbox_t object. - mailbox_t (const mailbox_t&); - const mailbox_t &operator = (const mailbox_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/mailbox_safe.cpp b/dep/libzmq/src/mailbox_safe.cpp deleted file mode 100644 index a22d7b84bf..0000000000 --- a/dep/libzmq/src/mailbox_safe.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "mailbox_safe.hpp" -#include "clock.hpp" -#include "err.hpp" - -zmq::mailbox_safe_t::mailbox_safe_t (mutex_t* sync_) : - sync (sync_) -{ - // Get the pipe into passive state. That way, if the users starts by - // polling on the associated file descriptor it will get woken up when - // new command is posted. - const bool ok = cpipe.read (NULL); - zmq_assert (!ok); -} - -zmq::mailbox_safe_t::~mailbox_safe_t () -{ - // TODO: Retrieve and deallocate commands inside the cpipe. - - // Work around problem that other threads might still be in our - // send() method, by waiting on the mutex before disappearing. - sync->lock (); - sync->unlock (); -} - -void zmq::mailbox_safe_t::add_signaler (signaler_t* signaler) -{ - signalers.push_back(signaler); -} - -void zmq::mailbox_safe_t::remove_signaler (signaler_t* signaler) -{ - std::vector::iterator it = signalers.begin(); - - // TODO: make a copy of array and signal outside the lock - for (; it != signalers.end(); ++it){ - if (*it == signaler) - break; - } - - if (it != signalers.end()) - signalers.erase(it); -} - -void zmq::mailbox_safe_t::clear_signalers () -{ - signalers.clear (); -} - -void zmq::mailbox_safe_t::send (const command_t &cmd_) -{ - sync->lock (); - cpipe.write (cmd_, false); - const bool ok = cpipe.flush (); - - if (!ok) { - cond_var.broadcast (); - for (std::vector::iterator it = signalers.begin(); it != signalers.end(); ++it){ - (*it)->send(); - } - } - - sync->unlock (); -} - -int zmq::mailbox_safe_t::recv (command_t *cmd_, int timeout_) -{ - // Try to get the command straight away. - if (cpipe.read (cmd_)) - return 0; - - // Wait for signal from the command sender. - int rc = cond_var.wait (sync, timeout_); - if (rc == -1) { - errno_assert (errno == EAGAIN || errno == EINTR); - return -1; - } - - // Another thread may already fetch the command - const bool ok = cpipe.read (cmd_); - - if (!ok) { - errno = EAGAIN; - return -1; - } - - return 0; -} diff --git a/dep/libzmq/src/mailbox_safe.hpp b/dep/libzmq/src/mailbox_safe.hpp deleted file mode 100644 index 0e1382f2be..0000000000 --- a/dep/libzmq/src/mailbox_safe.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MAILBOX_SAFE_HPP_INCLUDED__ -#define __ZMQ_MAILBOX_SAFE_HPP_INCLUDED__ - -#include -#include - -#include "signaler.hpp" -#include "fd.hpp" -#include "config.hpp" -#include "command.hpp" -#include "ypipe.hpp" -#include "mutex.hpp" -#include "i_mailbox.hpp" -#include "condition_variable.hpp" - -namespace zmq -{ - - class mailbox_safe_t : public i_mailbox - { - public: - - mailbox_safe_t (mutex_t* sync_); - ~mailbox_safe_t (); - - void send (const command_t &cmd_); - int recv (command_t *cmd_, int timeout_); - - // Add signaler to mailbox which will be called when a message is ready - void add_signaler (signaler_t* signaler); - void remove_signaler (signaler_t* signaler); - void clear_signalers (); - -#ifdef HAVE_FORK - // close the file descriptors in the signaller. This is used in a forked - // child process to close the file descriptors so that they do not interfere - // with the context in the parent process. - void forked () - { - // TODO: call fork on the condition variable - } -#endif - - private: - - // The pipe to store actual commands. - typedef ypipe_t cpipe_t; - cpipe_t cpipe; - - // Condition variable to pass signals from writer thread to reader thread. - condition_variable_t cond_var; - - // Synchronize access to the mailbox from receivers and senders - mutex_t* sync; - - std::vector signalers; - - // Disable copying of mailbox_t object. - mailbox_safe_t (const mailbox_safe_t&); - const mailbox_safe_t &operator = (const mailbox_safe_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/mechanism.cpp b/dep/libzmq/src/mechanism.cpp deleted file mode 100644 index 24cc3f2a07..0000000000 --- a/dep/libzmq/src/mechanism.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "mechanism.hpp" -#include "options.hpp" -#include "msg.hpp" -#include "err.hpp" -#include "wire.hpp" -#include "session_base.hpp" - -zmq::mechanism_t::mechanism_t (const options_t &options_) : - options (options_) -{ -} - -zmq::mechanism_t::~mechanism_t () -{ -} - -void zmq::mechanism_t::set_peer_routing_id (const void *id_ptr, size_t id_size) -{ - routing_id.set (static_cast (id_ptr), id_size); -} - -void zmq::mechanism_t::peer_routing_id (msg_t *msg_) -{ - const int rc = msg_->init_size (routing_id.size ()); - errno_assert (rc == 0); - memcpy (msg_->data (), routing_id.data (), routing_id.size ()); - msg_->set_flags (msg_t::routing_id); -} - -void zmq::mechanism_t::set_user_id (const void *data_, size_t size_) -{ - user_id.set (static_cast (data_), size_); - zap_properties.ZMQ_MAP_INSERT_OR_EMPLACE ( - ZMQ_MSG_PROPERTY_USER_ID, std::string ((char *) data_, size_)); -} - -const zmq::blob_t &zmq::mechanism_t::get_user_id () const -{ - return user_id; -} - -const char *zmq::mechanism_t::socket_type_string (int socket_type) const -{ - static const char *names [] = {"PAIR", "PUB", "SUB", "REQ", "REP", - "DEALER", "ROUTER", "PULL", "PUSH", - "XPUB", "XSUB", "STREAM", - "SERVER", "CLIENT", - "RADIO", "DISH", - "GATHER", "SCATTER", "DGRAM"}; - zmq_assert (socket_type >= 0 && socket_type <= 18); - return names [socket_type]; -} - -static size_t property_len (size_t name_len, size_t value_len) -{ - return 1 + name_len + 4 + value_len; -} - -static size_t name_len (const char *name) -{ - const size_t name_len = strlen (name); - zmq_assert (name_len <= 255); - return name_len; -} - -size_t zmq::mechanism_t::add_property (unsigned char *ptr, - size_t ptr_capacity, - const char *name, - const void *value, - size_t value_len) -{ - const size_t name_len = ::name_len (name); - const size_t total_len = ::property_len (name_len, value_len); - zmq_assert (total_len <= ptr_capacity); - - *ptr++ = static_cast (name_len); - memcpy (ptr, name, name_len); - ptr += name_len; - zmq_assert (value_len <= 0x7FFFFFFF); - put_uint32 (ptr, static_cast (value_len)); - ptr += 4; - memcpy (ptr, value, value_len); - - return total_len; -} - -size_t zmq::mechanism_t::property_len (const char *name, size_t value_len) -{ - return ::property_len (name_len (name), value_len); -} - -#define ZMTP_PROPERTY_SOCKET_TYPE "Socket-Type" -#define ZMTP_PROPERTY_IDENTITY "Identity" - -size_t zmq::mechanism_t::add_basic_properties (unsigned char *buf, - size_t buf_capacity) const -{ - unsigned char *ptr = buf; - - // Add socket type property - const char *socket_type = socket_type_string (options.type); - ptr += add_property (ptr, buf_capacity, - ZMTP_PROPERTY_SOCKET_TYPE, socket_type, - strlen (socket_type)); - - // Add identity (aka routing id) property - if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER - || options.type == ZMQ_ROUTER) - ptr += add_property (ptr, buf_capacity - (ptr - buf), - ZMTP_PROPERTY_IDENTITY, options.routing_id, - options.routing_id_size); - - return ptr - buf; -} - -size_t zmq::mechanism_t::basic_properties_len() const -{ - const char *socket_type = socket_type_string (options.type); - return property_len (ZMTP_PROPERTY_SOCKET_TYPE, strlen (socket_type)) - + ((options.type == ZMQ_REQ || options.type == ZMQ_DEALER - || options.type == ZMQ_ROUTER) - ? property_len (ZMTP_PROPERTY_IDENTITY, - options.routing_id_size) - : 0); -} - -void zmq::mechanism_t::make_command_with_basic_properties ( - msg_t *msg_, const char *prefix, size_t prefix_len) const -{ - const size_t command_size = prefix_len + basic_properties_len (); - const int rc = msg_->init_size (command_size); - errno_assert (rc == 0); - - unsigned char *ptr = (unsigned char *) msg_->data (); - - // Add prefix - memcpy (ptr, prefix, prefix_len); - ptr += prefix_len; - - add_basic_properties ( - ptr, command_size - (ptr - (unsigned char *) msg_->data ())); -} - -int zmq::mechanism_t::parse_metadata (const unsigned char *ptr_, - size_t length_, - bool zap_flag) -{ - size_t bytes_left = length_; - - while (bytes_left > 1) { - const size_t name_length = static_cast (*ptr_); - ptr_ += 1; - bytes_left -= 1; - if (bytes_left < name_length) - break; - - const std::string name = std::string ((char *) ptr_, name_length); - ptr_ += name_length; - bytes_left -= name_length; - if (bytes_left < 4) - break; - - const size_t value_length = static_cast (get_uint32 (ptr_)); - ptr_ += 4; - bytes_left -= 4; - if (bytes_left < value_length) - break; - - const uint8_t *value = ptr_; - ptr_ += value_length; - bytes_left -= value_length; - - if (name == ZMTP_PROPERTY_IDENTITY && options.recv_routing_id) - set_peer_routing_id (value, value_length); - else - if (name == ZMTP_PROPERTY_SOCKET_TYPE) { - const std::string socket_type ((char *) value, value_length); - if (!check_socket_type (socket_type)) { - errno = EINVAL; - return -1; - } - } - else { - const int rc = property (name, value, value_length); - if (rc == -1) - return -1; - } - if (zap_flag) - zap_properties.ZMQ_MAP_INSERT_OR_EMPLACE ( - name, std::string ((char *) value, value_length)); - else - zmtp_properties.ZMQ_MAP_INSERT_OR_EMPLACE ( - name, std::string ((char *) value, value_length)); - } - if (bytes_left > 0) { - errno = EPROTO; - return -1; - } - return 0; -} - -int zmq::mechanism_t::property (const std::string& /* name_ */, - const void * /* value_ */, size_t /* length_ */) -{ - // Default implementation does not check - // property values and returns 0 to signal success. - return 0; -} - -bool zmq::mechanism_t::check_socket_type (const std::string& type_) const -{ - switch (options.type) { - case ZMQ_REQ: - return type_ == "REP" || type_ == "ROUTER"; - case ZMQ_REP: - return type_ == "REQ" || type_ == "DEALER"; - case ZMQ_DEALER: - return type_ == "REP" || type_ == "DEALER" || type_ == "ROUTER"; - case ZMQ_ROUTER: - return type_ == "REQ" || type_ == "DEALER" || type_ == "ROUTER"; - case ZMQ_PUSH: - return type_ == "PULL"; - case ZMQ_PULL: - return type_ == "PUSH"; - case ZMQ_PUB: - return type_ == "SUB" || type_ == "XSUB"; - case ZMQ_SUB: - return type_ == "PUB" || type_ == "XPUB"; - case ZMQ_XPUB: - return type_ == "SUB" || type_ == "XSUB"; - case ZMQ_XSUB: - return type_ == "PUB" || type_ == "XPUB"; - case ZMQ_PAIR: - return type_ == "PAIR"; - case ZMQ_SERVER: - return type_ == "CLIENT"; - case ZMQ_CLIENT: - return type_ == "SERVER"; - case ZMQ_RADIO: - return type_ == "DISH"; - case ZMQ_DISH: - return type_ == "RADIO"; - case ZMQ_GATHER: - return type_ == "SCATTER"; - case ZMQ_SCATTER: - return type_ == "GATHER"; - case ZMQ_DGRAM: - return type_ == "DGRAM"; - default: - break; - } - return false; -} diff --git a/dep/libzmq/src/mechanism.hpp b/dep/libzmq/src/mechanism.hpp deleted file mode 100644 index cd2b7d2b18..0000000000 --- a/dep/libzmq/src/mechanism.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MECHANISM_HPP_INCLUDED__ -#define __ZMQ_MECHANISM_HPP_INCLUDED__ - -#include "stdint.hpp" -#include "options.hpp" -#include "blob.hpp" -#include "metadata.hpp" - -namespace zmq -{ - - class msg_t; - class session_base_t; - - // Abstract class representing security mechanism. - // Different mechanism extends this class. - - class mechanism_t - { - public: - - enum status_t { - handshaking, - ready, - error - }; - - mechanism_t (const options_t &options_); - - virtual ~mechanism_t (); - - // Prepare next handshake command that is to be sent to the peer. - virtual int next_handshake_command (msg_t *msg_) = 0; - - // Process the handshake command received from the peer. - virtual int process_handshake_command (msg_t *msg_) = 0; - - virtual int encode (msg_t *) { return 0; } - - virtual int decode (msg_t *) { return 0; } - - // Notifies mechanism about availability of ZAP message. - virtual int zap_msg_available () { return 0; } - - // Returns the status of this mechanism. - virtual status_t status () const = 0; - - void set_peer_routing_id (const void *id_ptr, size_t id_size); - - void peer_routing_id (msg_t *msg_); - - void set_user_id (const void *user_id, size_t size); - - const blob_t &get_user_id () const; - - const metadata_t::dict_t& get_zmtp_properties () { - return zmtp_properties; - } - - const metadata_t::dict_t& get_zap_properties () { - return zap_properties; - } - - protected: - - // Only used to identify the socket for the Socket-Type - // property in the wire protocol. - const char *socket_type_string (int socket_type) const; - - static size_t add_property (unsigned char *ptr, - size_t ptr_capacity, - const char *name, - const void *value, - size_t value_len); - static size_t property_len (const char *name, - size_t value_len); - - size_t add_basic_properties (unsigned char *ptr, size_t ptr_capacity) const; - size_t basic_properties_len () const; - - void make_command_with_basic_properties (msg_t *msg_, - const char *prefix, - size_t prefix_len) const; - - // Parses a metadata. - // Metadata consists of a list of properties consisting of - // name and value as size-specified strings. - // Returns 0 on success and -1 on error, in which case errno is set. - int parse_metadata ( - const unsigned char *ptr_, size_t length, bool zap_flag = false); - - // This is called by parse_property method whenever it - // parses a new property. The function should return 0 - // on success and -1 on error, in which case it should - // set errno. Signaling error prevents parser from - // parsing remaining data. - // Derived classes are supposed to override this - // method to handle custom processing. - virtual int property (const std::string& name_, - const void *value_, size_t length_); - - // Properties received from ZMTP peer. - metadata_t::dict_t zmtp_properties; - - // Properties received from ZAP server. - metadata_t::dict_t zap_properties; - - options_t options; - - private: - - blob_t routing_id; - - blob_t user_id; - - // Returns true iff socket associated with the mechanism - // is compatible with a given socket type 'type_'. - bool check_socket_type (const std::string& type_) const; - }; - -} - -#endif diff --git a/dep/libzmq/src/mechanism_base.cpp b/dep/libzmq/src/mechanism_base.cpp deleted file mode 100644 index 216261a40f..0000000000 --- a/dep/libzmq/src/mechanism_base.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include "mechanism_base.hpp" -#include "session_base.hpp" - -zmq::mechanism_base_t::mechanism_base_t (session_base_t *const session_, - const options_t &options_) : - mechanism_t (options_), - session (session_) -{ - -} - -int zmq::mechanism_base_t::check_basic_command_structure (msg_t *msg_) -{ - if (msg_->size () <= 1 || msg_->size () <= ((uint8_t *) msg_->data ())[0]) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED); - errno = EPROTO; - return -1; - } - return 0; -} - -void zmq::mechanism_base_t::handle_error_reason (const char *error_reason, - size_t error_reason_len) -{ - if (error_reason_len == 3 && error_reason[1] == '0' - && error_reason[2] == '0' && error_reason[0] >= '3' - && error_reason[0] <= '5') { - // it is a ZAP status code, so emit an authentication failure event - session->get_socket ()->event_handshake_failed_auth ( - session->get_endpoint (), (error_reason[0] - '0') * 100); - } -} - -bool zmq::mechanism_base_t::zap_required() const -{ - return !options.zap_domain.empty (); -} diff --git a/dep/libzmq/src/mechanism_base.hpp b/dep/libzmq/src/mechanism_base.hpp deleted file mode 100644 index c6e76eeaf1..0000000000 --- a/dep/libzmq/src/mechanism_base.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MECHANISM_BASE_HPP_INCLUDED__ -#define __ZMQ_MECHANISM_BASE_HPP_INCLUDED__ - -#include "mechanism.hpp" - -namespace zmq -{ -class mechanism_base_t : public mechanism_t -{ - protected: - mechanism_base_t (session_base_t *const session_, - const options_t &options_); - - session_base_t *const session; - - int check_basic_command_structure (msg_t *msg_); - - void handle_error_reason (const char *error_reason, size_t error_reason_len); - - bool zap_required() const; -}; -} - -#endif diff --git a/dep/libzmq/src/metadata.cpp b/dep/libzmq/src/metadata.cpp deleted file mode 100644 index e2a8a11def..0000000000 --- a/dep/libzmq/src/metadata.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "metadata.hpp" - -zmq::metadata_t::metadata_t (const dict_t &dict) : - ref_cnt (1), - dict (dict) -{ -} - -const char *zmq::metadata_t::get (const std::string &property) const -{ - dict_t::const_iterator it = dict.find (property); - if (it == dict.end()) - { - /** \todo remove this when support for the deprecated name "Identity" is dropped */ - if (property == "Identity") - return get (ZMQ_MSG_PROPERTY_ROUTING_ID); - - return NULL; - } - else - return it->second.c_str (); -} - -void zmq::metadata_t::add_ref () -{ - ref_cnt.add (1); -} - -bool zmq::metadata_t::drop_ref () -{ - return !ref_cnt.sub (1); -} diff --git a/dep/libzmq/src/metadata.hpp b/dep/libzmq/src/metadata.hpp deleted file mode 100644 index 2b1a89f633..0000000000 --- a/dep/libzmq/src/metadata.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_METADATA_HPP_INCLUDED__ -#define __ZMQ_METADATA_HPP_INCLUDED__ - -#include -#include - -#include "atomic_counter.hpp" - -namespace zmq -{ - class metadata_t - { - public: - typedef std::map dict_t; - - metadata_t (const dict_t &dict); - - // Returns pointer to property value or NULL if - // property is not found. - const char *get (const std::string &property) const; - - void add_ref (); - - // Drop reference. Returns true iff the reference - // counter drops to zero. - bool drop_ref (); - - private: - metadata_t(const metadata_t&); - metadata_t & operator=(const metadata_t&); - - // Reference counter. - atomic_counter_t ref_cnt; - - // Dictionary holding metadata. - dict_t dict; - }; - -} - -#endif diff --git a/dep/libzmq/src/msg.cpp b/dep/libzmq/src/msg.cpp deleted file mode 100644 index 9924ba05ac..0000000000 --- a/dep/libzmq/src/msg.cpp +++ /dev/null @@ -1,578 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "msg.hpp" - -#include -#include -#include - -#include "stdint.hpp" -#include "likely.hpp" -#include "metadata.hpp" -#include "err.hpp" - -// Check whether the sizes of public representation of the message (zmq_msg_t) -// and private representation of the message (zmq::msg_t) match. - -typedef char zmq_msg_size_check - [2 * ((sizeof (zmq::msg_t) == sizeof (zmq_msg_t)) != 0) - 1]; - -bool zmq::msg_t::check () const -{ - return u.base.type >= type_min && u.base.type <= type_max; -} - -int zmq::msg_t::init (void* data_, size_t size_, - msg_free_fn* ffn_, void* hint, - content_t* content_) -{ - if (size_ < max_vsm_size) { - int const rc = init_size(size_); - - if (rc != -1) - { - memcpy(data(), data_, size_); - return 0; - } - else - { - return -1; - } - } - else if(content_) - { - return init_external_storage(content_, data_, size_, ffn_, hint); - } - else - { - return init_data(data_, size_, ffn_, hint); - } -} - -int zmq::msg_t::init () -{ - u.vsm.metadata = NULL; - u.vsm.type = type_vsm; - u.vsm.flags = 0; - u.vsm.size = 0; - u.vsm.group[0] = '\0'; - u.vsm.routing_id = 0; - return 0; -} - -int zmq::msg_t::init_size (size_t size_) -{ - if (size_ <= max_vsm_size) { - u.vsm.metadata = NULL; - u.vsm.type = type_vsm; - u.vsm.flags = 0; - u.vsm.size = (unsigned char) size_; - u.vsm.group[0] = '\0'; - u.vsm.routing_id = 0; - } - else { - u.lmsg.metadata = NULL; - u.lmsg.type = type_lmsg; - u.lmsg.flags = 0; - u.lmsg.group[0] = '\0'; - u.lmsg.routing_id = 0; - u.lmsg.content = NULL; - if (sizeof (content_t) + size_ > size_) - u.lmsg.content = (content_t*) malloc (sizeof (content_t) + size_); - if (unlikely (!u.lmsg.content)) { - errno = ENOMEM; - return -1; - } - - u.lmsg.content->data = u.lmsg.content + 1; - u.lmsg.content->size = size_; - u.lmsg.content->ffn = NULL; - u.lmsg.content->hint = NULL; - new (&u.lmsg.content->refcnt) zmq::atomic_counter_t (); - } - return 0; -} - -int zmq::msg_t::init_external_storage(content_t* content_, void* data_, size_t size_, - msg_free_fn *ffn_, void* hint_) -{ - zmq_assert(NULL != data_); - zmq_assert(NULL != content_); - - u.zclmsg.metadata = NULL; - u.zclmsg.type = type_zclmsg; - u.zclmsg.flags = 0; - u.zclmsg.group[0] = '\0'; - u.zclmsg.routing_id = 0; - - u.zclmsg.content = content_; - u.zclmsg.content->data = data_; - u.zclmsg.content->size = size_; - u.zclmsg.content->ffn = ffn_; - u.zclmsg.content->hint = hint_; - new (&u.zclmsg.content->refcnt) zmq::atomic_counter_t(); - - return 0; -} - -int zmq::msg_t::init_data (void *data_, size_t size_, - msg_free_fn *ffn_, void *hint_) -{ - // If data is NULL and size is not 0, a segfault - // would occur once the data is accessed - zmq_assert (data_ != NULL || size_ == 0); - - // Initialize constant message if there's no need to deallocate - if (ffn_ == NULL) { - u.cmsg.metadata = NULL; - u.cmsg.type = type_cmsg; - u.cmsg.flags = 0; - u.cmsg.data = data_; - u.cmsg.size = size_; - u.cmsg.group[0] = '\0'; - u.cmsg.routing_id = 0; - } - else { - u.lmsg.metadata = NULL; - u.lmsg.type = type_lmsg; - u.lmsg.flags = 0; - u.lmsg.group[0] = '\0'; - u.lmsg.routing_id = 0; - u.lmsg.content = (content_t*) malloc (sizeof (content_t)); - if (!u.lmsg.content) { - errno = ENOMEM; - return -1; - } - - u.lmsg.content->data = data_; - u.lmsg.content->size = size_; - u.lmsg.content->ffn = ffn_; - u.lmsg.content->hint = hint_; - new (&u.lmsg.content->refcnt) zmq::atomic_counter_t (); - } - return 0; - -} - -int zmq::msg_t::init_delimiter () -{ - u.delimiter.metadata = NULL; - u.delimiter.type = type_delimiter; - u.delimiter.flags = 0; - u.delimiter.group[0] = '\0'; - u.delimiter.routing_id = 0; - return 0; -} - -int zmq::msg_t::init_join () -{ - u.base.metadata = NULL; - u.base.type = type_join; - u.base.flags = 0; - u.base.group[0] = '\0'; - u.base.routing_id = 0; - return 0; -} - -int zmq::msg_t::init_leave () -{ - u.base.metadata = NULL; - u.base.type = type_leave; - u.base.flags = 0; - u.base.group[0] = '\0'; - u.base.routing_id = 0; - return 0; -} - -int zmq::msg_t::close () -{ - // Check the validity of the message. - if (unlikely (!check ())) { - errno = EFAULT; - return -1; - } - - if (u.base.type == type_lmsg) { - - // If the content is not shared, or if it is shared and the reference - // count has dropped to zero, deallocate it. - if (!(u.lmsg.flags & msg_t::shared) || - !u.lmsg.content->refcnt.sub (1)) { - - // We used "placement new" operator to initialize the reference - // counter so we call the destructor explicitly now. - u.lmsg.content->refcnt.~atomic_counter_t (); - - if (u.lmsg.content->ffn) - u.lmsg.content->ffn (u.lmsg.content->data, - u.lmsg.content->hint); - free (u.lmsg.content); - } - } - - if (is_zcmsg()) - { - zmq_assert(u.zclmsg.content->ffn); - - // If the content is not shared, or if it is shared and the reference - // count has dropped to zero, deallocate it. - if (!(u.zclmsg.flags & msg_t::shared) || - !u.zclmsg.content->refcnt.sub (1)) { - - // We used "placement new" operator to initialize the reference - // counter so we call the destructor explicitly now. - u.zclmsg.content->refcnt.~atomic_counter_t (); - - u.zclmsg.content->ffn (u.zclmsg.content->data, - u.zclmsg.content->hint); - } - } - - if (u.base.metadata != NULL) { - if (u.base.metadata->drop_ref ()) { - LIBZMQ_DELETE(u.base.metadata); - } - u.base.metadata = NULL; - } - - // Make the message invalid. - u.base.type = 0; - - return 0; -} - -int zmq::msg_t::move (msg_t &src_) -{ - // Check the validity of the source. - if (unlikely (!src_.check ())) { - errno = EFAULT; - return -1; - } - - int rc = close (); - if (unlikely (rc < 0)) - return rc; - - *this = src_; - - rc = src_.init (); - if (unlikely (rc < 0)) - return rc; - - return 0; -} - -int zmq::msg_t::copy (msg_t &src_) -{ - // Check the validity of the source. - if (unlikely (!src_.check ())) { - errno = EFAULT; - return -1; - } - - int rc = close (); - if (unlikely (rc < 0)) - return rc; - - if (src_.u.base.type == type_lmsg ) { - - // One reference is added to shared messages. Non-shared messages - // are turned into shared messages and reference count is set to 2. - if (src_.u.lmsg.flags & msg_t::shared) - src_.u.lmsg.content->refcnt.add (1); - else { - src_.u.lmsg.flags |= msg_t::shared; - src_.u.lmsg.content->refcnt.set (2); - } - } - - if (src_.is_zcmsg()) { - - // One reference is added to shared messages. Non-shared messages - // are turned into shared messages and reference count is set to 2. - if (src_.u.zclmsg.flags & msg_t::shared) - src_.refcnt()->add (1); - else { - src_.u.zclmsg.flags |= msg_t::shared; - src_.refcnt()->set (2); - } - } - if (src_.u.base.metadata != NULL) - src_.u.base.metadata->add_ref (); - - *this = src_; - - return 0; - -} - -void *zmq::msg_t::data () -{ - // Check the validity of the message. - zmq_assert (check ()); - - switch (u.base.type) { - case type_vsm: - return u.vsm.data; - case type_lmsg: - return u.lmsg.content->data; - case type_cmsg: - return u.cmsg.data; - case type_zclmsg: - return u.zclmsg.content->data; - default: - zmq_assert (false); - return NULL; - } -} - -size_t zmq::msg_t::size () const -{ - // Check the validity of the message. - zmq_assert (check ()); - - switch (u.base.type) { - case type_vsm: - return u.vsm.size; - case type_lmsg: - return u.lmsg.content->size; - case type_zclmsg: - return u.zclmsg.content->size; - case type_cmsg: - return u.cmsg.size; - default: - zmq_assert (false); - return 0; - } -} - -unsigned char zmq::msg_t::flags () const -{ - return u.base.flags; -} - -void zmq::msg_t::set_flags (unsigned char flags_) -{ - u.base.flags |= flags_; -} - -void zmq::msg_t::reset_flags (unsigned char flags_) -{ - u.base.flags &= ~flags_; -} - -zmq::metadata_t *zmq::msg_t::metadata () const -{ - return u.base.metadata; -} - -void zmq::msg_t::set_metadata (zmq::metadata_t *metadata_) -{ - assert (metadata_ != NULL); - assert (u.base.metadata == NULL); - metadata_->add_ref (); - u.base.metadata = metadata_; -} - -void zmq::msg_t::reset_metadata () -{ - if (u.base.metadata) { - if (u.base.metadata->drop_ref ()) { - LIBZMQ_DELETE(u.base.metadata); - } - u.base.metadata = NULL; - } -} - -bool zmq::msg_t::is_routing_id () const -{ - return (u.base.flags & routing_id) == routing_id; -} - -bool zmq::msg_t::is_credential () const -{ - return (u.base.flags & credential) == credential; -} - -bool zmq::msg_t::is_delimiter () const -{ - return u.base.type == type_delimiter; -} - -bool zmq::msg_t::is_vsm () const -{ - return u.base.type == type_vsm; -} - -bool zmq::msg_t::is_cmsg () const -{ - return u.base.type == type_cmsg; -} - -bool zmq::msg_t::is_zcmsg() const -{ - return u.base.type == type_zclmsg; -} - -bool zmq::msg_t::is_join() const -{ - return u.base.type == type_join; -} - -bool zmq::msg_t::is_leave() const -{ - return u.base.type == type_leave; -} - -void zmq::msg_t::add_refs (int refs_) -{ - zmq_assert (refs_ >= 0); - - // Operation not supported for messages with metadata. - zmq_assert (u.base.metadata == NULL); - - // No copies required. - if (!refs_) - return; - - // VSMs, CMSGS and delimiters can be copied straight away. The only - // message type that needs special care are long messages. - if (u.base.type == type_lmsg || is_zcmsg() ) { - if (u.base.flags & msg_t::shared) - refcnt()->add (refs_); - else { - refcnt()->set (refs_ + 1); - u.base.flags |= msg_t::shared; - } - } -} - -bool zmq::msg_t::rm_refs (int refs_) -{ - zmq_assert (refs_ >= 0); - - // Operation not supported for messages with metadata. - zmq_assert (u.base.metadata == NULL); - - // No copies required. - if (!refs_) - return true; - - // If there's only one reference close the message. - if ( (u.base.type != type_zclmsg && u.base.type != type_lmsg) || !(u.base.flags & msg_t::shared)) { - close (); - return false; - } - - // The only message type that needs special care are long and zcopy messages. - if (u.base.type == type_lmsg && !u.lmsg.content->refcnt.sub(refs_)) { - // We used "placement new" operator to initialize the reference - // counter so we call the destructor explicitly now. - u.lmsg.content->refcnt.~atomic_counter_t (); - - if (u.lmsg.content->ffn) - u.lmsg.content->ffn (u.lmsg.content->data, u.lmsg.content->hint); - free (u.lmsg.content); - - return false; - } - - if (is_zcmsg() && !u.zclmsg.content->refcnt.sub(refs_)) { - // storage for rfcnt is provided externally - if (u.zclmsg.content->ffn) { - u.zclmsg.content->ffn(u.zclmsg.content->data, u.zclmsg.content->hint); - } - - return false; - } - - return true; -} - -uint32_t zmq::msg_t::get_routing_id () -{ - return u.base.routing_id; -} - -int zmq::msg_t::set_routing_id (uint32_t routing_id_) -{ - if (routing_id_) { - u.base.routing_id = routing_id_; - return 0; - } - errno = EINVAL; - return -1; -} - -int zmq::msg_t::reset_routing_id () -{ - u.base.routing_id = 0; - return 0; -} - -const char * zmq::msg_t::group () -{ - return u.base.group; -} - -int zmq::msg_t::set_group (const char * group_) -{ - return set_group (group_, strlen (group_)); -} - -int zmq::msg_t::set_group (const char * group_, size_t length_) -{ - if (length_> ZMQ_GROUP_MAX_LENGTH) - { - errno = EINVAL; - return -1; - } - - strncpy (u.base.group, group_, length_); - u.base.group[length_] = '\0'; - - return 0; -} - -zmq::atomic_counter_t *zmq::msg_t::refcnt() -{ - switch(u.base.type) - { - case type_lmsg: - return &u.lmsg.content->refcnt; - case type_zclmsg: - return &u.zclmsg.content->refcnt; - default: - zmq_assert(false); - return NULL; - } -} diff --git a/dep/libzmq/src/msg.hpp b/dep/libzmq/src/msg.hpp deleted file mode 100644 index 4ce4b1f4b1..0000000000 --- a/dep/libzmq/src/msg.hpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MSG_HPP_INCLUDE__ -#define __ZMQ_MSG_HPP_INCLUDE__ - -#include -#include - -#include "config.hpp" -#include "err.hpp" -#include "fd.hpp" -#include "atomic_counter.hpp" -#include "metadata.hpp" - -// Signature for free function to deallocate the message content. -// Note that it has to be declared as "C" so that it is the same as -// zmq_free_fn defined in zmq.h. -extern "C" -{ - typedef void (msg_free_fn) (void *data, void *hint); -} - -namespace zmq -{ - - // Note that this structure needs to be explicitly constructed - // (init functions) and destructed (close function). - - class msg_t - { - public: - - // Shared message buffer. Message data are either allocated in one - // continuous block along with this structure - thus avoiding one - // malloc/free pair or they are stored in user-supplied memory. - // In the latter case, ffn member stores pointer to the function to be - // used to deallocate the data. If the buffer is actually shared (there - // are at least 2 references to it) refcount member contains number of - // references. - struct content_t - { - void *data; - size_t size; - msg_free_fn *ffn; - void *hint; - zmq::atomic_counter_t refcnt; - }; - - // Message flags. - enum - { - more = 1, // Followed by more parts - command = 2, // Command frame (see ZMTP spec) - credential = 32, - routing_id = 64, - shared = 128 - }; - - bool check () const; - int init(); - - int init (void* data, size_t size_, - msg_free_fn* ffn_, void* hint, - content_t* content_ = NULL); - - int init_size (size_t size_); - int init_data (void *data_, size_t size_, msg_free_fn *ffn_, - void *hint_); - int init_external_storage(content_t* content_, void *data_, size_t size_, - msg_free_fn *ffn_, void *hint_); - int init_delimiter (); - int init_join (); - int init_leave (); - int close (); - int move (msg_t &src_); - int copy (msg_t &src_); - void *data (); - size_t size () const; - unsigned char flags () const; - void set_flags (unsigned char flags_); - void reset_flags (unsigned char flags_); - metadata_t *metadata () const; - void set_metadata (metadata_t *metadata_); - void reset_metadata (); - bool is_routing_id () const; - bool is_credential () const; - bool is_delimiter () const; - bool is_join () const; - bool is_leave () const; - bool is_vsm () const; - bool is_cmsg () const; - bool is_zcmsg() const; - uint32_t get_routing_id (); - int set_routing_id (uint32_t routing_id_); - int reset_routing_id (); - const char * group (); - int set_group (const char* group_); - int set_group (const char*, size_t length); - - // After calling this function you can copy the message in POD-style - // refs_ times. No need to call copy. - void add_refs (int refs_); - - // Removes references previously added by add_refs. If the number of - // references drops to 0, the message is closed and false is returned. - bool rm_refs (int refs_); - - // Size in bytes of the largest message that is still copied around - // rather than being reference-counted. - enum { msg_t_size = 64 }; - enum { max_vsm_size = msg_t_size - (sizeof (metadata_t *) + - 3 + - 16 + - sizeof (uint32_t))}; - private: - zmq::atomic_counter_t* refcnt(); - - // Different message types. - enum type_t - { - type_min = 101, - // VSM messages store the content in the message itself - type_vsm = 101, - // LMSG messages store the content in malloc-ed memory - type_lmsg = 102, - // Delimiter messages are used in envelopes - type_delimiter = 103, - // CMSG messages point to constant data - type_cmsg = 104, - - // zero-copy LMSG message for v2_decoder - type_zclmsg = 105, - - // Join message for radio_dish - type_join = 106, - - // Leave message for radio_dish - type_leave = 107, - - type_max = 107 - }; - - // Note that fields shared between different message types are not - // moved to the parent class (msg_t). This way we get tighter packing - // of the data. Shared fields can be accessed via 'base' member of - // the union. - union { - struct { - metadata_t *metadata; - unsigned char unused [msg_t_size - (sizeof (metadata_t *) + - 2 + - 16 + - sizeof (uint32_t))]; - unsigned char type; - unsigned char flags; - char group [16]; - uint32_t routing_id; - } base; - struct { - metadata_t *metadata; - unsigned char data [max_vsm_size]; - unsigned char size; - unsigned char type; - unsigned char flags; - char group [16]; - uint32_t routing_id; - } vsm; - struct { - metadata_t *metadata; - content_t *content; - unsigned char unused [msg_t_size - (sizeof (metadata_t *) + - sizeof (content_t*) + - 2 + - 16 + - sizeof (uint32_t))]; - unsigned char type; - unsigned char flags; - char group [16]; - uint32_t routing_id; - } lmsg; - struct { - metadata_t *metadata; - content_t *content; - unsigned char unused [msg_t_size - (sizeof (metadata_t *) + - sizeof (content_t*) + - 2 + - 16 + - sizeof (uint32_t))]; - unsigned char type; - unsigned char flags; - char group [16]; - uint32_t routing_id; - } zclmsg; - struct { - metadata_t *metadata; - void* data; - size_t size; - unsigned char unused [msg_t_size - (sizeof (metadata_t *) + - sizeof (void*) + - sizeof (size_t) + - 2 + - 16 + - sizeof (uint32_t))]; - unsigned char type; - unsigned char flags; - char group [16]; - uint32_t routing_id; - } cmsg; - struct { - metadata_t *metadata; - unsigned char unused [msg_t_size - (sizeof (metadata_t *) + - 2 + - 16 + - sizeof (uint32_t))]; - unsigned char type; - unsigned char flags; - char group [16]; - uint32_t routing_id; - } delimiter; - } u; - }; - - inline int close_and_return (zmq::msg_t *msg, int echo) - { - // Since we abort on close failure we preserve errno for success case. - int err = errno; - const int rc = msg->close (); - errno_assert (rc == 0); - errno = err; - return echo; - } - - inline int close_and_return (zmq::msg_t msg [], int count, int echo) - { - for (int i = 0; i < count; i++) - close_and_return (&msg [i], 0); - return echo; - } -} - -#endif diff --git a/dep/libzmq/src/mtrie.cpp b/dep/libzmq/src/mtrie.cpp deleted file mode 100644 index a280622148..0000000000 --- a/dep/libzmq/src/mtrie.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include -#include - -#include "err.hpp" -#include "pipe.hpp" -#include "macros.hpp" -#include "mtrie.hpp" - -zmq::mtrie_t::mtrie_t () : - pipes (0), - min (0), - count (0), - live_nodes (0) -{ -} - -zmq::mtrie_t::~mtrie_t () -{ - LIBZMQ_DELETE(pipes); - - if (count == 1) { - zmq_assert (next.node); - LIBZMQ_DELETE(next.node); - } - else if (count > 1) { - for (unsigned short i = 0; i != count; ++i) { - LIBZMQ_DELETE(next.table[i]); - } - free (next.table); - } -} - -bool zmq::mtrie_t::add (unsigned char *prefix_, size_t size_, pipe_t *pipe_) -{ - return add_helper (prefix_, size_, pipe_); -} - -bool zmq::mtrie_t::add_helper (unsigned char *prefix_, size_t size_, - pipe_t *pipe_) -{ - // We are at the node corresponding to the prefix. We are done. - if (!size_) { - bool result = !pipes; - if (!pipes) { - pipes = new (std::nothrow) pipes_t; - alloc_assert (pipes); - } - pipes->insert (pipe_); - return result; - } - - unsigned char c = *prefix_; - if (c < min || c >= min + count) { - - // The character is out of range of currently handled - // characters. We have to extend the table. - if (!count) { - min = c; - count = 1; - next.node = NULL; - } - else - if (count == 1) { - unsigned char oldc = min; - mtrie_t *oldp = next.node; - count = (min < c ? c - min : min - c) + 1; - next.table = (mtrie_t**) - malloc (sizeof (mtrie_t*) * count); - alloc_assert (next.table); - for (unsigned short i = 0; i != count; ++i) - next.table [i] = 0; - min = std::min (min, c); - next.table [oldc - min] = oldp; - } - else - if (min < c) { - // The new character is above the current character range. - unsigned short old_count = count; - count = c - min + 1; - next.table = (mtrie_t**) realloc (next.table, - sizeof (mtrie_t*) * count); - alloc_assert (next.table); - for (unsigned short i = old_count; i != count; i++) - next.table [i] = NULL; - } - else { - // The new character is below the current character range. - unsigned short old_count = count; - count = (min + old_count) - c; - next.table = (mtrie_t**) realloc (next.table, - sizeof (mtrie_t*) * count); - alloc_assert (next.table); - memmove (next.table + min - c, next.table, - old_count * sizeof (mtrie_t*)); - for (unsigned short i = 0; i != min - c; i++) - next.table [i] = NULL; - min = c; - } - } - - // If next node does not exist, create one. - if (count == 1) { - if (!next.node) { - next.node = new (std::nothrow) mtrie_t; - alloc_assert (next.node); - ++live_nodes; - } - return next.node->add_helper (prefix_ + 1, size_ - 1, pipe_); - } - else { - if (!next.table [c - min]) { - next.table [c - min] = new (std::nothrow) mtrie_t; - alloc_assert (next.table [c - min]); - ++live_nodes; - } - return next.table [c - min]->add_helper (prefix_ + 1, size_ - 1, pipe_); - } -} - - -void zmq::mtrie_t::rm (pipe_t *pipe_, - void (*func_) (unsigned char *data_, size_t size_, void *arg_), - void *arg_, bool call_on_uniq_) -{ - unsigned char *buff = NULL; - rm_helper (pipe_, &buff, 0, 0, func_, arg_, call_on_uniq_); - free (buff); -} - -void zmq::mtrie_t::rm_helper (pipe_t *pipe_, unsigned char **buff_, - size_t buffsize_, size_t maxbuffsize_, - void (*func_) (unsigned char *data_, size_t size_, void *arg_), - void *arg_, bool call_on_uniq_) -{ - // Remove the subscription from this node. - if (pipes && pipes->erase (pipe_)) { - if (!call_on_uniq_ || pipes->empty ()) { - func_ (*buff_, buffsize_, arg_); - } - - if (pipes->empty ()) { - LIBZMQ_DELETE(pipes); - } - } - - // Adjust the buffer. - if (buffsize_ >= maxbuffsize_) { - maxbuffsize_ = buffsize_ + 256; - *buff_ = (unsigned char*) realloc (*buff_, maxbuffsize_); - alloc_assert (*buff_); - } - - // If there are no subnodes in the trie, return. - if (count == 0) - return; - - // If there's one subnode (optimisation). - if (count == 1) { - (*buff_) [buffsize_] = min; - buffsize_++; - next.node->rm_helper (pipe_, buff_, buffsize_, maxbuffsize_, - func_, arg_, call_on_uniq_); - - // Prune the node if it was made redundant by the removal - if (next.node->is_redundant ()) { - LIBZMQ_DELETE(next.node); - count = 0; - --live_nodes; - zmq_assert (live_nodes == 0); - } - return; - } - - // If there are multiple subnodes. - // - // New min non-null character in the node table after the removal - unsigned char new_min = min + count - 1; - // New max non-null character in the node table after the removal - unsigned char new_max = min; - for (unsigned short c = 0; c != count; c++) { - (*buff_) [buffsize_] = min + c; - if (next.table [c]) { - next.table [c]->rm_helper (pipe_, buff_, buffsize_ + 1, - maxbuffsize_, func_, arg_, call_on_uniq_); - - // Prune redundant nodes from the mtrie - if (next.table [c]->is_redundant ()) { - LIBZMQ_DELETE(next.table[c]); - - zmq_assert (live_nodes > 0); - --live_nodes; - } - else { - // The node is not redundant, so it's a candidate for being - // the new min/max node. - // - // We loop through the node array from left to right, so the - // first non-null, non-redundant node encountered is the new - // minimum index. Conversely, the last non-redundant, non-null - // node encountered is the new maximum index. - if (c + min < new_min) - new_min = c + min; - if (c + min > new_max) - new_max = c + min; - } - } - } - - zmq_assert (count > 1); - - // Free the node table if it's no longer used. - if (live_nodes == 0) { - free (next.table); - next.table = NULL; - count = 0; - } - // Compact the node table if possible - else - if (live_nodes == 1) { - // If there's only one live node in the table we can - // switch to using the more compact single-node - // representation - zmq_assert (new_min == new_max); - zmq_assert (new_min >= min && new_min < min + count); - mtrie_t *node = next.table [new_min - min]; - zmq_assert (node); - free (next.table); - next.node = node; - count = 1; - min = new_min; - } - else - if (new_min > min || new_max < min + count - 1) { - zmq_assert (new_max - new_min + 1 > 1); - - mtrie_t **old_table = next.table; - zmq_assert (new_min > min || new_max < min + count - 1); - zmq_assert (new_min >= min); - zmq_assert (new_max <= min + count - 1); - zmq_assert (new_max - new_min + 1 < count); - - count = new_max - new_min + 1; - next.table = (mtrie_t**) malloc (sizeof (mtrie_t*) * count); - alloc_assert (next.table); - - memmove (next.table, old_table + (new_min - min), - sizeof (mtrie_t*) * count); - free (old_table); - - min = new_min; - } -} - -bool zmq::mtrie_t::rm (unsigned char *prefix_, size_t size_, pipe_t *pipe_) -{ - return rm_helper (prefix_, size_, pipe_); -} - -bool zmq::mtrie_t::rm_helper (unsigned char *prefix_, size_t size_, - pipe_t *pipe_) -{ - if (!size_) { - if (pipes) { - pipes_t::size_type erased = pipes->erase (pipe_); - zmq_assert (erased == 1); - if (pipes->empty ()) { - LIBZMQ_DELETE(pipes); - } - } - return !pipes; - } - - unsigned char c = *prefix_; - if (!count || c < min || c >= min + count) - return false; - - mtrie_t *next_node = - count == 1 ? next.node : next.table [c - min]; - - if (!next_node) - return false; - - bool ret = next_node->rm_helper (prefix_ + 1, size_ - 1, pipe_); - - if (next_node->is_redundant ()) { - LIBZMQ_DELETE(next_node); - zmq_assert (count > 0); - - if (count == 1) { - next.node = 0; - count = 0; - --live_nodes; - zmq_assert (live_nodes == 0); - } - else { - next.table [c - min] = 0; - zmq_assert (live_nodes > 1); - --live_nodes; - - // Compact the table if possible - if (live_nodes == 1) { - // If there's only one live node in the table we can - // switch to using the more compact single-node - // representation - unsigned short i; - for (i = 0; i < count; ++i) - if (next.table [i]) - break; - - zmq_assert (i < count); - min += i; - count = 1; - mtrie_t *oldp = next.table [i]; - free (next.table); - next.node = oldp; - } - else - if (c == min) { - // We can compact the table "from the left" - unsigned short i; - for (i = 1; i < count; ++i) - if (next.table [i]) - break; - - zmq_assert (i < count); - min += i; - count -= i; - mtrie_t **old_table = next.table; - next.table = (mtrie_t**) malloc (sizeof (mtrie_t*) * count); - alloc_assert (next.table); - memmove (next.table, old_table + i, sizeof (mtrie_t*) * count); - free (old_table); - } - else - if (c == min + count - 1) { - // We can compact the table "from the right" - unsigned short i; - for (i = 1; i < count; ++i) - if (next.table [count - 1 - i]) - break; - - zmq_assert (i < count); - count -= i; - mtrie_t **old_table = next.table; - next.table = (mtrie_t**) malloc (sizeof (mtrie_t*) * count); - alloc_assert (next.table); - memmove (next.table, old_table, sizeof (mtrie_t*) * count); - free (old_table); - } - } - } - - return ret; -} - -void zmq::mtrie_t::match (unsigned char *data_, size_t size_, - void (*func_) (pipe_t *pipe_, void *arg_), void *arg_) -{ - mtrie_t *current = this; - while (true) { - - // Signal the pipes attached to this node. - if (current->pipes) { - for (pipes_t::iterator it = current->pipes->begin (); - it != current->pipes->end (); ++it) - func_ (*it, arg_); - } - - // If we are at the end of the message, there's nothing more to match. - if (!size_) - break; - - // If there are no subnodes in the trie, return. - if (current->count == 0) - break; - - // If there's one subnode (optimisation). - if (current->count == 1) { - if (data_ [0] != current->min) - break; - current = current->next.node; - data_++; - size_--; - continue; - } - - // If there are multiple subnodes. - if (data_ [0] < current->min || data_ [0] >= - current->min + current->count) - break; - if (!current->next.table [data_ [0] - current->min]) - break; - current = current->next.table [data_ [0] - current->min]; - data_++; - size_--; - } -} - -bool zmq::mtrie_t::is_redundant () const -{ - return !pipes && live_nodes == 0; -} diff --git a/dep/libzmq/src/mtrie.hpp b/dep/libzmq/src/mtrie.hpp deleted file mode 100644 index 632e0d7e5c..0000000000 --- a/dep/libzmq/src/mtrie.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MTRIE_HPP_INCLUDED__ -#define __ZMQ_MTRIE_HPP_INCLUDED__ - -#include -#include - -#include "stdint.hpp" - -namespace zmq -{ - - class pipe_t; - - // Multi-trie. Each node in the trie is a set of pointers to pipes. - - class mtrie_t - { - public: - - mtrie_t (); - ~mtrie_t (); - - // Add key to the trie. Returns true if it's a new subscription - // rather than a duplicate. - bool add (unsigned char *prefix_, size_t size_, zmq::pipe_t *pipe_); - - // Remove all subscriptions for a specific peer from the trie. - // The call_on_uniq_ flag controls if the callback is invoked - // when there are no subscriptions left on some topics or on - // every removal. - void rm (zmq::pipe_t *pipe_, - void (*func_) (unsigned char *data_, size_t size_, void *arg_), - void *arg_, bool call_on_uniq_); - - // Remove specific subscription from the trie. Return true is it was - // actually removed rather than de-duplicated. - bool rm (unsigned char *prefix_, size_t size_, zmq::pipe_t *pipe_); - - // Signal all the matching pipes. - void match (unsigned char *data_, size_t size_, - void (*func_) (zmq::pipe_t *pipe_, void *arg_), void *arg_); - - private: - - bool add_helper (unsigned char *prefix_, size_t size_, - zmq::pipe_t *pipe_); - void rm_helper (zmq::pipe_t *pipe_, unsigned char **buff_, - size_t buffsize_, size_t maxbuffsize_, - void (*func_) (unsigned char *data_, size_t size_, void *arg_), - void *arg_, bool call_on_uniq_); - bool rm_helper (unsigned char *prefix_, size_t size_, - zmq::pipe_t *pipe_); - bool is_redundant () const; - - typedef std::set pipes_t; - pipes_t *pipes; - - unsigned char min; - unsigned short count; - unsigned short live_nodes; - union { - class mtrie_t *node; - class mtrie_t **table; - } next; - - mtrie_t (const mtrie_t&); - const mtrie_t &operator = (const mtrie_t&); - }; - -} - -#endif - diff --git a/dep/libzmq/src/mutex.hpp b/dep/libzmq/src/mutex.hpp deleted file mode 100644 index 5391a489ce..0000000000 --- a/dep/libzmq/src/mutex.hpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_MUTEX_HPP_INCLUDED__ -#define __ZMQ_MUTEX_HPP_INCLUDED__ - -#include "err.hpp" - -// Mutex class encapsulates OS mutex in a platform-independent way. - -#ifdef ZMQ_HAVE_WINDOWS - -#include "windows.hpp" - -namespace zmq -{ - - class mutex_t - { - public: - inline mutex_t () - { - InitializeCriticalSection (&cs); - } - - inline ~mutex_t () - { - DeleteCriticalSection (&cs); - } - - inline void lock () - { - EnterCriticalSection (&cs); - } - - inline bool try_lock () - { - return (TryEnterCriticalSection (&cs)) ? true : false; - } - - inline void unlock () - { - LeaveCriticalSection (&cs); - } - - inline CRITICAL_SECTION* get_cs() - { - return &cs; - } - - private: - - CRITICAL_SECTION cs; - - // Disable copy construction and assignment. - mutex_t (const mutex_t&); - void operator = (const mutex_t&); - }; - -} - -#else - -#include - -namespace zmq -{ - - class mutex_t - { - public: - inline mutex_t () - { - int rc = pthread_mutexattr_init(&attr); - posix_assert (rc); - - rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - posix_assert (rc); - - rc = pthread_mutex_init (&mutex, &attr); - posix_assert (rc); - } - - inline ~mutex_t () - { - int rc = pthread_mutex_destroy (&mutex); - posix_assert (rc); - - rc = pthread_mutexattr_destroy (&attr); - posix_assert (rc); - } - - inline void lock () - { - int rc = pthread_mutex_lock (&mutex); - posix_assert (rc); - } - - inline bool try_lock () - { - int rc = pthread_mutex_trylock (&mutex); - if (rc == EBUSY) - return false; - - posix_assert (rc); - return true; - } - - inline void unlock () - { - int rc = pthread_mutex_unlock (&mutex); - posix_assert (rc); - } - - inline pthread_mutex_t* get_mutex() - { - return &mutex; - } - - private: - - pthread_mutex_t mutex; - pthread_mutexattr_t attr; - - // Disable copy construction and assignment. - mutex_t (const mutex_t&); - const mutex_t &operator = (const mutex_t&); - }; - -} - -#endif - - -namespace zmq -{ - struct scoped_lock_t - { - scoped_lock_t (mutex_t& mutex_) - : mutex (mutex_) - { - mutex.lock (); - } - - ~scoped_lock_t () - { - mutex.unlock (); - } - - private: - - mutex_t& mutex; - - // Disable copy construction and assignment. - scoped_lock_t (const scoped_lock_t&); - const scoped_lock_t &operator = (const scoped_lock_t&); - }; - - - struct scoped_optional_lock_t - { - scoped_optional_lock_t (mutex_t* mutex_) - : mutex (mutex_) - { - if(mutex != NULL) - mutex->lock (); - } - - ~scoped_optional_lock_t () - { - if(mutex != NULL) - mutex->unlock (); - } - - private: - - mutex_t* mutex; - - // Disable copy construction and assignment. - scoped_optional_lock_t (const scoped_lock_t&); - const scoped_optional_lock_t &operator = (const scoped_lock_t&); - }; - - -} - -#endif diff --git a/dep/libzmq/src/norm_engine.hpp b/dep/libzmq/src/norm_engine.hpp deleted file mode 100644 index d45e194667..0000000000 --- a/dep/libzmq/src/norm_engine.hpp +++ /dev/null @@ -1,190 +0,0 @@ - -#ifndef __ZMQ_NORM_ENGINE_HPP_INCLUDED__ -#define __ZMQ_NORM_ENGINE_HPP_INCLUDED__ - -#if defined ZMQ_HAVE_NORM - -#include "io_object.hpp" -#include "i_engine.hpp" -#include "options.hpp" -#include "v2_decoder.hpp" -#include "v2_encoder.hpp" - -#include - -namespace zmq -{ - class io_thread_t; - class session_base_t; - - class norm_engine_t : public io_object_t, public i_engine - { - public: - norm_engine_t (zmq::io_thread_t *parent_, const options_t &options_); - ~norm_engine_t (); - - // create NORM instance, session, etc - int init(const char* network_, bool send, bool recv); - void shutdown(); - - // i_engine interface implementation. - // Plug the engine to the session. - virtual void plug (zmq::io_thread_t *io_thread_, - class session_base_t *session_); - - // Terminate and deallocate the engine. Note that 'detached' - // events are not fired on termination. - virtual void terminate (); - - // This method is called by the session to signalise that more - // messages can be written to the pipe. - virtual void restart_input (); - - // This method is called by the session to signalise that there - // are messages to send available. - virtual void restart_output (); - - virtual void zap_msg_available () {}; - - virtual const char *get_endpoint () const; - - // i_poll_events interface implementation. - // (we only need in_event() for NormEvent notification) - // (i.e., don't have any output events or timers (yet)) - void in_event (); - - private: - void unplug(); - void send_data(); - void recv_data(NormObjectHandle stream); - - - enum {BUFFER_SIZE = 2048}; - - // Used to keep track of streams from multiple senders - class NormRxStreamState - { - public: - NormRxStreamState(NormObjectHandle normStream, - int64_t maxMsgSize); - ~NormRxStreamState(); - - NormObjectHandle GetStreamHandle() const - {return norm_stream;} - - bool Init(); - - void SetRxReady(bool state) - {rx_ready = state;} - bool IsRxReady() const - {return rx_ready;} - - void SetSync(bool state) - {in_sync = state;} - bool InSync() const - {return in_sync;} - - // These are used to feed data to decoder - // and its underlying "msg" buffer - char* AccessBuffer() - {return (char*)(buffer_ptr + buffer_count);} - size_t GetBytesNeeded() const - {return (buffer_size - buffer_count);} - void IncrementBufferCount(size_t count) - {buffer_count += count;} - msg_t* AccessMsg() - {return zmq_decoder->msg();} - // This invokes the decoder "decode" method - // returning 0 if more data is needed, - // 1 if the message is complete, If an error - // occurs the 'sync' is dropped and the - // decoder re-initialized - int Decode(); - - class List - { - public: - List(); - ~List(); - - void Append(NormRxStreamState& item); - void Remove(NormRxStreamState& item); - - bool IsEmpty() const - {return (NULL == head);} - - void Destroy(); - - class Iterator - { - public: - Iterator(const List& list); - NormRxStreamState* GetNextItem(); - private: - NormRxStreamState* next_item; - }; - friend class Iterator; - - private: - NormRxStreamState* head; - NormRxStreamState* tail; - - }; // end class zmq::norm_engine_t::NormRxStreamState::List - - friend class List; - - List* AccessList() - {return list;} - - - private: - NormObjectHandle norm_stream; - int64_t max_msg_size; - bool in_sync; - bool rx_ready; - v2_decoder_t* zmq_decoder; - bool skip_norm_sync; - unsigned char* buffer_ptr; - size_t buffer_size; - size_t buffer_count; - - NormRxStreamState* prev; - NormRxStreamState* next; - NormRxStreamState::List* list; - - }; // end class zmq::norm_engine_t::NormRxStreamState - - session_base_t* zmq_session; - options_t options; - NormInstanceHandle norm_instance; - handle_t norm_descriptor_handle; - NormSessionHandle norm_session; - bool is_sender; - bool is_receiver; - // Sender state - msg_t tx_msg; - v2_encoder_t zmq_encoder; // for tx messages (we use v2 for now) - NormObjectHandle norm_tx_stream; - bool tx_first_msg; - bool tx_more_bit; - bool zmq_output_ready; // zmq has msg(s) to send - bool norm_tx_ready; // norm has tx queue vacancy - // TBD - maybe don't need buffer if can access zmq message buffer directly? - char tx_buffer[BUFFER_SIZE]; - unsigned int tx_index; - unsigned int tx_len; - - // Receiver state - // Lists of norm rx streams from remote senders - bool zmq_input_ready; // zmq ready to receive msg(s) - NormRxStreamState::List rx_pending_list; // rx streams waiting for data reception - NormRxStreamState::List rx_ready_list; // rx streams ready for NormStreamRead() - NormRxStreamState::List msg_ready_list; // rx streams w/ msg ready for push to zmq - - - }; // end class norm_engine_t -} - -#endif // ZMQ_HAVE_NORM - -#endif // !__ZMQ_NORM_ENGINE_HPP_INCLUDED__ diff --git a/dep/libzmq/src/null_mechanism.cpp b/dep/libzmq/src/null_mechanism.cpp deleted file mode 100644 index 560aec3c81..0000000000 --- a/dep/libzmq/src/null_mechanism.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include -#include -#include - -#include "err.hpp" -#include "msg.hpp" -#include "session_base.hpp" -#include "wire.hpp" -#include "null_mechanism.hpp" - -zmq::null_mechanism_t::null_mechanism_t (session_base_t *session_, - const std::string &peer_address_, - const options_t &options_) : - mechanism_base_t (session_, options_), - zap_client_t (session_, peer_address_, options_), - ready_command_sent (false), - error_command_sent (false), - ready_command_received (false), - error_command_received (false), - zap_request_sent (false), - zap_reply_received (false) -{ -} - -zmq::null_mechanism_t::~null_mechanism_t () -{ -} - -int zmq::null_mechanism_t::next_handshake_command (msg_t *msg_) -{ - if (ready_command_sent || error_command_sent) { - errno = EAGAIN; - return -1; - } - - if (zap_required() && !zap_reply_received) { - if (zap_request_sent) { - errno = EAGAIN; - return -1; - } - int rc = session->zap_connect(); - if (rc == -1) - { - session->get_socket()->event_handshake_failed_no_detail ( - session->get_endpoint(), - EFAULT); - return -1; - } - send_zap_request (); - zap_request_sent = true; - - // TODO actually, it is quite unlikely that we can read the ZAP - // reply already, but removing this has some strange side-effect - // (probably because the pipe's in_active flag is true until a read - // is attempted) - rc = receive_and_process_zap_reply (); - if (rc != 0) - return -1; - - zap_reply_received = true; - } - - if (zap_reply_received && status_code != "200") { - error_command_sent = true; - if (status_code != "300") { - const size_t status_code_len = 3; - const int rc = msg_->init_size (6 + 1 + status_code_len); - zmq_assert (rc == 0); - unsigned char *msg_data = - static_cast (msg_->data ()); - memcpy (msg_data, "\5ERROR", 6); - msg_data[6] = status_code_len; - memcpy (msg_data + 7, status_code.c_str (), status_code_len); - return 0; - } else { - errno = EAGAIN; - return -1; - } - } - - make_command_with_basic_properties (msg_, "\5READY", 6); - - ready_command_sent = true; - - return 0; -} - -int zmq::null_mechanism_t::process_handshake_command (msg_t *msg_) -{ - if (ready_command_received || error_command_received) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - return -1; - } - - const unsigned char *cmd_data = - static_cast (msg_->data ()); - const size_t data_size = msg_->size (); - - int rc = 0; - if (data_size >= 6 && !memcmp (cmd_data, "\5READY", 6)) - rc = process_ready_command (cmd_data, data_size); - else - if (data_size >= 6 && !memcmp (cmd_data, "\5ERROR", 6)) - rc = process_error_command (cmd_data, data_size); - else { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - rc = -1; - } - - if (rc == 0) { - rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - } - return rc; -} - -int zmq::null_mechanism_t::process_ready_command ( - const unsigned char *cmd_data, size_t data_size) -{ - ready_command_received = true; - return parse_metadata (cmd_data + 6, data_size - 6); -} - -int zmq::null_mechanism_t::process_error_command ( - const unsigned char *cmd_data, size_t data_size) -{ - if (data_size < 7) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR); - - errno = EPROTO; - return -1; - } - const size_t error_reason_len = static_cast (cmd_data [6]); - if (error_reason_len > data_size - 7) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR); - - errno = EPROTO; - return -1; - } - const char *error_reason = reinterpret_cast (cmd_data) + 7; - handle_error_reason (error_reason, error_reason_len); - error_command_received = true; - return 0; -} - -int zmq::null_mechanism_t::zap_msg_available () -{ - if (zap_reply_received) { - errno = EFSM; - return -1; - } - const int rc = receive_and_process_zap_reply (); - if (rc == 0) - zap_reply_received = true; - return rc == -1 ? -1 : 0; -} - -zmq::mechanism_t::status_t zmq::null_mechanism_t::status () const -{ - const bool command_sent = - ready_command_sent || error_command_sent; - const bool command_received = - ready_command_received || error_command_received; - - if (ready_command_sent && ready_command_received) - return mechanism_t::ready; - else - if (command_sent && command_received) - return error; - else - return handshaking; -} - -void zmq::null_mechanism_t::send_zap_request () -{ - zap_client_t::send_zap_request ("NULL", 4, NULL, NULL, 0); -} diff --git a/dep/libzmq/src/null_mechanism.hpp b/dep/libzmq/src/null_mechanism.hpp deleted file mode 100644 index 4fca49df4f..0000000000 --- a/dep/libzmq/src/null_mechanism.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_NULL_MECHANISM_HPP_INCLUDED__ -#define __ZMQ_NULL_MECHANISM_HPP_INCLUDED__ - -#include "mechanism.hpp" -#include "options.hpp" -#include "zap_client.hpp" - -namespace zmq -{ - - class msg_t; - class session_base_t; - - class null_mechanism_t : public zap_client_t - { - public: - - null_mechanism_t (session_base_t *session_, - const std::string &peer_address, - const options_t &options_); - virtual ~null_mechanism_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - virtual int zap_msg_available (); - virtual status_t status () const; - - private: - - bool ready_command_sent; - bool error_command_sent; - bool ready_command_received; - bool error_command_received; - bool zap_request_sent; - bool zap_reply_received; - - int process_ready_command ( - const unsigned char *cmd_data, size_t data_size); - int process_error_command ( - const unsigned char *cmd_data, size_t data_size); - - void send_zap_request (); - }; - -} - -#endif diff --git a/dep/libzmq/src/object.cpp b/dep/libzmq/src/object.cpp deleted file mode 100644 index 1e07226fcd..0000000000 --- a/dep/libzmq/src/object.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "object.hpp" -#include "ctx.hpp" -#include "err.hpp" -#include "pipe.hpp" -#include "io_thread.hpp" -#include "session_base.hpp" -#include "socket_base.hpp" - -zmq::object_t::object_t (ctx_t *ctx_, uint32_t tid_) : - ctx (ctx_), - tid (tid_) -{ -} - -zmq::object_t::object_t (object_t *parent_) : - ctx (parent_->ctx), - tid (parent_->tid) -{ -} - -zmq::object_t::~object_t () -{ -} - -uint32_t zmq::object_t::get_tid () -{ - return tid; -} - -void zmq::object_t::set_tid(uint32_t id) -{ - tid = id; -} - -zmq::ctx_t *zmq::object_t::get_ctx () -{ - return ctx; -} - -void zmq::object_t::process_command (command_t &cmd_) -{ - switch (cmd_.type) { - - case command_t::activate_read: - process_activate_read (); - break; - - case command_t::activate_write: - process_activate_write (cmd_.args.activate_write.msgs_read); - break; - - case command_t::stop: - process_stop (); - break; - - case command_t::plug: - process_plug (); - process_seqnum (); - break; - - case command_t::own: - process_own (cmd_.args.own.object); - process_seqnum (); - break; - - case command_t::attach: - process_attach (cmd_.args.attach.engine); - process_seqnum (); - break; - - case command_t::bind: - process_bind (cmd_.args.bind.pipe); - process_seqnum (); - break; - - case command_t::hiccup: - process_hiccup (cmd_.args.hiccup.pipe); - break; - - case command_t::pipe_term: - process_pipe_term (); - break; - - case command_t::pipe_term_ack: - process_pipe_term_ack (); - break; - - case command_t::pipe_hwm: - process_pipe_hwm (cmd_.args.pipe_hwm.inhwm, cmd_.args.pipe_hwm.outhwm); - break; - - case command_t::term_req: - process_term_req (cmd_.args.term_req.object); - break; - - case command_t::term: - process_term (cmd_.args.term.linger); - break; - - case command_t::term_ack: - process_term_ack (); - break; - - case command_t::term_endpoint: - process_term_endpoint (cmd_.args.term_endpoint.endpoint); - break; - - case command_t::reap: - process_reap (cmd_.args.reap.socket); - break; - - case command_t::reaped: - process_reaped (); - break; - - case command_t::inproc_connected: - process_seqnum (); - break; - - case command_t::done: - default: - zmq_assert (false); - } -} - -int zmq::object_t::register_endpoint (const char *addr_, - const endpoint_t &endpoint_) -{ - return ctx->register_endpoint (addr_, endpoint_); -} - -int zmq::object_t::unregister_endpoint ( - const std::string &addr_, socket_base_t *socket_) -{ - return ctx->unregister_endpoint (addr_, socket_); -} - -void zmq::object_t::unregister_endpoints (socket_base_t *socket_) -{ - return ctx->unregister_endpoints (socket_); -} - -zmq::endpoint_t zmq::object_t::find_endpoint (const char *addr_) -{ - return ctx->find_endpoint (addr_); -} - -void zmq::object_t::pend_connection (const std::string &addr_, - const endpoint_t &endpoint_, pipe_t **pipes_) -{ - ctx->pend_connection (addr_, endpoint_, pipes_); -} - -void zmq::object_t::connect_pending (const char *addr_, zmq::socket_base_t *bind_socket_) -{ - return ctx->connect_pending(addr_, bind_socket_); -} - -void zmq::object_t::destroy_socket (socket_base_t *socket_) -{ - ctx->destroy_socket (socket_); -} - -zmq::io_thread_t *zmq::object_t::choose_io_thread (uint64_t affinity_) -{ - return ctx->choose_io_thread (affinity_); -} - -void zmq::object_t::send_stop () -{ - // 'stop' command goes always from administrative thread to - // the current object. - command_t cmd; - cmd.destination = this; - cmd.type = command_t::stop; - ctx->send_command (tid, cmd); -} - -void zmq::object_t::send_plug (own_t *destination_, bool inc_seqnum_) -{ - if (inc_seqnum_) - destination_->inc_seqnum (); - - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::plug; - send_command (cmd); -} - -void zmq::object_t::send_own (own_t *destination_, own_t *object_) -{ - destination_->inc_seqnum (); - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::own; - cmd.args.own.object = object_; - send_command (cmd); -} - -void zmq::object_t::send_attach (session_base_t *destination_, - i_engine *engine_, bool inc_seqnum_) -{ - if (inc_seqnum_) - destination_->inc_seqnum (); - - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::attach; - cmd.args.attach.engine = engine_; - send_command (cmd); -} - -void zmq::object_t::send_bind (own_t *destination_, pipe_t *pipe_, - bool inc_seqnum_) -{ - if (inc_seqnum_) - destination_->inc_seqnum (); - - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::bind; - cmd.args.bind.pipe = pipe_; - send_command (cmd); -} - -void zmq::object_t::send_activate_read (pipe_t *destination_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::activate_read; - send_command (cmd); -} - -void zmq::object_t::send_activate_write (pipe_t *destination_, - uint64_t msgs_read_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::activate_write; - cmd.args.activate_write.msgs_read = msgs_read_; - send_command (cmd); -} - -void zmq::object_t::send_hiccup (pipe_t *destination_, void *pipe_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::hiccup; - cmd.args.hiccup.pipe = pipe_; - send_command (cmd); -} - -void zmq::object_t::send_pipe_term (pipe_t *destination_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::pipe_term; - send_command (cmd); -} - -void zmq::object_t::send_pipe_term_ack (pipe_t *destination_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::pipe_term_ack; - send_command (cmd); -} - -void zmq::object_t::send_pipe_hwm (pipe_t *destination_, int inhwm_, int outhwm_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::pipe_hwm; - cmd.args.pipe_hwm.inhwm = inhwm_; - cmd.args.pipe_hwm.outhwm = outhwm_; - send_command (cmd); -} - -void zmq::object_t::send_term_req (own_t *destination_, - own_t *object_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::term_req; - cmd.args.term_req.object = object_; - send_command (cmd); -} - -void zmq::object_t::send_term (own_t *destination_, int linger_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::term; - cmd.args.term.linger = linger_; - send_command (cmd); -} - -void zmq::object_t::send_term_ack (own_t *destination_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::term_ack; - send_command (cmd); -} - -void zmq::object_t::send_term_endpoint (own_t *destination_, - std::string *endpoint_) -{ - command_t cmd; - cmd.destination = destination_; - cmd.type = command_t::term_endpoint; - cmd.args.term_endpoint.endpoint = endpoint_; - send_command (cmd); -} - -void zmq::object_t::send_reap (class socket_base_t *socket_) -{ - command_t cmd; - cmd.destination = ctx->get_reaper (); - cmd.type = command_t::reap; - cmd.args.reap.socket = socket_; - send_command (cmd); -} - -void zmq::object_t::send_reaped () -{ - command_t cmd; - cmd.destination = ctx->get_reaper (); - cmd.type = command_t::reaped; - send_command (cmd); -} - -void zmq::object_t::send_inproc_connected (zmq::socket_base_t *socket_) -{ - command_t cmd; - cmd.destination = socket_; - cmd.type = command_t::inproc_connected; - send_command (cmd); -} - -void zmq::object_t::send_done () -{ - command_t cmd; - cmd.destination = NULL; - cmd.type = command_t::done; - ctx->send_command (ctx_t::term_tid, cmd); -} - -void zmq::object_t::process_stop () -{ - zmq_assert (false); -} - -void zmq::object_t::process_plug () -{ - zmq_assert (false); -} - -void zmq::object_t::process_own (own_t *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_attach (i_engine *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_bind (pipe_t *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_activate_read () -{ - zmq_assert (false); -} - -void zmq::object_t::process_activate_write (uint64_t) -{ - zmq_assert (false); -} - -void zmq::object_t::process_hiccup (void *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_pipe_term () -{ - zmq_assert (false); -} - -void zmq::object_t::process_pipe_term_ack () -{ - zmq_assert (false); -} - -void zmq::object_t::process_pipe_hwm (int, int) -{ - zmq_assert (false); -} - -void zmq::object_t::process_term_req (own_t *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_term (int) -{ - zmq_assert (false); -} - -void zmq::object_t::process_term_ack () -{ - zmq_assert (false); -} - -void zmq::object_t::process_term_endpoint (std::string *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_reap (class socket_base_t *) -{ - zmq_assert (false); -} - -void zmq::object_t::process_reaped () -{ - zmq_assert (false); -} - -void zmq::object_t::process_seqnum () -{ - zmq_assert (false); -} - -void zmq::object_t::send_command (command_t &cmd_) -{ - ctx->send_command (cmd_.destination->get_tid (), cmd_); -} - diff --git a/dep/libzmq/src/object.hpp b/dep/libzmq/src/object.hpp deleted file mode 100644 index 90e12dd6a4..0000000000 --- a/dep/libzmq/src/object.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_OBJECT_HPP_INCLUDED__ -#define __ZMQ_OBJECT_HPP_INCLUDED__ - -#include -#include "stdint.hpp" - -namespace zmq -{ - - struct i_engine; - struct endpoint_t; - struct pending_connection_t; - struct command_t; - class ctx_t; - class pipe_t; - class socket_base_t; - class session_base_t; - class io_thread_t; - class own_t; - - // Base class for all objects that participate in inter-thread - // communication. - - class object_t - { - public: - - object_t (zmq::ctx_t *ctx_, uint32_t tid_); - object_t (object_t *parent_); - virtual ~object_t (); - - uint32_t get_tid (); - void set_tid(uint32_t id); - ctx_t *get_ctx (); - void process_command (zmq::command_t &cmd_); - void send_inproc_connected (zmq::socket_base_t *socket_); - void send_bind (zmq::own_t *destination_, zmq::pipe_t *pipe_, bool inc_seqnum_ = true); - - protected: - - // Using following function, socket is able to access global - // repository of inproc endpoints. - int register_endpoint (const char *addr_, - const zmq::endpoint_t &endpoint_); - int unregister_endpoint ( - const std::string &addr_, socket_base_t *socket_); - void unregister_endpoints (zmq::socket_base_t *socket_); - zmq::endpoint_t find_endpoint (const char *addr_); - void pend_connection (const std::string &addr_, - const endpoint_t &endpoint, pipe_t **pipes_); - void connect_pending (const char *addr_, zmq::socket_base_t *bind_socket_); - - void destroy_socket (zmq::socket_base_t *socket_); - - // Logs an message. - void log (const char *format_, ...); - - // Chooses least loaded I/O thread. - zmq::io_thread_t *choose_io_thread (uint64_t affinity_); - - // Derived object can use these functions to send commands - // to other objects. - void send_stop (); - void send_plug (zmq::own_t *destination_, - bool inc_seqnum_ = true); - void send_own (zmq::own_t *destination_, - zmq::own_t *object_); - void send_attach (zmq::session_base_t *destination_, - zmq::i_engine *engine_, bool inc_seqnum_ = true); - void send_activate_read (zmq::pipe_t *destination_); - void send_activate_write (zmq::pipe_t *destination_, - uint64_t msgs_read_); - void send_hiccup (zmq::pipe_t *destination_, void *pipe_); - void send_pipe_term (zmq::pipe_t *destination_); - void send_pipe_term_ack (zmq::pipe_t *destination_); - void send_pipe_hwm (zmq::pipe_t *destination_, int inhwm_, int outhwm_); - void send_term_req (zmq::own_t *destination_, - zmq::own_t *object_); - void send_term (zmq::own_t *destination_, int linger_); - void send_term_ack (zmq::own_t *destination_); - void send_term_endpoint (own_t *destination_, std::string *endpoint_); - void send_reap (zmq::socket_base_t *socket_); - void send_reaped (); - void send_done (); - - // These handlers can be overridden by the derived objects. They are - // called when command arrives from another thread. - virtual void process_stop (); - virtual void process_plug (); - virtual void process_own (zmq::own_t *object_); - virtual void process_attach (zmq::i_engine *engine_); - virtual void process_bind (zmq::pipe_t *pipe_); - virtual void process_activate_read (); - virtual void process_activate_write (uint64_t msgs_read_); - virtual void process_hiccup (void *pipe_); - virtual void process_pipe_term (); - virtual void process_pipe_term_ack (); - virtual void process_pipe_hwm (int inhwm_, int outhwm_); - virtual void process_term_req (zmq::own_t *object_); - virtual void process_term (int linger_); - virtual void process_term_ack (); - virtual void process_term_endpoint (std::string *endpoint_); - virtual void process_reap (zmq::socket_base_t *socket_); - virtual void process_reaped (); - - // Special handler called after a command that requires a seqnum - // was processed. The implementation should catch up with its counter - // of processed commands here. - virtual void process_seqnum (); - - private: - - // Context provides access to the global state. - zmq::ctx_t *ctx; - - // Thread ID of the thread the object belongs to. - uint32_t tid; - - void send_command (command_t &cmd_); - - object_t (const object_t&); - const object_t &operator = (const object_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/options.cpp b/dep/libzmq/src/options.cpp deleted file mode 100644 index 6aeb14a7aa..0000000000 --- a/dep/libzmq/src/options.cpp +++ /dev/null @@ -1,1089 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "options.hpp" -#include "err.hpp" -#include "macros.hpp" - -#ifndef ZMQ_HAVE_WINDOWS -#include -#endif - -#if defined IFNAMSIZ -#define BINDDEVSIZ IFNAMSIZ -#else -#define BINDDEVSIZ 16 -#endif - -zmq::options_t::options_t () : - sndhwm (1000), - rcvhwm (1000), - affinity (0), - routing_id_size (0), - rate (100), - recovery_ivl (10000), - multicast_hops (1), - multicast_maxtpdu (1500), - sndbuf (-1), - rcvbuf (-1), - tos (0), - type (-1), - linger (-1), - connect_timeout (0), - tcp_maxrt (0), - reconnect_ivl (100), - reconnect_ivl_max (0), - backlog (100), - maxmsgsize (-1), - rcvtimeo (-1), - sndtimeo (-1), - ipv6 (0), - immediate (0), - filter (false), - invert_matching(false), - recv_routing_id (false), - raw_socket (false), - raw_notify (true), - tcp_keepalive (-1), - tcp_keepalive_cnt (-1), - tcp_keepalive_idle (-1), - tcp_keepalive_intvl (-1), - mechanism (ZMQ_NULL), - as_server (0), - gss_principal_nt (ZMQ_GSSAPI_NT_HOSTBASED), - gss_service_principal_nt (ZMQ_GSSAPI_NT_HOSTBASED), - gss_plaintext (false), - socket_id (0), - conflate (false), - handshake_ivl (30000), - connected (false), - heartbeat_ttl (0), - heartbeat_interval (0), - heartbeat_timeout (-1), - use_fd (-1), - zap_enforce_domain (false) -{ - memset (curve_public_key, 0, CURVE_KEYSIZE); - memset (curve_secret_key, 0, CURVE_KEYSIZE); - memset (curve_server_key, 0, CURVE_KEYSIZE); -#if defined ZMQ_HAVE_VMCI - vmci_buffer_size = 0; - vmci_buffer_min_size = 0; - vmci_buffer_max_size = 0; - vmci_connect_timeout = -1; -#endif -} - -int zmq::options_t::set_curve_key(uint8_t * destination, const void * optval_, size_t optvallen_) -{ - switch (optvallen_) { - - case CURVE_KEYSIZE: - memcpy (destination, optval_, optvallen_); - mechanism = ZMQ_CURVE; - return 0; - - case CURVE_KEYSIZE_Z85 + 1: - if (zmq_z85_decode (destination, (char *) optval_)) { - mechanism = ZMQ_CURVE; - return 0; - } - break; - - case CURVE_KEYSIZE_Z85: - char z85_key [CURVE_KEYSIZE_Z85 + 1]; - memcpy (z85_key, (char *) optval_, optvallen_); - z85_key [CURVE_KEYSIZE_Z85] = 0; - if (zmq_z85_decode (destination, z85_key)) { - mechanism = ZMQ_CURVE; - return 0; - } - break; - - default: - break; - } - return -1; -} - -int zmq::options_t::setsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - bool is_int = (optvallen_ == sizeof (int)); - int value = 0; - if (is_int) memcpy(&value, optval_, sizeof (int)); -#if defined (ZMQ_ACT_MILITANT) - bool malformed = true; // Did caller pass a bad option value? -#endif - - switch (option_) { - case ZMQ_SNDHWM: - if (is_int && value >= 0) { - sndhwm = value; - return 0; - } - break; - - case ZMQ_RCVHWM: - if (is_int && value >= 0) { - rcvhwm = value; - return 0; - } - break; - - case ZMQ_AFFINITY: - if (optvallen_ == sizeof (uint64_t)) { - affinity = *((uint64_t*) optval_); - return 0; - } - break; - - case ZMQ_ROUTING_ID: - // Routing id is any binary string from 1 to 255 octets - if (optvallen_ > 0 && optvallen_ < 256) { - routing_id_size = (unsigned char) optvallen_; - memcpy (routing_id, optval_, routing_id_size); - return 0; - } - break; - - case ZMQ_RATE: - if (is_int && value > 0) { - rate = value; - return 0; - } - break; - - case ZMQ_RECOVERY_IVL: - if (is_int && value >= 0) { - recovery_ivl = value; - return 0; - } - break; - - case ZMQ_SNDBUF: - if (is_int && value >= -1) { - sndbuf = value; - return 0; - } - break; - - case ZMQ_RCVBUF: - if (is_int && value >= -1) { - rcvbuf = value; - return 0; - } - break; - - case ZMQ_TOS: - if (is_int && value >= 0) { - tos = value; - return 0; - } - break; - - case ZMQ_LINGER: - if (is_int && value >= -1) { - linger = value; - return 0; - } - break; - - case ZMQ_CONNECT_TIMEOUT: - if (is_int && value >= 0) { - connect_timeout = value; - return 0; - } - break; - - case ZMQ_TCP_MAXRT: - if (is_int && value >= 0) { - tcp_maxrt = value; - return 0; - } - break; - - case ZMQ_RECONNECT_IVL: - if (is_int && value >= -1) { - reconnect_ivl = value; - return 0; - } - break; - - case ZMQ_RECONNECT_IVL_MAX: - if (is_int && value >= 0) { - reconnect_ivl_max = value; - return 0; - } - break; - - case ZMQ_BACKLOG: - if (is_int && value >= 0) { - backlog = value; - return 0; - } - break; - - case ZMQ_MAXMSGSIZE: - if (optvallen_ == sizeof (int64_t)) { - maxmsgsize = *((int64_t *) optval_); - return 0; - } - break; - - case ZMQ_MULTICAST_HOPS: - if (is_int && value > 0) { - multicast_hops = value; - return 0; - } - break; - - case ZMQ_MULTICAST_MAXTPDU: - if (is_int && value > 0) { - multicast_maxtpdu = value; - return 0; - } - break; - - case ZMQ_RCVTIMEO: - if (is_int && value >= -1) { - rcvtimeo = value; - return 0; - } - break; - - case ZMQ_SNDTIMEO: - if (is_int && value >= -1) { - sndtimeo = value; - return 0; - } - break; - - /* Deprecated in favor of ZMQ_IPV6 */ - case ZMQ_IPV4ONLY: - if (is_int && (value == 0 || value == 1)) { - ipv6 = (value == 0); - return 0; - } - break; - - /* To replace the somewhat surprising IPV4ONLY */ - case ZMQ_IPV6: - if (is_int && (value == 0 || value == 1)) { - ipv6 = (value != 0); - return 0; - } - break; - - case ZMQ_SOCKS_PROXY: - if (optval_ == NULL && optvallen_ == 0) { - socks_proxy_address.clear (); - return 0; - } - else - if (optval_ != NULL && optvallen_ > 0 ) { - socks_proxy_address = - std::string ((const char *) optval_, optvallen_); - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE: - if (is_int && (value == -1 || value == 0 || value == 1)) { - tcp_keepalive = value; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE_CNT: - if (is_int && (value == -1 || value >= 0)) { - tcp_keepalive_cnt = value; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE_IDLE: - if (is_int && (value == -1 || value >= 0)) { - tcp_keepalive_idle = value; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE_INTVL: - if (is_int && (value == -1 || value >= 0)) { - tcp_keepalive_intvl = value; - return 0; - } - break; - - case ZMQ_IMMEDIATE: - if (is_int && (value == 0 || value == 1)) { - immediate = value; - return 0; - } - break; - - case ZMQ_TCP_ACCEPT_FILTER: - if (optvallen_ == 0 && optval_ == NULL) { - tcp_accept_filters.clear (); - return 0; - } - else - if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL && *((const char*) optval_) != 0) { - std::string filter_str ((const char *) optval_, optvallen_); - tcp_address_mask_t mask; - int rc = mask.resolve (filter_str.c_str (), ipv6); - if (rc == 0) { - tcp_accept_filters.push_back (mask); - return 0; - } - } - break; - -#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED - case ZMQ_IPC_FILTER_UID: - if (optvallen_ == 0 && optval_ == NULL) { - ipc_uid_accept_filters.clear (); - return 0; - } - else - if (optvallen_ == sizeof (uid_t) && optval_ != NULL) { - ipc_uid_accept_filters.insert (*((uid_t *) optval_)); - return 0; - } - break; - - case ZMQ_IPC_FILTER_GID: - if (optvallen_ == 0 && optval_ == NULL) { - ipc_gid_accept_filters.clear (); - return 0; - } - else - if (optvallen_ == sizeof (gid_t) && optval_ != NULL) { - ipc_gid_accept_filters.insert (*((gid_t *) optval_)); - return 0; - } - break; -#endif - -#if defined ZMQ_HAVE_SO_PEERCRED - case ZMQ_IPC_FILTER_PID: - if (optvallen_ == 0 && optval_ == NULL) { - ipc_pid_accept_filters.clear (); - return 0; - } - else - if (optvallen_ == sizeof (pid_t) && optval_ != NULL) { - ipc_pid_accept_filters.insert (*((pid_t *) optval_)); - return 0; - } - break; -#endif - - case ZMQ_PLAIN_SERVER: - if (is_int && (value == 0 || value == 1)) { - as_server = value; - mechanism = value? ZMQ_PLAIN: ZMQ_NULL; - return 0; - } - break; - - case ZMQ_PLAIN_USERNAME: - if (optvallen_ == 0 && optval_ == NULL) { - mechanism = ZMQ_NULL; - return 0; - } - else - if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) { - plain_username.assign ((const char *) optval_, optvallen_); - as_server = 0; - mechanism = ZMQ_PLAIN; - return 0; - } - break; - - case ZMQ_PLAIN_PASSWORD: - if (optvallen_ == 0 && optval_ == NULL) { - mechanism = ZMQ_NULL; - return 0; - } - else - if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) { - plain_password.assign ((const char *) optval_, optvallen_); - as_server = 0; - mechanism = ZMQ_PLAIN; - return 0; - } - break; - - case ZMQ_ZAP_DOMAIN: - if (optvallen_ < 256) { - zap_domain.assign ((const char *) optval_, optvallen_); - return 0; - } - break; - - // If curve encryption isn't built, these options provoke EINVAL -#ifdef ZMQ_HAVE_CURVE - case ZMQ_CURVE_SERVER: - if (is_int && (value == 0 || value == 1)) { - as_server = value; - mechanism = value? ZMQ_CURVE: ZMQ_NULL; - return 0; - } - break; - - case ZMQ_CURVE_PUBLICKEY: - if(0 == set_curve_key(curve_public_key, optval_, optvallen_)) { - return 0; - } - break; - - case ZMQ_CURVE_SECRETKEY: - if(0 == set_curve_key(curve_secret_key, optval_, optvallen_)) { - return 0; - } - break; - - case ZMQ_CURVE_SERVERKEY: - if(0 == set_curve_key(curve_server_key, optval_, optvallen_)) { - as_server = 0; - return 0; - } - break; -#endif - - case ZMQ_CONFLATE: - if (is_int && (value == 0 || value == 1)) { - conflate = (value != 0); - return 0; - } - break; - - // If libgssapi isn't installed, these options provoke EINVAL -#ifdef HAVE_LIBGSSAPI_KRB5 - case ZMQ_GSSAPI_SERVER: - if (is_int && (value == 0 || value == 1)) { - as_server = value; - mechanism = ZMQ_GSSAPI; - return 0; - } - break; - - case ZMQ_GSSAPI_PRINCIPAL: - if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) { - gss_principal.assign ((const char *) optval_, optvallen_); - mechanism = ZMQ_GSSAPI; - return 0; - } - break; - - case ZMQ_GSSAPI_SERVICE_PRINCIPAL: - if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) { - gss_service_principal.assign ((const char *) optval_, optvallen_); - mechanism = ZMQ_GSSAPI; - as_server = 0; - return 0; - } - break; - - case ZMQ_GSSAPI_PLAINTEXT: - if (is_int && (value == 0 || value == 1)) { - gss_plaintext = (value != 0); - return 0; - } - break; - - case ZMQ_GSSAPI_PRINCIPAL_NAMETYPE: - if (is_int && (value == ZMQ_GSSAPI_NT_HOSTBASED - || value == ZMQ_GSSAPI_NT_USER_NAME - || value == ZMQ_GSSAPI_NT_KRB5_PRINCIPAL)) { - gss_principal_nt = value; - return 0; - } - break; - - case ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE: - if (is_int && (value == ZMQ_GSSAPI_NT_HOSTBASED - || value == ZMQ_GSSAPI_NT_USER_NAME - || value == ZMQ_GSSAPI_NT_KRB5_PRINCIPAL)) { - gss_service_principal_nt = value; - return 0; - } - break; -#endif - - case ZMQ_HANDSHAKE_IVL: - if (is_int && value >= 0) { - handshake_ivl = value; - return 0; - } - break; - - case ZMQ_INVERT_MATCHING: - if (is_int) { - invert_matching = (value != 0); - return 0; - } - break; - - case ZMQ_HEARTBEAT_IVL: - if (is_int && value >= 0) { - heartbeat_interval = value; - return 0; - } - break; - - case ZMQ_HEARTBEAT_TTL: - // Convert this to deciseconds from milliseconds - value = value / 100; - if (is_int && value >= 0 && value <= 6553) { - heartbeat_ttl = (uint16_t)value; - return 0; - } - break; - - case ZMQ_HEARTBEAT_TIMEOUT: - if (is_int && value >= 0) { - heartbeat_timeout = value; - return 0; - } - break; - -#ifdef ZMQ_HAVE_VMCI - case ZMQ_VMCI_BUFFER_SIZE: - if (optvallen_ == sizeof (uint64_t)) { - vmci_buffer_size = *((uint64_t*) optval_); - return 0; - } - break; - - case ZMQ_VMCI_BUFFER_MIN_SIZE: - if (optvallen_ == sizeof (uint64_t)) { - vmci_buffer_min_size = *((uint64_t*) optval_); - return 0; - } - break; - - case ZMQ_VMCI_BUFFER_MAX_SIZE: - if (optvallen_ == sizeof (uint64_t)) { - vmci_buffer_max_size = *((uint64_t*) optval_); - return 0; - } - break; - - case ZMQ_VMCI_CONNECT_TIMEOUT: - if (optvallen_ == sizeof (int)) { - vmci_connect_timeout = *((int*) optval_); - return 0; - } - break; -#endif - - case ZMQ_USE_FD: - if (is_int && value >= -1) { - use_fd = value; - return 0; - } - break; - - case ZMQ_BINDTODEVICE: - if (optval_ == NULL && optvallen_ == 0) { - bound_device.clear (); - return 0; - } - else - if (optval_ != NULL && optvallen_ > 0 && optvallen_ <= BINDDEVSIZ) { - bound_device = - std::string ((const char *) optval_, optvallen_); - return 0; - } - break; - - case ZMQ_ZAP_ENFORCE_DOMAIN: - if (is_int) { - zap_enforce_domain = (value != 0); - return 0; - } - break; - - - default: -#if defined (ZMQ_ACT_MILITANT) - // There are valid scenarios for probing with unknown socket option - // values, e.g. to check if security is enabled or not. This will not - // provoke a militant assert. However, passing bad values to a valid - // socket option will, if ZMQ_ACT_MILITANT is defined. - malformed = false; -#endif - break; - } -#if defined (ZMQ_ACT_MILITANT) - // There is no valid use case for passing an error back to the application - // when it sent malformed arguments to a socket option. Use ./configure - // --with-militant to enable this checking. - if (malformed) - zmq_assert (false); -#endif - errno = EINVAL; - return -1; -} - -int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) const -{ - bool is_int = (*optvallen_ == sizeof (int)); - int *value = (int *) optval_; -#if defined (ZMQ_ACT_MILITANT) - bool malformed = true; // Did caller pass a bad option value? -#endif - - switch (option_) { - case ZMQ_SNDHWM: - if (is_int) { - *value = sndhwm; - return 0; - } - break; - - case ZMQ_RCVHWM: - if (is_int) { - *value = rcvhwm; - return 0; - } - break; - - case ZMQ_AFFINITY: - if (*optvallen_ == sizeof (uint64_t)) { - *((uint64_t *) optval_) = affinity; - return 0; - } - break; - - case ZMQ_ROUTING_ID: - if (*optvallen_ >= routing_id_size) { - memcpy (optval_, routing_id, routing_id_size); - *optvallen_ = routing_id_size; - return 0; - } - break; - - case ZMQ_RATE: - if (is_int) { - *value = rate; - return 0; - } - break; - - case ZMQ_RECOVERY_IVL: - if (is_int) { - *value = recovery_ivl; - return 0; - } - break; - - case ZMQ_SNDBUF: - if (is_int) { - *value = sndbuf; - return 0; - } - break; - - case ZMQ_RCVBUF: - if (is_int) { - *value = rcvbuf; - return 0; - } - break; - - case ZMQ_TOS: - if (is_int) { - *value = tos; - return 0; - } - break; - - case ZMQ_TYPE: - if (is_int) { - *value = type; - return 0; - } - break; - - case ZMQ_LINGER: - if (is_int) { - *value = linger; - return 0; - } - break; - - case ZMQ_CONNECT_TIMEOUT: - if (is_int) { - *value = connect_timeout; - return 0; - } - break; - - case ZMQ_TCP_MAXRT: - if (is_int) { - *value = tcp_maxrt; - return 0; - } - break; - - case ZMQ_RECONNECT_IVL: - if (is_int) { - *value = reconnect_ivl; - return 0; - } - break; - - case ZMQ_RECONNECT_IVL_MAX: - if (is_int) { - *value = reconnect_ivl_max; - return 0; - } - break; - - case ZMQ_BACKLOG: - if (is_int) { - *value = backlog; - return 0; - } - break; - - case ZMQ_MAXMSGSIZE: - if (*optvallen_ == sizeof (int64_t)) { - *((int64_t *) optval_) = maxmsgsize; - *optvallen_ = sizeof (int64_t); - return 0; - } - break; - - case ZMQ_MULTICAST_HOPS: - if (is_int) { - *value = multicast_hops; - return 0; - } - break; - - case ZMQ_MULTICAST_MAXTPDU: - if (is_int) { - *value = multicast_maxtpdu; - return 0; - } - break; - - case ZMQ_RCVTIMEO: - if (is_int) { - *value = rcvtimeo; - return 0; - } - break; - - case ZMQ_SNDTIMEO: - if (is_int) { - *value = sndtimeo; - return 0; - } - break; - - case ZMQ_IPV4ONLY: - if (is_int) { - *value = 1 - ipv6; - return 0; - } - break; - - case ZMQ_IPV6: - if (is_int) { - *value = ipv6; - return 0; - } - break; - - case ZMQ_IMMEDIATE: - if (is_int) { - *value = immediate; - return 0; - } - break; - - case ZMQ_SOCKS_PROXY: - if (*optvallen_ >= socks_proxy_address.size () + 1) { - memcpy (optval_, socks_proxy_address.c_str (), socks_proxy_address.size () + 1); - *optvallen_ = socks_proxy_address.size () + 1; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE: - if (is_int) { - *value = tcp_keepalive; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE_CNT: - if (is_int) { - *value = tcp_keepalive_cnt; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE_IDLE: - if (is_int) { - *value = tcp_keepalive_idle; - return 0; - } - break; - - case ZMQ_TCP_KEEPALIVE_INTVL: - if (is_int) { - *value = tcp_keepalive_intvl; - return 0; - } - break; - - case ZMQ_MECHANISM: - if (is_int) { - *value = mechanism; - return 0; - } - break; - - case ZMQ_PLAIN_SERVER: - if (is_int) { - *value = as_server && mechanism == ZMQ_PLAIN; - return 0; - } - break; - - case ZMQ_PLAIN_USERNAME: - if (*optvallen_ >= plain_username.size () + 1) { - memcpy (optval_, plain_username.c_str (), plain_username.size () + 1); - *optvallen_ = plain_username.size () + 1; - return 0; - } - break; - - case ZMQ_PLAIN_PASSWORD: - if (*optvallen_ >= plain_password.size () + 1) { - memcpy (optval_, plain_password.c_str (), plain_password.size () + 1); - *optvallen_ = plain_password.size () + 1; - return 0; - } - break; - - case ZMQ_ZAP_DOMAIN: - if (*optvallen_ >= zap_domain.size () + 1) { - memcpy (optval_, zap_domain.c_str (), zap_domain.size () + 1); - *optvallen_ = zap_domain.size () + 1; - return 0; - } - break; - - // If curve encryption isn't built, these options provoke EINVAL -#ifdef ZMQ_HAVE_CURVE - case ZMQ_CURVE_SERVER: - if (is_int) { - *value = as_server && mechanism == ZMQ_CURVE; - return 0; - } - break; - - case ZMQ_CURVE_PUBLICKEY: - if (*optvallen_ == CURVE_KEYSIZE) { - memcpy (optval_, curve_public_key, CURVE_KEYSIZE); - return 0; - } - else - if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { - zmq_z85_encode ((char *) optval_, curve_public_key, CURVE_KEYSIZE); - return 0; - } - break; - - case ZMQ_CURVE_SECRETKEY: - if (*optvallen_ == CURVE_KEYSIZE) { - memcpy (optval_, curve_secret_key, CURVE_KEYSIZE); - return 0; - } - else - if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { - zmq_z85_encode ((char *) optval_, curve_secret_key, CURVE_KEYSIZE); - return 0; - } - break; - - case ZMQ_CURVE_SERVERKEY: - if (*optvallen_ == CURVE_KEYSIZE) { - memcpy (optval_, curve_server_key, CURVE_KEYSIZE); - return 0; - } - else - if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { - zmq_z85_encode ((char *) optval_, curve_server_key, CURVE_KEYSIZE); - return 0; - } - break; -#endif - - case ZMQ_CONFLATE: - if (is_int) { - *value = conflate; - return 0; - } - break; - - // If libgssapi isn't installed, these options provoke EINVAL -#ifdef HAVE_LIBGSSAPI_KRB5 - case ZMQ_GSSAPI_SERVER: - if (is_int) { - *value = as_server && mechanism == ZMQ_GSSAPI; - return 0; - } - break; - - case ZMQ_GSSAPI_PRINCIPAL: - if (*optvallen_ >= gss_principal.size () + 1) { - memcpy (optval_, gss_principal.c_str (), gss_principal.size () + 1); - *optvallen_ = gss_principal.size () + 1; - return 0; - } - break; - - case ZMQ_GSSAPI_SERVICE_PRINCIPAL: - if (*optvallen_ >= gss_service_principal.size () + 1) { - memcpy (optval_, gss_service_principal.c_str (), gss_service_principal.size () + 1); - *optvallen_ = gss_service_principal.size () + 1; - return 0; - } - break; - - case ZMQ_GSSAPI_PLAINTEXT: - if (is_int) { - *value = gss_plaintext; - return 0; - } - break; - - case ZMQ_GSSAPI_PRINCIPAL_NAMETYPE: - if (is_int) { - *value = gss_principal_nt; - return 0; - } - break; - case ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE: - if (is_int) { - *value = gss_service_principal_nt; - return 0; - } - break; -#endif - - case ZMQ_HANDSHAKE_IVL: - if (is_int) { - *value = handshake_ivl; - return 0; - } - break; - - case ZMQ_INVERT_MATCHING: - if (is_int) { - *value = invert_matching; - return 0; - } - break; - - case ZMQ_HEARTBEAT_IVL: - if (is_int) { - *value = heartbeat_interval; - return 0; - } - break; - - case ZMQ_HEARTBEAT_TTL: - if (is_int) { - // Convert the internal deciseconds value to milliseconds - *value = heartbeat_ttl * 100; - return 0; - } - break; - - case ZMQ_HEARTBEAT_TIMEOUT: - if (is_int) { - *value = heartbeat_timeout; - return 0; - } - break; - - case ZMQ_USE_FD: - if (is_int) { - *value = use_fd; - return 0; - } - break; - - case ZMQ_BINDTODEVICE: - if (*optvallen_ >= bound_device.size () + 1) { - memcpy (optval_, bound_device.c_str (), bound_device.size () + 1); - *optvallen_ = bound_device.size () + 1; - return 0; - } - break; - - case ZMQ_ZAP_ENFORCE_DOMAIN: - if (is_int) { - *value = zap_enforce_domain; - return 0; - } - break; - - default: -#if defined (ZMQ_ACT_MILITANT) - malformed = false; -#endif - break; - } -#if defined (ZMQ_ACT_MILITANT) - if (malformed) - zmq_assert (false); -#endif - errno = EINVAL; - return -1; -} - -bool zmq::options_t::is_valid (int option_) const -{ - LIBZMQ_UNUSED (option_); - return true; -} diff --git a/dep/libzmq/src/options.hpp b/dep/libzmq/src/options.hpp deleted file mode 100644 index ff9fac056d..0000000000 --- a/dep/libzmq/src/options.hpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_OPTIONS_HPP_INCLUDED__ -#define __ZMQ_OPTIONS_HPP_INCLUDED__ - -#include -#include -#include - -#include "stddef.h" -#include "stdint.hpp" -#include "tcp_address.hpp" - -#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED -#include -#endif -#ifdef ZMQ_HAVE_LOCAL_PEERCRED -#include -#endif - -// Normal base 256 key is 32 bytes -#define CURVE_KEYSIZE 32 -// Key encoded using Z85 is 40 bytes -#define CURVE_KEYSIZE_Z85 40 - -namespace zmq -{ - struct options_t - { - options_t (); - - int set_curve_key(uint8_t * destination, const void * optval_, size_t optvallen_); - - int setsockopt (int option_, const void *optval_, size_t optvallen_); - int getsockopt (int option_, void *optval_, size_t *optvallen_) const; - - bool is_valid (int option_) const; - - // High-water marks for message pipes. - int sndhwm; - int rcvhwm; - - // I/O thread affinity. - uint64_t affinity; - - // Socket routing id. - unsigned char routing_id_size; - unsigned char routing_id [256]; - - // Maximum transfer rate [kb/s]. Default 100kb/s. - int rate; - - // Reliability time interval [ms]. Default 10 seconds. - int recovery_ivl; - - // Sets the time-to-live field in every multicast packet sent. - int multicast_hops; - - // Sets the maximum transport data unit size in every multicast - // packet sent. - int multicast_maxtpdu; - - // SO_SNDBUF and SO_RCVBUF to be passed to underlying transport sockets. - int sndbuf; - int rcvbuf; - - // Type of service (containing DSCP and ECN socket options) - int tos; - - // Socket type. - int type; - - // Linger time, in milliseconds. - int linger; - - // Maximum interval in milliseconds beyond which userspace will - // timeout connect(). - // Default 0 (unused) - int connect_timeout; - - // Maximum interval in milliseconds beyond which TCP will timeout - // retransmitted packets. - // Default 0 (unused) - int tcp_maxrt; - - // Minimum interval between attempts to reconnect, in milliseconds. - // Default 100ms - int reconnect_ivl; - - // Maximum interval between attempts to reconnect, in milliseconds. - // Default 0 (unused) - int reconnect_ivl_max; - - // Maximum backlog for pending connections. - int backlog; - - // Maximal size of message to handle. - int64_t maxmsgsize; - - // The timeout for send/recv operations for this socket, in milliseconds. - int rcvtimeo; - int sndtimeo; - - // If true, IPv6 is enabled (as well as IPv4) - bool ipv6; - - // If 1, connecting pipes are not attached immediately, meaning a send() - // on a socket with only connecting pipes would block - int immediate; - - // If 1, (X)SUB socket should filter the messages. If 0, it should not. - bool filter; - - // If true, the subscription matching on (X)PUB and (X)SUB sockets - // is reversed. Messages are sent to and received by non-matching - // sockets. - bool invert_matching; - - // If true, the routing id message is forwarded to the socket. - bool recv_routing_id; - - // if true, router socket accepts non-zmq tcp connections - bool raw_socket; - bool raw_notify; // Provide connect notifications - - // Address of SOCKS proxy - std::string socks_proxy_address; - - // TCP keep-alive settings. - // Defaults to -1 = do not change socket options - int tcp_keepalive; - int tcp_keepalive_cnt; - int tcp_keepalive_idle; - int tcp_keepalive_intvl; - - // TCP accept() filters - typedef std::vector tcp_accept_filters_t; - tcp_accept_filters_t tcp_accept_filters; - - // IPC accept() filters -# if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED - typedef std::set ipc_uid_accept_filters_t; - ipc_uid_accept_filters_t ipc_uid_accept_filters; - typedef std::set ipc_gid_accept_filters_t; - ipc_gid_accept_filters_t ipc_gid_accept_filters; -# endif -# if defined ZMQ_HAVE_SO_PEERCRED - typedef std::set ipc_pid_accept_filters_t; - ipc_pid_accept_filters_t ipc_pid_accept_filters; -# endif - - // Security mechanism for all connections on this socket - int mechanism; - - // If peer is acting as server for PLAIN or CURVE mechanisms - int as_server; - - // ZAP authentication domain - std::string zap_domain; - - // Security credentials for PLAIN mechanism - std::string plain_username; - std::string plain_password; - - // Security credentials for CURVE mechanism - uint8_t curve_public_key [CURVE_KEYSIZE]; - uint8_t curve_secret_key [CURVE_KEYSIZE]; - uint8_t curve_server_key [CURVE_KEYSIZE]; - - // Principals for GSSAPI mechanism - std::string gss_principal; - std::string gss_service_principal; - - // Name types GSSAPI principals - int gss_principal_nt; - int gss_service_principal_nt; - - // If true, gss encryption will be disabled - bool gss_plaintext; - - // ID of the socket. - int socket_id; - - // If true, socket conflates outgoing/incoming messages. - // Applicable to dealer, push/pull, pub/sub socket types. - // Cannot receive multi-part messages. - // Ignores hwm - bool conflate; - - // If connection handshake is not done after this many milliseconds, - // close socket. Default is 30 secs. 0 means no handshake timeout. - int handshake_ivl; - - bool connected; - // If remote peer receives a PING message and doesn't receive another - // message within the ttl value, it should close the connection - // (measured in tenths of a second) - uint16_t heartbeat_ttl; - // Time in milliseconds between sending heartbeat PING messages. - int heartbeat_interval; - // Time in milliseconds to wait for a PING response before disconnecting - int heartbeat_timeout; - -# if defined ZMQ_HAVE_VMCI - uint64_t vmci_buffer_size; - uint64_t vmci_buffer_min_size; - uint64_t vmci_buffer_max_size; - int vmci_connect_timeout; -# endif - - // When creating a new ZMQ socket, if this option is set the value - // will be used as the File Descriptor instead of allocating a new - // one via the socket () system call. - int use_fd; - - // Device to bind the underlying socket to, eg. VRF or interface - std::string bound_device; - - // Enforce a non-empty ZAP domain requirement for PLAIN auth - bool zap_enforce_domain; - }; -} - -#endif diff --git a/dep/libzmq/src/own.cpp b/dep/libzmq/src/own.cpp deleted file mode 100644 index b87f4ee034..0000000000 --- a/dep/libzmq/src/own.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "own.hpp" -#include "err.hpp" -#include "io_thread.hpp" - -zmq::own_t::own_t (class ctx_t *parent_, uint32_t tid_) : - object_t (parent_, tid_), - terminating (false), - sent_seqnum (0), - processed_seqnum (0), - owner (NULL), - term_acks (0) -{ -} - -zmq::own_t::own_t (io_thread_t *io_thread_, const options_t &options_) : - object_t (io_thread_), - options (options_), - terminating (false), - sent_seqnum (0), - processed_seqnum (0), - owner (NULL), - term_acks (0) -{ -} - -zmq::own_t::~own_t () -{ -} - -void zmq::own_t::set_owner (own_t *owner_) -{ - zmq_assert (!owner); - owner = owner_; -} - -void zmq::own_t::inc_seqnum () -{ - // This function may be called from a different thread! - sent_seqnum.add (1); -} - -void zmq::own_t::process_seqnum () -{ - // Catch up with counter of processed commands. - processed_seqnum++; - - // We may have catched up and still have pending terms acks. - check_term_acks (); -} - -void zmq::own_t::launch_child (own_t *object_) -{ - // Specify the owner of the object. - object_->set_owner (this); - - // Plug the object into the I/O thread. - send_plug (object_); - - // Take ownership of the object. - send_own (this, object_); -} - -void zmq::own_t::term_child (own_t *object_) -{ - process_term_req (object_); -} - -void zmq::own_t::process_term_req (own_t *object_) -{ - // When shutting down we can ignore termination requests from owned - // objects. The termination request was already sent to the object. - if (terminating) - return; - - // If I/O object is well and alive let's ask it to terminate. - owned_t::iterator it = std::find (owned.begin (), owned.end (), object_); - - // If not found, we assume that termination request was already sent to - // the object so we can safely ignore the request. - if (it == owned.end ()) - return; - - owned.erase (it); - register_term_acks (1); - - // Note that this object is the root of the (partial shutdown) thus, its - // value of linger is used, rather than the value stored by the children. - send_term (object_, options.linger); -} - -void zmq::own_t::process_own (own_t *object_) -{ - // If the object is already being shut down, new owned objects are - // immediately asked to terminate. Note that linger is set to zero. - if (terminating) { - register_term_acks (1); - send_term (object_, 0); - return; - } - - // Store the reference to the owned object. - owned.insert (object_); -} - -void zmq::own_t::terminate () -{ - // If termination is already underway, there's no point - // in starting it anew. - if (terminating) - return; - - // As for the root of the ownership tree, there's no one to terminate it, - // so it has to terminate itself. - if (!owner) { - process_term (options.linger); - return; - } - - // If I am an owned object, I'll ask my owner to terminate me. - send_term_req (owner, this); -} - -bool zmq::own_t::is_terminating () -{ - return terminating; -} - -void zmq::own_t::process_term (int linger_) -{ - // Double termination should never happen. - zmq_assert (!terminating); - - // Send termination request to all owned objects. - for (owned_t::iterator it = owned.begin (); it != owned.end (); ++it) - send_term (*it, linger_); - register_term_acks ((int) owned.size ()); - owned.clear (); - - // Start termination process and check whether by chance we cannot - // terminate immediately. - terminating = true; - check_term_acks (); -} - -void zmq::own_t::register_term_acks (int count_) -{ - term_acks += count_; -} - -void zmq::own_t::unregister_term_ack () -{ - zmq_assert (term_acks > 0); - term_acks--; - - // This may be a last ack we are waiting for before termination... - check_term_acks (); -} - -void zmq::own_t::process_term_ack () -{ - unregister_term_ack (); -} - -void zmq::own_t::check_term_acks () -{ - if (terminating && processed_seqnum == sent_seqnum.get () && - term_acks == 0) { - - // Sanity check. There should be no active children at this point. - zmq_assert (owned.empty ()); - - // The root object has nobody to confirm the termination to. - // Other nodes will confirm the termination to the owner. - if (owner) - send_term_ack (owner); - - // Deallocate the resources. - process_destroy (); - } -} - -void zmq::own_t::process_destroy () -{ - delete this; -} - diff --git a/dep/libzmq/src/own.hpp b/dep/libzmq/src/own.hpp deleted file mode 100644 index 4c71dbd5ba..0000000000 --- a/dep/libzmq/src/own.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_OWN_HPP_INCLUDED__ -#define __ZMQ_OWN_HPP_INCLUDED__ - -#include -#include - -#include "object.hpp" -#include "options.hpp" -#include "atomic_counter.hpp" -#include "stdint.hpp" - -namespace zmq -{ - - class ctx_t; - class io_thread_t; - - // Base class for objects forming a part of ownership hierarchy. - // It handles initialisation and destruction of such objects. - - class own_t : public object_t - { - public: - - // Note that the owner is unspecified in the constructor. - // It'll be supplied later on when the object is plugged in. - - // The object is not living within an I/O thread. It has it's own - // thread outside of 0MQ infrastructure. - own_t (zmq::ctx_t *parent_, uint32_t tid_); - - // The object is living within I/O thread. - own_t (zmq::io_thread_t *io_thread_, const options_t &options_); - - // When another owned object wants to send command to this object - // it calls this function to let it know it should not shut down - // before the command is delivered. - void inc_seqnum (); - - // Use following two functions to wait for arbitrary events before - // terminating. Just add number of events to wait for using - // register_tem_acks functions. When event occurs, call - // remove_term_ack. When number of pending acks reaches zero - // object will be deallocated. - void register_term_acks (int count_); - void unregister_term_ack (); - - protected: - - // Launch the supplied object and become its owner. - void launch_child (own_t *object_); - - // Terminate owned object - void term_child (own_t *object_); - - // Ask owner object to terminate this object. It may take a while - // while actual termination is started. This function should not be - // called more than once. - void terminate (); - - // Returns true if the object is in process of termination. - bool is_terminating (); - - // Derived object destroys own_t. There's no point in allowing - // others to invoke the destructor. At the same time, it has to be - // virtual so that generic own_t deallocation mechanism destroys - // specific type of the owned object correctly. - virtual ~own_t (); - - // Term handler is protected rather than private so that it can - // be intercepted by the derived class. This is useful to add custom - // steps to the beginning of the termination process. - void process_term (int linger_); - - // A place to hook in when physical destruction of the object - // is to be delayed. - virtual void process_destroy (); - - // Socket options associated with this object. - options_t options; - - private: - - // Set owner of the object - void set_owner (own_t *owner_); - - // Handlers for incoming commands. - void process_own (own_t *object_); - void process_term_req (own_t *object_); - void process_term_ack (); - void process_seqnum (); - - // Check whether all the pending term acks were delivered. - // If so, deallocate this object. - void check_term_acks (); - - // True if termination was already initiated. If so, we can destroy - // the object if there are no more child objects or pending term acks. - bool terminating; - - // Sequence number of the last command sent to this object. - atomic_counter_t sent_seqnum; - - // Sequence number of the last command processed by this object. - uint64_t processed_seqnum; - - // Socket owning this object. It's responsible for shutting down - // this object. - own_t *owner; - - // List of all objects owned by this socket. We are responsible - // for deallocating them before we quit. - typedef std::set owned_t; - owned_t owned; - - // Number of events we have to get before we can destroy the object. - int term_acks; - - own_t (const own_t&); - const own_t &operator = (const own_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/pair.cpp b/dep/libzmq/src/pair.cpp deleted file mode 100644 index 586007e551..0000000000 --- a/dep/libzmq/src/pair.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "pair.hpp" -#include "err.hpp" -#include "pipe.hpp" -#include "msg.hpp" - -zmq::pair_t::pair_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - pipe (NULL), - last_in (NULL) -{ - options.type = ZMQ_PAIR; -} - -zmq::pair_t::~pair_t () -{ - zmq_assert (!pipe); -} - -void zmq::pair_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_ != NULL); - - // ZMQ_PAIR socket can only be connected to a single peer. - // The socket rejects any further connection requests. - if (pipe == NULL) - pipe = pipe_; - else - pipe_->terminate (false); -} - -void zmq::pair_t::xpipe_terminated (pipe_t *pipe_) -{ - if (pipe_ == pipe) { - if (last_in == pipe) { - saved_credential.set_deep_copy (last_in->get_credential ()); - last_in = NULL; - } - pipe = NULL; - } -} - -void zmq::pair_t::xread_activated (pipe_t *) -{ - // There's just one pipe. No lists of active and inactive pipes. - // There's nothing to do here. -} - -void zmq::pair_t::xwrite_activated (pipe_t *) -{ - // There's just one pipe. No lists of active and inactive pipes. - // There's nothing to do here. -} - -int zmq::pair_t::xsend (msg_t *msg_) -{ - if (!pipe || !pipe->write (msg_)) { - errno = EAGAIN; - return -1; - } - - if (!(msg_->flags () & msg_t::more)) - pipe->flush (); - - // Detach the original message from the data buffer. - int rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -int zmq::pair_t::xrecv (msg_t *msg_) -{ - // Deallocate old content of the message. - int rc = msg_->close (); - errno_assert (rc == 0); - - if (!pipe || !pipe->read (msg_)) { - - // Initialise the output parameter to be a 0-byte message. - rc = msg_->init (); - errno_assert (rc == 0); - - errno = EAGAIN; - return -1; - } - last_in = pipe; - return 0; -} - -bool zmq::pair_t::xhas_in () -{ - if (!pipe) - return false; - - return pipe->check_read (); -} - -bool zmq::pair_t::xhas_out () -{ - if (!pipe) - return false; - - return pipe->check_write (); -} - -const zmq::blob_t &zmq::pair_t::get_credential () const -{ - return last_in? last_in->get_credential (): saved_credential; -} diff --git a/dep/libzmq/src/pair.hpp b/dep/libzmq/src/pair.hpp deleted file mode 100644 index 63c46e29b7..0000000000 --- a/dep/libzmq/src/pair.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PAIR_HPP_INCLUDED__ -#define __ZMQ_PAIR_HPP_INCLUDED__ - -#include "blob.hpp" -#include "socket_base.hpp" -#include "session_base.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - class io_thread_t; - - class pair_t : - public socket_base_t - { - public: - - pair_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~pair_t (); - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - zmq::pipe_t *pipe; - - zmq::pipe_t *last_in; - - blob_t saved_credential; - - pair_t (const pair_t&); - const pair_t &operator = (const pair_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/pgm_receiver.hpp b/dep/libzmq/src/pgm_receiver.hpp deleted file mode 100644 index 7c854e7881..0000000000 --- a/dep/libzmq/src/pgm_receiver.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PGM_RECEIVER_HPP_INCLUDED__ -#define __ZMQ_PGM_RECEIVER_HPP_INCLUDED__ - -#if defined ZMQ_HAVE_OPENPGM - -#include -#include - -#include "io_object.hpp" -#include "i_engine.hpp" -#include "options.hpp" -#include "v1_decoder.hpp" -#include "pgm_socket.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - - class pgm_receiver_t : public io_object_t, public i_engine - { - - public: - - pgm_receiver_t (zmq::io_thread_t *parent_, const options_t &options_); - ~pgm_receiver_t (); - - int init (bool udp_encapsulation_, const char *network_); - - // i_engine interface implementation. - void plug (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_); - void terminate (); - void restart_input (); - void restart_output (); - void zap_msg_available () {} - const char *get_endpoint () const; - - // i_poll_events interface implementation. - void in_event (); - void timer_event (int token); - - private: - - // Unplug the engine from the session. - void unplug (); - - // Decode received data (inpos, insize) and forward decoded - // messages to the session. - int process_input (v1_decoder_t *decoder); - - // PGM is not able to move subscriptions upstream. Thus, drop all - // the pending subscriptions. - void drop_subscriptions (); - - // RX timeout timer ID. - enum {rx_timer_id = 0xa1}; - - // RX timer is running. - bool has_rx_timer; - - // If joined is true we are already getting messages from the peer. - // It it's false, we are getting data but still we haven't seen - // beginning of a message. - struct peer_info_t - { - bool joined; - v1_decoder_t *decoder; - }; - - struct tsi_comp - { - bool operator () (const pgm_tsi_t <si, - const pgm_tsi_t &rtsi) const - { - uint32_t ll[2], rl[2]; - memcpy (ll, <si, sizeof (ll)); - memcpy (rl, &rtsi, sizeof (rl)); - return (ll[0] < rl[0]) || (ll[0] == rl[0] && ll[1] < rl[1]); - } - }; - - typedef std::map peers_t; - peers_t peers; - - // PGM socket. - pgm_socket_t pgm_socket; - - // Socket options. - options_t options; - - // Associated session. - zmq::session_base_t *session; - - const pgm_tsi_t *active_tsi; - - // Number of bytes not consumed by the decoder due to pipe overflow. - size_t insize; - - // Pointer to data still waiting to be processed by the decoder. - const unsigned char *inpos; - - // Poll handle associated with PGM socket. - handle_t socket_handle; - - // Poll handle associated with engine PGM waiting pipe. - handle_t pipe_handle; - - pgm_receiver_t (const pgm_receiver_t&); - const pgm_receiver_t &operator = (const pgm_receiver_t&); - }; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/pgm_sender.hpp b/dep/libzmq/src/pgm_sender.hpp deleted file mode 100644 index 973bac26e3..0000000000 --- a/dep/libzmq/src/pgm_sender.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PGM_SENDER_HPP_INCLUDED__ -#define __ZMQ_PGM_SENDER_HPP_INCLUDED__ - -#if defined ZMQ_HAVE_OPENPGM - -#include "stdint.hpp" -#include "io_object.hpp" -#include "i_engine.hpp" -#include "options.hpp" -#include "pgm_socket.hpp" -#include "v1_encoder.hpp" -#include "msg.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - - class pgm_sender_t : public io_object_t, public i_engine - { - - public: - - pgm_sender_t (zmq::io_thread_t *parent_, const options_t &options_); - ~pgm_sender_t (); - - int init (bool udp_encapsulation_, const char *network_); - - // i_engine interface implementation. - void plug (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_); - void terminate (); - void restart_input (); - void restart_output (); - void zap_msg_available () {} - const char *get_endpoint () const; - - // i_poll_events interface implementation. - void in_event (); - void out_event (); - void timer_event (int token); - - private: - - // Unplug the engine from the session. - void unplug (); - - // TX and RX timeout timer ID's. - enum {tx_timer_id = 0xa0, rx_timer_id = 0xa1}; - - // Timers are running. - bool has_tx_timer; - bool has_rx_timer; - - session_base_t *session; - - // Message encoder. - v1_encoder_t encoder; - - msg_t msg; - - // Keeps track of message boundaries. - bool more_flag; - - // PGM socket. - pgm_socket_t pgm_socket; - - // Socket options. - options_t options; - - // Poll handle associated with PGM socket. - handle_t handle; - handle_t uplink_handle; - handle_t rdata_notify_handle; - handle_t pending_notify_handle; - - // Output buffer from pgm_socket. - unsigned char *out_buffer; - - // Output buffer size. - size_t out_buffer_size; - - // Number of bytes in the buffer to be written to the socket. - // If zero, there are no data to be sent. - size_t write_size; - - pgm_sender_t (const pgm_sender_t&); - const pgm_sender_t &operator = (const pgm_sender_t&); - }; - -} -#endif - -#endif diff --git a/dep/libzmq/src/pipe.cpp b/dep/libzmq/src/pipe.cpp deleted file mode 100644 index 956b03a18e..0000000000 --- a/dep/libzmq/src/pipe.cpp +++ /dev/null @@ -1,547 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "macros.hpp" -#include "pipe.hpp" -#include "err.hpp" - -#include "ypipe.hpp" -#include "ypipe_conflate.hpp" - -int zmq::pipepair (class object_t *parents_ [2], class pipe_t* pipes_ [2], - int hwms_ [2], bool conflate_ [2]) -{ - // Creates two pipe objects. These objects are connected by two ypipes, - // each to pass messages in one direction. - - typedef ypipe_t upipe_normal_t; - typedef ypipe_conflate_t upipe_conflate_t; - - pipe_t::upipe_t *upipe1; - if(conflate_ [0]) - upipe1 = new (std::nothrow) upipe_conflate_t (); - else - upipe1 = new (std::nothrow) upipe_normal_t (); - alloc_assert (upipe1); - - pipe_t::upipe_t *upipe2; - if(conflate_ [1]) - upipe2 = new (std::nothrow) upipe_conflate_t (); - else - upipe2 = new (std::nothrow) upipe_normal_t (); - alloc_assert (upipe2); - - pipes_ [0] = new (std::nothrow) pipe_t (parents_ [0], upipe1, upipe2, - hwms_ [1], hwms_ [0], conflate_ [0]); - alloc_assert (pipes_ [0]); - pipes_ [1] = new (std::nothrow) pipe_t (parents_ [1], upipe2, upipe1, - hwms_ [0], hwms_ [1], conflate_ [1]); - alloc_assert (pipes_ [1]); - - pipes_ [0]->set_peer (pipes_ [1]); - pipes_ [1]->set_peer (pipes_ [0]); - - return 0; -} - -zmq::pipe_t::pipe_t (object_t *parent_, upipe_t *inpipe_, upipe_t *outpipe_, - int inhwm_, int outhwm_, bool conflate_) : - object_t (parent_), - inpipe (inpipe_), - outpipe (outpipe_), - in_active (true), - out_active (true), - hwm (outhwm_), - lwm (compute_lwm (inhwm_)), - inhwmboost(-1), - outhwmboost(-1), - msgs_read (0), - msgs_written (0), - peers_msgs_read (0), - peer (NULL), - sink (NULL), - state (active), - delay (true), - server_socket_routing_id (0), - conflate (conflate_) -{ -} - -zmq::pipe_t::~pipe_t () -{ -} - -void zmq::pipe_t::set_peer (pipe_t *peer_) -{ - // Peer can be set once only. - zmq_assert (!peer); - peer = peer_; -} - -void zmq::pipe_t::set_event_sink (i_pipe_events *sink_) -{ - // Sink can be set once only. - zmq_assert (!sink); - sink = sink_; -} - -void zmq::pipe_t::set_server_socket_routing_id (uint32_t server_socket_routing_id_) -{ - server_socket_routing_id = server_socket_routing_id_; -} - -uint32_t zmq::pipe_t::get_server_socket_routing_id () -{ - return server_socket_routing_id; -} - -void zmq::pipe_t::set_router_socket_routing_id (const blob_t &router_socket_routing_id_) -{ - router_socket_routing_id.set_deep_copy (router_socket_routing_id_); -} - -const zmq::blob_t &zmq::pipe_t::get_routing_id () -{ - return router_socket_routing_id; -} - -const zmq::blob_t &zmq::pipe_t::get_credential () const -{ - return credential; -} - -bool zmq::pipe_t::check_read () -{ - if (unlikely (!in_active)) - return false; - if (unlikely (state != active && state != waiting_for_delimiter)) - return false; - - // Check if there's an item in the pipe. - if (!inpipe->check_read ()) { - in_active = false; - return false; - } - - // If the next item in the pipe is message delimiter, - // initiate termination process. - if (inpipe->probe (is_delimiter)) { - msg_t msg; - bool ok = inpipe->read (&msg); - zmq_assert (ok); - process_delimiter (); - return false; - } - - return true; -} - -bool zmq::pipe_t::read (msg_t *msg_) -{ - if (unlikely (!in_active)) - return false; - if (unlikely (state != active && state != waiting_for_delimiter)) - return false; - -read_message: - if (!inpipe->read (msg_)) { - in_active = false; - return false; - } - - // If this is a credential, save a copy and receive next message. - if (unlikely (msg_->is_credential ())) { - const unsigned char *data = static_cast (msg_->data ()); - credential.set (data, msg_->size ()); - const int rc = msg_->close (); - zmq_assert (rc == 0); - goto read_message; - } - - // If delimiter was read, start termination process of the pipe. - if (msg_->is_delimiter ()) { - process_delimiter (); - return false; - } - - if (!(msg_->flags () & msg_t::more) && !msg_->is_routing_id ()) - msgs_read++; - - if (lwm > 0 && msgs_read % lwm == 0) - send_activate_write (peer, msgs_read); - - return true; -} - -bool zmq::pipe_t::check_write () -{ - if (unlikely (!out_active || state != active)) - return false; - - bool full = !check_hwm(); - - if (unlikely (full)) { - out_active = false; - return false; - } - - return true; -} - -bool zmq::pipe_t::write (msg_t *msg_) -{ - if (unlikely (!check_write ())) - return false; - - bool more = msg_->flags () & msg_t::more ? true : false; - const bool is_routing_id = msg_->is_routing_id (); - outpipe->write (*msg_, more); - if (!more && !is_routing_id) - msgs_written++; - - return true; -} - -void zmq::pipe_t::rollback () -{ - // Remove incomplete message from the outbound pipe. - msg_t msg; - if (outpipe) { - while (outpipe->unwrite (&msg)) { - zmq_assert (msg.flags () & msg_t::more); - int rc = msg.close (); - errno_assert (rc == 0); - } - } -} - -void zmq::pipe_t::flush () -{ - // The peer does not exist anymore at this point. - if (state == term_ack_sent) - return; - - if (outpipe && !outpipe->flush ()) - send_activate_read (peer); -} - -void zmq::pipe_t::process_activate_read () -{ - if (!in_active && (state == active || state == waiting_for_delimiter)) { - in_active = true; - sink->read_activated (this); - } -} - -void zmq::pipe_t::process_activate_write (uint64_t msgs_read_) -{ - // Remember the peer's message sequence number. - peers_msgs_read = msgs_read_; - - if (!out_active && state == active) { - out_active = true; - sink->write_activated (this); - } -} - -void zmq::pipe_t::process_hiccup (void *pipe_) -{ - // Destroy old outpipe. Note that the read end of the pipe was already - // migrated to this thread. - zmq_assert (outpipe); - outpipe->flush (); - msg_t msg; - while (outpipe->read (&msg)) { - if (!(msg.flags () & msg_t::more)) - msgs_written--; - int rc = msg.close (); - errno_assert (rc == 0); - } - LIBZMQ_DELETE(outpipe); - - // Plug in the new outpipe. - zmq_assert (pipe_); - outpipe = (upipe_t*) pipe_; - out_active = true; - - // If appropriate, notify the user about the hiccup. - if (state == active) - sink->hiccuped (this); -} - -void zmq::pipe_t::process_pipe_term () -{ - zmq_assert (state == active - || state == delimiter_received - || state == term_req_sent1); - - // This is the simple case of peer-induced termination. If there are no - // more pending messages to read, or if the pipe was configured to drop - // pending messages, we can move directly to the term_ack_sent state. - // Otherwise we'll hang up in waiting_for_delimiter state till all - // pending messages are read. - if (state == active) { - if (delay) - state = waiting_for_delimiter; - else { - state = term_ack_sent; - outpipe = NULL; - send_pipe_term_ack (peer); - } - } - - // Delimiter happened to arrive before the term command. Now we have the - // term command as well, so we can move straight to term_ack_sent state. - else - if (state == delimiter_received) { - state = term_ack_sent; - outpipe = NULL; - send_pipe_term_ack (peer); - } - - // This is the case where both ends of the pipe are closed in parallel. - // We simply reply to the request by ack and continue waiting for our - // own ack. - else - if (state == term_req_sent1) { - state = term_req_sent2; - outpipe = NULL; - send_pipe_term_ack (peer); - } -} - -void zmq::pipe_t::process_pipe_term_ack () -{ - // Notify the user that all the references to the pipe should be dropped. - zmq_assert (sink); - sink->pipe_terminated (this); - - // In term_ack_sent and term_req_sent2 states there's nothing to do. - // Simply deallocate the pipe. In term_req_sent1 state we have to ack - // the peer before deallocating this side of the pipe. - // All the other states are invalid. - if (state == term_req_sent1) { - outpipe = NULL; - send_pipe_term_ack (peer); - } - else - zmq_assert (state == term_ack_sent || state == term_req_sent2); - - // We'll deallocate the inbound pipe, the peer will deallocate the outbound - // pipe (which is an inbound pipe from its point of view). - // First, delete all the unread messages in the pipe. We have to do it by - // hand because msg_t doesn't have automatic destructor. Then deallocate - // the ypipe itself. - - if (!conflate) { - msg_t msg; - while (inpipe->read (&msg)) { - int rc = msg.close (); - errno_assert (rc == 0); - } - } - - LIBZMQ_DELETE(inpipe); - - // Deallocate the pipe object - delete this; -} - -void zmq::pipe_t::process_pipe_hwm (int inhwm_, int outhwm_) -{ - set_hwms(inhwm_, outhwm_); -} - -void zmq::pipe_t::set_nodelay () -{ - this->delay = false; -} - -void zmq::pipe_t::terminate (bool delay_) -{ - // Overload the value specified at pipe creation. - delay = delay_; - - // If terminate was already called, we can ignore the duplicate invocation. - if (state == term_req_sent1 || state == term_req_sent2) { - return; - } - // If the pipe is in the final phase of async termination, it's going to - // closed anyway. No need to do anything special here. - else if (state == term_ack_sent) { - return; - } - // The simple sync termination case. Ask the peer to terminate and wait - // for the ack. - else if (state == active) { - send_pipe_term (peer); - state = term_req_sent1; - } - // There are still pending messages available, but the user calls - // 'terminate'. We can act as if all the pending messages were read. - else if (state == waiting_for_delimiter && !delay) { - // Drop any unfinished outbound messages. - rollback (); - outpipe = NULL; - send_pipe_term_ack (peer); - state = term_ack_sent; - } - // If there are pending messages still available, do nothing. - else if (state == waiting_for_delimiter) { - } - // We've already got delimiter, but not term command yet. We can ignore - // the delimiter and ack synchronously terminate as if we were in - // active state. - else if (state == delimiter_received) { - send_pipe_term (peer); - state = term_req_sent1; - } - // There are no other states. - else { - zmq_assert (false); - } - - // Stop outbound flow of messages. - out_active = false; - - if (outpipe) { - - // Drop any unfinished outbound messages. - rollback (); - - // Write the delimiter into the pipe. Note that watermarks are not - // checked; thus the delimiter can be written even when the pipe is full. - msg_t msg; - msg.init_delimiter (); - outpipe->write (msg, false); - flush (); - } -} - -bool zmq::pipe_t::is_delimiter (const msg_t &msg_) -{ - return msg_.is_delimiter (); -} - -int zmq::pipe_t::compute_lwm (int hwm_) -{ - // Compute the low water mark. Following point should be taken - // into consideration: - // - // 1. LWM has to be less than HWM. - // 2. LWM cannot be set to very low value (such as zero) as after filling - // the queue it would start to refill only after all the messages are - // read from it and thus unnecessarily hold the progress back. - // 3. LWM cannot be set to very high value (such as HWM-1) as it would - // result in lock-step filling of the queue - if a single message is - // read from a full queue, writer thread is resumed to write exactly one - // message to the queue and go back to sleep immediately. This would - // result in low performance. - // - // Given the 3. it would be good to keep HWM and LWM as far apart as - // possible to reduce the thread switching overhead to almost zero. - // Let's make LWM 1/2 of HWM. - int result = (hwm_ + 1) / 2; - - return result; -} - -void zmq::pipe_t::process_delimiter () -{ - zmq_assert (state == active - || state == waiting_for_delimiter); - - if (state == active) - state = delimiter_received; - else { - outpipe = NULL; - send_pipe_term_ack (peer); - state = term_ack_sent; - } -} - -void zmq::pipe_t::hiccup () -{ - // If termination is already under way do nothing. - if (state != active) - return; - - // We'll drop the pointer to the inpipe. From now on, the peer is - // responsible for deallocating it. - inpipe = NULL; - - // Create new inpipe. - if (conflate) - inpipe = new (std::nothrow)ypipe_conflate_t (); - else - inpipe = new (std::nothrow)ypipe_t (); - - alloc_assert (inpipe); - in_active = true; - - // Notify the peer about the hiccup. - send_hiccup (peer, (void*) inpipe); -} - -void zmq::pipe_t::set_hwms (int inhwm_, int outhwm_) -{ - int in = inhwm_ + (inhwmboost > 0 ? inhwmboost : 0); - int out = outhwm_ + (outhwmboost > 0 ? outhwmboost : 0); - - // if either send or recv side has hwm <= 0 it means infinite so we should set hwms infinite - if (inhwm_ <= 0 || inhwmboost == 0) - in = 0; - - if (outhwm_ <= 0 || outhwmboost == 0) - out = 0; - - lwm = compute_lwm(in); - hwm = out; -} - -void zmq::pipe_t::set_hwms_boost(int inhwmboost_, int outhwmboost_) -{ - inhwmboost = inhwmboost_; - outhwmboost = outhwmboost_; -} - -bool zmq::pipe_t::check_hwm () const -{ - bool full = hwm > 0 && msgs_written - peers_msgs_read >= uint64_t (hwm); - return( !full ); -} - -void zmq::pipe_t::send_hwms_to_peer(int inhwm_, int outhwm_) -{ - send_pipe_hwm(peer, inhwm_, outhwm_); -} diff --git a/dep/libzmq/src/pipe.hpp b/dep/libzmq/src/pipe.hpp deleted file mode 100644 index c07c9849c9..0000000000 --- a/dep/libzmq/src/pipe.hpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PIPE_HPP_INCLUDED__ -#define __ZMQ_PIPE_HPP_INCLUDED__ - -#include "msg.hpp" -#include "ypipe_base.hpp" -#include "config.hpp" -#include "object.hpp" -#include "stdint.hpp" -#include "array.hpp" -#include "blob.hpp" - -namespace zmq -{ - - class object_t; - class pipe_t; - - // Create a pipepair for bi-directional transfer of messages. - // First HWM is for messages passed from first pipe to the second pipe. - // Second HWM is for messages passed from second pipe to the first pipe. - // Delay specifies how the pipe behaves when the peer terminates. If true - // pipe receives all the pending messages before terminating, otherwise it - // terminates straight away. - // If conflate is true, only the most recently arrived message could be - // read (older messages are discarded) - int pipepair (zmq::object_t *parents_ [2], zmq::pipe_t* pipes_ [2], - int hwms_ [2], bool conflate_ [2]); - - struct i_pipe_events - { - virtual ~i_pipe_events () {} - - virtual void read_activated (zmq::pipe_t *pipe_) = 0; - virtual void write_activated (zmq::pipe_t *pipe_) = 0; - virtual void hiccuped (zmq::pipe_t *pipe_) = 0; - virtual void pipe_terminated (zmq::pipe_t *pipe_) = 0; - }; - - // Note that pipe can be stored in three different arrays. - // The array of inbound pipes (1), the array of outbound pipes (2) and - // the generic array of pipes to be deallocated (3). - - class pipe_t : - public object_t, - public array_item_t <1>, - public array_item_t <2>, - public array_item_t <3> - { - // This allows pipepair to create pipe objects. - friend int pipepair (zmq::object_t *parents_ [2], zmq::pipe_t* pipes_ [2], - int hwms_ [2], bool conflate_ [2]); - - public: - - // Specifies the object to send events to. - void set_event_sink (i_pipe_events *sink_); - - // Pipe endpoint can store an routing ID to be used by its clients. - void set_server_socket_routing_id (uint32_t routing_id_); - uint32_t get_server_socket_routing_id (); - - // Pipe endpoint can store an opaque ID to be used by its clients. - void set_router_socket_routing_id (const blob_t &identity_); - const blob_t &get_routing_id (); - - const blob_t &get_credential () const; - - // Returns true if there is at least one message to read in the pipe. - bool check_read (); - - // Reads a message to the underlying pipe. - bool read (msg_t *msg_); - - // Checks whether messages can be written to the pipe. If the pipe is - // closed or if writing the message would cause high watermark the - // function returns false. - bool check_write (); - - // Writes a message to the underlying pipe. Returns false if the - // message does not pass check_write. If false, the message object - // retains ownership of its message buffer. - bool write (msg_t *msg_); - - // Remove unfinished parts of the outbound message from the pipe. - void rollback (); - - // Flush the messages downstream. - void flush (); - - // Temporarily disconnects the inbound message stream and drops - // all the messages on the fly. Causes 'hiccuped' event to be generated - // in the peer. - void hiccup (); - - // Ensure the pipe won't block on receiving pipe_term. - void set_nodelay (); - - // Ask pipe to terminate. The termination will happen asynchronously - // and user will be notified about actual deallocation by 'terminated' - // event. If delay is true, the pending messages will be processed - // before actual shutdown. - void terminate (bool delay_); - - // Set the high water marks. - void set_hwms (int inhwm_, int outhwm_); - - // Set the boost to high water marks, used by inproc sockets so total hwm are sum of connect and bind sockets watermarks - void set_hwms_boost(int inhwmboost_, int outhwmboost_); - - // send command to peer for notify the change of hwm - void send_hwms_to_peer(int inhwm_, int outhwm_); - - // Returns true if HWM is not reached - bool check_hwm () const; - private: - - // Type of the underlying lock-free pipe. - typedef ypipe_base_t upipe_t; - - // Command handlers. - void process_activate_read (); - void process_activate_write (uint64_t msgs_read_); - void process_hiccup (void *pipe_); - void process_pipe_term (); - void process_pipe_term_ack (); - void process_pipe_hwm (int inhwm_, int outhwm_); - - // Handler for delimiter read from the pipe. - void process_delimiter (); - - // Constructor is private. Pipe can only be created using - // pipepair function. - pipe_t (object_t *parent_, upipe_t *inpipe_, upipe_t *outpipe_, - int inhwm_, int outhwm_, bool conflate_); - - // Pipepair uses this function to let us know about - // the peer pipe object. - void set_peer (pipe_t *pipe_); - - // Destructor is private. Pipe objects destroy themselves. - ~pipe_t (); - - // Underlying pipes for both directions. - upipe_t *inpipe; - upipe_t *outpipe; - - // Can the pipe be read from / written to? - bool in_active; - bool out_active; - - // High watermark for the outbound pipe. - int hwm; - - // Low watermark for the inbound pipe. - int lwm; - - // boosts for high and low watermarks, used with inproc sockets so hwm are sum of send and recv hmws on each side of pipe - int inhwmboost; - int outhwmboost; - - // Number of messages read and written so far. - uint64_t msgs_read; - uint64_t msgs_written; - - // Last received peer's msgs_read. The actual number in the peer - // can be higher at the moment. - uint64_t peers_msgs_read; - - // The pipe object on the other side of the pipepair. - pipe_t *peer; - - // Sink to send events to. - i_pipe_events *sink; - - // States of the pipe endpoint: - // active: common state before any termination begins, - // delimiter_received: delimiter was read from pipe before - // term command was received, - // waiting_for_delimiter: term command was already received - // from the peer but there are still pending messages to read, - // term_ack_sent: all pending messages were already read and - // all we are waiting for is ack from the peer, - // term_req_sent1: 'terminate' was explicitly called by the user, - // term_req_sent2: user called 'terminate' and then we've got - // term command from the peer as well. - enum { - active, - delimiter_received, - waiting_for_delimiter, - term_ack_sent, - term_req_sent1, - term_req_sent2 - } state; - - // If true, we receive all the pending inbound messages before - // terminating. If false, we terminate immediately when the peer - // asks us to. - bool delay; - - // Routing id of the writer. Used uniquely by the reader side. - blob_t router_socket_routing_id; - - // Routing id of the writer. Used uniquely by the reader side. - int server_socket_routing_id; - - // Pipe's credential. - blob_t credential; - - // Returns true if the message is delimiter; false otherwise. - static bool is_delimiter (const msg_t &msg_); - - // Computes appropriate low watermark from the given high watermark. - static int compute_lwm (int hwm_); - - const bool conflate; - - // Disable copying. - pipe_t (const pipe_t&); - const pipe_t &operator = (const pipe_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/plain_client.cpp b/dep/libzmq/src/plain_client.cpp deleted file mode 100644 index 4aa023c859..0000000000 --- a/dep/libzmq/src/plain_client.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" - -#include - -#include "msg.hpp" -#include "err.hpp" -#include "plain_client.hpp" -#include "session_base.hpp" - -zmq::plain_client_t::plain_client_t (session_base_t *const session_, - const options_t &options_) : - mechanism_base_t (session_, options_), - state (sending_hello) -{ -} - -zmq::plain_client_t::~plain_client_t () -{ -} - -int zmq::plain_client_t::next_handshake_command (msg_t *msg_) -{ - int rc = 0; - - switch (state) { - case sending_hello: - rc = produce_hello (msg_); - if (rc == 0) - state = waiting_for_welcome; - break; - case sending_initiate: - rc = produce_initiate (msg_); - if (rc == 0) - state = waiting_for_ready; - break; - default: - errno = EAGAIN; - rc = -1; - } - return rc; -} - -int zmq::plain_client_t::process_handshake_command (msg_t *msg_) -{ - const unsigned char *cmd_data = - static_cast (msg_->data ()); - const size_t data_size = msg_->size (); - - int rc = 0; - if (data_size >= 8 && !memcmp (cmd_data, "\7WELCOME", 8)) - rc = process_welcome (cmd_data, data_size); - else - if (data_size >= 6 && !memcmp (cmd_data, "\5READY", 6)) - rc = process_ready (cmd_data, data_size); - else - if (data_size >= 6 && !memcmp (cmd_data, "\5ERROR", 6)) - rc = process_error (cmd_data, data_size); - else { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - rc = -1; - } - - if (rc == 0) { - rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - } - - return rc; -} - -zmq::mechanism_t::status_t zmq::plain_client_t::status () const -{ - if (state == ready) - return mechanism_t::ready; - else - if (state == error_command_received) - return mechanism_t::error; - else - return mechanism_t::handshaking; -} - -int zmq::plain_client_t::produce_hello (msg_t *msg_) const -{ - const std::string username = options.plain_username; - zmq_assert (username.length () < 256); - - const std::string password = options.plain_password; - zmq_assert (password.length () < 256); - - const size_t command_size = 6 + 1 + username.length () - + 1 + password.length (); - - const int rc = msg_->init_size (command_size); - errno_assert (rc == 0); - - unsigned char *ptr = static_cast (msg_->data ()); - memcpy (ptr, "\x05HELLO", 6); - ptr += 6; - - *ptr++ = static_cast (username.length ()); - memcpy (ptr, username.c_str (), username.length ()); - ptr += username.length (); - - *ptr++ = static_cast (password.length ()); - memcpy (ptr, password.c_str (), password.length ()); - - return 0; -} - -int zmq::plain_client_t::process_welcome ( - const unsigned char *cmd_data, size_t data_size) -{ - LIBZMQ_UNUSED (cmd_data); - - if (state != waiting_for_welcome) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - return -1; - } - if (data_size != 8) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME); - errno = EPROTO; - return -1; - } - state = sending_initiate; - return 0; -} - -int zmq::plain_client_t::produce_initiate (msg_t *msg_) const -{ - make_command_with_basic_properties (msg_, "\x08INITIATE", 9); - - return 0; -} - -int zmq::plain_client_t::process_ready ( - const unsigned char *cmd_data, size_t data_size) -{ - if (state != waiting_for_ready) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - return -1; - } - const int rc = parse_metadata (cmd_data + 6, data_size - 6); - if (rc == 0) - state = ready; - else - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA); - - return rc; -} - -int zmq::plain_client_t::process_error ( - const unsigned char *cmd_data, size_t data_size) -{ - if (state != waiting_for_welcome && state != waiting_for_ready) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - return -1; - } - if (data_size < 7) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR); - errno = EPROTO; - return -1; - } - const size_t error_reason_len = static_cast (cmd_data [6]); - if (error_reason_len > data_size - 7) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), - ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR); - errno = EPROTO; - return -1; - } - const char *error_reason = reinterpret_cast (cmd_data) + 7; - handle_error_reason (error_reason, error_reason_len); - state = error_command_received; - return 0; -} diff --git a/dep/libzmq/src/plain_client.hpp b/dep/libzmq/src/plain_client.hpp deleted file mode 100644 index 76789e09f9..0000000000 --- a/dep/libzmq/src/plain_client.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PLAIN_CLIENT_HPP_INCLUDED__ -#define __ZMQ_PLAIN_CLIENT_HPP_INCLUDED__ - -#include "mechanism_base.hpp" -#include "options.hpp" - -namespace zmq -{ - - class msg_t; - - class plain_client_t : public mechanism_base_t - { - public: - plain_client_t (session_base_t *const session_, - const options_t &options_); - virtual ~plain_client_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - virtual status_t status () const; - - private: - - enum state_t { - sending_hello, - waiting_for_welcome, - sending_initiate, - waiting_for_ready, - error_command_received, - ready - }; - - state_t state; - - int produce_hello (msg_t *msg_) const; - int produce_initiate (msg_t *msg_) const; - - int process_welcome ( - const unsigned char *cmd_data, size_t data_size); - int process_ready ( - const unsigned char *cmd_data, size_t data_size); - int process_error ( - const unsigned char *cmd_data, size_t data_size); - }; - -} - -#endif diff --git a/dep/libzmq/src/plain_server.cpp b/dep/libzmq/src/plain_server.cpp deleted file mode 100644 index e993507d7e..0000000000 --- a/dep/libzmq/src/plain_server.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include - -#include "msg.hpp" -#include "session_base.hpp" -#include "err.hpp" -#include "plain_server.hpp" -#include "wire.hpp" - -zmq::plain_server_t::plain_server_t (session_base_t *session_, - const std::string &peer_address_, - const options_t &options_) : - mechanism_base_t (session_, options_), - zap_client_common_handshake_t ( - session_, peer_address_, options_, sending_welcome) -{ - // Note that there is no point to PLAIN if ZAP is not set up to handle the - // username and password, so if ZAP is not configured it is considered a - // failure. - // Given this is a backward-incompatible change, it's behind a socket - // option disabled by default. - if (options.zap_enforce_domain) - zmq_assert (zap_required()); -} - -zmq::plain_server_t::~plain_server_t () -{ -} - -int zmq::plain_server_t::next_handshake_command (msg_t *msg_) -{ - int rc = 0; - - switch (state) { - case sending_welcome: - rc = produce_welcome (msg_); - if (rc == 0) - state = waiting_for_initiate; - break; - case sending_ready: - rc = produce_ready (msg_); - if (rc == 0) - state = ready; - break; - case sending_error: - rc = produce_error (msg_); - if (rc == 0) - state = error_sent; - break; - default: - errno = EAGAIN; - rc = -1; - } - return rc; -} - -int zmq::plain_server_t::process_handshake_command (msg_t *msg_) -{ - int rc = 0; - - switch (state) { - case waiting_for_hello: - rc = process_hello (msg_); - break; - case waiting_for_initiate: - rc = process_initiate (msg_); - break; - default: - // TODO see comment in curve_server_t::process_handshake_command - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED); - errno = EPROTO; - rc = -1; - break; - } - if (rc == 0) { - rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - } - return rc; -} - -int zmq::plain_server_t::process_hello (msg_t *msg_) -{ - int rc = check_basic_command_structure (msg_); - if (rc == -1) - return -1; - - const unsigned char *ptr = static_cast (msg_->data ()); - size_t bytes_left = msg_->size (); - - if (bytes_left < 6 || memcmp (ptr, "\x05HELLO", 6)) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - return -1; - } - ptr += 6; - bytes_left -= 6; - - if (bytes_left < 1) { - // PLAIN I: invalid PLAIN client, did not send username - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); - errno = EPROTO; - return -1; - } - const uint8_t username_length = *ptr++; - bytes_left -= 1; - - if (bytes_left < username_length) { - // PLAIN I: invalid PLAIN client, sent malformed username - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); - errno = EPROTO; - return -1; - } - const std::string username = std::string ((char *) ptr, username_length); - ptr += username_length; - bytes_left -= username_length; - if (bytes_left < 1) { - // PLAIN I: invalid PLAIN client, did not send password - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); - errno = EPROTO; - return -1; - } - - const uint8_t password_length = *ptr++; - bytes_left -= 1; - if (bytes_left < password_length) { - // PLAIN I: invalid PLAIN client, sent malformed password - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); - errno = EPROTO; - return -1; - } - - const std::string password = std::string ((char *) ptr, password_length); - ptr += password_length; - bytes_left -= password_length; - if (bytes_left > 0) { - // PLAIN I: invalid PLAIN client, sent extraneous data - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); - errno = EPROTO; - return -1; - } - - // Use ZAP protocol (RFC 27) to authenticate the user. - rc = session->zap_connect (); - if (rc != 0) { - session->get_socket ()->event_handshake_failed_no_detail ( - session->get_endpoint (), EFAULT); - return -1; - } - - send_zap_request (username, password); - state = waiting_for_zap_reply; - - // TODO actually, it is quite unlikely that we can read the ZAP - // reply already, but removing this has some strange side-effect - // (probably because the pipe's in_active flag is true until a read - // is attempted) - return receive_and_process_zap_reply () == -1 ? -1 : 0; -} - -int zmq::plain_server_t::produce_welcome (msg_t *msg_) const -{ - const int rc = msg_->init_size (8); - errno_assert (rc == 0); - memcpy (msg_->data (), "\x07WELCOME", 8); - return 0; -} - -int zmq::plain_server_t::process_initiate (msg_t *msg_) -{ - const unsigned char *ptr = static_cast (msg_->data ()); - const size_t bytes_left = msg_->size (); - - if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); - errno = EPROTO; - return -1; - } - const int rc = parse_metadata (ptr + 9, bytes_left - 9); - if (rc == 0) - state = sending_ready; - return rc; -} - -int zmq::plain_server_t::produce_ready (msg_t *msg_) const -{ - make_command_with_basic_properties (msg_, "\5READY", 6); - - return 0; -} - -int zmq::plain_server_t::produce_error (msg_t *msg_) const -{ - zmq_assert (status_code.length () == 3); - const int rc = msg_->init_size (6 + 1 + status_code.length ()); - zmq_assert (rc == 0); - char *msg_data = static_cast (msg_->data ()); - memcpy (msg_data, "\5ERROR", 6); - msg_data [6] = (char) status_code.length (); - memcpy (msg_data + 7, status_code.c_str (), status_code.length ()); - return 0; -} - -void zmq::plain_server_t::send_zap_request (const std::string &username, - const std::string &password) -{ - const uint8_t *credentials[] = { - reinterpret_cast (username.c_str ()), - reinterpret_cast (password.c_str ())}; - size_t credentials_sizes[] = {username.size (), password.size ()}; - zap_client_t::send_zap_request ("PLAIN", 5, credentials, credentials_sizes, - 2); -} diff --git a/dep/libzmq/src/plain_server.hpp b/dep/libzmq/src/plain_server.hpp deleted file mode 100644 index 7033944f1a..0000000000 --- a/dep/libzmq/src/plain_server.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PLAIN_SERVER_HPP_INCLUDED__ -#define __ZMQ_PLAIN_SERVER_HPP_INCLUDED__ - -#include "mechanism.hpp" -#include "options.hpp" -#include "zap_client.hpp" - -namespace zmq -{ - - class msg_t; - class session_base_t; - - class plain_server_t : public zap_client_common_handshake_t - { - public: - - plain_server_t (session_base_t *session_, - const std::string &peer_address_, - const options_t &options_); - virtual ~plain_server_t (); - - // mechanism implementation - virtual int next_handshake_command (msg_t *msg_); - virtual int process_handshake_command (msg_t *msg_); - - private: - - int produce_welcome (msg_t *msg_) const; - int produce_ready (msg_t *msg_) const; - int produce_error (msg_t *msg_) const; - - int process_hello (msg_t *msg_); - int process_initiate (msg_t *msg_); - - void send_zap_request (const std::string &username, - const std::string &password); - }; - -} - -#endif diff --git a/dep/libzmq/src/platform.hpp b/dep/libzmq/src/platform.hpp deleted file mode 100644 index a38b7776aa..0000000000 --- a/dep/libzmq/src/platform.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __PLATFORM_HPP_INCLUDED__ -#define __PLATFORM_HPP_INCLUDED__ - -// #define ZMQ_HAVE_WINDOWS - -// MSVC build configuration is controlled via options exposed in the Visual -// Studio user interface. The option to use libsodium is not exposed in the -// user interface unless a sibling `libsodium` directory to that of this -// repository exists and contains the following files: -// -// \builds\msvc\vs2015\libsodium.import.props -// \builds\msvc\vs2015\libsodium.import.xml - -#endif diff --git a/dep/libzmq/src/poll.cpp b/dep/libzmq/src/poll.cpp deleted file mode 100644 index 1f9163cf4d..0000000000 --- a/dep/libzmq/src/poll.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "poll.hpp" -#if defined ZMQ_USE_POLL - -#include -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#endif -#include - -#include "poll.hpp" -#include "err.hpp" -#include "config.hpp" -#include "i_poll_events.hpp" - -zmq::poll_t::poll_t (const zmq::ctx_t &ctx_) : - ctx(ctx_), - retired (false), - stopping (false) -{ -} - -zmq::poll_t::~poll_t () -{ - worker.stop (); -} - -zmq::poll_t::handle_t zmq::poll_t::add_fd (fd_t fd_, i_poll_events *events_) -{ - // If the file descriptor table is too small expand it. - fd_table_t::size_type sz = fd_table.size (); - if (sz <= (fd_table_t::size_type) fd_) { - fd_table.resize (fd_ + 1); - while (sz != (fd_table_t::size_type) (fd_ + 1)) { - fd_table [sz].index = retired_fd; - ++sz; - } - } - - pollfd pfd = {fd_, 0, 0}; - pollset.push_back (pfd); - zmq_assert (fd_table [fd_].index == retired_fd); - - fd_table [fd_].index = pollset.size() - 1; - fd_table [fd_].events = events_; - - // Increase the load metric of the thread. - adjust_load (1); - - return fd_; -} - -void zmq::poll_t::rm_fd (handle_t handle_) -{ - fd_t index = fd_table [handle_].index; - zmq_assert (index != retired_fd); - - // Mark the fd as unused. - pollset [index].fd = retired_fd; - fd_table [handle_].index = retired_fd; - retired = true; - - // Decrease the load metric of the thread. - adjust_load (-1); -} - -void zmq::poll_t::set_pollin (handle_t handle_) -{ - fd_t index = fd_table [handle_].index; - pollset [index].events |= POLLIN; -} - -void zmq::poll_t::reset_pollin (handle_t handle_) -{ - fd_t index = fd_table [handle_].index; - pollset [index].events &= ~((short) POLLIN); -} - -void zmq::poll_t::set_pollout (handle_t handle_) -{ - fd_t index = fd_table [handle_].index; - pollset [index].events |= POLLOUT; -} - -void zmq::poll_t::reset_pollout (handle_t handle_) -{ - fd_t index = fd_table [handle_].index; - pollset [index].events &= ~((short) POLLOUT); -} - -void zmq::poll_t::start () -{ - ctx.start_thread (worker, worker_routine, this); -} - -void zmq::poll_t::stop () -{ - stopping = true; -} - -int zmq::poll_t::max_fds () -{ - return -1; -} - -void zmq::poll_t::loop () -{ - while (!stopping) { - - // Execute any due timers. - int timeout = (int) execute_timers (); - - // Wait for events. - int rc = poll (&pollset [0], pollset.size (), timeout ? timeout : -1); - if (rc == -1) { - errno_assert (errno == EINTR); - continue; - } - - // If there are no events (i.e. it's a timeout) there's no point - // in checking the pollset. - if (rc == 0) - continue; - - for (pollset_t::size_type i = 0; i != pollset.size (); i++) { - - zmq_assert (!(pollset [i].revents & POLLNVAL)); - if (pollset [i].fd == retired_fd) - continue; - if (pollset [i].revents & (POLLERR | POLLHUP)) - fd_table [pollset [i].fd].events->in_event (); - if (pollset [i].fd == retired_fd) - continue; - if (pollset [i].revents & POLLOUT) - fd_table [pollset [i].fd].events->out_event (); - if (pollset [i].fd == retired_fd) - continue; - if (pollset [i].revents & POLLIN) - fd_table [pollset [i].fd].events->in_event (); - } - - // Clean up the pollset and update the fd_table accordingly. - if (retired) { - pollset_t::size_type i = 0; - while (i < pollset.size ()) { - if (pollset [i].fd == retired_fd) - pollset.erase (pollset.begin () + i); - else { - fd_table [pollset [i].fd].index = i; - i ++; - } - } - retired = false; - } - } -} - -void zmq::poll_t::worker_routine (void *arg_) -{ - ((poll_t*) arg_)->loop (); -} - -#endif diff --git a/dep/libzmq/src/poll.hpp b/dep/libzmq/src/poll.hpp deleted file mode 100644 index 8481805509..0000000000 --- a/dep/libzmq/src/poll.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_POLL_HPP_INCLUDED__ -#define __ZMQ_POLL_HPP_INCLUDED__ - -// poller.hpp decides which polling mechanism to use. -#include "poller.hpp" -#if defined ZMQ_USE_POLL - -#if !defined ZMQ_HAVE_WINDOWS -#include -#endif -#include -#include - -#include "ctx.hpp" -#include "fd.hpp" -#include "thread.hpp" -#include "poller_base.hpp" - -namespace zmq -{ - - struct i_poll_events; - - // Implements socket polling mechanism using the POSIX.1-2001 - // poll() system call. - - class poll_t : public poller_base_t - { - public: - - typedef fd_t handle_t; - - poll_t (const ctx_t &ctx_); - ~poll_t (); - - // "poller" concept. - handle_t add_fd (fd_t fd_, zmq::i_poll_events *events_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void start (); - void stop (); - - static int max_fds (); - - private: - - // Main worker thread routine. - static void worker_routine (void *arg_); - - // Main event loop. - void loop (); - - // Reference to ZMQ context. - const ctx_t &ctx; - - struct fd_entry_t - { - fd_t index; - zmq::i_poll_events *events; - }; - - // This table stores data for registered descriptors. - typedef std::vector fd_table_t; - fd_table_t fd_table; - - // Pollset to pass to the poll function. - typedef std::vector pollset_t; - pollset_t pollset; - - // If true, there's at least one retired event source. - bool retired; - - // If true, thread is in the process of shutting down. - bool stopping; - - // Handle of the physical thread doing the I/O work. - thread_t worker; - - poll_t (const poll_t&); - const poll_t &operator = (const poll_t&); - }; - - typedef poll_t poller_t; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/poller.hpp b/dep/libzmq/src/poller.hpp deleted file mode 100644 index 42c6db411d..0000000000 --- a/dep/libzmq/src/poller.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_POLLER_HPP_INCLUDED__ -#define __ZMQ_POLLER_HPP_INCLUDED__ - -#if defined ZMQ_USE_KQUEUE + defined ZMQ_USE_EPOLL \ - + defined ZMQ_USE_DEVPOLL + defined ZMQ_USE_POLLSET \ - + defined ZMQ_USE_POLL + defined ZMQ_USE_SELECT > 1 -#error More than one of the ZMQ_USE_* macros defined -#endif - -#if defined ZMQ_USE_KQUEUE -# include "kqueue.hpp" -#elif defined ZMQ_USE_EPOLL -# include "epoll.hpp" -#elif defined ZMQ_USE_DEVPOLL -# include "devpoll.hpp" -#elif defined ZMQ_USE_POLLSET -# include "pollset.hpp" -#elif defined ZMQ_USE_POLL -# include "poll.hpp" -#elif defined ZMQ_USE_SELECT -# include "select.hpp" -#elif defined ZMQ_HAVE_GNU -# define ZMQ_USE_POLL -# include "poll.hpp" -#else -# error None of the ZMQ_USE_* macros defined -#endif - -#if defined ZMQ_USE_SELECT -#define ZMQ_POLL_BASED_ON_SELECT -#else -#define ZMQ_POLL_BASED_ON_POLL -#endif - -#endif diff --git a/dep/libzmq/src/poller_base.cpp b/dep/libzmq/src/poller_base.cpp deleted file mode 100644 index 50c540c302..0000000000 --- a/dep/libzmq/src/poller_base.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "poller_base.hpp" -#include "i_poll_events.hpp" -#include "err.hpp" - -zmq::poller_base_t::poller_base_t () -{ -} - -zmq::poller_base_t::~poller_base_t () -{ - // Make sure there is no more load on the shutdown. - zmq_assert (get_load () == 0); -} - -int zmq::poller_base_t::get_load () -{ - return load.get (); -} - -void zmq::poller_base_t::adjust_load (int amount_) -{ - if (amount_ > 0) - load.add (amount_); - else - if (amount_ < 0) - load.sub (-amount_); -} - -void zmq::poller_base_t::add_timer (int timeout_, i_poll_events *sink_, int id_) -{ - uint64_t expiration = clock.now_ms () + timeout_; - timer_info_t info = {sink_, id_}; - timers.insert (timers_t::value_type (expiration, info)); -} - -void zmq::poller_base_t::cancel_timer (i_poll_events *sink_, int id_) -{ - // Complexity of this operation is O(n). We assume it is rarely used. - for (timers_t::iterator it = timers.begin (); it != timers.end (); ++it) - if (it->second.sink == sink_ && it->second.id == id_) { - timers.erase (it); - return; - } - - // Timer not found. - zmq_assert (false); -} - -uint64_t zmq::poller_base_t::execute_timers () -{ - // Fast track. - if (timers.empty ()) - return 0; - - // Get the current time. - uint64_t current = clock.now_ms (); - - // Execute the timers that are already due. - timers_t::iterator it = timers.begin (); - while (it != timers.end ()) { - - // If we have to wait to execute the item, same will be true about - // all the following items (multimap is sorted). Thus we can stop - // checking the subsequent timers and return the time to wait for - // the next timer (at least 1ms). - if (it->first > current) - return it->first - current; - - // Trigger the timer. - it->second.sink->timer_event (it->second.id); - - // Remove it from the list of active timers. - timers_t::iterator o = it; - ++it; - timers.erase (o); - } - - // There are no more timers. - return 0; -} diff --git a/dep/libzmq/src/poller_base.hpp b/dep/libzmq/src/poller_base.hpp deleted file mode 100644 index 4f1195c368..0000000000 --- a/dep/libzmq/src/poller_base.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_POLLER_BASE_HPP_INCLUDED__ -#define __ZMQ_POLLER_BASE_HPP_INCLUDED__ - -#include - -#include "clock.hpp" -#include "atomic_counter.hpp" - -namespace zmq -{ - - struct i_poll_events; - - class poller_base_t - { - public: - - poller_base_t (); - virtual ~poller_base_t (); - - // Returns load of the poller. Note that this function can be - // invoked from a different thread! - int get_load (); - - // Add a timeout to expire in timeout_ milliseconds. After the - // expiration timer_event on sink_ object will be called with - // argument set to id_. - void add_timer (int timeout_, zmq::i_poll_events *sink_, int id_); - - // Cancel the timer created by sink_ object with ID equal to id_. - void cancel_timer (zmq::i_poll_events *sink_, int id_); - - protected: - - // Called by individual poller implementations to manage the load. - void adjust_load (int amount_); - - // Executes any timers that are due. Returns number of milliseconds - // to wait to match the next timer or 0 meaning "no timers". - uint64_t execute_timers (); - - private: - - // Clock instance private to this I/O thread. - clock_t clock; - - // List of active timers. - struct timer_info_t - { - zmq::i_poll_events *sink; - int id; - }; - typedef std::multimap timers_t; - timers_t timers; - - // Load of the poller. Currently the number of file descriptors - // registered. - atomic_counter_t load; - - poller_base_t (const poller_base_t&); - const poller_base_t &operator = (const poller_base_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/pollset.cpp b/dep/libzmq/src/pollset.cpp deleted file mode 100644 index f08b34b44e..0000000000 --- a/dep/libzmq/src/pollset.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "pollset.hpp" -#if defined ZMQ_USE_POLLSET - -#include -#include -#include -#include -#include - -#include "macros.hpp" -#include "err.hpp" -#include "config.hpp" -#include "i_poll_events.hpp" - -zmq::pollset_t::pollset_t (const zmq::ctx_t &ctx_) : - ctx(ctx_), - stopping (false) -{ - pollset_fd = pollset_create (-1); - errno_assert (pollset_fd != -1); -} - -zmq::pollset_t::~pollset_t () -{ - // Wait till the worker thread exits. - worker.stop (); - - pollset_destroy (pollset_fd); - for (retired_t::iterator it = retired.begin (); it != retired.end (); ++it) - LIBZMQ_DELETE(*it); -} - -zmq::pollset_t::handle_t zmq::pollset_t::add_fd (fd_t fd_, i_poll_events *events_) -{ - poll_entry_t *pe = new (std::nothrow) poll_entry_t; - alloc_assert (pe); - - pe->fd = fd_; - pe->flag_pollin = false; - pe->flag_pollout = false; - pe->events = events_; - - struct poll_ctl pc; - pc.fd = fd_; - pc.cmd = PS_ADD; - pc.events = 0; - - int rc = pollset_ctl (pollset_fd, &pc, 1); - errno_assert (rc != -1); - - // Increase the load metric of the thread. - adjust_load (1); - - if (fd_ >= fd_table.size ()) { - fd_table.resize(fd_ + 1, NULL); - } - fd_table [fd_] = pe; - return pe; -} - -void zmq::pollset_t::rm_fd (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - - struct poll_ctl pc; - pc.fd = pe->fd; - pc.cmd = PS_DELETE; - pc.events = 0; - pollset_ctl (pollset_fd, &pc, 1); - - fd_table [pe->fd] = NULL; - - pe->fd = retired_fd; - retired.push_back (pe); - - // Decrease the load metric of the thread. - adjust_load (-1); -} - -void zmq::pollset_t::set_pollin (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (likely (!pe->flag_pollin)) { - struct poll_ctl pc; - pc.fd = pe->fd; - pc.cmd = PS_MOD; - pc.events = POLLIN; - - const int rc = pollset_ctl (pollset_fd, &pc, 1); - errno_assert (rc != -1); - - pe->flag_pollin = true; - } -} - -void zmq::pollset_t::reset_pollin (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (unlikely(!pe->flag_pollin)) { - return; - } - - struct poll_ctl pc; - pc.fd = pe->fd; - pc.events = 0; - - pc.cmd = PS_DELETE; - int rc = pollset_ctl (pollset_fd, &pc, 1); - - if (pe->flag_pollout) { - pc.events = POLLOUT; - pc.cmd = PS_MOD; - rc = pollset_ctl (pollset_fd, &pc, 1); - errno_assert (rc != -1); - } - - pe->flag_pollin = false; -} - -void zmq::pollset_t::set_pollout (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (likely (!pe->flag_pollout)) { - struct poll_ctl pc; - pc.fd = pe->fd; - pc.cmd = PS_MOD; - pc.events = POLLOUT; - - const int rc = pollset_ctl (pollset_fd, &pc, 1); - errno_assert (rc != -1); - - pe->flag_pollout = true; - } -} - -void zmq::pollset_t::reset_pollout (handle_t handle_) -{ - poll_entry_t *pe = (poll_entry_t*) handle_; - if (unlikely(!pe->flag_pollout)) { - return; - } - - struct poll_ctl pc; - pc.fd = pe->fd; - pc.events = 0; - - pc.cmd = PS_DELETE; - int rc = pollset_ctl (pollset_fd, &pc, 1); - errno_assert (rc != -1); - - if (pe->flag_pollin) { - pc.cmd = PS_MOD; - pc.events = POLLIN; - rc = pollset_ctl (pollset_fd, &pc, 1); - errno_assert (rc != -1); - } - pe->flag_pollout = false; -} - -void zmq::pollset_t::start () -{ - ctx.start_thread (worker, worker_routine, this); -} - -void zmq::pollset_t::stop () -{ - stopping = true; -} - -int zmq::pollset_t::max_fds () -{ - return -1; -} - -void zmq::pollset_t::loop () -{ - struct pollfd polldata_array[max_io_events]; - - while (!stopping) { - - // Execute any due timers. - int timeout = (int) execute_timers (); - - // Wait for events. - int n = pollset_poll(pollset_fd, polldata_array, max_io_events, - timeout ? timeout : -1); - if (n == -1) { - errno_assert (errno == EINTR); - continue; - } - - for (int i = 0; i < n; i ++) { - poll_entry_t *pe = fd_table [polldata_array [i].fd]; - if (!pe) - continue; - - if (pe->fd == retired_fd) - continue; - if (polldata_array [i].revents & (POLLERR | POLLHUP)) - pe->events->in_event (); - if (pe->fd == retired_fd) - continue; - if (polldata_array [i].revents & POLLOUT) - pe->events->out_event (); - if (pe->fd == retired_fd) - continue; - if (polldata_array [i].revents & POLLIN) - pe->events->in_event (); - } - - // Destroy retired event sources. - for (retired_t::iterator it = retired.begin (); it != retired.end (); - ++it) - LIBZMQ_DELETE(*it); - retired.clear (); - } -} - -void zmq::pollset_t::worker_routine (void *arg_) -{ - ((pollset_t*) arg_)->loop (); -} - -#endif diff --git a/dep/libzmq/src/pollset.hpp b/dep/libzmq/src/pollset.hpp deleted file mode 100644 index 9ce333caeb..0000000000 --- a/dep/libzmq/src/pollset.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_POLLSET_HPP_INCLUDED__ -#define __ZMQ_POLLSET_HPP_INCLUDED__ - -// poller.hpp decides which polling mechanism to use. -#include "poller.hpp" -#if defined ZMQ_USE_POLLSET - -#include -#include -#include - -#include "ctx.hpp" -#include "fd.hpp" -#include "thread.hpp" -#include "poller_base.hpp" - -namespace zmq -{ - - struct i_poll_events; - - // This class implements socket polling mechanism using the AIX-specific - // pollset mechanism. - - class pollset_t : public poller_base_t - { - public: - - typedef void* handle_t; - - pollset_t (const ctx_t &ctx_); - ~pollset_t (); - - // "poller" concept. - handle_t add_fd (fd_t fd_, zmq::i_poll_events *events_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void start (); - void stop (); - - static int max_fds (); - - private: - - // Main worker thread routine. - static void worker_routine (void *arg_); - - // Main event loop. - void loop (); - - // Reference to ZMQ context. - const ctx_t &ctx; - - // Main pollset file descriptor - ::pollset_t pollset_fd; - - struct poll_entry_t - { - fd_t fd; - bool flag_pollin; - bool flag_pollout; - zmq::i_poll_events *events; - }; - - // List of retired event sources. - typedef std::vector retired_t; - retired_t retired; - - // This table stores data for registered descriptors. - typedef std::vector fd_table_t; - fd_table_t fd_table; - - // If true, thread is in the process of shutting down. - bool stopping; - - // Handle of the physical thread doing the I/O work. - thread_t worker; - - pollset_t (const pollset_t&); - const pollset_t &operator = (const pollset_t&); - }; - - typedef pollset_t poller_t; - -} - -#endif - -#endif diff --git a/dep/libzmq/src/precompiled.hpp b/dep/libzmq/src/precompiled.hpp deleted file mode 100644 index dc0bc36ed9..0000000000 --- a/dep/libzmq/src/precompiled.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PRECOMPILED_HPP_INCLUDED__ -#define __ZMQ_PRECOMPILED_HPP_INCLUDED__ - -#include "platform.hpp" - -#define __STDC_LIMIT_MACROS - -// This must be included before any windows headers are compiled. -#if defined ZMQ_HAVE_WINDOWS -#include "windows.hpp" -#endif - -// 0MQ definitions and exported functions -#include "../include/zmq.h" - -// 0MQ DRAFT definitions and exported functions -#include "zmq_draft.h" - -// TODO: expand pch implementation to non-windows builds. -#ifdef _MSC_VER - -// standard C headers -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// standard C++ headers -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if _MSC_VER >= 1800 -#include -#endif - -#if _MSC_VER >= 1700 -#include -#endif - -#if defined _WIN32_WCE -#include -#else -#include -#endif - -#if defined HAVE_LIBGSSAPI_KRB5 -#include "err.hpp" -#include "msg.hpp" -#include "mechanism.hpp" -#include "session_base.hpp" -#include "gssapi_server.hpp" -#include "wire.hpp" -#include -#include -#endif - -#include "options.hpp" - -#endif // _MSC_VER - -#endif //ifndef __ZMQ_PRECOMPILED_HPP_INCLUDED__ diff --git a/dep/libzmq/src/proxy.cpp b/dep/libzmq/src/proxy.cpp deleted file mode 100644 index 32ff9cfd43..0000000000 --- a/dep/libzmq/src/proxy.cpp +++ /dev/null @@ -1,622 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -// On AIX platform, poll.h has to be included first to get consistent -// definition of pollfd structure (AIX uses 'reqevents' and 'retnevents' -// instead of 'events' and 'revents' and defines macros to map from POSIX-y -// names to AIX-specific names). -// zmq.h must be included *after* poll.h for AIX to build properly. -// precompiled.hpp includes include/zmq.h -#if defined ZMQ_POLL_BASED_ON_POLL && defined ZMQ_HAVE_AIX -#include -#endif - -#include "precompiled.hpp" -#include -#include "poller.hpp" -#include "proxy.hpp" -#include "likely.hpp" - -#if defined ZMQ_POLL_BASED_ON_POLL && !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_AIX -#include -#endif - -// These headers end up pulling in zmq.h somewhere in their include -// dependency chain -#include "socket_base.hpp" -#include "err.hpp" - -#ifdef ZMQ_HAVE_POLLER - -#include "socket_poller.hpp" - -// Macros for repetitive code. - -// PROXY_CLEANUP() must not be used before these variables are initialized. -#define PROXY_CLEANUP()\ - do {\ - delete poller_all;\ - delete poller_in;\ - delete poller_control;\ - delete poller_receive_blocked;\ - delete poller_send_blocked;\ - delete poller_both_blocked;\ - delete poller_frontend_only;\ - delete poller_backend_only;\ - } while (false) - - -#define CHECK_RC_EXIT_ON_FAILURE()\ - do {\ - if (rc < 0) {\ - PROXY_CLEANUP();\ - return close_and_return (&msg, -1);\ - }\ - } while (false) - -#endif // ZMQ_HAVE_POLLER - - -// Control socket messages - -typedef struct -{ - uint64_t msg_in; - uint64_t bytes_in; - uint64_t msg_out; - uint64_t bytes_out; -} zmq_socket_stats_t; - - - -// Utility functions - -int capture ( - class zmq::socket_base_t *capture_, - zmq::msg_t& msg_, - int more_ = 0) -{ - // Copy message to capture socket if any - if (capture_) { - zmq::msg_t ctrl; - int rc = ctrl.init (); - if (unlikely (rc < 0)) - return -1; - rc = ctrl.copy (msg_); - if (unlikely (rc < 0)) - return -1; - rc = capture_->send (&ctrl, more_ ? ZMQ_SNDMORE : 0); - if (unlikely (rc < 0)) - return -1; - } - return 0; -} - -int forward ( - class zmq::socket_base_t *from_, zmq_socket_stats_t* from_stats, - class zmq::socket_base_t *to_, zmq_socket_stats_t* to_stats, - class zmq::socket_base_t *capture_, - zmq::msg_t& msg_) -{ - int more; - size_t moresz; - size_t complete_msg_size = 0; - while (true) { - int rc = from_->recv (&msg_, 0); - if (unlikely (rc < 0)) - return -1; - - complete_msg_size += msg_.size(); - - moresz = sizeof more; - rc = from_->getsockopt (ZMQ_RCVMORE, &more, &moresz); - if (unlikely (rc < 0)) - return -1; - - // Copy message to capture socket if any - rc = capture (capture_, msg_, more); - if (unlikely (rc < 0)) - return -1; - - rc = to_->send (&msg_, more ? ZMQ_SNDMORE : 0); - if (unlikely (rc < 0)) - return -1; - - if (more == 0) - break; - } - - // A multipart message counts as 1 packet: - from_stats->msg_in++; - from_stats->bytes_in += complete_msg_size; - to_stats->msg_out++; - to_stats->bytes_out += complete_msg_size; - - return 0; -} - -static int loop_and_send_multipart_stat (zmq::socket_base_t *control_, - uint64_t stat, bool first, bool more) -{ - int rc; - zmq::msg_t msg; - - // VSM of 8 bytes can't fail to init - msg.init_size (sizeof (uint64_t)); - memcpy (msg.data (), (const void *)&stat, sizeof (uint64_t)); - - // if the first message is handed to the pipe successfully then the HWM - // is not full, which means failures are due to interrupts (on Windows pipes - // are TCP sockets), so keep retrying - do { - rc = control_->send (&msg, more ? ZMQ_SNDMORE : 0); - } while (!first && rc != 0 && errno == EAGAIN); - - return rc; -} - -int reply_stats( - class zmq::socket_base_t *control_, - zmq_socket_stats_t* frontend_stats, - zmq_socket_stats_t* backend_stats) -{ - // first part: frontend stats - the first send might fail due to HWM - if (loop_and_send_multipart_stat (control_, frontend_stats->msg_in, true, true) != 0) - return -1; - - loop_and_send_multipart_stat (control_, frontend_stats->bytes_in, false, true); - loop_and_send_multipart_stat (control_, frontend_stats->msg_out, false, true); - loop_and_send_multipart_stat (control_, frontend_stats->bytes_out, false, true); - - // second part: backend stats - loop_and_send_multipart_stat (control_, backend_stats->msg_in, false, true); - loop_and_send_multipart_stat (control_, backend_stats->bytes_in, false, true); - loop_and_send_multipart_stat (control_, backend_stats->msg_out, false, true); - loop_and_send_multipart_stat (control_, backend_stats->bytes_out, false, false); - - return 0; -} - - -#ifdef ZMQ_HAVE_POLLER - -int zmq::proxy ( - class socket_base_t *frontend_, - class socket_base_t *backend_, - class socket_base_t *capture_, - class socket_base_t *control_) -{ - msg_t msg; - int rc = msg.init (); - if (rc != 0) - return -1; - - // The algorithm below assumes ratio of requests and replies processed - // under full load to be 1:1. - - int more; - size_t moresz = sizeof (more); - - // Proxy can be in these three states - enum { - active, - paused, - terminated - } state = active; - - bool frontend_equal_to_backend; - bool frontend_in = false; - bool frontend_out = false; - bool backend_in = false; - bool backend_out = false; - bool control_in = false; - zmq::socket_poller_t::event_t events [3]; - zmq_socket_stats_t frontend_stats; - zmq_socket_stats_t backend_stats; - memset(&frontend_stats, 0, sizeof(frontend_stats)); - memset(&backend_stats, 0, sizeof(backend_stats)); - - // Don't allocate these pollers from stack because they will take more than 900 kB of stack! - // On Windows this blows up default stack of 1 MB and aborts the program. - // I wanted to use std::shared_ptr here as the best solution but that requires C++11... - zmq::socket_poller_t *poller_all = new (std::nothrow) zmq::socket_poller_t; // Poll for everything. - zmq::socket_poller_t *poller_in = new (std::nothrow) zmq::socket_poller_t; // Poll only 'ZMQ_POLLIN' on all sockets. Initial blocking poll in loop. - zmq::socket_poller_t *poller_control = new (std::nothrow) zmq::socket_poller_t; // Poll only for 'ZMQ_POLLIN' on 'control_', when proxy is paused. - zmq::socket_poller_t *poller_receive_blocked = new (std::nothrow) zmq::socket_poller_t; // All except 'ZMQ_POLLIN' on 'frontend_'. - - // If frontend_==backend_ 'poller_send_blocked' and 'poller_receive_blocked' are the same, 'ZMQ_POLLIN' is ignored. - // In that case 'poller_send_blocked' is not used. We need only 'poller_receive_blocked'. - // We also don't need 'poller_both_blocked', 'poller_backend_only' nor 'poller_frontend_only' no need to initialize it. - // We save some RAM and time for initialization. - zmq::socket_poller_t *poller_send_blocked = NULL; // All except 'ZMQ_POLLIN' on 'backend_'. - zmq::socket_poller_t *poller_both_blocked = NULL; // All except 'ZMQ_POLLIN' on both 'frontend_' and 'backend_'. - zmq::socket_poller_t *poller_frontend_only = NULL; // Only 'ZMQ_POLLIN' and 'ZMQ_POLLOUT' on 'frontend_'. - zmq::socket_poller_t *poller_backend_only = NULL; // Only 'ZMQ_POLLIN' and 'ZMQ_POLLOUT' on 'backend_'. - - if (frontend_ != backend_) { - poller_send_blocked = new (std::nothrow) zmq::socket_poller_t; // All except 'ZMQ_POLLIN' on 'backend_'. - poller_both_blocked = new (std::nothrow) zmq::socket_poller_t; // All except 'ZMQ_POLLIN' on both 'frontend_' and 'backend_'. - poller_frontend_only = new (std::nothrow) zmq::socket_poller_t; // Only 'ZMQ_POLLIN' and 'ZMQ_POLLOUT' on 'frontend_'. - poller_backend_only = new (std::nothrow) zmq::socket_poller_t; // Only 'ZMQ_POLLIN' and 'ZMQ_POLLOUT' on 'backend_'. - frontend_equal_to_backend = false; - } else - frontend_equal_to_backend = true; - - if (poller_all == NULL || poller_in == NULL || poller_control == NULL || poller_receive_blocked == NULL - || ((poller_send_blocked == NULL || poller_both_blocked == NULL) && !frontend_equal_to_backend)) { - PROXY_CLEANUP (); - return close_and_return (&msg, -1); - } - - zmq::socket_poller_t *poller_wait = poller_in; // Poller for blocking wait, initially all 'ZMQ_POLLIN'. - - // Register 'frontend_' and 'backend_' with pollers. - rc = poller_all->add (frontend_, NULL, ZMQ_POLLIN | ZMQ_POLLOUT); // Everything. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_in->add (frontend_, NULL, ZMQ_POLLIN); // All 'ZMQ_POLLIN's. - CHECK_RC_EXIT_ON_FAILURE (); - - if (frontend_equal_to_backend) { - // If frontend_==backend_ 'poller_send_blocked' and 'poller_receive_blocked' are the same, - // so we don't need 'poller_send_blocked'. We need only 'poller_receive_blocked'. - // We also don't need 'poller_both_blocked', no need to initialize it. - rc = poller_receive_blocked->add (frontend_, NULL, ZMQ_POLLOUT); - CHECK_RC_EXIT_ON_FAILURE (); - } else { - rc = poller_all->add (backend_, NULL, ZMQ_POLLIN | ZMQ_POLLOUT); // Everything. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_in->add (backend_, NULL, ZMQ_POLLIN); // All 'ZMQ_POLLIN's. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_both_blocked->add (frontend_, NULL, ZMQ_POLLOUT); // Waiting only for 'ZMQ_POLLOUT'. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_both_blocked->add (backend_, NULL, ZMQ_POLLOUT); // Waiting only for 'ZMQ_POLLOUT'. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_send_blocked->add (backend_, NULL, ZMQ_POLLOUT); // All except 'ZMQ_POLLIN' on 'backend_'. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_send_blocked->add (frontend_, NULL, ZMQ_POLLIN | ZMQ_POLLOUT); // All except 'ZMQ_POLLIN' on 'backend_'. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_receive_blocked->add (frontend_, NULL, ZMQ_POLLOUT); // All except 'ZMQ_POLLIN' on 'frontend_'. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_receive_blocked->add (backend_, NULL, ZMQ_POLLIN | ZMQ_POLLOUT); // All except 'ZMQ_POLLIN' on 'frontend_'. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_frontend_only->add (frontend_, NULL, ZMQ_POLLIN | ZMQ_POLLOUT); - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_backend_only->add (backend_, NULL, ZMQ_POLLIN | ZMQ_POLLOUT); - CHECK_RC_EXIT_ON_FAILURE (); - } - - // Register 'control_' with pollers. - if (control_ != NULL) { - rc = poller_all->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_in->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_control->add (control_, NULL, ZMQ_POLLIN); // When proxy is paused we wait only for ZMQ_POLLIN on 'control_' socket. - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_receive_blocked->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - if (!frontend_equal_to_backend) { - rc = poller_send_blocked->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_both_blocked->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_frontend_only->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - rc = poller_backend_only->add (control_, NULL, ZMQ_POLLIN); - CHECK_RC_EXIT_ON_FAILURE (); - } - } - - - int i; - bool request_processed, reply_processed; - - - while (state != terminated) { - - // Blocking wait initially only for 'ZMQ_POLLIN' - 'poller_wait' points to 'poller_in'. - // If one of receiving end's queue is full ('ZMQ_POLLOUT' not available), - // 'poller_wait' is pointed to 'poller_receive_blocked', 'poller_send_blocked' or 'poller_both_blocked'. - rc = poller_wait->wait (events, 3, -1); - if (rc < 0 && errno == EAGAIN) - rc = 0; - CHECK_RC_EXIT_ON_FAILURE (); - - // Some of events waited for by 'poller_wait' have arrived, now poll for everything without blocking. - rc = poller_all->wait (events, 3, 0); - if (rc < 0 && errno == EAGAIN) - rc = 0; - CHECK_RC_EXIT_ON_FAILURE (); - - // Process events. - for (i = 0; i < rc; i++) { - if (events [i].socket == frontend_) { - frontend_in = (events [i].events & ZMQ_POLLIN) != 0; - frontend_out = (events [i].events & ZMQ_POLLOUT) != 0; - } else - // This 'if' needs to be after check for 'frontend_' in order never - // to be reached in case frontend_==backend_, so we ensure backend_in=false in that case. - if (events [i].socket == backend_) { - backend_in = (events [i].events & ZMQ_POLLIN) != 0; - backend_out = (events [i].events & ZMQ_POLLOUT) != 0; - } else - if (events [i].socket == control_) - control_in = (events [i].events & ZMQ_POLLIN) != 0; - } - - - // Process a control command if any. - if (control_in) { - rc = control_->recv (&msg, 0); - CHECK_RC_EXIT_ON_FAILURE (); - rc = control_->getsockopt (ZMQ_RCVMORE, &more, &moresz); - if (unlikely (rc < 0) || more) { - PROXY_CLEANUP (); - return close_and_return (&msg, -1); - } - - // Copy message to capture socket if any. - rc = capture (capture_, msg); - CHECK_RC_EXIT_ON_FAILURE (); - - if (msg.size () == 5 && memcmp (msg.data (), "PAUSE", 5) == 0) { - state = paused; - poller_wait = poller_control; - } else - if (msg.size () == 6 && memcmp (msg.data (), "RESUME", 6) == 0) { - state = active; - poller_wait = poller_in; - } else { - if (msg.size () == 9 && memcmp (msg.data (), "TERMINATE", 9) == 0) - state = terminated; - else { -#ifdef ZMQ_BUILD_DRAFT_API - if (msg.size () == 10 && memcmp (msg.data (), "STATISTICS", 10) == 0) - { - rc = reply_stats(control_, &frontend_stats, &backend_stats); - CHECK_RC_EXIT_ON_FAILURE (); - } - else { -#endif - // This is an API error, we assert - puts ("E: invalid command sent to proxy"); - zmq_assert (false); -#ifdef ZMQ_BUILD_DRAFT_API - } -#endif - } - } - control_in = false; - } - - if (state == active) { - - // Process a request, 'ZMQ_POLLIN' on 'frontend_' and 'ZMQ_POLLOUT' on 'backend_'. - // In case of frontend_==backend_ there's no 'ZMQ_POLLOUT' event. - if (frontend_in && (backend_out || frontend_equal_to_backend)) { - rc = forward (frontend_, &frontend_stats, backend_, &backend_stats, capture_, msg); - CHECK_RC_EXIT_ON_FAILURE (); - request_processed = true; - frontend_in = backend_out = false; - } else request_processed = false; - - // Process a reply, 'ZMQ_POLLIN' on 'backend_' and 'ZMQ_POLLOUT' on 'frontend_'. - // If 'frontend_' and 'backend_' are the same this is not needed because previous processing - // covers all of the cases. 'backend_in' is always false if frontend_==backend_ due to - // design in 'for' event processing loop. - if (backend_in && frontend_out) { - rc = forward (backend_, &backend_stats, frontend_, &frontend_stats, capture_, msg); - CHECK_RC_EXIT_ON_FAILURE (); - reply_processed = true; - backend_in = frontend_out = false; - } else reply_processed = false; - - if (request_processed || reply_processed) { - // If request/reply is processed that means we had at least one 'ZMQ_POLLOUT' event. - // Enable corresponding 'ZMQ_POLLIN' for blocking wait if any was disabled. - if (poller_wait != poller_in) { - if (request_processed) { // 'frontend_' -> 'backend_' - if (poller_wait == poller_both_blocked) - poller_wait = poller_send_blocked; - else - if (poller_wait == poller_receive_blocked || poller_wait == poller_frontend_only) - poller_wait = poller_in; - } - if (reply_processed) { // 'backend_' -> 'frontend_' - if (poller_wait == poller_both_blocked) - poller_wait = poller_receive_blocked; - else - if (poller_wait == poller_send_blocked || poller_wait == poller_backend_only) - poller_wait = poller_in; - } - } - } else { - // No requests have been processed, there were no 'ZMQ_POLLIN' with corresponding 'ZMQ_POLLOUT' events. - // That means that out queue(s) is/are full or one out queue is full and second one has no messages to process. - // Disable receiving 'ZMQ_POLLIN' for sockets for which there's no 'ZMQ_POLLOUT', - // or wait only on both 'backend_''s or 'frontend_''s 'ZMQ_POLLIN' and 'ZMQ_POLLOUT'. - if (frontend_in) { - if (frontend_out) - // If frontend_in and frontend_out are true, obviously backend_in and backend_out are both false. - // In that case we need to wait for both 'ZMQ_POLLIN' and 'ZMQ_POLLOUT' only on 'backend_'. - // We'll never get here in case of frontend_==backend_ because then frontend_out will always be false. - poller_wait = poller_backend_only; - else { - if (poller_wait == poller_send_blocked) - poller_wait = poller_both_blocked; - else - if (poller_wait == poller_in) - poller_wait = poller_receive_blocked; - } - } - if (backend_in) { - // Will never be reached if frontend_==backend_, 'backend_in' will - // always be false due to design in 'for' event processing loop. - if (backend_out) - // If backend_in and backend_out are true, obviously frontend_in and frontend_out are both false. - // In that case we need to wait for both 'ZMQ_POLLIN' and 'ZMQ_POLLOUT' only on 'frontend_'. - poller_wait = poller_frontend_only; - else { - if (poller_wait == poller_receive_blocked) - poller_wait = poller_both_blocked; - else - if (poller_wait == poller_in) - poller_wait = poller_send_blocked; - } - } - } - - } - } - PROXY_CLEANUP (); - return close_and_return (&msg, 0); -} - -#else // ZMQ_HAVE_POLLER - -int zmq::proxy ( - class socket_base_t *frontend_, - class socket_base_t *backend_, - class socket_base_t *capture_, - class socket_base_t *control_) -{ - msg_t msg; - int rc = msg.init (); - if (rc != 0) - return -1; - - // The algorithm below assumes ratio of requests and replies processed - // under full load to be 1:1. - - int more; - size_t moresz; - zmq_pollitem_t items [] = { - { frontend_, 0, ZMQ_POLLIN, 0 }, - { backend_, 0, ZMQ_POLLIN, 0 }, - { control_, 0, ZMQ_POLLIN, 0 } - }; - int qt_poll_items = (control_ ? 3 : 2); - zmq_pollitem_t itemsout [] = { - { frontend_, 0, ZMQ_POLLOUT, 0 }, - { backend_, 0, ZMQ_POLLOUT, 0 } - }; - - zmq_socket_stats_t frontend_stats; - memset(&frontend_stats, 0, sizeof(frontend_stats)); - zmq_socket_stats_t backend_stats; - memset(&backend_stats, 0, sizeof(backend_stats)); - - // Proxy can be in these three states - enum { - active, - paused, - terminated - } state = active; - - while (state != terminated) { - // Wait while there are either requests or replies to process. - rc = zmq_poll (&items [0], qt_poll_items, -1); - if (unlikely (rc < 0)) - return close_and_return (&msg, -1); - - // Get the pollout separately because when combining this with pollin it maxes the CPU - // because pollout shall most of the time return directly. - // POLLOUT is only checked when frontend and backend sockets are not the same. - if (frontend_ != backend_) { - rc = zmq_poll (&itemsout [0], 2, 0); - if (unlikely (rc < 0)) { - return close_and_return (&msg, -1); - } - } - - // Process a control command if any - if (control_ && items [2].revents & ZMQ_POLLIN) { - rc = control_->recv (&msg, 0); - if (unlikely (rc < 0)) - return close_and_return (&msg, -1); - - moresz = sizeof more; - rc = control_->getsockopt (ZMQ_RCVMORE, &more, &moresz); - if (unlikely (rc < 0) || more) - return close_and_return (&msg, -1); - - // Copy message to capture socket if any - rc = capture (capture_, msg); - if (unlikely (rc < 0)) - return close_and_return (&msg, -1); - - if (msg.size () == 5 && memcmp (msg.data (), "PAUSE", 5) == 0) - state = paused; - else - if (msg.size () == 6 && memcmp (msg.data (), "RESUME", 6) == 0) - state = active; - else - if (msg.size () == 9 && memcmp (msg.data (), "TERMINATE", 9) == 0) - state = terminated; - else { -#ifdef ZMQ_BUILD_DRAFT_API - if (msg.size () == 10 && memcmp (msg.data (), "STATISTICS", 10) == 0) - { - rc = reply_stats(control_, &frontend_stats, &backend_stats); - if (unlikely (rc < 0)) - return close_and_return (&msg, -1); - } - else { -#endif - // This is an API error, we assert - puts ("E: invalid command sent to proxy"); - zmq_assert (false); -#ifdef ZMQ_BUILD_DRAFT_API - } -#endif - } - } - // Process a request - if (state == active - && items [0].revents & ZMQ_POLLIN - && (frontend_ == backend_ || itemsout [1].revents & ZMQ_POLLOUT)) { - rc = forward (frontend_, &frontend_stats, backend_, &backend_stats, capture_, msg); - if (unlikely (rc < 0)) - return close_and_return (&msg, -1); - } - // Process a reply - if (state == active - && frontend_ != backend_ - && items [1].revents & ZMQ_POLLIN - && itemsout [0].revents & ZMQ_POLLOUT) { - rc = forward (backend_, &backend_stats, frontend_, &frontend_stats, capture_, msg); - if (unlikely (rc < 0)) - return close_and_return (&msg, -1); - } - } - - return close_and_return (&msg, 0); -} - -#endif // ZMQ_HAVE_POLLER diff --git a/dep/libzmq/src/proxy.hpp b/dep/libzmq/src/proxy.hpp deleted file mode 100644 index de9416edd8..0000000000 --- a/dep/libzmq/src/proxy.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PROXY_HPP_INCLUDED__ -#define __ZMQ_PROXY_HPP_INCLUDED__ - -namespace zmq -{ - int proxy ( - class socket_base_t *frontend_, - class socket_base_t *backend_, - class socket_base_t *capture_, - class socket_base_t *control_ = NULL); // backward compatibility without this argument -} - -#endif diff --git a/dep/libzmq/src/pub.cpp b/dep/libzmq/src/pub.cpp deleted file mode 100644 index 303da068c7..0000000000 --- a/dep/libzmq/src/pub.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "pub.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::pub_t::pub_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - xpub_t (parent_, tid_, sid_) -{ - options.type = ZMQ_PUB; -} - -zmq::pub_t::~pub_t () -{ -} - -void zmq::pub_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - zmq_assert (pipe_); - - // Don't delay pipe termination as there is no one - // to receive the delimiter. - pipe_->set_nodelay (); - - xpub_t::xattach_pipe (pipe_, subscribe_to_all_); -} - -int zmq::pub_t::xrecv (class msg_t *) -{ - // Messages cannot be received from PUB socket. - errno = ENOTSUP; - return -1; -} - -bool zmq::pub_t::xhas_in () -{ - return false; -} diff --git a/dep/libzmq/src/pub.hpp b/dep/libzmq/src/pub.hpp deleted file mode 100644 index 2ba81134fa..0000000000 --- a/dep/libzmq/src/pub.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PUB_HPP_INCLUDED__ -#define __ZMQ_PUB_HPP_INCLUDED__ - -#include "xpub.hpp" - -namespace zmq -{ - - class ctx_t; - class io_thread_t; - class socket_base_t; - class msg_t; - - class pub_t : public xpub_t - { - public: - - pub_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~pub_t (); - - // Implementations of virtual functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_ = false); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - - private: - - pub_t (const pub_t&); - const pub_t &operator = (const pub_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/pull.cpp b/dep/libzmq/src/pull.cpp deleted file mode 100644 index 12620fab51..0000000000 --- a/dep/libzmq/src/pull.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "pull.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "pipe.hpp" - -zmq::pull_t::pull_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_) -{ - options.type = ZMQ_PULL; -} - -zmq::pull_t::~pull_t () -{ -} - -void zmq::pull_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - fq.attach (pipe_); -} - -void zmq::pull_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::pull_t::xpipe_terminated (pipe_t *pipe_) -{ - fq.pipe_terminated (pipe_); -} - -int zmq::pull_t::xrecv (msg_t *msg_) -{ - return fq.recv (msg_); -} - -bool zmq::pull_t::xhas_in () -{ - return fq.has_in (); -} - -const zmq::blob_t &zmq::pull_t::get_credential () const -{ - return fq.get_credential (); -} diff --git a/dep/libzmq/src/pull.hpp b/dep/libzmq/src/pull.hpp deleted file mode 100644 index 5677ed9800..0000000000 --- a/dep/libzmq/src/pull.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PULL_HPP_INCLUDED__ -#define __ZMQ_PULL_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "fq.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - class msg_t; - class io_thread_t; - - class pull_t : - public socket_base_t - { - public: - - pull_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~pull_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Fair queueing object for inbound pipes. - fq_t fq; - - pull_t (const pull_t&); - const pull_t &operator = (const pull_t&); - - }; - -} - -#endif diff --git a/dep/libzmq/src/push.cpp b/dep/libzmq/src/push.cpp deleted file mode 100644 index 0eb05cf70f..0000000000 --- a/dep/libzmq/src/push.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "push.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::push_t::push_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_) -{ - options.type = ZMQ_PUSH; -} - -zmq::push_t::~push_t () -{ -} - -void zmq::push_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - // Don't delay pipe termination as there is no one - // to receive the delimiter. - pipe_->set_nodelay (); - - zmq_assert (pipe_); - lb.attach (pipe_); -} - -void zmq::push_t::xwrite_activated (pipe_t *pipe_) -{ - lb.activated (pipe_); -} - -void zmq::push_t::xpipe_terminated (pipe_t *pipe_) -{ - lb.pipe_terminated (pipe_); -} - -int zmq::push_t::xsend (msg_t *msg_) -{ - return lb.send (msg_); -} - -bool zmq::push_t::xhas_out () -{ - return lb.has_out (); -} diff --git a/dep/libzmq/src/push.hpp b/dep/libzmq/src/push.hpp deleted file mode 100644 index d6289dfab3..0000000000 --- a/dep/libzmq/src/push.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_PUSH_HPP_INCLUDED__ -#define __ZMQ_PUSH_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "lb.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - class msg_t; - class io_thread_t; - - class push_t : - public socket_base_t - { - public: - - push_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~push_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Load balancer managing the outbound pipes. - lb_t lb; - - push_t (const push_t&); - const push_t &operator = (const push_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/radio.cpp b/dep/libzmq/src/radio.cpp deleted file mode 100644 index 3e2d192982..0000000000 --- a/dep/libzmq/src/radio.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "radio.hpp" -#include "macros.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::radio_t::radio_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_, true) -{ - options.type = ZMQ_RADIO; -} - -zmq::radio_t::~radio_t () -{ -} - -void zmq::radio_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - - // Don't delay pipe termination as there is no one - // to receive the delimiter. - pipe_->set_nodelay (); - - dist.attach (pipe_); - - if (subscribe_to_all_) - udp_pipes.push_back (pipe_); - // The pipe is active when attached. Let's read the subscriptions from - // it, if any. - else - xread_activated (pipe_); -} - -void zmq::radio_t::xread_activated (pipe_t *pipe_) -{ - // There are some subscriptions waiting. Let's process them. - msg_t msg; - while (pipe_->read (&msg)) { - // Apply the subscription to the trie - if (msg.is_join () || msg.is_leave ()) { - std::string group = std::string (msg.group ()); - - if (msg.is_join ()) - subscriptions.ZMQ_MAP_INSERT_OR_EMPLACE (ZMQ_MOVE(group), pipe_); - else { - std::pair range = - subscriptions.equal_range (group); - - for (subscriptions_t::iterator it = range.first; it != range.second; ++it) { - if (it->second == pipe_) { - subscriptions.erase (it); - break; - } - } - } - } - msg.close (); - } -} - -void zmq::radio_t::xwrite_activated (pipe_t *pipe_) -{ - dist.activated (pipe_); -} - -void zmq::radio_t::xpipe_terminated (pipe_t *pipe_) -{ - // NOTE: erase invalidates an iterator, and that's why it's not incrementing in post-loop - // read-after-free caught by Valgrind, see https://github.com/zeromq/libzmq/pull/1771 - for (subscriptions_t::iterator it = subscriptions.begin (); it != subscriptions.end (); ) { - if (it->second == pipe_) { - subscriptions.erase (it++); - } else { - ++it; - } - } - - udp_pipes_t::iterator it = std::find(udp_pipes.begin(), - udp_pipes.end (), pipe_); - if (it != udp_pipes.end ()) - udp_pipes.erase (it); - - dist.pipe_terminated (pipe_); -} - -int zmq::radio_t::xsend (msg_t *msg_) -{ - // Radio sockets do not allow multipart data (ZMQ_SNDMORE) - if (msg_->flags () & msg_t::more) { - errno = EINVAL; - return -1; - } - - dist.unmatch (); - - std::pair range = - subscriptions.equal_range (std::string(msg_->group ())); - - for (subscriptions_t::iterator it = range.first; it != range.second; ++it) - dist.match (it-> second); - - for (udp_pipes_t::iterator it = udp_pipes.begin (); it != udp_pipes.end (); ++it) - dist.match (*it); - - int rc = dist.send_to_matching (msg_); - - return rc; -} - -bool zmq::radio_t::xhas_out () -{ - return dist.has_out (); -} - -int zmq::radio_t::xrecv (msg_t *msg_) -{ - // Messages cannot be received from PUB socket. - LIBZMQ_UNUSED (msg_); - errno = ENOTSUP; - return -1; -} - -bool zmq::radio_t::xhas_in () -{ - return false; -} - -zmq::radio_session_t::radio_session_t (io_thread_t *io_thread_, bool connect_, - socket_base_t *socket_, const options_t &options_, - address_t *addr_) : - session_base_t (io_thread_, connect_, socket_, options_, addr_), - state (group) -{ -} - -zmq::radio_session_t::~radio_session_t () -{ -} - -int zmq::radio_session_t::push_msg (msg_t *msg_) -{ - if (msg_->flags() & msg_t::command) { - char *command_data = - static_cast (msg_->data ()); - const size_t data_size = msg_->size (); - - int group_length; - char * group; - - msg_t join_leave_msg; - int rc; - - // Set the msg type to either JOIN or LEAVE - if (data_size >= 5 && memcmp (command_data, "\4JOIN", 5) == 0) { - group_length = (int) data_size - 5; - group = command_data + 5; - rc = join_leave_msg.init_join (); - } - else if (data_size >= 6 && memcmp (command_data, "\5LEAVE", 6) == 0) { - group_length = (int) data_size - 6; - group = command_data + 6; - rc = join_leave_msg.init_leave (); - } - // If it is not a JOIN or LEAVE just push the message - else - return session_base_t::push_msg (msg_); - - errno_assert (rc == 0); - - // Set the group - rc = join_leave_msg.set_group (group, group_length); - errno_assert (rc == 0); - - // Close the current command - rc = msg_->close (); - errno_assert (rc == 0); - - // Push the join or leave command - *msg_ = join_leave_msg; - return session_base_t::push_msg (msg_); - } - else - return session_base_t::push_msg (msg_); -} - -int zmq::radio_session_t::pull_msg (msg_t *msg_) -{ - if (state == group) { - int rc = session_base_t::pull_msg (&pending_msg); - if (rc != 0) - return rc; - - const char *group = pending_msg.group (); - int length = (int) strlen (group); - - // First frame is the group - rc = msg_->init_size (length); - errno_assert(rc == 0); - msg_->set_flags(msg_t::more); - memcpy (msg_->data (), group, length); - - // Next status is the body - state = body; - return 0; - } - else { - *msg_ = pending_msg; - state = group; - return 0; - } -} - -void zmq::radio_session_t::reset () -{ - session_base_t::reset (); - state = group; -} diff --git a/dep/libzmq/src/radio.hpp b/dep/libzmq/src/radio.hpp deleted file mode 100644 index eb0dbf58fc..0000000000 --- a/dep/libzmq/src/radio.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_RADIO_HPP_INCLUDED__ -#define __ZMQ_RADIO_HPP_INCLUDED__ - -#include -#include -#include - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "mtrie.hpp" -#include "array.hpp" -#include "dist.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - class io_thread_t; - - class radio_t : - public socket_base_t - { - public: - - radio_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~radio_t (); - - // Implementations of virtual functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_ = false); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - // List of all subscriptions mapped to corresponding pipes. - typedef std::multimap subscriptions_t; - subscriptions_t subscriptions; - - // List of udp pipes - typedef std::vector udp_pipes_t; - udp_pipes_t udp_pipes; - - // Distributor of messages holding the list of outbound pipes. - dist_t dist; - - radio_t (const radio_t&); - const radio_t &operator = (const radio_t&); - }; - - class radio_session_t : public session_base_t - { - public: - - radio_session_t (zmq::io_thread_t *io_thread_, bool connect_, - zmq::socket_base_t *socket_, const options_t &options_, - address_t *addr_); - ~radio_session_t (); - - // Overrides of the functions from session_base_t. - int push_msg (msg_t *msg_); - int pull_msg (msg_t *msg_); - void reset (); - private: - - enum { - group, - body - } state; - - msg_t pending_msg; - - radio_session_t (const radio_session_t&); - const radio_session_t &operator = (const radio_session_t&); - }; -} - -#endif diff --git a/dep/libzmq/src/random.cpp b/dep/libzmq/src/random.cpp deleted file mode 100644 index 12fe33ce3c..0000000000 --- a/dep/libzmq/src/random.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#if !defined ZMQ_HAVE_WINDOWS -#include -#endif - -#include "random.hpp" -#include "stdint.hpp" -#include "clock.hpp" -#include "mutex.hpp" -#include "macros.hpp" - -#if defined (ZMQ_USE_TWEETNACL) -#include "tweetnacl.h" -#elif defined (ZMQ_USE_LIBSODIUM) -#include "sodium.h" -#endif - -void zmq::seed_random () -{ -#if defined ZMQ_HAVE_WINDOWS - int pid = (int) GetCurrentProcessId (); -#else - int pid = (int) getpid (); -#endif - srand ((unsigned int) (clock_t::now_us () + pid)); -} - -uint32_t zmq::generate_random () -{ - // Compensate for the fact that rand() returns signed integer. - uint32_t low = (uint32_t) rand (); - uint32_t high = (uint32_t) rand (); - high <<= (sizeof (int) * 8 - 1); - return high | low; -} - -// When different threads have their own context the file descriptor -// variable is shared and is subject to race conditions in tweetnacl, -// that lead to file descriptors leaks. In long-running programs with -// ephemeral threads this is a problem as it accumulates. -// thread-local storage cannot be used to initialise the file descriptor -// as it is perfectly legal to share a context among many threads, each -// of which might call curve APIs. -// Also libsodium documentation specifically states that sodium_init -// must not be called concurrently from multiple threads, for the -// same reason. Inspecting the code also reveals that the close API is -// not thread safe. -// The context class cannot be used with static variables as the curve -// utility APIs like zmq_curve_keypair also call into the crypto -// library. -// The safest solution for all use cases therefore is to have a global, -// static lock to serialize calls into an initialiser and a finaliser, -// using refcounts to make sure that a thread does not close the library -// while another is still using it. -static unsigned int random_refcount = 0; -static zmq::mutex_t random_sync; - -void zmq::random_open (void) -{ -#if defined (ZMQ_USE_LIBSODIUM) || \ - (defined (ZMQ_USE_TWEETNACL) && !defined (ZMQ_HAVE_WINDOWS) && !defined (ZMQ_HAVE_GETRANDOM)) - scoped_lock_t locker (random_sync); - - if (random_refcount == 0) { - int rc = sodium_init (); - zmq_assert (rc != -1); - } - - ++random_refcount; -#else - LIBZMQ_UNUSED (random_refcount); -#endif -} - -void zmq::random_close (void) -{ -#if defined (ZMQ_USE_LIBSODIUM) || \ - (defined (ZMQ_USE_TWEETNACL) && !defined (ZMQ_HAVE_WINDOWS) && !defined (ZMQ_HAVE_GETRANDOM)) - scoped_lock_t locker (random_sync); - --random_refcount; - - if (random_refcount == 0) { - randombytes_close (); - } -#endif -} - diff --git a/dep/libzmq/src/random.hpp b/dep/libzmq/src/random.hpp deleted file mode 100644 index 11d9cedb77..0000000000 --- a/dep/libzmq/src/random.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_RANDOM_HPP_INCLUDED__ -#define __ZMQ_RANDOM_HPP_INCLUDED__ - -#include "stdint.hpp" - -namespace zmq -{ - - // Seeds the random number generator. - void seed_random (); - - // Generates random value. - uint32_t generate_random (); - - // [De-]Initialise crypto library, if needed. - // Serialised and refcounted, so that it can be called - // from multiple threads, each with its own context, and from - // the various zmq_utils curve functions safely. - void random_open (); - void random_close (); -} - -#endif diff --git a/dep/libzmq/src/raw_decoder.cpp b/dep/libzmq/src/raw_decoder.cpp deleted file mode 100644 index b9a8d5c386..0000000000 --- a/dep/libzmq/src/raw_decoder.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "raw_decoder.hpp" -#include "err.hpp" - -zmq::raw_decoder_t::raw_decoder_t (size_t bufsize_) : - allocator( bufsize_, 1 ) -{ - int rc = in_progress.init (); - errno_assert (rc == 0); -} - -zmq::raw_decoder_t::~raw_decoder_t () -{ - int rc = in_progress.close (); - errno_assert (rc == 0); -} - -void zmq::raw_decoder_t::get_buffer (unsigned char **data_, size_t *size_) -{ - *data_ = allocator.allocate(); - *size_ = allocator.size(); -} - -int zmq::raw_decoder_t::decode (const uint8_t *data_, size_t size_, - size_t &bytes_used_) -{ - int rc = in_progress.init ((unsigned char*)data_, size_, - shared_message_memory_allocator::call_dec_ref, - allocator.buffer (), - allocator.provide_content ()); - - // if the buffer serves as memory for a zero-copy message, release it - // and allocate a new buffer in get_buffer for the next decode - if (in_progress.is_zcmsg ()) { - allocator.advance_content(); - allocator.release(); - } - - errno_assert (rc != -1); - bytes_used_ = size_; - return 1; -} diff --git a/dep/libzmq/src/raw_decoder.hpp b/dep/libzmq/src/raw_decoder.hpp deleted file mode 100644 index 5f08572eb3..0000000000 --- a/dep/libzmq/src/raw_decoder.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_RAW_DECODER_HPP_INCLUDED__ -#define __ZMQ_RAW_DECODER_HPP_INCLUDED__ - -#include "err.hpp" -#include "msg.hpp" -#include "i_decoder.hpp" -#include "stdint.hpp" -#include "decoder_allocators.hpp" - -namespace zmq -{ - - // Decoder for 0MQ v1 framing protocol. Converts data stream into messages. - - class raw_decoder_t : public i_decoder - { - public: - - raw_decoder_t (size_t bufsize_); - virtual ~raw_decoder_t (); - - // i_decoder interface. - - virtual void get_buffer (unsigned char **data_, size_t *size_); - - virtual int decode (const unsigned char *data_, size_t size_, - size_t &processed); - - virtual msg_t *msg () { return &in_progress; } - - virtual void resize_buffer(size_t) {} - - private: - msg_t in_progress; - - shared_message_memory_allocator allocator; - - raw_decoder_t (const raw_decoder_t&); - void operator = (const raw_decoder_t&); - }; - -} - -#endif - diff --git a/dep/libzmq/src/raw_encoder.cpp b/dep/libzmq/src/raw_encoder.cpp deleted file mode 100644 index ae35cb53de..0000000000 --- a/dep/libzmq/src/raw_encoder.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "encoder.hpp" -#include "raw_encoder.hpp" -#include "likely.hpp" -#include "wire.hpp" - -zmq::raw_encoder_t::raw_encoder_t (size_t bufsize_) : - encoder_base_t (bufsize_) -{ - // Write 0 bytes to the batch and go to message_ready state. - next_step (NULL, 0, &raw_encoder_t::raw_message_ready, true); -} - -zmq::raw_encoder_t::~raw_encoder_t () -{ -} - -void zmq::raw_encoder_t::raw_message_ready () -{ - next_step (in_progress->data (), in_progress->size (), - &raw_encoder_t::raw_message_ready, true); -} diff --git a/dep/libzmq/src/raw_encoder.hpp b/dep/libzmq/src/raw_encoder.hpp deleted file mode 100644 index f55e131c7b..0000000000 --- a/dep/libzmq/src/raw_encoder.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_RAW_ENCODER_HPP_INCLUDED__ -#define __ZMQ_RAW_ENCODER_HPP_INCLUDED__ - -#include -#include -#include -#include - -#include "err.hpp" -#include "msg.hpp" -#include "i_encoder.hpp" - -namespace zmq -{ - - // Encoder for 0MQ framing protocol. Converts messages into data batches. - - class raw_encoder_t : public encoder_base_t - { - public: - - raw_encoder_t (size_t bufsize_); - ~raw_encoder_t (); - - private: - - void raw_message_ready (); - - raw_encoder_t (const raw_encoder_t&); - const raw_encoder_t &operator = (const raw_encoder_t&); - }; -} - -#endif - diff --git a/dep/libzmq/src/reaper.cpp b/dep/libzmq/src/reaper.cpp deleted file mode 100644 index 82935b64b1..0000000000 --- a/dep/libzmq/src/reaper.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "reaper.hpp" -#include "socket_base.hpp" -#include "err.hpp" - -zmq::reaper_t::reaper_t (class ctx_t *ctx_, uint32_t tid_) : - object_t (ctx_, tid_), - mailbox_handle((poller_t::handle_t)NULL), - sockets (0), - terminating (false) -{ - poller = new (std::nothrow) poller_t (*ctx_); - alloc_assert (poller); - - if (mailbox.get_fd () != retired_fd) { - mailbox_handle = poller->add_fd (mailbox.get_fd (), this); - poller->set_pollin (mailbox_handle); - } - -#ifdef HAVE_FORK - pid = getpid(); -#endif -} - -zmq::reaper_t::~reaper_t () -{ - LIBZMQ_DELETE(poller); -} - -zmq::mailbox_t *zmq::reaper_t::get_mailbox () -{ - return &mailbox; -} - -void zmq::reaper_t::start () -{ - // Start the thread. - poller->start (); -} - -void zmq::reaper_t::stop () -{ - send_stop (); -} - -void zmq::reaper_t::in_event () -{ - while (true) { -#ifdef HAVE_FORK - if (unlikely(pid != getpid())) - { - //printf("zmq::reaper_t::in_event return in child process %d\n", (int)getpid()); - return; - } -#endif - - // Get the next command. If there is none, exit. - command_t cmd; - int rc = mailbox.recv (&cmd, 0); - if (rc != 0 && errno == EINTR) - continue; - if (rc != 0 && errno == EAGAIN) - break; - errno_assert (rc == 0); - - // Process the command. - cmd.destination->process_command (cmd); - } -} - -void zmq::reaper_t::out_event () -{ - zmq_assert (false); -} - -void zmq::reaper_t::timer_event (int) -{ - zmq_assert (false); -} - -void zmq::reaper_t::process_stop () -{ - terminating = true; - - // If there are no sockets being reaped finish immediately. - if (!sockets) { - send_done (); - poller->rm_fd (mailbox_handle); - poller->stop (); - } -} - -void zmq::reaper_t::process_reap (socket_base_t *socket_) -{ - // Add the socket to the poller. - socket_->start_reaping (poller); - - ++sockets; -} - -void zmq::reaper_t::process_reaped () -{ - --sockets; - - // If reaped was already asked to terminate and there are no more sockets, - // finish immediately. - if (!sockets && terminating) { - send_done (); - poller->rm_fd (mailbox_handle); - poller->stop (); - } -} diff --git a/dep/libzmq/src/reaper.hpp b/dep/libzmq/src/reaper.hpp deleted file mode 100644 index a1fbbc2271..0000000000 --- a/dep/libzmq/src/reaper.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_REAPER_HPP_INCLUDED__ -#define __ZMQ_REAPER_HPP_INCLUDED__ - -#include "object.hpp" -#include "mailbox.hpp" -#include "poller.hpp" -#include "i_poll_events.hpp" - -namespace zmq -{ - - class ctx_t; - class socket_base_t; - - class reaper_t : public object_t, public i_poll_events - { - public: - - reaper_t (zmq::ctx_t *ctx_, uint32_t tid_); - ~reaper_t (); - - mailbox_t *get_mailbox (); - - void start (); - void stop (); - - // i_poll_events implementation. - void in_event (); - void out_event (); - void timer_event (int id_); - - private: - - // Command handlers. - void process_stop (); - void process_reap (zmq::socket_base_t *socket_); - void process_reaped (); - - // Reaper thread accesses incoming commands via this mailbox. - mailbox_t mailbox; - - // Handle associated with mailbox' file descriptor. - poller_t::handle_t mailbox_handle; - - // I/O multiplexing is performed using a poller object. - poller_t *poller; - - // Number of sockets being reaped at the moment. - int sockets; - - // If true, we were already asked to terminate. - bool terminating; - - reaper_t (const reaper_t&); - const reaper_t &operator = (const reaper_t&); - -#ifdef HAVE_FORK - // the process that created this context. Used to detect forking. - pid_t pid; -#endif - }; - -} - -#endif diff --git a/dep/libzmq/src/rep.cpp b/dep/libzmq/src/rep.cpp deleted file mode 100644 index b3a41bfabb..0000000000 --- a/dep/libzmq/src/rep.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "rep.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::rep_t::rep_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - router_t (parent_, tid_, sid_), - sending_reply (false), - request_begins (true) -{ - options.type = ZMQ_REP; -} - -zmq::rep_t::~rep_t () -{ -} - -int zmq::rep_t::xsend (msg_t *msg_) -{ - // If we are in the middle of receiving a request, we cannot send reply. - if (!sending_reply) { - errno = EFSM; - return -1; - } - - bool more = msg_->flags () & msg_t::more ? true : false; - - // Push message to the reply pipe. - int rc = router_t::xsend (msg_); - if (rc != 0) - return rc; - - // If the reply is complete flip the FSM back to request receiving state. - if (!more) - sending_reply = false; - - return 0; -} - -int zmq::rep_t::xrecv (msg_t *msg_) -{ - // If we are in middle of sending a reply, we cannot receive next request. - if (sending_reply) { - errno = EFSM; - return -1; - } - - // First thing to do when receiving a request is to copy all the labels - // to the reply pipe. - if (request_begins) { - while (true) { - int rc = router_t::xrecv (msg_); - if (rc != 0) - return rc; - - if ((msg_->flags () & msg_t::more)) { - // Empty message part delimits the traceback stack. - bool bottom = (msg_->size () == 0); - - // Push it to the reply pipe. - rc = router_t::xsend (msg_); - errno_assert (rc == 0); - - if (bottom) - break; - } - else { - // If the traceback stack is malformed, discard anything - // already sent to pipe (we're at end of invalid message). - rc = router_t::rollback (); - errno_assert (rc == 0); - } - } - request_begins = false; - } - - // Get next message part to return to the user. - int rc = router_t::xrecv (msg_); - if (rc != 0) - return rc; - - // If whole request is read, flip the FSM to reply-sending state. - if (!(msg_->flags () & msg_t::more)) { - sending_reply = true; - request_begins = true; - } - - return 0; -} - -bool zmq::rep_t::xhas_in () -{ - if (sending_reply) - return false; - - return router_t::xhas_in (); -} - -bool zmq::rep_t::xhas_out () -{ - if (!sending_reply) - return false; - - return router_t::xhas_out (); -} diff --git a/dep/libzmq/src/rep.hpp b/dep/libzmq/src/rep.hpp deleted file mode 100644 index 9874af909c..0000000000 --- a/dep/libzmq/src/rep.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_REP_HPP_INCLUDED__ -#define __ZMQ_REP_HPP_INCLUDED__ - -#include "router.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class io_thread_t; - class socket_base_t; - - class rep_t : public router_t - { - public: - - rep_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~rep_t (); - - // Overrides of functions from socket_base_t. - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - - private: - - // If true, we are in process of sending the reply. If false we are - // in process of receiving a request. - bool sending_reply; - - // If true, we are starting to receive a request. The beginning - // of the request is the backtrace stack. - bool request_begins; - - rep_t (const rep_t&); - const rep_t &operator = (const rep_t&); - - }; - -} - -#endif diff --git a/dep/libzmq/src/req.cpp b/dep/libzmq/src/req.cpp deleted file mode 100644 index 8889b0ff7f..0000000000 --- a/dep/libzmq/src/req.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "req.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "wire.hpp" -#include "random.hpp" -#include "likely.hpp" - -extern "C" -{ - static void free_id (void *data, void *hint) - { - LIBZMQ_UNUSED (hint); - free (data); - } -} - -zmq::req_t::req_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - dealer_t (parent_, tid_, sid_), - receiving_reply (false), - message_begins (true), - reply_pipe (NULL), - request_id_frames_enabled (false), - request_id (generate_random ()), - strict (true) -{ - options.type = ZMQ_REQ; -} - -zmq::req_t::~req_t () -{ -} - -int zmq::req_t::xsend (msg_t *msg_) -{ - // If we've sent a request and we still haven't got the reply, - // we can't send another request unless the strict option is disabled. - if (receiving_reply) { - if (strict) { - errno = EFSM; - return -1; - } - - receiving_reply = false; - message_begins = true; - } - - // First part of the request is the request routing id. - if (message_begins) { - reply_pipe = NULL; - - if (request_id_frames_enabled) { - request_id++; - - // Copy request id before sending (see issue #1695 for details). - uint32_t *request_id_copy = (uint32_t *) malloc (sizeof (uint32_t)); - zmq_assert (request_id_copy); - - *request_id_copy = request_id; - - msg_t id; - int rc = id.init_data (request_id_copy, sizeof (uint32_t), - free_id, NULL); - errno_assert (rc == 0); - id.set_flags (msg_t::more); - - rc = dealer_t::sendpipe (&id, &reply_pipe); - if (rc != 0) - return -1; - } - - msg_t bottom; - int rc = bottom.init (); - errno_assert (rc == 0); - bottom.set_flags (msg_t::more); - - rc = dealer_t::sendpipe (&bottom, &reply_pipe); - if (rc != 0) - return -1; - zmq_assert (reply_pipe); - - message_begins = false; - - // Eat all currently available messages before the request is fully - // sent. This is done to avoid: - // REQ sends request to A, A replies, B replies too. - // A's reply was first and matches, that is used. - // An hour later REQ sends a request to B. B's old reply is used. - msg_t drop; - while (true) { - rc = drop.init (); - errno_assert (rc == 0); - rc = dealer_t::xrecv (&drop); - if (rc != 0) - break; - drop.close (); - } - } - - bool more = msg_->flags () & msg_t::more ? true : false; - - int rc = dealer_t::xsend (msg_); - if (rc != 0) - return rc; - - // If the request was fully sent, flip the FSM into reply-receiving state. - if (!more) { - receiving_reply = true; - message_begins = true; - } - - return 0; -} - -int zmq::req_t::xrecv (msg_t *msg_) -{ - // If request wasn't send, we can't wait for reply. - if (!receiving_reply) { - errno = EFSM; - return -1; - } - - // Skip messages until one with the right first frames is found. - while (message_begins) { - // If enabled, the first frame must have the correct request_id. - if (request_id_frames_enabled) { - int rc = recv_reply_pipe (msg_); - if (rc != 0) - return rc; - - if (unlikely (!(msg_->flags () & msg_t::more) || - msg_->size () != sizeof (request_id) || - *static_cast (msg_->data ()) != request_id)) { - // Skip the remaining frames and try the next message - while (msg_->flags () & msg_t::more) { - rc = recv_reply_pipe (msg_); - errno_assert (rc == 0); - } - continue; - } - } - - // The next frame must be 0. - // TODO: Failing this check should also close the connection with the peer! - int rc = recv_reply_pipe (msg_); - if (rc != 0) - return rc; - - if (unlikely (!(msg_->flags () & msg_t::more) || msg_->size () != 0)) { - // Skip the remaining frames and try the next message - while (msg_->flags () & msg_t::more) { - rc = recv_reply_pipe (msg_); - errno_assert (rc == 0); - } - continue; - } - - message_begins = false; - } - - int rc = recv_reply_pipe (msg_); - if (rc != 0) - return rc; - - // If the reply is fully received, flip the FSM into request-sending state. - if (!(msg_->flags () & msg_t::more)) { - receiving_reply = false; - message_begins = true; - } - - return 0; -} - -bool zmq::req_t::xhas_in () -{ - // TODO: Duplicates should be removed here. - - if (!receiving_reply) - return false; - - return dealer_t::xhas_in (); -} - -bool zmq::req_t::xhas_out () -{ - if (receiving_reply && strict) - return false; - - return dealer_t::xhas_out (); -} - -int zmq::req_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_) -{ - bool is_int = (optvallen_ == sizeof (int)); - int value = 0; - if (is_int) - memcpy (&value, optval_, sizeof (int)); - - switch (option_) { - case ZMQ_REQ_CORRELATE: - if (is_int && value >= 0) { - request_id_frames_enabled = (value != 0); - return 0; - } - break; - - case ZMQ_REQ_RELAXED: - if (is_int && value >= 0) { - strict = (value == 0); - return 0; - } - break; - - default: - break; - } - - return dealer_t::xsetsockopt (option_, optval_, optvallen_); -} - -void zmq::req_t::xpipe_terminated (pipe_t *pipe_) -{ - if (reply_pipe == pipe_) - reply_pipe = NULL; - dealer_t::xpipe_terminated (pipe_); -} - -int zmq::req_t::recv_reply_pipe (msg_t *msg_) -{ - while (true) { - pipe_t *pipe = NULL; - int rc = dealer_t::recvpipe (msg_, &pipe); - if (rc != 0) - return rc; - if (!reply_pipe || pipe == reply_pipe) - return 0; - } -} - -zmq::req_session_t::req_session_t (io_thread_t *io_thread_, bool connect_, - socket_base_t *socket_, const options_t &options_, - address_t *addr_) : - session_base_t (io_thread_, connect_, socket_, options_, addr_), - state (bottom) -{ -} - -zmq::req_session_t::~req_session_t () -{ -} - -int zmq::req_session_t::push_msg (msg_t *msg_) -{ - switch (state) { - case bottom: - if (msg_->flags () == msg_t::more) { - // In case option ZMQ_CORRELATE is on, allow request_id to be - // transfered as first frame (would be too cumbersome to check - // whether the option is actually on or not). - if (msg_->size () == sizeof (uint32_t)) { - state = request_id; - return session_base_t::push_msg (msg_); - } - else if (msg_->size () == 0) { - state = body; - return session_base_t::push_msg (msg_); - } - } - break; - case request_id: - if (msg_->flags () == msg_t::more && msg_->size () == 0) { - state = body; - return session_base_t::push_msg (msg_); - } - break; - case body: - if (msg_->flags () == msg_t::more) - return session_base_t::push_msg (msg_); - if (msg_->flags () == 0) { - state = bottom; - return session_base_t::push_msg (msg_); - } - break; - } - errno = EFAULT; - return -1; -} - -void zmq::req_session_t::reset () -{ - session_base_t::reset (); - state = bottom; -} diff --git a/dep/libzmq/src/req.hpp b/dep/libzmq/src/req.hpp deleted file mode 100644 index db3f011d40..0000000000 --- a/dep/libzmq/src/req.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_REQ_HPP_INCLUDED__ -#define __ZMQ_REQ_HPP_INCLUDED__ - -#include "dealer.hpp" -#include "stdint.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class io_thread_t; - class socket_base_t; - - class req_t : public dealer_t - { - public: - - req_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~req_t (); - - // Overrides of functions from socket_base_t. - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - int xsetsockopt (int option_, const void *optval_, size_t optvallen_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - protected: - - // Receive only from the pipe the request was sent to, discarding - // frames from other pipes. - int recv_reply_pipe (zmq::msg_t *msg_); - - private: - - // If true, request was already sent and reply wasn't received yet or - // was received partially. - bool receiving_reply; - - // If true, we are starting to send/recv a message. The first part - // of the message must be empty message part (backtrace stack bottom). - bool message_begins; - - // The pipe the request was sent to and where the reply is expected. - zmq::pipe_t *reply_pipe; - - // Whether request id frames shall be sent and expected. - bool request_id_frames_enabled; - - // The current request id. It is incremented every time before a new - // request is sent. - uint32_t request_id; - - // If false, send() will reset its internal state and terminate the - // reply_pipe's connection instead of failing if a previous request is - // still pending. - bool strict; - - req_t (const req_t&); - const req_t &operator = (const req_t&); - }; - - class req_session_t : public session_base_t - { - public: - - req_session_t (zmq::io_thread_t *io_thread_, bool connect_, - zmq::socket_base_t *socket_, const options_t &options_, - address_t *addr_); - ~req_session_t (); - - // Overrides of the functions from session_base_t. - int push_msg (msg_t *msg_); - void reset (); - - private: - - enum { - bottom, - request_id, - body - } state; - - req_session_t (const req_session_t&); - const req_session_t &operator = (const req_session_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/resource.h b/dep/libzmq/src/resource.h deleted file mode 100644 index 27e2900cbd..0000000000 --- a/dep/libzmq/src/resource.h +++ /dev/null @@ -1,14 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/dep/libzmq/src/router.cpp b/dep/libzmq/src/router.cpp deleted file mode 100644 index 3e7106bd14..0000000000 --- a/dep/libzmq/src/router.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "router.hpp" -#include "pipe.hpp" -#include "wire.hpp" -#include "random.hpp" -#include "likely.hpp" -#include "err.hpp" - -zmq::router_t::router_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - prefetched (false), - routing_id_sent (false), - current_in (NULL), - terminate_current_in (false), - more_in (false), - current_out (NULL), - more_out (false), - next_integral_routing_id (generate_random ()), - mandatory (false), - // raw_socket functionality in ROUTER is deprecated - raw_socket (false), - probe_router (false), - handover (false) -{ - options.type = ZMQ_ROUTER; - options.recv_routing_id = true; - options.raw_socket = false; - - prefetched_id.init (); - prefetched_msg.init (); -} - -zmq::router_t::~router_t () -{ - zmq_assert (anonymous_pipes.empty ());; - zmq_assert (outpipes.empty ()); - prefetched_id.close (); - prefetched_msg.close (); -} - -void zmq::router_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - - if (probe_router) { - msg_t probe_msg_; - int rc = probe_msg_.init (); - errno_assert (rc == 0); - - rc = pipe_->write (&probe_msg_); - // zmq_assert (rc) is not applicable here, since it is not a bug. - pipe_->flush (); - - rc = probe_msg_.close (); - errno_assert (rc == 0); - } - - bool routing_id_ok = identify_peer (pipe_); - if (routing_id_ok) - fq.attach (pipe_); - else - anonymous_pipes.insert (pipe_); -} - -int zmq::router_t::xsetsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - bool is_int = (optvallen_ == sizeof (int)); - int value = 0; - if (is_int) memcpy(&value, optval_, sizeof (int)); - - switch (option_) { - case ZMQ_CONNECT_ROUTING_ID: - if (optval_ && optvallen_) { - connect_routing_id.assign ((char *) optval_, optvallen_); - return 0; - } - break; - - case ZMQ_ROUTER_RAW: - if (is_int && value >= 0) { - raw_socket = (value != 0); - if (raw_socket) { - options.recv_routing_id = false; - options.raw_socket = true; - } - return 0; - } - break; - - case ZMQ_ROUTER_MANDATORY: - if (is_int && value >= 0) { - mandatory = (value != 0); - return 0; - } - break; - - case ZMQ_PROBE_ROUTER: - if (is_int && value >= 0) { - probe_router = (value != 0); - return 0; - } - break; - - case ZMQ_ROUTER_HANDOVER: - if (is_int && value >= 0) { - handover = (value != 0); - return 0; - } - break; - - default: - break; - } - errno = EINVAL; - return -1; -} - - -void zmq::router_t::xpipe_terminated (pipe_t *pipe_) -{ - std::set ::iterator it = anonymous_pipes.find (pipe_); - if (it != anonymous_pipes.end ()) - anonymous_pipes.erase (it); - else { - outpipes_t::iterator iter = outpipes.find (pipe_->get_routing_id ()); - zmq_assert (iter != outpipes.end ()); - outpipes.erase (iter); - fq.pipe_terminated (pipe_); - pipe_->rollback (); - if (pipe_ == current_out) - current_out = NULL; - } -} - -void zmq::router_t::xread_activated (pipe_t *pipe_) -{ - std::set ::iterator it = anonymous_pipes.find (pipe_); - if (it == anonymous_pipes.end ()) - fq.activated (pipe_); - else { - bool routing_id_ok = identify_peer (pipe_); - if (routing_id_ok) { - anonymous_pipes.erase (it); - fq.attach (pipe_); - } - } -} - -void zmq::router_t::xwrite_activated (pipe_t *pipe_) -{ - outpipes_t::iterator it; - for (it = outpipes.begin (); it != outpipes.end (); ++it) - if (it->second.pipe == pipe_) - break; - - zmq_assert (it != outpipes.end ()); - zmq_assert (!it->second.active); - it->second.active = true; -} - -int zmq::router_t::xsend (msg_t *msg_) -{ - // If this is the first part of the message it's the ID of the - // peer to send the message to. - if (!more_out) { - zmq_assert (!current_out); - - // If we have malformed message (prefix with no subsequent message) - // then just silently ignore it. - // TODO: The connections should be killed instead. - if (msg_->flags () & msg_t::more) { - - more_out = true; - - // Find the pipe associated with the routing id stored in the prefix. - // If there's no such pipe just silently ignore the message, unless - // router_mandatory is set. - blob_t routing_id ((unsigned char*) msg_->data (), msg_->size (), - zmq::reference_tag_t()); - outpipes_t::iterator it = outpipes.find (routing_id); - - if (it != outpipes.end ()) { - current_out = it->second.pipe; - - // Check whether pipe is closed or not - if (!current_out->check_write()) { - // Check whether pipe is full or not - bool pipe_full = !current_out->check_hwm (); - it->second.active = false; - current_out = NULL; - - if (mandatory) { - more_out = false; - if (pipe_full) - errno = EAGAIN; - else - errno = EHOSTUNREACH; - return -1; - } - } - } - else - if (mandatory) { - more_out = false; - errno = EHOSTUNREACH; - return -1; - } - } - - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - return 0; - } - - // Ignore the MORE flag for raw-sock or assert? - if (options.raw_socket) - msg_->reset_flags (msg_t::more); - - // Check whether this is the last part of the message. - more_out = msg_->flags () & msg_t::more ? true : false; - - // Push the message into the pipe. If there's no out pipe, just drop it. - if (current_out) { - - // Close the remote connection if user has asked to do so - // by sending zero length message. - // Pending messages in the pipe will be dropped (on receiving term- ack) - if (raw_socket && msg_->size() == 0) { - current_out->terminate (false); - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - current_out = NULL; - return 0; - } - - bool ok = current_out->write (msg_); - if (unlikely (!ok)) { - // Message failed to send - we must close it ourselves. - int rc = msg_->close (); - errno_assert (rc == 0); - // HWM was checked before, so the pipe must be gone. Roll back - // messages that were piped, for example REP labels. - current_out->rollback (); - current_out = NULL; - } else { - if (!more_out) { - current_out->flush (); - current_out = NULL; - } - } - } - else { - int rc = msg_->close (); - errno_assert (rc == 0); - } - - // Detach the message from the data buffer. - int rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -int zmq::router_t::xrecv (msg_t *msg_) -{ - if (prefetched) { - if (!routing_id_sent) { - int rc = msg_->move (prefetched_id); - errno_assert (rc == 0); - routing_id_sent = true; - } - else { - int rc = msg_->move (prefetched_msg); - errno_assert (rc == 0); - prefetched = false; - } - more_in = msg_->flags () & msg_t::more ? true : false; - - if (!more_in) { - if (terminate_current_in) { - current_in->terminate (true); - terminate_current_in = false; - } - current_in = NULL; - } - return 0; - } - - pipe_t *pipe = NULL; - int rc = fq.recvpipe (msg_, &pipe); - - // It's possible that we receive peer's routing id. That happens - // after reconnection. The current implementation assumes that - // the peer always uses the same routing id. - while (rc == 0 && msg_->is_routing_id ()) - rc = fq.recvpipe (msg_, &pipe); - - if (rc != 0) - return -1; - - zmq_assert (pipe != NULL); - - // If we are in the middle of reading a message, just return the next part. - if (more_in) { - more_in = msg_->flags () & msg_t::more ? true : false; - - if (!more_in) { - if (terminate_current_in) { - current_in->terminate (true); - terminate_current_in = false; - } - current_in = NULL; - } - } - else { - // We are at the beginning of a message. - // Keep the message part we have in the prefetch buffer - // and return the ID of the peer instead. - rc = prefetched_msg.move (*msg_); - errno_assert (rc == 0); - prefetched = true; - current_in = pipe; - - const blob_t &routing_id = pipe->get_routing_id (); - rc = msg_->init_size (routing_id.size ()); - errno_assert (rc == 0); - memcpy (msg_->data (), routing_id.data (), routing_id.size ()); - msg_->set_flags (msg_t::more); - if (prefetched_msg.metadata()) - msg_->set_metadata(prefetched_msg.metadata()); - routing_id_sent = true; - } - - return 0; -} - -int zmq::router_t::rollback (void) -{ - if (current_out) { - current_out->rollback (); - current_out = NULL; - more_out = false; - } - return 0; -} - -bool zmq::router_t::xhas_in () -{ - // If we are in the middle of reading the messages, there are - // definitely more parts available. - if (more_in) - return true; - - // We may already have a message pre-fetched. - if (prefetched) - return true; - - // Try to read the next message. - // The message, if read, is kept in the pre-fetch buffer. - pipe_t *pipe = NULL; - int rc = fq.recvpipe (&prefetched_msg, &pipe); - - // It's possible that we receive peer's routing id. That happens - // after reconnection. The current implementation assumes that - // the peer always uses the same routing id. - // TODO: handle the situation when the peer changes its routing id. - while (rc == 0 && prefetched_msg.is_routing_id ()) - rc = fq.recvpipe (&prefetched_msg, &pipe); - - if (rc != 0) - return false; - - zmq_assert (pipe != NULL); - - const blob_t &routing_id = pipe->get_routing_id (); - rc = prefetched_id.init_size (routing_id.size ()); - errno_assert (rc == 0); - memcpy (prefetched_id.data (), routing_id.data (), routing_id.size ()); - prefetched_id.set_flags (msg_t::more); - - prefetched = true; - routing_id_sent = false; - current_in = pipe; - - return true; -} - -bool zmq::router_t::xhas_out () -{ - // In theory, ROUTER socket is always ready for writing (except when - // MANDATORY is set). Whether actual attempt to write succeeds depends - // on whitch pipe the message is going to be routed to. - - if(!mandatory) - return true; - - bool has_out = false; - outpipes_t::iterator it; - for (it = outpipes.begin (); it != outpipes.end (); ++it) - has_out |= it->second.pipe->check_hwm(); - - return has_out; -} - -const zmq::blob_t &zmq::router_t::get_credential () const -{ - return fq.get_credential (); -} - -int zmq::router_t::get_peer_state (const void *routing_id_, - size_t routing_id_size_) const -{ - int res = 0; - - blob_t routing_id_blob ((unsigned char *) routing_id_, routing_id_size_); - outpipes_t::const_iterator it = outpipes.find (routing_id_blob); - if (it == outpipes.end ()) { - errno = EHOSTUNREACH; - return -1; - } - - const outpipe_t &outpipe = it->second; - if (outpipe.pipe->check_hwm ()) - res |= ZMQ_POLLOUT; - - /** \todo does it make any sense to check the inpipe as well? */ - - return res; -} - -bool zmq::router_t::identify_peer (pipe_t *pipe_) -{ - msg_t msg; - bool ok; - blob_t routing_id; - - if (connect_routing_id.length()) { - routing_id.set ((unsigned char*)connect_routing_id.c_str(), - connect_routing_id.length()); - connect_routing_id.clear(); - outpipes_t::iterator it = outpipes.find(routing_id); - if (it != outpipes.end()) - zmq_assert(false); // Not allowed to duplicate an existing rid - } - else - if (options.raw_socket) { // Always assign an integral routing id for raw-socket - unsigned char buf [5]; - buf [0] = 0; - put_uint32 (buf + 1, next_integral_routing_id++); - routing_id.set (buf, sizeof buf); - } - else - if (!options.raw_socket) { - // Pick up handshake cases and also case where next integral routing id is set - msg.init (); - ok = pipe_->read (&msg); - if (!ok) - return false; - - if (msg.size () == 0) { - // Fall back on the auto-generation - unsigned char buf [5]; - buf [0] = 0; - put_uint32 (buf + 1, next_integral_routing_id++); - routing_id.set (buf, sizeof buf); - msg.close (); - } - else { - routing_id.set ((unsigned char*) msg.data (), msg.size ()); - outpipes_t::iterator it = outpipes.find (routing_id); - msg.close (); - - if (it != outpipes.end ()) { - if (!handover) - // Ignore peers with duplicate ID - return false; - else { - // We will allow the new connection to take over this - // routing id. Temporarily assign a new routing id to the - // existing pipe so we can terminate it asynchronously. - unsigned char buf [5]; - buf [0] = 0; - put_uint32 (buf + 1, next_integral_routing_id++); - blob_t new_routing_id (buf, sizeof buf); - - it->second.pipe->set_router_socket_routing_id (new_routing_id); - outpipe_t existing_outpipe = - {it->second.pipe, it->second.active}; - - ok = outpipes.ZMQ_MAP_INSERT_OR_EMPLACE ( - ZMQ_MOVE(new_routing_id), existing_outpipe).second; - zmq_assert (ok); - - // Remove the existing routing id entry to allow the new - // connection to take the routing id. - outpipes.erase (it); - - if (existing_outpipe.pipe == current_in) - terminate_current_in = true; - else - existing_outpipe.pipe->terminate (true); - } - } - } - } - - pipe_->set_router_socket_routing_id (routing_id); - // Add the record into output pipes lookup table - outpipe_t outpipe = {pipe_, true}; - ok = outpipes.ZMQ_MAP_INSERT_OR_EMPLACE (ZMQ_MOVE(routing_id), outpipe).second; - zmq_assert (ok); - - return true; -} diff --git a/dep/libzmq/src/router.hpp b/dep/libzmq/src/router.hpp deleted file mode 100644 index 1a7bfcd6b7..0000000000 --- a/dep/libzmq/src/router.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ROUTER_HPP_INCLUDED__ -#define __ZMQ_ROUTER_HPP_INCLUDED__ - -#include - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "stdint.hpp" -#include "blob.hpp" -#include "msg.hpp" -#include "fq.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - - // TODO: This class uses O(n) scheduling. Rewrite it to use O(1) algorithm. - class router_t : - public socket_base_t - { - public: - - router_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~router_t (); - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsetsockopt (int option_, const void *optval_, size_t optvallen_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - int get_peer_state (const void *identity, size_t identity_size) const; - - protected: - - // Rollback any message parts that were sent but not yet flushed. - int rollback (); - const blob_t &get_credential () const; - - private: - - // Receive peer id and update lookup map - bool identify_peer (pipe_t *pipe_); - - // Fair queueing object for inbound pipes. - fq_t fq; - - // True iff there is a message held in the pre-fetch buffer. - bool prefetched; - - // If true, the receiver got the message part with - // the peer's identity. - bool routing_id_sent; - - // Holds the prefetched identity. - msg_t prefetched_id; - - // Holds the prefetched message. - msg_t prefetched_msg; - - // The pipe we are currently reading from - zmq::pipe_t *current_in; - - // Should current_in should be terminate after all parts received? - bool terminate_current_in; - - // If true, more incoming message parts are expected. - bool more_in; - - struct outpipe_t - { - zmq::pipe_t *pipe; - bool active; - }; - - // We keep a set of pipes that have not been identified yet. - std::set anonymous_pipes; - - // Outbound pipes indexed by the peer IDs. - typedef std::map outpipes_t; - outpipes_t outpipes; - - // The pipe we are currently writing to. - zmq::pipe_t *current_out; - - // If true, more outgoing message parts are expected. - bool more_out; - - // Routing IDs are generated. It's a simple increment and wrap-over - // algorithm. This value is the next ID to use (if not used already). - uint32_t next_integral_routing_id; - - // If true, report EAGAIN to the caller instead of silently dropping - // the message targeting an unknown peer. - bool mandatory; - bool raw_socket; - - // if true, send an empty message to every connected router peer - bool probe_router; - - // If true, the router will reassign an identity upon encountering a - // name collision. The new pipe will take the identity, the old pipe - // will be terminated. - bool handover; - - router_t (const router_t&); - const router_t &operator = (const router_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/scatter.cpp b/dep/libzmq/src/scatter.cpp deleted file mode 100644 index dde3a79901..0000000000 --- a/dep/libzmq/src/scatter.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "scatter.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" - -zmq::scatter_t::scatter_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_, true) -{ - options.type = ZMQ_SCATTER; -} - -zmq::scatter_t::~scatter_t () -{ -} - -void zmq::scatter_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - // Don't delay pipe termination as there is no one - // to receive the delimiter. - pipe_->set_nodelay (); - - zmq_assert (pipe_); - lb.attach (pipe_); -} - -void zmq::scatter_t::xwrite_activated (pipe_t *pipe_) -{ - lb.activated (pipe_); -} - -void zmq::scatter_t::xpipe_terminated (pipe_t *pipe_) -{ - lb.pipe_terminated (pipe_); -} - -int zmq::scatter_t::xsend (msg_t *msg_) -{ - // SCATTER sockets do not allow multipart data (ZMQ_SNDMORE) - if (msg_->flags () & msg_t::more) { - errno = EINVAL; - return -1; - } - - return lb.send (msg_); -} - -bool zmq::scatter_t::xhas_out () -{ - return lb.has_out (); -} diff --git a/dep/libzmq/src/scatter.hpp b/dep/libzmq/src/scatter.hpp deleted file mode 100644 index 8c65148092..0000000000 --- a/dep/libzmq/src/scatter.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SCATTER_HPP_INCLUDED__ -#define __ZMQ_SCATTER_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "lb.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - class msg_t; - class io_thread_t; - - class scatter_t : - public socket_base_t - { - public: - - scatter_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~scatter_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Load balancer managing the outbound pipes. - lb_t lb; - - scatter_t (const scatter_t&); - const scatter_t &operator = (const scatter_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/select.cpp b/dep/libzmq/src/select.cpp deleted file mode 100644 index 58af98d9e4..0000000000 --- a/dep/libzmq/src/select.cpp +++ /dev/null @@ -1,567 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "select.hpp" -#if defined ZMQ_USE_SELECT - -#if defined ZMQ_HAVE_WINDOWS -#elif defined ZMQ_HAVE_HPUX -#include -#include -#include -#elif defined ZMQ_HAVE_OPENVMS -#include -#include -#else -#include -#endif - -#include "err.hpp" -#include "config.hpp" -#include "i_poll_events.hpp" - -zmq::select_t::select_t (const zmq::ctx_t &ctx_) : - ctx (ctx_), -#if defined ZMQ_HAVE_WINDOWS - // Fine as long as map is not cleared. - current_family_entry_it (family_entries.end ()), -#else - maxfd (retired_fd), -#endif - stopping (false) -{ -#if defined ZMQ_HAVE_WINDOWS - for (size_t i = 0; i < fd_family_cache_size; ++i) - fd_family_cache [i] = std::make_pair (retired_fd, 0); -#endif -} - -zmq::select_t::~select_t () -{ - worker.stop (); -} - -zmq::select_t::handle_t zmq::select_t::add_fd (fd_t fd_, i_poll_events *events_) -{ - fd_entry_t fd_entry; - fd_entry.fd = fd_; - fd_entry.events = events_; - -#if defined ZMQ_HAVE_WINDOWS - u_short family = get_fd_family (fd_); - wsa_assert (family != AF_UNSPEC); - family_entry_t &family_entry = family_entries [family]; -#endif - family_entry.fd_entries.push_back (fd_entry); - FD_SET (fd_, &family_entry.fds_set.error); - -#if !defined ZMQ_HAVE_WINDOWS - if (fd_ > maxfd) - maxfd = fd_; -#endif - - adjust_load (1); - - return fd_; -} - -zmq::select_t::fd_entries_t::iterator -zmq::select_t::find_fd_entry_by_handle (fd_entries_t &fd_entries, - handle_t handle_) -{ - fd_entries_t::iterator fd_entry_it; - for (fd_entry_it = fd_entries.begin (); fd_entry_it != fd_entries.end (); - ++fd_entry_it) - if (fd_entry_it->fd == handle_) - break; - - return fd_entry_it; -} - -void zmq::select_t::trigger_events (const fd_entries_t &fd_entries_, - const fds_set_t &local_fds_set_, - int event_count_) -{ - // Size is cached to avoid iteration through recently added descriptors. - for (fd_entries_t::size_type i = 0, size = fd_entries_.size (); - i < size && event_count_ > 0; ++i) { - const fd_entry_t ¤t_fd_entry = fd_entries_ [i]; - - if (is_retired_fd (current_fd_entry)) - continue; - - if (FD_ISSET (current_fd_entry.fd, &local_fds_set_.read)) { - current_fd_entry.events->in_event (); - --event_count_; - } - - // TODO: can the is_retired_fd be true at this point? if it - // was retired before, we would already have continued, and I - // don't see where it might have been modified - // And if rc == 0, we can break instead of continuing - if (is_retired_fd (current_fd_entry) || event_count_ == 0) - continue; - - if (FD_ISSET (current_fd_entry.fd, &local_fds_set_.write)) { - current_fd_entry.events->out_event (); - --event_count_; - } - - // TODO: same as above - if (is_retired_fd (current_fd_entry) || event_count_ == 0) - continue; - - if (FD_ISSET (current_fd_entry.fd, &local_fds_set_.error)) { - current_fd_entry.events->in_event (); - --event_count_; - } - } -} - -#if defined ZMQ_HAVE_WINDOWS -bool zmq::select_t::try_remove_fd_entry ( - family_entries_t::iterator family_entry_it, zmq::fd_t &handle_) -{ - family_entry_t &family_entry = family_entry_it->second; - - fd_entries_t::iterator fd_entry_it = - find_fd_entry_by_handle (family_entry.fd_entries, handle_); - if (fd_entry_it == family_entry.fd_entries.end ()) - return false; - if (family_entry_it != current_family_entry_it) { - // Family is not currently being iterated and can be safely - // modified in-place. So later it can be skipped without - // re-verifying its content. - family_entry.fd_entries.erase (fd_entry_it); - } else { - // Otherwise mark removed entries as retired. It will be cleaned up - // at the end of the iteration. See zmq::select_t::loop - fd_entry_it->fd = retired_fd; - family_entry.retired = true; - } - family_entry.fds_set.remove_fd (handle_); - return true; -} -#endif - -void zmq::select_t::rm_fd (handle_t handle_) -{ -#if defined ZMQ_HAVE_WINDOWS - u_short family = get_fd_family (handle_); - if (family != AF_UNSPEC) { - family_entries_t::iterator family_entry_it = - family_entries.find (family); - - int removed = try_remove_fd_entry (family_entry_it, handle_); - assert (removed); - } else { - // get_fd_family may fail and return AF_UNSPEC if the socket was not - // successfully connected. In that case, we need to look for the - // socket in all family_entries. - family_entries_t::iterator end = family_entries.end (); - for (family_entries_t::iterator family_entry_it = - family_entries.begin (); - family_entry_it != end; ++family_entry_it) { - if (try_remove_fd_entry (family_entry_it, handle_)) - break; - } - } -#else - fd_entries_t::iterator fd_entry_it = - find_fd_entry_by_handle (family_entry.fd_entries, handle_); - assert (fd_entry_it != fd_entries.end ()); - - fd_entry_it->fd = retired_fd; - family_entry.fds_set.remove_fd (handle_); - - if (handle_ == maxfd) { - maxfd = retired_fd; - for (fd_entry_it = family_entry.fd_entries.begin (); - fd_entry_it != family_entry.fd_entries.end (); ++fd_entry_it) - if (fd_entry_it->fd > maxfd) - maxfd = fd_entry_it->fd; - } - - family_entry.retired = true; -#endif - adjust_load (-1); -} - -void zmq::select_t::set_pollin (handle_t handle_) -{ -#if defined ZMQ_HAVE_WINDOWS - u_short family = get_fd_family (handle_); - wsa_assert (family != AF_UNSPEC); - family_entry_t &family_entry = family_entries [family]; -#endif - FD_SET (handle_, &family_entry.fds_set.read); -} - -void zmq::select_t::reset_pollin (handle_t handle_) -{ -#if defined ZMQ_HAVE_WINDOWS - u_short family = get_fd_family (handle_); - wsa_assert (family != AF_UNSPEC); - family_entry_t &family_entry = family_entries [family]; -#endif - FD_CLR (handle_, &family_entry.fds_set.read); -} - -void zmq::select_t::set_pollout (handle_t handle_) -{ -#if defined ZMQ_HAVE_WINDOWS - u_short family = get_fd_family (handle_); - wsa_assert (family != AF_UNSPEC); - family_entry_t &family_entry = family_entries [family]; -#endif - FD_SET (handle_, &family_entry.fds_set.write); -} - -void zmq::select_t::reset_pollout (handle_t handle_) -{ -#if defined ZMQ_HAVE_WINDOWS - u_short family = get_fd_family (handle_); - wsa_assert (family != AF_UNSPEC); - family_entry_t &family_entry = family_entries [family]; -#endif - FD_CLR (handle_, &family_entry.fds_set.write); -} - -void zmq::select_t::start () -{ - ctx.start_thread (worker, worker_routine, this); -} - -void zmq::select_t::stop () -{ - stopping = true; -} - -int zmq::select_t::max_fds () -{ - return FD_SETSIZE; -} - -void zmq::select_t::loop () -{ - while (!stopping) { - // Execute any due timers. - int timeout = (int) execute_timers (); - -#if defined ZMQ_HAVE_OSX - struct timeval tv = {(long) (timeout / 1000), timeout % 1000 * 1000}; -#else - struct timeval tv = {(long) (timeout / 1000), - (long) (timeout % 1000 * 1000)}; -#endif - - int rc = 0; - -#if defined ZMQ_HAVE_WINDOWS - /* - On Windows select does not allow to mix descriptors from different - service providers. It seems to work for AF_INET and AF_INET6, - but fails for AF_INET and VMCI. The workaround is to use - WSAEventSelect and WSAWaitForMultipleEvents to wait, then use - select to find out what actually changed. WSAWaitForMultipleEvents - cannot be used alone, because it does not support more than 64 events - which is not enough. - - To reduce unnecessary overhead, WSA is only used when there are more - than one family. Moreover, AF_INET and AF_INET6 are considered the same - family because Windows seems to handle them properly. - See get_fd_family for details. - */ - - // If there is just one family, there is no reason to use WSA events. - const bool use_wsa_events = family_entries.size () > 1; - if (use_wsa_events) { - // TODO: I don't really understand why we are doing this. If any of - // the events was signaled, we will call select for each fd_family - // afterwards. The only benefit is if none of the events was - // signaled, then we continue early. - // IMHO, either WSAEventSelect/WSAWaitForMultipleEvents or select - // should be used, but not both - - wsa_events_t wsa_events; - - for (family_entries_t::iterator family_entry_it = - family_entries.begin (); - family_entry_it != family_entries.end (); ++family_entry_it) { - family_entry_t &family_entry = family_entry_it->second; - - for (fd_entries_t::iterator fd_entry_it = - family_entry.fd_entries.begin (); - fd_entry_it != family_entry.fd_entries.end (); - ++fd_entry_it) { - fd_t fd = fd_entry_it->fd; - - // http://stackoverflow.com/q/35043420/188530 - if (FD_ISSET (fd, &family_entry.fds_set.read) - && FD_ISSET (fd, &family_entry.fds_set.write)) - rc = - WSAEventSelect (fd, wsa_events.events [3], - FD_READ | FD_ACCEPT | FD_CLOSE - | FD_WRITE | FD_CONNECT | FD_OOB); - else if (FD_ISSET (fd, &family_entry.fds_set.read)) - rc = WSAEventSelect (fd, wsa_events.events [0], - FD_READ | FD_ACCEPT | FD_CLOSE - | FD_OOB); - else if (FD_ISSET (fd, &family_entry.fds_set.write)) - rc = WSAEventSelect (fd, wsa_events.events [1], - FD_WRITE | FD_CONNECT | FD_OOB); - else if (FD_ISSET (fd, &family_entry.fds_set.error)) - rc = WSAEventSelect (fd, wsa_events.events [2], FD_OOB); - else - rc = 0; - - wsa_assert (rc != SOCKET_ERROR); - } - } - - rc = WSAWaitForMultipleEvents (4, wsa_events.events, FALSE, - timeout ? timeout : INFINITE, FALSE); - wsa_assert (rc != (int) WSA_WAIT_FAILED); - zmq_assert (rc != WSA_WAIT_IO_COMPLETION); - - if (rc == WSA_WAIT_TIMEOUT) - continue; - } - - for (current_family_entry_it = family_entries.begin (); - current_family_entry_it != family_entries.end (); - ++current_family_entry_it) { - family_entry_t &family_entry = current_family_entry_it->second; - - - if (use_wsa_events) { - // There is no reason to wait again after WSAWaitForMultipleEvents. - // Simply collect what is ready. - struct timeval tv_nodelay = {0, 0}; - select_family_entry (family_entry, 0, true, tv_nodelay); - } else { - select_family_entry (family_entry, 0, timeout > 0, tv); - } - } -#else - select_family_entry (family_entry, maxfd, timeout > 0, tv); -#endif - } -} - -void zmq::select_t::select_family_entry (family_entry_t &family_entry_, - const int max_fd_, - const bool use_timeout_, - struct timeval &tv_) -{ - // select will fail when run with empty sets. - fd_entries_t &fd_entries = family_entry_.fd_entries; - if (fd_entries.empty ()) - return; - - fds_set_t local_fds_set = family_entry_.fds_set; - int rc = select (max_fd_, &local_fds_set.read, &local_fds_set.write, - &local_fds_set.error, use_timeout_ ? &tv_ : NULL); - -#if defined ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - if (rc == -1) { - errno_assert (errno == EINTR); - return; - } -#endif - - trigger_events (fd_entries, local_fds_set, rc); - - if (family_entry_.retired) { - family_entry_.retired = false; - family_entry_.fd_entries.erase (std::remove_if (fd_entries.begin (), - fd_entries.end (), - is_retired_fd), - family_entry_.fd_entries.end ()); - } -} - -void zmq::select_t::worker_routine (void *arg_) -{ - ((select_t *) arg_)->loop (); -} - -zmq::select_t::fds_set_t::fds_set_t () -{ - FD_ZERO (&read); - FD_ZERO (&write); - FD_ZERO (&error); -} - -zmq::select_t::fds_set_t::fds_set_t (const fds_set_t &other_) -{ -#if defined ZMQ_HAVE_WINDOWS - // On Windows we don't need to copy the whole fd_set. - // SOCKETS are continuous from the beginning of fd_array in fd_set. - // We just need to copy fd_count elements of fd_array. - // We gain huge memcpy() improvement if number of used SOCKETs is much lower than FD_SETSIZE. - memcpy (&read, &other_.read, - (char *) (other_.read.fd_array + other_.read.fd_count) - - (char *) &other_.read); - memcpy (&write, &other_.write, - (char *) (other_.write.fd_array + other_.write.fd_count) - - (char *) &other_.write); - memcpy (&error, &other_.error, - (char *) (other_.error.fd_array + other_.error.fd_count) - - (char *) &other_.error); -#else - memcpy (&read, &other_.read, sizeof other_.read); - memcpy (&write, &other_.write, sizeof other_.write); - memcpy (&error, &other_.error, sizeof other_.error); -#endif -} - -zmq::select_t::fds_set_t &zmq::select_t::fds_set_t:: -operator= (const fds_set_t &other_) -{ -#if defined ZMQ_HAVE_WINDOWS - // On Windows we don't need to copy the whole fd_set. - // SOCKETS are continuous from the beginning of fd_array in fd_set. - // We just need to copy fd_count elements of fd_array. - // We gain huge memcpy() improvement if number of used SOCKETs is much lower than FD_SETSIZE. - memcpy (&read, &other_.read, - (char *) (other_.read.fd_array + other_.read.fd_count) - - (char *) &other_.read); - memcpy (&write, &other_.write, - (char *) (other_.write.fd_array + other_.write.fd_count) - - (char *) &other_.write); - memcpy (&error, &other_.error, - (char *) (other_.error.fd_array + other_.error.fd_count) - - (char *) &other_.error); -#else - memcpy (&read, &other_.read, sizeof other_.read); - memcpy (&write, &other_.write, sizeof other_.write); - memcpy (&error, &other_.error, sizeof other_.error); -#endif - return *this; -} - -void zmq::select_t::fds_set_t::remove_fd (const fd_t &fd_) -{ - FD_CLR (fd_, &read); - FD_CLR (fd_, &write); - FD_CLR (fd_, &error); -} - -bool zmq::select_t::is_retired_fd (const fd_entry_t &entry) -{ - return (entry.fd == retired_fd); -} - -#if defined ZMQ_HAVE_WINDOWS -u_short zmq::select_t::get_fd_family (fd_t fd_) -{ - // cache the results of determine_fd_family, as this is frequently called - // for the same sockets, and determine_fd_family is expensive - size_t i; - for (i = 0; i < fd_family_cache_size; ++i) { - const std::pair &entry = fd_family_cache [i]; - if (entry.first == fd_) { - return entry.second; - } - if (entry.first == retired_fd) - break; - } - - std::pair res = - std::make_pair (fd_, determine_fd_family (fd_)); - if (i < fd_family_cache_size) { - fd_family_cache [i] = res; - } else { - // just overwrite a random entry - // could be optimized by some LRU strategy - fd_family_cache [rand () % fd_family_cache_size] = res; - } - - return res.second; -} - -u_short zmq::select_t::determine_fd_family (fd_t fd_) -{ - // Use sockaddr_storage instead of sockaddr to accommodate different structure sizes - sockaddr_storage addr = {0}; - int addr_size = sizeof addr; - - int type; - int type_length = sizeof (int); - - int rc = - getsockopt (fd_, SOL_SOCKET, SO_TYPE, (char *) &type, &type_length); - - if (rc == 0) { - if (type == SOCK_DGRAM) - return AF_INET; - else { - rc = getsockname (fd_, (sockaddr *) &addr, &addr_size); - - // AF_INET and AF_INET6 can be mixed in select - // TODO: If proven otherwise, should simply return addr.sa_family - if (rc != SOCKET_ERROR) - return addr.ss_family == AF_INET6 ? AF_INET : addr.ss_family; - } - } - - return AF_UNSPEC; -} - -zmq::select_t::family_entry_t::family_entry_t () : retired (false) -{ -} - - -zmq::select_t::wsa_events_t::wsa_events_t () -{ - events [0] = WSACreateEvent (); - wsa_assert (events [0] != WSA_INVALID_EVENT); - events [1] = WSACreateEvent (); - wsa_assert (events [1] != WSA_INVALID_EVENT); - events [2] = WSACreateEvent (); - wsa_assert (events [2] != WSA_INVALID_EVENT); - events [3] = WSACreateEvent (); - wsa_assert (events [3] != WSA_INVALID_EVENT); -} - -zmq::select_t::wsa_events_t::~wsa_events_t () -{ - wsa_assert (WSACloseEvent (events [0])); - wsa_assert (WSACloseEvent (events [1])); - wsa_assert (WSACloseEvent (events [2])); - wsa_assert (WSACloseEvent (events [3])); -} -#endif - -#endif diff --git a/dep/libzmq/src/select.hpp b/dep/libzmq/src/select.hpp deleted file mode 100644 index e76ebcaa63..0000000000 --- a/dep/libzmq/src/select.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SELECT_HPP_INCLUDED__ -#define __ZMQ_SELECT_HPP_INCLUDED__ - -// poller.hpp decides which polling mechanism to use. -#include "poller.hpp" -#if defined ZMQ_USE_SELECT - -#include -#include -#include - -#if defined ZMQ_HAVE_WINDOWS -#elif defined ZMQ_HAVE_OPENVMS -#include -#include -#else -#include -#endif - -#include "ctx.hpp" -#include "fd.hpp" -#include "thread.hpp" -#include "poller_base.hpp" - -namespace zmq -{ -struct i_poll_events; - -// Implements socket polling mechanism using POSIX.1-2001 select() -// function. - -class select_t : public poller_base_t -{ - public: - typedef fd_t handle_t; - - select_t (const ctx_t &ctx_); - ~select_t (); - - // "poller" concept. - handle_t add_fd (fd_t fd_, zmq::i_poll_events *events_); - void rm_fd (handle_t handle_); - void set_pollin (handle_t handle_); - void reset_pollin (handle_t handle_); - void set_pollout (handle_t handle_); - void reset_pollout (handle_t handle_); - void start (); - void stop (); - - static int max_fds (); - - private: - // Main worker thread routine. - static void worker_routine (void *arg_); - - // Main event loop. - void loop (); - - // Reference to ZMQ context. - const ctx_t &ctx; - - // Internal state. - struct fds_set_t - { - fds_set_t (); - fds_set_t (const fds_set_t &other_); - fds_set_t &operator= (const fds_set_t &other_); - // Convenience method to descriptor from all sets. - void remove_fd (const fd_t &fd_); - - fd_set read; - fd_set write; - fd_set error; - }; - - struct fd_entry_t - { - fd_t fd; - zmq::i_poll_events *events; - }; - typedef std::vector fd_entries_t; - - void trigger_events (const fd_entries_t &fd_entries_, - const fds_set_t &local_fds_set_, - int event_count_); - - struct family_entry_t - { - family_entry_t (); - - fd_entries_t fd_entries; - fds_set_t fds_set; - bool retired; - }; - - void select_family_entry (family_entry_t &family_entry_, - int max_fd_, - bool use_timeout_, - struct timeval &tv_); - -#if defined ZMQ_HAVE_WINDOWS - typedef std::map family_entries_t; - - struct wsa_events_t - { - wsa_events_t (); - ~wsa_events_t (); - - // read, write, error and readwrite - WSAEVENT events [4]; - }; - - family_entries_t family_entries; - // See loop for details. - family_entries_t::iterator current_family_entry_it; - - bool try_remove_fd_entry (family_entries_t::iterator family_entry_it, - zmq::fd_t &handle_); - - static const size_t fd_family_cache_size = 8; - std::pair fd_family_cache [fd_family_cache_size]; - - u_short get_fd_family (fd_t fd_); - - // Socket's family or AF_UNSPEC on error. - static u_short determine_fd_family (fd_t fd_); -#else - // on non-Windows, we can treat all fds as one family - family_entry_t family_entry; - fd_t maxfd; - bool retired; -#endif - - // Checks if an fd_entry_t is retired. - static bool is_retired_fd (const fd_entry_t &entry); - - static fd_entries_t::iterator - find_fd_entry_by_handle (fd_entries_t &fd_entries, handle_t handle_); - - // If true, thread is shutting down. - bool stopping; - - // Handle of the physical thread doing the I/O work. - thread_t worker; - - select_t (const select_t &); - const select_t &operator= (const select_t &); -}; - -typedef select_t poller_t; -} - -#endif - -#endif diff --git a/dep/libzmq/src/server.cpp b/dep/libzmq/src/server.cpp deleted file mode 100644 index 3cfecb7707..0000000000 --- a/dep/libzmq/src/server.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "server.hpp" -#include "pipe.hpp" -#include "wire.hpp" -#include "random.hpp" -#include "likely.hpp" -#include "err.hpp" - -zmq::server_t::server_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_, true), - next_routing_id (generate_random ()) -{ - options.type = ZMQ_SERVER; -} - -zmq::server_t::~server_t () -{ - zmq_assert (outpipes.empty ()); -} - -void zmq::server_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - - uint32_t routing_id = next_routing_id++; - if (!routing_id) - routing_id = next_routing_id++; // Never use Routing ID zero - - pipe_->set_server_socket_routing_id (routing_id); - // Add the record into output pipes lookup table - outpipe_t outpipe = {pipe_, true}; - bool ok = outpipes.ZMQ_MAP_INSERT_OR_EMPLACE (routing_id, outpipe).second; - zmq_assert (ok); - - fq.attach (pipe_); -} - -void zmq::server_t::xpipe_terminated (pipe_t *pipe_) -{ - outpipes_t::iterator it = outpipes.find (pipe_->get_server_socket_routing_id ()); - zmq_assert (it != outpipes.end ()); - outpipes.erase (it); - fq.pipe_terminated (pipe_); -} - -void zmq::server_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::server_t::xwrite_activated (pipe_t *pipe_) -{ - outpipes_t::iterator it; - for (it = outpipes.begin (); it != outpipes.end (); ++it) - if (it->second.pipe == pipe_) - break; - - zmq_assert (it != outpipes.end ()); - zmq_assert (!it->second.active); - it->second.active = true; -} - -int zmq::server_t::xsend (msg_t *msg_) -{ - // SERVER sockets do not allow multipart data (ZMQ_SNDMORE) - if (msg_->flags () & msg_t::more) { - errno = EINVAL; - return -1; - } - // Find the pipe associated with the routing stored in the message. - uint32_t routing_id = msg_->get_routing_id (); - outpipes_t::iterator it = outpipes.find (routing_id); - - if (it != outpipes.end ()) { - if (!it->second.pipe->check_write ()) { - it->second.active = false; - errno = EAGAIN; - return -1; - } - } - else { - errno = EHOSTUNREACH; - return -1; - } - - // Message might be delivered over inproc, so we reset routing id - int rc = msg_->reset_routing_id (); - errno_assert (rc == 0); - - bool ok = it->second.pipe->write (msg_); - if (unlikely (!ok)) { - // Message failed to send - we must close it ourselves. - rc = msg_->close (); - errno_assert (rc == 0); - } - else - it->second.pipe->flush (); - - // Detach the message from the data buffer. - rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -int zmq::server_t::xrecv (msg_t *msg_) -{ - pipe_t *pipe = NULL; - int rc = fq.recvpipe (msg_, &pipe); - - // Drop any messages with more flag - while (rc == 0 && msg_->flags () & msg_t::more) { - - // drop all frames of the current multi-frame message - rc = fq.recvpipe (msg_, NULL); - - while (rc == 0 && msg_->flags () & msg_t::more) - rc = fq.recvpipe (msg_, NULL); - - // get the new message - if (rc == 0) - rc = fq.recvpipe (msg_, &pipe); - } - - if (rc != 0) - return rc; - - zmq_assert (pipe != NULL); - - uint32_t routing_id = pipe->get_server_socket_routing_id (); - msg_->set_routing_id (routing_id); - - return 0; -} - -bool zmq::server_t::xhas_in () -{ - return fq.has_in (); -} - -bool zmq::server_t::xhas_out () -{ - // In theory, SERVER socket is always ready for writing. Whether actual - // attempt to write succeeds depends on which pipe the message is going - // to be routed to. - return true; -} - -const zmq::blob_t &zmq::server_t::get_credential () const -{ - return fq.get_credential (); -} diff --git a/dep/libzmq/src/server.hpp b/dep/libzmq/src/server.hpp deleted file mode 100644 index 5e1919b75a..0000000000 --- a/dep/libzmq/src/server.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SERVER_HPP_INCLUDED__ -#define __ZMQ_SERVER_HPP_INCLUDED__ - -#include - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "stdint.hpp" -#include "blob.hpp" -#include "msg.hpp" -#include "fq.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - - // TODO: This class uses O(n) scheduling. Rewrite it to use O(1) algorithm. - class server_t : - public socket_base_t - { - public: - - server_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~server_t (); - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - protected: - - const blob_t &get_credential () const; - - private: - - // Fair queueing object for inbound pipes. - fq_t fq; - - struct outpipe_t - { - zmq::pipe_t *pipe; - bool active; - }; - - // Outbound pipes indexed by the peer IDs. - typedef std::map outpipes_t; - outpipes_t outpipes; - - // Routing IDs are generated. It's a simple increment and wrap-over - // algorithm. This value is the next ID to use (if not used already). - uint32_t next_routing_id; - - server_t (const server_t&); - const server_t &operator = (const server_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/session_base.cpp b/dep/libzmq/src/session_base.cpp deleted file mode 100644 index 84212361c4..0000000000 --- a/dep/libzmq/src/session_base.cpp +++ /dev/null @@ -1,716 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "session_base.hpp" -#include "i_engine.hpp" -#include "err.hpp" -#include "pipe.hpp" -#include "likely.hpp" -#include "tcp_connecter.hpp" -#include "ipc_connecter.hpp" -#include "tipc_connecter.hpp" -#include "socks_connecter.hpp" -#include "vmci_connecter.hpp" -#include "pgm_sender.hpp" -#include "pgm_receiver.hpp" -#include "address.hpp" -#include "norm_engine.hpp" -#include "udp_engine.hpp" - -#include "ctx.hpp" -#include "req.hpp" -#include "radio.hpp" -#include "dish.hpp" - -zmq::session_base_t *zmq::session_base_t::create (class io_thread_t *io_thread_, - bool active_, class socket_base_t *socket_, const options_t &options_, - address_t *addr_) -{ - session_base_t *s = NULL; - switch (options_.type) { - case ZMQ_REQ: - s = new (std::nothrow) req_session_t (io_thread_, active_, - socket_, options_, addr_); - break; - case ZMQ_RADIO: - s = new (std::nothrow) radio_session_t (io_thread_, active_, - socket_, options_, addr_); - break; - case ZMQ_DISH: - s = new (std::nothrow) dish_session_t (io_thread_, active_, - socket_, options_, addr_); - break; - case ZMQ_DEALER: - case ZMQ_REP: - case ZMQ_ROUTER: - case ZMQ_PUB: - case ZMQ_XPUB: - case ZMQ_SUB: - case ZMQ_XSUB: - case ZMQ_PUSH: - case ZMQ_PULL: - case ZMQ_PAIR: - case ZMQ_STREAM: - case ZMQ_SERVER: - case ZMQ_CLIENT: - case ZMQ_GATHER: - case ZMQ_SCATTER: - case ZMQ_DGRAM: - s = new (std::nothrow) session_base_t (io_thread_, active_, - socket_, options_, addr_); - break; - default: - errno = EINVAL; - return NULL; - } - alloc_assert (s); - return s; -} - -zmq::session_base_t::session_base_t (class io_thread_t *io_thread_, - bool active_, class socket_base_t *socket_, const options_t &options_, - address_t *addr_) : - own_t (io_thread_, options_), - io_object_t (io_thread_), - active (active_), - pipe (NULL), - zap_pipe (NULL), - incomplete_in (false), - pending (false), - engine (NULL), - socket (socket_), - io_thread (io_thread_), - has_linger_timer (false), - addr (addr_) -{ -} - -const char *zmq::session_base_t::get_endpoint () const -{ - return engine->get_endpoint (); -} - -zmq::session_base_t::~session_base_t () -{ - zmq_assert (!pipe); - zmq_assert (!zap_pipe); - - // If there's still a pending linger timer, remove it. - if (has_linger_timer) { - cancel_timer (linger_timer_id); - has_linger_timer = false; - } - - // Close the engine. - if (engine) - engine->terminate (); - - LIBZMQ_DELETE(addr); -} - -void zmq::session_base_t::attach_pipe (pipe_t *pipe_) -{ - zmq_assert (!is_terminating ()); - zmq_assert (!pipe); - zmq_assert (pipe_); - pipe = pipe_; - pipe->set_event_sink (this); -} - -int zmq::session_base_t::pull_msg (msg_t *msg_) -{ - if (!pipe || !pipe->read (msg_)) { - errno = EAGAIN; - return -1; - } - - incomplete_in = msg_->flags () & msg_t::more ? true : false; - - return 0; -} - -int zmq::session_base_t::push_msg (msg_t *msg_) -{ - if(msg_->flags() & msg_t::command) - return 0; - if (pipe && pipe->write (msg_)) { - int rc = msg_->init (); - errno_assert (rc == 0); - return 0; - } - - errno = EAGAIN; - return -1; -} - -int zmq::session_base_t::read_zap_msg (msg_t *msg_) -{ - if (zap_pipe == NULL) { - errno = ENOTCONN; - return -1; - } - - if (!zap_pipe->read (msg_)) { - errno = EAGAIN; - return -1; - } - - return 0; -} - -int zmq::session_base_t::write_zap_msg (msg_t *msg_) -{ - if (zap_pipe == NULL || !zap_pipe->write (msg_)) { - errno = ENOTCONN; - return -1; - } - - if ((msg_->flags () & msg_t::more) == 0) - zap_pipe->flush (); - - const int rc = msg_->init (); - errno_assert (rc == 0); - return 0; -} - -void zmq::session_base_t::reset () -{ -} - -void zmq::session_base_t::flush () -{ - if (pipe) - pipe->flush (); -} - -void zmq::session_base_t::clean_pipes () -{ - zmq_assert (pipe != NULL); - - // Get rid of half-processed messages in the out pipe. Flush any - // unflushed messages upstream. - pipe->rollback (); - pipe->flush (); - - // Remove any half-read message from the in pipe. - while (incomplete_in) { - msg_t msg; - int rc = msg.init (); - errno_assert (rc == 0); - rc = pull_msg (&msg); - errno_assert (rc == 0); - rc = msg.close (); - errno_assert (rc == 0); - } -} - -void zmq::session_base_t::pipe_terminated (pipe_t *pipe_) -{ - // Drop the reference to the deallocated pipe if required. - zmq_assert (pipe_ == pipe - || pipe_ == zap_pipe - || terminating_pipes.count (pipe_) == 1); - - if (pipe_ == pipe) { - // If this is our current pipe, remove it - pipe = NULL; - if (has_linger_timer) { - cancel_timer (linger_timer_id); - has_linger_timer = false; - } - } - else - if (pipe_ == zap_pipe) - zap_pipe = NULL; - else - // Remove the pipe from the detached pipes set - terminating_pipes.erase (pipe_); - - if (!is_terminating () && options.raw_socket) { - if (engine) { - engine->terminate (); - engine = NULL; - } - terminate (); - } - - // If we are waiting for pending messages to be sent, at this point - // we are sure that there will be no more messages and we can proceed - // with termination safely. - if (pending && !pipe && !zap_pipe && terminating_pipes.empty ()) { - pending = false; - own_t::process_term (0); - } -} - -void zmq::session_base_t::read_activated (pipe_t *pipe_) -{ - // Skip activating if we're detaching this pipe - if (unlikely (pipe_ != pipe && pipe_ != zap_pipe)) { - zmq_assert (terminating_pipes.count (pipe_) == 1); - return; - } - - if (unlikely (engine == NULL)) { - pipe->check_read (); - return; - } - - if (likely (pipe_ == pipe)) - engine->restart_output (); - else { - // i.e. pipe_ == zap_pipe - engine->zap_msg_available (); - } -} - -void zmq::session_base_t::write_activated (pipe_t *pipe_) -{ - // Skip activating if we're detaching this pipe - if (pipe != pipe_) { - zmq_assert (terminating_pipes.count (pipe_) == 1); - return; - } - - if (engine) - engine->restart_input (); -} - -void zmq::session_base_t::hiccuped (pipe_t *) -{ - // Hiccups are always sent from session to socket, not the other - // way round. - zmq_assert (false); -} - -zmq::socket_base_t *zmq::session_base_t::get_socket () -{ - return socket; -} - -void zmq::session_base_t::process_plug () -{ - if (active) - start_connecting (false); -} - -// This functions can return 0 on success or -1 and errno=ECONNREFUSED if ZAP -// is not setup (IE: inproc://zeromq.zap.01 does not exist in the same context) -// or it aborts on any other error. In other words, either ZAP is not -// configured or if it is configured it MUST be configured correctly and it -// MUST work, otherwise authentication cannot be guaranteed and it would be a -// security flaw. -int zmq::session_base_t::zap_connect () -{ - if (zap_pipe != NULL) - return 0; - - endpoint_t peer = find_endpoint ("inproc://zeromq.zap.01"); - if (peer.socket == NULL) { - errno = ECONNREFUSED; - return -1; - } - zmq_assert (peer.options.type == ZMQ_REP || - peer.options.type == ZMQ_ROUTER || - peer.options.type == ZMQ_SERVER); - - // Create a bi-directional pipe that will connect - // session with zap socket. - object_t *parents [2] = {this, peer.socket}; - pipe_t *new_pipes [2] = {NULL, NULL}; - int hwms [2] = {0, 0}; - bool conflates [2] = {false, false}; - int rc = pipepair (parents, new_pipes, hwms, conflates); - errno_assert (rc == 0); - - // Attach local end of the pipe to this socket object. - zap_pipe = new_pipes [0]; - zap_pipe->set_nodelay (); - zap_pipe->set_event_sink (this); - - send_bind (peer.socket, new_pipes [1], false); - - // Send empty routing id if required by the peer. - if (peer.options.recv_routing_id) { - msg_t id; - rc = id.init (); - errno_assert (rc == 0); - id.set_flags (msg_t::routing_id); - bool ok = zap_pipe->write (&id); - zmq_assert (ok); - zap_pipe->flush (); - } - - return 0; -} - -bool zmq::session_base_t::zap_enabled () -{ - return ( - options.mechanism != ZMQ_NULL || - !options.zap_domain.empty() - ); -} - -void zmq::session_base_t::process_attach (i_engine *engine_) -{ - zmq_assert (engine_ != NULL); - - // Create the pipe if it does not exist yet. - if (!pipe && !is_terminating ()) { - object_t *parents [2] = {this, socket}; - pipe_t *pipes [2] = {NULL, NULL}; - - bool conflate = options.conflate && - (options.type == ZMQ_DEALER || - options.type == ZMQ_PULL || - options.type == ZMQ_PUSH || - options.type == ZMQ_PUB || - options.type == ZMQ_SUB); - - int hwms [2] = {conflate? -1 : options.rcvhwm, - conflate? -1 : options.sndhwm}; - bool conflates [2] = {conflate, conflate}; - int rc = pipepair (parents, pipes, hwms, conflates); - errno_assert (rc == 0); - - // Plug the local end of the pipe. - pipes [0]->set_event_sink (this); - - // Remember the local end of the pipe. - zmq_assert (!pipe); - pipe = pipes [0]; - - // Ask socket to plug into the remote end of the pipe. - send_bind (socket, pipes [1]); - } - - // Plug in the engine. - zmq_assert (!engine); - engine = engine_; - engine->plug (io_thread, this); -} - -void zmq::session_base_t::engine_error ( - zmq::stream_engine_t::error_reason_t reason) -{ - // Engine is dead. Let's forget about it. - engine = NULL; - - // Remove any half-done messages from the pipes. - if (pipe) - clean_pipes (); - - zmq_assert (reason == stream_engine_t::connection_error - || reason == stream_engine_t::timeout_error - || reason == stream_engine_t::protocol_error); - - switch (reason) { - case stream_engine_t::timeout_error: - /* FALLTHROUGH */ - case stream_engine_t::connection_error: - if (active) { - reconnect (); - break; - } - /* FALLTHROUGH */ - case stream_engine_t::protocol_error: - if (pending) { - if (pipe) - pipe->terminate (0); - if (zap_pipe) - zap_pipe->terminate (0); - } else { - terminate (); - } - break; - } - - // Just in case there's only a delimiter in the pipe. - if (pipe) - pipe->check_read (); - - if (zap_pipe) - zap_pipe->check_read (); -} - -void zmq::session_base_t::process_term (int linger_) -{ - zmq_assert (!pending); - - // If the termination of the pipe happens before the term command is - // delivered there's nothing much to do. We can proceed with the - // standard termination immediately. - if (!pipe && !zap_pipe && terminating_pipes.empty ()) { - own_t::process_term (0); - return; - } - - pending = true; - - if (pipe != NULL) { - // If there's finite linger value, delay the termination. - // If linger is infinite (negative) we don't even have to set - // the timer. - if (linger_ > 0) { - zmq_assert (!has_linger_timer); - add_timer (linger_, linger_timer_id); - has_linger_timer = true; - } - - // Start pipe termination process. Delay the termination till all messages - // are processed in case the linger time is non-zero. - pipe->terminate (linger_ != 0); - - // TODO: Should this go into pipe_t::terminate ? - // In case there's no engine and there's only delimiter in the - // pipe it wouldn't be ever read. Thus we check for it explicitly. - if (!engine) - pipe->check_read (); - } - - if (zap_pipe != NULL) - zap_pipe->terminate (false); -} - -void zmq::session_base_t::timer_event (int id_) -{ - // Linger period expired. We can proceed with termination even though - // there are still pending messages to be sent. - zmq_assert (id_ == linger_timer_id); - has_linger_timer = false; - - // Ask pipe to terminate even though there may be pending messages in it. - zmq_assert (pipe); - pipe->terminate (false); -} - -void zmq::session_base_t::reconnect () -{ - // For delayed connect situations, terminate the pipe - // and reestablish later on - if (pipe && options.immediate == 1 - && addr->protocol != "pgm" && addr->protocol != "epgm" - && addr->protocol != "norm" && addr->protocol != "udp") { - pipe->hiccup (); - pipe->terminate (false); - terminating_pipes.insert (pipe); - pipe = NULL; - - if (has_linger_timer) { - cancel_timer (linger_timer_id); - has_linger_timer = false; - } - } - - reset (); - - // Reconnect. - if (options.reconnect_ivl != -1) - start_connecting (true); - else { - std::string *ep = new (std::string); - addr->to_string (*ep); - send_term_endpoint (socket, ep); - } - - // For subscriber sockets we hiccup the inbound pipe, which will cause - // the socket object to resend all the subscriptions. - if (pipe && (options.type == ZMQ_SUB || options.type == ZMQ_XSUB || options.type == ZMQ_DISH)) - pipe->hiccup (); -} - -void zmq::session_base_t::start_connecting (bool wait_) -{ - zmq_assert (active); - - // Choose I/O thread to run connecter in. Given that we are already - // running in an I/O thread, there must be at least one available. - io_thread_t *io_thread = choose_io_thread (options.affinity); - zmq_assert (io_thread); - - // Create the connecter object. - - if (addr->protocol == "tcp") { - if (!options.socks_proxy_address.empty()) { - address_t *proxy_address = new (std::nothrow) - address_t ("tcp", options.socks_proxy_address, this->get_ctx ()); - alloc_assert (proxy_address); - socks_connecter_t *connecter = - new (std::nothrow) socks_connecter_t ( - io_thread, this, options, addr, proxy_address, wait_); - alloc_assert (connecter); - launch_child (connecter); - } - else { - tcp_connecter_t *connecter = new (std::nothrow) - tcp_connecter_t (io_thread, this, options, addr, wait_); - alloc_assert (connecter); - launch_child (connecter); - } - return; - } - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - if (addr->protocol == "ipc") { - ipc_connecter_t *connecter = new (std::nothrow) ipc_connecter_t ( - io_thread, this, options, addr, wait_); - alloc_assert (connecter); - launch_child (connecter); - return; - } -#endif -#if defined ZMQ_HAVE_TIPC - if (addr->protocol == "tipc") { - tipc_connecter_t *connecter = new (std::nothrow) tipc_connecter_t ( - io_thread, this, options, addr, wait_); - alloc_assert (connecter); - launch_child (connecter); - return; - } -#endif - - if (addr->protocol == "udp") { - zmq_assert (options.type == ZMQ_DISH || options.type == ZMQ_RADIO || options.type == ZMQ_DGRAM); - - udp_engine_t* engine = new (std::nothrow) udp_engine_t (options); - alloc_assert (engine); - - bool recv = false; - bool send = false; - - if (options.type == ZMQ_RADIO) { - send = true; - recv = false; - } - else if (options.type == ZMQ_DISH) { - send = false; - recv = true; - } - else if (options.type == ZMQ_DGRAM) { - send = true; - recv = true; - } - - int rc = engine->init (addr, send, recv); - errno_assert (rc == 0); - - send_attach (this, engine); - - return; - } - -#ifdef ZMQ_HAVE_OPENPGM - - // Both PGM and EPGM transports are using the same infrastructure. - if (addr->protocol == "pgm" || addr->protocol == "epgm") { - - zmq_assert (options.type == ZMQ_PUB || options.type == ZMQ_XPUB - || options.type == ZMQ_SUB || options.type == ZMQ_XSUB); - - // For EPGM transport with UDP encapsulation of PGM is used. - bool const udp_encapsulation = addr->protocol == "epgm"; - - // At this point we'll create message pipes to the session straight - // away. There's no point in delaying it as no concept of 'connect' - // exists with PGM anyway. - if (options.type == ZMQ_PUB || options.type == ZMQ_XPUB) { - - // PGM sender. - pgm_sender_t *pgm_sender = new (std::nothrow) pgm_sender_t ( - io_thread, options); - alloc_assert (pgm_sender); - - int rc = pgm_sender->init (udp_encapsulation, addr->address.c_str ()); - errno_assert (rc == 0); - - send_attach (this, pgm_sender); - } - else { - - // PGM receiver. - pgm_receiver_t *pgm_receiver = new (std::nothrow) pgm_receiver_t ( - io_thread, options); - alloc_assert (pgm_receiver); - - int rc = pgm_receiver->init (udp_encapsulation, addr->address.c_str ()); - errno_assert (rc == 0); - - send_attach (this, pgm_receiver); - } - - return; - } -#endif - -#ifdef ZMQ_HAVE_NORM - if (addr->protocol == "norm") { - // At this point we'll create message pipes to the session straight - // away. There's no point in delaying it as no concept of 'connect' - // exists with NORM anyway. - if (options.type == ZMQ_PUB || options.type == ZMQ_XPUB) { - - // NORM sender. - norm_engine_t* norm_sender = new (std::nothrow) norm_engine_t(io_thread, options); - alloc_assert (norm_sender); - - int rc = norm_sender->init (addr->address.c_str (), true, false); - errno_assert (rc == 0); - - send_attach (this, norm_sender); - } - else { // ZMQ_SUB or ZMQ_XSUB - - // NORM receiver. - norm_engine_t* norm_receiver = new (std::nothrow) norm_engine_t (io_thread, options); - alloc_assert (norm_receiver); - - int rc = norm_receiver->init (addr->address.c_str (), false, true); - errno_assert (rc == 0); - - send_attach (this, norm_receiver); - } - return; - } -#endif // ZMQ_HAVE_NORM - -#if defined ZMQ_HAVE_VMCI - if (addr->protocol == "vmci") { - vmci_connecter_t *connecter = new (std::nothrow) vmci_connecter_t ( - io_thread, this, options, addr, wait_); - alloc_assert (connecter); - launch_child (connecter); - return; - } -#endif - - zmq_assert (false); -} diff --git a/dep/libzmq/src/session_base.hpp b/dep/libzmq/src/session_base.hpp deleted file mode 100644 index be92a67ccb..0000000000 --- a/dep/libzmq/src/session_base.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SESSION_BASE_HPP_INCLUDED__ -#define __ZMQ_SESSION_BASE_HPP_INCLUDED__ - -#include -#include - -#include "own.hpp" -#include "io_object.hpp" -#include "pipe.hpp" -#include "socket_base.hpp" -#include "stream_engine.hpp" - -namespace zmq -{ - - class pipe_t; - class io_thread_t; - class socket_base_t; - struct i_engine; - struct address_t; - - class session_base_t : - public own_t, - public io_object_t, - public i_pipe_events - { - public: - - // Create a session of the particular type. - static session_base_t *create (zmq::io_thread_t *io_thread_, - bool active_, zmq::socket_base_t *socket_, - const options_t &options_, address_t *addr_); - - // To be used once only, when creating the session. - void attach_pipe (zmq::pipe_t *pipe_); - - // Following functions are the interface exposed towards the engine. - virtual void reset (); - void flush (); - void engine_error (zmq::stream_engine_t::error_reason_t reason); - - // i_pipe_events interface implementation. - void read_activated (zmq::pipe_t *pipe_); - void write_activated (zmq::pipe_t *pipe_); - void hiccuped (zmq::pipe_t *pipe_); - void pipe_terminated (zmq::pipe_t *pipe_); - - // Delivers a message. Returns 0 if successful; -1 otherwise. - // The function takes ownership of the message. - virtual int push_msg (msg_t *msg_); - - int zap_connect (); - bool zap_enabled (); - - // Fetches a message. Returns 0 if successful; -1 otherwise. - // The caller is responsible for freeing the message when no - // longer used. - virtual int pull_msg (msg_t *msg_); - - // Receives message from ZAP socket. - // Returns 0 on success; -1 otherwise. - // The caller is responsible for freeing the message. - int read_zap_msg (msg_t *msg_); - - // Sends message to ZAP socket. - // Returns 0 on success; -1 otherwise. - // The function takes ownership of the message. - int write_zap_msg (msg_t *msg_); - - socket_base_t *get_socket (); - const char *get_endpoint () const; - - protected: - - session_base_t (zmq::io_thread_t *io_thread_, bool active_, - zmq::socket_base_t *socket_, const options_t &options_, - address_t *addr_); - virtual ~session_base_t (); - - private: - - void start_connecting (bool wait_); - - void reconnect (); - - // Handlers for incoming commands. - void process_plug (); - void process_attach (zmq::i_engine *engine_); - void process_term (int linger_); - - // i_poll_events handlers. - void timer_event (int id_); - - // Remove any half processed messages. Flush unflushed messages. - // Call this function when engine disconnect to get rid of leftovers. - void clean_pipes (); - - // If true, this session (re)connects to the peer. Otherwise, it's - // a transient session created by the listener. - const bool active; - - // Pipe connecting the session to its socket. - zmq::pipe_t *pipe; - - // Pipe used to exchange messages with ZAP socket. - zmq::pipe_t *zap_pipe; - - // This set is added to with pipes we are disconnecting, but haven't yet completed - std::set terminating_pipes; - - // This flag is true if the remainder of the message being processed - // is still in the in pipe. - bool incomplete_in; - - // True if termination have been suspended to push the pending - // messages to the network. - bool pending; - - // The protocol I/O engine connected to the session. - zmq::i_engine *engine; - - // The socket the session belongs to. - zmq::socket_base_t *socket; - - // I/O thread the session is living in. It will be used to plug in - // the engines into the same thread. - zmq::io_thread_t *io_thread; - - // ID of the linger timer - enum {linger_timer_id = 0x20}; - - // True is linger timer is running. - bool has_linger_timer; - - // Protocol and address to use when connecting. - address_t *addr; - - session_base_t (const session_base_t&); - const session_base_t &operator = (const session_base_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/signaler.cpp b/dep/libzmq/src/signaler.cpp deleted file mode 100644 index 4afffdd020..0000000000 --- a/dep/libzmq/src/signaler.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -// On AIX, poll.h has to be included before zmq.h to get consistent -// definition of pollfd structure (AIX uses 'reqevents' and 'retnevents' -// instead of 'events' and 'revents' and defines macros to map from POSIX-y -// names to AIX-specific names). -// zmq.h must be included *after* poll.h for AIX to build properly. -// precompiled.hpp includes include/zmq.h -#if defined ZMQ_POLL_BASED_ON_POLL && defined ZMQ_HAVE_AIX -#include -#endif - -#include "precompiled.hpp" -#include "poller.hpp" - -#if defined ZMQ_POLL_BASED_ON_POLL -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_AIX -#include -#endif -#elif defined ZMQ_POLL_BASED_ON_SELECT -#if defined ZMQ_HAVE_WINDOWS -#elif defined ZMQ_HAVE_HPUX -#include -#include -#include -#elif defined ZMQ_HAVE_OPENVMS -#include -#include -#else -#include -#endif -#endif - -#include "signaler.hpp" -#include "likely.hpp" -#include "stdint.hpp" -#include "config.hpp" -#include "err.hpp" -#include "fd.hpp" -#include "ip.hpp" - -#if defined ZMQ_HAVE_EVENTFD -#include -#endif - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#endif - -#if !defined (ZMQ_HAVE_WINDOWS) -// Helper to sleep for specific number of milliseconds (or until signal) -// -static int sleep_ms (unsigned int ms_) -{ - if (ms_ == 0) - return 0; -#if defined ZMQ_HAVE_WINDOWS - Sleep (ms_ > 0 ? ms_ : INFINITE); - return 0; -#elif defined ZMQ_HAVE_ANDROID - usleep (ms_ * 1000); - return 0; -#else - return usleep (ms_ * 1000); -#endif -} - -// Helper to wait on close(), for non-blocking sockets, until it completes -// If EAGAIN is received, will sleep briefly (1-100ms) then try again, until -// the overall timeout is reached. -// -static int close_wait_ms (int fd_, unsigned int max_ms_ = 2000) -{ - unsigned int ms_so_far = 0; - unsigned int step_ms = max_ms_ / 10; - if (step_ms < 1) - step_ms = 1; - if (step_ms > 100) - step_ms = 100; - - int rc = 0; // do not sleep on first attempt - do { - if (rc == -1 && errno == EAGAIN) { - sleep_ms (step_ms); - ms_so_far += step_ms; - } - rc = close (fd_); - } while (ms_so_far < max_ms_ && rc == -1 && errno == EAGAIN); - - return rc; -} -#endif - -zmq::signaler_t::signaler_t () -{ - // Create the socketpair for signaling. - if (make_fdpair (&r, &w) == 0) { - unblock_socket (w); - unblock_socket (r); - } -#ifdef HAVE_FORK - pid = getpid (); -#endif -} - -// This might get run after some part of construction failed, leaving one or -// both of r and w retired_fd. -zmq::signaler_t::~signaler_t () -{ -#if defined ZMQ_HAVE_EVENTFD - if (r == retired_fd) return; - int rc = close_wait_ms (r); - errno_assert (rc == 0); -#elif defined ZMQ_HAVE_WINDOWS - if (w != retired_fd) { - const struct linger so_linger = { 1, 0 }; - int rc = setsockopt (w, SOL_SOCKET, SO_LINGER, - (const char *) &so_linger, sizeof so_linger); - // Only check shutdown if WSASTARTUP was previously done - if (rc == 0 || WSAGetLastError () != WSANOTINITIALISED) { - wsa_assert (rc != SOCKET_ERROR); - rc = closesocket (w); - wsa_assert (rc != SOCKET_ERROR); - if (r == retired_fd) return; - rc = closesocket (r); - wsa_assert (rc != SOCKET_ERROR); - } - } -#else - if (w != retired_fd) { - int rc = close_wait_ms (w); - errno_assert (rc == 0); - } - if (r != retired_fd) { - int rc = close_wait_ms (r); - errno_assert (rc == 0); - } -#endif -} - -zmq::fd_t zmq::signaler_t::get_fd () const -{ - return r; -} - -void zmq::signaler_t::send () -{ -#if defined HAVE_FORK - if (unlikely (pid != getpid ())) { - //printf("Child process %d signaler_t::send returning without sending #1\n", getpid()); - return; // do not send anything in forked child context - } -#endif -#if defined ZMQ_HAVE_EVENTFD - const uint64_t inc = 1; - ssize_t sz = write (w, &inc, sizeof (inc)); - errno_assert (sz == sizeof (inc)); -#elif defined ZMQ_HAVE_WINDOWS - unsigned char dummy = 0; - while (true) { - int nbytes = ::send (w, (char*) &dummy, sizeof (dummy), 0); - wsa_assert (nbytes != SOCKET_ERROR); - if (unlikely (nbytes == SOCKET_ERROR)) - continue; - zmq_assert (nbytes == sizeof (dummy)); - break; - } -#else - unsigned char dummy = 0; - while (true) { - ssize_t nbytes = ::send (w, &dummy, sizeof (dummy), 0); - if (unlikely (nbytes == -1 && errno == EINTR)) - continue; -#if defined(HAVE_FORK) - if (unlikely (pid != getpid ())) { - //printf("Child process %d signaler_t::send returning without sending #2\n", getpid()); - errno = EINTR; - break; - } -#endif - zmq_assert (nbytes == sizeof dummy); - break; - } -#endif -} - -int zmq::signaler_t::wait (int timeout_) -{ -#ifdef HAVE_FORK - if (unlikely (pid != getpid ())) { - // we have forked and the file descriptor is closed. Emulate an interrupt - // response. - //printf("Child process %d signaler_t::wait returning simulating interrupt #1\n", getpid()); - errno = EINTR; - return -1; - } -#endif - -#ifdef ZMQ_POLL_BASED_ON_POLL - struct pollfd pfd; - pfd.fd = r; - pfd.events = POLLIN; - int rc = poll (&pfd, 1, timeout_); - if (unlikely (rc < 0)) { - errno_assert (errno == EINTR); - return -1; - } - else - if (unlikely (rc == 0)) { - errno = EAGAIN; - return -1; - } -#ifdef HAVE_FORK - else - if (unlikely (pid != getpid ())) { - // we have forked and the file descriptor is closed. Emulate an interrupt - // response. - //printf("Child process %d signaler_t::wait returning simulating interrupt #2\n", getpid()); - errno = EINTR; - return -1; - } -#endif - zmq_assert (rc == 1); - zmq_assert (pfd.revents & POLLIN); - return 0; - -#elif defined ZMQ_POLL_BASED_ON_SELECT - - fd_set fds; - FD_ZERO (&fds); - FD_SET (r, &fds); - struct timeval timeout; - if (timeout_ >= 0) { - timeout.tv_sec = timeout_ / 1000; - timeout.tv_usec = timeout_ % 1000 * 1000; - } -#ifdef ZMQ_HAVE_WINDOWS - int rc = select (0, &fds, NULL, NULL, - timeout_ >= 0 ? &timeout : NULL); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = select (r + 1, &fds, NULL, NULL, - timeout_ >= 0 ? &timeout : NULL); - if (unlikely (rc < 0)) { - errno_assert (errno == EINTR); - return -1; - } -#endif - if (unlikely (rc == 0)) { - errno = EAGAIN; - return -1; - } - zmq_assert (rc == 1); - return 0; - -#else -#error -#endif -} - -void zmq::signaler_t::recv () -{ - // Attempt to read a signal. -#if defined ZMQ_HAVE_EVENTFD - uint64_t dummy; - ssize_t sz = read (r, &dummy, sizeof (dummy)); - errno_assert (sz == sizeof (dummy)); - - // If we accidentally grabbed the next signal(s) along with the current - // one, return it back to the eventfd object. - if (unlikely (dummy > 1)) { - const uint64_t inc = dummy - 1; - ssize_t sz2 = write (w, &inc, sizeof (inc)); - errno_assert (sz2 == sizeof (inc)); - return; - } - - zmq_assert (dummy == 1); -#else - unsigned char dummy; -#if defined ZMQ_HAVE_WINDOWS - int nbytes = ::recv (r, (char *) &dummy, sizeof (dummy), 0); - wsa_assert (nbytes != SOCKET_ERROR); -#else - ssize_t nbytes = ::recv (r, &dummy, sizeof (dummy), 0); - errno_assert (nbytes >= 0); -#endif - zmq_assert (nbytes == sizeof (dummy)); - zmq_assert (dummy == 0); -#endif -} - -int zmq::signaler_t::recv_failable () -{ - // Attempt to read a signal. -#if defined ZMQ_HAVE_EVENTFD - uint64_t dummy; - ssize_t sz = read (r, &dummy, sizeof (dummy)); - if (sz == -1) { - errno_assert (errno == EAGAIN); - return -1; - } - else { - errno_assert (sz == sizeof (dummy)); - - // If we accidentally grabbed the next signal(s) along with the current - // one, return it back to the eventfd object. - if (unlikely (dummy > 1)) { - const uint64_t inc = dummy - 1; - ssize_t sz2 = write (w, &inc, sizeof (inc)); - errno_assert (sz2 == sizeof (inc)); - return 0; - } - - zmq_assert (dummy == 1); - } -#else - unsigned char dummy; -#if defined ZMQ_HAVE_WINDOWS - int nbytes = ::recv (r, (char *) &dummy, sizeof (dummy), 0); - if (nbytes == SOCKET_ERROR) { - const int last_error = WSAGetLastError(); - if (last_error == WSAEWOULDBLOCK) { - errno = EAGAIN; - return -1; - } - wsa_assert (last_error == WSAEWOULDBLOCK); - } -#else - ssize_t nbytes = ::recv (r, &dummy, sizeof (dummy), 0); - if (nbytes == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { - errno = EAGAIN; - return -1; - } - errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR); - } -#endif - zmq_assert (nbytes == sizeof (dummy)); - zmq_assert (dummy == 0); -#endif - return 0; -} - -#ifdef HAVE_FORK -void zmq::signaler_t::forked () -{ - // Close file descriptors created in the parent and create new pair - close (r); - close (w); - make_fdpair (&r, &w); -} -#endif - -// Returns -1 if we could not make the socket pair successfully -int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) -{ -#if defined ZMQ_HAVE_EVENTFD - int flags = 0; -#if defined ZMQ_HAVE_EVENTFD_CLOEXEC - // Setting this option result in sane behaviour when exec() functions - // are used. Old sockets are closed and don't block TCP ports, avoid - // leaks, etc. - flags |= EFD_CLOEXEC; -#endif - fd_t fd = eventfd (0, flags); - if (fd == -1) { - errno_assert (errno == ENFILE || errno == EMFILE); - *w_ = *r_ = -1; - return -1; - } - else { - *w_ = *r_ = fd; - return 0; - } - -#elif defined ZMQ_HAVE_WINDOWS -# if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP - // Windows CE does not manage security attributes - SECURITY_DESCRIPTOR sd; - SECURITY_ATTRIBUTES sa; - memset (&sd, 0, sizeof sd); - memset (&sa, 0, sizeof sa); - - InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); - SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE); - - sa.nLength = sizeof (SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = &sd; -# endif - - // This function has to be in a system-wide critical section so that - // two instances of the library don't accidentally create signaler - // crossing the process boundary. - // We'll use named event object to implement the critical section. - // Note that if the event object already exists, the CreateEvent requests - // EVENT_ALL_ACCESS access right. If this fails, we try to open - // the event object asking for SYNCHRONIZE access only. - HANDLE sync = NULL; - - // Create critical section only if using fixed signaler port - // Use problematic Event implementation for compatibility if using old port 5905. - // Otherwise use Mutex implementation. - int event_signaler_port = 5905; - - if (signaler_port == event_signaler_port) { -# if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP - sync = CreateEventW (&sa, FALSE, TRUE, L"Global\\zmq-signaler-port-sync"); -# else - sync = CreateEventW (NULL, FALSE, TRUE, L"Global\\zmq-signaler-port-sync"); -# endif - if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED) - sync = OpenEventW (SYNCHRONIZE | EVENT_MODIFY_STATE, - FALSE, L"Global\\zmq-signaler-port-sync"); - - win_assert (sync != NULL); - } - else - if (signaler_port != 0) { - wchar_t mutex_name [MAX_PATH]; -# ifdef __MINGW32__ - _snwprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port); -# else - swprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port); -# endif - -# if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP - sync = CreateMutexW (&sa, FALSE, mutex_name); -# else - sync = CreateMutexW (NULL, FALSE, mutex_name); -# endif - if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED) - sync = OpenMutexW (SYNCHRONIZE, FALSE, mutex_name); - - win_assert (sync != NULL); - } - - // Windows has no 'socketpair' function. CreatePipe is no good as pipe - // handles cannot be polled on. Here we create the socketpair by hand. - *w_ = INVALID_SOCKET; - *r_ = INVALID_SOCKET; - - // Create listening socket. - SOCKET listener; - listener = open_socket (AF_INET, SOCK_STREAM, 0); - wsa_assert (listener != INVALID_SOCKET); - - // Set SO_REUSEADDR and TCP_NODELAY on listening socket. - BOOL so_reuseaddr = 1; - int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, - (char *) &so_reuseaddr, sizeof so_reuseaddr); - wsa_assert (rc != SOCKET_ERROR); - BOOL tcp_nodelay = 1; - rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, - (char *) &tcp_nodelay, sizeof tcp_nodelay); - wsa_assert (rc != SOCKET_ERROR); - - // Init sockaddr to signaler port. - struct sockaddr_in addr; - memset (&addr, 0, sizeof addr); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - addr.sin_port = htons (signaler_port); - - // Create the writer socket. - *w_ = open_socket (AF_INET, SOCK_STREAM, 0); - wsa_assert (*w_ != INVALID_SOCKET); - - // Set TCP_NODELAY on writer socket. - rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, - (char *) &tcp_nodelay, sizeof tcp_nodelay); - wsa_assert (rc != SOCKET_ERROR); - - if (sync != NULL) { - // Enter the critical section. - DWORD dwrc = WaitForSingleObject (sync, INFINITE); - zmq_assert (dwrc == WAIT_OBJECT_0 || dwrc == WAIT_ABANDONED); - } - - // Bind listening socket to signaler port. - rc = bind (listener, (const struct sockaddr *) &addr, sizeof addr); - - if (rc != SOCKET_ERROR && signaler_port == 0) { - // Retrieve ephemeral port number - int addrlen = sizeof addr; - rc = getsockname (listener, (struct sockaddr *) &addr, &addrlen); - } - - // Listen for incoming connections. - if (rc != SOCKET_ERROR) - rc = listen (listener, 1); - - // Connect writer to the listener. - if (rc != SOCKET_ERROR) - rc = connect (*w_, (struct sockaddr *) &addr, sizeof addr); - - // Accept connection from writer. - if (rc != SOCKET_ERROR) - *r_ = accept (listener, NULL, NULL); - - // Send/receive large chunk to work around TCP slow start - // This code is a workaround for #1608 - if (*r_ != INVALID_SOCKET) { - size_t dummy_size = 1024 * 1024; // 1M to overload default receive buffer - unsigned char *dummy = (unsigned char *) malloc (dummy_size); - wsa_assert (dummy); - - int still_to_send = (int) dummy_size; - int still_to_recv = (int) dummy_size; - while (still_to_send || still_to_recv) { - int nbytes; - if (still_to_send > 0) { - nbytes = ::send (*w_, (char *) (dummy + dummy_size - still_to_send), still_to_send, 0); - wsa_assert (nbytes != SOCKET_ERROR); - still_to_send -= nbytes; - } - nbytes = ::recv (*r_, (char *) (dummy + dummy_size - still_to_recv), still_to_recv, 0); - wsa_assert (nbytes != SOCKET_ERROR); - still_to_recv -= nbytes; - } - free (dummy); - } - - // Save errno if error occurred in bind/listen/connect/accept. - int saved_errno = 0; - if (*r_ == INVALID_SOCKET) - saved_errno = WSAGetLastError (); - - // We don't need the listening socket anymore. Close it. - rc = closesocket (listener); - wsa_assert(rc != SOCKET_ERROR); - - if (sync != NULL) { - // Exit the critical section. - BOOL brc; - if (signaler_port == event_signaler_port) - brc = SetEvent (sync); - else - brc = ReleaseMutex (sync); - win_assert (brc != 0); - - // Release the kernel object - brc = CloseHandle (sync); - win_assert (brc != 0); - } - - if (*r_ != INVALID_SOCKET) { -# if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP - // On Windows, preventing sockets to be inherited by child processes. - BOOL brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0); - win_assert (brc); -# endif - return 0; - } - else { - // Cleanup writer if connection failed - if (*w_ != INVALID_SOCKET) { - rc = closesocket (*w_); - wsa_assert (rc != SOCKET_ERROR); - *w_ = INVALID_SOCKET; - } - // Set errno from saved value - errno = wsa_error_to_errno (saved_errno); - return -1; - } - -#elif defined ZMQ_HAVE_OPENVMS - - // Whilst OpenVMS supports socketpair - it maps to AF_INET only. Further, - // it does not set the socket options TCP_NODELAY and TCP_NODELACK which - // can lead to performance problems. - // - // The bug will be fixed in V5.6 ECO4 and beyond. In the meantime, we'll - // create the socket pair manually. - struct sockaddr_in lcladdr; - memset (&lcladdr, 0, sizeof lcladdr); - lcladdr.sin_family = AF_INET; - lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - lcladdr.sin_port = 0; - - int listener = open_socket (AF_INET, SOCK_STREAM, 0); - errno_assert (listener != -1); - - int on = 1; - int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); - errno_assert (rc != -1); - - rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on); - errno_assert (rc != -1); - - rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr); - errno_assert (rc != -1); - - socklen_t lcladdr_len = sizeof lcladdr; - - rc = getsockname (listener, (struct sockaddr *) &lcladdr, &lcladdr_len); - errno_assert (rc != -1); - - rc = listen (listener, 1); - errno_assert (rc != -1); - - *w_ = open_socket (AF_INET, SOCK_STREAM, 0); - errno_assert (*w_ != -1); - - rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); - errno_assert (rc != -1); - - rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on); - errno_assert (rc != -1); - - rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr); - errno_assert (rc != -1); - - *r_ = accept (listener, NULL, NULL); - errno_assert (*r_ != -1); - - close (listener); - - return 0; - -#else - // All other implementations support socketpair() - int sv [2]; - int type = SOCK_STREAM; - // Setting this option result in sane behaviour when exec() functions - // are used. Old sockets are closed and don't block TCP ports, avoid - // leaks, etc. -#if defined ZMQ_HAVE_SOCK_CLOEXEC - type |= SOCK_CLOEXEC; -#endif - int rc = socketpair (AF_UNIX, type, 0, sv); - if (rc == -1) { - errno_assert (errno == ENFILE || errno == EMFILE); - *w_ = *r_ = -1; - return -1; - } - else { - // If there's no SOCK_CLOEXEC, let's try the second best option. Note that - // race condition can cause socket not to be closed (if fork happens - // between socket creation and this point). -#if !defined ZMQ_HAVE_SOCK_CLOEXEC && defined FD_CLOEXEC - rc = fcntl (sv [0], F_SETFD, FD_CLOEXEC); - errno_assert (rc != -1); - rc = fcntl (sv [1], F_SETFD, FD_CLOEXEC); - errno_assert (rc != -1); -#endif - *w_ = sv [0]; - *r_ = sv [1]; - return 0; - } -#endif -} diff --git a/dep/libzmq/src/signaler.hpp b/dep/libzmq/src/signaler.hpp deleted file mode 100644 index 12de2f085b..0000000000 --- a/dep/libzmq/src/signaler.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SIGNALER_HPP_INCLUDED__ -#define __ZMQ_SIGNALER_HPP_INCLUDED__ - -#ifdef HAVE_FORK -#include -#endif - -#include "fd.hpp" - -namespace zmq -{ - - // This is a cross-platform equivalent to signal_fd. However, as opposed - // to signal_fd there can be at most one signal in the signaler at any - // given moment. Attempt to send a signal before receiving the previous - // one will result in undefined behaviour. - - class signaler_t - { - public: - - signaler_t (); - ~signaler_t (); - - fd_t get_fd () const; - void send (); - int wait (int timeout_); - void recv (); - int recv_failable (); - -#ifdef HAVE_FORK - // close the file descriptors in a forked child process so that they - // do not interfere with the context in the parent process. - void forked (); -#endif - - private: - - // Creates a pair of file descriptors that will be used - // to pass the signals. - static int make_fdpair (fd_t *r_, fd_t *w_); - - // Underlying write & read file descriptor - // Will be -1 if we exceeded number of available handles - fd_t w; - fd_t r; - - // Disable copying of signaler_t object. - signaler_t (const signaler_t&); - const signaler_t &operator = (const signaler_t&); - -#ifdef HAVE_FORK - // the process that created this context. Used to detect forking. - pid_t pid; - // idempotent close of file descriptors that is safe to use by destructor - // and forked(). - void close_internal (); -#endif - }; -} - -#endif diff --git a/dep/libzmq/src/socket_base.cpp b/dep/libzmq/src/socket_base.cpp deleted file mode 100644 index f18e6e1eb1..0000000000 --- a/dep/libzmq/src/socket_base.cpp +++ /dev/null @@ -1,1778 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include -#include - -#include "macros.hpp" - -#if defined ZMQ_HAVE_WINDOWS -#if defined _MSC_VER -#if defined _WIN32_WCE -#include -#else -#include -#endif -#endif -#else -#include -#include -#endif - -#include "socket_base.hpp" -#include "tcp_listener.hpp" -#include "ipc_listener.hpp" -#include "tipc_listener.hpp" -#include "tcp_connecter.hpp" -#include "io_thread.hpp" -#include "session_base.hpp" -#include "config.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "ctx.hpp" -#include "likely.hpp" -#include "msg.hpp" -#include "address.hpp" -#include "ipc_address.hpp" -#include "tcp_address.hpp" -#include "udp_address.hpp" -#include "tipc_address.hpp" -#include "mailbox.hpp" -#include "mailbox_safe.hpp" - -#if defined ZMQ_HAVE_VMCI -#include "vmci_address.hpp" -#include "vmci_listener.hpp" -#endif - -#ifdef ZMQ_HAVE_OPENPGM -#include "pgm_socket.hpp" -#endif - -#include "pair.hpp" -#include "pub.hpp" -#include "sub.hpp" -#include "req.hpp" -#include "rep.hpp" -#include "pull.hpp" -#include "push.hpp" -#include "dealer.hpp" -#include "router.hpp" -#include "xpub.hpp" -#include "xsub.hpp" -#include "stream.hpp" -#include "server.hpp" -#include "client.hpp" -#include "radio.hpp" -#include "dish.hpp" -#include "gather.hpp" -#include "scatter.hpp" -#include "dgram.hpp" - - - -bool zmq::socket_base_t::check_tag () -{ - return tag == 0xbaddecaf; -} - -zmq::socket_base_t *zmq::socket_base_t::create (int type_, class ctx_t *parent_, - uint32_t tid_, int sid_) -{ - socket_base_t *s = NULL; - switch (type_) { - case ZMQ_PAIR: - s = new (std::nothrow) pair_t (parent_, tid_, sid_); - break; - case ZMQ_PUB: - s = new (std::nothrow) pub_t (parent_, tid_, sid_); - break; - case ZMQ_SUB: - s = new (std::nothrow) sub_t (parent_, tid_, sid_); - break; - case ZMQ_REQ: - s = new (std::nothrow) req_t (parent_, tid_, sid_); - break; - case ZMQ_REP: - s = new (std::nothrow) rep_t (parent_, tid_, sid_); - break; - case ZMQ_DEALER: - s = new (std::nothrow) dealer_t (parent_, tid_, sid_); - break; - case ZMQ_ROUTER: - s = new (std::nothrow) router_t (parent_, tid_, sid_); - break; - case ZMQ_PULL: - s = new (std::nothrow) pull_t (parent_, tid_, sid_); - break; - case ZMQ_PUSH: - s = new (std::nothrow) push_t (parent_, tid_, sid_); - break; - case ZMQ_XPUB: - s = new (std::nothrow) xpub_t (parent_, tid_, sid_); - break; - case ZMQ_XSUB: - s = new (std::nothrow) xsub_t (parent_, tid_, sid_); - break; - case ZMQ_STREAM: - s = new (std::nothrow) stream_t (parent_, tid_, sid_); - break; - case ZMQ_SERVER: - s = new (std::nothrow) server_t (parent_, tid_, sid_); - break; - case ZMQ_CLIENT: - s = new (std::nothrow) client_t (parent_, tid_, sid_); - break; - case ZMQ_RADIO: - s = new (std::nothrow) radio_t (parent_, tid_, sid_); - break; - case ZMQ_DISH: - s = new (std::nothrow) dish_t (parent_, tid_, sid_); - break; - case ZMQ_GATHER: - s = new (std::nothrow) gather_t (parent_, tid_, sid_); - break; - case ZMQ_SCATTER: - s = new (std::nothrow) scatter_t (parent_, tid_, sid_); - break; - case ZMQ_DGRAM: - s = new (std::nothrow) dgram_t (parent_, tid_, sid_); - break; - default: - errno = EINVAL; - return NULL; - } - - alloc_assert (s); - - if (s->mailbox == NULL) { - s->destroyed = true; - LIBZMQ_DELETE(s); - return NULL; - } - - return s; -} - -zmq::socket_base_t::socket_base_t (ctx_t *parent_, uint32_t tid_, int sid_, bool thread_safe_) : - own_t (parent_, tid_), - tag (0xbaddecaf), - ctx_terminated (false), - destroyed (false), - poller(NULL), - handle((poller_t::handle_t)NULL), - last_tsc (0), - ticks (0), - rcvmore (false), - monitor_socket (NULL), - monitor_events (0), - thread_safe (thread_safe_), - reaper_signaler (NULL), - sync(), - monitor_sync() -{ - options.socket_id = sid_; - options.ipv6 = (parent_->get (ZMQ_IPV6) != 0); - options.linger = parent_->get (ZMQ_BLOCKY)? -1: 0; - - if (thread_safe) - { - mailbox = new (std::nothrow) mailbox_safe_t(&sync); - zmq_assert (mailbox); - } - else { - mailbox_t *m = new (std::nothrow) mailbox_t(); - zmq_assert (m); - - if (m->get_fd () != retired_fd) - mailbox = m; - else { - LIBZMQ_DELETE (m); - mailbox = NULL; - } - } -} - -int zmq::socket_base_t::get_peer_state (const void *routing_id_, - size_t routing_id_size_) const -{ - LIBZMQ_UNUSED (routing_id_); - LIBZMQ_UNUSED (routing_id_size_); - - // Only ROUTER sockets support this - errno = ENOTSUP; - return -1; -} - -zmq::socket_base_t::~socket_base_t () -{ - if (mailbox) - LIBZMQ_DELETE(mailbox); - - if (reaper_signaler) - LIBZMQ_DELETE(reaper_signaler); - - scoped_lock_t lock(monitor_sync); - stop_monitor (); - - zmq_assert (destroyed); -} - -zmq::i_mailbox *zmq::socket_base_t::get_mailbox () -{ - return mailbox; -} - -void zmq::socket_base_t::stop () -{ - // Called by ctx when it is terminated (zmq_ctx_term). - // 'stop' command is sent from the threads that called zmq_ctx_term to - // the thread owning the socket. This way, blocking call in the - // owner thread can be interrupted. - send_stop (); -} - -int zmq::socket_base_t::parse_uri (const char *uri_, - std::string &protocol_, std::string &address_) -{ - zmq_assert (uri_ != NULL); - - std::string uri (uri_); - std::string::size_type pos = uri.find ("://"); - if (pos == std::string::npos) { - errno = EINVAL; - return -1; - } - protocol_ = uri.substr (0, pos); - address_ = uri.substr (pos + 3); - - if (protocol_.empty () || address_.empty ()) { - errno = EINVAL; - return -1; - } - return 0; -} - -int zmq::socket_base_t::check_protocol (const std::string &protocol_) -{ - // First check out whether the protocol is something we are aware of. - if (protocol_ != "inproc" -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - && protocol_ != "ipc" -#endif - && protocol_ != "tcp" -#if defined ZMQ_HAVE_OPENPGM - // pgm/epgm transports only available if 0MQ is compiled with OpenPGM. - && protocol_ != "pgm" - && protocol_ != "epgm" -#endif -#if defined ZMQ_HAVE_TIPC - // TIPC transport is only available on Linux. - && protocol_ != "tipc" -#endif -#if defined ZMQ_HAVE_NORM - && protocol_ != "norm" -#endif -#if defined ZMQ_HAVE_VMCI - && protocol_ != "vmci" -#endif - && protocol_ != "udp") { - errno = EPROTONOSUPPORT; - return -1; - } - - // Check whether socket type and transport protocol match. - // Specifically, multicast protocols can't be combined with - // bi-directional messaging patterns (socket types). -#if defined ZMQ_HAVE_OPENPGM || defined ZMQ_HAVE_NORM - if ((protocol_ == "pgm" || protocol_ == "epgm" || protocol_ == "norm") && - options.type != ZMQ_PUB && options.type != ZMQ_SUB && - options.type != ZMQ_XPUB && options.type != ZMQ_XSUB) { - errno = ENOCOMPATPROTO; - return -1; - } -#endif - - if (protocol_ == "udp" && (options.type != ZMQ_DISH && - options.type != ZMQ_RADIO && - options.type != ZMQ_DGRAM)) { - errno = ENOCOMPATPROTO; - return -1; - } - - // Protocol is available. - return 0; -} - -void zmq::socket_base_t::attach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - // First, register the pipe so that we can terminate it later on. - pipe_->set_event_sink (this); - pipes.push_back (pipe_); - - // Let the derived socket type know about new pipe. - xattach_pipe (pipe_, subscribe_to_all_); - - // If the socket is already being closed, ask any new pipes to terminate - // straight away. - if (is_terminating ()) { - register_term_acks (1); - pipe_->terminate (false); - } -} - -int zmq::socket_base_t::setsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - if (!options.is_valid(option_)) { - errno = EINVAL; - return -1; - } - - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // First, check whether specific socket type overloads the option. - int rc = xsetsockopt (option_, optval_, optvallen_); - if (rc == 0 || errno != EINVAL) { - return rc; - } - - // If the socket type doesn't support the option, pass it to - // the generic option parser. - rc = options.setsockopt (option_, optval_, optvallen_); - update_pipe_options(option_); - - return rc; -} - -int zmq::socket_base_t::getsockopt (int option_, void *optval_, - size_t *optvallen_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - if (option_ == ZMQ_RCVMORE) { - if (*optvallen_ < sizeof (int)) { - errno = EINVAL; - return -1; - } - memset(optval_, 0, *optvallen_); - *((int*) optval_) = rcvmore ? 1 : 0; - *optvallen_ = sizeof (int); - return 0; - } - - if (option_ == ZMQ_FD) { - if (*optvallen_ < sizeof (fd_t)) { - errno = EINVAL; - return -1; - } - - if (thread_safe) { - // thread safe socket doesn't provide file descriptor - errno = EINVAL; - return -1; - } - - *((fd_t*)optval_) = ((mailbox_t*)mailbox)->get_fd(); - *optvallen_ = sizeof(fd_t); - - return 0; - } - - if (option_ == ZMQ_EVENTS) { - if (*optvallen_ < sizeof (int)) { - errno = EINVAL; - return -1; - } - int rc = process_commands (0, false); - if (rc != 0 && (errno == EINTR || errno == ETERM)) { - return -1; - } - errno_assert (rc == 0); - *((int*) optval_) = 0; - if (has_out ()) - *((int*) optval_) |= ZMQ_POLLOUT; - if (has_in ()) - *((int*) optval_) |= ZMQ_POLLIN; - *optvallen_ = sizeof (int); - return 0; - } - - if (option_ == ZMQ_LAST_ENDPOINT) { - if (*optvallen_ < last_endpoint.size () + 1) { - errno = EINVAL; - return -1; - } - strncpy(static_cast (optval_), last_endpoint.c_str(), last_endpoint.size() + 1); - *optvallen_ = last_endpoint.size () + 1; - return 0; - } - - if (option_ == ZMQ_THREAD_SAFE) { - if (*optvallen_ < sizeof (int)) { - errno = EINVAL; - return -1; - } - memset(optval_, 0, *optvallen_); - *((int*) optval_) = thread_safe ? 1 : 0; - *optvallen_ = sizeof (int); - return 0; - } - - int rc = options.getsockopt (option_, optval_, optvallen_); - return rc; -} - -int zmq::socket_base_t::join (const char* group_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - int rc = xjoin (group_); - - - return rc; -} - -int zmq::socket_base_t::leave (const char* group_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - int rc = xleave (group_); - - - return rc; -} - -int zmq::socket_base_t::add_signaler(signaler_t *s_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - if (!thread_safe) { - errno = EINVAL; - return -1; - } - - ((mailbox_safe_t*)mailbox)->add_signaler(s_); - - return 0; -} - -int zmq::socket_base_t::remove_signaler(signaler_t *s_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - if (!thread_safe) { - errno = EINVAL; - return -1; - } - - ((mailbox_safe_t*)mailbox)->remove_signaler(s_); - - return 0; -} - -int zmq::socket_base_t::bind (const char *addr_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // Process pending commands, if any. - int rc = process_commands (0, false); - if (unlikely (rc != 0)) { - return -1; - } - - // Parse addr_ string. - std::string protocol; - std::string address; - if (parse_uri (addr_, protocol, address) || check_protocol (protocol)) { - return -1; - } - - if (protocol == "inproc") { - const endpoint_t endpoint = { this, options }; - rc = register_endpoint (addr_, endpoint); - if (rc == 0) { - connect_pending (addr_, this); - last_endpoint.assign (addr_); - options.connected = true; - } - return rc; - } - - if (protocol == "pgm" || protocol == "epgm" || protocol == "norm") { - // For convenience's sake, bind can be used interchangeable with - // connect for PGM, EPGM, NORM transports. - rc = connect (addr_); - if (rc != -1) - options.connected = true; - return rc; - } - - if (protocol == "udp") { - if (!(options.type == ZMQ_DGRAM || options.type == ZMQ_DISH)) { - errno = ENOCOMPATPROTO; - return -1; - } - - // Choose the I/O thread to run the session in. - io_thread_t *io_thread = choose_io_thread (options.affinity); - if (!io_thread) { - errno = EMTHREAD; - return -1; - } - - address_t *paddr = new (std::nothrow) address_t (protocol, address, this->get_ctx ()); - alloc_assert (paddr); - - paddr->resolved.udp_addr = new (std::nothrow) udp_address_t (); - alloc_assert (paddr->resolved.udp_addr); - rc = paddr->resolved.udp_addr->resolve (address.c_str(), true); - if (rc != 0) { - LIBZMQ_DELETE(paddr); - return -1; - } - - session_base_t *session = session_base_t::create (io_thread, true, this, - options, paddr); - errno_assert (session); - - pipe_t *newpipe = NULL; - - // Create a bi-directional pipe. - object_t *parents [2] = {this, session}; - pipe_t *new_pipes [2] = {NULL, NULL}; - - int hwms [2] = {options.sndhwm, options.rcvhwm}; - bool conflates [2] = {false, false}; - rc = pipepair (parents, new_pipes, hwms, conflates); - errno_assert (rc == 0); - - // Attach local end of the pipe to the socket object. - attach_pipe (new_pipes [0], true); - newpipe = new_pipes [0]; - - // Attach remote end of the pipe to the session object later on. - session->attach_pipe (new_pipes [1]); - - // Save last endpoint URI - paddr->to_string (last_endpoint); - - add_endpoint (addr_, (own_t *) session, newpipe); - - return 0; - } - - // Remaining transports require to be run in an I/O thread, so at this - // point we'll choose one. - io_thread_t *io_thread = choose_io_thread (options.affinity); - if (!io_thread) { - errno = EMTHREAD; - return -1; - } - - if (protocol == "tcp") { - tcp_listener_t *listener = new (std::nothrow) tcp_listener_t ( - io_thread, this, options); - alloc_assert (listener); - rc = listener->set_address (address.c_str ()); - if (rc != 0) { - LIBZMQ_DELETE(listener); - event_bind_failed (address, zmq_errno()); - return -1; - } - - // Save last endpoint URI - listener->get_address (last_endpoint); - - add_endpoint (last_endpoint.c_str (), (own_t *) listener, NULL); - options.connected = true; - return 0; - } - -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - if (protocol == "ipc") { - ipc_listener_t *listener = new (std::nothrow) ipc_listener_t ( - io_thread, this, options); - alloc_assert (listener); - int rc = listener->set_address (address.c_str ()); - if (rc != 0) { - LIBZMQ_DELETE(listener); - event_bind_failed (address, zmq_errno()); - return -1; - } - - // Save last endpoint URI - listener->get_address (last_endpoint); - - add_endpoint (last_endpoint.c_str (), (own_t *) listener, NULL); - options.connected = true; - return 0; - } -#endif -#if defined ZMQ_HAVE_TIPC - if (protocol == "tipc") { - tipc_listener_t *listener = new (std::nothrow) tipc_listener_t ( - io_thread, this, options); - alloc_assert (listener); - int rc = listener->set_address (address.c_str ()); - if (rc != 0) { - LIBZMQ_DELETE(listener); - event_bind_failed (address, zmq_errno()); - return -1; - } - - // Save last endpoint URI - listener->get_address (last_endpoint); - - add_endpoint (addr_, (own_t *) listener, NULL); - options.connected = true; - return 0; - } -#endif -#if defined ZMQ_HAVE_VMCI - if (protocol == "vmci") { - vmci_listener_t *listener = new (std::nothrow) vmci_listener_t ( - io_thread, this, options); - alloc_assert (listener); - int rc = listener->set_address (address.c_str ()); - if (rc != 0) { - LIBZMQ_DELETE(listener); - event_bind_failed (address, zmq_errno ()); - return -1; - } - - listener->get_address (last_endpoint); - - add_endpoint (last_endpoint.c_str(), (own_t *) listener, NULL); - options.connected = true; - return 0; - } -#endif - - zmq_assert (false); - return -1; -} - -int zmq::socket_base_t::connect (const char *addr_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // Process pending commands, if any. - int rc = process_commands (0, false); - if (unlikely (rc != 0)) { - return -1; - } - - // Parse addr_ string. - std::string protocol; - std::string address; - if (parse_uri (addr_, protocol, address) || check_protocol (protocol)) { - return -1; - } - - if (protocol == "inproc") { - - // TODO: inproc connect is specific with respect to creating pipes - // as there's no 'reconnect' functionality implemented. Once that - // is in place we should follow generic pipe creation algorithm. - - // Find the peer endpoint. - endpoint_t peer = find_endpoint (addr_); - - // The total HWM for an inproc connection should be the sum of - // the binder's HWM and the connector's HWM. - int sndhwm = 0; - if (peer.socket == NULL) - sndhwm = options.sndhwm; - else if (options.sndhwm != 0 && peer.options.rcvhwm != 0) - sndhwm = options.sndhwm + peer.options.rcvhwm; - int rcvhwm = 0; - if (peer.socket == NULL) - rcvhwm = options.rcvhwm; - else - if (options.rcvhwm != 0 && peer.options.sndhwm != 0) - rcvhwm = options.rcvhwm + peer.options.sndhwm; - - // Create a bi-directional pipe to connect the peers. - object_t *parents [2] = {this, peer.socket == NULL ? this : peer.socket}; - pipe_t *new_pipes [2] = {NULL, NULL}; - - bool conflate = options.conflate && - (options.type == ZMQ_DEALER || - options.type == ZMQ_PULL || - options.type == ZMQ_PUSH || - options.type == ZMQ_PUB || - options.type == ZMQ_SUB); - - int hwms [2] = {conflate? -1 : sndhwm, conflate? -1 : rcvhwm}; - bool conflates [2] = {conflate, conflate}; - rc = pipepair (parents, new_pipes, hwms, conflates); - if (!conflate) { - new_pipes[0]->set_hwms_boost(peer.options.sndhwm, peer.options.rcvhwm); - new_pipes[1]->set_hwms_boost(options.sndhwm, options.rcvhwm); - } - - errno_assert (rc == 0); - - if (!peer.socket) { - // The peer doesn't exist yet so we don't know whether - // to send the routing id message or not. To resolve this, - // we always send our routing id and drop it later if - // the peer doesn't expect it. - msg_t id; - rc = id.init_size (options.routing_id_size); - errno_assert (rc == 0); - memcpy (id.data (), options.routing_id, options.routing_id_size); - id.set_flags (msg_t::routing_id); - bool written = new_pipes [0]->write (&id); - zmq_assert (written); - new_pipes [0]->flush (); - - const endpoint_t endpoint = {this, options}; - pend_connection (std::string (addr_), endpoint, new_pipes); - } - else { - // If required, send the routing id of the local socket to the peer. - if (peer.options.recv_routing_id) { - msg_t id; - rc = id.init_size (options.routing_id_size); - errno_assert (rc == 0); - memcpy (id.data (), options.routing_id, options.routing_id_size); - id.set_flags (msg_t::routing_id); - bool written = new_pipes [0]->write (&id); - zmq_assert (written); - new_pipes [0]->flush (); - } - - // If required, send the routing id of the peer to the local socket. - if (options.recv_routing_id) { - msg_t id; - rc = id.init_size (peer.options.routing_id_size); - errno_assert (rc == 0); - memcpy (id.data (), peer.options.routing_id, peer.options.routing_id_size); - id.set_flags (msg_t::routing_id); - bool written = new_pipes [1]->write (&id); - zmq_assert (written); - new_pipes [1]->flush (); - } - - // Attach remote end of the pipe to the peer socket. Note that peer's - // seqnum was incremented in find_endpoint function. We don't need it - // increased here. - send_bind (peer.socket, new_pipes [1], false); - } - - // Attach local end of the pipe to this socket object. - attach_pipe (new_pipes [0]); - - // Save last endpoint URI - last_endpoint.assign (addr_); - - // remember inproc connections for disconnect - inprocs.ZMQ_MAP_INSERT_OR_EMPLACE (addr_, new_pipes [0]); - - options.connected = true; - return 0; - } - bool is_single_connect = (options.type == ZMQ_DEALER || - options.type == ZMQ_SUB || - options.type == ZMQ_REQ); - if (unlikely (is_single_connect)) { - const endpoints_t::iterator it = endpoints.find (addr_); - if (it != endpoints.end ()) { - // There is no valid use for multiple connects for SUB-PUB nor - // DEALER-ROUTER nor REQ-REP. Multiple connects produces - // nonsensical results. - return 0; - } - } - - // Choose the I/O thread to run the session in. - io_thread_t *io_thread = choose_io_thread (options.affinity); - if (!io_thread) { - errno = EMTHREAD; - return -1; - } - - address_t *paddr = new (std::nothrow) address_t (protocol, address, this->get_ctx ()); - alloc_assert (paddr); - - // Resolve address (if needed by the protocol) - if (protocol == "tcp") { - // Do some basic sanity checks on tcp:// address syntax - // - hostname starts with digit or letter, with embedded '-' or '.' - // - IPv6 address may contain hex chars and colons. - // - IPv6 link local address may contain % followed by interface name / zone_id - // (Reference: https://tools.ietf.org/html/rfc4007) - // - IPv4 address may contain decimal digits and dots. - // - Address must end in ":port" where port is *, or numeric - // - Address may contain two parts separated by ':' - // Following code is quick and dirty check to catch obvious errors, - // without trying to be fully accurate. - const char *check = address.c_str (); - if (isalnum (*check) || isxdigit (*check) || *check == '[' || *check == ':') { - check++; - while (isalnum (*check) - || isxdigit (*check) - || *check == '.' || *check == '-' || *check == ':' || *check == '%' - || *check == ';' || *check == '[' || *check == ']' || *check == '_' - || *check == '*' - ) { - check++; - } - } - // Assume the worst, now look for success - rc = -1; - // Did we reach the end of the address safely? - if (*check == 0) { - // Do we have a valid port string? (cannot be '*' in connect - check = strrchr (address.c_str (), ':'); - if (check) { - check++; - if (*check && (isdigit (*check))) - rc = 0; // Valid - } - } - if (rc == -1) { - errno = EINVAL; - LIBZMQ_DELETE(paddr); - return -1; - } - // Defer resolution until a socket is opened - paddr->resolved.tcp_addr = NULL; - } -#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS - else - if (protocol == "ipc") { - paddr->resolved.ipc_addr = new (std::nothrow) ipc_address_t (); - alloc_assert (paddr->resolved.ipc_addr); - int rc = paddr->resolved.ipc_addr->resolve (address.c_str ()); - if (rc != 0) { - LIBZMQ_DELETE(paddr); - return -1; - } - } -#endif - - if (protocol == "udp") { - if (options.type != ZMQ_RADIO) { - errno = ENOCOMPATPROTO; - LIBZMQ_DELETE(paddr); - return -1; - } - - paddr->resolved.udp_addr = new (std::nothrow) udp_address_t (); - alloc_assert (paddr->resolved.udp_addr); - rc = paddr->resolved.udp_addr->resolve (address.c_str(), false); - if (rc != 0) { - LIBZMQ_DELETE(paddr); - return -1; - } - } - -// TBD - Should we check address for ZMQ_HAVE_NORM??? - -#ifdef ZMQ_HAVE_OPENPGM - if (protocol == "pgm" || protocol == "epgm") { - struct pgm_addrinfo_t *res = NULL; - uint16_t port_number = 0; - int rc = pgm_socket_t::init_address(address.c_str(), &res, &port_number); - if (res != NULL) - pgm_freeaddrinfo (res); - if (rc != 0 || port_number == 0) { - return -1; - } - } -#endif -#if defined ZMQ_HAVE_TIPC - else - if (protocol == "tipc") { - paddr->resolved.tipc_addr = new (std::nothrow) tipc_address_t (); - alloc_assert (paddr->resolved.tipc_addr); - int rc = paddr->resolved.tipc_addr->resolve (address.c_str()); - if (rc != 0) { - LIBZMQ_DELETE(paddr); - return -1; - } - } -#endif -#if defined ZMQ_HAVE_VMCI - else - if (protocol == "vmci") { - paddr->resolved.vmci_addr = new (std::nothrow) vmci_address_t (this->get_ctx ()); - alloc_assert (paddr->resolved.vmci_addr); - int rc = paddr->resolved.vmci_addr->resolve (address.c_str ()); - if (rc != 0) { - LIBZMQ_DELETE(paddr); - return -1; - } - } -#endif - - // Create session. - session_base_t *session = session_base_t::create (io_thread, true, this, - options, paddr); - errno_assert (session); - - // PGM does not support subscription forwarding; ask for all data to be - // sent to this pipe. (same for NORM, currently?) - bool subscribe_to_all = protocol == "pgm" || protocol == "epgm" || protocol == "norm" || protocol == "udp"; - pipe_t *newpipe = NULL; - - if (options.immediate != 1 || subscribe_to_all) { - // Create a bi-directional pipe. - object_t *parents [2] = {this, session}; - pipe_t *new_pipes [2] = {NULL, NULL}; - - bool conflate = options.conflate && - (options.type == ZMQ_DEALER || - options.type == ZMQ_PULL || - options.type == ZMQ_PUSH || - options.type == ZMQ_PUB || - options.type == ZMQ_SUB); - - int hwms [2] = {conflate? -1 : options.sndhwm, - conflate? -1 : options.rcvhwm}; - bool conflates [2] = {conflate, conflate}; - rc = pipepair (parents, new_pipes, hwms, conflates); - errno_assert (rc == 0); - - // Attach local end of the pipe to the socket object. - attach_pipe (new_pipes [0], subscribe_to_all); - newpipe = new_pipes [0]; - - // Attach remote end of the pipe to the session object later on. - session->attach_pipe (new_pipes [1]); - } - - // Save last endpoint URI - paddr->to_string (last_endpoint); - - add_endpoint (addr_, (own_t *) session, newpipe); - return 0; -} - -void zmq::socket_base_t::add_endpoint (const char *addr_, own_t *endpoint_, pipe_t *pipe) -{ - // Activate the session. Make it a child of this socket. - launch_child (endpoint_); - endpoints.ZMQ_MAP_INSERT_OR_EMPLACE (addr_, endpoint_pipe_t (endpoint_, pipe)); -} - -int zmq::socket_base_t::term_endpoint (const char *addr_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - // Check whether the library haven't been shut down yet. - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // Check whether endpoint address passed to the function is valid. - if (unlikely (!addr_)) { - errno = EINVAL; - return -1; - } - - // Process pending commands, if any, since there could be pending unprocessed process_own()'s - // (from launch_child() for example) we're asked to terminate now. - int rc = process_commands (0, false); - if (unlikely(rc != 0)) { - return -1; - } - - // Parse addr_ string. - std::string protocol; - std::string address; - if (parse_uri(addr_, protocol, address) || check_protocol(protocol)) { - return -1; - } - - // Disconnect an inproc socket - if (protocol == "inproc") { - if (unregister_endpoint (std::string(addr_), this) == 0) { - return 0; - } - std::pair range = inprocs.equal_range (std::string (addr_)); - if (range.first == range.second) { - errno = ENOENT; - return -1; - } - - for (inprocs_t::iterator it = range.first; it != range.second; ++it) - it->second->terminate (true); - inprocs.erase (range.first, range.second); - return 0; - } - - std::string resolved_addr = std::string (addr_); - std::pair range; - - // The resolved last_endpoint is used as a key in the endpoints map. - // The address passed by the user might not match in the TCP case due to - // IPv4-in-IPv6 mapping (EG: tcp://[::ffff:127.0.0.1]:9999), so try to - // resolve before giving up. Given at this stage we don't know whether a - // socket is connected or bound, try with both. - if (protocol == "tcp") { - range = endpoints.equal_range (resolved_addr); - if (range.first == range.second) { - tcp_address_t *tcp_addr = new (std::nothrow) tcp_address_t (); - alloc_assert (tcp_addr); - rc = tcp_addr->resolve (address.c_str (), false, options.ipv6); - - if (rc == 0) { - tcp_addr->to_string (resolved_addr); - range = endpoints.equal_range (resolved_addr); - - if (range.first == range.second) { - rc = tcp_addr->resolve (address.c_str (), true, options.ipv6); - if (rc == 0) { - tcp_addr->to_string (resolved_addr); - } - } - } - LIBZMQ_DELETE(tcp_addr); - } - } - - // Find the endpoints range (if any) corresponding to the addr_ string. - range = endpoints.equal_range (resolved_addr); - if (range.first == range.second) { - errno = ENOENT; - return -1; - } - - for (endpoints_t::iterator it = range.first; it != range.second; ++it) { - // If we have an associated pipe, terminate it. - if (it->second.second != NULL) - it->second.second->terminate (false); - term_child (it->second.first); - } - endpoints.erase (range.first, range.second); - return 0; -} - -int zmq::socket_base_t::send (msg_t *msg_, int flags_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - // Check whether the library haven't been shut down yet. - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // Check whether message passed to the function is valid. - if (unlikely (!msg_ || !msg_->check ())) { - errno = EFAULT; - return -1; - } - - // Process pending commands, if any. - int rc = process_commands (0, true); - if (unlikely (rc != 0)) { - return -1; - } - - // Clear any user-visible flags that are set on the message. - msg_->reset_flags (msg_t::more); - - // At this point we impose the flags on the message. - if (flags_ & ZMQ_SNDMORE) - msg_->set_flags (msg_t::more); - - msg_->reset_metadata (); - - // Try to send the message using method in each socket class - rc = xsend (msg_); - if (rc == 0) { - return 0; - } - if (unlikely (errno != EAGAIN)) { - return -1; - } - - // In case of non-blocking send we'll simply propagate - // the error - including EAGAIN - up the stack. - if ((flags_ & ZMQ_DONTWAIT) || options.sndtimeo == 0) { - return -1; - } - - // Compute the time when the timeout should occur. - // If the timeout is infinite, don't care. - int timeout = options.sndtimeo; - uint64_t end = timeout < 0 ? 0 : (clock.now_ms () + timeout); - - // Oops, we couldn't send the message. Wait for the next - // command, process it and try to send the message again. - // If timeout is reached in the meantime, return EAGAIN. - while (true) { - if (unlikely (process_commands (timeout, false) != 0)) { - return -1; - } - rc = xsend (msg_); - if (rc == 0) - break; - if (unlikely (errno != EAGAIN)) { - return -1; - } - if (timeout > 0) { - timeout = (int) (end - clock.now_ms ()); - if (timeout <= 0) { - errno = EAGAIN; - return -1; - } - } - } - - return 0; -} - -int zmq::socket_base_t::recv (msg_t *msg_, int flags_) -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - // Check whether the library haven't been shut down yet. - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // Check whether message passed to the function is valid. - if (unlikely (!msg_ || !msg_->check ())) { - errno = EFAULT; - return -1; - } - - // Once every inbound_poll_rate messages check for signals and process - // incoming commands. This happens only if we are not polling altogether - // because there are messages available all the time. If poll occurs, - // ticks is set to zero and thus we avoid this code. - // - // Note that 'recv' uses different command throttling algorithm (the one - // described above) from the one used by 'send'. This is because counting - // ticks is more efficient than doing RDTSC all the time. - if (++ticks == inbound_poll_rate) { - if (unlikely (process_commands (0, false) != 0)) { - return -1; - } - ticks = 0; - } - - // Get the message. - int rc = xrecv (msg_); - if (unlikely (rc != 0 && errno != EAGAIN)) { - return -1; - } - - // If we have the message, return immediately. - if (rc == 0) { - extract_flags (msg_); - return 0; - } - - // If the message cannot be fetched immediately, there are two scenarios. - // For non-blocking recv, commands are processed in case there's an - // activate_reader command already waiting in a command pipe. - // If it's not, return EAGAIN. - if ((flags_ & ZMQ_DONTWAIT) || options.rcvtimeo == 0) { - if (unlikely (process_commands (0, false) != 0)) { - return -1; - } - ticks = 0; - - rc = xrecv (msg_); - if (rc < 0) { - return rc; - } - extract_flags (msg_); - - return 0; - } - - // Compute the time when the timeout should occur. - // If the timeout is infinite, don't care. - int timeout = options.rcvtimeo; - uint64_t end = timeout < 0 ? 0 : (clock.now_ms () + timeout); - - // In blocking scenario, commands are processed over and over again until - // we are able to fetch a message. - bool block = (ticks != 0); - while (true) { - if (unlikely (process_commands (block ? timeout : 0, false) != 0)) { - return -1; - } - rc = xrecv (msg_); - if (rc == 0) { - ticks = 0; - break; - } - if (unlikely (errno != EAGAIN)) { - return -1; - } - block = true; - if (timeout > 0) { - timeout = (int) (end - clock.now_ms ()); - if (timeout <= 0) { - errno = EAGAIN; - return -1; - } - } - } - - extract_flags (msg_); - return 0; -} - -int zmq::socket_base_t::close () -{ - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - // Remove all existing signalers for thread safe sockets - if (thread_safe) - ((mailbox_safe_t*)mailbox)->clear_signalers(); - - // Mark the socket as dead - tag = 0xdeadbeef; - - - // Transfer the ownership of the socket from this application thread - // to the reaper thread which will take care of the rest of shutdown - // process. - send_reap (this); - - return 0; -} - -bool zmq::socket_base_t::has_in () -{ - return xhas_in (); -} - -bool zmq::socket_base_t::has_out () -{ - return xhas_out (); -} - -void zmq::socket_base_t::start_reaping (poller_t *poller_) -{ - // Plug the socket to the reaper thread. - poller = poller_; - - fd_t fd; - - if (!thread_safe) - fd = ((mailbox_t*)mailbox)->get_fd(); - else { - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - reaper_signaler = new (std::nothrow) signaler_t(); - zmq_assert (reaper_signaler); - - // Add signaler to the safe mailbox - fd = reaper_signaler->get_fd(); - ((mailbox_safe_t*)mailbox)->add_signaler(reaper_signaler); - - // Send a signal to make sure reaper handle existing commands - reaper_signaler->send(); - - } - - handle = poller->add_fd (fd, this); - poller->set_pollin (handle); - - // Initialise the termination and check whether it can be deallocated - // immediately. - terminate (); - check_destroy (); -} - -int zmq::socket_base_t::process_commands (int timeout_, bool throttle_) -{ - int rc; - command_t cmd; - if (timeout_ != 0) { - - // If we are asked to wait, simply ask mailbox to wait. - rc = mailbox->recv (&cmd, timeout_); - } - else { - - // If we are asked not to wait, check whether we haven't processed - // commands recently, so that we can throttle the new commands. - - // Get the CPU's tick counter. If 0, the counter is not available. - const uint64_t tsc = zmq::clock_t::rdtsc (); - - // Optimised version of command processing - it doesn't have to check - // for incoming commands each time. It does so only if certain time - // elapsed since last command processing. Command delay varies - // depending on CPU speed: It's ~1ms on 3GHz CPU, ~2ms on 1.5GHz CPU - // etc. The optimisation makes sense only on platforms where getting - // a timestamp is a very cheap operation (tens of nanoseconds). - if (tsc && throttle_) { - - // Check whether TSC haven't jumped backwards (in case of migration - // between CPU cores) and whether certain time have elapsed since - // last command processing. If it didn't do nothing. - if (tsc >= last_tsc && tsc - last_tsc <= max_command_delay) - return 0; - last_tsc = tsc; - } - - // Check whether there are any commands pending for this thread. - rc = mailbox->recv (&cmd, 0); - } - - // Process all available commands. - while (rc == 0) { - cmd.destination->process_command (cmd); - rc = mailbox->recv (&cmd, 0); - } - - if (errno == EINTR) - return -1; - - zmq_assert (errno == EAGAIN); - - if (ctx_terminated) { - errno = ETERM; - return -1; - } - - return 0; -} - -void zmq::socket_base_t::process_stop () -{ - // Here, someone have called zmq_ctx_term while the socket was still alive. - // We'll remember the fact so that any blocking call is interrupted and any - // further attempt to use the socket will return ETERM. The user is still - // responsible for calling zmq_close on the socket though! - scoped_lock_t lock(monitor_sync); - stop_monitor (); - - ctx_terminated = true; -} - -void zmq::socket_base_t::process_bind (pipe_t *pipe_) -{ - attach_pipe (pipe_); -} - -void zmq::socket_base_t::process_term (int linger_) -{ - // Unregister all inproc endpoints associated with this socket. - // Doing this we make sure that no new pipes from other sockets (inproc) - // will be initiated. - unregister_endpoints (this); - - // Ask all attached pipes to terminate. - for (pipes_t::size_type i = 0; i != pipes.size (); ++i) - pipes [i]->terminate (false); - register_term_acks ((int) pipes.size ()); - - // Continue the termination process immediately. - own_t::process_term (linger_); -} - -void zmq::socket_base_t::process_term_endpoint (std::string *endpoint_) -{ - term_endpoint (endpoint_->c_str()); - delete endpoint_; -} - -void zmq::socket_base_t::update_pipe_options(int option_) -{ - if (option_ == ZMQ_SNDHWM || option_ == ZMQ_RCVHWM) - { - for (pipes_t::size_type i = 0; i != pipes.size(); ++i) - { - pipes[i]->set_hwms(options.rcvhwm, options.sndhwm); - pipes[i]->send_hwms_to_peer(options.sndhwm, options.rcvhwm); - } - } - -} - -void zmq::socket_base_t::process_destroy () -{ - destroyed = true; -} - -int zmq::socket_base_t::xsetsockopt (int, const void *, size_t) -{ - errno = EINVAL; - return -1; -} - -bool zmq::socket_base_t::xhas_out () -{ - return false; -} - -int zmq::socket_base_t::xsend (msg_t *) -{ - errno = ENOTSUP; - return -1; -} - -bool zmq::socket_base_t::xhas_in () -{ - return false; -} - -int zmq::socket_base_t::xjoin (const char *group_) -{ - LIBZMQ_UNUSED (group_); - errno = ENOTSUP; - return -1; -} - -int zmq::socket_base_t::xleave (const char *group_) -{ - LIBZMQ_UNUSED (group_); - errno = ENOTSUP; - return -1; -} - -int zmq::socket_base_t::xrecv (msg_t *) -{ - errno = ENOTSUP; - return -1; -} - -static const zmq::blob_t empty_blob; - -const zmq::blob_t &zmq::socket_base_t::get_credential () const -{ - return empty_blob; -} - -void zmq::socket_base_t::xread_activated (pipe_t *) -{ - zmq_assert (false); -} -void zmq::socket_base_t::xwrite_activated (pipe_t *) -{ - zmq_assert (false); -} - -void zmq::socket_base_t::xhiccuped (pipe_t *) -{ - zmq_assert (false); -} - -void zmq::socket_base_t::in_event () -{ - // This function is invoked only once the socket is running in the context - // of the reaper thread. Process any commands from other threads/sockets - // that may be available at the moment. Ultimately, the socket will - // be destroyed. - { - scoped_optional_lock_t sync_lock(thread_safe ? &sync : NULL); - - // If the socket is thread safe we need to unsignal the reaper signaler - if (thread_safe) - reaper_signaler->recv(); - - process_commands (0, false); - } - check_destroy(); -} - -void zmq::socket_base_t::out_event () -{ - zmq_assert (false); -} - -void zmq::socket_base_t::timer_event (int) -{ - zmq_assert (false); -} - -void zmq::socket_base_t::check_destroy () -{ - // If the object was already marked as destroyed, finish the deallocation. - if (destroyed) { - - // Remove the socket from the reaper's poller. - poller->rm_fd (handle); - - // Remove the socket from the context. - destroy_socket (this); - - // Notify the reaper about the fact. - send_reaped (); - - // Deallocate. - own_t::process_destroy (); - } -} - -void zmq::socket_base_t::read_activated (pipe_t *pipe_) -{ - xread_activated (pipe_); -} - -void zmq::socket_base_t::write_activated (pipe_t *pipe_) -{ - xwrite_activated (pipe_); -} - -void zmq::socket_base_t::hiccuped (pipe_t *pipe_) -{ - if (options.immediate == 1) - pipe_->terminate (false); - else - // Notify derived sockets of the hiccup - xhiccuped (pipe_); -} - -void zmq::socket_base_t::pipe_terminated (pipe_t *pipe_) -{ - // Notify the specific socket type about the pipe termination. - xpipe_terminated (pipe_); - - // Remove pipe from inproc pipes - for (inprocs_t::iterator it = inprocs.begin (); it != inprocs.end (); ++it) - if (it->second == pipe_) { - inprocs.erase (it); - break; - } - - // Remove the pipe from the list of attached pipes and confirm its - // termination if we are already shutting down. - pipes.erase (pipe_); - if (is_terminating ()) - unregister_term_ack (); -} - -void zmq::socket_base_t::extract_flags (msg_t *msg_) -{ - // Test whether routing_id flag is valid for this socket type. - if (unlikely (msg_->flags () & msg_t::routing_id)) - zmq_assert (options.recv_routing_id); - - // Remove MORE flag. - rcvmore = msg_->flags () & msg_t::more ? true : false; -} - -int zmq::socket_base_t::monitor (const char *addr_, int events_) -{ - scoped_lock_t lock(monitor_sync); - - if (unlikely (ctx_terminated)) { - errno = ETERM; - return -1; - } - - // Support deregistering monitoring endpoints as well - if (addr_ == NULL) { - stop_monitor (); - return 0; - } - // Parse addr_ string. - std::string protocol; - std::string address; - if (parse_uri (addr_, protocol, address) || check_protocol (protocol)) - return -1; - - // Event notification only supported over inproc:// - if (protocol != "inproc") { - errno = EPROTONOSUPPORT; - return -1; - } - // already monitoring. Stop previous monitor before starting new one. - if (monitor_socket != NULL) { - stop_monitor (true); - } - // Register events to monitor - monitor_events = events_; - monitor_socket = zmq_socket (get_ctx (), ZMQ_PAIR); - if (monitor_socket == NULL) - return -1; - - // Never block context termination on pending event messages - int linger = 0; - int rc = zmq_setsockopt (monitor_socket, ZMQ_LINGER, &linger, sizeof (linger)); - if (rc == -1) - stop_monitor (false); - - // Spawn the monitor socket endpoint - rc = zmq_bind (monitor_socket, addr_); - if (rc == -1) - stop_monitor (false); - return rc; -} - -void zmq::socket_base_t::event_connected (const std::string &addr_, zmq::fd_t fd_) -{ - event(addr_, fd_, ZMQ_EVENT_CONNECTED); -} - -void zmq::socket_base_t::event_connect_delayed (const std::string &addr_, int err_) -{ - event(addr_, err_, ZMQ_EVENT_CONNECT_DELAYED); -} - -void zmq::socket_base_t::event_connect_retried (const std::string &addr_, int interval_) -{ - event(addr_, interval_, ZMQ_EVENT_CONNECT_RETRIED); -} - -void zmq::socket_base_t::event_listening (const std::string &addr_, zmq::fd_t fd_) -{ - event(addr_, fd_, ZMQ_EVENT_LISTENING); -} - -void zmq::socket_base_t::event_bind_failed (const std::string &addr_, int err_) -{ - event(addr_, err_, ZMQ_EVENT_BIND_FAILED); -} - -void zmq::socket_base_t::event_accepted (const std::string &addr_, zmq::fd_t fd_) -{ - event(addr_, fd_, ZMQ_EVENT_ACCEPTED); -} - -void zmq::socket_base_t::event_accept_failed (const std::string &addr_, int err_) -{ - event(addr_, err_, ZMQ_EVENT_ACCEPT_FAILED); -} - -void zmq::socket_base_t::event_closed (const std::string &addr_, zmq::fd_t fd_) -{ - event(addr_, fd_, ZMQ_EVENT_CLOSED); -} - -void zmq::socket_base_t::event_close_failed (const std::string &addr_, int err_) -{ - event(addr_, err_, ZMQ_EVENT_CLOSE_FAILED); -} - -void zmq::socket_base_t::event_disconnected (const std::string &addr_, zmq::fd_t fd_) -{ - event(addr_, fd_, ZMQ_EVENT_DISCONNECTED); -} - -void zmq::socket_base_t::event_handshake_failed_no_detail ( - const std::string &addr_, int err_) -{ - event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL); -} - -void zmq::socket_base_t::event_handshake_failed_protocol ( - const std::string &addr_, int err_) -{ - event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL); -} - -void zmq::socket_base_t::event_handshake_failed_auth (const std::string &addr_, - int err_) -{ - event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH); -} - -void zmq::socket_base_t::event_handshake_succeeded (const std::string &addr_, - int err_) -{ - event (addr_, err_, ZMQ_EVENT_HANDSHAKE_SUCCEEDED); -} - -void zmq::socket_base_t::event(const std::string &addr_, intptr_t value_, int type_) -{ - scoped_lock_t lock(monitor_sync); - if (monitor_events & type_) - { - monitor_event (type_, value_, addr_); - } -} - -// Send a monitor event -void zmq::socket_base_t::monitor_event (int event_, intptr_t value_, const std::string &addr_) -{ - // this is a private method which is only called from - // contexts where the mutex has been locked before - - if (monitor_socket) { - // Send event in first frame - zmq_msg_t msg; - zmq_msg_init_size (&msg, 6); - uint8_t *data = (uint8_t *) zmq_msg_data (&msg); - // Avoid dereferencing uint32_t on unaligned address - uint16_t event = (uint16_t) event_; - uint32_t value = (uint32_t) value_; - memcpy (data + 0, &event, sizeof(event)); - memcpy (data + 2, &value, sizeof(value)); - zmq_sendmsg (monitor_socket, &msg, ZMQ_SNDMORE); - - // Send address in second frame - zmq_msg_init_size (&msg, addr_.size()); - memcpy (zmq_msg_data (&msg), addr_.c_str (), addr_.size ()); - zmq_sendmsg (monitor_socket, &msg, 0); - } -} - -void zmq::socket_base_t::stop_monitor (bool send_monitor_stopped_event_) -{ - // this is a private method which is only called from - // contexts where the mutex has been locked before - - if (monitor_socket) { - if ((monitor_events & ZMQ_EVENT_MONITOR_STOPPED) && send_monitor_stopped_event_) - monitor_event (ZMQ_EVENT_MONITOR_STOPPED, 0, ""); - zmq_close (monitor_socket); - monitor_socket = NULL; - monitor_events = 0; - } -} diff --git a/dep/libzmq/src/socket_base.hpp b/dep/libzmq/src/socket_base.hpp deleted file mode 100644 index 430a1be21d..0000000000 --- a/dep/libzmq/src/socket_base.hpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SOCKET_BASE_HPP_INCLUDED__ -#define __ZMQ_SOCKET_BASE_HPP_INCLUDED__ - -#include -#include -#include - -#include "own.hpp" -#include "array.hpp" -#include "blob.hpp" -#include "stdint.hpp" -#include "poller.hpp" -#include "atomic_counter.hpp" -#include "i_poll_events.hpp" -#include "i_mailbox.hpp" -#include "stdint.hpp" -#include "clock.hpp" -#include "pipe.hpp" - -extern "C" -{ - void zmq_free_event (void *data, void *hint); -} - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - - class socket_base_t : - public own_t, - public array_item_t <>, - public i_poll_events, - public i_pipe_events - { - friend class reaper_t; - - public: - - // Returns false if object is not a socket. - bool check_tag (); - - // Create a socket of a specified type. - static socket_base_t *create (int type_, zmq::ctx_t *parent_, - uint32_t tid_, int sid_); - - // Returns the mailbox associated with this socket. - i_mailbox *get_mailbox (); - - // Interrupt blocking call if the socket is stuck in one. - // This function can be called from a different thread! - void stop (); - - // Interface for communication with the API layer. - int setsockopt (int option_, const void *optval_, size_t optvallen_); - int getsockopt (int option_, void *optval_, size_t *optvallen_); - int bind (const char *addr_); - int connect (const char *addr_); - int term_endpoint (const char *addr_); - int send (zmq::msg_t *msg_, int flags_); - int recv (zmq::msg_t *msg_, int flags_); - int add_signaler (signaler_t *s); - int remove_signaler (signaler_t *s); - int close (); - - // These functions are used by the polling mechanism to determine - // which events are to be reported from this socket. - bool has_in (); - bool has_out (); - - // Joining and leaving groups - int join (const char *group); - int leave (const char *group); - - // Using this function reaper thread ask the socket to register with - // its poller. - void start_reaping (poller_t *poller_); - - // i_poll_events implementation. This interface is used when socket - // is handled by the poller in the reaper thread. - void in_event (); - void out_event (); - void timer_event (int id_); - - // i_pipe_events interface implementation. - void read_activated (pipe_t *pipe_); - void write_activated (pipe_t *pipe_); - void hiccuped (pipe_t *pipe_); - void pipe_terminated (pipe_t *pipe_); - void lock(); - void unlock(); - - int monitor (const char *endpoint_, int events_); - - void event_connected (const std::string &addr_, zmq::fd_t fd_); - void event_connect_delayed (const std::string &addr_, int err_); - void event_connect_retried (const std::string &addr_, int interval_); - void event_listening (const std::string &addr_, zmq::fd_t fd_); - void event_bind_failed (const std::string &addr_, int err_); - void event_accepted (const std::string &addr_, zmq::fd_t fd_); - void event_accept_failed (const std::string &addr_, int err_); - void event_closed (const std::string &addr_, zmq::fd_t fd_); - void event_close_failed (const std::string &addr_, int err_); - void event_disconnected (const std::string &addr_, zmq::fd_t fd_); - void event_handshake_failed_no_detail(const std::string &addr_, int err_); - void event_handshake_failed_protocol(const std::string &addr_, int err_); - void event_handshake_failed_auth(const std::string &addr_, int err_); - void event_handshake_succeeded(const std::string &addr_, int err_); - - // Query the state of a specific peer. The default implementation - // always returns an ENOTSUP error. - virtual int get_peer_state (const void *identity, - size_t identity_size) const; - - protected: - - socket_base_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_, bool thread_safe_ = false); - virtual ~socket_base_t (); - - // Concrete algorithms for the x- methods are to be defined by - // individual socket types. - virtual void xattach_pipe (zmq::pipe_t *pipe_, - bool subscribe_to_all_ = false) = 0; - - // The default implementation assumes there are no specific socket - // options for the particular socket type. If not so, override this - // method. - virtual int xsetsockopt (int option_, const void *optval_, - size_t optvallen_); - - // The default implementation assumes that send is not supported. - virtual bool xhas_out (); - virtual int xsend (zmq::msg_t *msg_); - - // The default implementation assumes that recv in not supported. - virtual bool xhas_in (); - virtual int xrecv (zmq::msg_t *msg_); - - // Returns the credential for the peer from which we have received - // the last message. If no message has been received yet, - // the function returns empty credential. - virtual const blob_t &get_credential () const; - - // i_pipe_events will be forwarded to these functions. - virtual void xread_activated (pipe_t *pipe_); - virtual void xwrite_activated (pipe_t *pipe_); - virtual void xhiccuped (pipe_t *pipe_); - virtual void xpipe_terminated (pipe_t *pipe_) = 0; - - // the default implementation assumes that joub and leave are not supported. - virtual int xjoin (const char *group_); - virtual int xleave (const char *group_); - - // Delay actual destruction of the socket. - void process_destroy (); - - // Next assigned name on a zmq_connect() call used by ROUTER and STREAM socket types - std::string connect_routing_id; - - private: - // test if event should be sent and then dispatch it - void event(const std::string &addr_, intptr_t fd_, int type_); - - // Socket event data dispatch - void monitor_event (int event_, intptr_t value_, const std::string& addr_); - - // Monitor socket cleanup - void stop_monitor (bool send_monitor_stopped_event_ = true); - - // Creates new endpoint ID and adds the endpoint to the map. - void add_endpoint (const char *addr_, own_t *endpoint_, pipe_t *pipe); - - // Map of open endpoints. - typedef std::pair endpoint_pipe_t; - typedef std::multimap endpoints_t; - endpoints_t endpoints; - - // Map of open inproc endpoints. - typedef std::multimap inprocs_t; - inprocs_t inprocs; - - // To be called after processing commands or invoking any command - // handlers explicitly. If required, it will deallocate the socket. - void check_destroy (); - - // Moves the flags from the message to local variables, - // to be later retrieved by getsockopt. - void extract_flags (msg_t *msg_); - - // Used to check whether the object is a socket. - uint32_t tag; - - // If true, associated context was already terminated. - bool ctx_terminated; - - // If true, object should have been already destroyed. However, - // destruction is delayed while we unwind the stack to the point - // where it doesn't intersect the object being destroyed. - bool destroyed; - - // Parse URI string. - int parse_uri (const char *uri_, std::string &protocol_, - std::string &address_); - - // Check whether transport protocol, as specified in connect or - // bind, is available and compatible with the socket type. - int check_protocol (const std::string &protocol_); - - // Register the pipe with this socket. - void attach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_ = false); - - // Processes commands sent to this socket (if any). If timeout is -1, - // returns only after at least one command was processed. - // If throttle argument is true, commands are processed at most once - // in a predefined time period. - int process_commands (int timeout_, bool throttle_); - - // Handlers for incoming commands. - void process_stop (); - void process_bind (zmq::pipe_t *pipe_); - void process_term (int linger_); - void process_term_endpoint (std::string *endpoint_); - - void update_pipe_options(int option_); - - // Socket's mailbox object. - i_mailbox *mailbox; - - // List of attached pipes. - typedef array_t pipes_t; - pipes_t pipes; - - // Reaper's poller and handle of this socket within it. - poller_t *poller; - poller_t::handle_t handle; - - // Timestamp of when commands were processed the last time. - uint64_t last_tsc; - - // Number of messages received since last command processing. - int ticks; - - // True if the last message received had MORE flag set. - bool rcvmore; - - // Improves efficiency of time measurement. - clock_t clock; - - // Monitor socket; - void *monitor_socket; - - // Bitmask of events being monitored - int monitor_events; - - // Last socket endpoint resolved URI - std::string last_endpoint; - - // Indicate if the socket is thread safe - bool thread_safe; - - // Signaler to be used in the reaping stage - signaler_t* reaper_signaler; - - // Mutex for synchronize access to the socket in thread safe mode - mutex_t sync; - - // Mutex to synchronize access to the monitor Pair socket - mutex_t monitor_sync; - - socket_base_t (const socket_base_t&); - const socket_base_t &operator = (const socket_base_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/socket_poller.cpp b/dep/libzmq/src/socket_poller.cpp deleted file mode 100644 index 3bda68e2cf..0000000000 --- a/dep/libzmq/src/socket_poller.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "socket_poller.hpp" -#include "err.hpp" - -zmq::socket_poller_t::socket_poller_t () : - tag (0xCAFEBABE), - signaler (NULL), - need_rebuild (true), - use_signaler (false), - poll_size(0) -#if defined ZMQ_POLL_BASED_ON_POLL - , - pollfds (NULL) -#elif defined ZMQ_POLL_BASED_ON_SELECT - , - maxfd(0) -#endif -{ -#if defined ZMQ_POLL_BASED_ON_SELECT -#if defined ZMQ_HAVE_WINDOWS - // On Windows fd_set contains array of SOCKETs, each 4 bytes. - // For large fd_sets memset() could be expensive and it is unnecessary. - // It is enough to set fd_count to 0, exactly what FD_ZERO() macro does. - FD_ZERO (&pollset_in); - FD_ZERO (&pollset_out); - FD_ZERO (&pollset_err); -#else - memset(&pollset_in, 0, sizeof(pollset_in)); - memset(&pollset_out, 0, sizeof(pollset_out)); - memset(&pollset_err, 0, sizeof(pollset_err)); -#endif -#endif -} - -zmq::socket_poller_t::~socket_poller_t () -{ - // Mark the socket_poller as dead - tag = 0xdeadbeef; - - for (items_t::iterator it = items.begin(); it != items.end(); ++it) { - if (it->socket && it->socket->check_tag()) { - int thread_safe; - size_t thread_safe_size = sizeof(int); - - if (it->socket->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, &thread_safe_size) == 0 && thread_safe) - it->socket->remove_signaler (signaler); - } - } - - if (signaler != NULL) { - delete signaler; - signaler = NULL; - } - -#if defined ZMQ_POLL_BASED_ON_POLL - if (pollfds) { - free (pollfds); - pollfds = NULL; - } -#endif -} - -bool zmq::socket_poller_t::check_tag () -{ - return tag == 0xCAFEBABE; -} - -int zmq::socket_poller_t::add (socket_base_t *socket_, void* user_data_, short events_) -{ - for (items_t::iterator it = items.begin (); it != items.end (); ++it) { - if (it->socket == socket_) { - errno = EINVAL; - return -1; - } - } - - int thread_safe; - size_t thread_safe_size = sizeof(int); - - int rc = - socket_->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, &thread_safe_size); - zmq_assert (rc == 0); - - if (thread_safe) { - if (signaler == NULL) - signaler = new signaler_t (); - - rc = socket_->add_signaler (signaler); - zmq_assert (rc == 0); - } - - item_t item = {socket_, 0, user_data_, events_ -#if defined ZMQ_POLL_BASED_ON_POLL - ,-1 -#endif - }; - items.push_back (item); - need_rebuild = true; - - return 0; -} - -int zmq::socket_poller_t::add_fd (fd_t fd_, void *user_data_, short events_) -{ - for (items_t::iterator it = items.begin (); it != items.end (); ++it) { - if (!it->socket && it->fd == fd_) { - errno = EINVAL; - return -1; - } - } - - item_t item = {NULL, fd_, user_data_, events_ -#if defined ZMQ_POLL_BASED_ON_POLL - ,-1 -#endif - }; - items.push_back (item); - need_rebuild = true; - - return 0; -} - -int zmq::socket_poller_t::modify (socket_base_t *socket_, short events_) -{ - items_t::iterator it; - - for (it = items.begin (); it != items.end (); ++it) { - if (it->socket == socket_) - break; - } - - if (it == items.end()) { - errno = EINVAL; - return -1; - } - - it->events = events_; - need_rebuild = true; - - return 0; -} - - -int zmq::socket_poller_t::modify_fd (fd_t fd_, short events_) -{ - items_t::iterator it; - - for (it = items.begin (); it != items.end (); ++it) { - if (!it->socket && it->fd == fd_) - break; - } - - if (it == items.end()) { - errno = EINVAL; - return -1; - } - - it->events = events_; - need_rebuild = true; - - return 0; -} - - -int zmq::socket_poller_t::remove (socket_base_t *socket_) -{ - items_t::iterator it; - - for (it = items.begin (); it != items.end (); ++it) { - if (it->socket == socket_) - break; - } - - if (it == items.end()) { - errno = EINVAL; - return -1; - } - - items.erase(it); - need_rebuild = true; - - int thread_safe; - size_t thread_safe_size = sizeof(int); - - if (socket_->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, &thread_safe_size) == 0 && thread_safe) - socket_->remove_signaler (signaler); - - return 0; -} - -int zmq::socket_poller_t::remove_fd (fd_t fd_) -{ - items_t::iterator it; - - for (it = items.begin (); it != items.end (); ++it) { - if (!it->socket && it->fd == fd_) - break; - } - - if (it == items.end()) { - errno = EINVAL; - return -1; - } - - items.erase (it); - need_rebuild = true; - - return 0; -} - -void zmq::socket_poller_t::rebuild () -{ -#if defined ZMQ_POLL_BASED_ON_POLL - - if (pollfds) { - free (pollfds); - pollfds = NULL; - } - - use_signaler = false; - - poll_size = 0; - - for (items_t::iterator it = items.begin (); it != items.end (); ++it) { - if (it->events) { - if (it->socket) { - int thread_safe; - size_t thread_safe_size = sizeof(int); - - int rc = it->socket->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, - &thread_safe_size); - zmq_assert (rc == 0); - - if (thread_safe) { - if (!use_signaler) { - use_signaler = true; - poll_size++; - } - } - else - poll_size++; - } - else - poll_size++; - } - } - - if (poll_size == 0) - return; - - pollfds = (pollfd*) malloc (poll_size * sizeof (pollfd)); - alloc_assert (pollfds); - - int item_nbr = 0; - - if (use_signaler) { - item_nbr = 1; - pollfds[0].fd = signaler->get_fd(); - pollfds[0].events = POLLIN; - } - - for (items_t::iterator it = items.begin (); it != items.end (); ++it) { - if (it->events) { - if (it->socket) { - int thread_safe; - size_t thread_safe_size = sizeof(int); - - int rc = it->socket->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, - &thread_safe_size); - zmq_assert (rc == 0); - - if (!thread_safe) { - size_t fd_size = sizeof (zmq::fd_t); - rc = it->socket->getsockopt (ZMQ_FD, &pollfds [item_nbr].fd, &fd_size); - zmq_assert (rc == 0); - - pollfds [item_nbr].events = POLLIN; - item_nbr++; - } - } - else { - pollfds [item_nbr].fd = it->fd; - pollfds [item_nbr].events = - (it->events & ZMQ_POLLIN ? POLLIN : 0) | - (it->events & ZMQ_POLLOUT ? POLLOUT : 0) | - (it->events & ZMQ_POLLPRI ? POLLPRI : 0); - it->pollfd_index = item_nbr; - item_nbr++; - } - } - } - - #elif defined ZMQ_POLL_BASED_ON_SELECT - - FD_ZERO (&pollset_in); - FD_ZERO (&pollset_out); - FD_ZERO (&pollset_err); - - // Ensure we do not attempt to select () on more than FD_SETSIZE - // file descriptors. - zmq_assert (items.size () <= FD_SETSIZE); - - poll_size = 0; - - use_signaler = false; - - for (items_t::iterator it = items.begin (); it != items.end (); ++it) { - if (it->socket) { - int thread_safe; - size_t thread_safe_size = sizeof(int); - - int rc = it->socket->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, - &thread_safe_size); - zmq_assert (rc == 0); - - if (thread_safe && it->events) { - use_signaler = true; - FD_SET (signaler->get_fd (), &pollset_in); - poll_size = 1; - break; - } - } - } - - maxfd = 0; - - // Build the fd_sets for passing to select (). - for (items_t::iterator it = items.begin (); it != items.end (); ++it) { - if (it->events) { - // If the poll item is a 0MQ socket we are interested in input on the - // notification file descriptor retrieved by the ZMQ_FD socket option. - if (it->socket) { - int thread_safe; - size_t thread_safe_size = sizeof(int); - - int rc = it->socket->getsockopt (ZMQ_THREAD_SAFE, &thread_safe, - &thread_safe_size); - zmq_assert (rc == 0); - - if (!thread_safe) { - zmq::fd_t notify_fd; - size_t fd_size = sizeof (zmq::fd_t); - rc = it->socket->getsockopt (ZMQ_FD, ¬ify_fd, &fd_size); - zmq_assert (rc == 0); - - FD_SET (notify_fd, &pollset_in); - if (maxfd < notify_fd) - maxfd = notify_fd; - - poll_size++; - } - } - // Else, the poll item is a raw file descriptor. Convert the poll item - // events to the appropriate fd_sets. - else { - if (it->events & ZMQ_POLLIN) - FD_SET (it->fd, &pollset_in); - if (it->events & ZMQ_POLLOUT) - FD_SET (it->fd, &pollset_out); - if (it->events & ZMQ_POLLERR) - FD_SET (it->fd, &pollset_err); - if (maxfd < it->fd) - maxfd = it->fd; - - poll_size++; - } - } - } - -#endif - - need_rebuild = false; -} - -void zmq::socket_poller_t::zero_trail_events ( - zmq::socket_poller_t::event_t *events_, - int n_events_, - int found) -{ - for (int i = found; i < n_events_; ++i) { - events_[i].socket = NULL; - events_[i].fd = 0; - events_[i].user_data = NULL; - events_[i].events = 0; - } -} - -#if defined ZMQ_POLL_BASED_ON_POLL -int zmq::socket_poller_t::check_events (zmq::socket_poller_t::event_t *events_, - int n_events_) -#elif defined ZMQ_POLL_BASED_ON_SELECT -int zmq::socket_poller_t::check_events (zmq::socket_poller_t::event_t *events_, - int n_events_, - fd_set& inset, - fd_set& outset, - fd_set& errset) -#endif -{ - int found = 0; - for (items_t::iterator it = items.begin (); it != items.end () && - found < n_events_; ++it) { - - // The poll item is a 0MQ socket. Retrieve pending events - // using the ZMQ_EVENTS socket option. - if (it->socket) { - size_t events_size = sizeof (uint32_t); - uint32_t events; - if (it->socket->getsockopt (ZMQ_EVENTS, &events, &events_size) - == -1) { - return -1; - } - - if (it->events & events) { - events_[found].socket = it->socket; - events_[found].user_data = it->user_data; - events_[found].events = it->events & events; - ++found; - } - } - // Else, the poll item is a raw file descriptor, simply convert - // the events to zmq_pollitem_t-style format. - else { - -#if defined ZMQ_POLL_BASED_ON_POLL - - short revents = pollfds [it->pollfd_index].revents; - short events = 0; - - if (revents & POLLIN) - events |= ZMQ_POLLIN; - if (revents & POLLOUT) - events |= ZMQ_POLLOUT; - if (revents & POLLPRI) - events |= ZMQ_POLLPRI; - if (revents & ~(POLLIN | POLLOUT | POLLPRI)) - events |= ZMQ_POLLERR; - -#elif defined ZMQ_POLL_BASED_ON_SELECT - - short events = 0; - - if (FD_ISSET (it->fd, &inset)) - events |= ZMQ_POLLIN; - if (FD_ISSET (it->fd, &outset)) - events |= ZMQ_POLLOUT; - if (FD_ISSET (it->fd, &errset)) - events |= ZMQ_POLLERR; -#endif //POLL_SELECT - - if (events) { - events_[found].socket = NULL; - events_[found].user_data = it->user_data; - events_[found].fd = it->fd; - events_[found].events = events; - ++found; - } - } - } - - return found; -} - -//Return 0 if timeout is expired otherwise 1 -int zmq::socket_poller_t::adjust_timeout (zmq::clock_t& clock, long timeout_, - uint64_t& now, - uint64_t& end, - bool& first_pass) -{ - - // If socket_poller_t::timeout is zero, exit immediately whether there - // are events or not. - if (timeout_ == 0) - return 0; - - // At this point we are meant to wait for events but there are none. - // If timeout is infinite we can just loop until we get some events. - if (timeout_ < 0) { - if (first_pass) - first_pass = false; - return 1; - } - - // The timeout is finite and there are no events. In the first pass - // we get a timestamp of when the polling have begun. (We assume that - // first pass have taken negligible time). We also compute the time - // when the polling should time out. - now = clock.now_ms (); - if (first_pass) { - end = now + timeout_; - first_pass = false; - return 1; - } - - // Find out whether timeout have expired. - if (now >= end) - return 0; - - return 1; -} - -int zmq::socket_poller_t::wait (zmq::socket_poller_t::event_t *events_, - int n_events_, - long timeout_) -{ - if (items.empty () && timeout_ < 0) { - errno = EFAULT; - return -1; - } - - if (need_rebuild) - rebuild (); - - if (unlikely (poll_size == 0)) { - // We'll report an error (timed out) as if the list was non-empty and - // no event occurred within the specified timeout. Otherwise the caller - // needs to check the return value AND the event to avoid using the - // nullified event data. - errno = EAGAIN; - if (timeout_ == 0) - return -1; -#if defined ZMQ_HAVE_WINDOWS - Sleep (timeout_ > 0 ? timeout_ : INFINITE); - return -1; -#elif defined ZMQ_HAVE_ANDROID - usleep (timeout_ * 1000); - return -1; -#elif defined ZMQ_HAVE_OSX - usleep (timeout_ * 1000); - errno = EAGAIN; - return -1; -#else - usleep (timeout_ * 1000); - return -1; -#endif - } - -#if defined ZMQ_POLL_BASED_ON_POLL - zmq::clock_t clock; - uint64_t now = 0; - uint64_t end = 0; - - bool first_pass = true; - - while (true) { - // Compute the timeout for the subsequent poll. - int timeout; - if (first_pass) - timeout = 0; - else - if (timeout_ < 0) - timeout = -1; - else - timeout = end - now; - - // Wait for events. - while (true) { - int rc = poll (pollfds, poll_size, timeout); - if (rc == -1 && errno == EINTR) { - return -1; - } - errno_assert (rc >= 0); - break; - } - - // Receive the signal from pollfd - if (use_signaler && pollfds[0].revents & POLLIN) - signaler->recv (); - - // Check for the events. - int found = check_events (events_, n_events_); - if (found) { - if (found > 0) - zero_trail_events (events_, n_events_, found); - return found; - } - - // Adjust timeout or break - if (adjust_timeout (clock, timeout_, now, end, first_pass) == 0) - break; - } - errno = EAGAIN; - return -1; - -#elif defined ZMQ_POLL_BASED_ON_SELECT - - zmq::clock_t clock; - uint64_t now = 0; - uint64_t end = 0; - - bool first_pass = true; - - fd_set inset, outset, errset; - - while (true) { - - // Compute the timeout for the subsequent poll. - timeval timeout; - timeval *ptimeout; - if (first_pass) { - timeout.tv_sec = 0; - timeout.tv_usec = 0; - ptimeout = &timeout; - } - else - if (timeout_ < 0) - ptimeout = NULL; - else { - timeout.tv_sec = (long) ((end - now) / 1000); - timeout.tv_usec = (long) ((end - now) % 1000 * 1000); - ptimeout = &timeout; - } - - // Wait for events. Ignore interrupts if there's infinite timeout. - while (true) { -#if defined ZMQ_HAVE_WINDOWS - // On Windows we don't need to copy the whole fd_set. - // SOCKETS are continuous from the beginning of fd_array in fd_set. - // We just need to copy fd_count elements of fd_array. - // We gain huge memcpy() improvement if number of used SOCKETs is much lower than FD_SETSIZE. - memcpy (&inset, &pollset_in, (char *) (pollset_in.fd_array + pollset_in.fd_count ) - (char *) &pollset_in ); - memcpy (&outset, &pollset_out, (char *) (pollset_out.fd_array + pollset_out.fd_count) - (char *) &pollset_out); - memcpy (&errset, &pollset_err, (char *) (pollset_err.fd_array + pollset_err.fd_count) - (char *) &pollset_err); - int rc = select (0, &inset, &outset, &errset, ptimeout); - if (unlikely (rc == SOCKET_ERROR)) { - errno = zmq::wsa_error_to_errno (WSAGetLastError ()); - wsa_assert (errno == ENOTSOCK); - return -1; - } -#else - memcpy (&inset, &pollset_in, sizeof (fd_set)); - memcpy (&outset, &pollset_out, sizeof (fd_set)); - memcpy (&errset, &pollset_err, sizeof (fd_set)); - int rc = select (maxfd + 1, &inset, &outset, &errset, ptimeout); - if (unlikely (rc == -1)) { - errno_assert (errno == EINTR || errno == EBADF); - return -1; - } -#endif - break; - } - - if (use_signaler && FD_ISSET (signaler->get_fd (), &inset)) - signaler->recv (); - - // Check for the events. - int found = check_events(events_, n_events_, inset, outset, errset); - if (found) { - if (found > 0) - zero_trail_events (events_, n_events_, found); - return found; - } - - // Adjust timeout or break - if (adjust_timeout (clock, timeout_, now, end, first_pass) == 0) - break; - } - - errno = EAGAIN; - return -1; - -#else - - // Exotic platforms that support neither poll() nor select(). - errno = ENOTSUP; - return -1; - -#endif -} diff --git a/dep/libzmq/src/socket_poller.hpp b/dep/libzmq/src/socket_poller.hpp deleted file mode 100644 index a774ce6a2b..0000000000 --- a/dep/libzmq/src/socket_poller.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SOCKET_POLLER_HPP_INCLUDED__ -#define __ZMQ_SOCKET_POLLER_HPP_INCLUDED__ - -#include "poller.hpp" - -#if defined ZMQ_POLL_BASED_ON_POLL && !defined ZMQ_HAVE_WINDOWS -#include -#endif - -#if defined ZMQ_HAVE_WINDOWS -#include "windows.hpp" -#else -#include -#endif - -#include -#include - -#include "socket_base.hpp" -#include "signaler.hpp" - -namespace zmq -{ - - class socket_poller_t - { - public: - socket_poller_t (); - ~socket_poller_t (); - - typedef struct event_t - { - socket_base_t *socket; - fd_t fd; - void *user_data; - short events; - } event_t; - - int add (socket_base_t *socket, void *user_data, short events); - int modify (socket_base_t *socket, short events); - int remove (socket_base_t *socket); - - int add_fd (fd_t fd, void *user_data, short events); - int modify_fd (fd_t fd, short events); - int remove_fd (fd_t fd); - - int wait (event_t *event, int n_events, long timeout); - - inline int size (void) { return static_cast (items.size ()); }; - - // Return false if object is not a socket. - bool check_tag (); - - private: - void zero_trail_events (zmq::socket_poller_t::event_t *events_, - int n_events_, - int found); -#if defined ZMQ_POLL_BASED_ON_POLL - int check_events (zmq::socket_poller_t::event_t *events_, - int n_events_); -#elif defined ZMQ_POLL_BASED_ON_SELECT - int check_events (zmq::socket_poller_t::event_t *events_, int n_events_, - fd_set& inset, - fd_set& outset, - fd_set& errset); -#endif - int adjust_timeout (zmq::clock_t& clock, long timeout_, uint64_t& now, - uint64_t& end, - bool& first_pass); - void rebuild (); - - // Used to check whether the object is a socket_poller. - uint32_t tag; - - // Signaler used for thread safe sockets polling - signaler_t* signaler; - - typedef struct item_t { - socket_base_t *socket; - fd_t fd; - void *user_data; - short events; -#if defined ZMQ_POLL_BASED_ON_POLL - int pollfd_index; -#endif - } item_t; - - // List of sockets - typedef std::vector items_t; - items_t items; - - // Does the pollset needs rebuilding? - bool need_rebuild; - - // Should the signaler be used for the thread safe polling? - bool use_signaler; - - // Size of the pollset - int poll_size; - -#if defined ZMQ_POLL_BASED_ON_POLL - pollfd *pollfds; -#elif defined ZMQ_POLL_BASED_ON_SELECT - fd_set pollset_in; - fd_set pollset_out; - fd_set pollset_err; - zmq::fd_t maxfd; -#endif - - socket_poller_t (const socket_poller_t&); - const socket_poller_t &operator = (const socket_poller_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/socks.cpp b/dep/libzmq/src/socks.cpp deleted file mode 100644 index 6a7cb2e72a..0000000000 --- a/dep/libzmq/src/socks.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "err.hpp" -#include "socks.hpp" -#include "tcp.hpp" - -#ifndef ZMQ_HAVE_WINDOWS -#include -#include -#include -#endif - -zmq::socks_greeting_t::socks_greeting_t (uint8_t method_) : - num_methods (1) -{ - methods [0] = method_; -} - -zmq::socks_greeting_t::socks_greeting_t ( - uint8_t *methods_, uint8_t num_methods_) - : num_methods (num_methods_) -{ - for (uint8_t i = 0; i < num_methods_; i++) - methods [i] = methods_ [i]; -} - -zmq::socks_greeting_encoder_t::socks_greeting_encoder_t () - : bytes_encoded (0), bytes_written (0) -{} - -void zmq::socks_greeting_encoder_t::encode (const socks_greeting_t &greeting_) -{ - uint8_t *ptr = buf; - - *ptr++ = 0x05; - *ptr++ = (uint8_t) greeting_.num_methods; - for (uint8_t i = 0; i < greeting_.num_methods; i++) - *ptr++ = greeting_.methods [i]; - - bytes_encoded = 2 + greeting_.num_methods; - bytes_written = 0; -} - -int zmq::socks_greeting_encoder_t::output (fd_t fd_) -{ - const int rc = tcp_write ( - fd_, buf + bytes_written, bytes_encoded - bytes_written); - if (rc > 0) - bytes_written += static_cast (rc); - return rc; -} - -bool zmq::socks_greeting_encoder_t::has_pending_data () const -{ - return bytes_written < bytes_encoded; -} - -void zmq::socks_greeting_encoder_t::reset () -{ - bytes_encoded = bytes_written = 0; -} - -zmq::socks_choice_t::socks_choice_t (unsigned char method_) - : method (method_) -{} - -zmq::socks_choice_decoder_t::socks_choice_decoder_t () - : bytes_read (0) -{} - -int zmq::socks_choice_decoder_t::input (fd_t fd_) -{ - zmq_assert (bytes_read < 2); - const int rc = tcp_read (fd_, buf + bytes_read, 2 - bytes_read); - if (rc > 0) { - bytes_read += static_cast (rc); - if (buf [0] != 0x05) - return -1; - } - return rc; -} - -bool zmq::socks_choice_decoder_t::message_ready () const -{ - return bytes_read == 2; -} - -zmq::socks_choice_t zmq::socks_choice_decoder_t::decode () -{ - zmq_assert (message_ready ()); - return socks_choice_t (buf [1]); -} - -void zmq::socks_choice_decoder_t::reset () -{ - bytes_read = 0; -} - - -zmq::socks_request_t::socks_request_t ( - uint8_t command_, std::string hostname_, uint16_t port_) - : command (command_), hostname (hostname_), port (port_) -{ - zmq_assert (hostname_.size () <= UINT8_MAX); -} - -zmq::socks_request_encoder_t::socks_request_encoder_t () - : bytes_encoded (0), bytes_written (0) -{} - -void zmq::socks_request_encoder_t::encode (const socks_request_t &req) -{ - zmq_assert (req.hostname.size() <= UINT8_MAX); - - unsigned char *ptr = buf; - *ptr++ = 0x05; - *ptr++ = req.command; - *ptr++ = 0x00; - -#if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64 - __addrinfo64 hints, *res = NULL; -#else - addrinfo hints, *res = NULL; -#endif - - memset (&hints, 0, sizeof hints); - - // Suppress potential DNS lookups. - hints.ai_flags = AI_NUMERICHOST; - - const int rc = getaddrinfo (req.hostname.c_str (), NULL, &hints, &res); - if (rc == 0 && res->ai_family == AF_INET) { - struct sockaddr_in *sockaddr_in = - reinterpret_cast (res->ai_addr); - *ptr++ = 0x01; - memcpy (ptr, &sockaddr_in->sin_addr, 4); - ptr += 4; - } - else - if (rc == 0 && res->ai_family == AF_INET6) { - struct sockaddr_in6 *sockaddr_in6 = - reinterpret_cast (res->ai_addr); - *ptr++ = 0x04; - memcpy (ptr, &sockaddr_in6->sin6_addr, 16); - ptr += 16; - } - else { - *ptr++ = 0x03; - *ptr++ = (unsigned char) req.hostname.size (); - memcpy (ptr, req.hostname.c_str (), req.hostname.size ()); - ptr += req.hostname.size (); - } - - if (rc == 0) - freeaddrinfo (res); - - *ptr++ = req.port / 256; - *ptr++ = req.port % 256; - - bytes_encoded = ptr - buf; - bytes_written = 0; -} - -int zmq::socks_request_encoder_t::output (fd_t fd_) -{ - const int rc = tcp_write ( - fd_, buf + bytes_written, bytes_encoded - bytes_written); - if (rc > 0) - bytes_written += static_cast (rc); - return rc; -} - -bool zmq::socks_request_encoder_t::has_pending_data () const -{ - return bytes_written < bytes_encoded; -} - -void zmq::socks_request_encoder_t::reset () -{ - bytes_encoded = bytes_written = 0; -} - -zmq::socks_response_t::socks_response_t ( - uint8_t response_code_, std::string address_, uint16_t port_) - : response_code (response_code_), address (address_), port (port_) -{} - -zmq::socks_response_decoder_t::socks_response_decoder_t () - : bytes_read (0) -{} - -int zmq::socks_response_decoder_t::input (fd_t fd_) -{ - size_t n = 0; - - if (bytes_read < 5) - n = 5 - bytes_read; - else { - const uint8_t atyp = buf [3]; - zmq_assert (atyp == 0x01 || atyp == 0x03 || atyp == 0x04); - if (atyp == 0x01) - n = 3 + 2; - else - if (atyp == 0x03) - n = buf [4] + 2; - else - if (atyp == 0x04) - n = 15 + 2; - } - const int rc = tcp_read (fd_, buf + bytes_read, n); - if (rc > 0) { - bytes_read += static_cast (rc); - if (buf [0] != 0x05) - return -1; - if (bytes_read >= 2) - if (buf [1] > 0x08) - return -1; - if (bytes_read >= 3) - if (buf [2] != 0x00) - return -1; - if (bytes_read >= 4) { - const uint8_t atyp = buf [3]; - if (atyp != 0x01 && atyp != 0x03 && atyp != 0x04) - return -1; - } - } - return rc; -} - -bool zmq::socks_response_decoder_t::message_ready () const -{ - if (bytes_read < 4) - return false; - else { - const uint8_t atyp = buf [3]; - zmq_assert (atyp == 0x01 || atyp == 0x03 || atyp == 0x04); - if (atyp == 0x01) - return bytes_read == 10; - else - if (atyp == 0x03) - return bytes_read > 4 && bytes_read == 4 + 1 + buf [4] + 2u; - else - return bytes_read == 22; - } -} - -zmq::socks_response_t zmq::socks_response_decoder_t::decode () -{ - zmq_assert (message_ready ()); - return socks_response_t (buf [1], "", 0); -} - -void zmq::socks_response_decoder_t::reset () -{ - bytes_read = 0; -} diff --git a/dep/libzmq/src/socks.hpp b/dep/libzmq/src/socks.hpp deleted file mode 100644 index 6376e793ec..0000000000 --- a/dep/libzmq/src/socks.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SOCKS_HPP_INCLUDED__ -#define __ZMQ_SOCKS_HPP_INCLUDED__ - -#include -#include "fd.hpp" -#include "stdint.hpp" - -namespace zmq -{ - - struct socks_greeting_t - { - socks_greeting_t (uint8_t method); - socks_greeting_t (uint8_t *methods_, uint8_t num_methods_); - - uint8_t methods [UINT8_MAX]; - const size_t num_methods; - }; - - class socks_greeting_encoder_t - { - public: - socks_greeting_encoder_t (); - void encode (const socks_greeting_t &greeting_); - int output (fd_t fd_); - bool has_pending_data () const; - void reset (); - - private: - size_t bytes_encoded; - size_t bytes_written; - uint8_t buf [2 + UINT8_MAX]; - }; - - struct socks_choice_t - { - socks_choice_t (uint8_t method_); - - uint8_t method; - }; - - class socks_choice_decoder_t - { - public: - socks_choice_decoder_t (); - int input (fd_t fd_); - bool message_ready () const; - socks_choice_t decode (); - void reset (); - - private: - unsigned char buf [2]; - size_t bytes_read; - }; - - struct socks_request_t - { - socks_request_t ( - uint8_t command_, std::string hostname_, uint16_t port_); - - const uint8_t command; - const std::string hostname; - const uint16_t port; - }; - - class socks_request_encoder_t - { - public: - socks_request_encoder_t (); - void encode (const socks_request_t &req); - int output (fd_t fd_); - bool has_pending_data () const; - void reset (); - - private: - size_t bytes_encoded; - size_t bytes_written; - uint8_t buf [4 + UINT8_MAX + 1 + 2]; - }; - - struct socks_response_t - { - socks_response_t ( - uint8_t response_code_, std::string address_, uint16_t port_); - uint8_t response_code; - std::string address; - uint16_t port; - }; - - class socks_response_decoder_t - { - public: - socks_response_decoder_t (); - int input (fd_t fd_); - bool message_ready () const; - socks_response_t decode (); - void reset (); - - private: - int8_t buf [4 + UINT8_MAX + 1 + 2]; - size_t bytes_read; - }; - -} - -#endif diff --git a/dep/libzmq/src/socks_connecter.cpp b/dep/libzmq/src/socks_connecter.cpp deleted file mode 100644 index ab14dcd5a1..0000000000 --- a/dep/libzmq/src/socks_connecter.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "macros.hpp" -#include "socks_connecter.hpp" -#include "stream_engine.hpp" -#include "random.hpp" -#include "err.hpp" -#include "ip.hpp" -#include "tcp.hpp" -#include "address.hpp" -#include "tcp_address.hpp" -#include "session_base.hpp" -#include "socks.hpp" - -#ifndef ZMQ_HAVE_WINDOWS -#include -#include -#include -#endif - -zmq::socks_connecter_t::socks_connecter_t (class io_thread_t *io_thread_, - class session_base_t *session_, const options_t &options_, - address_t *addr_, address_t *proxy_addr_, bool delayed_start_) : - own_t (io_thread_, options_), - io_object_t (io_thread_), - addr (addr_), - proxy_addr (proxy_addr_), - status (unplugged), - s (retired_fd), - handle((handle_t)NULL), - handle_valid(false), - delayed_start (delayed_start_), - timer_started(false), - session (session_), - current_reconnect_ivl (options.reconnect_ivl) -{ - zmq_assert (addr); - zmq_assert (addr->protocol == "tcp"); - proxy_addr->to_string (endpoint); - socket = session->get_socket (); -} - -zmq::socks_connecter_t::~socks_connecter_t () -{ - zmq_assert (s == retired_fd); - LIBZMQ_DELETE(proxy_addr); -} - -void zmq::socks_connecter_t::process_plug () -{ - if (delayed_start) - start_timer (); - else - initiate_connect (); -} - -void zmq::socks_connecter_t::process_term (int linger_) -{ - switch (status) { - case unplugged: - break; - case waiting_for_reconnect_time: - cancel_timer (reconnect_timer_id); - break; - case waiting_for_proxy_connection: - case sending_greeting: - case waiting_for_choice: - case sending_request: - case waiting_for_response: - rm_fd (handle); - if (s != retired_fd) - close (); - break; - } - - own_t::process_term (linger_); -} - -void zmq::socks_connecter_t::in_event () -{ - zmq_assert (status != unplugged - && status != waiting_for_reconnect_time); - - if (status == waiting_for_choice) { - int rc = choice_decoder.input (s); - if (rc == 0 || rc == -1) - error (); - else - if (choice_decoder.message_ready ()) { - const socks_choice_t choice = choice_decoder.decode (); - rc = process_server_response (choice); - if (rc == -1) - error (); - else { - std::string hostname = ""; - uint16_t port = 0; - if (parse_address (addr->address, hostname, port) == -1) - error (); - else { - request_encoder.encode ( - socks_request_t (1, hostname, port)); - reset_pollin (handle); - set_pollout (handle); - status = sending_request; - } - } - } - } - else - if (status == waiting_for_response) { - int rc = response_decoder.input (s); - if (rc == 0 || rc == -1) - error (); - else - if (response_decoder.message_ready ()) { - const socks_response_t response = response_decoder.decode (); - rc = process_server_response (response); - if (rc == -1) - error (); - else { - // Create the engine object for this connection. - stream_engine_t *engine = new (std::nothrow) - stream_engine_t (s, options, endpoint); - alloc_assert (engine); - - // Attach the engine to the corresponding session object. - send_attach (session, engine); - - socket->event_connected (endpoint, (int) s); - - rm_fd (handle); - s = -1; - status = unplugged; - - // Shut the connecter down. - terminate (); - } - } - } - else - error (); -} - -void zmq::socks_connecter_t::out_event () -{ - zmq_assert (status == waiting_for_proxy_connection - || status == sending_greeting - || status == sending_request); - - if (status == waiting_for_proxy_connection) { - const int rc = (int) check_proxy_connection (); - if (rc == -1) - error (); - else { - greeting_encoder.encode ( - socks_greeting_t (socks_no_auth_required)); - status = sending_greeting; - } - } - else - if (status == sending_greeting) { - zmq_assert (greeting_encoder.has_pending_data ()); - const int rc = greeting_encoder.output (s); - if (rc == -1 || rc == 0) - error (); - else - if (!greeting_encoder.has_pending_data ()) { - reset_pollout (handle); - set_pollin (handle); - status = waiting_for_choice; - } - } - else { - zmq_assert (request_encoder.has_pending_data ()); - const int rc = request_encoder.output (s); - if (rc == -1 || rc == 0) - error (); - else - if (!request_encoder.has_pending_data ()) { - reset_pollout (handle); - set_pollin (handle); - status = waiting_for_response; - } - } -} - -void zmq::socks_connecter_t::initiate_connect () -{ - // Open the connecting socket. - const int rc = connect_to_proxy (); - - // Connect may succeed in synchronous manner. - if (rc == 0) { - handle = add_fd (s); - set_pollout (handle); - status = sending_greeting; - } - // Connection establishment may be delayed. Poll for its completion. - else - if (errno == EINPROGRESS) { - handle = add_fd (s); - set_pollout (handle); - status = waiting_for_proxy_connection; - socket->event_connect_delayed (endpoint, zmq_errno ()); - } - // Handle any other error condition by eventual reconnect. - else { - if (s != retired_fd) - close (); - start_timer (); - } -} - -int zmq::socks_connecter_t::process_server_response ( - const socks_choice_t &response) -{ - // We do not support any authentication method for now. - return response.method == 0? 0: -1; -} - -int zmq::socks_connecter_t::process_server_response ( - const socks_response_t &response) -{ - return response.response_code == 0? 0: -1; -} - -void zmq::socks_connecter_t::timer_event (int id_) -{ - zmq_assert (status == waiting_for_reconnect_time); - zmq_assert (id_ == reconnect_timer_id); - initiate_connect (); -} - -void zmq::socks_connecter_t::error () -{ - rm_fd (handle); - close (); - greeting_encoder.reset (); - choice_decoder.reset (); - request_encoder.reset (); - response_decoder.reset (); - start_timer (); -} - -void zmq::socks_connecter_t::start_timer () -{ - const int interval = get_new_reconnect_ivl (); - add_timer (interval, reconnect_timer_id); - status = waiting_for_reconnect_time; - socket->event_connect_retried (endpoint, interval); -} - -int zmq::socks_connecter_t::get_new_reconnect_ivl () -{ - // The new interval is the current interval + random value. - const int interval = current_reconnect_ivl + - generate_random () % options.reconnect_ivl; - - // Only change the current reconnect interval if the maximum reconnect - // interval was set and if it's larger than the reconnect interval. - if (options.reconnect_ivl_max > 0 && - options.reconnect_ivl_max > options.reconnect_ivl) - // Calculate the next interval - current_reconnect_ivl = - std::min (current_reconnect_ivl * 2, options.reconnect_ivl_max); - return interval; -} - -int zmq::socks_connecter_t::connect_to_proxy () -{ - zmq_assert (s == retired_fd); - - // Resolve the address - LIBZMQ_DELETE(proxy_addr->resolved.tcp_addr); - proxy_addr->resolved.tcp_addr = new (std::nothrow) tcp_address_t (); - alloc_assert (proxy_addr->resolved.tcp_addr); - - int rc = proxy_addr->resolved.tcp_addr->resolve ( - proxy_addr->address.c_str (), false, options.ipv6); - if (rc != 0) { - LIBZMQ_DELETE(proxy_addr->resolved.tcp_addr); - return -1; - } - zmq_assert (proxy_addr->resolved.tcp_addr != NULL); - const tcp_address_t *tcp_addr = proxy_addr->resolved.tcp_addr; - - // Create the socket. - s = open_socket (tcp_addr->family (), SOCK_STREAM, IPPROTO_TCP); -#ifdef ZMQ_HAVE_WINDOWS - if (s == INVALID_SOCKET) - return -1; -#else - if (s == -1) - return -1; -#endif - - // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. - // Switch it on in such cases. - if (tcp_addr->family () == AF_INET6) - enable_ipv4_mapping (s); - - // Set the IP Type-Of-Service priority for this socket - if (options.tos != 0) - set_ip_type_of_service (s, options.tos); - - // Bind the socket to a device if applicable - if (!options.bound_device.empty ()) - bind_to_device (s, options.bound_device); - - // Set the socket to non-blocking mode so that we get async connect(). - unblock_socket (s); - - // Set the socket buffer limits for the underlying socket. - if (options.sndbuf >= 0) - set_tcp_send_buffer (s, options.sndbuf); - if (options.rcvbuf >= 0) - set_tcp_receive_buffer (s, options.rcvbuf); - - // Set the IP Type-Of-Service for the underlying socket - if (options.tos != 0) - set_ip_type_of_service (s, options.tos); - - // Set a source address for conversations - if (tcp_addr->has_src_addr ()) { - rc = ::bind (s, tcp_addr->src_addr (), tcp_addr->src_addrlen ()); - if (rc == -1) { - close (); - return -1; - } - } - - // Connect to the remote peer. - rc = ::connect (s, tcp_addr->addr (), tcp_addr->addrlen ()); - - // Connect was successful immediately. - if (rc == 0) - return 0; - - // Translate error codes indicating asynchronous connect has been - // launched to a uniform EINPROGRESS. -#ifdef ZMQ_HAVE_WINDOWS - const int last_error = WSAGetLastError(); - if (last_error == WSAEINPROGRESS || last_error == WSAEWOULDBLOCK) - errno = EINPROGRESS; - else { - errno = wsa_error_to_errno (last_error); - close (); - } -#else - if (errno == EINTR) - errno = EINPROGRESS; -#endif - return -1; -} - -zmq::fd_t zmq::socks_connecter_t::check_proxy_connection () -{ - // Async connect has finished. Check whether an error occurred - int err = 0; -#ifdef ZMQ_HAVE_HPUX - int len = sizeof err; -#else - socklen_t len = sizeof err; -#endif - - int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len); - - // Assert if the error was caused by 0MQ bug. - // Networking problems are OK. No need to assert. -#ifdef ZMQ_HAVE_WINDOWS - zmq_assert (rc == 0); - if (err != 0) { - wsa_assert (err == WSAECONNREFUSED - || err == WSAETIMEDOUT - || err == WSAECONNABORTED - || err == WSAEHOSTUNREACH - || err == WSAENETUNREACH - || err == WSAENETDOWN - || err == WSAEACCES - || err == WSAEINVAL - || err == WSAEADDRINUSE); - return -1; - } -#else - // Following code should handle both Berkeley-derived socket - // implementations and Solaris. - if (rc == -1) - err = errno; - if (err != 0) { - errno = err; - errno_assert ( - errno == ECONNREFUSED || - errno == ECONNRESET || - errno == ETIMEDOUT || - errno == EHOSTUNREACH || - errno == ENETUNREACH || - errno == ENETDOWN || - errno == EINVAL); - return -1; - } -#endif - - rc = tune_tcp_socket (s); - rc = rc | tune_tcp_keepalives (s, options.tcp_keepalive, options.tcp_keepalive_cnt, - options.tcp_keepalive_idle, options.tcp_keepalive_intvl); - if (rc != 0) - return -1; - - return 0; -} - -void zmq::socks_connecter_t::close () -{ - zmq_assert (s != retired_fd); -#ifdef ZMQ_HAVE_WINDOWS - const int rc = closesocket (s); - wsa_assert (rc != SOCKET_ERROR); -#else - const int rc = ::close (s); - errno_assert (rc == 0); -#endif - socket->event_closed (endpoint, (int) s); - s = retired_fd; -} - -int zmq::socks_connecter_t::parse_address ( - const std::string &address_, std::string &hostname_, uint16_t &port_) -{ - // Find the ':' at end that separates address from the port number. - const size_t idx = address_.rfind (':'); - if (idx == std::string::npos) { - errno = EINVAL; - return -1; - } - - // Extract hostname - if (idx < 2 || address_ [0] != '[' || address_ [idx - 1] != ']') - hostname_ = address_.substr (0, idx); - else - hostname_ = address_.substr (1, idx - 2); - - // Separate the hostname/port. - const std::string port_str = address_.substr (idx + 1); - // Parse the port number (0 is not a valid port). - port_ = (uint16_t) atoi (port_str.c_str ()); - if (port_ == 0) { - errno = EINVAL; - return -1; - } - return 0; -} diff --git a/dep/libzmq/src/socks_connecter.hpp b/dep/libzmq/src/socks_connecter.hpp deleted file mode 100644 index e34a0254bd..0000000000 --- a/dep/libzmq/src/socks_connecter.hpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __SOCKS_CONNECTER_HPP_INCLUDED__ -#define __SOCKS_CONNECTER_HPP_INCLUDED__ - -#include "fd.hpp" -#include "io_object.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "socks.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - struct address_t; - - class socks_connecter_t : public own_t, public io_object_t - { - public: - - // If 'delayed_start' is true connecter first waits for a while, - // then starts connection process. - socks_connecter_t (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_, const options_t &options_, - address_t *addr_, address_t *proxy_addr_, bool delayed_start_); - ~socks_connecter_t (); - - private: - enum { - unplugged, - waiting_for_reconnect_time, - waiting_for_proxy_connection, - sending_greeting, - waiting_for_choice, - sending_request, - waiting_for_response - }; - - // ID of the timer used to delay the reconnection. - enum { reconnect_timer_id = 1 }; - - // Method ID - enum { socks_no_auth_required = 0 }; - - // Handlers for incoming commands. - virtual void process_plug (); - virtual void process_term (int linger_); - - // Handlers for I/O events. - virtual void in_event (); - virtual void out_event (); - virtual void timer_event (int id_); - - // Internal function to start the actual connection establishment. - void initiate_connect (); - - int process_server_response (const socks_choice_t &response); - int process_server_response (const socks_response_t &response); - - int parse_address (const std::string &address_, - std::string &hostname_, uint16_t &port_); - - int connect_to_proxy (); - - void error (); - - // Internal function to start reconnect timer - void start_timer (); - - // Internal function to return a reconnect backoff delay. - // Will modify the current_reconnect_ivl used for next call - // Returns the currently used interval - int get_new_reconnect_ivl (); - - // Open TCP connecting socket. Returns -1 in case of error, - // 0 if connect was successful immediately. Returns -1 with - // EAGAIN errno if async connect was launched. - int open (); - - // Close the connecting socket. - void close (); - - // Get the file descriptor of newly created connection. Returns - // retired_fd if the connection was unsuccessful. - zmq::fd_t check_proxy_connection (); - - socks_greeting_encoder_t greeting_encoder; - socks_choice_decoder_t choice_decoder; - socks_request_encoder_t request_encoder; - socks_response_decoder_t response_decoder; - - // Address to connect to. Owned by session_base_t. - address_t *addr; - - // SOCKS address; owned by this connecter. - address_t *proxy_addr; - - int status; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // If true file descriptor is registered with the poller and 'handle' - // contains valid value. - bool handle_valid; - - // If true, connecter is waiting a while before trying to connect. - const bool delayed_start; - - // True iff a timer has been started. - bool timer_started; - - // Reference to the session we belong to. - zmq::session_base_t *session; - - // Current reconnect ivl, updated for backoff strategy - int current_reconnect_ivl; - - // String representation of endpoint to connect to - std::string endpoint; - - // Socket - zmq::socket_base_t *socket; - - socks_connecter_t (const socks_connecter_t&); - const socks_connecter_t &operator = (const socks_connecter_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/stdint.hpp b/dep/libzmq/src/stdint.hpp deleted file mode 100644 index 3ee4892a2c..0000000000 --- a/dep/libzmq/src/stdint.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_STDINT_HPP_INCLUDED__ -#define __ZMQ_STDINT_HPP_INCLUDED__ - -#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS - -#include - -#elif defined _MSC_VER && _MSC_VER < 1600 - -#ifndef int8_t -typedef __int8 int8_t; -#endif -#ifndef int16_t -typedef __int16 int16_t; -#endif -#ifndef int32_t -typedef __int32 int32_t; -#endif -#ifndef int64_t -typedef __int64 int64_t; -#endif -#ifndef uint8_t -typedef unsigned __int8 uint8_t; -#endif -#ifndef uint16_t -typedef unsigned __int16 uint16_t; -#endif -#ifndef uint32_t -typedef unsigned __int32 uint32_t; -#endif -#ifndef uint64_t -typedef unsigned __int64 uint64_t; -#endif -#ifndef UINT32_MAX -#define UINT32_MAX _UI32_MAX -#endif - -#else - -#include - -#endif - -#ifndef UINT8_MAX -#define UINT8_MAX 0xFF -#endif - -#endif diff --git a/dep/libzmq/src/stream.cpp b/dep/libzmq/src/stream.cpp deleted file mode 100644 index f522ffcd16..0000000000 --- a/dep/libzmq/src/stream.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "stream.hpp" -#include "pipe.hpp" -#include "wire.hpp" -#include "random.hpp" -#include "likely.hpp" -#include "err.hpp" - -zmq::stream_t::stream_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - prefetched (false), - routing_id_sent (false), - current_out (NULL), - more_out (false), - next_integral_routing_id (generate_random ()) -{ - options.type = ZMQ_STREAM; - options.raw_socket = true; - - prefetched_routing_id.init (); - prefetched_msg.init (); -} - -zmq::stream_t::~stream_t () -{ - zmq_assert (outpipes.empty ()); - prefetched_routing_id.close (); - prefetched_msg.close (); -} - -void zmq::stream_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED(subscribe_to_all_); - - zmq_assert (pipe_); - - identify_peer (pipe_); - fq.attach (pipe_); -} - -void zmq::stream_t::xpipe_terminated (pipe_t *pipe_) -{ - outpipes_t::iterator it = outpipes.find (pipe_->get_routing_id ()); - zmq_assert (it != outpipes.end ()); - outpipes.erase (it); - fq.pipe_terminated (pipe_); - if (pipe_ == current_out) - current_out = NULL; -} - -void zmq::stream_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::stream_t::xwrite_activated (pipe_t *pipe_) -{ - outpipes_t::iterator it; - for (it = outpipes.begin (); it != outpipes.end (); ++it) - if (it->second.pipe == pipe_) - break; - - zmq_assert (it != outpipes.end ()); - zmq_assert (!it->second.active); - it->second.active = true; -} - -int zmq::stream_t::xsend (msg_t *msg_) -{ - // If this is the first part of the message it's the ID of the - // peer to send the message to. - if (!more_out) { - zmq_assert (!current_out); - - // If we have malformed message (prefix with no subsequent message) - // then just silently ignore it. - // TODO: The connections should be killed instead. - if (msg_->flags () & msg_t::more) { - - // Find the pipe associated with the routing id stored in the prefix. - // If there's no such pipe return an error - blob_t routing_id ((unsigned char*) msg_->data (), msg_->size ()); - outpipes_t::iterator it = outpipes.find (routing_id); - - if (it != outpipes.end ()) { - current_out = it->second.pipe; - if (!current_out->check_write ()) { - it->second.active = false; - current_out = NULL; - errno = EAGAIN; - return -1; - } - } - else { - errno = EHOSTUNREACH; - return -1; - } - } - - // Expect one more message frame. - more_out = true; - - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - return 0; - } - - // Ignore the MORE flag - msg_->reset_flags (msg_t::more); - - // This is the last part of the message. - more_out = false; - - // Push the message into the pipe. If there's no out pipe, just drop it. - if (current_out) { - - // Close the remote connection if user has asked to do so - // by sending zero length message. - // Pending messages in the pipe will be dropped (on receiving term- ack) - if (msg_->size () == 0) { - current_out->terminate (false); - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - current_out = NULL; - return 0; - } - bool ok = current_out->write (msg_); - if (likely (ok)) - current_out->flush (); - current_out = NULL; - } - else { - int rc = msg_->close (); - errno_assert (rc == 0); - } - - // Detach the message from the data buffer. - int rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -int zmq::stream_t::xsetsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - bool is_int = (optvallen_ == sizeof (int)); - int value = 0; - if (is_int) memcpy(&value, optval_, sizeof (int)); - - switch (option_) { - case ZMQ_CONNECT_ROUTING_ID: - if (optval_ && optvallen_) { - connect_routing_id.assign ((char*) optval_, optvallen_); - return 0; - } - break; - - case ZMQ_STREAM_NOTIFY: - if (is_int && (value == 0 || value == 1)) { - options.raw_notify = (value != 0); - return 0; - } - break; - - default: - break; - } - errno = EINVAL; - return -1; -} - -int zmq::stream_t::xrecv (msg_t *msg_) -{ - if (prefetched) { - if (!routing_id_sent) { - int rc = msg_->move (prefetched_routing_id); - errno_assert (rc == 0); - routing_id_sent = true; - } - else { - int rc = msg_->move (prefetched_msg); - errno_assert (rc == 0); - prefetched = false; - } - return 0; - } - - pipe_t *pipe = NULL; - int rc = fq.recvpipe (&prefetched_msg, &pipe); - if (rc != 0) - return -1; - - zmq_assert (pipe != NULL); - zmq_assert ((prefetched_msg.flags () & msg_t::more) == 0); - - // We have received a frame with TCP data. - // Rather than sending this frame, we keep it in prefetched - // buffer and send a frame with peer's ID. - const blob_t &routing_id = pipe->get_routing_id (); - rc = msg_->close(); - errno_assert (rc == 0); - rc = msg_->init_size (routing_id.size ()); - errno_assert (rc == 0); - - // forward metadata (if any) - metadata_t *metadata = prefetched_msg.metadata(); - if (metadata) - msg_->set_metadata(metadata); - - memcpy (msg_->data (), routing_id.data (), routing_id.size ()); - msg_->set_flags (msg_t::more); - - prefetched = true; - routing_id_sent = true; - - return 0; -} - -bool zmq::stream_t::xhas_in () -{ - // We may already have a message pre-fetched. - if (prefetched) - return true; - - // Try to read the next message. - // The message, if read, is kept in the pre-fetch buffer. - pipe_t *pipe = NULL; - int rc = fq.recvpipe (&prefetched_msg, &pipe); - if (rc != 0) - return false; - - zmq_assert (pipe != NULL); - zmq_assert ((prefetched_msg.flags () & msg_t::more) == 0); - - const blob_t &routing_id = pipe->get_routing_id (); - rc = prefetched_routing_id.init_size (routing_id.size ()); - errno_assert (rc == 0); - - // forward metadata (if any) - metadata_t *metadata = prefetched_msg.metadata(); - if (metadata) - prefetched_routing_id.set_metadata(metadata); - - memcpy (prefetched_routing_id.data (), routing_id.data (), routing_id.size ()); - prefetched_routing_id.set_flags (msg_t::more); - - prefetched = true; - routing_id_sent = false; - - return true; -} - -bool zmq::stream_t::xhas_out () -{ - // In theory, STREAM socket is always ready for writing. Whether actual - // attempt to write succeeds depends on which pipe the message is going - // to be routed to. - return true; -} - -void zmq::stream_t::identify_peer (pipe_t *pipe_) -{ - // Always assign routing id for raw-socket - unsigned char buffer [5]; - buffer [0] = 0; - blob_t routing_id; - if (connect_routing_id.length ()) { - routing_id.set ((unsigned char*) connect_routing_id.c_str(), - connect_routing_id.length ()); - connect_routing_id.clear (); - outpipes_t::iterator it = outpipes.find (routing_id); - zmq_assert (it == outpipes.end ()); - } - else { - put_uint32 (buffer + 1, next_integral_routing_id++); - routing_id.set (buffer, sizeof buffer); - memcpy (options.routing_id, routing_id.data (), routing_id.size ()); - options.routing_id_size = (unsigned char) routing_id.size (); - } - pipe_->set_router_socket_routing_id (routing_id); - // Add the record into output pipes lookup table - outpipe_t outpipe = {pipe_, true}; - const bool ok = outpipes.ZMQ_MAP_INSERT_OR_EMPLACE ( - ZMQ_MOVE(routing_id), outpipe).second; - zmq_assert (ok); -} diff --git a/dep/libzmq/src/stream.hpp b/dep/libzmq/src/stream.hpp deleted file mode 100644 index b3a4a617bc..0000000000 --- a/dep/libzmq/src/stream.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_STREAM_HPP_INCLUDED__ -#define __ZMQ_STREAM_HPP_INCLUDED__ - -#include - -#include "router.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - - class stream_t : - public socket_base_t - { - public: - - stream_t (zmq::ctx_t *parent_, uint32_t tid_, int sid); - ~stream_t (); - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - bool xhas_out (); - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - int xsetsockopt (int option_, const void *optval_, size_t optvallen_); - private: - // Generate peer's id and update lookup map - void identify_peer (pipe_t *pipe_); - - // Fair queueing object for inbound pipes. - fq_t fq; - - // True iff there is a message held in the pre-fetch buffer. - bool prefetched; - - // If true, the receiver got the message part with - // the peer's identity. - bool routing_id_sent; - - // Holds the prefetched identity. - msg_t prefetched_routing_id; - - // Holds the prefetched message. - msg_t prefetched_msg; - - struct outpipe_t - { - zmq::pipe_t *pipe; - bool active; - }; - - // Outbound pipes indexed by the peer IDs. - typedef std::map outpipes_t; - outpipes_t outpipes; - - // The pipe we are currently writing to. - zmq::pipe_t *current_out; - - // If true, more outgoing message parts are expected. - bool more_out; - - // Routing IDs are generated. It's a simple increment and wrap-over - // algorithm. This value is the next ID to use (if not used already). - uint32_t next_integral_routing_id; - - stream_t (const stream_t&); - const stream_t &operator = (const stream_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/stream_engine.cpp b/dep/libzmq/src/stream_engine.cpp deleted file mode 100644 index f0f2887110..0000000000 --- a/dep/libzmq/src/stream_engine.cpp +++ /dev/null @@ -1,1110 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" - -#include - -#ifndef ZMQ_HAVE_WINDOWS -#include -#endif - -#include -#include - -#include "stream_engine.hpp" -#include "io_thread.hpp" -#include "session_base.hpp" -#include "v1_encoder.hpp" -#include "v1_decoder.hpp" -#include "v2_encoder.hpp" -#include "v2_decoder.hpp" -#include "null_mechanism.hpp" -#include "plain_client.hpp" -#include "plain_server.hpp" -#include "gssapi_client.hpp" -#include "gssapi_server.hpp" -#include "curve_client.hpp" -#include "curve_server.hpp" -#include "raw_decoder.hpp" -#include "raw_encoder.hpp" -#include "config.hpp" -#include "err.hpp" -#include "ip.hpp" -#include "tcp.hpp" -#include "likely.hpp" -#include "wire.hpp" - -zmq::stream_engine_t::stream_engine_t (fd_t fd_, const options_t &options_, - const std::string &endpoint_) : - s (fd_), - as_server(false), - handle((handle_t)NULL), - inpos (NULL), - insize (0), - decoder (NULL), - outpos (NULL), - outsize (0), - encoder (NULL), - metadata (NULL), - handshaking (true), - greeting_size (v2_greeting_size), - greeting_bytes_read (0), - session (NULL), - options (options_), - endpoint (endpoint_), - plugged (false), - next_msg (&stream_engine_t::routing_id_msg), - process_msg (&stream_engine_t::process_routing_id_msg), - io_error (false), - subscription_required (false), - mechanism (NULL), - input_stopped (false), - output_stopped (false), - has_handshake_timer (false), - has_ttl_timer (false), - has_timeout_timer (false), - has_heartbeat_timer (false), - heartbeat_timeout (0), - socket (NULL) -{ - int rc = tx_msg.init (); - errno_assert (rc == 0); - - // Put the socket into non-blocking mode. - unblock_socket (s); - - int family = get_peer_ip_address (s, peer_address); - if (family == 0) - peer_address.clear(); -#if defined ZMQ_HAVE_SO_PEERCRED - else - if (family == PF_UNIX) { - struct ucred cred; - socklen_t size = sizeof (cred); - if (!getsockopt (s, SOL_SOCKET, SO_PEERCRED, &cred, &size)) { - std::ostringstream buf; - buf << ":" << cred.uid << ":" << cred.gid << ":" << cred.pid; - peer_address += buf.str (); - } - } -#elif defined ZMQ_HAVE_LOCAL_PEERCRED - else - if (family == PF_UNIX) { - struct xucred cred; - socklen_t size = sizeof (cred); - if (!getsockopt (s, 0, LOCAL_PEERCRED, &cred, &size) - && cred.cr_version == XUCRED_VERSION) { - std::ostringstream buf; - buf << ":" << cred.cr_uid << ":"; - if (cred.cr_ngroups > 0) - buf << cred.cr_groups[0]; - buf << ":"; - peer_address += buf.str (); - } - } -#endif - - if(options.heartbeat_interval > 0) { - heartbeat_timeout = options.heartbeat_timeout; - if(heartbeat_timeout == -1) - heartbeat_timeout = options.heartbeat_interval; - } -} - -zmq::stream_engine_t::~stream_engine_t () -{ - zmq_assert (!plugged); - - if (s != retired_fd) { -#ifdef ZMQ_HAVE_WINDOWS - int rc = closesocket (s); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = close (s); -#if defined(__FreeBSD_kernel__) || defined (__FreeBSD__) - // FreeBSD may return ECONNRESET on close() under load but this is not - // an error. - if (rc == -1 && errno == ECONNRESET) - rc = 0; -#endif - errno_assert (rc == 0); -#endif - s = retired_fd; - } - - int rc = tx_msg.close (); - errno_assert (rc == 0); - - // Drop reference to metadata and destroy it if we are - // the only user. - if (metadata != NULL) { - if (metadata->drop_ref ()) { - LIBZMQ_DELETE(metadata); - } - } - - LIBZMQ_DELETE(encoder); - LIBZMQ_DELETE(decoder); - LIBZMQ_DELETE(mechanism); -} - -void zmq::stream_engine_t::plug (io_thread_t *io_thread_, - session_base_t *session_) -{ - zmq_assert (!plugged); - plugged = true; - - // Connect to session object. - zmq_assert (!session); - zmq_assert (session_); - session = session_; - socket = session-> get_socket (); - - // Connect to I/O threads poller object. - io_object_t::plug (io_thread_); - handle = add_fd (s); - io_error = false; - - if (options.raw_socket) { - // no handshaking for raw sock, instantiate raw encoder and decoders - encoder = new (std::nothrow) raw_encoder_t (out_batch_size); - alloc_assert (encoder); - - decoder = new (std::nothrow) raw_decoder_t (in_batch_size); - alloc_assert (decoder); - - // disable handshaking for raw socket - handshaking = false; - - next_msg = &stream_engine_t::pull_msg_from_session; - process_msg = &stream_engine_t::push_raw_msg_to_session; - - properties_t properties; - if (init_properties(properties)) { - // Compile metadata. - zmq_assert (metadata == NULL); - metadata = new (std::nothrow) metadata_t (properties); - alloc_assert (metadata); - } - - if (options.raw_notify) { - // For raw sockets, send an initial 0-length message to the - // application so that it knows a peer has connected. - msg_t connector; - connector.init(); - push_raw_msg_to_session (&connector); - connector.close(); - session->flush (); - } - } - else { - // start optional timer, to prevent handshake hanging on no input - set_handshake_timer (); - - // Send the 'length' and 'flags' fields of the routing id message. - // The 'length' field is encoded in the long format. - outpos = greeting_send; - outpos [outsize++] = 0xff; - put_uint64 (&outpos [outsize], options.routing_id_size + 1); - outsize += 8; - outpos [outsize++] = 0x7f; - } - - set_pollin (handle); - set_pollout (handle); - // Flush all the data that may have been already received downstream. - in_event (); -} - -void zmq::stream_engine_t::unplug () -{ - zmq_assert (plugged); - plugged = false; - - // Cancel all timers. - if (has_handshake_timer) { - cancel_timer (handshake_timer_id); - has_handshake_timer = false; - } - - if (has_ttl_timer) { - cancel_timer (heartbeat_ttl_timer_id); - has_ttl_timer = false; - } - - if (has_timeout_timer) { - cancel_timer (heartbeat_timeout_timer_id); - has_timeout_timer = false; - } - - if (has_heartbeat_timer) { - cancel_timer (heartbeat_ivl_timer_id); - has_heartbeat_timer = false; - } - // Cancel all fd subscriptions. - if (!io_error) - rm_fd (handle); - - // Disconnect from I/O threads poller object. - io_object_t::unplug (); - - session = NULL; -} - -void zmq::stream_engine_t::terminate () -{ - unplug (); - delete this; -} - -void zmq::stream_engine_t::in_event () -{ - zmq_assert (!io_error); - - // If still handshaking, receive and process the greeting message. - if (unlikely (handshaking)) - if (!handshake ()) - return; - - zmq_assert (decoder); - - // If there has been an I/O error, stop polling. - if (input_stopped) { - rm_fd (handle); - io_error = true; - return; - } - - // If there's no data to process in the buffer... - if (!insize) { - - // Retrieve the buffer and read as much data as possible. - // Note that buffer can be arbitrarily large. However, we assume - // the underlying TCP layer has fixed buffer size and thus the - // number of bytes read will be always limited. - size_t bufsize = 0; - decoder->get_buffer (&inpos, &bufsize); - - const int rc = tcp_read (s, inpos, bufsize); - - if (rc == 0) { - // connection closed by peer - errno = EPIPE; - error (connection_error); - return; - } - if (rc == -1) { - if (errno != EAGAIN) - error (connection_error); - return; - } - - // Adjust input size - insize = static_cast (rc); - // Adjust buffer size to received bytes - decoder->resize_buffer(insize); - } - - int rc = 0; - size_t processed = 0; - - while (insize > 0) { - rc = decoder->decode (inpos, insize, processed); - zmq_assert (processed <= insize); - inpos += processed; - insize -= processed; - if (rc == 0 || rc == -1) - break; - rc = (this->*process_msg) (decoder->msg ()); - if (rc == -1) - break; - } - - // Tear down the connection if we have failed to decode input data - // or the session has rejected the message. - if (rc == -1) { - if (errno != EAGAIN) { - error(protocol_error); - return; - } - input_stopped = true; - reset_pollin (handle); - } - - session->flush (); -} - -void zmq::stream_engine_t::out_event () -{ - zmq_assert (!io_error); - - // If write buffer is empty, try to read new data from the encoder. - if (!outsize) { - - // Even when we stop polling as soon as there is no - // data to send, the poller may invoke out_event one - // more time due to 'speculative write' optimisation. - if (unlikely (encoder == NULL)) { - zmq_assert (handshaking); - return; - } - - outpos = NULL; - outsize = encoder->encode (&outpos, 0); - - while (outsize < (size_t) out_batch_size) { - if ((this->*next_msg) (&tx_msg) == -1) - break; - encoder->load_msg (&tx_msg); - unsigned char *bufptr = outpos + outsize; - size_t n = encoder->encode (&bufptr, out_batch_size - outsize); - zmq_assert (n > 0); - if (outpos == NULL) - outpos = bufptr; - outsize += n; - } - - // If there is no data to send, stop polling for output. - if (outsize == 0) { - output_stopped = true; - reset_pollout (handle); - return; - } - } - - // If there are any data to write in write buffer, write as much as - // possible to the socket. Note that amount of data to write can be - // arbitrarily large. However, we assume that underlying TCP layer has - // limited transmission buffer and thus the actual number of bytes - // written should be reasonably modest. - const int nbytes = tcp_write (s, outpos, outsize); - - // IO error has occurred. We stop waiting for output events. - // The engine is not terminated until we detect input error; - // this is necessary to prevent losing incoming messages. - if (nbytes == -1) { - reset_pollout (handle); - return; - } - - outpos += nbytes; - outsize -= nbytes; - - // If we are still handshaking and there are no data - // to send, stop polling for output. - if (unlikely (handshaking)) - if (outsize == 0) - reset_pollout (handle); -} - -void zmq::stream_engine_t::restart_output () -{ - if (unlikely (io_error)) - return; - - if (likely (output_stopped)) { - set_pollout (handle); - output_stopped = false; - } - - // Speculative write: The assumption is that at the moment new message - // was sent by the user the socket is probably available for writing. - // Thus we try to write the data to socket avoiding polling for POLLOUT. - // Consequently, the latency should be better in request/reply scenarios. - out_event (); -} - -void zmq::stream_engine_t::restart_input () -{ - zmq_assert (input_stopped); - zmq_assert (session != NULL); - zmq_assert (decoder != NULL); - - int rc = (this->*process_msg) (decoder->msg ()); - if (rc == -1) { - if (errno == EAGAIN) - session->flush (); - else - error (protocol_error); - return; - } - - while (insize > 0) { - size_t processed = 0; - rc = decoder->decode (inpos, insize, processed); - zmq_assert (processed <= insize); - inpos += processed; - insize -= processed; - if (rc == 0 || rc == -1) - break; - rc = (this->*process_msg) (decoder->msg ()); - if (rc == -1) - break; - } - - if (rc == -1 && errno == EAGAIN) - session->flush (); - else - if (io_error) - error (connection_error); - else - if (rc == -1) - error (protocol_error); - else { - input_stopped = false; - set_pollin (handle); - session->flush (); - - // Speculative read. - in_event (); - } -} - -bool zmq::stream_engine_t::handshake () -{ - zmq_assert (handshaking); - zmq_assert (greeting_bytes_read < greeting_size); - // Receive the greeting. - while (greeting_bytes_read < greeting_size) { - const int n = tcp_read (s, greeting_recv + greeting_bytes_read, - greeting_size - greeting_bytes_read); - if (n == 0) { - errno = EPIPE; - error (connection_error); - return false; - } - if (n == -1) { - if (errno != EAGAIN) - error (connection_error); - return false; - } - - greeting_bytes_read += n; - - // We have received at least one byte from the peer. - // If the first byte is not 0xff, we know that the - // peer is using unversioned protocol. - if (greeting_recv [0] != 0xff) - break; - - if (greeting_bytes_read < signature_size) - continue; - - // Inspect the right-most bit of the 10th byte (which coincides - // with the 'flags' field if a regular message was sent). - // Zero indicates this is a header of a routing id message - // (i.e. the peer is using the unversioned protocol). - if (!(greeting_recv [9] & 0x01)) - break; - - // The peer is using versioned protocol. - // Send the major version number. - if (outpos + outsize == greeting_send + signature_size) { - if (outsize == 0) - set_pollout (handle); - outpos [outsize++] = 3; // Major version number - } - - if (greeting_bytes_read > signature_size) { - if (outpos + outsize == greeting_send + signature_size + 1) { - if (outsize == 0) - set_pollout (handle); - - // Use ZMTP/2.0 to talk to older peers. - if (greeting_recv [10] == ZMTP_1_0 - || greeting_recv [10] == ZMTP_2_0) - outpos [outsize++] = options.type; - else { - outpos [outsize++] = 0; // Minor version number - memset (outpos + outsize, 0, 20); - - zmq_assert (options.mechanism == ZMQ_NULL - || options.mechanism == ZMQ_PLAIN - || options.mechanism == ZMQ_CURVE - || options.mechanism == ZMQ_GSSAPI); - - if (options.mechanism == ZMQ_NULL) - memcpy (outpos + outsize, "NULL", 4); - else - if (options.mechanism == ZMQ_PLAIN) - memcpy (outpos + outsize, "PLAIN", 5); - else - if (options.mechanism == ZMQ_GSSAPI) - memcpy (outpos + outsize, "GSSAPI", 6); - else - if (options.mechanism == ZMQ_CURVE) - memcpy (outpos + outsize, "CURVE", 5); - outsize += 20; - memset (outpos + outsize, 0, 32); - outsize += 32; - greeting_size = v3_greeting_size; - } - } - } - } - - // Position of the revision field in the greeting. - const size_t revision_pos = 10; - - // Is the peer using ZMTP/1.0 with no revision number? - // If so, we send and receive rest of routing id message - if (greeting_recv [0] != 0xff || !(greeting_recv [9] & 0x01)) { - if (session->zap_enabled ()) { - // reject ZMTP 1.0 connections if ZAP is enabled - error (protocol_error); - return false; - } - - encoder = new (std::nothrow) v1_encoder_t (out_batch_size); - alloc_assert (encoder); - - decoder = new (std::nothrow) v1_decoder_t (in_batch_size, options.maxmsgsize); - alloc_assert (decoder); - - // We have already sent the message header. - // Since there is no way to tell the encoder to - // skip the message header, we simply throw that - // header data away. - const size_t header_size = options.routing_id_size + 1 >= 255 ? 10 : 2; - unsigned char tmp [10], *bufferp = tmp; - - // Prepare the routing id message and load it into encoder. - // Then consume bytes we have already sent to the peer. - const int rc = tx_msg.init_size (options.routing_id_size); - zmq_assert (rc == 0); - memcpy (tx_msg.data (), options.routing_id, options.routing_id_size); - encoder->load_msg (&tx_msg); - size_t buffer_size = encoder->encode (&bufferp, header_size); - zmq_assert (buffer_size == header_size); - - // Make sure the decoder sees the data we have already received. - inpos = greeting_recv; - insize = greeting_bytes_read; - - // To allow for interoperability with peers that do not forward - // their subscriptions, we inject a phantom subscription message - // message into the incoming message stream. - if (options.type == ZMQ_PUB || options.type == ZMQ_XPUB) - subscription_required = true; - - // We are sending our routing id now and the next message - // will come from the socket. - next_msg = &stream_engine_t::pull_msg_from_session; - - // We are expecting routing id message. - process_msg = &stream_engine_t::process_routing_id_msg; - } - else - if (greeting_recv [revision_pos] == ZMTP_1_0) { - if (session->zap_enabled ()) { - // reject ZMTP 1.0 connections if ZAP is enabled - error (protocol_error); - return false; - } - - encoder = new (std::nothrow) v1_encoder_t (out_batch_size); - alloc_assert (encoder); - - decoder = new (std::nothrow) v1_decoder_t ( - in_batch_size, options.maxmsgsize); - alloc_assert (decoder); - } - else - if (greeting_recv [revision_pos] == ZMTP_2_0) { - if (session->zap_enabled ()) { - // reject ZMTP 2.0 connections if ZAP is enabled - error (protocol_error); - return false; - } - - encoder = new (std::nothrow) v2_encoder_t (out_batch_size); - alloc_assert (encoder); - - decoder = new (std::nothrow) v2_decoder_t ( - in_batch_size, options.maxmsgsize); - alloc_assert (decoder); - } - else { - encoder = new (std::nothrow) v2_encoder_t (out_batch_size); - alloc_assert (encoder); - - decoder = new (std::nothrow) v2_decoder_t ( - in_batch_size, options.maxmsgsize); - alloc_assert (decoder); - - if (options.mechanism == ZMQ_NULL - && memcmp (greeting_recv + 12, "NULL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0) { - mechanism = new (std::nothrow) - null_mechanism_t (session, peer_address, options); - alloc_assert (mechanism); - } - else - if (options.mechanism == ZMQ_PLAIN - && memcmp (greeting_recv + 12, "PLAIN\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0) { - if (options.as_server) - mechanism = new (std::nothrow) - plain_server_t (session, peer_address, options); - else - mechanism = new (std::nothrow) - plain_client_t (session, options); - alloc_assert (mechanism); - } -#ifdef ZMQ_HAVE_CURVE - else - if (options.mechanism == ZMQ_CURVE - && memcmp (greeting_recv + 12, "CURVE\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0) { - if (options.as_server) - mechanism = new (std::nothrow) - curve_server_t (session, peer_address, options); - else - mechanism = - new (std::nothrow) curve_client_t (session, options); - alloc_assert (mechanism); - } -#endif -#ifdef HAVE_LIBGSSAPI_KRB5 - else - if (options.mechanism == ZMQ_GSSAPI - && memcmp (greeting_recv + 12, "GSSAPI\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0) { - if (options.as_server) - mechanism = new (std::nothrow) - gssapi_server_t (session, peer_address, options); - else - mechanism = - new (std::nothrow) gssapi_client_t (session, options); - alloc_assert (mechanism); - } -#endif - else { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH); - error (protocol_error); - return false; - } - next_msg = &stream_engine_t::next_handshake_command; - process_msg = &stream_engine_t::process_handshake_command; - } - - // Start polling for output if necessary. - if (outsize == 0) - set_pollout (handle); - - // Handshaking was successful. - // Switch into the normal message flow. - handshaking = false; - - if (has_handshake_timer) { - cancel_timer (handshake_timer_id); - has_handshake_timer = false; - } - - return true; -} - -int zmq::stream_engine_t::routing_id_msg (msg_t *msg_) -{ - int rc = msg_->init_size (options.routing_id_size); - errno_assert (rc == 0); - if (options.routing_id_size > 0) - memcpy (msg_->data (), options.routing_id, options.routing_id_size); - next_msg = &stream_engine_t::pull_msg_from_session; - return 0; -} - -int zmq::stream_engine_t::process_routing_id_msg (msg_t *msg_) -{ - if (options.recv_routing_id) { - msg_->set_flags (msg_t::routing_id); - int rc = session->push_msg (msg_); - errno_assert (rc == 0); - } - else { - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - } - - if (subscription_required) { - msg_t subscription; - - // Inject the subscription message, so that also - // ZMQ 2.x peers receive published messages. - int rc = subscription.init_size (1); - errno_assert (rc == 0); - *(unsigned char*) subscription.data () = 1; - rc = session->push_msg (&subscription); - errno_assert (rc == 0); - } - - process_msg = &stream_engine_t::push_msg_to_session; - - return 0; -} - -int zmq::stream_engine_t::next_handshake_command (msg_t *msg_) -{ - zmq_assert (mechanism != NULL); - - if (mechanism->status () == mechanism_t::ready) { - mechanism_ready (); - return pull_and_encode (msg_); - } - else - if (mechanism->status () == mechanism_t::error) { - errno = EPROTO; - return -1; - } - else { - const int rc = mechanism->next_handshake_command (msg_); - - if (rc == 0) - msg_->set_flags (msg_t::command); - - return rc; - } -} - -int zmq::stream_engine_t::process_handshake_command (msg_t *msg_) -{ - zmq_assert (mechanism != NULL); - const int rc = mechanism->process_handshake_command (msg_); - if (rc == 0) { - if (mechanism->status () == mechanism_t::ready) - mechanism_ready (); - else - if (mechanism->status () == mechanism_t::error) { - errno = EPROTO; - return -1; - } - if (output_stopped) - restart_output (); - } - - return rc; -} - -void zmq::stream_engine_t::zap_msg_available () -{ - zmq_assert (mechanism != NULL); - - const int rc = mechanism->zap_msg_available (); - if (rc == -1) { - error (protocol_error); - return; - } - if (input_stopped) - restart_input (); - if (output_stopped) - restart_output (); -} - -const char *zmq::stream_engine_t::get_endpoint () const -{ - return endpoint.c_str (); -} - -void zmq::stream_engine_t::mechanism_ready () -{ - if (options.heartbeat_interval > 0) { - add_timer(options.heartbeat_interval, heartbeat_ivl_timer_id); - has_heartbeat_timer = true; - } - - if (options.recv_routing_id) { - msg_t routing_id; - mechanism->peer_routing_id (&routing_id); - const int rc = session->push_msg (&routing_id); - if (rc == -1 && errno == EAGAIN) { - // If the write is failing at this stage with - // an EAGAIN the pipe must be being shut down, - // so we can just bail out of the routing id set. - return; - } - errno_assert (rc == 0); - session->flush (); - } - - next_msg = &stream_engine_t::pull_and_encode; - process_msg = &stream_engine_t::write_credential; - - // Compile metadata. - properties_t properties; - init_properties(properties); - - // Add ZAP properties. - const properties_t& zap_properties = mechanism->get_zap_properties (); - properties.insert(zap_properties.begin (), zap_properties.end ()); - - // Add ZMTP properties. - const properties_t& zmtp_properties = mechanism->get_zmtp_properties (); - properties.insert(zmtp_properties.begin (), zmtp_properties.end ()); - - zmq_assert (metadata == NULL); - if (!properties.empty ()) - { - metadata = new (std::nothrow) metadata_t (properties); - alloc_assert (metadata); - } - -#ifdef ZMQ_BUILD_DRAFT_API - socket->event_handshake_succeeded (endpoint, 0); -#endif -} - -int zmq::stream_engine_t::pull_msg_from_session (msg_t *msg_) -{ - return session->pull_msg (msg_); -} - -int zmq::stream_engine_t::push_msg_to_session (msg_t *msg_) -{ - return session->push_msg (msg_); -} - -int zmq::stream_engine_t::push_raw_msg_to_session (msg_t *msg_) { - if (metadata && metadata != msg_->metadata()) - msg_->set_metadata(metadata); - return push_msg_to_session(msg_); -} - -int zmq::stream_engine_t::write_credential (msg_t *msg_) -{ - zmq_assert (mechanism != NULL); - zmq_assert (session != NULL); - - const blob_t &credential = mechanism->get_user_id (); - if (credential.size () > 0) { - msg_t msg; - int rc = msg.init_size (credential.size ()); - zmq_assert (rc == 0); - memcpy (msg.data (), credential.data (), credential.size ()); - msg.set_flags (msg_t::credential); - rc = session->push_msg (&msg); - if (rc == -1) { - rc = msg.close (); - errno_assert (rc == 0); - return -1; - } - } - process_msg = &stream_engine_t::decode_and_push; - return decode_and_push (msg_); -} - -int zmq::stream_engine_t::pull_and_encode (msg_t *msg_) -{ - zmq_assert (mechanism != NULL); - - if (session->pull_msg (msg_) == -1) - return -1; - if (mechanism->encode (msg_) == -1) - return -1; - return 0; -} - -int zmq::stream_engine_t::decode_and_push (msg_t *msg_) -{ - zmq_assert (mechanism != NULL); - - if (mechanism->decode (msg_) == -1) - return -1; - - if(has_timeout_timer) { - has_timeout_timer = false; - cancel_timer(heartbeat_timeout_timer_id); - } - - if(has_ttl_timer) { - has_ttl_timer = false; - cancel_timer(heartbeat_ttl_timer_id); - } - - if(msg_->flags() & msg_t::command) { - uint8_t cmd_id = *((uint8_t*)msg_->data()); - if(cmd_id == 4) - process_heartbeat_message(msg_); - } - - if (metadata) - msg_->set_metadata (metadata); - if (session->push_msg (msg_) == -1) { - if (errno == EAGAIN) - process_msg = &stream_engine_t::push_one_then_decode_and_push; - return -1; - } - return 0; -} - -int zmq::stream_engine_t::push_one_then_decode_and_push (msg_t *msg_) -{ - const int rc = session->push_msg (msg_); - if (rc == 0) - process_msg = &stream_engine_t::decode_and_push; - return rc; -} - -void zmq::stream_engine_t::error (error_reason_t reason) -{ - if (options.raw_socket && options.raw_notify) { - // For raw sockets, send a final 0-length message to the application - // so that it knows the peer has been disconnected. - msg_t terminator; - terminator.init(); - (this->*process_msg) (&terminator); - terminator.close(); - } - zmq_assert (session); -#ifdef ZMQ_BUILD_DRAFT_API - // protocol errors have been signaled already at the point where they occurred - if (reason != protocol_error - && (mechanism == NULL - || mechanism->status () == mechanism_t::handshaking)) { - int err = errno; - socket->event_handshake_failed_no_detail (endpoint, err); - } -#endif - socket->event_disconnected (endpoint, (int) s); - session->flush (); - session->engine_error (reason); - unplug (); - delete this; -} - -void zmq::stream_engine_t::set_handshake_timer () -{ - zmq_assert (!has_handshake_timer); - - if (!options.raw_socket && options.handshake_ivl > 0) { - add_timer (options.handshake_ivl, handshake_timer_id); - has_handshake_timer = true; - } -} - -bool zmq::stream_engine_t::init_properties (properties_t & properties) { - if (peer_address.empty()) return false; - properties.ZMQ_MAP_INSERT_OR_EMPLACE ( - ZMQ_MSG_PROPERTY_PEER_ADDRESS, peer_address); - - // Private property to support deprecated SRCFD - std::ostringstream stream; - stream << (int)s; - std::string fd_string = stream.str(); - properties.ZMQ_MAP_INSERT_OR_EMPLACE ("__fd", ZMQ_MOVE(fd_string)); - return true; -} - -void zmq::stream_engine_t::timer_event (int id_) -{ - if(id_ == handshake_timer_id) { - has_handshake_timer = false; - // handshake timer expired before handshake completed, so engine fail - error (timeout_error); - } - else if(id_ == heartbeat_ivl_timer_id) { - next_msg = &stream_engine_t::produce_ping_message; - out_event(); - add_timer(options.heartbeat_interval, heartbeat_ivl_timer_id); - } - else if(id_ == heartbeat_ttl_timer_id) { - has_ttl_timer = false; - error(timeout_error); - } - else if(id_ == heartbeat_timeout_timer_id) { - has_timeout_timer = false; - error(timeout_error); - } - else - // There are no other valid timer ids! - assert(false); -} - -int zmq::stream_engine_t::produce_ping_message(msg_t * msg_) -{ - int rc = 0; - zmq_assert (mechanism != NULL); - - // 16-bit TTL + \4PING == 7 - rc = msg_->init_size(7); - errno_assert(rc == 0); - msg_->set_flags(msg_t::command); - // Copy in the command message - memcpy(msg_->data(), "\4PING", 5); - - uint16_t ttl_val = htons(options.heartbeat_ttl); - memcpy(((uint8_t*)msg_->data()) + 5, &ttl_val, sizeof(ttl_val)); - - rc = mechanism->encode (msg_); - next_msg = &stream_engine_t::pull_and_encode; - if(!has_timeout_timer && heartbeat_timeout > 0) { - add_timer(heartbeat_timeout, heartbeat_timeout_timer_id); - has_timeout_timer = true; - } - return rc; -} - -int zmq::stream_engine_t::produce_pong_message(msg_t * msg_) -{ - int rc = 0; - zmq_assert (mechanism != NULL); - - rc = msg_->init_size(5); - errno_assert(rc == 0); - msg_->set_flags(msg_t::command); - - memcpy(msg_->data(), "\4PONG", 5); - - rc = mechanism->encode (msg_); - next_msg = &stream_engine_t::pull_and_encode; - return rc; -} - -int zmq::stream_engine_t::process_heartbeat_message(msg_t * msg_) -{ - if(memcmp(msg_->data(), "\4PING", 5) == 0) { - uint16_t remote_heartbeat_ttl; - // Get the remote heartbeat TTL to setup the timer - memcpy(&remote_heartbeat_ttl, (uint8_t*)msg_->data() + 5, 2); - remote_heartbeat_ttl = ntohs(remote_heartbeat_ttl); - // The remote heartbeat is in 10ths of a second - // so we multiply it by 100 to get the timer interval in ms. - remote_heartbeat_ttl *= 100; - - if(!has_ttl_timer && remote_heartbeat_ttl > 0) { - add_timer(remote_heartbeat_ttl, heartbeat_ttl_timer_id); - has_ttl_timer = true; - } - - next_msg = &stream_engine_t::produce_pong_message; - out_event(); - } - - return 0; -} diff --git a/dep/libzmq/src/stream_engine.hpp b/dep/libzmq/src/stream_engine.hpp deleted file mode 100644 index fac8df6a8d..0000000000 --- a/dep/libzmq/src/stream_engine.hpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_STREAM_ENGINE_HPP_INCLUDED__ -#define __ZMQ_STREAM_ENGINE_HPP_INCLUDED__ - -#include - -#include "fd.hpp" -#include "i_engine.hpp" -#include "io_object.hpp" -#include "i_encoder.hpp" -#include "i_decoder.hpp" -#include "options.hpp" -#include "socket_base.hpp" -#include "metadata.hpp" - -namespace zmq -{ - // Protocol revisions - enum - { - ZMTP_1_0 = 0, - ZMTP_2_0 = 1 - }; - - class io_thread_t; - class msg_t; - class session_base_t; - class mechanism_t; - - // This engine handles any socket with SOCK_STREAM semantics, - // e.g. TCP socket or an UNIX domain socket. - - class stream_engine_t : public io_object_t, public i_engine - { - public: - - enum error_reason_t { - protocol_error, - connection_error, - timeout_error - }; - - stream_engine_t (fd_t fd_, const options_t &options_, - const std::string &endpoint); - ~stream_engine_t (); - - // i_engine interface implementation. - void plug (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_); - void terminate (); - void restart_input (); - void restart_output (); - void zap_msg_available (); - const char *get_endpoint () const; - - // i_poll_events interface implementation. - void in_event (); - void out_event (); - void timer_event (int id_); - - private: - // Unplug the engine from the session. - void unplug (); - - // Function to handle network disconnections. - void error (error_reason_t reason); - - // Receives the greeting message from the peer. - int receive_greeting (); - - // Detects the protocol used by the peer. - bool handshake (); - - int routing_id_msg (msg_t *msg_); - int process_routing_id_msg (msg_t *msg_); - - int next_handshake_command (msg_t *msg); - int process_handshake_command (msg_t *msg); - - int pull_msg_from_session (msg_t *msg_); - int push_msg_to_session (msg_t *msg); - - int push_raw_msg_to_session (msg_t *msg); - - int write_credential (msg_t *msg_); - int pull_and_encode (msg_t *msg_); - int decode_and_push (msg_t *msg_); - int push_one_then_decode_and_push (msg_t *msg_); - - void mechanism_ready (); - - size_t add_property (unsigned char *ptr, - const char *name, const void *value, size_t value_len); - - void set_handshake_timer(); - - typedef metadata_t::dict_t properties_t; - bool init_properties (properties_t & properties); - - int produce_ping_message(msg_t * msg_); - int process_heartbeat_message(msg_t * msg_); - int produce_pong_message(msg_t * msg_); - - // Underlying socket. - fd_t s; - - // True iff this is server's engine. - bool as_server; - - msg_t tx_msg; - - handle_t handle; - - unsigned char *inpos; - size_t insize; - i_decoder *decoder; - - unsigned char *outpos; - size_t outsize; - i_encoder *encoder; - - // Metadata to be attached to received messages. May be NULL. - metadata_t *metadata; - - // When true, we are still trying to determine whether - // the peer is using versioned protocol, and if so, which - // version. When false, normal message flow has started. - bool handshaking; - - static const size_t signature_size = 10; - - // Size of ZMTP/1.0 and ZMTP/2.0 greeting message - static const size_t v2_greeting_size = 12; - - // Size of ZMTP/3.0 greeting message - static const size_t v3_greeting_size = 64; - - // Expected greeting size. - size_t greeting_size; - - // Greeting received from, and sent to peer - unsigned char greeting_recv [v3_greeting_size]; - unsigned char greeting_send [v3_greeting_size]; - - // Size of greeting received so far - unsigned int greeting_bytes_read; - - // The session this engine is attached to. - zmq::session_base_t *session; - - options_t options; - - // String representation of endpoint - std::string endpoint; - - bool plugged; - - int (stream_engine_t::*next_msg) (msg_t *msg_); - - int (stream_engine_t::*process_msg) (msg_t *msg_); - - bool io_error; - - // Indicates whether the engine is to inject a phantom - // subscription message into the incoming stream. - // Needed to support old peers. - bool subscription_required; - - mechanism_t *mechanism; - - // True iff the engine couldn't consume the last decoded message. - bool input_stopped; - - // True iff the engine doesn't have any message to encode. - bool output_stopped; - - // ID of the handshake timer - enum {handshake_timer_id = 0x40}; - - // True is linger timer is running. - bool has_handshake_timer; - - // Heartbeat stuff - enum { - heartbeat_ivl_timer_id = 0x80, - heartbeat_timeout_timer_id = 0x81, - heartbeat_ttl_timer_id = 0x82 - }; - bool has_ttl_timer; - bool has_timeout_timer; - bool has_heartbeat_timer; - int heartbeat_timeout; - - // Socket - zmq::socket_base_t *socket; - - std::string peer_address; - - stream_engine_t (const stream_engine_t&); - const stream_engine_t &operator = (const stream_engine_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/sub.cpp b/dep/libzmq/src/sub.cpp deleted file mode 100644 index e8718e58c5..0000000000 --- a/dep/libzmq/src/sub.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "sub.hpp" -#include "msg.hpp" - -zmq::sub_t::sub_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - xsub_t (parent_, tid_, sid_) -{ - options.type = ZMQ_SUB; - - // Switch filtering messages on (as opposed to XSUB which where the - // filtering is off). - options.filter = true; -} - -zmq::sub_t::~sub_t () -{ -} - -int zmq::sub_t::xsetsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - if (option_ != ZMQ_SUBSCRIBE && option_ != ZMQ_UNSUBSCRIBE) { - errno = EINVAL; - return -1; - } - - // Create the subscription message. - msg_t msg; - int rc = msg.init_size (optvallen_ + 1); - errno_assert (rc == 0); - unsigned char *data = (unsigned char*) msg.data (); - if (option_ == ZMQ_SUBSCRIBE) - *data = 1; - else - if (option_ == ZMQ_UNSUBSCRIBE) - *data = 0; - // We explicitly allow a NULL subscription with size zero - if (optvallen_) { - assert (optval_); - memcpy (data + 1, optval_, optvallen_); - } - // Pass it further on in the stack. - rc = xsub_t::xsend (&msg); - return close_and_return (&msg, rc); -} - -int zmq::sub_t::xsend (msg_t *) -{ - // Override the XSUB's send. - errno = ENOTSUP; - return -1; -} - -bool zmq::sub_t::xhas_out () -{ - // Override the XSUB's send. - return false; -} diff --git a/dep/libzmq/src/sub.hpp b/dep/libzmq/src/sub.hpp deleted file mode 100644 index d913493312..0000000000 --- a/dep/libzmq/src/sub.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_SUB_HPP_INCLUDED__ -#define __ZMQ_SUB_HPP_INCLUDED__ - -#include "xsub.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class io_thread_t; - class socket_base_t; - - class sub_t : public xsub_t - { - public: - - sub_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~sub_t (); - - protected: - - int xsetsockopt (int option_, const void *optval_, size_t optvallen_); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - - private: - - sub_t (const sub_t&); - const sub_t &operator = (const sub_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/tcp.cpp b/dep/libzmq/src/tcp.cpp deleted file mode 100644 index 7682cfa0c4..0000000000 --- a/dep/libzmq/src/tcp.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "ip.hpp" -#include "tcp.hpp" -#include "err.hpp" - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#include -#endif - -#if defined ZMQ_HAVE_OPENVMS -#include -#endif - -int zmq::tune_tcp_socket (fd_t s_) -{ - // Disable Nagle's algorithm. We are doing data batching on 0MQ level, - // so using Nagle wouldn't improve throughput in anyway, but it would - // hurt latency. - int nodelay = 1; - int rc = setsockopt (s_, IPPROTO_TCP, TCP_NODELAY, (char*) &nodelay, - sizeof (int)); - tcp_assert_tuning_error (s_, rc); - if (rc != 0) - return rc; - -#ifdef ZMQ_HAVE_OPENVMS - // Disable delayed acknowledgements as they hurt latency significantly. - int nodelack = 1; - rc = setsockopt (s_, IPPROTO_TCP, TCP_NODELACK, (char*) &nodelack, - sizeof (int)); - tcp_assert_tuning_error (s_, rc); -#endif - return rc; -} - -int zmq::set_tcp_send_buffer (fd_t sockfd_, int bufsize_) -{ - const int rc = setsockopt (sockfd_, SOL_SOCKET, SO_SNDBUF, - (char*) &bufsize_, sizeof bufsize_); - tcp_assert_tuning_error (sockfd_, rc); - return rc; -} - -int zmq::set_tcp_receive_buffer (fd_t sockfd_, int bufsize_) -{ - const int rc = setsockopt (sockfd_, SOL_SOCKET, SO_RCVBUF, - (char *) &bufsize_, sizeof bufsize_); - tcp_assert_tuning_error (sockfd_, rc); - return rc; -} - -int zmq::tune_tcp_keepalives (fd_t s_, int keepalive_, int keepalive_cnt_, - int keepalive_idle_, int keepalive_intvl_) -{ - // These options are used only under certain #ifdefs below. - LIBZMQ_UNUSED (keepalive_); - LIBZMQ_UNUSED (keepalive_cnt_); - LIBZMQ_UNUSED (keepalive_idle_); - LIBZMQ_UNUSED (keepalive_intvl_); - - // If none of the #ifdefs apply, then s_ is unused. - LIBZMQ_UNUSED (s_); - - // Tuning TCP keep-alives if platform allows it - // All values = -1 means skip and leave it for OS -#ifdef ZMQ_HAVE_WINDOWS - if (keepalive_ != -1) { - tcp_keepalive keepalive_opts; - keepalive_opts.onoff = keepalive_; - keepalive_opts.keepalivetime = keepalive_idle_ != -1 ? - keepalive_idle_ * 1000 : 7200000; - keepalive_opts.keepaliveinterval = keepalive_intvl_ != -1 ? - keepalive_intvl_ * 1000 : 1000; - DWORD num_bytes_returned; - int rc = WSAIoctl (s_, SIO_KEEPALIVE_VALS, &keepalive_opts, - sizeof (keepalive_opts), NULL, 0, &num_bytes_returned, NULL, NULL); - tcp_assert_tuning_error (s_, rc); - if (rc == SOCKET_ERROR) - return rc; - } -#else -#ifdef ZMQ_HAVE_SO_KEEPALIVE - if (keepalive_ != -1) { - int rc = setsockopt (s_, SOL_SOCKET, SO_KEEPALIVE, - (char*) &keepalive_, sizeof (int)); - tcp_assert_tuning_error (s_, rc); - if (rc != 0) - return rc; - -#ifdef ZMQ_HAVE_TCP_KEEPCNT - if (keepalive_cnt_ != -1) { - int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPCNT, - &keepalive_cnt_, sizeof (int)); - tcp_assert_tuning_error (s_, rc); - if (rc != 0) - return rc; - } -#endif // ZMQ_HAVE_TCP_KEEPCNT - -#ifdef ZMQ_HAVE_TCP_KEEPIDLE - if (keepalive_idle_ != -1) { - int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPIDLE, - &keepalive_idle_, sizeof (int)); - tcp_assert_tuning_error (s_, rc); - if (rc != 0) - return rc; - } -#else // ZMQ_HAVE_TCP_KEEPIDLE -#ifdef ZMQ_HAVE_TCP_KEEPALIVE - if (keepalive_idle_ != -1) { - int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPALIVE, - &keepalive_idle_, sizeof (int)); - tcp_assert_tuning_error (s_, rc); - if (rc != 0) - return rc; - } -#endif // ZMQ_HAVE_TCP_KEEPALIVE -#endif // ZMQ_HAVE_TCP_KEEPIDLE - -#ifdef ZMQ_HAVE_TCP_KEEPINTVL - if (keepalive_intvl_ != -1) { - int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPINTVL, - &keepalive_intvl_, sizeof (int)); - tcp_assert_tuning_error (s_, rc); - if (rc != 0) - return rc; - } -#endif // ZMQ_HAVE_TCP_KEEPINTVL - } -#endif // ZMQ_HAVE_SO_KEEPALIVE -#endif // ZMQ_HAVE_WINDOWS - - return 0; -} - -int zmq::tune_tcp_maxrt (fd_t sockfd_, int timeout_) -{ - if (timeout_ <= 0) - return 0; - - LIBZMQ_UNUSED (sockfd_); - -#if defined (ZMQ_HAVE_WINDOWS) && defined (TCP_MAXRT) - // msdn says it's supported in >= Vista, >= Windows Server 2003 - timeout_ /= 1000; // in seconds - int rc = setsockopt (sockfd_, IPPROTO_TCP, TCP_MAXRT, (char*) &timeout_, - sizeof (timeout_)); - tcp_assert_tuning_error (sockfd_, rc); - return rc; -// FIXME: should be ZMQ_HAVE_TCP_USER_TIMEOUT -#elif defined (TCP_USER_TIMEOUT) - int rc = setsockopt (sockfd_, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout_, - sizeof (timeout_)); - tcp_assert_tuning_error (sockfd_, rc); - return rc; -#endif - return 0; -} - - int zmq::tcp_write (fd_t s_, const void *data_, size_t size_) -{ -#ifdef ZMQ_HAVE_WINDOWS - - int nbytes = send (s_, (char*) data_, (int) size_, 0); - - // If not a single byte can be written to the socket in non-blocking mode - // we'll get an error (this may happen during the speculative write). - const int last_error = WSAGetLastError (); - if (nbytes == SOCKET_ERROR && last_error == WSAEWOULDBLOCK) - return 0; - - // Signalise peer failure. - if (nbytes == SOCKET_ERROR && ( - last_error == WSAENETDOWN || - last_error == WSAENETRESET || - last_error == WSAEHOSTUNREACH || - last_error == WSAECONNABORTED || - last_error == WSAETIMEDOUT || - last_error == WSAECONNRESET - )) - return -1; - - // Circumvent a Windows bug: - // See https://support.microsoft.com/en-us/kb/201213 - // See https://zeromq.jira.com/browse/LIBZMQ-195 - if (nbytes == SOCKET_ERROR && last_error == WSAENOBUFS) - return 0; - - wsa_assert (nbytes != SOCKET_ERROR); - return nbytes; - -#else - ssize_t nbytes = send (s_, data_, size_, 0); - - // Several errors are OK. When speculative write is being done we may not - // be able to write a single byte from the socket. Also, SIGSTOP issued - // by a debugging tool can result in EINTR error. - if (nbytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR)) - return 0; - - // Signalise peer failure. - if (nbytes == -1) { - errno_assert (errno != EACCES - && errno != EBADF - && errno != EDESTADDRREQ - && errno != EFAULT - && errno != EISCONN - && errno != EMSGSIZE - && errno != ENOMEM - && errno != ENOTSOCK - && errno != EOPNOTSUPP); - return -1; - } - - return static_cast (nbytes); - -#endif -} - -int zmq::tcp_read (fd_t s_, void *data_, size_t size_) -{ -#ifdef ZMQ_HAVE_WINDOWS - - const int rc = recv (s_, (char*) data_, (int) size_, 0); - - // If not a single byte can be read from the socket in non-blocking mode - // we'll get an error (this may happen during the speculative read). - if (rc == SOCKET_ERROR) { - const int last_error = WSAGetLastError (); - if (last_error == WSAEWOULDBLOCK) { - errno = EAGAIN; - } - else { - wsa_assert (last_error == WSAENETDOWN || - last_error == WSAENETRESET || - last_error == WSAECONNABORTED || - last_error == WSAETIMEDOUT || - last_error == WSAECONNRESET || - last_error == WSAECONNREFUSED || - last_error == WSAENOTCONN); - errno = wsa_error_to_errno (last_error); - } - } - - return rc == SOCKET_ERROR ? -1 : rc; - -#else - - const ssize_t rc = recv (s_, data_, size_, 0); - - // Several errors are OK. When speculative read is being done we may not - // be able to read a single byte from the socket. Also, SIGSTOP issued - // by a debugging tool can result in EINTR error. - if (rc == -1) { - errno_assert (errno != EBADF - && errno != EFAULT - && errno != ENOMEM - && errno != ENOTSOCK); - if (errno == EWOULDBLOCK || errno == EINTR) - errno = EAGAIN; - } - - return static_cast (rc); - -#endif -} - -void zmq::tcp_assert_tuning_error (zmq::fd_t s_, int rc_) -{ - if (rc_ == 0) - return; - - // Check whether an error occurred - int err = 0; -#ifdef ZMQ_HAVE_HPUX - int len = sizeof err; -#else - socklen_t len = sizeof err; -#endif - - int rc = getsockopt (s_, SOL_SOCKET, SO_ERROR, (char*) &err, &len); - - // Assert if the error was caused by 0MQ bug. - // Networking problems are OK. No need to assert. -#ifdef ZMQ_HAVE_WINDOWS - zmq_assert (rc == 0); - if (err != 0) { - wsa_assert (err == WSAECONNREFUSED - || err == WSAECONNRESET - || err == WSAECONNABORTED - || err == WSAEINTR - || err == WSAETIMEDOUT - || err == WSAEHOSTUNREACH - || err == WSAENETUNREACH - || err == WSAENETDOWN - || err == WSAENETRESET - || err == WSAEACCES - || err == WSAEINVAL - || err == WSAEADDRINUSE); - } -#else - // Following code should handle both Berkeley-derived socket - // implementations and Solaris. - if (rc == -1) - err = errno; - if (err != 0) { - errno = err; - errno_assert ( - errno == ECONNREFUSED || - errno == ECONNRESET || - errno == ECONNABORTED || - errno == EINTR || - errno == ETIMEDOUT || - errno == EHOSTUNREACH || - errno == ENETUNREACH || - errno == ENETDOWN || - errno == ENETRESET || - errno == EINVAL); - } -#endif -} diff --git a/dep/libzmq/src/tcp.hpp b/dep/libzmq/src/tcp.hpp deleted file mode 100644 index 4d18a3aee2..0000000000 --- a/dep/libzmq/src/tcp.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_TCP_HPP_INCLUDED__ -#define __ZMQ_TCP_HPP_INCLUDED__ - -#include "fd.hpp" - -namespace zmq -{ - - // Tunes the supplied TCP socket for the best latency. - int tune_tcp_socket (fd_t s_); - - // Sets the socket send buffer size. - int set_tcp_send_buffer (fd_t sockfd_, int bufsize_); - - // Sets the socket receive buffer size. - int set_tcp_receive_buffer (fd_t sockfd_, int bufsize_); - - // Tunes TCP keep-alives - int tune_tcp_keepalives (fd_t s_, int keepalive_, int keepalive_cnt_, - int keepalive_idle_, int keepalive_intvl_); - - // Tunes TCP max retransmit timeout - int tune_tcp_maxrt (fd_t sockfd_, int timeout_); - - // Writes data to the socket. Returns the number of bytes actually - // written (even zero is to be considered to be a success). In case - // of error or orderly shutdown by the other peer -1 is returned. - int tcp_write (fd_t s_, const void *data_, size_t size_); - - // Reads data from the socket (up to 'size' bytes). - // Returns the number of bytes actually read or -1 on error. - // Zero indicates the peer has closed the connection. - int tcp_read (fd_t s_, void *data_, size_t size_); - - // Asserts that an internal error did not occur. Does not assert - // on network errors such as reset or aborted connections. - void tcp_assert_tuning_error (fd_t s_, int rc_); -} - -#endif diff --git a/dep/libzmq/src/tcp_address.cpp b/dep/libzmq/src/tcp_address.cpp deleted file mode 100644 index 12c2339513..0000000000 --- a/dep/libzmq/src/tcp_address.cpp +++ /dev/null @@ -1,897 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "macros.hpp" -#include "tcp_address.hpp" -#include "stdint.hpp" -#include "err.hpp" -#include "ip.hpp" - -#ifndef ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#ifdef ZMQ_HAVE_SOLARIS -#include - -// On Solaris platform, network interface name can be queried by ioctl. -int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv6_, bool is_src_) -{ - // TODO: Unused parameter, IPv6 support not implemented for Solaris. - LIBZMQ_UNUSED (ipv6_); - - // Create a socket. - const int fd = open_socket (AF_INET, SOCK_DGRAM, 0); - errno_assert (fd != -1); - - // Retrieve number of interfaces. - lifnum ifn; - ifn.lifn_family = AF_INET; - ifn.lifn_flags = 0; - int rc = ioctl (fd, SIOCGLIFNUM, (char*) &ifn); - errno_assert (rc != -1); - - // Allocate memory to get interface names. - const size_t ifr_size = sizeof (struct lifreq) * ifn.lifn_count; - char *ifr = (char*) malloc (ifr_size); - alloc_assert (ifr); - - // Retrieve interface names. - lifconf ifc; - ifc.lifc_family = AF_INET; - ifc.lifc_flags = 0; - ifc.lifc_len = ifr_size; - ifc.lifc_buf = ifr; - rc = ioctl (fd, SIOCGLIFCONF, (char*) &ifc); - errno_assert (rc != -1); - - // Find the interface with the specified name and AF_INET family. - bool found = false; - lifreq *ifrp = ifc.lifc_req; - for (int n = 0; n < (int) (ifc.lifc_len / sizeof (lifreq)); - n ++, ifrp ++) { - if (!strcmp (nic_, ifrp->lifr_name)) { - rc = ioctl (fd, SIOCGLIFADDR, (char*) ifrp); - errno_assert (rc != -1); - if (ifrp->lifr_addr.ss_family == AF_INET) { - if (is_src_) - source_address.ipv4 = *(sockaddr_in*) &ifrp->lifr_addr; - else - address.ipv4 = *(sockaddr_in*) &ifrp->lifr_addr; - found = true; - break; - } - } - } - - // Clean-up. - free (ifr); - close (fd); - - if (!found) { - errno = ENODEV; - return -1; - } - return 0; -} - -#elif defined ZMQ_HAVE_AIX || defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_ANDROID -#include - -int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv6_, bool is_src_) -{ -#if defined ZMQ_HAVE_AIX || defined ZMQ_HAVE_HPUX - // IPv6 support not implemented for AIX or HP/UX. - if (ipv6_) - { - errno = ENODEV; - return -1; - } -#endif - - // Create a socket. - const int sd = open_socket (ipv6_ ? AF_INET6 : AF_INET, SOCK_DGRAM, 0); - errno_assert (sd != -1); - - struct ifreq ifr; - - // Copy interface name for ioctl get. - strncpy (ifr.ifr_name, nic_, sizeof (ifr.ifr_name) ); - - // Fetch interface address. - const int rc = ioctl (sd, SIOCGIFADDR, (caddr_t) &ifr, sizeof (ifr) ); - - // Clean up. - close (sd); - - if (rc == -1) { - errno = ENODEV; - return -1; - } - - const int family = ifr.ifr_addr.sa_family; - if (family == (ipv6_ ? AF_INET6 : AF_INET) - && !strcmp (nic_, ifr.ifr_name)) - { - if (is_src_) - memcpy (&source_address, &ifr.ifr_addr, - (family == AF_INET) ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)); - else - memcpy (&address, &ifr.ifr_addr, - (family == AF_INET) ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)); - } - else - { - errno = ENODEV; - return -1; - } - - return 0; -} - -#elif ((defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD ||\ - defined ZMQ_HAVE_OSX || defined ZMQ_HAVE_OPENBSD ||\ - defined ZMQ_HAVE_QNXNTO || defined ZMQ_HAVE_NETBSD ||\ - defined ZMQ_HAVE_DRAGONFLY || defined ZMQ_HAVE_GNU)\ - && defined ZMQ_HAVE_IFADDRS) - -#include - -// On these platforms, network interface name can be queried -// using getifaddrs function. -int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv6_, bool is_src_) -{ - // Get the addresses. - ifaddrs *ifa = NULL; - int rc = 0; - const int max_attempts = 10; - const int backoff_msec = 1; - for (int i = 0; i < max_attempts; i++) { - rc = getifaddrs (&ifa); - if (rc == 0 || (rc < 0 && errno != ECONNREFUSED)) - break; - usleep ((backoff_msec << i) * 1000); - } - - if (rc != 0 && ((errno == EINVAL) || (errno==EOPNOTSUPP))) { - // Windows Subsystem for Linux compatibility - LIBZMQ_UNUSED (nic_); - LIBZMQ_UNUSED (ipv6_); - - errno = ENODEV; - return -1; - } - errno_assert (rc == 0); - zmq_assert (ifa != NULL); - - // Find the corresponding network interface. - bool found = false; - for (ifaddrs *ifp = ifa; ifp != NULL; ifp = ifp->ifa_next) { - if (ifp->ifa_addr == NULL) - continue; - - const int family = ifp->ifa_addr->sa_family; - if (family == (ipv6_ ? AF_INET6 : AF_INET) - && !strcmp (nic_, ifp->ifa_name)) { - if (is_src_) - memcpy (&source_address, ifp->ifa_addr, - (family == AF_INET) ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)); - else - memcpy (&address, ifp->ifa_addr, - (family == AF_INET) ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)); - found = true; - break; - } - } - - // Clean-up; - freeifaddrs (ifa); - - if (!found) { - errno = ENODEV; - return -1; - } - return 0; -} - -#elif (defined ZMQ_HAVE_WINDOWS) - -#include - -int zmq::tcp_address_t::get_interface_name(unsigned long index, char ** dest) const { -#ifdef ZMQ_HAVE_WINDOWS_UWP - char * buffer = (char*)malloc(1024); -#else - char * buffer = (char*)malloc(IF_MAX_STRING_SIZE); -#endif - alloc_assert(buffer); - - char * if_name_result = NULL; - -#if !defined ZMQ_HAVE_WINDOWS_TARGET_XP && !defined ZMQ_HAVE_WINDOWS_UWP - if_name_result = if_indextoname(index, buffer); -#endif - - if (if_name_result == NULL) { - free(buffer); - return -1; - } - - *dest = buffer; - return 0; -} - -int zmq::tcp_address_t::wchar_to_utf8(const WCHAR * src, char ** dest) const { - int rc; - int buffer_len = WideCharToMultiByte(CP_UTF8, 0, - src, -1, - NULL, 0, - NULL, 0); - - char * buffer = (char*) malloc(buffer_len); - alloc_assert(buffer); - - rc = WideCharToMultiByte(CP_UTF8, 0, - src, -1, - buffer, buffer_len, - NULL, 0); - - if (rc == 0) { - free(buffer); - return -1; - } - - *dest = buffer; - return 0; -} - -int zmq::tcp_address_t::resolve_nic_name(const char *nic_, bool ipv6_, bool is_src_) -{ - int rc; - bool found = false; - const int max_attempts = 10; - - int iterations = 0; - IP_ADAPTER_ADDRESSES * addresses = NULL; - IP_ADAPTER_ADDRESSES * current_addresses = NULL; - unsigned long out_buf_len = sizeof(IP_ADAPTER_ADDRESSES); - - do { - addresses = (IP_ADAPTER_ADDRESSES *) malloc(out_buf_len); - alloc_assert(addresses); - - rc = GetAdaptersAddresses(AF_UNSPEC, - GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, - NULL, - addresses, &out_buf_len); - if (rc == ERROR_BUFFER_OVERFLOW) { - free(addresses); - addresses = NULL; - } - else { - break; - } - iterations++; - } while ((rc == ERROR_BUFFER_OVERFLOW) && (iterations < max_attempts)); - - if (rc == 0) { - current_addresses = addresses; - while (current_addresses) { - char * if_name = NULL; - char * if_friendly_name = NULL; - int str_rc1, str_rc2; - - str_rc1 = get_interface_name(current_addresses->IfIndex, &if_name); - str_rc2 = wchar_to_utf8(current_addresses->FriendlyName, &if_friendly_name); - - // Find a network adapter by its "name" or "friendly name" - if ( - ((str_rc1 == 0) && (!strcmp(nic_, if_name))) - || ((str_rc2 == 0) && (!strcmp(nic_, if_friendly_name))) - ) { - - // Iterate over all unicast addresses bound to the current network interface - IP_ADAPTER_UNICAST_ADDRESS * unicast_address = current_addresses->FirstUnicastAddress; - IP_ADAPTER_UNICAST_ADDRESS * current_unicast_address = unicast_address; - - while (current_unicast_address) { - ADDRESS_FAMILY family = current_unicast_address->Address.lpSockaddr->sa_family; - - if (family == (ipv6_ ? AF_INET6 : AF_INET)) { - if (is_src_) - memcpy(&source_address, current_unicast_address->Address.lpSockaddr, - (family == AF_INET) ? sizeof(struct sockaddr_in) - : sizeof(struct sockaddr_in6)); - else - memcpy(&address, current_unicast_address->Address.lpSockaddr, - (family == AF_INET) ? sizeof(struct sockaddr_in) - : sizeof(struct sockaddr_in6)); - found = true; - break; - } - - current_unicast_address = current_unicast_address->Next; - } - - if (found) break; - } - - if (str_rc1 == 0) free(if_name); - if (str_rc2 == 0) free(if_friendly_name); - - current_addresses = current_addresses->Next; - } - - free(addresses); - } - - if (!found) { - errno = ENODEV; - return -1; - } - return 0; -} - -#else - -// On other platforms we assume there are no sane interface names. -int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv6_, bool is_src_) -{ - LIBZMQ_UNUSED (nic_); - LIBZMQ_UNUSED (ipv6_); - - errno = ENODEV; - return -1; -} - -#endif - -int zmq::tcp_address_t::resolve_interface (const char *interface_, bool ipv6_, bool is_src_) -{ - // Initialize temporary output pointers with storage address. - sockaddr_storage ss; - sockaddr *out_addr = (sockaddr*) &ss; - size_t out_addrlen; - - // Initialise IP-format family/port and populate temporary output pointers - // with the address. - if (ipv6_) { - sockaddr_in6 ip6_addr; - memset (&ip6_addr, 0, sizeof (ip6_addr) ); - ip6_addr.sin6_family = AF_INET6; - memcpy (&ip6_addr.sin6_addr, &in6addr_any, sizeof (in6addr_any) ); - out_addrlen = sizeof (ip6_addr); - memcpy (out_addr, &ip6_addr, out_addrlen); - } - else { - sockaddr_in ip4_addr; - memset (&ip4_addr, 0, sizeof (ip4_addr) ); - ip4_addr.sin_family = AF_INET; - ip4_addr.sin_addr.s_addr = htonl (INADDR_ANY); - out_addrlen = sizeof (ip4_addr); - memcpy (out_addr, &ip4_addr, out_addrlen); - } - // "*" resolves to INADDR_ANY or in6addr_any. - if (strcmp (interface_, "*") == 0) { - zmq_assert (out_addrlen <= sizeof (address) ); - if (is_src_) - memcpy (&source_address, out_addr, out_addrlen); - else - memcpy (&address, out_addr, out_addrlen); - return 0; - } - - // Try to resolve the string as a NIC name. - int rc = resolve_nic_name (interface_, ipv6_, is_src_); - if (rc == 0 || errno != ENODEV) - return rc; - - // There's no such interface name. Assume literal address. -#if defined ZMQ_HAVE_OPENVMS && defined __ia64 - __addrinfo64 *res = NULL; - __addrinfo64 req; -#else - addrinfo *res = NULL; - addrinfo req; -#endif - memset (&req, 0, sizeof (req) ); - - // Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for - // IPv4-in-IPv6 addresses. - req.ai_family = ipv6_? AF_INET6: AF_INET; - - // Arbitrary, not used in the output, but avoids duplicate results. - req.ai_socktype = SOCK_STREAM; - - // Restrict hostname/service to literals to avoid any DNS lookups or - // service-name irregularity due to indeterminate socktype. - req.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - -#if defined AI_V4MAPPED - // In this API we only require IPv4-mapped addresses when - // no native IPv6 interfaces are available (~AI_ALL). - // This saves an additional DNS roundtrip for IPv4 addresses. - if (req.ai_family == AF_INET6) - req.ai_flags |= AI_V4MAPPED; -#endif - - // Resolve the literal address. Some of the error info is lost in case - // of error, however, there's no way to report EAI errors via errno. - - rc = getaddrinfo(interface_, NULL, &req, &res); - -#if defined AI_V4MAPPED - // Some OS do have AI_V4MAPPED defined but it is not supported in getaddrinfo() - // returning EAI_BADFLAGS. Detect this and retry - if (rc == EAI_BADFLAGS && (req.ai_flags & AI_V4MAPPED)) { - req.ai_flags &= ~AI_V4MAPPED; - rc = getaddrinfo(interface_, NULL, &req, &res); - } -#endif - -#if defined ZMQ_HAVE_WINDOWS - // Resolve specific case on Windows platform when using IPv4 address - // with ZMQ_IPv6 socket option. - if ((req.ai_family == AF_INET6) && (rc == WSAHOST_NOT_FOUND)) { - req.ai_family = AF_INET; - rc = getaddrinfo(interface_, NULL, &req, &res); - } -#endif - - if (rc) { - errno = ENODEV; - return -1; - } - - // Use the first result. - zmq_assert (res != NULL); - zmq_assert ((size_t) res->ai_addrlen <= sizeof (address) ); - if (is_src_) - memcpy (&source_address, res->ai_addr, res->ai_addrlen); - else - memcpy (&address, res->ai_addr, res->ai_addrlen); - - // Cleanup getaddrinfo after copying the possibly referenced result. - freeaddrinfo (res); - - return 0; -} - -int zmq::tcp_address_t::resolve_hostname (const char *hostname_, bool ipv6_, bool is_src_) -{ - // Set up the query. -#if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64 - __addrinfo64 req; -#else - addrinfo req; -#endif - memset (&req, 0, sizeof (req) ); - - // Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for - // IPv4-in-IPv6 addresses. - req.ai_family = ipv6_? AF_INET6: AF_INET; - - // Need to choose one to avoid duplicate results from getaddrinfo() - this - // doesn't really matter, since it's not included in the addr-output. - req.ai_socktype = SOCK_STREAM; - -#if defined AI_V4MAPPED - // In this API we only require IPv4-mapped addresses when - // no native IPv6 interfaces are available. - // This saves an additional DNS roundtrip for IPv4 addresses. - if (req.ai_family == AF_INET6) - req.ai_flags |= AI_V4MAPPED; -#endif - - // Resolve host name. Some of the error info is lost in case of error, - // however, there's no way to report EAI errors via errno. -#if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64 - __addrinfo64 *res; -#else - addrinfo *res; -#endif - int rc = getaddrinfo (hostname_, NULL, &req, &res); - -#if defined AI_V4MAPPED - // Some OS do have AI_V4MAPPED defined but it is not supported in getaddrinfo() - // returning EAI_BADFLAGS. Detect this and retry - if (rc == EAI_BADFLAGS && (req.ai_flags & AI_V4MAPPED)) { - req.ai_flags &= ~AI_V4MAPPED; - rc = getaddrinfo(hostname_, NULL, &req, &res); - } -#endif - - if (rc) { - switch (rc) { - case EAI_MEMORY: - errno = ENOMEM; - break; - default: - errno = EINVAL; - break; - } - return -1; - } - - // Copy first result to output addr with hostname and service. - zmq_assert ((size_t) res->ai_addrlen <= sizeof (address) ); - if (is_src_) - memcpy (&source_address, res->ai_addr, res->ai_addrlen); - else - memcpy (&address, res->ai_addr, res->ai_addrlen); - - freeaddrinfo (res); - - return 0; -} - -zmq::tcp_address_t::tcp_address_t () : - _has_src_addr (false) -{ - memset (&address, 0, sizeof (address) ); - memset (&source_address, 0, sizeof (source_address) ); -} - -zmq::tcp_address_t::tcp_address_t (const sockaddr *sa, socklen_t sa_len) : - _has_src_addr (false) -{ - zmq_assert (sa && sa_len > 0); - - memset (&address, 0, sizeof (address) ); - memset (&source_address, 0, sizeof (source_address) ); - if (sa->sa_family == AF_INET && sa_len >= (socklen_t) sizeof (address.ipv4) ) - memcpy (&address.ipv4, sa, sizeof (address.ipv4) ); - else - if (sa->sa_family == AF_INET6 && sa_len >= (socklen_t) sizeof (address.ipv6) ) - memcpy (&address.ipv6, sa, sizeof (address.ipv6) ); -} - -zmq::tcp_address_t::~tcp_address_t () -{ -} - -int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_, bool is_src_) -{ - if (!is_src_) { - // Test the ';' to know if we have a source address in name_ - const char *src_delimiter = strrchr (name_, ';'); - if (src_delimiter) { - std::string src_name (name_, src_delimiter - name_); - const int rc = resolve (src_name.c_str (), local_, ipv6_, true); - if (rc != 0) - return -1; - name_ = src_delimiter + 1; - _has_src_addr = true; - } - } - - // Find the ':' at end that separates address from the port number. - const char *delimiter = strrchr (name_, ':'); - if (!delimiter) { - errno = EINVAL; - return -1; - } - - // Separate the address/port. - std::string addr_str (name_, delimiter - name_); - std::string port_str (delimiter + 1); - - // Remove square brackets around the address, if any, as used in IPv6 - if (addr_str.size () >= 2 && addr_str [0] == '[' && - addr_str [addr_str.size () - 1] == ']') - addr_str = addr_str.substr (1, addr_str.size () - 2); - - // Test the '%' to know if we have an interface name / zone_id in the address - // Reference: https://tools.ietf.org/html/rfc4007 - std::size_t pos = addr_str.rfind('%'); - uint32_t zone_id = 0; - if (pos != std::string::npos) { - std::string if_str = addr_str.substr(pos + 1); - addr_str = addr_str.substr(0, pos); - if (isalpha (if_str.at (0))) -#if !defined ZMQ_HAVE_WINDOWS_TARGET_XP && !defined ZMQ_HAVE_WINDOWS_UWP - zone_id = if_nametoindex(if_str.c_str()); -#else - // The function 'if_nametoindex' is not supported on Windows XP. - // If we are targeting XP using a vxxx_xp toolset then fail. - // This is brutal as this code could be run on later windows clients - // meaning the IPv6 zone_id cannot have an interface name. - // This could be fixed with a runtime check. - zone_id = 0; -#endif - else - zone_id = (uint32_t) atoi (if_str.c_str ()); - if (zone_id == 0) { - errno = EINVAL; - return -1; - } - - } - - // Allow 0 specifically, to detect invalid port error in atoi if not - uint16_t port; - if (port_str == "*" || port_str == "0") - // Resolve wildcard to 0 to allow autoselection of port - port = 0; - else { - // Parse the port number (0 is not a valid port). - port = (uint16_t) atoi (port_str.c_str ()); - if (port == 0) { - errno = EINVAL; - return -1; - } - } - - // Resolve the IP address. - int rc; - if (local_ || is_src_) - rc = resolve_interface (addr_str.c_str (), ipv6_, is_src_); - else - rc = resolve_hostname (addr_str.c_str (), ipv6_, is_src_); - if (rc != 0) - return -1; - - // Set the port into the address structure. - if (is_src_) { - if (source_address.generic.sa_family == AF_INET6) { - source_address.ipv6.sin6_port = htons (port); - source_address.ipv6.sin6_scope_id = zone_id; - } - else - source_address.ipv4.sin_port = htons (port); - } - else { - if (address.generic.sa_family == AF_INET6) { - address.ipv6.sin6_port = htons (port); - address.ipv6.sin6_scope_id = zone_id; - } - else - address.ipv4.sin_port = htons (port); - } - - return 0; -} - -int zmq::tcp_address_t::to_string (std::string &addr_) -{ - if (address.generic.sa_family != AF_INET - && address.generic.sa_family != AF_INET6) { - addr_.clear (); - return -1; - } - - // Not using service resolving because of - // https://github.com/zeromq/libzmq/commit/1824574f9b5a8ce786853320e3ea09fe1f822bc4 - char hbuf [NI_MAXHOST]; - int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL, 0, NI_NUMERICHOST); - if (rc != 0) { - addr_.clear (); - return rc; - } - - if (address.generic.sa_family == AF_INET6) { - std::stringstream s; - s << "tcp://[" << hbuf << "]:" << ntohs (address.ipv6.sin6_port); - addr_ = s.str (); - } - else { - std::stringstream s; - s << "tcp://" << hbuf << ":" << ntohs (address.ipv4.sin_port); - addr_ = s.str (); - } - return 0; -} - -const sockaddr *zmq::tcp_address_t::addr () const -{ - return &address.generic; -} - -socklen_t zmq::tcp_address_t::addrlen () const -{ - if (address.generic.sa_family == AF_INET6) - return (socklen_t) sizeof (address.ipv6); - else - return (socklen_t) sizeof (address.ipv4); -} - -const sockaddr *zmq::tcp_address_t::src_addr () const -{ - return &source_address.generic; -} - -socklen_t zmq::tcp_address_t::src_addrlen () const -{ - if (address.generic.sa_family == AF_INET6) - return (socklen_t) sizeof (source_address.ipv6); - else - return (socklen_t) sizeof (source_address.ipv4); -} - -bool zmq::tcp_address_t::has_src_addr () const -{ - return _has_src_addr; -} - -#if defined ZMQ_HAVE_WINDOWS -unsigned short zmq::tcp_address_t::family () const -#else -sa_family_t zmq::tcp_address_t::family () const -#endif -{ - return address.generic.sa_family; -} - -zmq::tcp_address_mask_t::tcp_address_mask_t () : - tcp_address_t (), - address_mask (-1) -{ -} - -int zmq::tcp_address_mask_t::mask () const -{ - return address_mask; -} - -int zmq::tcp_address_mask_t::resolve (const char *name_, bool ipv6_) -{ - // Find '/' at the end that separates address from the cidr mask number. - // Allow empty mask clause and treat it like '/32' for ipv4 or '/128' for ipv6. - std::string addr_str, mask_str; - const char *delimiter = strrchr (name_, '/'); - if (delimiter != NULL) { - addr_str.assign (name_, delimiter - name_); - mask_str.assign (delimiter + 1); - if (mask_str.empty ()) { - errno = EINVAL; - return -1; - } - } - else - addr_str.assign (name_); - - // Parse address part using standard routines. - const int rc = - tcp_address_t::resolve_hostname (addr_str.c_str (), ipv6_); - if (rc != 0) - return rc; - - // Parse the cidr mask number. - if (mask_str.empty ()) { - if (address.generic.sa_family == AF_INET6) - address_mask = 128; - else - address_mask = 32; - } - else - if (mask_str == "0") - address_mask = 0; - else { - const int mask = atoi (mask_str.c_str ()); - if ( - (mask < 1) || - (address.generic.sa_family == AF_INET6 && mask > 128) || - (address.generic.sa_family != AF_INET6 && mask > 32) - ) { - errno = EINVAL; - return -1; - } - address_mask = mask; - } - - return 0; -} - -int zmq::tcp_address_mask_t::to_string (std::string &addr_) -{ - if (address.generic.sa_family != AF_INET - && address.generic.sa_family != AF_INET6) { - addr_.clear (); - return -1; - } - if (address_mask == -1) { - addr_.clear (); - return -1; - } - - char hbuf [NI_MAXHOST]; - int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL, 0, NI_NUMERICHOST); - if (rc != 0) { - addr_.clear (); - return rc; - } - - if (address.generic.sa_family == AF_INET6) { - std::stringstream s; - s << "[" << hbuf << "]/" << address_mask; - addr_ = s.str (); - } - else { - std::stringstream s; - s << hbuf << "/" << address_mask; - addr_ = s.str (); - } - return 0; -} - -bool zmq::tcp_address_mask_t::match_address (const struct sockaddr *ss, const socklen_t ss_len) const -{ - zmq_assert (address_mask != -1 - && ss != NULL - && ss_len >= (socklen_t) sizeof (struct sockaddr)); - - if (ss->sa_family != address.generic.sa_family) - return false; - - if (address_mask > 0) { - int mask; - const uint8_t *our_bytes, *their_bytes; - if (ss->sa_family == AF_INET6) { - zmq_assert (ss_len == sizeof (struct sockaddr_in6)); - their_bytes = (const uint8_t *) &(((const struct sockaddr_in6 *) ss)->sin6_addr); - our_bytes = (const uint8_t *) &address.ipv6.sin6_addr; - mask = sizeof (struct in6_addr) * 8; - } - else { - zmq_assert (ss_len == sizeof (struct sockaddr_in)); - their_bytes = (const uint8_t *) &(((const struct sockaddr_in *) ss)->sin_addr); - our_bytes = (const uint8_t *) &address.ipv4.sin_addr; - mask = sizeof (struct in_addr) * 8; - } - if (address_mask < mask) - mask = address_mask; - - const size_t full_bytes = mask / 8; - if (memcmp (our_bytes, their_bytes, full_bytes)) - return false; - - const uint8_t last_byte_bits = 0xffU << (8 - mask % 8); - if (last_byte_bits) { - if ((their_bytes [full_bytes] & last_byte_bits) != (our_bytes [full_bytes] & last_byte_bits)) - return false; - } - } - - return true; -} diff --git a/dep/libzmq/src/tcp_address.hpp b/dep/libzmq/src/tcp_address.hpp deleted file mode 100644 index f853e7443a..0000000000 --- a/dep/libzmq/src/tcp_address.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_TCP_ADDRESS_HPP_INCLUDED__ -#define __ZMQ_TCP_ADDRESS_HPP_INCLUDED__ - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#endif - -namespace zmq -{ - - class tcp_address_t - { - public: - - tcp_address_t (); - tcp_address_t (const sockaddr *sa, socklen_t sa_len); - virtual ~tcp_address_t (); - - // This function translates textual TCP address into an address - // structure. If 'local' is true, names are resolved as local interface - // names. If it is false, names are resolved as remote hostnames. - // If 'ipv6' is true, the name may resolve to IPv6 address. - int resolve (const char *name_, bool local_, bool ipv6_, bool is_src_ = false); - - // The opposite to resolve() - virtual int to_string (std::string &addr_); - -#if defined ZMQ_HAVE_WINDOWS - unsigned short family () const; -#else - sa_family_t family () const; -#endif - const sockaddr *addr () const; - socklen_t addrlen () const; - - const sockaddr *src_addr () const; - socklen_t src_addrlen () const; - bool has_src_addr () const; - - protected: - int resolve_nic_name (const char *nic_, bool ipv6_, bool is_src_ = false); - int resolve_interface (const char *interface_, bool ipv6_, bool is_src_ = false); - int resolve_hostname (const char *hostname_, bool ipv6_, bool is_src_ = false); - -#if defined ZMQ_HAVE_WINDOWS - int get_interface_name(unsigned long index, char ** dest) const; - int wchar_to_utf8(const WCHAR * src, char ** dest) const; -#endif - - union { - sockaddr generic; - sockaddr_in ipv4; - sockaddr_in6 ipv6; - } address; - - union { - sockaddr generic; - sockaddr_in ipv4; - sockaddr_in6 ipv6; - } source_address; - bool _has_src_addr; - }; - - class tcp_address_mask_t : public tcp_address_t - { - public: - tcp_address_mask_t (); - - // This function enhances tcp_address_t::resolve() with ability to parse - // additional cidr-like(/xx) mask value at the end of the name string. - // Works only with remote hostnames. - int resolve (const char *name_, bool ipv6_); - - // The opposite to resolve() - int to_string (std::string &addr_); - - int mask () const; - - bool match_address (const struct sockaddr *ss, const socklen_t ss_len) const; - - private: - int address_mask; - }; - -} - -#endif diff --git a/dep/libzmq/src/tcp_connecter.cpp b/dep/libzmq/src/tcp_connecter.cpp deleted file mode 100644 index 688787353b..0000000000 --- a/dep/libzmq/src/tcp_connecter.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "macros.hpp" -#include "tcp_connecter.hpp" -#include "stream_engine.hpp" -#include "io_thread.hpp" -#include "random.hpp" -#include "err.hpp" -#include "ip.hpp" -#include "tcp.hpp" -#include "address.hpp" -#include "tcp_address.hpp" -#include "session_base.hpp" - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ZMQ_HAVE_OPENVMS -#include -#endif -#endif - -zmq::tcp_connecter_t::tcp_connecter_t (class io_thread_t *io_thread_, - class session_base_t *session_, const options_t &options_, - address_t *addr_, bool delayed_start_) : - own_t (io_thread_, options_), - io_object_t (io_thread_), - addr (addr_), - s (retired_fd), - handle((handle_t)NULL), - handle_valid (false), - delayed_start (delayed_start_), - connect_timer_started (false), - reconnect_timer_started (false), - session (session_), - current_reconnect_ivl (options.reconnect_ivl) -{ - zmq_assert (addr); - zmq_assert (addr->protocol == "tcp"); - addr->to_string (endpoint); - socket = session->get_socket (); -} - -zmq::tcp_connecter_t::~tcp_connecter_t () -{ - zmq_assert (!connect_timer_started); - zmq_assert (!reconnect_timer_started); - zmq_assert (!handle_valid); - zmq_assert (s == retired_fd); -} - -void zmq::tcp_connecter_t::process_plug () -{ - if (delayed_start) - add_reconnect_timer (); - else - start_connecting (); -} - -void zmq::tcp_connecter_t::process_term (int linger_) -{ - if (connect_timer_started) { - cancel_timer (connect_timer_id); - connect_timer_started = false; - } - - if (reconnect_timer_started) { - cancel_timer (reconnect_timer_id); - reconnect_timer_started = false; - } - - if (handle_valid) { - rm_fd (handle); - handle_valid = false; - } - - if (s != retired_fd) - close (); - - own_t::process_term (linger_); -} - -void zmq::tcp_connecter_t::in_event () -{ - // We are not polling for incoming data, so we are actually called - // because of error here. However, we can get error on out event as well - // on some platforms, so we'll simply handle both events in the same way. - out_event (); -} - -void zmq::tcp_connecter_t::out_event () -{ - if (connect_timer_started) { - cancel_timer (connect_timer_id); - connect_timer_started = false; - } - - rm_fd (handle); - handle_valid = false; - - const fd_t fd = connect (); - - // Handle the error condition by attempt to reconnect. - if (fd == retired_fd) { - close (); - add_reconnect_timer (); - return; - } - - int rc = tune_tcp_socket (fd); - rc = rc | tune_tcp_keepalives (fd, options.tcp_keepalive, options.tcp_keepalive_cnt, - options.tcp_keepalive_idle, options.tcp_keepalive_intvl); - rc = rc | tune_tcp_maxrt (fd, options.tcp_maxrt); - if (rc != 0) { - close (); - add_reconnect_timer (); - return; - } - - // Create the engine object for this connection. - stream_engine_t *engine = new (std::nothrow) - stream_engine_t (fd, options, endpoint); - alloc_assert (engine); - - // Attach the engine to the corresponding session object. - send_attach (session, engine); - - // Shut the connecter down. - terminate (); - - socket->event_connected (endpoint, (int) fd); -} - -void zmq::tcp_connecter_t::timer_event (int id_) -{ - zmq_assert (id_ == reconnect_timer_id || id_ == connect_timer_id); - if (id_ == connect_timer_id) { - connect_timer_started = false; - - rm_fd (handle); - handle_valid = false; - - close (); - add_reconnect_timer (); - } - else if (id_ == reconnect_timer_id) { - reconnect_timer_started = false; - start_connecting (); - } -} - -void zmq::tcp_connecter_t::start_connecting () -{ - // Open the connecting socket. - const int rc = open (); - - // Connect may succeed in synchronous manner. - if (rc == 0) { - handle = add_fd (s); - handle_valid = true; - out_event (); - } - - // Connection establishment may be delayed. Poll for its completion. - else - if (rc == -1 && errno == EINPROGRESS) { - handle = add_fd (s); - handle_valid = true; - set_pollout (handle); - socket->event_connect_delayed (endpoint, zmq_errno()); - - // add userspace connect timeout - add_connect_timer (); - } - - // Handle any other error condition by eventual reconnect. - else { - if (s != retired_fd) - close (); - add_reconnect_timer (); - } -} - -void zmq::tcp_connecter_t::add_connect_timer () -{ - if (options.connect_timeout > 0) { - add_timer (options.connect_timeout, connect_timer_id); - connect_timer_started = true; - } -} - -void zmq::tcp_connecter_t::add_reconnect_timer () -{ - const int interval = get_new_reconnect_ivl (); - add_timer (interval, reconnect_timer_id); - socket->event_connect_retried (endpoint, interval); - reconnect_timer_started = true; -} - -int zmq::tcp_connecter_t::get_new_reconnect_ivl () -{ - // The new interval is the current interval + random value. - const int interval = current_reconnect_ivl + - generate_random () % options.reconnect_ivl; - - // Only change the current reconnect interval if the maximum reconnect - // interval was set and if it's larger than the reconnect interval. - if (options.reconnect_ivl_max > 0 && - options.reconnect_ivl_max > options.reconnect_ivl) - // Calculate the next interval - current_reconnect_ivl = - std::min (current_reconnect_ivl * 2, options.reconnect_ivl_max); - return interval; -} - -int zmq::tcp_connecter_t::open () -{ - zmq_assert (s == retired_fd); - - // Resolve the address - if (addr->resolved.tcp_addr != NULL) { - LIBZMQ_DELETE(addr->resolved.tcp_addr); - } - - addr->resolved.tcp_addr = new (std::nothrow) tcp_address_t (); - alloc_assert (addr->resolved.tcp_addr); - int rc = addr->resolved.tcp_addr->resolve ( - addr->address.c_str (), false, options.ipv6); - if (rc != 0) { - LIBZMQ_DELETE(addr->resolved.tcp_addr); - return -1; - } - zmq_assert (addr->resolved.tcp_addr != NULL); - tcp_address_t * const tcp_addr = addr->resolved.tcp_addr; - - // Create the socket. - s = open_socket (tcp_addr->family (), SOCK_STREAM, IPPROTO_TCP); - - // IPv6 address family not supported, try automatic downgrade to IPv4. - if (s == zmq::retired_fd && tcp_addr->family () == AF_INET6 - && errno == EAFNOSUPPORT - && options.ipv6) { - rc = addr->resolved.tcp_addr->resolve ( - addr->address.c_str (), false, false); - if (rc != 0) { - LIBZMQ_DELETE(addr->resolved.tcp_addr); - return -1; - } - s = open_socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); - } - -#ifdef ZMQ_HAVE_WINDOWS - if (s == INVALID_SOCKET) { - errno = wsa_error_to_errno (WSAGetLastError ()); - return -1; - } -#else - if (s == -1) - return -1; -#endif - - // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. - // Switch it on in such cases. - if (tcp_addr->family () == AF_INET6) - enable_ipv4_mapping (s); - - // Set the IP Type-Of-Service priority for this socket - if (options.tos != 0) - set_ip_type_of_service (s, options.tos); - - // Bind the socket to a device if applicable - if (!options.bound_device.empty ()) - bind_to_device (s, options.bound_device); - - // Set the socket to non-blocking mode so that we get async connect(). - unblock_socket (s); - - // Set the socket buffer limits for the underlying socket. - if (options.sndbuf >= 0) - set_tcp_send_buffer (s, options.sndbuf); - if (options.rcvbuf >= 0) - set_tcp_receive_buffer (s, options.rcvbuf); - - // Set the IP Type-Of-Service for the underlying socket - if (options.tos != 0) - set_ip_type_of_service (s, options.tos); - - // Set a source address for conversations - if (tcp_addr->has_src_addr ()) { - // Allow reusing of the address, to connect to different servers - // using the same source port on the client. - int flag = 1; -#ifdef ZMQ_HAVE_WINDOWS - rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (const char*) &flag, - sizeof (int)); - wsa_assert (rc != SOCKET_ERROR); -#else - rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); - errno_assert (rc == 0); -#endif - - rc = ::bind (s, tcp_addr->src_addr (), tcp_addr->src_addrlen ()); - if (rc == -1) - return -1; - } - - // Connect to the remote peer. - rc = ::connect (s, tcp_addr->addr (), tcp_addr->addrlen ()); - - // Connect was successful immediately. - if (rc == 0) - return 0; - - // Translate error codes indicating asynchronous connect has been - // launched to a uniform EINPROGRESS. -#ifdef ZMQ_HAVE_WINDOWS - const int last_error = WSAGetLastError(); - if (last_error == WSAEINPROGRESS || last_error == WSAEWOULDBLOCK) - errno = EINPROGRESS; - else - errno = wsa_error_to_errno (last_error); -#else - if (errno == EINTR) - errno = EINPROGRESS; -#endif - return -1; -} - -zmq::fd_t zmq::tcp_connecter_t::connect () -{ - // Async connect has finished. Check whether an error occurred - int err = 0; -#ifdef ZMQ_HAVE_HPUX - int len = sizeof err; -#else - socklen_t len = sizeof err; -#endif - - const int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len); - - // Assert if the error was caused by 0MQ bug. - // Networking problems are OK. No need to assert. -#ifdef ZMQ_HAVE_WINDOWS - zmq_assert (rc == 0); - if (err != 0) { - if (err == WSAEBADF || - err == WSAENOPROTOOPT || - err == WSAENOTSOCK || - err == WSAENOBUFS) - { - wsa_assert_no (err); - } - return retired_fd; - } -#else - // Following code should handle both Berkeley-derived socket - // implementations and Solaris. - if (rc == -1) - err = errno; - if (err != 0) { - errno = err; - errno_assert ( - errno != EBADF && - errno != ENOPROTOOPT && - errno != ENOTSOCK && - errno != ENOBUFS); - return retired_fd; - } -#endif - - // Return the newly connected socket. - const fd_t result = s; - s = retired_fd; - return result; -} - -void zmq::tcp_connecter_t::close () -{ - zmq_assert (s != retired_fd); -#ifdef ZMQ_HAVE_WINDOWS - const int rc = closesocket (s); - wsa_assert (rc != SOCKET_ERROR); -#else - const int rc = ::close (s); - errno_assert (rc == 0); -#endif - socket->event_closed (endpoint, (int) s); - s = retired_fd; -} diff --git a/dep/libzmq/src/tcp_connecter.hpp b/dep/libzmq/src/tcp_connecter.hpp deleted file mode 100644 index c4fe7d7cea..0000000000 --- a/dep/libzmq/src/tcp_connecter.hpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __TCP_CONNECTER_HPP_INCLUDED__ -#define __TCP_CONNECTER_HPP_INCLUDED__ - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - struct address_t; - - class tcp_connecter_t : public own_t, public io_object_t - { - public: - - // If 'delayed_start' is true connecter first waits for a while, - // then starts connection process. - tcp_connecter_t (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_, const options_t &options_, - address_t *addr_, bool delayed_start_); - ~tcp_connecter_t (); - - private: - - // ID of the timer used to delay the reconnection. - enum {reconnect_timer_id = 1, connect_timer_id}; - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - void out_event (); - void timer_event (int id_); - - // Internal function to start the actual connection establishment. - void start_connecting (); - - // Internal function to add a connect timer - void add_connect_timer(); - - // Internal function to add a reconnect timer - void add_reconnect_timer(); - - // Internal function to return a reconnect backoff delay. - // Will modify the current_reconnect_ivl used for next call - // Returns the currently used interval - int get_new_reconnect_ivl (); - - // Open TCP connecting socket. Returns -1 in case of error, - // 0 if connect was successful immediately. Returns -1 with - // EAGAIN errno if async connect was launched. - int open (); - - // Close the connecting socket. - void close (); - - // Get the file descriptor of newly created connection. Returns - // retired_fd if the connection was unsuccessful. - fd_t connect (); - - // Address to connect to. Owned by session_base_t. - address_t *addr; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // If true file descriptor is registered with the poller and 'handle' - // contains valid value. - bool handle_valid; - - // If true, connecter is waiting a while before trying to connect. - const bool delayed_start; - - // True iff a timer has been started. - bool connect_timer_started; - bool reconnect_timer_started; - - // Reference to the session we belong to. - zmq::session_base_t *session; - - // Current reconnect ivl, updated for backoff strategy - int current_reconnect_ivl; - - // String representation of endpoint to connect to - std::string endpoint; - - // Socket - zmq::socket_base_t *socket; - - tcp_connecter_t (const tcp_connecter_t&); - const tcp_connecter_t &operator = (const tcp_connecter_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/tcp_listener.cpp b/dep/libzmq/src/tcp_listener.cpp deleted file mode 100644 index 7b929d4298..0000000000 --- a/dep/libzmq/src/tcp_listener.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include -#include - -#include "tcp_listener.hpp" -#include "stream_engine.hpp" -#include "io_thread.hpp" -#include "session_base.hpp" -#include "config.hpp" -#include "err.hpp" -#include "ip.hpp" -#include "tcp.hpp" -#include "socket_base.hpp" - -#ifndef ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#include -#include -#include -#endif - -#ifdef ZMQ_HAVE_OPENVMS -#include -#endif - -zmq::tcp_listener_t::tcp_listener_t (io_thread_t *io_thread_, - socket_base_t *socket_, const options_t &options_) : - own_t (io_thread_, options_), - io_object_t (io_thread_), - s (retired_fd), - handle((handle_t)NULL), - socket (socket_) -{ -} - -zmq::tcp_listener_t::~tcp_listener_t () -{ - zmq_assert (s == retired_fd); -} - -void zmq::tcp_listener_t::process_plug () -{ - // Start polling for incoming connections. - handle = add_fd (s); - set_pollin (handle); -} - -void zmq::tcp_listener_t::process_term (int linger_) -{ - rm_fd (handle); - close (); - own_t::process_term (linger_); -} - -void zmq::tcp_listener_t::in_event () -{ - fd_t fd = accept (); - - // If connection was reset by the peer in the meantime, just ignore it. - // TODO: Handle specific errors like ENFILE/EMFILE etc. - if (fd == retired_fd) { - socket->event_accept_failed (endpoint, zmq_errno()); - return; - } - - int rc = tune_tcp_socket (fd); - rc = rc | tune_tcp_keepalives (fd, options.tcp_keepalive, options.tcp_keepalive_cnt, - options.tcp_keepalive_idle, options.tcp_keepalive_intvl); - rc = rc | tune_tcp_maxrt (fd, options.tcp_maxrt); - if (rc != 0) { - socket->event_accept_failed (endpoint, zmq_errno()); - return; - } - - // Create the engine object for this connection. - stream_engine_t *engine = new (std::nothrow) - stream_engine_t (fd, options, endpoint); - alloc_assert (engine); - - // Choose I/O thread to run connecter in. Given that we are already - // running in an I/O thread, there must be at least one available. - io_thread_t *io_thread = choose_io_thread (options.affinity); - zmq_assert (io_thread); - - // Create and launch a session object. - session_base_t *session = session_base_t::create (io_thread, false, socket, - options, NULL); - errno_assert (session); - session->inc_seqnum (); - launch_child (session); - send_attach (session, engine, false); - socket->event_accepted (endpoint, (int) fd); -} - -void zmq::tcp_listener_t::close () -{ - zmq_assert (s != retired_fd); -#ifdef ZMQ_HAVE_WINDOWS - int rc = closesocket (s); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = ::close (s); - errno_assert (rc == 0); -#endif - socket->event_closed (endpoint, (int) s); - s = retired_fd; -} - -int zmq::tcp_listener_t::get_address (std::string &addr_) -{ - // Get the details of the TCP socket - struct sockaddr_storage ss; -#ifdef ZMQ_HAVE_HPUX - int sl = sizeof (ss); -#else - socklen_t sl = sizeof (ss); -#endif - int rc = getsockname (s, (struct sockaddr *) &ss, &sl); - - if (rc != 0) { - addr_.clear (); - return rc; - } - - tcp_address_t addr ((struct sockaddr *) &ss, sl); - return addr.to_string (addr_); -} - -int zmq::tcp_listener_t::set_address (const char *addr_) -{ - // Convert the textual address into address structure. - int rc = address.resolve (addr_, true, options.ipv6); - if (rc != 0) - return -1; - - address.to_string (endpoint); - - if (options.use_fd != -1) { - s = options.use_fd; - socket->event_listening (endpoint, (int) s); - return 0; - } - - // Create a listening socket. - s = open_socket (address.family (), SOCK_STREAM, IPPROTO_TCP); - - // IPv6 address family not supported, try automatic downgrade to IPv4. - if (s == zmq::retired_fd && address.family () == AF_INET6 - && errno == EAFNOSUPPORT - && options.ipv6) { - rc = address.resolve (addr_, true, false); - if (rc != 0) - return rc; - s = open_socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); - } - -#ifdef ZMQ_HAVE_WINDOWS - if (s == INVALID_SOCKET) { - errno = wsa_error_to_errno (WSAGetLastError ()); - return -1; - } -#if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP - // On Windows, preventing sockets to be inherited by child processes. - BOOL brc = SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0); - win_assert (brc); -#endif -#else - if (s == -1) - return -1; -#endif - - // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. - // Switch it on in such cases. - if (address.family () == AF_INET6) - enable_ipv4_mapping (s); - - // Set the IP Type-Of-Service for the underlying socket - if (options.tos != 0) - set_ip_type_of_service (s, options.tos); - - // Bind the socket to a device if applicable - if (!options.bound_device.empty ()) - bind_to_device (s, options.bound_device); - - // Set the socket buffer limits for the underlying socket. - if (options.sndbuf >= 0) - set_tcp_send_buffer (s, options.sndbuf); - if (options.rcvbuf >= 0) - set_tcp_receive_buffer (s, options.rcvbuf); - - // Allow reusing of the address. - int flag = 1; -#ifdef ZMQ_HAVE_WINDOWS - rc = setsockopt (s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, - (const char*) &flag, sizeof (int)); - wsa_assert (rc != SOCKET_ERROR); -#else - rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); - errno_assert (rc == 0); -#endif - - // Bind the socket to the network interface and port. - rc = bind (s, address.addr (), address.addrlen ()); -#ifdef ZMQ_HAVE_WINDOWS - if (rc == SOCKET_ERROR) { - errno = wsa_error_to_errno (WSAGetLastError ()); - goto error; - } -#else - if (rc != 0) - goto error; -#endif - - // Listen for incoming connections. - rc = listen (s, options.backlog); -#ifdef ZMQ_HAVE_WINDOWS - if (rc == SOCKET_ERROR) { - errno = wsa_error_to_errno (WSAGetLastError ()); - goto error; - } -#else - if (rc != 0) - goto error; -#endif - - socket->event_listening (endpoint, (int) s); - return 0; - -error: - int err = errno; - close (); - errno = err; - return -1; -} - -zmq::fd_t zmq::tcp_listener_t::accept () -{ - // The situation where connection cannot be accepted due to insufficient - // resources is considered valid and treated by ignoring the connection. - // Accept one connection and deal with different failure modes. - zmq_assert (s != retired_fd); - - struct sockaddr_storage ss; - memset (&ss, 0, sizeof (ss)); -#ifdef ZMQ_HAVE_HPUX - int ss_len = sizeof (ss); -#else - socklen_t ss_len = sizeof (ss); -#endif -#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4 - fd_t sock = ::accept4 (s, (struct sockaddr *) &ss, &ss_len, SOCK_CLOEXEC); -#else - fd_t sock = ::accept (s, (struct sockaddr *) &ss, &ss_len); -#endif - -#ifdef ZMQ_HAVE_WINDOWS - if (sock == INVALID_SOCKET) { - const int last_error = WSAGetLastError(); - wsa_assert (last_error == WSAEWOULDBLOCK || - last_error == WSAECONNRESET || - last_error == WSAEMFILE || - last_error == WSAENOBUFS); - return retired_fd; - } -#if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP - // On Windows, preventing sockets to be inherited by child processes. - BOOL brc = SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0); - win_assert (brc); -#endif -#else - if (sock == -1) { - errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINTR || errno == ECONNABORTED || errno == EPROTO || - errno == ENOBUFS || errno == ENOMEM || errno == EMFILE || - errno == ENFILE); - return retired_fd; - } -#endif - -#if (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) && defined FD_CLOEXEC - // Race condition can cause socket not to be closed (if fork happens - // between accept and this point). - int rc = fcntl (sock, F_SETFD, FD_CLOEXEC); - errno_assert (rc != -1); -#endif - - if (!options.tcp_accept_filters.empty ()) { - bool matched = false; - for (options_t::tcp_accept_filters_t::size_type i = 0; i != options.tcp_accept_filters.size (); ++i) { - if (options.tcp_accept_filters[i].match_address ((struct sockaddr *) &ss, ss_len)) { - matched = true; - break; - } - } - if (!matched) { -#ifdef ZMQ_HAVE_WINDOWS - int rc = closesocket (sock); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = ::close (sock); - errno_assert (rc == 0); -#endif - return retired_fd; - } - } - - if (zmq::set_nosigpipe (sock)) { -#ifdef ZMQ_HAVE_WINDOWS - int rc = closesocket (sock); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = ::close (sock); - errno_assert (rc == 0); -#endif - return retired_fd; - } - - // Set the IP Type-Of-Service priority for this client socket - if (options.tos != 0) - set_ip_type_of_service (sock, options.tos); - - return sock; -} diff --git a/dep/libzmq/src/tcp_listener.hpp b/dep/libzmq/src/tcp_listener.hpp deleted file mode 100644 index 2b3ccff7e2..0000000000 --- a/dep/libzmq/src/tcp_listener.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_TCP_LISTENER_HPP_INCLUDED__ -#define __ZMQ_TCP_LISTENER_HPP_INCLUDED__ - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" -#include "tcp_address.hpp" - -namespace zmq -{ - - class io_thread_t; - class socket_base_t; - - class tcp_listener_t : public own_t, public io_object_t - { - public: - - tcp_listener_t (zmq::io_thread_t *io_thread_, - zmq::socket_base_t *socket_, const options_t &options_); - ~tcp_listener_t (); - - // Set address to listen on. - int set_address (const char *addr_); - - // Get the bound address for use with wildcard - int get_address (std::string &addr_); - - private: - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - - // Close the listening socket. - void close (); - - // Accept the new connection. Returns the file descriptor of the - // newly created connection. The function may return retired_fd - // if the connection was dropped while waiting in the listen backlog - // or was denied because of accept filters. - fd_t accept (); - - // Address to listen on. - tcp_address_t address; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // Socket the listener belongs to. - zmq::socket_base_t *socket; - - // String representation of endpoint to bind to - std::string endpoint; - - tcp_listener_t (const tcp_listener_t&); - const tcp_listener_t &operator = (const tcp_listener_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/thread.cpp b/dep/libzmq/src/thread.cpp deleted file mode 100644 index 4fc59c3ebe..0000000000 --- a/dep/libzmq/src/thread.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "thread.hpp" -#include "err.hpp" - -#ifdef ZMQ_HAVE_WINDOWS - -extern "C" -{ -#if defined _WIN32_WCE - static DWORD thread_routine (LPVOID arg_) -#else - static unsigned int __stdcall thread_routine (void *arg_) -#endif - { - zmq::thread_t *self = (zmq::thread_t*) arg_; - self->tfn (self->arg); - return 0; - } -} - -void zmq::thread_t::start (thread_fn *tfn_, void *arg_) -{ - tfn = tfn_; - arg = arg_; -#if defined _WIN32_WCE - descriptor = (HANDLE) CreateThread (NULL, 0, - &::thread_routine, this, 0 , NULL); -#else - descriptor = (HANDLE) _beginthreadex (NULL, 0, - &::thread_routine, this, 0 , NULL); -#endif - win_assert (descriptor != NULL); -} - -void zmq::thread_t::stop () -{ - DWORD rc = WaitForSingleObject (descriptor, INFINITE); - win_assert (rc != WAIT_FAILED); - BOOL rc2 = CloseHandle (descriptor); - win_assert (rc2 != 0); -} - -void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_, const std::set& affinity_cpus_) -{ - // not implemented - LIBZMQ_UNUSED (priority_); - LIBZMQ_UNUSED (schedulingPolicy_); - LIBZMQ_UNUSED (affinity_cpus_); -} - -void zmq::thread_t::setThreadName(const char *name_) -{ - // not implemented - LIBZMQ_UNUSED (name_); -} - -#else - -#include -#include -#include -#include - -extern "C" -{ - static void *thread_routine (void *arg_) - { -#if !defined ZMQ_HAVE_OPENVMS && !defined ZMQ_HAVE_ANDROID - // Following code will guarantee more predictable latencies as it'll - // disallow any signal handling in the I/O thread. - sigset_t signal_set; - int rc = sigfillset (&signal_set); - errno_assert (rc == 0); - rc = pthread_sigmask (SIG_BLOCK, &signal_set, NULL); - posix_assert (rc); -#endif - zmq::thread_t *self = (zmq::thread_t*) arg_; - self->applySchedulingParameters(); - self->tfn (self->arg); - return NULL; - } -} - -void zmq::thread_t::start (thread_fn *tfn_, void *arg_) -{ - tfn = tfn_; - arg = arg_; - int rc = pthread_create (&descriptor, NULL, thread_routine, this); - posix_assert (rc); -} - -void zmq::thread_t::stop () -{ - int rc = pthread_join (descriptor, NULL); - posix_assert (rc); -} - -void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_, const std::set& affinity_cpus_) -{ - thread_priority=priority_; - thread_sched_policy=schedulingPolicy_; - thread_affinity_cpus=affinity_cpus_; -} - -void zmq::thread_t::applySchedulingParameters() // to be called in secondary thread context -{ -#if defined _POSIX_THREAD_PRIORITY_SCHEDULING && _POSIX_THREAD_PRIORITY_SCHEDULING >= 0 - int policy = 0; - struct sched_param param; - -#if _POSIX_THREAD_PRIORITY_SCHEDULING == 0 && defined _SC_THREAD_PRIORITY_SCHEDULING - if (sysconf(_SC_THREAD_PRIORITY_SCHEDULING) < 0) { - return; - } -#endif - int rc = pthread_getschedparam(descriptor, &policy, ¶m); - posix_assert (rc); - - if(thread_sched_policy != ZMQ_THREAD_SCHED_POLICY_DFLT) - { - policy = thread_sched_policy; - } - - /* Quoting docs: - "Linux allows the static priority range 1 to 99 for the SCHED_FIFO and - SCHED_RR policies, and the priority 0 for the remaining policies." - Other policies may use the "nice value" in place of the priority: - */ - bool use_nice_instead_priority = (policy != SCHED_FIFO) && (policy != SCHED_RR); - - if(thread_priority != ZMQ_THREAD_PRIORITY_DFLT) - { - if (use_nice_instead_priority) - param.sched_priority = 0; // this is the only supported priority for most scheduling policies - else - param.sched_priority = thread_priority; // user should provide a value between 1 and 99 - } - -#ifdef __NetBSD__ - if(policy == SCHED_OTHER) param.sched_priority = -1; -#endif - - rc = pthread_setschedparam(descriptor, policy, ¶m); - -#if defined(__FreeBSD_kernel__) || defined (__FreeBSD__) - // If this feature is unavailable at run-time, don't abort. - if(rc == ENOSYS) return; -#endif - - posix_assert (rc); - - if (use_nice_instead_priority && - thread_priority != ZMQ_THREAD_PRIORITY_DFLT) - { - // assume the user wants to decrease the thread's nice value - // i.e., increase the chance of this thread being scheduled: try setting that to - // maximum priority. - rc = nice(-20); - - errno_assert (rc != -1); - // IMPORTANT: EPERM is typically returned for unprivileged processes: that's because - // CAP_SYS_NICE capability is required or RLIMIT_NICE resource limit should be changed to avoid EPERM! - - } - -#ifdef ZMQ_HAVE_PTHREAD_SET_AFFINITY - if (!thread_affinity_cpus.empty()) - { - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - for (std::set::const_iterator it = thread_affinity_cpus.begin(); it != thread_affinity_cpus.end(); it++) - { - CPU_SET( (int)(*it) , &cpuset ); - } - rc = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - posix_assert (rc); - } -#endif -#endif -} - -void zmq::thread_t::setThreadName(const char *name_) -{ -/* The thread name is a cosmetic string, added to ease debugging of - * multi-threaded applications. It is not a big issue if this value - * can not be set for any reason (such as Permission denied in some - * cases where the application changes its EUID, etc.) The value of - * "int rc" is retained where available, to help debuggers stepping - * through code to see its value - but otherwise it is ignored. - */ - if (!name_) - return; - -#if defined(ZMQ_HAVE_PTHREAD_SETNAME_1) - int rc = pthread_setname_np(name_); - if(rc) return; -#elif defined(ZMQ_HAVE_PTHREAD_SETNAME_2) - int rc = pthread_setname_np(descriptor, name_); - if(rc) return; -#elif defined(ZMQ_HAVE_PTHREAD_SETNAME_3) - int rc = pthread_setname_np(descriptor, name_, NULL); - if(rc) return; -#elif defined(ZMQ_HAVE_PTHREAD_SET_NAME) - pthread_set_name_np(descriptor, name_); -#endif -} - -#endif diff --git a/dep/libzmq/src/thread.hpp b/dep/libzmq/src/thread.hpp deleted file mode 100644 index 150b31d16d..0000000000 --- a/dep/libzmq/src/thread.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_THREAD_HPP_INCLUDED__ -#define __ZMQ_THREAD_HPP_INCLUDED__ - -#ifndef ZMQ_HAVE_WINDOWS -#include -#endif -#include - -namespace zmq -{ - - typedef void (thread_fn) (void*); - - // Class encapsulating OS thread. Thread initiation/termination is done - // using special functions rather than in constructor/destructor so that - // thread isn't created during object construction by accident, causing - // newly created thread to access half-initialised object. Same applies - // to the destruction process: Thread should be terminated before object - // destruction begins, otherwise it can access half-destructed object. - - class thread_t - { - public: - - inline thread_t () - : tfn(NULL) - , arg(NULL) - , thread_priority(ZMQ_THREAD_PRIORITY_DFLT) - , thread_sched_policy(ZMQ_THREAD_SCHED_POLICY_DFLT) - { - } - - // Creates OS thread. 'tfn' is main thread function. It'll be passed - // 'arg' as an argument. - void start (thread_fn *tfn_, void *arg_); - - // Waits for thread termination. - void stop (); - - // Sets the thread scheduling parameters. Only implemented for - // pthread. Has no effect on other platforms. - void setSchedulingParameters(int priority_, int schedulingPolicy_, const std::set& affinity_cpus_); - - // Sets the thread name, 16 characters max including terminating NUL. - // Only implemented for pthread. Has no effect on other platforms. - void setThreadName(const char *name_); - - // These are internal members. They should be private, however then - // they would not be accessible from the main C routine of the thread. - void applySchedulingParameters(); - thread_fn *tfn; - void *arg; - - private: - -#ifdef ZMQ_HAVE_WINDOWS - HANDLE descriptor; -#else - pthread_t descriptor; -#endif - - // Thread scheduling parameters. - int thread_priority; - int thread_sched_policy; - std::set thread_affinity_cpus; - - thread_t (const thread_t&); - const thread_t &operator = (const thread_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/timers.cpp b/dep/libzmq/src/timers.cpp deleted file mode 100644 index 1474ac2a5d..0000000000 --- a/dep/libzmq/src/timers.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - -This file is part of libzmq, the ZeroMQ core engine in C++. - -libzmq is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License (LGPL) as published -by the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -As a special exception, the Contributors give you permission to link -this library with independent modules to produce an executable, -regardless of the license terms of these independent modules, and to -copy and distribute the resulting executable under terms of your choice, -provided that you also meet, for each linked independent module, the -terms and conditions of the license of that module. An independent -module is a module which is not derived from or based on this library. -If you modify this library, you must extend this exception to your -version of the library. - -libzmq is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "timers.hpp" -#include "err.hpp" - -#include - -zmq::timers_t::timers_t () : tag (0xCAFEDADA), next_timer_id (0) -{ -} - -zmq::timers_t::~timers_t () -{ - // Mark the timers as dead - tag = 0xdeadbeef; -} - -bool zmq::timers_t::check_tag () -{ - return tag == 0xCAFEDADA; -} - -int zmq::timers_t::add (size_t interval_, timers_timer_fn handler_, void *arg_) -{ - if (!handler_) { - errno = EFAULT; - return -1; - } - - uint64_t when = clock.now_ms () + interval_; - timer_t timer = {++next_timer_id, interval_, handler_, arg_}; - timers.insert (timersmap_t::value_type (when, timer)); - - return timer.timer_id; -} - -struct zmq::timers_t::match_by_id -{ - match_by_id (int timer_id_) : timer_id (timer_id_) {} - - bool operator() (timersmap_t::value_type const &entry) const - { - return entry.second.timer_id == timer_id; - } - - private: - int timer_id; -}; - -int zmq::timers_t::cancel (int timer_id_) -{ - // check first if timer exists at all - if (timers.end () - == std::find_if (timers.begin (), timers.end (), - match_by_id (timer_id_))) { - errno = EINVAL; - return -1; - } - - // check if timer was already canceled - if (cancelled_timers.count (timer_id_)) { - errno = EINVAL; - return -1; - } - - cancelled_timers.insert (timer_id_); - - return 0; -} - -int zmq::timers_t::set_interval (int timer_id_, size_t interval_) -{ - const timersmap_t::iterator end = timers.end (); - const timersmap_t::iterator it = - std::find_if (timers.begin (), end, match_by_id (timer_id_)); - if (it != end) { - timer_t timer = it->second; - timer.interval = interval_; - uint64_t when = clock.now_ms () + interval_; - timers.erase (it); - timers.insert (timersmap_t::value_type (when, timer)); - - return 0; - } - - errno = EINVAL; - return -1; -} - -int zmq::timers_t::reset (int timer_id_) -{ - const timersmap_t::iterator end = timers.end (); - const timersmap_t::iterator it = - std::find_if (timers.begin (), end, match_by_id (timer_id_)); - if (it != end) { - timer_t timer = it->second; - uint64_t when = clock.now_ms () + timer.interval; - timers.erase (it); - timers.insert (timersmap_t::value_type (when, timer)); - - return 0; - } - - errno = EINVAL; - return -1; -} - -long zmq::timers_t::timeout () -{ - timersmap_t::iterator it = timers.begin (); - - uint64_t now = clock.now_ms (); - - while (it != timers.end ()) { - cancelled_timers_t::iterator cancelled_it = - cancelled_timers.find (it->second.timer_id); - - // Live timer, lets return the timeout - if (cancelled_it == cancelled_timers.end ()) { - if (it->first > now) - return (long) (it->first - now); - else - return 0; - } - - // Let's remove it from the beginning of the list - timersmap_t::iterator old = it; - ++it; - timers.erase (old); - cancelled_timers.erase (cancelled_it); - } - - // Wait forever as no timers are alive - return -1; -} - -int zmq::timers_t::execute () -{ - timersmap_t::iterator it = timers.begin (); - - uint64_t now = clock.now_ms (); - - while (it != timers.end ()) { - cancelled_timers_t::iterator cancelled_it = - cancelled_timers.find (it->second.timer_id); - - // Dead timer, lets remove it and continue - if (cancelled_it != cancelled_timers.end ()) { - timersmap_t::iterator old = it; - ++it; - timers.erase (old); - cancelled_timers.erase (cancelled_it); - continue; - } - - // Map is ordered, if we have to wait for current timer we can stop. - if (it->first > now) - break; - - timer_t timer = it->second; - - timer.handler (timer.timer_id, timer.arg); - - timersmap_t::iterator old = it; - ++it; - timers.erase (old); - timers.insert (timersmap_t::value_type (now + timer.interval, timer)); - } - - return 0; -} diff --git a/dep/libzmq/src/timers.hpp b/dep/libzmq/src/timers.hpp deleted file mode 100644 index b7c5ce655c..0000000000 --- a/dep/libzmq/src/timers.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - -This file is part of libzmq, the ZeroMQ core engine in C++. - -libzmq is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License (LGPL) as published -by the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -As a special exception, the Contributors give you permission to link -this library with independent modules to produce an executable, -regardless of the license terms of these independent modules, and to -copy and distribute the resulting executable under terms of your choice, -provided that you also meet, for each linked independent module, the -terms and conditions of the license of that module. An independent -module is a module which is not derived from or based on this library. -If you modify this library, you must extend this exception to your -version of the library. - -libzmq is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef __ZMQ_TIMERS_HPP_INCLUDED__ -#define __ZMQ_TIMERS_HPP_INCLUDED__ - -#include -#include -#include - -#include "clock.hpp" - -namespace zmq -{ - typedef void (timers_timer_fn)( - int timer_id, void *arg); - - class timers_t - { - public: - timers_t (); - ~timers_t (); - - // Add timer to the set, timer repeats forever, or until cancel is called. - // Returns a timer_id that is used to cancel the timer. - // Returns -1 if there was an error. - int add (size_t interval, timers_timer_fn handler, void* arg); - - // Set the interval of the timer. - // This method is slow, cancelling exsting and adding a new timer yield better performance. - // Returns 0 on success and -1 on error. - int set_interval (int timer_id, size_t interval); - - // Reset the timer. - // This method is slow, cancelling exsting and adding a new timer yield better performance. - // Returns 0 on success and -1 on error. - int reset (int timer_id); - - // Cancel a timer. - // Returns 0 on success and -1 on error. - int cancel (int timer_id); - - // Returns the time in millisecond until the next timer. - // Returns -1 if no timer is due. - long timeout (); - - // Execute timers. - // Return 0 if all succeed and -1 if error. - int execute (); - - // Return false if object is not a timers class. - bool check_tag (); - - private: - - // Used to check whether the object is a timers class. - uint32_t tag; - - int next_timer_id; - - // Clock instance. - clock_t clock; - - typedef struct timer_t { - int timer_id; - size_t interval; - timers_timer_fn *handler; - void *arg; - } timer_t; - - typedef std::multimap timersmap_t; - timersmap_t timers; - - typedef std::set cancelled_timers_t; - cancelled_timers_t cancelled_timers; - - timers_t (const timers_t&); - const timers_t &operator = (const timers_t&); - - struct match_by_id; - }; - } - - #endif diff --git a/dep/libzmq/src/tipc_address.cpp b/dep/libzmq/src/tipc_address.cpp deleted file mode 100644 index 8bbe10e5fa..0000000000 --- a/dep/libzmq/src/tipc_address.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include "tipc_address.hpp" - -#if defined ZMQ_HAVE_TIPC - -#include "err.hpp" - -#include -#include - -zmq::tipc_address_t::tipc_address_t () -{ - memset (&address, 0, sizeof address); -} - -zmq::tipc_address_t::tipc_address_t (const sockaddr *sa, socklen_t sa_len) -{ - zmq_assert (sa && sa_len > 0); - - memset (&address, 0, sizeof address); - if (sa->sa_family == AF_TIPC) - memcpy (&address, sa, sa_len); -} - -zmq::tipc_address_t::~tipc_address_t () -{ -} - -int zmq::tipc_address_t::resolve (const char *name) -{ - unsigned int type = 0; - unsigned int lower = 0; - unsigned int upper = 0; - unsigned int z = 1, c = 0, n = 0; - char eof; - const char *domain; - const int res = sscanf (name, "{%u,%u,%u}", &type, &lower, &upper); - - /* Fetch optional domain suffix. */ - if ((domain = strchr(name, '@'))) { - if (sscanf(domain, "@%u.%u.%u%c", &z, &c, &n, &eof) != 3) - return EINVAL; - } - if (res == 3) - goto nameseq; - else - if (res == 2 && type > TIPC_RESERVED_TYPES) { - address.family = AF_TIPC; - address.addrtype = TIPC_ADDR_NAME; - address.addr.name.name.type = type; - address.addr.name.name.instance = lower; - address.addr.name.domain = tipc_addr (z, c, n); - address.scope = 0; - return 0; - } - else - return EINVAL; -nameseq: - if (type < TIPC_RESERVED_TYPES || upper < lower) - return EINVAL; - address.family = AF_TIPC; - address.addrtype = TIPC_ADDR_NAMESEQ; - address.addr.nameseq.type = type; - address.addr.nameseq.lower = lower; - address.addr.nameseq.upper = upper; - address.scope = TIPC_ZONE_SCOPE; - return 0; -} - -int zmq::tipc_address_t::to_string (std::string &addr_) -{ - if (address.family != AF_TIPC) { - addr_.clear (); - return -1; - } - std::stringstream s; - s << "tipc://" << "{" << address.addr.nameseq.type; - s << ", " << address.addr.nameseq.lower; - s << ", " << address.addr.nameseq.upper << "}"; - addr_ = s.str (); - return 0; -} - -const sockaddr *zmq::tipc_address_t::addr () const -{ - return (sockaddr*) &address; -} - -socklen_t zmq::tipc_address_t::addrlen () const -{ - return (socklen_t) sizeof address; -} - -#endif diff --git a/dep/libzmq/src/tipc_address.hpp b/dep/libzmq/src/tipc_address.hpp deleted file mode 100644 index 4a379b00ef..0000000000 --- a/dep/libzmq/src/tipc_address.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_TIPC_ADDRESS_HPP_INCLUDED__ -#define __ZMQ_TIPC_ADDRESS_HPP_INCLUDED__ - -#include - -#include "platform.hpp" - -#if defined ZMQ_HAVE_TIPC - -#include -#include - -namespace zmq -{ - - class tipc_address_t - { - public: - - tipc_address_t (); - tipc_address_t (const sockaddr *sa, socklen_t sa_len); - ~tipc_address_t (); - - // This function sets up the address "{type, lower, upper}" for TIPC transport - int resolve (const char *name); - - // The opposite to resolve() - int to_string (std::string &addr_); - - const sockaddr *addr () const; - socklen_t addrlen () const; - - private: - - struct sockaddr_tipc address; - - tipc_address_t (const tipc_address_t&); - const tipc_address_t &operator = (const tipc_address_t&); - }; - -} - -#endif - -#endif - diff --git a/dep/libzmq/src/tipc_connecter.hpp b/dep/libzmq/src/tipc_connecter.hpp deleted file mode 100644 index 867c10ff29..0000000000 --- a/dep/libzmq/src/tipc_connecter.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __TIPC_CONNECTER_HPP_INCLUDED__ -#define __TIPC_CONNECTER_HPP_INCLUDED__ - -#include "platform.hpp" - -#if defined ZMQ_HAVE_TIPC - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - struct address_t; - - class tipc_connecter_t : public own_t, public io_object_t - { - public: - - // If 'delayed_start' is true connecter first waits for a while, - // then starts connection process. - tipc_connecter_t (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_, const options_t &options_, - const address_t *addr_, bool delayed_start_); - ~tipc_connecter_t (); - - private: - - // ID of the timer used to delay the reconnection. - enum {reconnect_timer_id = 1}; - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - void out_event (); - void timer_event (int id_); - - // Internal function to start the actual connection establishment. - void start_connecting (); - - // Internal function to add a reconnect timer - void add_reconnect_timer(); - - // Close the connecting socket. - void close (); - - // Get the file descriptor of newly created connection. Returns - // retired_fd if the connection was unsuccessful. - fd_t connect (); - - // Address to connect to. Owned by session_base_t. - const address_t *addr; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // If true file descriptor is registered with the poller and 'handle' - // contains valid value. - bool handle_valid; - - // If true, connecter is waiting a while before trying to connect. - const bool delayed_start; - - // True iff a timer has been started. - bool timer_started; - - // Reference to the session we belong to. - zmq::session_base_t *session; - - // Current reconnect ivl, updated for backoff strategy - int current_reconnect_ivl; - - // String representation of endpoint to connect to - std::string endpoint; - - // Socket - zmq::socket_base_t *socket; - - // Internal function to return a reconnect backoff delay. - // Will modify the current_reconnect_ivl used for next call - // Returns the currently used interval - int get_new_reconnect_ivl (); - - // Open IPC connecting socket. Returns -1 in case of error, - // 0 if connect was successful immediately. Returns -1 with - // EAGAIN errno if async connect was launched. - int open (); - - tipc_connecter_t (const tipc_connecter_t&); - const tipc_connecter_t &operator = (const tipc_connecter_t&); - }; - -} - -#endif - -#endif - diff --git a/dep/libzmq/src/tipc_listener.hpp b/dep/libzmq/src/tipc_listener.hpp deleted file mode 100644 index 73f3aa8564..0000000000 --- a/dep/libzmq/src/tipc_listener.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_TIPC_LISTENER_HPP_INCLUDED__ -#define __ZMQ_TIPC_LISTENER_HPP_INCLUDED__ - -#include "platform.hpp" - -#if defined ZMQ_HAVE_TIPC - -#include - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" -#include "tipc_address.hpp" - -namespace zmq -{ - - class io_thread_t; - class socket_base_t; - - class tipc_listener_t : public own_t, public io_object_t - { - public: - - tipc_listener_t (zmq::io_thread_t *io_thread_, - zmq::socket_base_t *socket_, const options_t &options_); - ~tipc_listener_t (); - - // Set address to listen on. - int set_address (const char *addr_); - - // Get the bound address for use with wildcards - int get_address (std::string &addr_); - - private: - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - - // Close the listening socket. - void close (); - - // Accept the new connection. Returns the file descriptor of the - // newly created connection. The function may return retired_fd - // if the connection was dropped while waiting in the listen backlog. - fd_t accept (); - - // Address to listen on - tipc_address_t address; - - // Underlying socket. - fd_t s; - - - // Handle corresponding to the listening socket. - handle_t handle; - - // Socket the listener belongs to. - zmq::socket_base_t *socket; - - // String representation of endpoint to bind to - std::string endpoint; - - tipc_listener_t (const tipc_listener_t&); - const tipc_listener_t &operator = (const tipc_listener_t&); - }; - -} - -#endif - -#endif - diff --git a/dep/libzmq/src/trie.cpp b/dep/libzmq/src/trie.cpp deleted file mode 100644 index 4e646731ca..0000000000 --- a/dep/libzmq/src/trie.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "macros.hpp" -#include "err.hpp" -#include "trie.hpp" - -#include - -#include -#include - -zmq::trie_t::trie_t () : - refcnt (0), - min (0), - count (0), - live_nodes (0) -{ -} - -zmq::trie_t::~trie_t () -{ - if (count == 1) { - zmq_assert (next.node); - LIBZMQ_DELETE(next.node); - } - else if (count > 1) { - for (unsigned short i = 0; i != count; ++i) { - LIBZMQ_DELETE(next.table[i]); - } - free (next.table); - } -} - -bool zmq::trie_t::add (unsigned char *prefix_, size_t size_) -{ - // We are at the node corresponding to the prefix. We are done. - if (!size_) { - ++refcnt; - return refcnt == 1; - } - - unsigned char c = *prefix_; - if (c < min || c >= min + count) { - - // The character is out of range of currently handled - // characters. We have to extend the table. - if (!count) { - min = c; - count = 1; - next.node = NULL; - } - else - if (count == 1) { - unsigned char oldc = min; - trie_t *oldp = next.node; - count = (min < c ? c - min : min - c) + 1; - next.table = (trie_t**) - malloc (sizeof (trie_t*) * count); - alloc_assert (next.table); - for (unsigned short i = 0; i != count; ++i) - next.table [i] = 0; - min = std::min (min, c); - next.table [oldc - min] = oldp; - } - else - if (min < c) { - // The new character is above the current character range. - unsigned short old_count = count; - count = c - min + 1; - next.table = (trie_t**) realloc ((void*) next.table, - sizeof (trie_t*) * count); - zmq_assert (next.table); - for (unsigned short i = old_count; i != count; i++) - next.table [i] = NULL; - } - else { - - // The new character is below the current character range. - unsigned short old_count = count; - count = (min + old_count) - c; - next.table = (trie_t**) realloc ((void*) next.table, - sizeof (trie_t*) * count); - zmq_assert (next.table); - memmove (next.table + min - c, next.table, - old_count * sizeof (trie_t*)); - for (unsigned short i = 0; i != min - c; i++) - next.table [i] = NULL; - min = c; - } - } - - // If next node does not exist, create one. - if (count == 1) { - if (!next.node) { - next.node = new (std::nothrow) trie_t; - alloc_assert (next.node); - ++live_nodes; - zmq_assert (live_nodes == 1); - } - return next.node->add (prefix_ + 1, size_ - 1); - } - else { - if (!next.table [c - min]) { - next.table [c - min] = new (std::nothrow) trie_t; - alloc_assert (next.table [c - min]); - ++live_nodes; - zmq_assert (live_nodes > 1); - } - return next.table [c - min]->add (prefix_ + 1, size_ - 1); - } -} - -bool zmq::trie_t::rm (unsigned char *prefix_, size_t size_) -{ - // TODO: Shouldn't an error be reported if the key does not exist? - if (!size_) { - if (!refcnt) - return false; - refcnt--; - return refcnt == 0; - } - unsigned char c = *prefix_; - if (!count || c < min || c >= min + count) - return false; - - trie_t *next_node = - count == 1 ? next.node : next.table [c - min]; - - if (!next_node) - return false; - - bool ret = next_node->rm (prefix_ + 1, size_ - 1); - - // Prune redundant nodes - if (next_node->is_redundant ()) { - LIBZMQ_DELETE(next_node); - zmq_assert (count > 0); - - if (count == 1) { - // The just pruned node is was the only live node - next.node = 0; - count = 0; - --live_nodes; - zmq_assert (live_nodes == 0); - } - else { - next.table [c - min] = 0; - zmq_assert (live_nodes > 1); - --live_nodes; - - // Compact the table if possible - if (live_nodes == 1) { - // We can switch to using the more compact single-node - // representation since the table only contains one live node - trie_t *node = 0; - // Since we always compact the table the pruned node must - // either be the left-most or right-most ptr in the node - // table - if (c == min) { - // The pruned node is the left-most node ptr in the - // node table => keep the right-most node - node = next.table [count - 1]; - min += count - 1; - } - else - if (c == min + count - 1) { - // The pruned node is the right-most node ptr in the - // node table => keep the left-most node - node = next.table [0]; - } - zmq_assert (node); - free (next.table); - next.node = node; - count = 1; - } - else - if (c == min) { - // We can compact the table "from the left". - // Find the left-most non-null node ptr, which we'll use as - // our new min - unsigned char new_min = min; - for (unsigned short i = 1; i < count; ++i) { - if (next.table [i]) { - new_min = i + min; - break; - } - } - zmq_assert (new_min != min); - - trie_t **old_table = next.table; - zmq_assert (new_min > min); - zmq_assert (count > new_min - min); - - count = count - (new_min - min); - next.table = (trie_t**) malloc (sizeof (trie_t*) * count); - alloc_assert (next.table); - - memmove (next.table, old_table + (new_min - min), - sizeof (trie_t*) * count); - free (old_table); - - min = new_min; - } - else - if (c == min + count - 1) { - // We can compact the table "from the right". - // Find the right-most non-null node ptr, which we'll use to - // determine the new table size - unsigned short new_count = count; - for (unsigned short i = 1; i < count; ++i) { - if (next.table [count - 1 - i]) { - new_count = count - i; - break; - } - } - zmq_assert (new_count != count); - count = new_count; - - trie_t **old_table = next.table; - next.table = (trie_t**) malloc (sizeof (trie_t*) * count); - alloc_assert (next.table); - - memmove (next.table, old_table, sizeof (trie_t*) * count); - free (old_table); - } - } - } - return ret; -} - -bool zmq::trie_t::check (unsigned char *data_, size_t size_) -{ - // This function is on critical path. It deliberately doesn't use - // recursion to get a bit better performance. - trie_t *current = this; - while (true) { - - // We've found a corresponding subscription! - if (current->refcnt) - return true; - - // We've checked all the data and haven't found matching subscription. - if (!size_) - return false; - - // If there's no corresponding slot for the first character - // of the prefix, the message does not match. - unsigned char c = *data_; - if (c < current->min || c >= current->min + current->count) - return false; - - // Move to the next character. - if (current->count == 1) - current = current->next.node; - else { - current = current->next.table [c - current->min]; - if (!current) - return false; - } - data_++; - size_--; - } -} - -void zmq::trie_t::apply (void (*func_) (unsigned char *data_, size_t size_, - void *arg_), void *arg_) -{ - unsigned char *buff = NULL; - apply_helper (&buff, 0, 0, func_, arg_); - free (buff); -} - -void zmq::trie_t::apply_helper ( - unsigned char **buff_, size_t buffsize_, size_t maxbuffsize_, - void (*func_) (unsigned char *data_, size_t size_, void *arg_), void *arg_) -{ - // If this node is a subscription, apply the function. - if (refcnt) - func_ (*buff_, buffsize_, arg_); - - // Adjust the buffer. - if (buffsize_ >= maxbuffsize_) { - maxbuffsize_ = buffsize_ + 256; - *buff_ = (unsigned char*) realloc (*buff_, maxbuffsize_); - zmq_assert (*buff_); - } - - // If there are no subnodes in the trie, return. - if (count == 0) - return; - - // If there's one subnode (optimisation). - if (count == 1) { - (*buff_) [buffsize_] = min; - buffsize_++; - next.node->apply_helper (buff_, buffsize_, maxbuffsize_, func_, arg_); - return; - } - - // If there are multiple subnodes. - for (unsigned short c = 0; c != count; c++) { - (*buff_) [buffsize_] = min + c; - if (next.table [c]) - next.table [c]->apply_helper (buff_, buffsize_ + 1, maxbuffsize_, - func_, arg_); - } -} - -bool zmq::trie_t::is_redundant () const -{ - return refcnt == 0 && live_nodes == 0; -} diff --git a/dep/libzmq/src/trie.hpp b/dep/libzmq/src/trie.hpp deleted file mode 100644 index b3a1b3a46f..0000000000 --- a/dep/libzmq/src/trie.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_TRIE_HPP_INCLUDED__ -#define __ZMQ_TRIE_HPP_INCLUDED__ - -#include - -#include "stdint.hpp" - -namespace zmq -{ - - class trie_t - { - public: - - trie_t (); - ~trie_t (); - - // Add key to the trie. Returns true if this is a new item in the trie - // rather than a duplicate. - bool add (unsigned char *prefix_, size_t size_); - - // Remove key from the trie. Returns true if the item is actually - // removed from the trie. - bool rm (unsigned char *prefix_, size_t size_); - - // Check whether particular key is in the trie. - bool check (unsigned char *data_, size_t size_); - - // Apply the function supplied to each subscription in the trie. - void apply (void (*func_) (unsigned char *data_, size_t size_, - void *arg_), void *arg_); - - private: - - void apply_helper ( - unsigned char **buff_, size_t buffsize_, size_t maxbuffsize_, - void (*func_) (unsigned char *data_, size_t size_, void *arg_), - void *arg_); - bool is_redundant () const; - - uint32_t refcnt; - unsigned char min; - unsigned short count; - unsigned short live_nodes; - union { - class trie_t *node; - class trie_t **table; - } next; - - trie_t (const trie_t&); - const trie_t &operator = (const trie_t&); - }; - -} - -#endif - diff --git a/dep/libzmq/src/tweetnacl.c b/dep/libzmq/src/tweetnacl.c deleted file mode 100644 index e081cd874c..0000000000 --- a/dep/libzmq/src/tweetnacl.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - Copyright (c) 2016-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/* - The precompiled header is not used for c files so this is required here. -*/ -#include "platform.hpp" - -#if defined (ZMQ_USE_TWEETNACL) - -/* - Disable warnings for this source only, rather than for the whole - codebase when building with C99 (gcc >= 4.2) or with Microsoft's compiler -*/ -#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) && __STDC_VERSION__ < 201112L -# pragma GCC diagnostic ignored "-Wsign-compare" -#elif defined _MSC_VER -# pragma warning (disable:4018 4244 4146) -#endif - -#include "tweetnacl.h" - -#define FOR(i,n) for (i = 0;i < n;++i) -#define sv static void - -static const u8 - _0[16], - _9[32] = {9}; -static const gf - gf0, - gf1 = {1}, - _121665 = {0xDB41,1}, - D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203}, - D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406}, - X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169}, - Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666}, - I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; - -static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); } - -static u32 ld32(const u8 *x) -{ - u32 u = x[3]; - u = (u<<8)|x[2]; - u = (u<<8)|x[1]; - return (u<<8)|x[0]; -} - -static u64 dl64(const u8 *x) -{ - u64 i,u=0; - FOR(i,8) u=(u<<8)|x[i]; - return u; -} - -sv st32(u8 *x,u32 u) -{ - int i; - FOR(i,4) { x[i] = u; u >>= 8; } -} - -sv ts64(u8 *x,u64 u) -{ - int i; - for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; } -} - -static int vn(const u8 *x,const u8 *y,int n) -{ - u32 i,d = 0; - FOR(i,n) d |= x[i]^y[i]; - return (1 & ((d - 1) >> 8)) - 1; -} - -int crypto_verify_16(const u8 *x,const u8 *y) -{ - return vn(x,y,16); -} - -int crypto_verify_32(const u8 *x,const u8 *y) -{ - return vn(x,y,32); -} - -sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h) -{ - u32 w[16],x[16],y[16],t[4]; - int i,j,m; - - FOR(i,4) { - x[5*i] = ld32(c+4*i); - x[1+i] = ld32(k+4*i); - x[6+i] = ld32(in+4*i); - x[11+i] = ld32(k+16+4*i); - } - - FOR(i,16) y[i] = x[i]; - - FOR(i,20) { - FOR(j,4) { - FOR(m,4) t[m] = x[(5*j+4*m)%16]; - t[1] ^= L32(t[0]+t[3], 7); - t[2] ^= L32(t[1]+t[0], 9); - t[3] ^= L32(t[2]+t[1],13); - t[0] ^= L32(t[3]+t[2],18); - FOR(m,4) w[4*j+(j+m)%4] = t[m]; - } - FOR(m,16) x[m] = w[m]; - } - - if (h) { - FOR(i,16) x[i] += y[i]; - FOR(i,4) { - x[5*i] -= ld32(c+4*i); - x[6+i] -= ld32(in+4*i); - } - FOR(i,4) { - st32(out+4*i,x[5*i]); - st32(out+16+4*i,x[6+i]); - } - } else - FOR(i,16) st32(out + 4 * i,x[i] + y[i]); -} - -int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) -{ - core(out,in,k,c,0); - return 0; -} - -int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) -{ - core(out,in,k,c,1); - return 0; -} - -static const u8 sigma[16] = "expand 32-byte k"; - -int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k) -{ - u8 z[16],x[64]; - u32 u,i; - if (!b) return 0; - FOR(i,16) z[i] = 0; - FOR(i,8) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - FOR(i,64) c[i] = (m?m[i]:0) ^ x[i]; - u = 1; - for (i = 8;i < 16;++i) { - u += (u32) z[i]; - z[i] = u; - u >>= 8; - } - b -= 64; - c += 64; - if (m) m += 64; - } - if (b) { - crypto_core_salsa20(x,z,k,sigma); - FOR(i,b) c[i] = (m?m[i]:0) ^ x[i]; - } - return 0; -} - -int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k) -{ - return crypto_stream_salsa20_xor(c,0,d,n,k); -} - -int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k) -{ - u8 s[32]; - crypto_core_hsalsa20(s,n,k,sigma); - return crypto_stream_salsa20(c,d,n+16,s); -} - -int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) -{ - u8 s[32]; - crypto_core_hsalsa20(s,n,k,sigma); - return crypto_stream_salsa20_xor(c,m,d,n+16,s); -} - -sv add1305(u32 *h,const u32 *c) -{ - u32 j,u = 0; - FOR(j,17) { - u += h[j] + c[j]; - h[j] = u & 255; - u >>= 8; - } -} - -static const u32 minusp[17] = { - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 -} ; - -int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k) -{ - u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17]; - - FOR(j,17) r[j]=h[j]=0; - FOR(j,16) r[j]=k[j]; - r[3]&=15; - r[4]&=252; - r[7]&=15; - r[8]&=252; - r[11]&=15; - r[12]&=252; - r[15]&=15; - - while (n > 0) { - FOR(j,17) c[j] = 0; - for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j]; - c[j] = 1; - m += j; n -= j; - add1305(h,c); - FOR(i,17) { - x[i] = 0; - FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); - } - FOR(i,17) h[i] = x[i]; - u = 0; - FOR(j,16) { - u += h[j]; - h[j] = u & 255; - u >>= 8; - } - u += h[16]; h[16] = u & 3; - u = 5 * (u >> 2); - FOR(j,16) { - u += h[j]; - h[j] = u & 255; - u >>= 8; - } - u += h[16]; h[16] = u; - } - - FOR(j,17) g[j] = h[j]; - add1305(h,minusp); - s = -(h[16] >> 7); - FOR(j,17) h[j] ^= s & (g[j] ^ h[j]); - - FOR(j,16) c[j] = k[j + 16]; - c[16] = 0; - add1305(h,c); - FOR(j,16) out[j] = h[j]; - return 0; -} - -int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k) -{ - u8 x[16]; - crypto_onetimeauth(x,m,n,k); - return crypto_verify_16(h,x); -} - -int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) -{ - int i; - if (d < 32) return -1; - crypto_stream_xor(c,m,d,n,k); - crypto_onetimeauth(c + 16,c + 32,d - 32,c); - FOR(i,16) c[i] = 0; - return 0; -} - -int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) -{ - int i; - u8 x[32]; - if (d < 32) return -1; - crypto_stream(x,32,n,k); - if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1; - crypto_stream_xor(m,c,d,n,k); - FOR(i,32) m[i] = 0; - return 0; -} - -sv set25519(gf r, const gf a) -{ - int i; - FOR(i,16) r[i]=a[i]; -} - -sv car25519(gf o) -{ - int i; - i64 c; - FOR(i,16) { - o[i]+=(1LL<<16); - c=o[i]>>16; - o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15); - o[i]-=c<<16; - } -} - -sv sel25519(gf p,gf q,int b) -{ - i64 t,i,c=~(b-1); - FOR(i,16) { - t= c&(p[i]^q[i]); - p[i]^=t; - q[i]^=t; - } -} - -sv pack25519(u8 *o,const gf n) -{ - int i,j,b; - gf m,t; - FOR(i,16) t[i]=n[i]; - car25519(t); - car25519(t); - car25519(t); - FOR(j,2) { - m[0]=t[0]-0xffed; - for(i=1;i<15;i++) { - m[i]=t[i]-0xffff-((m[i-1]>>16)&1); - m[i-1]&=0xffff; - } - m[15]=t[15]-0x7fff-((m[14]>>16)&1); - b=(m[15]>>16)&1; - m[14]&=0xffff; - sel25519(t,m,1-b); - } - FOR(i,16) { - o[2*i]=t[i]&0xff; - o[2*i+1]=t[i]>>8; - } -} - -static int neq25519(const gf a, const gf b) -{ - u8 c[32],d[32]; - pack25519(c,a); - pack25519(d,b); - return crypto_verify_32(c,d); -} - -static u8 par25519(const gf a) -{ - u8 d[32]; - pack25519(d,a); - return d[0]&1; -} - -sv unpack25519(gf o, const u8 *n) -{ - int i; - FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8); - o[15]&=0x7fff; -} - -sv A(gf o,const gf a,const gf b) -{ - int i; - FOR(i,16) o[i]=a[i]+b[i]; -} - -sv Z(gf o,const gf a,const gf b) -{ - int i; - FOR(i,16) o[i]=a[i]-b[i]; -} - -sv M(gf o,const gf a,const gf b) -{ - i64 i,j,t[31]; - FOR(i,31) t[i]=0; - FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j]; - FOR(i,15) t[i]+=38*t[i+16]; - FOR(i,16) o[i]=t[i]; - car25519(o); - car25519(o); -} - -sv S(gf o,const gf a) -{ - M(o,a,a); -} - -sv inv25519(gf o,const gf i) -{ - gf c; - int a; - FOR(a,16) c[a]=i[a]; - for(a=253;a>=0;a--) { - S(c,c); - if(a!=2&&a!=4) M(c,c,i); - } - FOR(a,16) o[a]=c[a]; -} - -sv pow2523(gf o,const gf i) -{ - gf c; - int a; - FOR(a,16) c[a]=i[a]; - for(a=250;a>=0;a--) { - S(c,c); - if(a!=1) M(c,c,i); - } - FOR(a,16) o[a]=c[a]; -} - -int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p) -{ - u8 z[32]; - i64 x[80],r,i; - gf a,b,c,d,e,f; - FOR(i,31) z[i]=n[i]; - z[31]=(n[31]&127)|64; - z[0]&=248; - unpack25519(x,p); - FOR(i,16) { - b[i]=x[i]; - d[i]=a[i]=c[i]=0; - } - a[0]=d[0]=1; - for(i=254;i>=0;--i) { - r=(z[i>>3]>>(i&7))&1; - sel25519(a,b,r); - sel25519(c,d,r); - A(e,a,c); - Z(a,a,c); - A(c,b,d); - Z(b,b,d); - S(d,e); - S(f,a); - M(a,c,a); - M(c,b,e); - A(e,a,c); - Z(a,a,c); - S(b,a); - Z(c,d,f); - M(a,c,_121665); - A(a,a,d); - M(c,c,a); - M(a,d,f); - M(d,b,x); - S(b,e); - sel25519(a,b,r); - sel25519(c,d,r); - } - FOR(i,16) { - x[i+16]=a[i]; - x[i+32]=c[i]; - x[i+48]=b[i]; - x[i+64]=d[i]; - } - inv25519(x+32,x+32); - M(x+16,x+16,x+32); - pack25519(q,x+16); - return 0; -} - -int crypto_scalarmult_base(u8 *q,const u8 *n) -{ - return crypto_scalarmult(q,n,_9); -} - -int crypto_box_keypair(u8 *y,u8 *x) -{ - randombytes(x,32); - return crypto_scalarmult_base(y,x); -} - -int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x) -{ - u8 s[32]; - crypto_scalarmult(s,x,y); - return crypto_core_hsalsa20(k,_0,s,sigma); -} - -int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) -{ - return crypto_secretbox(c,m,d,n,k); -} - -int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) -{ - return crypto_secretbox_open(m,c,d,n,k); -} - -int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x) -{ - u8 k[32]; - crypto_box_beforenm(k,y,x); - return crypto_box_afternm(c,m,d,n,k); -} - -int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x) -{ - u8 k[32]; - crypto_box_beforenm(k,y,x); - return crypto_box_open_afternm(m,c,d,n,k); -} - -static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); } -static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); } -static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); } -static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); } -static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); } -static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } -static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } - -static const u64 K[80] = -{ - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -int crypto_hashblocks(u8 *x,const u8 *m,u64 n) -{ - u64 z[8],b[8],a[8],w[16],t; - int i,j; - - FOR(i,8) z[i] = a[i] = dl64(x + 8 * i); - - while (n >= 128) { - FOR(i,16) w[i] = dl64(m + 8 * i); - - FOR(i,80) { - FOR(j,8) b[j] = a[j]; - t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16]; - b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]); - b[3] += t; - FOR(j,8) a[(j+1)%8] = b[j]; - if (i%16 == 15) - FOR(j,16) - w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]); - } - - FOR(i,8) { a[i] += z[i]; z[i] = a[i]; } - - m += 128; - n -= 128; - } - - FOR(i,8) ts64(x+8*i,z[i]); - - return n; -} - -static const u8 iv[64] = { - 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, - 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, - 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, - 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, - 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, - 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, - 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, - 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 -} ; - -int crypto_hash(u8 *out,const u8 *m,u64 n) -{ - u8 h[64],x[256]; - u64 i,b = n; - - FOR(i,64) h[i] = iv[i]; - - crypto_hashblocks(h,m,n); - m += n; - n &= 127; - m -= n; - - FOR(i,256) x[i] = 0; - FOR(i,n) x[i] = m[i]; - x[n] = 128; - - n = 256-128*(n<112); - x[n-9] = b >> 61; - ts64(x+n-8,b<<3); - crypto_hashblocks(h,x,n); - - FOR(i,64) out[i] = h[i]; - - return 0; -} - -sv add(gf p[4],gf q[4]) -{ - gf a,b,c,d,t,e,f,g,h; - - Z(a, p[1], p[0]); - Z(t, q[1], q[0]); - M(a, a, t); - A(b, p[0], p[1]); - A(t, q[0], q[1]); - M(b, b, t); - M(c, p[3], q[3]); - M(c, c, D2); - M(d, p[2], q[2]); - A(d, d, d); - Z(e, b, a); - Z(f, d, c); - A(g, d, c); - A(h, b, a); - - M(p[0], e, f); - M(p[1], h, g); - M(p[2], g, f); - M(p[3], e, h); -} - -sv cswap(gf p[4],gf q[4],u8 b) -{ - int i; - FOR(i,4) - sel25519(p[i],q[i],b); -} - -sv pack(u8 *r,gf p[4]) -{ - gf tx, ty, zi; - inv25519(zi, p[2]); - M(tx, p[0], zi); - M(ty, p[1], zi); - pack25519(r, ty); - r[31] ^= par25519(tx) << 7; -} - -sv scalarmult(gf p[4],gf q[4],const u8 *s) -{ - int i; - set25519(p[0],gf0); - set25519(p[1],gf1); - set25519(p[2],gf1); - set25519(p[3],gf0); - for (i = 255;i >= 0;--i) { - u8 b = (s[i/8]>>(i&7))&1; - cswap(p,q,b); - add(q,p); - add(p,p); - cswap(p,q,b); - } -} - -sv scalarbase(gf p[4],const u8 *s) -{ - gf q[4]; - set25519(q[0],X); - set25519(q[1],Y); - set25519(q[2],gf1); - M(q[3],X,Y); - scalarmult(p,q,s); -} - -int crypto_sign_keypair(u8 *pk, u8 *sk) -{ - u8 d[64]; - gf p[4]; - int i; - - randombytes(sk, 32); - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - scalarbase(p,d); - pack(pk,p); - - FOR(i,32) sk[32 + i] = pk[i]; - return 0; -} - -static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; - -sv modL(u8 *r,i64 x[64]) -{ - i64 carry,i,j; - for (i = 63;i >= 32;--i) { - carry = 0; - for (j = i - 32;j < i - 12;++j) { - x[j] += carry - 16 * x[i] * L[j - (i - 32)]; - carry = (x[j] + 128) >> 8; - x[j] -= carry << 8; - } - x[j] += carry; - x[i] = 0; - } - carry = 0; - FOR(j,32) { - x[j] += carry - (x[31] >> 4) * L[j]; - carry = x[j] >> 8; - x[j] &= 255; - } - FOR(j,32) x[j] -= carry * L[j]; - FOR(i,32) { - x[i+1] += x[i] >> 8; - r[i] = x[i] & 255; - } -} - -sv reduce(u8 *r) -{ - i64 x[64],i; - FOR(i,64) x[i] = (u64) r[i]; - FOR(i,64) r[i] = 0; - modL(r,x); -} - -int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk) -{ - u8 d[64],h[64],r[64]; - i64 i,j,x[64]; - gf p[4]; - - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - *smlen = n+64; - FOR(i,n) sm[64 + i] = m[i]; - FOR(i,32) sm[32 + i] = d[32 + i]; - - crypto_hash(r, sm+32, n+32); - reduce(r); - scalarbase(p,r); - pack(sm,p); - - FOR(i,32) sm[i+32] = sk[i+32]; - crypto_hash(h,sm,n + 64); - reduce(h); - - FOR(i,64) x[i] = 0; - FOR(i,32) x[i] = (u64) r[i]; - FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j]; - modL(sm + 32,x); - - return 0; -} - -static int unpackneg(gf r[4],const u8 p[32]) -{ - gf t, chk, num, den, den2, den4, den6; - set25519(r[2],gf1); - unpack25519(r[1],p); - S(num,r[1]); - M(den,num,D); - Z(num,num,r[2]); - A(den,r[2],den); - - S(den2,den); - S(den4,den2); - M(den6,den4,den2); - M(t,den6,num); - M(t,t,den); - - pow2523(t,t); - M(t,t,num); - M(t,t,den); - M(t,t,den); - M(r[0],t,den); - - S(chk,r[0]); - M(chk,chk,den); - if (neq25519(chk, num)) M(r[0],r[0],I); - - S(chk,r[0]); - M(chk,chk,den); - if (neq25519(chk, num)) return -1; - - if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]); - - M(r[3],r[0],r[1]); - return 0; -} - -int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk) -{ - int i; - u8 t[32],h[64]; - gf p[4],q[4]; - - *mlen = -1; - if (n < 64) return -1; - - if (unpackneg(q,pk)) return -1; - - FOR(i,n) m[i] = sm[i]; - FOR(i,32) m[i+32] = pk[i]; - crypto_hash(h,m,n); - reduce(h); - scalarmult(p,q,h); - - scalarbase(q,sm + 32); - add(p,q); - pack(t,p); - - n -= 64; - if (crypto_verify_32(sm, t)) { - FOR(i,n) m[i] = 0; - return -1; - } - - FOR(i,n) m[i] = sm[i + 64]; - *mlen = n; - return 0; -} - - -#ifdef ZMQ_HAVE_WINDOWS - -#include -#include - -#define NCP ((HCRYPTPROV) 0) - -HCRYPTPROV hProvider = NCP; - -void randombytes(unsigned char *x,unsigned long long xlen) -{ - unsigned i; - BOOL ret; - - if (hProvider == NCP) { - for (;;) { - ret = CryptAcquireContext(&hProvider, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); - if (ret != FALSE) - break; - Sleep (1); - } - } - while (xlen > 0) { - if (xlen < 1048576) - i = (unsigned) xlen; - else - i = 1048576; - - ret = CryptGenRandom(hProvider, i, x); - if (ret == FALSE) { - Sleep(1); - continue; - } - x += i; - xlen -= i; - } -} - -int randombytes_close(void) -{ - int rc = -1; - if ((hProvider != NCP) && (CryptReleaseContext(hProvider, 0) != FALSE)) { - hProvider = NCP; - rc = 0; - } - return rc; -} - -int sodium_init (void) -{ - return 0; -} - -#else - -#include -#include - -#ifdef ZMQ_HAVE_GETRANDOM -#include -#else -#include -#include -#include - -static int fd = -1; -#endif - -void randombytes (unsigned char *x,unsigned long long xlen) -{ - int i; -#ifndef ZMQ_HAVE_GETRANDOM - // Require that random_open has already been called, to avoid - // race conditions. - assert (fd != -1); -#endif - while (xlen > 0) { - if (xlen < 1048576) - i = xlen; - else - i = 1048576; - -#ifdef ZMQ_HAVE_GETRANDOM - i = getrandom (x, i, 0); -#else - i = read(fd,x,i); -#endif - if (i < 1) { - sleep (1); - continue; - } - x += i; - xlen -= i; - } -} - -// Do not call manually! Use random_close from random.hpp -int randombytes_close (void) -{ - int rc = -1; -#ifndef ZMQ_HAVE_GETRANDOM - if (fd != -1 && close(fd) == 0) { - fd = -1; - rc = 0; - } -#endif // ZMQ_HAVE_GETRANDOM - return rc; -} - -// Do not call manually! Use random_open from random.hpp -int sodium_init (void) -{ -#ifndef ZMQ_HAVE_GETRANDOM - if (fd == -1) { - for (;;) { - int flags = O_RDONLY; -#ifdef ZMQ_HAVE_O_CLOEXEC - flags |= O_CLOEXEC; -#endif - fd = open ("/dev/urandom", flags); - if (fd != -1) - break; - sleep (1); - } -#if !defined ZMQ_HAVE_O_CLOEXEC && defined FD_CLOEXEC - int rc = fcntl (fd, F_SETFD, FD_CLOEXEC); - assert (rc != -1); -#endif - } -#endif // ZMQ_HAVE_GETRANDOM - return 0; -} - -#endif - -#endif diff --git a/dep/libzmq/src/tweetnacl.h b/dep/libzmq/src/tweetnacl.h deleted file mode 100644 index 95f8b2a58c..0000000000 --- a/dep/libzmq/src/tweetnacl.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (c) 2016-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef TWEETNACL_H -#define TWEETNACL_H - -#if defined (ZMQ_USE_TWEETNACL) - -#define crypto_box_SECRETKEYBYTES 32 -#define crypto_box_BOXZEROBYTES 16 -#define crypto_box_NONCEBYTES 24 -#define crypto_box_ZEROBYTES 32 -#define crypto_box_PUBLICKEYBYTES 32 -#define crypto_box_BEFORENMBYTES 32 -#define crypto_secretbox_KEYBYTES 32 -#define crypto_secretbox_NONCEBYTES 24 -#define crypto_secretbox_ZEROBYTES 32 -#define crypto_secretbox_BOXZEROBYTES 16 -typedef unsigned char u8; -typedef unsigned long u32; -typedef unsigned long long u64; -typedef long long i64; -typedef i64 gf[16]; - -#ifdef __cplusplus -extern "C" { -#endif -void randombytes (unsigned char *, unsigned long long); -// Do not call manually! Use random_close from random.hpp -int randombytes_close (void); -// Do not call manually! Use random_open from random.hpp -int sodium_init (void); - -int crypto_box_keypair(u8 *y,u8 *x); -int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k); -int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k); -int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x); -int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x); -int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x); -int crypto_scalarmult_base(u8 *q,const u8 *n); -int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k); -int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k); -#ifdef __cplusplus -} -#endif - -#endif - -#endif diff --git a/dep/libzmq/src/udp_address.cpp b/dep/libzmq/src/udp_address.cpp deleted file mode 100644 index 6c2c50f86e..0000000000 --- a/dep/libzmq/src/udp_address.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include - -#include "macros.hpp" -#include "udp_address.hpp" -#include "stdint.hpp" -#include "err.hpp" -#include "ip.hpp" - -#ifndef ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#endif - -zmq::udp_address_t::udp_address_t () - : is_multicast(false) -{ - memset (&bind_address, 0, sizeof bind_address); - memset (&dest_address, 0, sizeof dest_address); -} - -zmq::udp_address_t::~udp_address_t () -{ -} - -int zmq::udp_address_t::resolve (const char *name_, bool bind_) -{ - // Find the ':' at end that separates address from the port number. - const char *delimiter = strrchr (name_, ':'); - if (!delimiter) { - errno = EINVAL; - return -1; - } - - // Separate the address/port. - std::string addr_str (name_, delimiter - name_); - std::string port_str (delimiter + 1); - - // Parse the port number (0 is not a valid port). - uint16_t port = (uint16_t) atoi (port_str.c_str ()); - if (port == 0) { - errno = EINVAL; - return -1; - } - - dest_address.sin_family = AF_INET; - dest_address.sin_port = htons (port); - - // Only when the udp should bind we allow * as the address - if (addr_str == "*" && bind_) - dest_address.sin_addr.s_addr = htonl (INADDR_ANY); - else - dest_address.sin_addr.s_addr = inet_addr (addr_str.c_str ()); - - if (dest_address.sin_addr.s_addr == INADDR_NONE) { - errno = EINVAL; - return -1; - } - - // we will check only first byte of IP - // and if it from 224 to 239, then it can - // represent multicast IP. - int i = dest_address.sin_addr.s_addr & 0xFF; - if(i >= 224 && i <= 239) { - multicast = dest_address.sin_addr; - is_multicast = true; - } - else - is_multicast = false; - - iface.s_addr = htonl (INADDR_ANY); - if (iface.s_addr == INADDR_NONE) { - errno = EINVAL; - return -1; - } - - // If a should bind and not a multicast, the dest address - // is actually the bind address - if (bind_ && !is_multicast) - bind_address = dest_address; - else { - bind_address.sin_family = AF_INET; - bind_address.sin_port = htons (port); - bind_address.sin_addr.s_addr = htonl (INADDR_ANY); - } - - address = name_; - - return 0; -} - -int zmq::udp_address_t::to_string (std::string &addr_) -{ - addr_ = address; - return 0; -} - -bool zmq::udp_address_t::is_mcast () const -{ - return is_multicast; -} - -const sockaddr* zmq::udp_address_t::bind_addr () const -{ - return (sockaddr *) &bind_address; -} - -socklen_t zmq::udp_address_t::bind_addrlen () const -{ - return sizeof (sockaddr_in); -} - -const sockaddr* zmq::udp_address_t::dest_addr () const -{ - return (sockaddr *) &dest_address; -} - -socklen_t zmq::udp_address_t::dest_addrlen () const -{ - return sizeof (sockaddr_in); -} - -const in_addr zmq::udp_address_t::multicast_ip () const -{ - return multicast; -} - -const in_addr zmq::udp_address_t::interface_ip () const -{ - return iface; -} - -#if defined ZMQ_HAVE_WINDOWS -unsigned short zmq::udp_address_t::family () const -#else -sa_family_t zmq::udp_address_t::family () const -#endif -{ - return AF_INET; -} diff --git a/dep/libzmq/src/udp_address.hpp b/dep/libzmq/src/udp_address.hpp deleted file mode 100644 index b3794186cc..0000000000 --- a/dep/libzmq/src/udp_address.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_UDP_ADDRESS_HPP_INCLUDED__ -#define __ZMQ_UDP_ADDRESS_HPP_INCLUDED__ - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#endif - -namespace zmq -{ - class udp_address_t - { - public: - - udp_address_t (); - virtual ~udp_address_t (); - - int resolve (const char *name_, bool receiver_); - - // The opposite to resolve() - virtual int to_string (std::string &addr_); - -#if defined ZMQ_HAVE_WINDOWS - unsigned short family () const; -#else - sa_family_t family () const; -#endif - const sockaddr *bind_addr () const; - socklen_t bind_addrlen () const; - - const sockaddr *dest_addr () const; - socklen_t dest_addrlen () const; - - bool is_mcast () const; - - const in_addr multicast_ip () const; - const in_addr interface_ip () const; - - private: - in_addr multicast; - in_addr iface; - sockaddr_in bind_address; - sockaddr_in dest_address; - bool is_multicast; - std::string address; - }; -} - -#endif diff --git a/dep/libzmq/src/udp_engine.cpp b/dep/libzmq/src/udp_engine.cpp deleted file mode 100644 index 00d51b1396..0000000000 --- a/dep/libzmq/src/udp_engine.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* -Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - -This file is part of libzmq, the ZeroMQ core engine in C++. - -libzmq is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License (LGPL) as published -by the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -As a special exception, the Contributors give you permission to link -this library with independent modules to produce an executable, -regardless of the license terms of these independent modules, and to -copy and distribute the resulting executable under terms of your choice, -provided that you also meet, for each linked independent module, the -terms and conditions of the license of that module. An independent -module is a module which is not derived from or based on this library. -If you modify this library, you must extend this exception to your -version of the library. - -libzmq is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#if !defined ZMQ_HAVE_WINDOWS -#include -#include -#include -#include -#include -#endif - -#include "udp_engine.hpp" -#include "session_base.hpp" -#include "v2_protocol.hpp" -#include "err.hpp" -#include "ip.hpp" - -zmq::udp_engine_t::udp_engine_t(const options_t &options_) : - plugged (false), - fd(-1), - session(NULL), - handle((handle_t)NULL), - address(NULL), - options(options_), - send_enabled(false), - recv_enabled(false) -{ -} - -zmq::udp_engine_t::~udp_engine_t() -{ - zmq_assert (!plugged); - - if (fd != retired_fd) { -#ifdef ZMQ_HAVE_WINDOWS - int rc = closesocket (fd); - wsa_assert (rc != SOCKET_ERROR); -#else - int rc = close (fd); - errno_assert (rc == 0); -#endif - fd = retired_fd; - } -} - -int zmq::udp_engine_t::init (address_t *address_, bool send_, bool recv_) -{ - zmq_assert (address_); - zmq_assert (send_ || recv_); - send_enabled = send_; - recv_enabled = recv_; - address = address_; - - fd = open_socket (address->resolved.udp_addr->family (), SOCK_DGRAM, IPPROTO_UDP); - if (fd == retired_fd) - return -1; - - unblock_socket (fd); - - return 0; -} - -void zmq::udp_engine_t::plug (io_thread_t* io_thread_, session_base_t *session_) -{ - zmq_assert (!plugged); - plugged = true; - - zmq_assert (!session); - zmq_assert (session_); - session = session_; - - // Connect to I/O threads poller object. - io_object_t::plug (io_thread_); - handle = add_fd (fd); - - // Bind the socket to a device if applicable - if (!options.bound_device.empty ()) - bind_to_device (fd, options.bound_device); - - if (send_enabled) { - if (!options.raw_socket) { - out_address = address->resolved.udp_addr->dest_addr (); - out_addrlen = address->resolved.udp_addr->dest_addrlen (); - } - else { - out_address = (sockaddr *) &raw_address; - out_addrlen = sizeof (sockaddr_in); - } - - set_pollout (handle); - } - - if (recv_enabled) { - int on = 1; - int rc = setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)); -#ifdef ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - errno_assert (rc == 0); -#endif - - rc = bind (fd, address->resolved.udp_addr->bind_addr (), - address->resolved.udp_addr->bind_addrlen ()); -#ifdef ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - errno_assert (rc == 0); -#endif - - if (address->resolved.udp_addr->is_mcast ()) { - struct ip_mreq mreq; - mreq.imr_multiaddr = address->resolved.udp_addr->multicast_ip (); - mreq.imr_interface = address->resolved.udp_addr->interface_ip (); - rc = setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof (mreq)); -#ifdef ZMQ_HAVE_WINDOWS - wsa_assert (rc != SOCKET_ERROR); -#else - errno_assert (rc == 0); -#endif - } - set_pollin (handle); - - // Call restart output to drop all join/leave commands - restart_output (); - } -} - -void zmq::udp_engine_t::terminate() -{ - zmq_assert (plugged); - plugged = false; - - rm_fd (handle); - - // Disconnect from I/O threads poller object. - io_object_t::unplug (); - - delete this; -} - -void zmq::udp_engine_t::sockaddr_to_msg (zmq::msg_t *msg, sockaddr_in* addr) -{ - char* name = inet_ntoa(addr->sin_addr); - - char port[6]; - sprintf (port, "%d", (int) ntohs (addr->sin_port)); - - int size = (int) strlen (name) + (int) strlen (port) + 1 + 1; // Colon + NULL - int rc = msg->init_size (size); - errno_assert (rc == 0); - msg->set_flags (msg_t::more); - char *address = (char*)msg->data (); - - strcpy (address, name); - strcat (address, ":"); - strcat (address, port); -} - -int zmq::udp_engine_t::resolve_raw_address (char *name_, size_t length_) -{ - memset (&raw_address, 0, sizeof raw_address); - - const char *delimiter = NULL; - - // Find delimiter, cannot use memrchr as it is not supported on windows - if (length_ != 0) { - int chars_left = (int) length_; - char *current_char = name_ + length_; - do { - if (*(--current_char) == ':') { - delimiter = current_char; - break; - } - } while (--chars_left != 0); - } - - if (!delimiter) { - errno = EINVAL; - return -1; - } - - std::string addr_str (name_, delimiter - name_); - std::string port_str (delimiter + 1, name_ + length_ - delimiter - 1); - - // Parse the port number (0 is not a valid port). - uint16_t port = (uint16_t) atoi (port_str.c_str ()); - if (port == 0) { - errno = EINVAL; - return -1; - } - - raw_address.sin_family = AF_INET; - raw_address.sin_port = htons (port); - raw_address.sin_addr.s_addr = inet_addr (addr_str.c_str ()); - - if (raw_address.sin_addr.s_addr == INADDR_NONE) { - errno = EINVAL; - return -1; - } - - return 0; -} - -void zmq::udp_engine_t::out_event() -{ - msg_t group_msg; - int rc = session->pull_msg (&group_msg); - errno_assert (rc == 0 || (rc == -1 && errno == EAGAIN)); - - if (rc == 0) { - msg_t body_msg; - rc = session->pull_msg (&body_msg); - - size_t group_size = group_msg.size (); - size_t body_size = body_msg.size (); - size_t size; - - if (options.raw_socket) { - rc = resolve_raw_address ((char*) group_msg.data(), group_size); - - // We discard the message if address is not valid - if (rc != 0) { - rc = group_msg.close (); - errno_assert (rc == 0); - - body_msg.close (); - errno_assert (rc == 0); - - return; - } - - size = body_size; - - memcpy (out_buffer, body_msg.data (), body_size); - } - else { - size = group_size + body_size + 1; - - // TODO: check if larger than maximum size - out_buffer[0] = (unsigned char) group_size; - memcpy (out_buffer + 1, group_msg.data (), group_size); - memcpy (out_buffer + 1 + group_size, body_msg.data (), body_size); - } - - rc = group_msg.close (); - errno_assert (rc == 0); - - body_msg.close (); - errno_assert (rc == 0); - -#ifdef ZMQ_HAVE_WINDOWS - rc = sendto (fd, (const char *) out_buffer, (int) size, 0, - out_address, (int) out_addrlen); - wsa_assert (rc != SOCKET_ERROR); -#else - rc = sendto (fd, out_buffer, size, 0, out_address, out_addrlen); - errno_assert (rc != -1); -#endif - } - else - reset_pollout (handle); -} - -const char *zmq::udp_engine_t::get_endpoint () const -{ - return ""; -} - -void zmq::udp_engine_t::restart_output() -{ - // If we don't support send we just drop all messages - if (!send_enabled) { - msg_t msg; - while (session->pull_msg (&msg) == 0) - msg.close (); - } - else { - set_pollout(handle); - out_event (); - } -} - -void zmq::udp_engine_t::in_event() -{ - struct sockaddr_in in_address; - socklen_t in_addrlen = sizeof(sockaddr_in); -#ifdef ZMQ_HAVE_WINDOWS - int nbytes = recvfrom(fd, (char*) in_buffer, MAX_UDP_MSG, 0, (sockaddr*) &in_address, &in_addrlen); - const int last_error = WSAGetLastError(); - if (nbytes == SOCKET_ERROR) { - wsa_assert( - last_error == WSAENETDOWN || - last_error == WSAENETRESET || - last_error == WSAEWOULDBLOCK); - return; - } -#else - int nbytes = recvfrom(fd, in_buffer, MAX_UDP_MSG, 0, (sockaddr*) &in_address, &in_addrlen); - if (nbytes == -1) { - errno_assert(errno != EBADF - && errno != EFAULT - && errno != ENOMEM - && errno != ENOTSOCK); - return; - } -#endif - int rc; - int body_size; - int body_offset; - msg_t msg; - - if (options.raw_socket) { - sockaddr_to_msg (&msg, &in_address); - - body_size = nbytes; - body_offset = 0; - } - else { - char* group_buffer = (char *)in_buffer + 1; - int group_size = in_buffer[0]; - - rc = msg.init_size (group_size); - errno_assert (rc == 0); - msg.set_flags (msg_t::more); - memcpy (msg.data (), group_buffer, group_size); - - // This doesn't fit, just ingore - if (nbytes - 1 < group_size) - return; - - body_size = nbytes - 1 - group_size; - body_offset = 1 + group_size; - } - - rc = session->push_msg (&msg); - errno_assert (rc == 0 || (rc == -1 && errno == EAGAIN)); - - // Pipe is full - if (rc != 0) { - rc = msg.close (); - errno_assert (rc == 0); - - reset_pollin (handle); - return; - } - - rc = msg.close (); - errno_assert (rc == 0); - rc = msg.init_size (body_size); - errno_assert (rc == 0); - memcpy (msg.data (), in_buffer + body_offset, body_size); - rc = session->push_msg (&msg); - errno_assert (rc == 0); - rc = msg.close (); - errno_assert (rc == 0); - session->flush (); -} - -void zmq::udp_engine_t::restart_input() -{ - if (!recv_enabled) - return; - - set_pollin (handle); - in_event (); -} diff --git a/dep/libzmq/src/udp_engine.hpp b/dep/libzmq/src/udp_engine.hpp deleted file mode 100644 index 233d05f652..0000000000 --- a/dep/libzmq/src/udp_engine.hpp +++ /dev/null @@ -1,73 +0,0 @@ - -#ifndef __ZMQ_UDP_ENGINE_HPP_INCLUDED__ -#define __ZMQ_UDP_ENGINE_HPP_INCLUDED__ - -#include "io_object.hpp" -#include "i_engine.hpp" -#include "address.hpp" -#include "udp_address.hpp" -#include "msg.hpp" - -#define MAX_UDP_MSG 8192 - -namespace zmq -{ - class io_thread_t; - class session_base_t; - - class udp_engine_t : public io_object_t, public i_engine - { - public: - udp_engine_t (const options_t &options_); - ~udp_engine_t (); - - int init (address_t *address_, bool send_, bool recv_); - - // i_engine interface implementation. - // Plug the engine to the session. - void plug (zmq::io_thread_t *io_thread_, class session_base_t *session_); - - // Terminate and deallocate the engine. Note that 'detached' - // events are not fired on termination. - void terminate (); - - // This method is called by the session to signalise that more - // messages can be written to the pipe. - void restart_input (); - - // This method is called by the session to signalise that there - // are messages to send available. - void restart_output (); - - void zap_msg_available () {}; - - void in_event (); - void out_event (); - - const char *get_endpoint () const; - - private: - int resolve_raw_address (char *addr_, size_t length_); - void sockaddr_to_msg (zmq::msg_t *msg, sockaddr_in* addr); - - bool plugged; - - fd_t fd; - session_base_t* session; - handle_t handle; - address_t *address; - - options_t options; - - sockaddr_in raw_address; - const struct sockaddr* out_address; - socklen_t out_addrlen; - - unsigned char out_buffer[MAX_UDP_MSG]; - unsigned char in_buffer[MAX_UDP_MSG]; - bool send_enabled; - bool recv_enabled; - }; -} - -#endif diff --git a/dep/libzmq/src/v1_decoder.cpp b/dep/libzmq/src/v1_decoder.cpp deleted file mode 100644 index 7744d6eafa..0000000000 --- a/dep/libzmq/src/v1_decoder.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include -#include - -#include "decoder.hpp" -#include "v1_decoder.hpp" -#include "likely.hpp" -#include "wire.hpp" -#include "err.hpp" - -zmq::v1_decoder_t::v1_decoder_t (size_t bufsize_, int64_t maxmsgsize_) : - c_single_allocator(bufsize_), - decoder_base_t (this), - maxmsgsize (maxmsgsize_) -{ - int rc = in_progress.init (); - errno_assert (rc == 0); - - // At the beginning, read one byte and go to one_byte_size_ready state. - next_step (tmpbuf, 1, &v1_decoder_t::one_byte_size_ready); -} - -zmq::v1_decoder_t::~v1_decoder_t () -{ - int rc = in_progress.close (); - errno_assert (rc == 0); -} - -int zmq::v1_decoder_t::one_byte_size_ready (unsigned char const*) -{ - // First byte of size is read. If it is 0xff read 8-byte size. - // Otherwise allocate the buffer for message data and read the - // message data into it. - if (*tmpbuf == 0xff) - next_step (tmpbuf, 8, &v1_decoder_t::eight_byte_size_ready); - else { - - // There has to be at least one byte (the flags) in the message). - if (!*tmpbuf) { - errno = EPROTO; - return -1; - } - - if (maxmsgsize >= 0 && (int64_t) (*tmpbuf - 1) > maxmsgsize) { - errno = EMSGSIZE; - return -1; - } - - int rc = in_progress.close(); - assert(rc == 0); - rc = in_progress.init_size (*tmpbuf - 1); - if (rc != 0) { - errno_assert (errno == ENOMEM); - rc = in_progress.init (); - errno_assert (rc == 0); - errno = ENOMEM; - return -1; - } - - next_step (tmpbuf, 1, &v1_decoder_t::flags_ready); - } - return 0; -} - -int zmq::v1_decoder_t::eight_byte_size_ready (unsigned char const*) -{ - // 8-byte payload length is read. Allocate the buffer - // for message body and read the message data into it. - const uint64_t payload_length = get_uint64 (tmpbuf); - - // There has to be at least one byte (the flags) in the message). - if (payload_length == 0) { - errno = EPROTO; - return -1; - } - - // Message size must not exceed the maximum allowed size. - if (maxmsgsize >= 0 && payload_length - 1 > (uint64_t) maxmsgsize) { - errno = EMSGSIZE; - return -1; - } - - // Message size must fit within range of size_t data type. - if (payload_length - 1 > std::numeric_limits ::max ()) { - errno = EMSGSIZE; - return -1; - } - - const size_t msg_size = static_cast (payload_length - 1); - - int rc = in_progress.close(); - assert(rc == 0); - rc = in_progress.init_size (msg_size); - if (rc != 0) { - errno_assert (errno == ENOMEM); - rc = in_progress.init (); - errno_assert (rc == 0); - errno = ENOMEM; - return -1; - } - - next_step (tmpbuf, 1, &v1_decoder_t::flags_ready); - return 0; -} - -int zmq::v1_decoder_t::flags_ready (unsigned char const*) -{ - // Store the flags from the wire into the message structure. - in_progress.set_flags (tmpbuf [0] & msg_t::more); - - next_step (in_progress.data (), in_progress.size (), - &v1_decoder_t::message_ready); - - return 0; -} - -int zmq::v1_decoder_t::message_ready (unsigned char const*) -{ - // Message is completely read. Push it further and start reading - // new message. (in_progress is a 0-byte message after this point.) - next_step (tmpbuf, 1, &v1_decoder_t::one_byte_size_ready); - return 1; -} diff --git a/dep/libzmq/src/v1_decoder.hpp b/dep/libzmq/src/v1_decoder.hpp deleted file mode 100644 index 99afffd623..0000000000 --- a/dep/libzmq/src/v1_decoder.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_V1_DECODER_HPP_INCLUDED__ -#define __ZMQ_V1_DECODER_HPP_INCLUDED__ - -#include "decoder.hpp" - -namespace zmq -{ - // Decoder for ZMTP/1.0 protocol. Converts data batches into messages. - - class v1_decoder_t : - public zmq::c_single_allocator, - public decoder_base_t - { - public: - - v1_decoder_t (size_t bufsize_, int64_t maxmsgsize_); - ~v1_decoder_t (); - - virtual msg_t *msg () { return &in_progress; } - - private: - - int one_byte_size_ready (unsigned char const*); - int eight_byte_size_ready (unsigned char const*); - int flags_ready (unsigned char const*); - int message_ready (unsigned char const*); - - unsigned char tmpbuf [8]; - msg_t in_progress; - - int64_t maxmsgsize; - - v1_decoder_t (const v1_decoder_t&); - void operator = (const v1_decoder_t&); - }; - -} - -#endif - diff --git a/dep/libzmq/src/v1_encoder.cpp b/dep/libzmq/src/v1_encoder.cpp deleted file mode 100644 index 391e499e65..0000000000 --- a/dep/libzmq/src/v1_encoder.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "encoder.hpp" -#include "v1_encoder.hpp" -#include "likely.hpp" -#include "wire.hpp" - -zmq::v1_encoder_t::v1_encoder_t (size_t bufsize_) : - encoder_base_t (bufsize_) -{ - // Write 0 bytes to the batch and go to message_ready state. - next_step (NULL, 0, &v1_encoder_t::message_ready, true); -} - -zmq::v1_encoder_t::~v1_encoder_t () -{ -} - -void zmq::v1_encoder_t::size_ready () -{ - // Write message body into the buffer. - next_step (in_progress->data (), in_progress->size (), - &v1_encoder_t::message_ready, true); -} - -void zmq::v1_encoder_t::message_ready () -{ - // Get the message size. - size_t size = in_progress->size (); - - // Account for the 'flags' byte. - size++; - - // For messages less than 255 bytes long, write one byte of message size. - // For longer messages write 0xff escape character followed by 8-byte - // message size. In both cases 'flags' field follows. - if (size < 255) { - tmpbuf [0] = (unsigned char) size; - tmpbuf [1] = (in_progress->flags () & msg_t::more); - next_step (tmpbuf, 2, &v1_encoder_t::size_ready, false); - } - else { - tmpbuf [0] = 0xff; - put_uint64 (tmpbuf + 1, size); - tmpbuf [9] = (in_progress->flags () & msg_t::more); - next_step (tmpbuf, 10, &v1_encoder_t::size_ready, false); - } -} diff --git a/dep/libzmq/src/v1_encoder.hpp b/dep/libzmq/src/v1_encoder.hpp deleted file mode 100644 index 25e7997171..0000000000 --- a/dep/libzmq/src/v1_encoder.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_V1_ENCODER_HPP_INCLUDED__ -#define __ZMQ_V1_ENCODER_HPP_INCLUDED__ - -#include "encoder.hpp" - -namespace zmq -{ - // Encoder for ZMTP/1.0 protocol. Converts messages into data batches. - - class v1_encoder_t : public encoder_base_t - { - public: - - v1_encoder_t (size_t bufsize_); - ~v1_encoder_t (); - - private: - - void size_ready (); - void message_ready (); - - unsigned char tmpbuf [10]; - - v1_encoder_t (const v1_encoder_t&); - const v1_encoder_t &operator = (const v1_encoder_t&); - }; -} - -#endif - diff --git a/dep/libzmq/src/v2_decoder.cpp b/dep/libzmq/src/v2_decoder.cpp deleted file mode 100644 index 0754541f0e..0000000000 --- a/dep/libzmq/src/v2_decoder.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include -#include -#include - -#include "v2_protocol.hpp" -#include "v2_decoder.hpp" -#include "likely.hpp" -#include "wire.hpp" -#include "err.hpp" - -zmq::v2_decoder_t::v2_decoder_t (size_t bufsize_, int64_t maxmsgsize_) : - shared_message_memory_allocator( bufsize_), - decoder_base_t (this), - msg_flags (0), - maxmsgsize (maxmsgsize_) -{ - int rc = in_progress.init (); - errno_assert (rc == 0); - - // At the beginning, read one byte and go to flags_ready state. - next_step (tmpbuf, 1, &v2_decoder_t::flags_ready); -} - -zmq::v2_decoder_t::~v2_decoder_t () -{ - int rc = in_progress.close (); - errno_assert (rc == 0); -} - -int zmq::v2_decoder_t::flags_ready (unsigned char const*) -{ - msg_flags = 0; - if (tmpbuf [0] & v2_protocol_t::more_flag) - msg_flags |= msg_t::more; - if (tmpbuf [0] & v2_protocol_t::command_flag) - msg_flags |= msg_t::command; - - // The payload length is either one or eight bytes, - // depending on whether the 'large' bit is set. - if (tmpbuf [0] & v2_protocol_t::large_flag) - next_step (tmpbuf, 8, &v2_decoder_t::eight_byte_size_ready); - else - next_step (tmpbuf, 1, &v2_decoder_t::one_byte_size_ready); - - return 0; -} - -int zmq::v2_decoder_t::one_byte_size_ready (unsigned char const* read_from) -{ - return size_ready(tmpbuf[0], read_from); -} - -int zmq::v2_decoder_t::eight_byte_size_ready (unsigned char const* read_from) { - // The payload size is encoded as 64-bit unsigned integer. - // The most significant byte comes first. - const uint64_t msg_size = get_uint64(tmpbuf); - - return size_ready(msg_size, read_from); -} - -int zmq::v2_decoder_t::size_ready(uint64_t msg_size, unsigned char const* read_pos) { - // Message size must not exceed the maximum allowed size. - if (maxmsgsize >= 0) - if (unlikely (msg_size > static_cast (maxmsgsize))) { - errno = EMSGSIZE; - return -1; - } - - // Message size must fit into size_t data type. - if (unlikely (msg_size != static_cast (msg_size))) { - errno = EMSGSIZE; - return -1; - } - - int rc = in_progress.close(); - assert(rc == 0); - - // the current message can exceed the current buffer. We have to copy the buffer - // data into a new message and complete it in the next receive. - - if (unlikely ((unsigned char*)read_pos + msg_size > (data() + size()))) - { - // a new message has started, but the size would exceed the pre-allocated arena - // this happens every time when a message does not fit completely into the buffer - rc = in_progress.init_size (static_cast (msg_size)); - } - else - { - // construct message using n bytes from the buffer as storage - // increase buffer ref count - // if the message will be a large message, pass a valid refcnt memory location as well - rc = in_progress.init ((unsigned char *) read_pos, static_cast (msg_size), - shared_message_memory_allocator::call_dec_ref, buffer(), - provide_content ()); - - // For small messages, data has been copied and refcount does not have to be increased - if (in_progress.is_zcmsg()) - { - advance_content(); - inc_ref(); - } - } - - if (unlikely (rc)) { - errno_assert (errno == ENOMEM); - rc = in_progress.init (); - errno_assert (rc == 0); - errno = ENOMEM; - return -1; - } - - in_progress.set_flags (msg_flags); - // this sets read_pos to - // the message data address if the data needs to be copied - // for small message / messages exceeding the current buffer - // or - // to the current start address in the buffer because the message - // was constructed to use n bytes from the address passed as argument - next_step (in_progress.data (), in_progress.size (), - &v2_decoder_t::message_ready); - - return 0; -} - -int zmq::v2_decoder_t::message_ready (unsigned char const*) -{ - // Message is completely read. Signal this to the caller - // and prepare to decode next message. - next_step (tmpbuf, 1, &v2_decoder_t::flags_ready); - return 1; -} diff --git a/dep/libzmq/src/v2_decoder.hpp b/dep/libzmq/src/v2_decoder.hpp deleted file mode 100644 index f7a69a10d0..0000000000 --- a/dep/libzmq/src/v2_decoder.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_V2_DECODER_HPP_INCLUDED__ -#define __ZMQ_V2_DECODER_HPP_INCLUDED__ - -#include "decoder.hpp" -#include "decoder_allocators.hpp" - -namespace zmq -{ - // Decoder for ZMTP/2.x framing protocol. Converts data stream into messages. - // The class has to inherit from shared_message_memory_allocator because - // the base class calls allocate in its constructor. - class v2_decoder_t : - // inherit first from allocator to ensure that it is constructed before decoder_base_t - public shared_message_memory_allocator, - public decoder_base_t - { - public: - v2_decoder_t (size_t bufsize_, int64_t maxmsgsize_); - virtual ~v2_decoder_t (); - - // i_decoder interface. - virtual msg_t *msg () { return &in_progress; } - - private: - - int flags_ready (unsigned char const*); - int one_byte_size_ready (unsigned char const*); - int eight_byte_size_ready (unsigned char const*); - int message_ready (unsigned char const*); - - int size_ready(uint64_t size_, unsigned char const*); - - unsigned char tmpbuf [8]; - unsigned char msg_flags; - msg_t in_progress; - - const int64_t maxmsgsize; - - v2_decoder_t (const v2_decoder_t&); - void operator = (const v2_decoder_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/v2_encoder.cpp b/dep/libzmq/src/v2_encoder.cpp deleted file mode 100644 index d5d2bf4fed..0000000000 --- a/dep/libzmq/src/v2_encoder.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include "v2_protocol.hpp" -#include "v2_encoder.hpp" -#include "likely.hpp" -#include "wire.hpp" - -zmq::v2_encoder_t::v2_encoder_t (size_t bufsize_) : - encoder_base_t (bufsize_) -{ - // Write 0 bytes to the batch and go to message_ready state. - next_step (NULL, 0, &v2_encoder_t::message_ready, true); -} - -zmq::v2_encoder_t::~v2_encoder_t () -{ -} - -void zmq::v2_encoder_t::message_ready () -{ - // Encode flags. - unsigned char &protocol_flags = tmpbuf [0]; - protocol_flags = 0; - if (in_progress->flags () & msg_t::more) - protocol_flags |= v2_protocol_t::more_flag; - if (in_progress->size () > 255) - protocol_flags |= v2_protocol_t::large_flag; - if (in_progress->flags () & msg_t::command) - protocol_flags |= v2_protocol_t::command_flag; - - // Encode the message length. For messages less then 256 bytes, - // the length is encoded as 8-bit unsigned integer. For larger - // messages, 64-bit unsigned integer in network byte order is used. - const size_t size = in_progress->size (); - if (unlikely (size > 255)) { - put_uint64 (tmpbuf + 1, size); - next_step (tmpbuf, 9, &v2_encoder_t::size_ready, false); - } - else { - tmpbuf [1] = static_cast (size); - next_step (tmpbuf, 2, &v2_encoder_t::size_ready, false); - } -} - -void zmq::v2_encoder_t::size_ready () -{ - // Write message body into the buffer. - next_step (in_progress->data (), in_progress->size (), - &v2_encoder_t::message_ready, true); -} diff --git a/dep/libzmq/src/v2_encoder.hpp b/dep/libzmq/src/v2_encoder.hpp deleted file mode 100644 index 523deae8d7..0000000000 --- a/dep/libzmq/src/v2_encoder.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_V2_ENCODER_HPP_INCLUDED__ -#define __ZMQ_V2_ENCODER_HPP_INCLUDED__ - -#include "encoder.hpp" - -namespace zmq -{ - // Encoder for 0MQ framing protocol. Converts messages into data stream. - - class v2_encoder_t : public encoder_base_t - { - public: - - v2_encoder_t (size_t bufsize_); - virtual ~v2_encoder_t (); - - private: - - void size_ready (); - void message_ready (); - - unsigned char tmpbuf [9]; - - v2_encoder_t (const v2_encoder_t&); - const v2_encoder_t &operator = (const v2_encoder_t&); - }; -} - -#endif - diff --git a/dep/libzmq/src/v2_protocol.hpp b/dep/libzmq/src/v2_protocol.hpp deleted file mode 100644 index 3780ed2c59..0000000000 --- a/dep/libzmq/src/v2_protocol.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_V2_PROTOCOL_HPP_INCLUDED__ -#define __ZMQ_V2_PROTOCOL_HPP_INCLUDED__ - -namespace zmq -{ - // Definition of constants for ZMTP/2.0 transport protocol. - class v2_protocol_t - { - public: - // Message flags. - enum - { - more_flag = 1, - large_flag = 2, - command_flag = 4 - }; - }; -} - -#endif diff --git a/dep/libzmq/src/vmci_connecter.hpp b/dep/libzmq/src/vmci_connecter.hpp deleted file mode 100644 index 56483aebb0..0000000000 --- a/dep/libzmq/src/vmci_connecter.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_VMCI_CONNECTER_HPP_INCLUDED__ -#define __ZMQ_VMCI_CONNECTER_HPP_INCLUDED__ - -#include "platform.hpp" - -#if defined ZMQ_HAVE_VMCI - -#include "fd.hpp" -#include "own.hpp" -#include "stdint.hpp" -#include "io_object.hpp" - -namespace zmq -{ - - class io_thread_t; - class session_base_t; - struct address_t; - - class vmci_connecter_t : public own_t, public io_object_t - { - public: - - // If 'delayed_start' is true connecter first waits for a while, - // then starts connection process. - vmci_connecter_t (zmq::io_thread_t *io_thread_, - zmq::session_base_t *session_, const options_t &options_, - const address_t *addr_, bool delayed_start_); - ~vmci_connecter_t (); - - private: - - // ID of the timer used to delay the reconnection. - enum {reconnect_timer_id = 1}; - - // Handlers for incoming commands. - void process_plug (); - void process_term (int linger_); - - // Handlers for I/O events. - void in_event (); - void out_event (); - void timer_event (int id_); - - // Internal function to start the actual connection establishment. - void start_connecting (); - - // Internal function to add a reconnect timer - void add_reconnect_timer(); - - // Internal function to return a reconnect backoff delay. - // Will modify the current_reconnect_ivl used for next call - // Returns the currently used interval - int get_new_reconnect_ivl (); - - // Open VMCI connecting socket. Returns -1 in case of error, - // 0 if connect was successful immediately. Returns -1 with - // EAGAIN errno if async connect was launched. - int open (); - - // Close the connecting socket. - void close (); - - // Get the file descriptor of newly created connection. Returns - // retired_fd if the connection was unsuccessful. - fd_t connect (); - - // Address to connect to. Owned by session_base_t. - const address_t *addr; - - // Underlying socket. - fd_t s; - - // Handle corresponding to the listening socket. - handle_t handle; - - // If true file descriptor is registered with the poller and 'handle' - // contains valid value. - bool handle_valid; - - // If true, connecter is waiting a while before trying to connect. - const bool delayed_start; - - // True iff a timer has been started. - bool timer_started; - - // Reference to the session we belong to. - zmq::session_base_t *session; - - // Current reconnect ivl, updated for backoff strategy - int current_reconnect_ivl; - - // String representation of endpoint to connect to - std::string endpoint; - - // Socket - zmq::socket_base_t *socket; - - vmci_connecter_t (const vmci_connecter_t&); - const vmci_connecter_t &operator = (const vmci_connecter_t&); - }; -} - -#endif - -#endif - diff --git a/dep/libzmq/src/windows.hpp b/dep/libzmq/src/windows.hpp deleted file mode 100644 index 73e280e8e3..0000000000 --- a/dep/libzmq/src/windows.hpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_WINDOWS_HPP_INCLUDED__ -#define __ZMQ_WINDOWS_HPP_INCLUDED__ - -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif -#ifndef NOMINMAX -#define NOMINMAX // Macros min(a,b) and max(a,b) -#endif - -// Set target version to Windows Server 2008, Windows Vista or higher. -// Windows XP (0x0501) is supported but without client & server socket types. -#if !defined _WIN32_WINNT && !defined ZMQ_HAVE_WINDOWS_UWP -#define _WIN32_WINNT 0x0600 -#endif - -#if defined ZMQ_HAVE_WINDOWS_UWP -#define _WIN32_WINNT _WIN32_WINNT_WIN10 -#endif - -#ifdef __MINGW32__ -// Require Windows XP or higher with MinGW for getaddrinfo(). -#if(_WIN32_WINNT >= 0x0501) -#else -#error You need at least Windows XP target -#endif -#endif - -#include -#include -#include -#include - -#if !defined __MINGW32__ -#include -#endif - -// Workaround missing mstcpip.h in mingw32 (MinGW64 provides this) -// __MINGW64_VERSION_MAJOR is only defined when using in mingw-w64 -#if defined __MINGW32__ && !defined SIO_KEEPALIVE_VALS && \ - !defined __MINGW64_VERSION_MAJOR -struct tcp_keepalive { - u_long onoff; - u_long keepalivetime; - u_long keepaliveinterval; -}; -#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) -#endif - -#include -#include -#if !defined _WIN32_WCE -#include -#endif - -#if defined ZMQ_USE_POLL -static inline int poll(struct pollfd *pfd, unsigned long nfds, int timeout) { return WSAPoll(pfd, nfds, timeout); } -#endif - -// In MinGW environment AI_NUMERICSERV is not defined. -#ifndef AI_NUMERICSERV -#define AI_NUMERICSERV 0x0400 -#endif -#endif diff --git a/dep/libzmq/src/wire.hpp b/dep/libzmq/src/wire.hpp deleted file mode 100644 index 95a30e7625..0000000000 --- a/dep/libzmq/src/wire.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_WIRE_HPP_INCLUDED__ -#define __ZMQ_WIRE_HPP_INCLUDED__ - -#include "stdint.hpp" - -namespace zmq -{ - - // Helper functions to convert different integer types to/from network - // byte order. - - inline void put_uint8 (unsigned char *buffer_, uint8_t value) - { - *buffer_ = value; - } - - inline uint8_t get_uint8 (const unsigned char *buffer_) - { - return *buffer_; - } - - inline void put_uint16 (unsigned char *buffer_, uint16_t value) - { - buffer_ [0] = (unsigned char) (((value) >> 8) & 0xff); - buffer_ [1] = (unsigned char) (value & 0xff); - } - - inline uint16_t get_uint16 (const unsigned char *buffer_) - { - return - (((uint16_t) buffer_ [0]) << 8) | - ((uint16_t) buffer_ [1]); - } - - inline void put_uint32 (unsigned char *buffer_, uint32_t value) - { - buffer_ [0] = (unsigned char) (((value) >> 24) & 0xff); - buffer_ [1] = (unsigned char) (((value) >> 16) & 0xff); - buffer_ [2] = (unsigned char) (((value) >> 8) & 0xff); - buffer_ [3] = (unsigned char) (value & 0xff); - } - - inline uint32_t get_uint32 (const unsigned char *buffer_) - { - return - (((uint32_t) buffer_ [0]) << 24) | - (((uint32_t) buffer_ [1]) << 16) | - (((uint32_t) buffer_ [2]) << 8) | - ((uint32_t) buffer_ [3]); - } - - inline void put_uint64 (unsigned char *buffer_, uint64_t value) - { - buffer_ [0] = (unsigned char) (((value) >> 56) & 0xff); - buffer_ [1] = (unsigned char) (((value) >> 48) & 0xff); - buffer_ [2] = (unsigned char) (((value) >> 40) & 0xff); - buffer_ [3] = (unsigned char) (((value) >> 32) & 0xff); - buffer_ [4] = (unsigned char) (((value) >> 24) & 0xff); - buffer_ [5] = (unsigned char) (((value) >> 16) & 0xff); - buffer_ [6] = (unsigned char) (((value) >> 8) & 0xff); - buffer_ [7] = (unsigned char) (value & 0xff); - } - - inline uint64_t get_uint64 (const unsigned char *buffer_) - { - return - (((uint64_t) buffer_ [0]) << 56) | - (((uint64_t) buffer_ [1]) << 48) | - (((uint64_t) buffer_ [2]) << 40) | - (((uint64_t) buffer_ [3]) << 32) | - (((uint64_t) buffer_ [4]) << 24) | - (((uint64_t) buffer_ [5]) << 16) | - (((uint64_t) buffer_ [6]) << 8) | - ((uint64_t) buffer_ [7]); - } - -} - -#endif diff --git a/dep/libzmq/src/xpub.cpp b/dep/libzmq/src/xpub.cpp deleted file mode 100644 index 7a99dff2fd..0000000000 --- a/dep/libzmq/src/xpub.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "xpub.hpp" -#include "pipe.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "macros.hpp" - -zmq::xpub_t::xpub_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - verbose_subs (false), - verbose_unsubs (false), - more (false), - lossy (true), - manual (false), - pending_pipes (), - welcome_msg () -{ - last_pipe = NULL; - options.type = ZMQ_XPUB; - welcome_msg.init (); -} - -zmq::xpub_t::~xpub_t () -{ - welcome_msg.close (); -} - -void zmq::xpub_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - zmq_assert (pipe_); - dist.attach (pipe_); - - // If subscribe_to_all_ is specified, the caller would like to subscribe - // to all data on this pipe, implicitly. - if (subscribe_to_all_) - subscriptions.add (NULL, 0, pipe_); - - // if welcome message exists, send a copy of it - if (welcome_msg.size () > 0) - { - msg_t copy; - copy.init (); - int rc = copy.copy (welcome_msg); - errno_assert (rc == 0); - bool ok = pipe_->write (©); - zmq_assert (ok); - pipe_->flush (); - } - - // The pipe is active when attached. Let's read the subscriptions from - // it, if any. - xread_activated (pipe_); -} - -void zmq::xpub_t::xread_activated (pipe_t *pipe_) -{ - // There are some subscriptions waiting. Let's process them. - msg_t sub; - while (pipe_->read (&sub)) { - // Apply the subscription to the trie - unsigned char *const data = (unsigned char *) sub.data (); - const size_t size = sub.size (); - metadata_t* metadata = sub.metadata(); - if (size > 0 && (*data == 0 || *data == 1)) { - if (manual) - { - // Store manual subscription to use on termination - if (*data == 0) - manual_subscriptions.rm (data + 1, size - 1, pipe_); - else - manual_subscriptions.add (data + 1, size - 1, pipe_); - - pending_pipes.push_back (pipe_); - pending_data.push_back (blob_t (data, size)); - if (metadata) - metadata->add_ref (); - pending_metadata.push_back (metadata); - pending_flags.push_back (0); - } - else - { - bool unique; - if (*data == 0) - unique = subscriptions.rm (data + 1, size - 1, pipe_); - else - unique = subscriptions.add (data + 1, size - 1, pipe_); - - // If the (un)subscription is not a duplicate store it so that it can be - // passed to the user on next recv call unless verbose mode is enabled - // which makes to pass always these messages. - if (options.type == ZMQ_XPUB && (unique || (*data == 1 && verbose_subs) || - (*data == 0 && verbose_unsubs && verbose_subs))) { - pending_data.push_back (blob_t(data, size)); - if (metadata) - metadata->add_ref (); - pending_metadata.push_back (metadata); - pending_flags.push_back (0); - } - } - } - else { - // Process user message coming upstream from xsub socket - pending_data.push_back (blob_t (data, size)); - if (metadata) - metadata->add_ref (); - pending_metadata.push_back (metadata); - pending_flags.push_back (sub.flags ()); - } - sub.close (); - } -} - -void zmq::xpub_t::xwrite_activated (pipe_t *pipe_) -{ - dist.activated (pipe_); -} - -int zmq::xpub_t::xsetsockopt (int option_, const void *optval_, - size_t optvallen_) -{ - if (option_ == ZMQ_XPUB_VERBOSE - || option_ == ZMQ_XPUB_VERBOSER - || option_ == ZMQ_XPUB_NODROP - || option_ == ZMQ_XPUB_MANUAL) { - if (optvallen_ != sizeof (int) || *static_cast (optval_) < 0) { - errno = EINVAL; - return -1; - } - if (option_ == ZMQ_XPUB_VERBOSE) { - verbose_subs = (*static_cast (optval_) != 0); - verbose_unsubs = 0; - } - else - if (option_ == ZMQ_XPUB_VERBOSER) { - verbose_subs = (*static_cast (optval_) != 0); - verbose_unsubs = verbose_subs; - } - else - if (option_ == ZMQ_XPUB_NODROP) - lossy = (*static_cast (optval_) == 0); - else - if (option_ == ZMQ_XPUB_MANUAL) - manual = (*static_cast (optval_) != 0); - } - else - if (option_ == ZMQ_SUBSCRIBE && manual) { - if (last_pipe != NULL) - subscriptions.add ((unsigned char *) optval_, optvallen_, last_pipe); - } - else - if (option_ == ZMQ_UNSUBSCRIBE && manual) { - if (last_pipe != NULL) - subscriptions.rm ((unsigned char *) optval_, optvallen_, last_pipe); - } - else - if (option_ == ZMQ_XPUB_WELCOME_MSG) { - welcome_msg.close (); - - if (optvallen_ > 0) { - int rc = welcome_msg.init_size (optvallen_); - errno_assert(rc == 0); - - unsigned char *data = (unsigned char*) welcome_msg.data (); - memcpy (data, optval_, optvallen_); - } - else - welcome_msg.init (); - } - else { - errno = EINVAL; - return -1; - } - return 0; -} - -static void stub (unsigned char *data_, size_t size_, void *arg_) -{ - LIBZMQ_UNUSED(data_); - LIBZMQ_UNUSED(size_); - LIBZMQ_UNUSED(arg_); -} - -void zmq::xpub_t::xpipe_terminated (pipe_t *pipe_) -{ - if (manual) - { - // Remove the pipe from the trie and send corresponding manual - // unsubscriptions upstream. - manual_subscriptions.rm (pipe_, send_unsubscription, this, false); - // Remove pipe without actually sending the message as it was taken - // care of by the manual call above. subscriptions is the real mtrie, - // so the pipe must be removed from there or it will be left over. - subscriptions.rm (pipe_, stub, NULL, false); - } - else - { - // Remove the pipe from the trie. If there are topics that nobody - // is interested in anymore, send corresponding unsubscriptions - // upstream. - subscriptions.rm (pipe_, send_unsubscription, this, !verbose_unsubs); - } - - dist.pipe_terminated (pipe_); -} - -void zmq::xpub_t::mark_as_matching (pipe_t *pipe_, void *arg_) -{ - xpub_t *self = (xpub_t*) arg_; - self->dist.match (pipe_); -} - -int zmq::xpub_t::xsend (msg_t *msg_) -{ - bool msg_more = msg_->flags () & msg_t::more ? true : false; - - // For the first part of multi-part message, find the matching pipes. - if (!more) { - subscriptions.match ((unsigned char*) msg_->data (), msg_->size (), - mark_as_matching, this); - // If inverted matching is used, reverse the selection now - if (options.invert_matching) { - dist.reverse_match(); - } - } - - int rc = -1; // Assume we fail - if (lossy || dist.check_hwm ()) { - if (dist.send_to_matching (msg_) == 0) { - // If we are at the end of multi-part message we can mark - // all the pipes as non-matching. - if (!msg_more) - dist.unmatch (); - more = msg_more; - rc = 0; // Yay, sent successfully - } - } - else - errno = EAGAIN; - return rc; -} - -bool zmq::xpub_t::xhas_out () -{ - return dist.has_out (); -} - -int zmq::xpub_t::xrecv (msg_t *msg_) -{ - // If there is at least one - if (pending_data.empty ()) { - errno = EAGAIN; - return -1; - } - - // User is reading a message, set last_pipe and remove it from the deque - if (manual && !pending_pipes.empty ()) { - last_pipe = pending_pipes.front (); - pending_pipes.pop_front (); - } - - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init_size (pending_data.front ().size ()); - errno_assert (rc == 0); - memcpy (msg_->data (), - pending_data.front ().data (), - pending_data.front ().size ()); - - // set metadata only if there is some - if (metadata_t* metadata = pending_metadata.front ()) { - msg_->set_metadata (metadata); - // Remove ref corresponding to vector placement - metadata->drop_ref(); - } - - msg_->set_flags (pending_flags.front ()); - pending_data.pop_front (); - pending_metadata.pop_front (); - pending_flags.pop_front (); - return 0; -} - -bool zmq::xpub_t::xhas_in () -{ - return !pending_data.empty (); -} - -void zmq::xpub_t::send_unsubscription (unsigned char *data_, size_t size_, - void *arg_) -{ - xpub_t *self = (xpub_t*) arg_; - - if (self->options.type != ZMQ_PUB) { - // Place the unsubscription to the queue of pending (un)subscriptions - // to be retrieved by the user later on. - blob_t unsub (size_ + 1); - *unsub.data() = 0; - if (size_ > 0) - memcpy (unsub.data() + 1, data_, size_); - self->pending_data.ZMQ_PUSH_OR_EMPLACE_BACK (ZMQ_MOVE(unsub)); - self->pending_metadata.push_back (NULL); - self->pending_flags.push_back (0); - - if (self->manual) { - self->last_pipe = NULL; - self->pending_pipes.push_back (NULL); - } - } -} diff --git a/dep/libzmq/src/xpub.hpp b/dep/libzmq/src/xpub.hpp deleted file mode 100644 index 2dac4ea82d..0000000000 --- a/dep/libzmq/src/xpub.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_XPUB_HPP_INCLUDED__ -#define __ZMQ_XPUB_HPP_INCLUDED__ - -#include -#include - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "mtrie.hpp" -#include "array.hpp" -#include "dist.hpp" - -namespace zmq -{ - - class ctx_t; - class msg_t; - class pipe_t; - class io_thread_t; - - class xpub_t : - public socket_base_t - { - public: - - xpub_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~xpub_t (); - - // Implementations of virtual functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_ = false); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - int xsetsockopt (int option_, const void *optval_, size_t optvallen_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Function to be applied to the trie to send all the subscriptions - // upstream. - static void send_unsubscription (unsigned char *data_, size_t size_, - void *arg_); - - // Function to be applied to each matching pipes. - static void mark_as_matching (zmq::pipe_t *pipe_, void *arg_); - - // List of all subscriptions mapped to corresponding pipes. - mtrie_t subscriptions; - - // List of manual subscriptions mapped to corresponding pipes. - mtrie_t manual_subscriptions; - - // Distributor of messages holding the list of outbound pipes. - dist_t dist; - - // If true, send all subscription messages upstream, not just - // unique ones - bool verbose_subs; - - // If true, send all unsubscription messages upstream, not just - // unique ones - bool verbose_unsubs; - - // True if we are in the middle of sending a multi-part message. - bool more; - - // Drop messages if HWM reached, otherwise return with EAGAIN - bool lossy; - - // Subscriptions will not bed added automatically, only after calling set option with ZMQ_SUBSCRIBE or ZMQ_UNSUBSCRIBE - bool manual; - - // Last pipe that sent subscription message, only used if xpub is on manual - pipe_t *last_pipe; - - // Pipes that sent subscriptions messages that have not yet been processed, only used if xpub is on manual - std::deque pending_pipes; - - // Welcome message to send to pipe when attached - msg_t welcome_msg; - - // List of pending (un)subscriptions, ie. those that were already - // applied to the trie, but not yet received by the user. - std::deque pending_data; - std::deque pending_metadata; - std::deque pending_flags; - - xpub_t (const xpub_t&); - const xpub_t &operator = (const xpub_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/xsub.cpp b/dep/libzmq/src/xsub.cpp deleted file mode 100644 index 2902b50333..0000000000 --- a/dep/libzmq/src/xsub.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" -#include - -#include "macros.hpp" -#include "xsub.hpp" -#include "err.hpp" - -zmq::xsub_t::xsub_t (class ctx_t *parent_, uint32_t tid_, int sid_) : - socket_base_t (parent_, tid_, sid_), - has_message (false), - more (false) -{ - options.type = ZMQ_XSUB; - - // When socket is being closed down we don't want to wait till pending - // subscription commands are sent to the wire. - options.linger = 0; - - int rc = message.init (); - errno_assert (rc == 0); -} - -zmq::xsub_t::~xsub_t () -{ - int rc = message.close (); - errno_assert (rc == 0); -} - -void zmq::xsub_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_) -{ - LIBZMQ_UNUSED (subscribe_to_all_); - - zmq_assert (pipe_); - fq.attach (pipe_); - dist.attach (pipe_); - - // Send all the cached subscriptions to the new upstream peer. - subscriptions.apply (send_subscription, pipe_); - pipe_->flush (); -} - -void zmq::xsub_t::xread_activated (pipe_t *pipe_) -{ - fq.activated (pipe_); -} - -void zmq::xsub_t::xwrite_activated (pipe_t *pipe_) -{ - dist.activated (pipe_); -} - -void zmq::xsub_t::xpipe_terminated (pipe_t *pipe_) -{ - fq.pipe_terminated (pipe_); - dist.pipe_terminated (pipe_); -} - -void zmq::xsub_t::xhiccuped (pipe_t *pipe_) -{ - // Send all the cached subscriptions to the hiccuped pipe. - subscriptions.apply (send_subscription, pipe_); - pipe_->flush (); -} - -int zmq::xsub_t::xsend (msg_t *msg_) -{ - size_t size = msg_->size (); - unsigned char *data = (unsigned char *) msg_->data (); - - if (size > 0 && *data == 1) { - // Process subscribe message - // This used to filter out duplicate subscriptions, - // however this is alread done on the XPUB side and - // doing it here as well breaks ZMQ_XPUB_VERBOSE - // when there are forwarding devices involved. - subscriptions.add (data + 1, size - 1); - return dist.send_to_all (msg_); - } - else - if (size > 0 && *data == 0) { - // Process unsubscribe message - if (subscriptions.rm (data + 1, size - 1)) - return dist.send_to_all (msg_); - } - else - // User message sent upstream to XPUB socket - return dist.send_to_all (msg_); - - int rc = msg_->close (); - errno_assert (rc == 0); - rc = msg_->init (); - errno_assert (rc == 0); - - return 0; -} - -bool zmq::xsub_t::xhas_out () -{ - // Subscription can be added/removed anytime. - return true; -} - -int zmq::xsub_t::xrecv (msg_t *msg_) -{ - // If there's already a message prepared by a previous call to zmq_poll, - // return it straight ahead. - if (has_message) { - int rc = msg_->move (message); - errno_assert (rc == 0); - has_message = false; - more = msg_->flags () & msg_t::more ? true : false; - return 0; - } - - // TODO: This can result in infinite loop in the case of continuous - // stream of non-matching messages which breaks the non-blocking recv - // semantics. - while (true) { - - // Get a message using fair queueing algorithm. - int rc = fq.recv (msg_); - - // If there's no message available, return immediately. - // The same when error occurs. - if (rc != 0) - return -1; - - // Check whether the message matches at least one subscription. - // Non-initial parts of the message are passed - if (more || !options.filter || match (msg_)) { - more = msg_->flags () & msg_t::more ? true : false; - return 0; - } - - // Message doesn't match. Pop any remaining parts of the message - // from the pipe. - while (msg_->flags () & msg_t::more) { - rc = fq.recv (msg_); - errno_assert (rc == 0); - } - } -} - -bool zmq::xsub_t::xhas_in () -{ - // There are subsequent parts of the partly-read message available. - if (more) - return true; - - // If there's already a message prepared by a previous call to zmq_poll, - // return straight ahead. - if (has_message) - return true; - - // TODO: This can result in infinite loop in the case of continuous - // stream of non-matching messages. - while (true) { - - // Get a message using fair queueing algorithm. - int rc = fq.recv (&message); - - // If there's no message available, return immediately. - // The same when error occurs. - if (rc != 0) { - errno_assert (errno == EAGAIN); - return false; - } - - // Check whether the message matches at least one subscription. - if (!options.filter || match (&message)) { - has_message = true; - return true; - } - - // Message doesn't match. Pop any remaining parts of the message - // from the pipe. - while (message.flags () & msg_t::more) { - rc = fq.recv (&message); - errno_assert (rc == 0); - } - } -} - -const zmq::blob_t &zmq::xsub_t::get_credential () const -{ - return fq.get_credential (); -} - -bool zmq::xsub_t::match (msg_t *msg_) -{ - bool matching = subscriptions.check ((unsigned char*) msg_->data (), msg_->size ()); - - return matching ^ options.invert_matching; -} - -void zmq::xsub_t::send_subscription (unsigned char *data_, size_t size_, - void *arg_) -{ - pipe_t *pipe = (pipe_t*) arg_; - - // Create the subscription message. - msg_t msg; - int rc = msg.init_size (size_ + 1); - errno_assert (rc == 0); - unsigned char *data = (unsigned char*) msg.data (); - data [0] = 1; - - // We explicitly allow a NULL subscription with size zero - if (size_) { - assert (data_); - memcpy (data + 1, data_, size_); - } - - // Send it to the pipe. - bool sent = pipe->write (&msg); - // If we reached the SNDHWM, and thus cannot send the subscription, drop - // the subscription message instead. This matches the behaviour of - // zmq_setsockopt(ZMQ_SUBSCRIBE, ...), which also drops subscriptions - // when the SNDHWM is reached. - if (!sent) - msg.close (); -} diff --git a/dep/libzmq/src/xsub.hpp b/dep/libzmq/src/xsub.hpp deleted file mode 100644 index cc925f04fc..0000000000 --- a/dep/libzmq/src/xsub.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_XSUB_HPP_INCLUDED__ -#define __ZMQ_XSUB_HPP_INCLUDED__ - -#include "socket_base.hpp" -#include "session_base.hpp" -#include "dist.hpp" -#include "fq.hpp" -#include "trie.hpp" - -namespace zmq -{ - - class ctx_t; - class pipe_t; - class io_thread_t; - - class xsub_t : - public socket_base_t - { - public: - - xsub_t (zmq::ctx_t *parent_, uint32_t tid_, int sid_); - ~xsub_t (); - - protected: - - // Overrides of functions from socket_base_t. - void xattach_pipe (zmq::pipe_t *pipe_, bool subscribe_to_all_); - int xsend (zmq::msg_t *msg_); - bool xhas_out (); - int xrecv (zmq::msg_t *msg_); - bool xhas_in (); - const blob_t &get_credential () const; - void xread_activated (zmq::pipe_t *pipe_); - void xwrite_activated (zmq::pipe_t *pipe_); - void xhiccuped (pipe_t *pipe_); - void xpipe_terminated (zmq::pipe_t *pipe_); - - private: - - // Check whether the message matches at least one subscription. - bool match (zmq::msg_t *msg_); - - // Function to be applied to the trie to send all the subsciptions - // upstream. - static void send_subscription (unsigned char *data_, size_t size_, - void *arg_); - - // Fair queueing object for inbound pipes. - fq_t fq; - - // Object for distributing the subscriptions upstream. - dist_t dist; - - // The repository of subscriptions. - trie_t subscriptions; - - // If true, 'message' contains a matching message to return on the - // next recv call. - bool has_message; - msg_t message; - - // If true, part of a multipart message was already received, but - // there are following parts still waiting. - bool more; - - xsub_t (const xsub_t&); - const xsub_t &operator = (const xsub_t&); - }; - -} - -#endif - diff --git a/dep/libzmq/src/ypipe.hpp b/dep/libzmq/src/ypipe.hpp deleted file mode 100644 index 5321851640..0000000000 --- a/dep/libzmq/src/ypipe.hpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_YPIPE_HPP_INCLUDED__ -#define __ZMQ_YPIPE_HPP_INCLUDED__ - -#include "atomic_ptr.hpp" -#include "yqueue.hpp" -#include "ypipe_base.hpp" - -namespace zmq -{ - - // Lock-free queue implementation. - // Only a single thread can read from the pipe at any specific moment. - // Only a single thread can write to the pipe at any specific moment. - // T is the type of the object in the queue. - // N is granularity of the pipe, i.e. how many items are needed to - // perform next memory allocation. - - template class ypipe_t : public ypipe_base_t - { - public: - - // Initialises the pipe. - inline ypipe_t () - { - // Insert terminator element into the queue. - queue.push (); - - // Let all the pointers to point to the terminator. - // (unless pipe is dead, in which case c is set to NULL). - r = w = f = &queue.back (); - c.set (&queue.back ()); - } - - // The destructor doesn't have to be virtual. It is made virtual - // just to keep ICC and code checking tools from complaining. - inline virtual ~ypipe_t () - { - } - - // Following function (write) deliberately copies uninitialised data - // when used with zmq_msg. Initialising the VSM body for - // non-VSM messages won't be good for performance. - -#ifdef ZMQ_HAVE_OPENVMS -#pragma message save -#pragma message disable(UNINIT) -#endif - - // Write an item to the pipe. Don't flush it yet. If incomplete is - // set to true the item is assumed to be continued by items - // subsequently written to the pipe. Incomplete items are never - // flushed down the stream. - inline void write (const T &value_, bool incomplete_) - { - // Place the value to the queue, add new terminator element. - queue.back () = value_; - queue.push (); - - // Move the "flush up to here" poiter. - if (!incomplete_) - f = &queue.back (); - } - -#ifdef ZMQ_HAVE_OPENVMS -#pragma message restore -#endif - - // Pop an incomplete item from the pipe. Returns true if such - // item exists, false otherwise. - inline bool unwrite (T *value_) - { - if (f == &queue.back ()) - return false; - queue.unpush (); - *value_ = queue.back (); - return true; - } - - // Flush all the completed items into the pipe. Returns false if - // the reader thread is sleeping. In that case, caller is obliged to - // wake the reader up before using the pipe again. - inline bool flush () - { - // If there are no un-flushed items, do nothing. - if (w == f) - return true; - - // Try to set 'c' to 'f'. - if (c.cas (w, f) != w) { - - // Compare-and-swap was unseccessful because 'c' is NULL. - // This means that the reader is asleep. Therefore we don't - // care about thread-safeness and update c in non-atomic - // manner. We'll return false to let the caller know - // that reader is sleeping. - c.set (f); - w = f; - return false; - } - - // Reader is alive. Nothing special to do now. Just move - // the 'first un-flushed item' pointer to 'f'. - w = f; - return true; - } - - // Check whether item is available for reading. - inline bool check_read () - { - // Was the value prefetched already? If so, return. - if (&queue.front () != r && r) - return true; - - // There's no prefetched value, so let us prefetch more values. - // Prefetching is to simply retrieve the - // pointer from c in atomic fashion. If there are no - // items to prefetch, set c to NULL (using compare-and-swap). - r = c.cas (&queue.front (), NULL); - - // If there are no elements prefetched, exit. - // During pipe's lifetime r should never be NULL, however, - // it can happen during pipe shutdown when items - // are being deallocated. - if (&queue.front () == r || !r) - return false; - - // There was at least one value prefetched. - return true; - } - - // Reads an item from the pipe. Returns false if there is no value. - // available. - inline bool read (T *value_) - { - // Try to prefetch a value. - if (!check_read ()) - return false; - - // There was at least one value prefetched. - // Return it to the caller. - *value_ = queue.front (); - queue.pop (); - return true; - } - - // Applies the function fn to the first elemenent in the pipe - // and returns the value returned by the fn. - // The pipe mustn't be empty or the function crashes. - inline bool probe (bool (*fn)(const T &)) - { - bool rc = check_read (); - zmq_assert (rc); - - return (*fn) (queue.front ()); - } - - protected: - - // Allocation-efficient queue to store pipe items. - // Front of the queue points to the first prefetched item, back of - // the pipe points to last un-flushed item. Front is used only by - // reader thread, while back is used only by writer thread. - yqueue_t queue; - - // Points to the first un-flushed item. This variable is used - // exclusively by writer thread. - T *w; - - // Points to the first un-prefetched item. This variable is used - // exclusively by reader thread. - T *r; - - // Points to the first item to be flushed in the future. - T *f; - - // The single point of contention between writer and reader thread. - // Points past the last flushed item. If it is NULL, - // reader is asleep. This pointer should be always accessed using - // atomic operations. - atomic_ptr_t c; - - // Disable copying of ypipe object. - ypipe_t (const ypipe_t&); - const ypipe_t &operator = (const ypipe_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/ypipe_base.hpp b/dep/libzmq/src/ypipe_base.hpp deleted file mode 100644 index 7b7d5ece42..0000000000 --- a/dep/libzmq/src/ypipe_base.hpp +++ /dev/null @@ -1,54 +0,0 @@ - -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_YPIPE_BASE_HPP_INCLUDED__ -#define __ZMQ_YPIPE_BASE_HPP_INCLUDED__ - - -namespace zmq -{ - // ypipe_base abstracts ypipe and ypipe_conflate specific - // classes, one is selected according to a the conflate - // socket option - - template class ypipe_base_t - { - public: - virtual ~ypipe_base_t () {} - virtual void write (const T &value_, bool incomplete_) = 0; - virtual bool unwrite (T *value_) = 0; - virtual bool flush () = 0; - virtual bool check_read () = 0; - virtual bool read (T *value_) = 0; - virtual bool probe (bool (*fn)(const T &)) = 0; - }; -} - -#endif diff --git a/dep/libzmq/src/ypipe_conflate.hpp b/dep/libzmq/src/ypipe_conflate.hpp deleted file mode 100644 index ab903c92ea..0000000000 --- a/dep/libzmq/src/ypipe_conflate.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_YPIPE_CONFLATE_HPP_INCLUDED__ -#define __ZMQ_YPIPE_CONFLATE_HPP_INCLUDED__ - -#include "platform.hpp" -#include "dbuffer.hpp" -#include "ypipe_base.hpp" - -namespace zmq -{ - - // Adapter for dbuffer, to plug it in instead of a queue for the sake - // of implementing the conflate socket option, which, if set, makes - // the receiving side to discard all incoming messages but the last one. - // - // reader_awake flag is needed here to mimic ypipe delicate behaviour - // around the reader being asleep (see 'c' pointer being NULL in ypipe.hpp) - - template class ypipe_conflate_t : public ypipe_base_t - { - public: - - // Initialises the pipe. - inline ypipe_conflate_t () - : reader_awake(false) - { - } - - // The destructor doesn't have to be virtual. It is made virtual - // just to keep ICC and code checking tools from complaining. - inline virtual ~ypipe_conflate_t () - { - } - - // Following function (write) deliberately copies uninitialised data - // when used with zmq_msg. Initialising the VSM body for - // non-VSM messages won't be good for performance. - -#ifdef ZMQ_HAVE_OPENVMS -#pragma message save -#pragma message disable(UNINIT) -#endif - inline void write (const T &value_, bool incomplete_) - { - (void)incomplete_; - - dbuffer.write (value_); - } - -#ifdef ZMQ_HAVE_OPENVMS -#pragma message restore -#endif - - // There are no incomplete items for conflate ypipe - inline bool unwrite (T *) - { - return false; - } - - // Flush is no-op for conflate ypipe. Reader asleep behaviour - // is as of the usual ypipe. - // Returns false if the reader thread is sleeping. In that case, - // caller is obliged to wake the reader up before using the pipe again. - inline bool flush () - { - return reader_awake; - } - - // Check whether item is available for reading. - inline bool check_read () - { - bool res = dbuffer.check_read (); - if (!res) - reader_awake = false; - - return res; - } - - // Reads an item from the pipe. Returns false if there is no value. - // available. - inline bool read (T *value_) - { - if (!check_read ()) - return false; - - return dbuffer.read (value_); - } - - // Applies the function fn to the first elemenent in the pipe - // and returns the value returned by the fn. - // The pipe mustn't be empty or the function crashes. - inline bool probe (bool (*fn)(const T &)) - { - return dbuffer.probe (fn); - } - - protected: - - dbuffer_t dbuffer; - bool reader_awake; - - // Disable copying of ypipe object. - ypipe_conflate_t (const ypipe_conflate_t&); - const ypipe_conflate_t &operator = (const ypipe_conflate_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/yqueue.hpp b/dep/libzmq/src/yqueue.hpp deleted file mode 100644 index d8afd85b60..0000000000 --- a/dep/libzmq/src/yqueue.hpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_YQUEUE_HPP_INCLUDED__ -#define __ZMQ_YQUEUE_HPP_INCLUDED__ - -#include -#include - -#include "err.hpp" -#include "atomic_ptr.hpp" - -namespace zmq -{ - - // yqueue is an efficient queue implementation. The main goal is - // to minimise number of allocations/deallocations needed. Thus yqueue - // allocates/deallocates elements in batches of N. - // - // yqueue allows one thread to use push/back function and another one - // to use pop/front functions. However, user must ensure that there's no - // pop on the empty queue and that both threads don't access the same - // element in unsynchronised manner. - // - // T is the type of the object in the queue. - // N is granularity of the queue (how many pushes have to be done till - // actual memory allocation is required). -#ifdef HAVE_POSIX_MEMALIGN - // ALIGN is the memory alignment size to use in the case where we have - // posix_memalign available. Default value is 64, this alignment will - // prevent two queue chunks from occupying the same CPU cache line on - // architectures where cache lines are <= 64 bytes (e.g. most things - // except POWER). - template class yqueue_t -#else - template class yqueue_t -#endif - { - public: - - // Create the queue. - inline yqueue_t () - { - begin_chunk = allocate_chunk(); - alloc_assert (begin_chunk); - begin_pos = 0; - back_chunk = NULL; - back_pos = 0; - end_chunk = begin_chunk; - end_pos = 0; - } - - // Destroy the queue. - inline ~yqueue_t () - { - while (true) { - if (begin_chunk == end_chunk) { - free (begin_chunk); - break; - } - chunk_t *o = begin_chunk; - begin_chunk = begin_chunk->next; - free (o); - } - - chunk_t *sc = spare_chunk.xchg (NULL); - free (sc); - } - - // Returns reference to the front element of the queue. - // If the queue is empty, behaviour is undefined. - inline T &front () - { - return begin_chunk->values [begin_pos]; - } - - // Returns reference to the back element of the queue. - // If the queue is empty, behaviour is undefined. - inline T &back () - { - return back_chunk->values [back_pos]; - } - - // Adds an element to the back end of the queue. - inline void push () - { - back_chunk = end_chunk; - back_pos = end_pos; - - if (++end_pos != N) - return; - - chunk_t *sc = spare_chunk.xchg (NULL); - if (sc) { - end_chunk->next = sc; - sc->prev = end_chunk; - } else { - end_chunk->next = allocate_chunk(); - alloc_assert (end_chunk->next); - end_chunk->next->prev = end_chunk; - } - end_chunk = end_chunk->next; - end_pos = 0; - } - - // Removes element from the back end of the queue. In other words - // it rollbacks last push to the queue. Take care: Caller is - // responsible for destroying the object being unpushed. - // The caller must also guarantee that the queue isn't empty when - // unpush is called. It cannot be done automatically as the read - // side of the queue can be managed by different, completely - // unsynchronised thread. - inline void unpush () - { - // First, move 'back' one position backwards. - if (back_pos) - --back_pos; - else { - back_pos = N - 1; - back_chunk = back_chunk->prev; - } - - // Now, move 'end' position backwards. Note that obsolete end chunk - // is not used as a spare chunk. The analysis shows that doing so - // would require free and atomic operation per chunk deallocated - // instead of a simple free. - if (end_pos) - --end_pos; - else { - end_pos = N - 1; - end_chunk = end_chunk->prev; - free (end_chunk->next); - end_chunk->next = NULL; - } - } - - // Removes an element from the front end of the queue. - inline void pop () - { - if (++ begin_pos == N) { - chunk_t *o = begin_chunk; - begin_chunk = begin_chunk->next; - begin_chunk->prev = NULL; - begin_pos = 0; - - // 'o' has been more recently used than spare_chunk, - // so for cache reasons we'll get rid of the spare and - // use 'o' as the spare. - chunk_t *cs = spare_chunk.xchg (o); - free (cs); - } - } - - private: - - // Individual memory chunk to hold N elements. - struct chunk_t - { - T values [N]; - chunk_t *prev; - chunk_t *next; - }; - - inline chunk_t *allocate_chunk () - { -#ifdef HAVE_POSIX_MEMALIGN - void *pv; - if (posix_memalign(&pv, ALIGN, sizeof (chunk_t)) == 0) - return (chunk_t*) pv; - return NULL; -#else - return (chunk_t*) malloc (sizeof (chunk_t)); -#endif - } - - // Back position may point to invalid memory if the queue is empty, - // while begin & end positions are always valid. Begin position is - // accessed exclusively be queue reader (front/pop), while back and - // end positions are accessed exclusively by queue writer (back/push). - chunk_t *begin_chunk; - int begin_pos; - chunk_t *back_chunk; - int back_pos; - chunk_t *end_chunk; - int end_pos; - - // People are likely to produce and consume at similar rates. In - // this scenario holding onto the most recently freed chunk saves - // us from having to call malloc/free. - atomic_ptr_t spare_chunk; - - // Disable copying of yqueue. - yqueue_t (const yqueue_t&); - const yqueue_t &operator = (const yqueue_t&); - }; - -} - -#endif diff --git a/dep/libzmq/src/zap_client.cpp b/dep/libzmq/src/zap_client.cpp deleted file mode 100644 index e44b0e20ab..0000000000 --- a/dep/libzmq/src/zap_client.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include "zap_client.hpp" -#include "msg.hpp" -#include "session_base.hpp" - -namespace zmq -{ -zap_client_t::zap_client_t (session_base_t *const session_, - const std::string &peer_address_, - const options_t &options_) : - mechanism_base_t (session_, options_), - peer_address (peer_address_) -{ -} - -void zap_client_t::send_zap_request (const char *mechanism, - size_t mechanism_length, - const uint8_t *credentials, - size_t credentials_size) -{ - send_zap_request (mechanism, mechanism_length, &credentials, - &credentials_size, 1); -} - -void zap_client_t::send_zap_request (const char *mechanism, - size_t mechanism_length, - const uint8_t **credentials, - size_t *credentials_sizes, - size_t credentials_count) -{ - // write_zap_msg cannot fail. It could only fail if the HWM was exceeded, - // but on the ZAP socket, the HWM is disabled. - - int rc; - msg_t msg; - - // Address delimiter frame - rc = msg.init (); - errno_assert (rc == 0); - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Version frame - rc = msg.init_size (3); - errno_assert (rc == 0); - memcpy (msg.data (), "1.0", 3); - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Request ID frame - rc = msg.init_size (1); - errno_assert (rc == 0); - memcpy (msg.data (), "1", 1); - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Domain frame - rc = msg.init_size (options.zap_domain.length ()); - errno_assert (rc == 0); - memcpy (msg.data (), options.zap_domain.c_str (), - options.zap_domain.length ()); - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Address frame - rc = msg.init_size (peer_address.length ()); - errno_assert (rc == 0); - memcpy (msg.data (), peer_address.c_str (), peer_address.length ()); - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Routing id frame - rc = msg.init_size (options.routing_id_size); - errno_assert (rc == 0); - memcpy (msg.data (), options.routing_id, options.routing_id_size); - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Mechanism frame - rc = msg.init_size (mechanism_length); - errno_assert (rc == 0); - memcpy (msg.data (), mechanism, mechanism_length); - if (credentials_count) - msg.set_flags (msg_t::more); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - - // Credentials frames - for (size_t i = 0; i < credentials_count; ++i) { - rc = msg.init_size (credentials_sizes[i]); - errno_assert (rc == 0); - if (i < credentials_count - 1) - msg.set_flags (msg_t::more); - memcpy (msg.data (), credentials[i], credentials_sizes[i]); - rc = session->write_zap_msg (&msg); - errno_assert (rc == 0); - } -} - -int zap_client_t::receive_and_process_zap_reply () -{ - int rc = 0; - msg_t msg[7]; // ZAP reply consists of 7 frames - - // Initialize all reply frames - for (int i = 0; i < 7; i++) { - rc = msg[i].init (); - errno_assert (rc == 0); - } - - for (int i = 0; i < 7; i++) { - rc = session->read_zap_msg (&msg[i]); - if (rc == -1) { - if (errno == EAGAIN) { - return 1; - } - return close_and_return (msg, -1); - } - if ((msg[i].flags () & msg_t::more) == (i < 6 ? 0 : msg_t::more)) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY); - errno = EPROTO; - return close_and_return (msg, -1); - } - } - - // Address delimiter frame - if (msg[0].size () > 0) { - // TODO can a ZAP handler produce such a message at all? - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED); - errno = EPROTO; - return close_and_return (msg, -1); - } - - // Version frame - if (msg[1].size () != 3 || memcmp (msg[1].data (), "1.0", 3)) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION); - errno = EPROTO; - return close_and_return (msg, -1); - } - - // Request id frame - if (msg[2].size () != 1 || memcmp (msg[2].data (), "1", 1)) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID); - errno = EPROTO; - return close_and_return (msg, -1); - } - - // Status code frame, only 200, 300, 400 and 500 are valid status codes - char *status_code_data = static_cast (msg[3].data ()); - if (msg[3].size () != 3 || status_code_data[0] < '2' - || status_code_data[0] > '5' || status_code_data[1] != '0' - || status_code_data[2] != '0') { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE); - errno = EPROTO; - return close_and_return (msg, -1); - } - - // Save status code - status_code.assign (static_cast (msg[3].data ()), 3); - - // Save user id - set_user_id (msg[5].data (), msg[5].size ()); - - // Process metadata frame - rc = parse_metadata (static_cast (msg[6].data ()), - msg[6].size (), true); - - if (rc != 0) { - session->get_socket ()->event_handshake_failed_protocol ( - session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA); - errno = EPROTO; - return close_and_return (msg, -1); - } - - // Close all reply frames - for (int i = 0; i < 7; i++) { - const int rc2 = msg[i].close (); - errno_assert (rc2 == 0); - } - - handle_zap_status_code (); - - return 0; -} - -void zap_client_t::handle_zap_status_code () -{ - // we can assume here that status_code is a valid ZAP status code, - // i.e. 200, 300, 400 or 500 - int status_code_numeric = 0; - switch (status_code[0]) { - case '2': - return; - case '3': - status_code_numeric = 300; - break; - case '4': - status_code_numeric = 400; - break; - case '5': - status_code_numeric = 500; - break; - } - - session->get_socket ()->event_handshake_failed_auth ( - session->get_endpoint (), status_code_numeric); -} - -zap_client_common_handshake_t::zap_client_common_handshake_t ( - session_base_t *const session_, - const std::string &peer_address_, - const options_t &options_, - state_t zap_reply_ok_state_) : - mechanism_base_t (session_, options_), - zap_client_t (session_, peer_address_, options_), - state (waiting_for_hello), - zap_reply_ok_state (zap_reply_ok_state_) -{ -} - -zmq::mechanism_t::status_t zap_client_common_handshake_t::status () const -{ - if (state == ready) - return mechanism_t::ready; - else if (state == error_sent) - return mechanism_t::error; - else - return mechanism_t::handshaking; -} - -int zap_client_common_handshake_t::zap_msg_available () -{ - zmq_assert (state == waiting_for_zap_reply); - return receive_and_process_zap_reply () == -1 ? -1 : 0; -} - -void zap_client_common_handshake_t::handle_zap_status_code () -{ - zap_client_t::handle_zap_status_code (); - - // we can assume here that status_code is a valid ZAP status code, - // i.e. 200, 300, 400 or 500 - switch (status_code[0]) { - case '2': - state = zap_reply_ok_state; - break; - case '3': - // a 300 error code (temporary failure) - // should NOT result in an ERROR message, but instead the - // client should be silently disconnected (see CURVEZMQ RFC) - // therefore, go immediately to state error_sent - state = error_sent; - break; - default: - state = sending_error; - } -} - -int zap_client_common_handshake_t::receive_and_process_zap_reply () -{ - zmq_assert (state == waiting_for_zap_reply); - return zap_client_t::receive_and_process_zap_reply (); -} -} diff --git a/dep/libzmq/src/zap_client.hpp b/dep/libzmq/src/zap_client.hpp deleted file mode 100644 index 557cab6026..0000000000 --- a/dep/libzmq/src/zap_client.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_ZAP_CLIENT_HPP_INCLUDED__ -#define __ZMQ_ZAP_CLIENT_HPP_INCLUDED__ - -#include "mechanism_base.hpp" - -namespace zmq -{ -class zap_client_t : public virtual mechanism_base_t -{ - public: - zap_client_t (session_base_t *const session_, - const std::string &peer_address_, - const options_t &options_); - - void send_zap_request (const char *mechanism, - size_t mechanism_length, - const uint8_t *credentials, - size_t credentials_size); - - void send_zap_request (const char *mechanism, - size_t mechanism_length, - const uint8_t **credentials, - size_t *credentials_sizes, - size_t credentials_count); - - virtual int receive_and_process_zap_reply (); - virtual void handle_zap_status_code (); - protected: - const std::string peer_address; - - // Status code as received from ZAP handler - std::string status_code; -}; - -class zap_client_common_handshake_t : public zap_client_t -{ - protected: - enum state_t - { - waiting_for_hello, - sending_welcome, - waiting_for_initiate, - waiting_for_zap_reply, - sending_ready, - sending_error, - error_sent, - ready - }; - - zap_client_common_handshake_t (session_base_t *const session_, - const std::string &peer_address_, - const options_t &options_, - state_t zap_reply_ok_state); - - // methods from mechanism_t - status_t status () const; - int zap_msg_available (); - - // zap_client_t methods - int receive_and_process_zap_reply (); - void handle_zap_status_code (); - - // Current FSM state - state_t state; - - private: - const state_t zap_reply_ok_state; -}; -} - -#endif diff --git a/dep/libzmq/src/zmq.cpp b/dep/libzmq/src/zmq.cpp deleted file mode 100644 index 9d4c00630e..0000000000 --- a/dep/libzmq/src/zmq.cpp +++ /dev/null @@ -1,1527 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -// "Tell them I was a writer. -// A maker of software. -// A humanist. A father. -// And many things. -// But above all, a writer. -// Thank You. :)" -// - Pieter Hintjens - -#include "precompiled.hpp" -#define ZMQ_TYPE_UNSAFE - -#include "macros.hpp" -#include "poller.hpp" - -// On AIX platform, poll.h has to be included first to get consistent -// definition of pollfd structure (AIX uses 'reqevents' and 'retnevents' -// instead of 'events' and 'revents' and defines macros to map from POSIX-y -// names to AIX-specific names). -#if defined ZMQ_POLL_BASED_ON_POLL && !defined ZMQ_HAVE_WINDOWS -#include -#endif - -// TODO: determine if this is an issue, since zmq.h is being loaded from pch. -// zmq.h must be included *after* poll.h for AIX to build properly -//#include "../include/zmq.h" - -#if !defined ZMQ_HAVE_WINDOWS -#include -#endif - -// XSI vector I/O -#if defined ZMQ_HAVE_UIO -#include -#else -struct iovec { - void *iov_base; - size_t iov_len; -}; -#endif - -#include -#include -#include -#include - -#include "proxy.hpp" -#include "socket_base.hpp" -#include "stdint.hpp" -#include "config.hpp" -#include "likely.hpp" -#include "clock.hpp" -#include "ctx.hpp" -#include "err.hpp" -#include "msg.hpp" -#include "fd.hpp" -#include "metadata.hpp" -#include "signaler.hpp" -#include "socket_poller.hpp" -#include "timers.hpp" - -#if defined ZMQ_HAVE_OPENPGM -#define __PGM_WININT_H__ -#include -#endif - -// Compile time check whether msg_t fits into zmq_msg_t. -typedef char check_msg_t_size - [sizeof (zmq::msg_t) == sizeof (zmq_msg_t) ? 1 : -1]; - - -void zmq_version (int *major_, int *minor_, int *patch_) -{ - *major_ = ZMQ_VERSION_MAJOR; - *minor_ = ZMQ_VERSION_MINOR; - *patch_ = ZMQ_VERSION_PATCH; -} - - -const char *zmq_strerror (int errnum_) -{ - return zmq::errno_to_string (errnum_); -} - -int zmq_errno (void) -{ - return errno; -} - - -// New context API - -void *zmq_ctx_new (void) -{ -#if defined ZMQ_HAVE_OPENPGM - - // Init PGM transport. Ensure threading and timer are enabled. Find PGM - // protocol ID. Note that if you want to use gettimeofday and sleep for - // openPGM timing, set environment variables PGM_TIMER to "GTOD" and - // PGM_SLEEP to "USLEEP". - pgm_error_t *pgm_error = NULL; - const bool ok = pgm_init (&pgm_error); - if (ok != TRUE) { - - // Invalid parameters don't set pgm_error_t - zmq_assert (pgm_error != NULL); - if (pgm_error->domain == PGM_ERROR_DOMAIN_TIME && ( - pgm_error->code == PGM_ERROR_FAILED)) { - - // Failed to access RTC or HPET device. - pgm_error_free (pgm_error); - errno = EINVAL; - return NULL; - } - - // PGM_ERROR_DOMAIN_ENGINE: WSAStartup errors or missing WSARecvMsg. - zmq_assert (false); - } -#endif - -#ifdef ZMQ_HAVE_WINDOWS - // Intialise Windows sockets. Note that WSAStartup can be called multiple - // times given that WSACleanup will be called for each WSAStartup. - // We do this before the ctx constructor since its embedded mailbox_t - // object needs Winsock to be up and running. - WORD version_requested = MAKEWORD (2, 2); - WSADATA wsa_data; - int rc = WSAStartup (version_requested, &wsa_data); - zmq_assert (rc == 0); - zmq_assert (LOBYTE (wsa_data.wVersion) == 2 && - HIBYTE (wsa_data.wVersion) == 2); -#endif - - // Create 0MQ context. - zmq::ctx_t *ctx = new (std::nothrow) zmq::ctx_t; - alloc_assert (ctx); - return ctx; -} - -int zmq_ctx_term (void *ctx_) -{ - if (!ctx_ || !((zmq::ctx_t *) ctx_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - int rc = ((zmq::ctx_t *) ctx_)->terminate (); - int en = errno; - - // Shut down only if termination was not interrupted by a signal. - if (!rc || en != EINTR) { -#ifdef ZMQ_HAVE_WINDOWS - // On Windows, uninitialise socket layer. - rc = WSACleanup (); - wsa_assert (rc != SOCKET_ERROR); -#endif - -#if defined ZMQ_HAVE_OPENPGM - // Shut down the OpenPGM library. - if (pgm_shutdown () != TRUE) - zmq_assert (false); -#endif - } - - errno = en; - return rc; -} - -int zmq_ctx_shutdown (void *ctx_) -{ - if (!ctx_ || !((zmq::ctx_t *) ctx_)->check_tag ()) { - errno = EFAULT; - return -1; - } - return ((zmq::ctx_t *) ctx_)->shutdown (); -} - -int zmq_ctx_set (void *ctx_, int option_, int optval_) -{ - if (!ctx_ || !((zmq::ctx_t *) ctx_)->check_tag ()) { - errno = EFAULT; - return -1; - } - return ((zmq::ctx_t *) ctx_)->set (option_, optval_); -} - -int zmq_ctx_get (void *ctx_, int option_) -{ - if (!ctx_ || !((zmq::ctx_t *) ctx_)->check_tag ()) { - errno = EFAULT; - return -1; - } - return ((zmq::ctx_t *) ctx_)->get (option_); -} - -// Stable/legacy context API - -void *zmq_init (int io_threads_) -{ - if (io_threads_ >= 0) { - void *ctx = zmq_ctx_new (); - zmq_ctx_set (ctx, ZMQ_IO_THREADS, io_threads_); - return ctx; - } - errno = EINVAL; - return NULL; -} - -int zmq_term (void *ctx_) -{ - return zmq_ctx_term (ctx_); -} - -int zmq_ctx_destroy (void *ctx_) -{ - return zmq_ctx_term (ctx_); -} - - -// Sockets - -static zmq::socket_base_t *as_socket_base_t (void *s_) -{ - zmq::socket_base_t *s = static_cast (s_); - if (!s_ || !s->check_tag ()) { - errno = ENOTSOCK; - return NULL; - } - return s; -} - -void *zmq_socket (void *ctx_, int type_) -{ - if (!ctx_ || !((zmq::ctx_t *) ctx_)->check_tag ()) { - errno = EFAULT; - return NULL; - } - zmq::ctx_t *ctx = (zmq::ctx_t *) ctx_; - zmq::socket_base_t *s = ctx->create_socket (type_); - return (void *) s; -} - -int zmq_close (void *s_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - s->close (); - return 0; -} - -int zmq_setsockopt (void *s_, int option_, const void *optval_, - size_t optvallen_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->setsockopt (option_, optval_, optvallen_); -} - -int zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->getsockopt (option_, optval_, optvallen_); -} - -int zmq_socket_monitor (void *s_, const char *addr_, int events_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->monitor (addr_, events_); -} - -int zmq_join (void *s_, const char* group_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->join (group_); -} - -int zmq_leave (void *s_, const char* group_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->leave (group_); -} - -int zmq_bind (void *s_, const char *addr_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->bind (addr_); -} - -int zmq_connect (void *s_, const char *addr_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->connect (addr_); -} - -int zmq_unbind (void *s_, const char *addr_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->term_endpoint (addr_); -} - -int zmq_disconnect (void *s_, const char *addr_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s->term_endpoint (addr_); -} - -// Sending functions. - -static inline int -s_sendmsg (zmq::socket_base_t *s_, zmq_msg_t *msg_, int flags_) -{ - size_t sz = zmq_msg_size (msg_); - int rc = s_->send ((zmq::msg_t *) msg_, flags_); - if (unlikely (rc < 0)) - return -1; - - // This is what I'd like to do, my C++ fu is too weak -- PH 2016/02/09 - // int max_msgsz = s_->parent->get (ZMQ_MAX_MSGSZ); - size_t max_msgsz = INT_MAX; - - // Truncate returned size to INT_MAX to avoid overflow to negative values - return (int) (sz < max_msgsz? sz: max_msgsz); -} - -/* To be deprecated once zmq_msg_send() is stable */ -int zmq_sendmsg (void *s_, zmq_msg_t *msg_, int flags_) -{ - return zmq_msg_send (msg_, s_, flags_); -} - -int zmq_send (void *s_, const void *buf_, size_t len_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - zmq_msg_t msg; - if (zmq_msg_init_size (&msg, len_)) - return -1; - - // We explicitly allow a send from NULL, size zero - if (len_) { - assert (buf_); - memcpy (zmq_msg_data (&msg), buf_, len_); - } - int rc = s_sendmsg (s, &msg, flags_); - if (unlikely (rc < 0)) { - int err = errno; - int rc2 = zmq_msg_close (&msg); - errno_assert (rc2 == 0); - errno = err; - return -1; - } - // Note the optimisation here. We don't close the msg object as it is - // empty anyway. This may change when implementation of zmq_msg_t changes. - return rc; -} - -int zmq_send_const (void *s_, const void *buf_, size_t len_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - zmq_msg_t msg; - int rc = zmq_msg_init_data (&msg, (void *)buf_, len_, NULL, NULL); - if (rc != 0) - return -1; - - rc = s_sendmsg (s, &msg, flags_); - if (unlikely (rc < 0)) { - int err = errno; - int rc2 = zmq_msg_close (&msg); - errno_assert (rc2 == 0); - errno = err; - return -1; - } - // Note the optimisation here. We don't close the msg object as it is - // empty anyway. This may change when implementation of zmq_msg_t changes. - return rc; -} - - -// Send multiple messages. -// TODO: this function has no man page -// -// If flag bit ZMQ_SNDMORE is set the vector is treated as -// a single multi-part message, i.e. the last message has -// ZMQ_SNDMORE bit switched off. -// -int zmq_sendiov (void *s_, iovec *a_, size_t count_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - if (unlikely (count_ <= 0 || !a_)) { - errno = EINVAL; - return -1; - } - - int rc = 0; - zmq_msg_t msg; - - for (size_t i = 0; i < count_; ++i) { - rc = zmq_msg_init_size (&msg, a_[i].iov_len); - if (rc != 0) { - rc = -1; - break; - } - memcpy (zmq_msg_data (&msg), a_[i].iov_base, a_[i].iov_len); - if (i == count_ - 1) - flags_ = flags_ & ~ZMQ_SNDMORE; - rc = s_sendmsg (s, &msg, flags_); - if (unlikely (rc < 0)) { - int err = errno; - int rc2 = zmq_msg_close (&msg); - errno_assert (rc2 == 0); - errno = err; - rc = -1; - break; - } - } - return rc; -} - -// Receiving functions. - -static int -s_recvmsg (zmq::socket_base_t *s_, zmq_msg_t *msg_, int flags_) -{ - int rc = s_->recv ((zmq::msg_t *) msg_, flags_); - if (unlikely (rc < 0)) - return -1; - - // Truncate returned size to INT_MAX to avoid overflow to negative values - size_t sz = zmq_msg_size (msg_); - return (int) (sz < INT_MAX? sz: INT_MAX); -} - -/* To be deprecated once zmq_msg_recv() is stable */ -int zmq_recvmsg (void *s_, zmq_msg_t *msg_, int flags_) -{ - return zmq_msg_recv (msg_, s_, flags_); -} - - -int zmq_recv (void *s_, void *buf_, size_t len_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - zmq_msg_t msg; - int rc = zmq_msg_init (&msg); - errno_assert (rc == 0); - - int nbytes = s_recvmsg (s, &msg, flags_); - if (unlikely (nbytes < 0)) { - int err = errno; - rc = zmq_msg_close (&msg); - errno_assert (rc == 0); - errno = err; - return -1; - } - - // An oversized message is silently truncated. - size_t to_copy = size_t (nbytes) < len_ ? size_t (nbytes) : len_; - - // We explicitly allow a null buffer argument if len is zero - if (to_copy) { - assert (buf_); - memcpy (buf_, zmq_msg_data (&msg), to_copy); - } - rc = zmq_msg_close (&msg); - errno_assert (rc == 0); - - return nbytes; -} - -// Receive a multi-part message -// -// Receives up to *count_ parts of a multi-part message. -// Sets *count_ to the actual number of parts read. -// ZMQ_RCVMORE is set to indicate if a complete multi-part message was read. -// Returns number of message parts read, or -1 on error. -// -// Note: even if -1 is returned, some parts of the message -// may have been read. Therefore the client must consult -// *count_ to retrieve message parts successfully read, -// even if -1 is returned. -// -// The iov_base* buffers of each iovec *a_ filled in by this -// function may be freed using free(). -// TODO: this function has no man page -// -int zmq_recviov (void *s_, iovec *a_, size_t *count_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - if (unlikely (!count_ || *count_ <= 0 || !a_)) { - errno = EINVAL; - return -1; - } - - size_t count = *count_; - int nread = 0; - bool recvmore = true; - - *count_ = 0; - - for (size_t i = 0; recvmore && i < count; ++i) { - - zmq_msg_t msg; - int rc = zmq_msg_init (&msg); - errno_assert (rc == 0); - - int nbytes = s_recvmsg (s, &msg, flags_); - if (unlikely (nbytes < 0)) { - int err = errno; - rc = zmq_msg_close (&msg); - errno_assert (rc == 0); - errno = err; - nread = -1; - break; - } - - a_[i].iov_len = zmq_msg_size (&msg); - a_[i].iov_base = static_cast (malloc(a_[i].iov_len)); - if (unlikely (!a_[i].iov_base)) { - errno = ENOMEM; - return -1; - } - memcpy(a_[i].iov_base,static_cast (zmq_msg_data (&msg)), - a_[i].iov_len); - // Assume zmq_socket ZMQ_RVCMORE is properly set. - zmq::msg_t* p_msg = reinterpret_cast(&msg); - recvmore = p_msg->flags() & zmq::msg_t::more; - rc = zmq_msg_close(&msg); - errno_assert (rc == 0); - ++*count_; - ++nread; - } - return nread; -} - -// Message manipulators. - -int zmq_msg_init (zmq_msg_t *msg_) -{ - return ((zmq::msg_t*) msg_)->init (); -} - -int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_) -{ - return ((zmq::msg_t*) msg_)->init_size (size_); -} - -int zmq_msg_init_data (zmq_msg_t *msg_, void *data_, size_t size_, - zmq_free_fn *ffn_, void *hint_) -{ - return ((zmq::msg_t*) msg_)->init_data (data_, size_, ffn_, hint_); -} - -int zmq_msg_send (zmq_msg_t *msg_, void *s_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s_sendmsg (s, msg_, flags_); -} - -int zmq_msg_recv (zmq_msg_t *msg_, void *s_, int flags_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - return s_recvmsg (s, msg_, flags_); -} - -int zmq_msg_close (zmq_msg_t *msg_) -{ - return ((zmq::msg_t*) msg_)->close (); -} - -int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_) -{ - return ((zmq::msg_t*) dest_)->move (*(zmq::msg_t*) src_); -} - -int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_) -{ - return ((zmq::msg_t*) dest_)->copy (*(zmq::msg_t*) src_); -} - -void *zmq_msg_data (zmq_msg_t *msg_) -{ - return ((zmq::msg_t*) msg_)->data (); -} - -size_t zmq_msg_size (const zmq_msg_t *msg_) -{ - return ((zmq::msg_t*) msg_)->size (); -} - -int zmq_msg_more (const zmq_msg_t *msg_) -{ - return zmq_msg_get (msg_, ZMQ_MORE); -} - -int zmq_msg_get (const zmq_msg_t *msg_, int property_) -{ - const char* fd_string; - - switch (property_) { - case ZMQ_MORE: - return (((zmq::msg_t*) msg_)->flags () & zmq::msg_t::more)? 1: 0; - case ZMQ_SRCFD: - fd_string = zmq_msg_gets(msg_, "__fd"); - if (fd_string == NULL) - return (int)-1; - - return atoi(fd_string); - case ZMQ_SHARED: - return (((zmq::msg_t*) msg_)->is_cmsg ()) || - (((zmq::msg_t*) msg_)->flags () & zmq::msg_t::shared)? 1: 0; - default: - errno = EINVAL; - return -1; - } -} - -int zmq_msg_set (zmq_msg_t *, int, int) -{ - // No properties supported at present - errno = EINVAL; - return -1; -} - -int zmq_msg_set_routing_id (zmq_msg_t *msg_, uint32_t routing_id_) -{ - return ((zmq::msg_t *) msg_)->set_routing_id (routing_id_); -} - -uint32_t zmq_msg_routing_id (zmq_msg_t *msg_) -{ - return ((zmq::msg_t *) msg_)->get_routing_id (); -} - -int zmq_msg_set_group (zmq_msg_t *msg_, const char *group_) -{ - return ((zmq::msg_t *) msg_)->set_group (group_); -} - -const char *zmq_msg_group (zmq_msg_t *msg_) -{ - return ((zmq::msg_t *) msg_)->group (); -} - -// Get message metadata string - -const char *zmq_msg_gets (const zmq_msg_t *msg_, const char *property_) -{ - zmq::metadata_t *metadata = ((zmq::msg_t *) msg_)->metadata (); - const char *value = NULL; - if (metadata) - value = metadata->get (std::string (property_)); - if (value) - return value; - else { - errno = EINVAL; - return NULL; - } -} - -// Polling. - -#if defined ZMQ_HAVE_POLLER -inline int zmq_poller_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) -{ - // implement zmq_poll on top of zmq_poller - int rc; - zmq_poller_event_t *events; - zmq::socket_poller_t poller; - events = new (std::nothrow) zmq_poller_event_t[nitems_]; - alloc_assert(events); - - bool repeat_items = false; - // Register sockets with poller - for (int i = 0; i < nitems_; i++) { - items_[i].revents = 0; - - bool modify = false; - short e = items_[i].events; - if (items_[i].socket) { - // Poll item is a 0MQ socket. - for (int j = 0; j < i; ++j) { - // Check for repeat entries - if (items_[j].socket == items_[i].socket) { - repeat_items = true; - modify = true; - e |= items_[j].events; - } - } - if (modify) { - rc = zmq_poller_modify (&poller, items_[i].socket, e); - } else { - rc = zmq_poller_add (&poller, items_[i].socket, NULL, e); - } - if (rc < 0) { - delete [] events; - return rc; - } - } else { - // Poll item is a raw file descriptor. - for (int j = 0; j < i; ++j) { - // Check for repeat entries - if (!items_[j].socket && items_[j].fd == items_[i].fd) { - repeat_items = true; - modify = true; - e |= items_[j].events; - } - } - if (modify) { - rc = zmq_poller_modify_fd (&poller, items_[i].fd, e); - } else { - rc = zmq_poller_add_fd (&poller, items_[i].fd, NULL, e); - } - if (rc < 0) { - delete [] events; - return rc; - } - } - } - - // Wait for events - rc = zmq_poller_wait_all (&poller, events, nitems_, timeout_); - if (rc < 0) { - delete [] events; - if (zmq_errno() == EAGAIN) { - return 0; - } - return rc; - } - - // Transform poller events into zmq_pollitem events. - // items_ contains all items, while events only contains fired events. - // If no sockets are repeated (likely), the two are still co-ordered, so step through the items - // checking for matches only on the first event. - // If there are repeat items, they cannot be assumed to be co-ordered, - // so each pollitem must check fired events from the beginning. - int j_start = 0, found_events = rc; - for (int i = 0; i < nitems_; i++) { - for (int j = j_start; j < found_events; ++j) { - if ( - (items_[i].socket && items_[i].socket == events[j].socket) || - (!(items_[i].socket || events[j].socket) && items_[i].fd == events[j].fd) - ) { - items_[i].revents = events[j].events & items_[i].events; - if (!repeat_items) { - // no repeats, we can ignore events we've already seen - j_start++; - } - break; - } - if (!repeat_items) { - // no repeats, never have to look at j > j_start - break; - } - } - } - - // Cleanup - delete [] events; - return rc; -} -#endif // ZMQ_HAVE_POLLER - -int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) -{ - // TODO: the function implementation can just call zmq_pollfd_poll with - // pollfd as NULL, however pollfd is not yet stable. -#if defined ZMQ_HAVE_POLLER - // if poller is present, use that. - return zmq_poller_poll(items_, nitems_, timeout_); -#else -#if defined ZMQ_POLL_BASED_ON_POLL - if (unlikely (nitems_ < 0)) { - errno = EINVAL; - return -1; - } - if (unlikely (nitems_ == 0)) { - if (timeout_ == 0) - return 0; -#if defined ZMQ_HAVE_WINDOWS - Sleep (timeout_ > 0 ? timeout_ : INFINITE); - return 0; -#elif defined ZMQ_HAVE_ANDROID - usleep (timeout_ * 1000); - return 0; -#else - return usleep (timeout_ * 1000); -#endif - } - - if (!items_) { - errno = EFAULT; - return -1; - } - - zmq::clock_t clock; - uint64_t now = 0; - uint64_t end = 0; - pollfd spollfds[ZMQ_POLLITEMS_DFLT]; - pollfd *pollfds = spollfds; - - if (nitems_ > ZMQ_POLLITEMS_DFLT) { - pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd)); - alloc_assert (pollfds); - } - - // Build pollset for poll () system call. - for (int i = 0; i != nitems_; i++) { - - // If the poll item is a 0MQ socket, we poll on the file descriptor - // retrieved by the ZMQ_FD socket option. - if (items_ [i].socket) { - size_t zmq_fd_size = sizeof (zmq::fd_t); - if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, &pollfds [i].fd, - &zmq_fd_size) == -1) { - if (pollfds != spollfds) - free (pollfds); - return -1; - } - pollfds [i].events = items_ [i].events ? POLLIN : 0; - } - // Else, the poll item is a raw file descriptor. Just convert the - // events to normal POLLIN/POLLOUT for poll (). - else { - pollfds [i].fd = items_ [i].fd; - pollfds [i].events = - (items_ [i].events & ZMQ_POLLIN ? POLLIN : 0) | - (items_ [i].events & ZMQ_POLLOUT ? POLLOUT : 0) | - (items_ [i].events & ZMQ_POLLPRI ? POLLPRI : 0); - } - } - - bool first_pass = true; - int nevents = 0; - - while (true) { - // Compute the timeout for the subsequent poll. - int timeout; - if (first_pass) - timeout = 0; - else - if (timeout_ < 0) - timeout = -1; - else - timeout = end - now; - - // Wait for events. - { - int rc = poll (pollfds, nitems_, timeout); - if (rc == -1 && errno == EINTR) { - if (pollfds != spollfds) - free (pollfds); - return -1; - } - errno_assert (rc >= 0); - } - // Check for the events. - for (int i = 0; i != nitems_; i++) { - - items_ [i].revents = 0; - - // The poll item is a 0MQ socket. Retrieve pending events - // using the ZMQ_EVENTS socket option. - if (items_ [i].socket) { - size_t zmq_events_size = sizeof (uint32_t); - uint32_t zmq_events; - if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events, - &zmq_events_size) == -1) { - if (pollfds != spollfds) - free (pollfds); - return -1; - } - if ((items_ [i].events & ZMQ_POLLOUT) && - (zmq_events & ZMQ_POLLOUT)) - items_ [i].revents |= ZMQ_POLLOUT; - if ((items_ [i].events & ZMQ_POLLIN) && - (zmq_events & ZMQ_POLLIN)) - items_ [i].revents |= ZMQ_POLLIN; - } - // Else, the poll item is a raw file descriptor, simply convert - // the events to zmq_pollitem_t-style format. - else { - if (pollfds [i].revents & POLLIN) - items_ [i].revents |= ZMQ_POLLIN; - if (pollfds [i].revents & POLLOUT) - items_ [i].revents |= ZMQ_POLLOUT; - if (pollfds [i].revents & POLLPRI) - items_ [i].revents |= ZMQ_POLLPRI; - if (pollfds [i].revents & ~(POLLIN | POLLOUT | POLLPRI)) - items_ [i].revents |= ZMQ_POLLERR; - } - - if (items_ [i].revents) - nevents++; - } - - // If timeout is zero, exit immediately whether there are events or not. - if (timeout_ == 0) - break; - - // If there are events to return, we can exit immediately. - if (nevents) - break; - - // At this point we are meant to wait for events but there are none. - // If timeout is infinite we can just loop until we get some events. - if (timeout_ < 0) { - if (first_pass) - first_pass = false; - continue; - } - - // The timeout is finite and there are no events. In the first pass - // we get a timestamp of when the polling have begun. (We assume that - // first pass have taken negligible time). We also compute the time - // when the polling should time out. - if (first_pass) { - now = clock.now_ms (); - end = now + timeout_; - if (now == end) - break; - first_pass = false; - continue; - } - - // Find out whether timeout have expired. - now = clock.now_ms (); - if (now >= end) - break; - } - - if (pollfds != spollfds) - free (pollfds); - return nevents; - -#elif defined ZMQ_POLL_BASED_ON_SELECT - - if (unlikely (nitems_ < 0)) { - errno = EINVAL; - return -1; - } - if (unlikely (nitems_ == 0)) { - if (timeout_ == 0) - return 0; -#if defined ZMQ_HAVE_WINDOWS - Sleep (timeout_ > 0 ? timeout_ : INFINITE); - return 0; -#else - return usleep (timeout_ * 1000); -#endif - } - zmq::clock_t clock; - uint64_t now = 0; - uint64_t end = 0; - - // Ensure we do not attempt to select () on more than FD_SETSIZE - // file descriptors. - zmq_assert (nitems_ <= FD_SETSIZE); - - fd_set pollset_in; - FD_ZERO (&pollset_in); - fd_set pollset_out; - FD_ZERO (&pollset_out); - fd_set pollset_err; - FD_ZERO (&pollset_err); - - zmq::fd_t maxfd = 0; - - // Build the fd_sets for passing to select (). - for (int i = 0; i != nitems_; i++) { - - // If the poll item is a 0MQ socket we are interested in input on the - // notification file descriptor retrieved by the ZMQ_FD socket option. - if (items_ [i].socket) { - size_t zmq_fd_size = sizeof (zmq::fd_t); - zmq::fd_t notify_fd; - if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, ¬ify_fd, - &zmq_fd_size) == -1) - return -1; - if (items_ [i].events) { - FD_SET (notify_fd, &pollset_in); - if (maxfd < notify_fd) - maxfd = notify_fd; - } - } - // Else, the poll item is a raw file descriptor. Convert the poll item - // events to the appropriate fd_sets. - else { - if (items_ [i].events & ZMQ_POLLIN) - FD_SET (items_ [i].fd, &pollset_in); - if (items_ [i].events & ZMQ_POLLOUT) - FD_SET (items_ [i].fd, &pollset_out); - if (items_ [i].events & ZMQ_POLLERR) - FD_SET (items_ [i].fd, &pollset_err); - if (maxfd < items_ [i].fd) - maxfd = items_ [i].fd; - } - } - - bool first_pass = true; - int nevents = 0; - fd_set inset, outset, errset; - - while (true) { - - // Compute the timeout for the subsequent poll. - timeval timeout; - timeval *ptimeout; - if (first_pass) { - timeout.tv_sec = 0; - timeout.tv_usec = 0; - ptimeout = &timeout; - } - else - if (timeout_ < 0) - ptimeout = NULL; - else { - timeout.tv_sec = (long) ((end - now) / 1000); - timeout.tv_usec = (long) ((end - now) % 1000 * 1000); - ptimeout = &timeout; - } - - // Wait for events. Ignore interrupts if there's infinite timeout. - while (true) { -#if defined ZMQ_HAVE_WINDOWS - // On Windows we don't need to copy the whole fd_set. - // SOCKETS are continuous from the beginning of fd_array in fd_set. - // We just need to copy fd_count elements of fd_array. - // We gain huge memcpy() improvement if number of used SOCKETs is much lower than FD_SETSIZE. - memcpy (&inset, &pollset_in , (char *) (pollset_in.fd_array + pollset_in.fd_count ) - (char *) &pollset_in ); - memcpy (&outset, &pollset_out, (char *) (pollset_out.fd_array + pollset_out.fd_count) - (char *) &pollset_out); - memcpy (&errset, &pollset_err, (char *) (pollset_err.fd_array + pollset_err.fd_count) - (char *) &pollset_err); - int rc = select (0, &inset, &outset, &errset, ptimeout); - if (unlikely (rc == SOCKET_ERROR)) { - errno = zmq::wsa_error_to_errno (WSAGetLastError ()); - wsa_assert (errno == ENOTSOCK); - return -1; - } -#else - memcpy (&inset, &pollset_in, sizeof (fd_set)); - memcpy (&outset, &pollset_out, sizeof (fd_set)); - memcpy (&errset, &pollset_err, sizeof (fd_set)); - int rc = select (maxfd + 1, &inset, &outset, &errset, ptimeout); - if (unlikely (rc == -1)) { - errno_assert (errno == EINTR || errno == EBADF); - return -1; - } -#endif - break; - } - - // Check for the events. - for (int i = 0; i != nitems_; i++) { - - items_ [i].revents = 0; - - // The poll item is a 0MQ socket. Retrieve pending events - // using the ZMQ_EVENTS socket option. - if (items_ [i].socket) { - size_t zmq_events_size = sizeof (uint32_t); - uint32_t zmq_events; - if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events, - &zmq_events_size) == -1) - return -1; - if ((items_ [i].events & ZMQ_POLLOUT) && - (zmq_events & ZMQ_POLLOUT)) - items_ [i].revents |= ZMQ_POLLOUT; - if ((items_ [i].events & ZMQ_POLLIN) && - (zmq_events & ZMQ_POLLIN)) - items_ [i].revents |= ZMQ_POLLIN; - } - // Else, the poll item is a raw file descriptor, simply convert - // the events to zmq_pollitem_t-style format. - else { - if (FD_ISSET (items_ [i].fd, &inset)) - items_ [i].revents |= ZMQ_POLLIN; - if (FD_ISSET (items_ [i].fd, &outset)) - items_ [i].revents |= ZMQ_POLLOUT; - if (FD_ISSET (items_ [i].fd, &errset)) - items_ [i].revents |= ZMQ_POLLERR; - } - - if (items_ [i].revents) - nevents++; - } - - // If timeout is zero, exit immediately whether there are events or not. - if (timeout_ == 0) - break; - - // If there are events to return, we can exit immediately. - if (nevents) - break; - - // At this point we are meant to wait for events but there are none. - // If timeout is infinite we can just loop until we get some events. - if (timeout_ < 0) { - if (first_pass) - first_pass = false; - continue; - } - - // The timeout is finite and there are no events. In the first pass - // we get a timestamp of when the polling have begun. (We assume that - // first pass have taken negligible time). We also compute the time - // when the polling should time out. - if (first_pass) { - now = clock.now_ms (); - end = now + timeout_; - if (now == end) - break; - first_pass = false; - continue; - } - - // Find out whether timeout have expired. - now = clock.now_ms (); - if (now >= end) - break; - } - - return nevents; - -#else - // Exotic platforms that support neither poll() nor select(). - errno = ENOTSUP; - return -1; -#endif -#endif // ZMQ_HAVE_POLLER -} - -// The poller functionality - -void *zmq_poller_new (void) -{ - zmq::socket_poller_t *poller = new (std::nothrow) zmq::socket_poller_t; - alloc_assert (poller); - return poller; -} - -int zmq_poller_destroy (void **poller_p_) -{ - void *poller; - if (!poller_p_ || !(poller = *poller_p_) || - !((zmq::socket_poller_t*) poller)->check_tag ()) { - errno = EFAULT; - return -1; - } - - delete ((zmq::socket_poller_t*) poller); - *poller_p_ = NULL; - return 0; -} - -int zmq_poller_add (void *poller_, void *s_, void *user_data_, short events_) -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - if (!s_ || !((zmq::socket_base_t*)s_)->check_tag ()) { - errno = ENOTSOCK; - return -1; - } - zmq::socket_base_t *socket = (zmq::socket_base_t*)s_; - - return ((zmq::socket_poller_t*)poller_)->add (socket, user_data_, events_); -} - -#if defined _WIN32 -int zmq_poller_add_fd (void *poller_, SOCKET fd_, void *user_data_, short events_) -#else -int zmq_poller_add_fd (void *poller_, int fd_, void *user_data_, short events_) -#endif -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - if (fd_ == zmq::retired_fd) { - errno = EBADF; - return -1; - } - - return ((zmq::socket_poller_t*)poller_)->add_fd (fd_, user_data_, events_); -} - - -int zmq_poller_modify (void *poller_, void *s_, short events_) -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - if (!s_ || !((zmq::socket_base_t*)s_)->check_tag ()) { - errno = ENOTSOCK; - return -1; - } - zmq::socket_base_t *socket = (zmq::socket_base_t*)s_; - - return ((zmq::socket_poller_t*)poller_)->modify (socket, events_); -} - - -#if defined _WIN32 -int zmq_poller_modify_fd (void *poller_, SOCKET fd_, short events_) -#else -int zmq_poller_modify_fd (void *poller_, int fd_, short events_) -#endif -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - if (fd_ == zmq::retired_fd) { - errno = EBADF; - return -1; - } - - return ((zmq::socket_poller_t*)poller_)->modify_fd (fd_, events_); -} - - -int zmq_poller_remove (void *poller_, void *s_) -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - if (!s_ || !((zmq::socket_base_t*)s_)->check_tag ()) { - errno = ENOTSOCK; - return -1; - } - zmq::socket_base_t *socket = (zmq::socket_base_t*)s_; - - return ((zmq::socket_poller_t*)poller_)->remove (socket); -} - -#if defined _WIN32 -int zmq_poller_remove_fd (void *poller_, SOCKET fd_) -#else -int zmq_poller_remove_fd (void *poller_, int fd_) -#endif -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - if (fd_ == zmq::retired_fd) { - errno = EBADF; - return -1; - } - - return ((zmq::socket_poller_t*)poller_)->remove_fd (fd_); -} - - -int zmq_poller_wait (void *poller_, zmq_poller_event_t *event_, long timeout_) -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - if (!event_) { - errno = EFAULT; - return -1; - } - - int rc = zmq_poller_wait_all(poller_, event_, 1, timeout_); - - if (rc < 0) { - memset (event_, 0, sizeof(zmq_poller_event_t)); - } - // wait_all returns number of events, but we return 0 for any success - return rc >= 0 ? 0 : rc; -} - -int zmq_poller_wait_all (void *poller_, zmq_poller_event_t *events_, int n_events, long timeout_) -{ - if (!poller_ || !((zmq::socket_poller_t*)poller_)->check_tag ()) { - errno = EFAULT; - return -1; - } - if (!events_) { - errno = EFAULT; - return -1; - } - if (n_events < 0) { - errno = EINVAL; - return -1; - } - - int rc = ((zmq::socket_poller_t*)poller_)->wait ((zmq::socket_poller_t::event_t *)events_, n_events, timeout_); - - return rc; -} - -// Peer-specific state - -int zmq_socket_get_peer_state (void *s_, - const void *routing_id_, - size_t routing_id_size_) -{ - zmq::socket_base_t *s = as_socket_base_t (s_); - if (!s) - return -1; - - return s->get_peer_state (routing_id_, routing_id_size_); -} - -// Timers - -void *zmq_timers_new (void) -{ - zmq::timers_t *timers = new (std::nothrow) zmq::timers_t; - alloc_assert (timers); - return timers; -} - -int zmq_timers_destroy (void **timers_p_) -{ - void *timers = *timers_p_; - if (!timers || !((zmq::timers_t *) timers)->check_tag ()) { - errno = EFAULT; - return -1; - } - delete ((zmq::timers_t *) timers); - *timers_p_ = NULL; - return 0; -} - -int zmq_timers_add (void *timers_, size_t interval_, zmq_timer_fn handler_, void *arg_) -{ - if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - return ((zmq::timers_t*)timers_)->add (interval_, handler_, arg_); -} - -int zmq_timers_cancel (void *timers_, int timer_id_) -{ - if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - return ((zmq::timers_t*)timers_)->cancel (timer_id_); -} - -int zmq_timers_set_interval (void *timers_, int timer_id_, size_t interval_) -{ - if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - return ((zmq::timers_t*)timers_)->set_interval (timer_id_, interval_); -} - -int zmq_timers_reset (void *timers_, int timer_id_) -{ - if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - return ((zmq::timers_t*)timers_)->reset (timer_id_); -} - -long zmq_timers_timeout (void *timers_) -{ - if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - return ((zmq::timers_t*)timers_)->timeout (); -} - -int zmq_timers_execute (void *timers_) -{ - if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) { - errno = EFAULT; - return -1; - } - - return ((zmq::timers_t*)timers_)->execute (); -} - -// The proxy functionality - -int zmq_proxy (void *frontend_, void *backend_, void *capture_) -{ - if (!frontend_ || !backend_) { - errno = EFAULT; - return -1; - } - return zmq::proxy ( - (zmq::socket_base_t*) frontend_, - (zmq::socket_base_t*) backend_, - (zmq::socket_base_t*) capture_); -} - -int zmq_proxy_steerable (void *frontend_, void *backend_, void *capture_, void *control_) -{ - if (!frontend_ || !backend_) { - errno = EFAULT; - return -1; - } - return zmq::proxy ( - (zmq::socket_base_t*) frontend_, - (zmq::socket_base_t*) backend_, - (zmq::socket_base_t*) capture_, - (zmq::socket_base_t*) control_); -} - -// The deprecated device functionality - -int zmq_device (int /* type */, void *frontend_, void *backend_) -{ - return zmq::proxy ( - (zmq::socket_base_t*) frontend_, - (zmq::socket_base_t*) backend_, NULL); -} - -// Probe library capabilities; for now, reports on transport and security - -int zmq_has (const char *capability) -{ -#if !defined (ZMQ_HAVE_WINDOWS) && !defined (ZMQ_HAVE_OPENVMS) - if (strcmp (capability, "ipc") == 0) - return true; -#endif -#if defined (ZMQ_HAVE_OPENPGM) - if (strcmp (capability, "pgm") == 0) - return true; -#endif -#if defined (ZMQ_HAVE_TIPC) - if (strcmp (capability, "tipc") == 0) - return true; -#endif -#if defined (ZMQ_HAVE_NORM) - if (strcmp (capability, "norm") == 0) - return true; -#endif -#if defined (ZMQ_HAVE_CURVE) - if (strcmp (capability, "curve") == 0) - return true; -#endif -#if defined (HAVE_LIBGSSAPI_KRB5) - if (strcmp (capability, "gssapi") == 0) - return true; -#endif -#if defined (ZMQ_HAVE_VMCI) - if (strcmp (capability, "vmci") == 0) - return true; -#endif -#if defined (ZMQ_BUILD_DRAFT_API) - if (strcmp (capability, "draft") == 0) - return true; -#endif - // Whatever the application asked for, we don't have - return false; -} diff --git a/dep/libzmq/src/zmq_draft.h b/dep/libzmq/src/zmq_draft.h deleted file mode 100644 index cbffcf38f9..0000000000 --- a/dep/libzmq/src/zmq_draft.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef __ZMQ_DRAFT_H_INCLUDED__ -#define __ZMQ_DRAFT_H_INCLUDED__ - -/******************************************************************************/ -/* These functions are DRAFT and disabled in stable releases, and subject to */ -/* change at ANY time until declared stable. */ -/******************************************************************************/ - -#ifndef ZMQ_BUILD_DRAFT_API - -/* DRAFT Socket types. */ -#define ZMQ_SERVER 12 -#define ZMQ_CLIENT 13 -#define ZMQ_RADIO 14 -#define ZMQ_DISH 15 -#define ZMQ_GATHER 16 -#define ZMQ_SCATTER 17 -#define ZMQ_DGRAM 18 - -/* DRAFT Socket options. */ -#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90 -#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91 -#define ZMQ_BINDTODEVICE 92 -#define ZMQ_ZAP_ENFORCE_DOMAIN 93 - -/* DRAFT 0MQ socket events and monitoring */ -/* Unspecified system errors during handshake. Event value is an errno. */ -#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800 -/* Handshake complete successfully with successful authentication (if * - * enabled). Event value is unused. */ -#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000 -/* Protocol errors between ZMTP peers or between server and ZAP handler. * - * Event value is one of ZMQ_PROTOCOL_ERROR_* */ -#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000 -/* Failed authentication requests. Event value is the numeric ZAP status * - * code, i.e. 300, 400 or 500. */ -#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000 - -#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000 -#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001 -#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002 -#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR 0x10000015 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY 0x10000016 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME 0x10000017 -#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA 0x10000018 - -// the following two may be due to erroneous configuration of a peer -#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001 -#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002 - -#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000 -#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001 -#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002 -#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003 -#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004 -#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005 - -/* DRAFT Context options */ -#define ZMQ_MSG_T_SIZE 6 -#define ZMQ_THREAD_AFFINITY_CPU_ADD 7 -#define ZMQ_THREAD_AFFINITY_CPU_REMOVE 8 -#define ZMQ_THREAD_NAME_PREFIX 9 - -/* DRAFT Socket methods. */ -int zmq_join (void *s, const char *group); -int zmq_leave (void *s, const char *group); - -/* DRAFT Msg methods. */ -int zmq_msg_set_routing_id(zmq_msg_t *msg, uint32_t routing_id); -uint32_t zmq_msg_routing_id(zmq_msg_t *msg); -int zmq_msg_set_group(zmq_msg_t *msg, const char *group); -const char *zmq_msg_group(zmq_msg_t *msg); - -/* DRAFT Msg property names. */ -#define ZMQ_MSG_PROPERTY_ROUTING_ID "Routing-Id" -#define ZMQ_MSG_PROPERTY_SOCKET_TYPE "Socket-Type" -#define ZMQ_MSG_PROPERTY_USER_ID "User-Id" -#define ZMQ_MSG_PROPERTY_PEER_ADDRESS "Peer-Address" - -/******************************************************************************/ -/* Poller polling on sockets,fd and thread-safe sockets */ -/******************************************************************************/ - -typedef struct zmq_poller_event_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - void *user_data; - short events; -} zmq_poller_event_t; - -void *zmq_poller_new (void); -int zmq_poller_destroy (void **poller_p); -int zmq_poller_add (void *poller, void *socket, void *user_data, short events); -int zmq_poller_modify (void *poller, void *socket, short events); -int zmq_poller_remove (void *poller, void *socket); -int zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout); -int zmq_poller_wait_all (void *poller, zmq_poller_event_t *events, int n_events, long timeout); - -#if defined _WIN32 -int zmq_poller_add_fd (void *poller, SOCKET fd, void *user_data, short events); -int zmq_poller_modify_fd (void *poller, SOCKET fd, short events); -int zmq_poller_remove_fd (void *poller, SOCKET fd); -#else -int zmq_poller_add_fd (void *poller, int fd, void *user_data, short events); -int zmq_poller_modify_fd (void *poller, int fd, short events); -int zmq_poller_remove_fd (void *poller, int fd); -#endif - -int zmq_socket_get_peer_state (void *socket, - const void *routing_id, - size_t routing_id_size); - -/******************************************************************************/ -/* Scheduling timers */ -/******************************************************************************/ - -typedef void (zmq_timer_fn)(int timer_id, void *arg); - -void *zmq_timers_new (void); -int zmq_timers_destroy (void **timers_p); -int zmq_timers_add (void *timers, size_t interval, zmq_timer_fn handler, void *arg); -int zmq_timers_cancel (void *timers, int timer_id); -int zmq_timers_set_interval (void *timers, int timer_id, size_t interval); -int zmq_timers_reset (void *timers, int timer_id); -long zmq_timers_timeout (void *timers); -int zmq_timers_execute (void *timers); - -/******************************************************************************/ -/* GSSAPI definitions */ -/******************************************************************************/ - -/* GSSAPI principal name types */ -#define ZMQ_GSSAPI_NT_HOSTBASED 0 -#define ZMQ_GSSAPI_NT_USER_NAME 1 -#define ZMQ_GSSAPI_NT_KRB5_PRINCIPAL 2 - -#endif // ZMQ_BUILD_DRAFT_API - -#endif //ifndef __ZMQ_DRAFT_H_INCLUDED__ diff --git a/dep/libzmq/src/zmq_utils.cpp b/dep/libzmq/src/zmq_utils.cpp deleted file mode 100644 index 24f4df7384..0000000000 --- a/dep/libzmq/src/zmq_utils.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "precompiled.hpp" - -#include "macros.hpp" -#include "clock.hpp" -#include "err.hpp" -#include "thread.hpp" -#include "atomic_counter.hpp" -#include "atomic_ptr.hpp" -#include "random.hpp" -#include -#include - -#if !defined ZMQ_HAVE_WINDOWS -#include -#endif - -#if defined (ZMQ_USE_TWEETNACL) -#include "tweetnacl.h" -#elif defined (ZMQ_USE_LIBSODIUM) -#include "sodium.h" -#endif - -void zmq_sleep (int seconds_) -{ -#if defined ZMQ_HAVE_WINDOWS - Sleep (seconds_ * 1000); -#else - sleep (seconds_); -#endif -} - -void *zmq_stopwatch_start () -{ - uint64_t *watch = (uint64_t*) malloc (sizeof (uint64_t)); - alloc_assert (watch); - *watch = zmq::clock_t::now_us (); - return (void*) watch; -} - -unsigned long zmq_stopwatch_stop (void *watch_) -{ - uint64_t end = zmq::clock_t::now_us (); - uint64_t start = *(uint64_t*) watch_; - free (watch_); - return (unsigned long) (end - start); -} - -void *zmq_threadstart(zmq_thread_fn* func, void* arg) -{ - zmq::thread_t* thread = new (std::nothrow) zmq::thread_t; - alloc_assert(thread); - thread->start(func, arg); - return thread; -} - -void zmq_threadclose(void* thread) -{ - zmq::thread_t* pThread = static_cast(thread); - pThread->stop(); - LIBZMQ_DELETE(pThread); -} - -// Z85 codec, taken from 0MQ RFC project, implements RFC32 Z85 encoding - -// Maps base 256 to base 85 -static char encoder [85 + 1] = { - "0123456789" "abcdefghij" "klmnopqrst" "uvwxyzABCD" - "EFGHIJKLMN" "OPQRSTUVWX" "YZ.-:+=^!/" "*?&<>()[]{" - "}@%$#" -}; - -// Maps base 85 to base 256 -// We chop off lower 32 and higher 128 ranges -// 0xFF denotes invalid characters within this range -static uint8_t decoder [96] = { - 0xFF, 0x44, 0xFF, 0x54, 0x53, 0x52, 0x48, 0xFF, - 0x4B, 0x4C, 0x46, 0x41, 0xFF, 0x3F, 0x3E, 0x45, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x40, 0xFF, 0x49, 0x42, 0x4A, 0x47, - 0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, - 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, - 0x3B, 0x3C, 0x3D, 0x4D, 0xFF, 0x4E, 0x43, 0xFF, - 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, - 0x21, 0x22, 0x23, 0x4F, 0xFF, 0x50, 0xFF, 0xFF -}; - -// -------------------------------------------------------------------------- -// Encode a binary frame as a string; destination string MUST be at least -// size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns -// dest. Size must be a multiple of 4. -// Returns NULL and sets errno = EINVAL for invalid input. - -char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size) -{ - if (size % 4 != 0) { - errno = EINVAL; - return NULL; - } - unsigned int char_nbr = 0; - unsigned int byte_nbr = 0; - uint32_t value = 0; - while (byte_nbr < size) { - // Accumulate value in base 256 (binary) - value = value * 256 + data [byte_nbr++]; - if (byte_nbr % 4 == 0) { - // Output value in base 85 - unsigned int divisor = 85 * 85 * 85 * 85; - while (divisor) { - dest [char_nbr++] = encoder [value / divisor % 85]; - divisor /= 85; - } - value = 0; - } - } - assert (char_nbr == size * 5 / 4); - dest [char_nbr] = 0; - return dest; -} - - -// -------------------------------------------------------------------------- -// Decode an encoded string into a binary frame; dest must be at least -// strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string) -// must be a multiple of 5. -// Returns NULL and sets errno = EINVAL for invalid input. - -uint8_t *zmq_z85_decode (uint8_t *dest, const char *string) -{ - unsigned int byte_nbr = 0; - unsigned int char_nbr = 0; - uint32_t value = 0; - while (string[char_nbr]) { - // Accumulate value in base 85 - if (UINT32_MAX / 85 < value) { - // Invalid z85 encoding, represented value exceeds 0xffffffff - goto error_inval; - } - value *= 85; - uint8_t index = string [char_nbr++] - 32; - if (index >= sizeof(decoder)) { - // Invalid z85 encoding, character outside range - goto error_inval; - } - uint32_t summand = decoder [index]; - if (summand == 0xFF || summand > (UINT32_MAX - value)) { - // Invalid z85 encoding, invalid character or represented value exceeds 0xffffffff - goto error_inval; - } - value += summand; - if (char_nbr % 5 == 0) { - // Output value in base 256 - unsigned int divisor = 256 * 256 * 256; - while (divisor) { - dest [byte_nbr++] = value / divisor % 256; - divisor /= 256; - } - value = 0; - } - } - if (char_nbr % 5 != 0) { - goto error_inval; - } - assert (byte_nbr == strlen (string) * 4 / 5); - return dest; - -error_inval: - errno = EINVAL; - return NULL; -} - -// -------------------------------------------------------------------------- -// Generate a public/private keypair with tweetnacl or libsodium. -// Generated keys will be 40 byte z85-encoded strings. -// Returns 0 on success, -1 on failure, setting errno. -// Sets errno = ENOTSUP in the absence of a CURVE library. - -int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key) -{ -#if defined (ZMQ_HAVE_CURVE) -# if crypto_box_PUBLICKEYBYTES != 32 \ - || crypto_box_SECRETKEYBYTES != 32 -# error "CURVE encryption library not built correctly" -# endif - - uint8_t public_key [32]; - uint8_t secret_key [32]; - - zmq::random_open (); - - int res = crypto_box_keypair (public_key, secret_key); - zmq_z85_encode (z85_public_key, public_key, 32); - zmq_z85_encode (z85_secret_key, secret_key, 32); - - zmq::random_close (); - - return res; -#else - (void) z85_public_key, (void) z85_secret_key; - errno = ENOTSUP; - return -1; -#endif -} - -// -------------------------------------------------------------------------- -// Derive the public key from a private key using tweetnacl or libsodium. -// Derived key will be 40 byte z85-encoded string. -// Returns 0 on success, -1 on failure, setting errno. -// Sets errno = ENOTSUP in the absence of a CURVE library. - -int zmq_curve_public (char *z85_public_key, const char *z85_secret_key) -{ -#if defined (ZMQ_HAVE_CURVE) -# if crypto_box_PUBLICKEYBYTES != 32 \ - || crypto_box_SECRETKEYBYTES != 32 -# error "CURVE encryption library not built correctly" -# endif - - uint8_t public_key[32]; - uint8_t secret_key[32]; - - zmq::random_open (); - - if (zmq_z85_decode (secret_key, z85_secret_key) == NULL) - return -1; - - // Return codes are suppressed as none of these can actually fail. - crypto_scalarmult_base (public_key, secret_key); - zmq_z85_encode (z85_public_key, public_key, 32); - - zmq::random_close (); - - return 0; -#else - (void) z85_public_key, (void) z85_secret_key; - errno = ENOTSUP; - return -1; -#endif -} - - -// -------------------------------------------------------------------------- -// Initialize a new atomic counter, which is set to zero - -void *zmq_atomic_counter_new (void) -{ - zmq::atomic_counter_t *counter = new (std::nothrow) zmq::atomic_counter_t; - alloc_assert (counter); - return counter; -} - -// Se the value of the atomic counter - -void zmq_atomic_counter_set (void *counter_, int value_) -{ - ((zmq::atomic_counter_t *) counter_)->set (value_); -} - -// Increment the atomic counter, and return the old value - -int zmq_atomic_counter_inc (void *counter_) -{ - return ((zmq::atomic_counter_t *) counter_)->add (1); -} - -// Decrement the atomic counter and return 1 (if counter >= 1), or -// 0 if counter hit zero. - -int zmq_atomic_counter_dec (void *counter_) -{ - return ((zmq::atomic_counter_t *) counter_)->sub (1)? 1: 0; -} - -// Return actual value of atomic counter - -int zmq_atomic_counter_value (void *counter_) -{ - return ((zmq::atomic_counter_t *) counter_)->get (); -} - -// Destroy atomic counter, and set reference to NULL - -void zmq_atomic_counter_destroy (void **counter_p_) -{ - delete ((zmq::atomic_counter_t *) *counter_p_); - *counter_p_ = NULL; -} diff --git a/dep/zmqpp/zmqpp/compatibility.hpp b/dep/zmqpp/zmqpp/compatibility.hpp deleted file mode 100644 index 103b2c82eb..0000000000 --- a/dep/zmqpp/zmqpp/compatibility.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/** - * \file - * - * \date 10 Sep 2011 - * \author ron - * \author Ben Gray (\@benjamg) - * - * A fair number of C++0x (or more accurately C++11) features are used in this - * library and as this project is used where I work on older compilers this - * file was created to help. - * - * C++ features and their workaround where not supported: - * \li lambda functions - disabled, these are only used in the test anyway. - * \li typesafe enums - replaced with enum where comparisons needed. - * \li nullptr - defined to null. - * - * As of the port to version 3.1 (libzmqpp version 1.1.0) this file will also - * be used to maintain compatablity with multiple versions of 0mq - */ - -#ifndef ZMQPP_COMPATIBILITY_HPP_ -#define ZMQPP_COMPATIBILITY_HPP_ - -#include -#include - -// Currently we require at least 0mq version 2.2.x -#define ZMQPP_REQUIRED_ZMQ_MAJOR 2 -#define ZMQPP_REQUIRED_ZMQ_MINOR 2 - -#if (ZMQ_VERSION_MAJOR < ZMQPP_REQUIRED_ZMQ_MAJOR) || ((ZMQ_VERSION_MAJOR == ZMQPP_REQUIRED_ZMQ_MAJOR) && (ZMQ_VERSION_MINOR < ZMQPP_REQUIRED_ZMQ_MINOR)) -#error zmqpp requires a later version of 0mq -#endif - -// Experimental feature support -#if (ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR == 0) -#define ZMQ_EXPERIMENTAL_LABELS -#endif - -// Deal with older versions of gcc -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ == 4 - -// Deal with older gcc not supporting C++0x typesafe enum class name {} comparison -#if __GNUC_MINOR__ < 4 -#define ZMQPP_COMPARABLE_ENUM enum -#endif - -#if __GNUC_MINOR__ == 4 -#if __GNUC_PATCHLEVEL__ < 1 -#undef ZMQPP_COMPARABLE_ENUM -#define ZMQPP_COMPARABLE_ENUM enum -#endif // if __GNUC_PATCHLEVEL__ < 1 -#endif // if __GNUC_MINOR__ == 4 - -// Deal with older gcc not supporting C++0x lambda function -#if __GNUC_MINOR__ < 5 -#define ZMQPP_IGNORE_LAMBDA_FUNCTION_TESTS -#define ZMQPP_EXPLICITLY_DELETED -#endif // if __GNUC_MINOR__ < 5 - -// Deal with older gcc not supporting C++0x nullptr -#if __GNUC_MINOR__ < 6 -#define nullptr NULL -#define NOEXCEPT -#endif // if __GNUC_MINOR__ < 6 - -#endif // if __GNUC_ == 4 -#endif // if defined(__GNUC__) && !defined(__clang__) - -#if defined(_MSC_VER) -#define NOEXCEPT throw() -#if _MSC_VER < 1800 -#define ZMQPP_EXPLICITLY_DELETED -#endif // if _MSC_VER < 1800 -#if _MSC_VER < 1600 -#define nullptr NULL -#define ZMQPP_IGNORE_LAMBDA_FUNCTION_TESTS -#define ZMQPP_COMPARABLE_ENUM enum -#endif // if _MSC_VER < 1600 -#endif // if defined(_MSC_VER) - -// Generic state, assume a modern compiler -#ifndef ZMQPP_COMPARABLE_ENUM -#define ZMQPP_COMPARABLE_ENUM enum class -#endif - -#ifndef ZMQPP_EXPLICITLY_DELETED -#define ZMQPP_EXPLICITLY_DELETED = delete -#endif - -#ifndef NOEXCEPT -#define NOEXCEPT noexcept -#endif - -#endif /* ZMQPP_COMPATIBILITY_HPP_ */ - diff --git a/dep/zmqpp/zmqpp/context.cpp b/dep/zmqpp/zmqpp/context.cpp deleted file mode 100644 index 32c657199d..0000000000 --- a/dep/zmqpp/zmqpp/context.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#include "context.hpp" - -namespace zmqpp -{ - -void context::terminate() -{ - int result; - do - { -#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - result = zmq_term(_context); -#else - result = zmq_ctx_destroy(_context); -#endif - } while (result != 0 && zmq_errno() == EINTR); - if (result != 0) { throw zmq_internal_exception(); } - _context = nullptr; -} - -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -void context::set(context_option const option, int const value) -{ - if (nullptr == _context) { throw invalid_instance("context is invalid"); } - - if (0 != zmq_ctx_set(_context, static_cast(option), value)) - { - throw zmq_internal_exception(); - } -} - -int context::get(context_option const option) -{ - if (nullptr == _context) { throw invalid_instance("context is invalid"); } - - int result = zmq_ctx_get(_context, static_cast(option)); - - if (result < 0) - { - throw zmq_internal_exception(); - } - - return result; -} -#endif - -} diff --git a/dep/zmqpp/zmqpp/context.hpp b/dep/zmqpp/zmqpp/context.hpp deleted file mode 100644 index 3ffaf79144..0000000000 --- a/dep/zmqpp/zmqpp/context.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_CONTEXT_HPP_ -#define ZMQPP_CONTEXT_HPP_ - -#include - -#include - -#include "compatibility.hpp" -#include "exception.hpp" -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -#include "context_options.hpp" -#endif - -namespace zmqpp -{ - -/*! - * The context class represents internal zmq context and io threads. - * - * By default the context class will create one thread, however this can be - * overridden in the constructor. - * - * The context class is the only object that can be considered thread safe. - * - * All sockets using endpoints other than inproc require the context to have - * at least one thread. - * - * This class is c++0x move supporting and cannot be copied. - */ -class context -{ -public: - -#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - /*! - * Initialise the 0mq context. - * - * If only inproc is used then the context may be created with zero threads. - * Any inproc endpoint using sockets must be created using the same context. - * - * The context is thread safe an may be used anywhere in your application, - * however there is no requirement (other than inproc restrictions) for you - * to do this. - * - * \param threads an integer argument for the number of required threads. Defaults to 1. - */ - context(int const& threads = 1) -#else - /*! - * Initialise the 0mq context. - * - * The context is thread safe an may be used anywhere in your application, - * however there is no requirement (other than inproc restrictions) for you - * to do this. - */ - context() -#endif - : _context(nullptr) - { -#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - _context = zmq_init(threads); -#else - _context = zmq_ctx_new(); -#endif - - if (nullptr == _context) - { - throw zmq_internal_exception(); - } - } - - /*! - * Closes the 0mq context. - * - * Any blocking calls other than a socket close will return with an error. - * - * If there are open sockets will block while zmq internal buffers are - * processed up to a limit specified by that sockets linger option. - */ - ~context() NOEXCEPT - { - if (nullptr != _context) - { - terminate(); - } - } - - /*! - * Move supporting constructor. - * - * Allows zero-copy move semantics to be used with this class. - * - * \param source a rvalue instance of the object who's internals we wish to steal. - */ - context(context&& source) NOEXCEPT - : _context(source._context) - { - source._context = nullptr; - } - - /*! - * Move supporting operator. - * - * Allows zero-copy move semantics to be used with this class. - * - * \param source an rvalue instance of the context who's internals we wish to steal. - */ - context& operator=(context&& source) NOEXCEPT - { - std::swap( _context, source._context ); - return *this; - } - - /*! - * Terminate the current context. - * - * Any blocking calls other than a socket close will return with an error. - * - * If there are open sockets will block while zmq internal buffers are - * processed up to a limit specified by that sockets linger option. - */ - void terminate(); - -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) - /*! - * Set the value of an option in the underlaying zmq context. - * - * \param option a valid ::context_option - * \param value to set the option to - */ - void set(context_option const option, int const value); - - /*! - * Get a context option from the underlaying zmq context. - * - * \param option a valid ::context_option - * \return context option value - */ - int get(context_option const option); -#endif - - /*! - * Validity checking of the context - * - * Checks if the underlying 0mq context for this instance is valid. - * - * Contexts should always be valid unless people are doing 'fun' things with - * std::move. - * - * \return boolean true if the object is valid. - */ - operator bool() const NOEXCEPT - { - return nullptr != _context; - } - - /*! - * Access to the raw 0mq context - * - * \return void pointer to the underlying 0mq context. - */ - operator void*() const NOEXCEPT - { - return _context; - } - -private: - void* _context; - - // No copy - private and not implemented - context(context const&) ZMQPP_EXPLICITLY_DELETED; - context& operator=(context const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; -}; - -} - -#endif /* ZMQPP_CONTEXT_HPP_ */ diff --git a/dep/zmqpp/zmqpp/context_options.hpp b/dep/zmqpp/zmqpp/context_options.hpp deleted file mode 100644 index b2e2cf4805..0000000000 --- a/dep/zmqpp/zmqpp/context_options.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/** - * \file - * - * \date 3 Jul 2013 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_CONTEXT_OPTIONS_HPP_ -#define ZMQPP_CONTEXT_OPTIONS_HPP_ - -namespace zmqpp -{ - -/** \todo Expand the information on the options to make it actually useful. */ -/*! - * \brief possible Context options in zmq - */ - -enum class context_option { - io_threads = ZMQ_IO_THREADS, /*!< I/O thread count */ - max_sockets = ZMQ_MAX_SOCKETS, /*!< Maximum supported sockets */ -}; - -} - -#endif /* ZMQPP_CONTEXT_OPTIONS_HPP_ */ diff --git a/dep/zmqpp/zmqpp/exception.hpp b/dep/zmqpp/zmqpp/exception.hpp deleted file mode 100644 index a0b234769c..0000000000 --- a/dep/zmqpp/zmqpp/exception.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_EXCEPTION_HPP_ -#define ZMQPP_EXCEPTION_HPP_ - -#include -#include - -#include - -namespace zmqpp -{ - -/** \todo Have a larger variety of exceptions with better state debug information */ - -/*! - * Represents the base zmqpp exception. - * - * All zmqpp runtime exceptions are children of this class. - * The class itself does not provide any special access fields but it only - * for convince when catching exceptions. - * - * The class extends std::runtime_error. - * - */ -class exception : public std::runtime_error -{ -public: - /*! - * Standard exception constructor. - * - * \param message a string representing the error message. - */ - exception(std::string const& message) - : std::runtime_error(message) - { } -}; - -/*! - * Represents an attempt to use an invalid object. - * - * Objects may be invalid initially or after a shutdown or close. - */ -class invalid_instance : public exception -{ -public: - invalid_instance(std::string const& message) - : exception(message) - { } -}; - -/*! - * Represents internal zmq errors. - * - * Any error response from the zmq bindings will be wrapped in this error. - * - * The class provides access to the zmq error number via zmq_error(). - */ -class zmq_internal_exception : public exception -{ -public: - /*! - * Uses the zmq functions to pull out error messages and numbers. - */ - zmq_internal_exception() - : exception(zmq_strerror(zmq_errno())) - , _error(zmq_errno()) - { } - - /*! - * Retrieve the zmq error number associated with this exception. - * \return zmq error number - */ - int zmq_error() const { return _error; } - -private: - int _error; -}; - -} - -#endif /* ZMQPP_EXCEPTION_HPP_ */ diff --git a/dep/zmqpp/zmqpp/frame.cpp b/dep/zmqpp/zmqpp/frame.cpp deleted file mode 100644 index 4c512ae101..0000000000 --- a/dep/zmqpp/zmqpp/frame.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** - * \file - * - * \date 8 Jan 2014 - * \author Ben Gray (\@benjamg) - */ - -#include -#include - -#include "exception.hpp" -#include "frame.hpp" - -namespace zmqpp { - -frame::frame() - : _sent( false ) -{ - if( 0 != zmq_msg_init( &_msg ) ) - { - throw zmq_internal_exception(); - } -} - -frame::frame(size_t const size) - : _sent( false ) -{ - if( 0 != zmq_msg_init_size( &_msg, size ) ) - { - throw zmq_internal_exception(); - } -} - -frame::frame(void const* part, size_t const size) - : _sent( false ) -{ - if( 0 != zmq_msg_init_size( &_msg, size ) ) - { - throw zmq_internal_exception(); - } - - void* msg_data = zmq_msg_data( &_msg ); - memcpy( msg_data, part, size ); -} - -frame::frame(void* part, size_t const size, zmq_free_fn *ffn, void *hint) - : _sent( false ) -{ - if( 0 != zmq_msg_init_data( &_msg, part, size, ffn, hint ) ) - { - throw zmq_internal_exception(); - } -} - -frame::~frame() -{ -#ifndef NDEBUG // unused assert variable in release - int result = zmq_msg_close( &_msg ); - assert(0 == result); -#else - zmq_msg_close( &_msg ); -#endif // NDEBUG -} - -frame::frame(frame&& other) - : _sent( other._sent ) -{ - zmq_msg_init( &_msg ); - zmq_msg_move( &_msg, &other._msg ); - other._sent = false; -} - -frame& frame::operator=(frame&& other) -{ - zmq_msg_init( &_msg ); - zmq_msg_move( &_msg, &other._msg ); - std::swap( _sent, other._sent ); - - return *this; -} - -frame frame::copy() const -{ - frame other( size() ); - other._sent = _sent; - - if( 0 != zmq_msg_copy( &other._msg, const_cast(&_msg) ) ) - { - throw zmq_internal_exception(); - } - - return other; -} - -} // namespace zmqpp diff --git a/dep/zmqpp/zmqpp/frame.hpp b/dep/zmqpp/zmqpp/frame.hpp deleted file mode 100644 index c9e4b9b7d8..0000000000 --- a/dep/zmqpp/zmqpp/frame.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * \file - * - * \date 8 Jan 2014 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_MESSAGE_FRAME_HPP_ -#define ZMQPP_MESSAGE_FRAME_HPP_ - -#include - -#include "compatibility.hpp" - -namespace zmqpp { - -/*! - * \brief an internal frame wrapper for a single zmq message - * - * This frame wrapper consists of a zmq message and meta data it is used - * by the zmqpp message class to keep track of parts in the internal - * queue. It is unlikely you need to use this class. - */ -class frame -{ -public: - frame(); - frame(size_t const size); - frame(void const* part, size_t const size); - frame(void* part, size_t const size, zmq_free_fn *ffn, void *hint); - - ~frame(); - - bool is_sent() const { return _sent; } - void const* data() const { return zmq_msg_data( const_cast(&_msg) ); } - size_t size() const { return zmq_msg_size( const_cast(&_msg) ); } - - void mark_sent() { _sent = true; } - zmq_msg_t& msg() { return _msg; } - - // Move operators - frame(frame&& other); - frame& operator=(frame&& other); - - frame copy() const; - -private: - bool _sent; - zmq_msg_t _msg; - - // Disable implicit copy support, code must request a copy to clone - frame(frame const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; - frame& operator=(frame const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; -}; - -} // namespace zmqpp - -#endif /* ZMQPP_MESSAGE_FRAME_HPP_ */ diff --git a/dep/zmqpp/zmqpp/inet.hpp b/dep/zmqpp/zmqpp/inet.hpp deleted file mode 100644 index 5245aa4143..0000000000 --- a/dep/zmqpp/zmqpp/inet.hpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * \file - * - * \date 10 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_INET_HPP_ -#define ZMQPP_INET_HPP_ - -/** \todo cross-platform version of including headers. */ -// We get htons and htonl from here -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "compatibility.hpp" - -namespace zmqpp -{ - -/*! - * \brief Possible byte order types. - * - * An enumeration of all the known order types, all two of them. - * There is also an entry for unknown which is just used as a default. - */ -ZMQPP_COMPARABLE_ENUM order { - big_endian, /*!< byte order is big endian */ - little_endian /*!< byte order is little endian */ -}; - -/*! - * Common code for the 64bit versions of htons/htons and ntohs/ntohl - * - * As htons and ntohs (or htonl and ntohs) always just do the same thing, ie - * swap bytes if the host order differs from network order or otherwise don't - * do anything, it seemed silly to type the code twice. - * - * \note This code assumes network order is always big endian. Which it is. - * \note The host endian is only checked once and afterwards assumed to remain - * the same. - * - * \param value_to_check unsigned 64 bit integer to swap - * \return swapped (or not) unsigned 64 bit integer - */ -inline uint64_t swap_if_needed(uint64_t const value_to_check) -{ - static order host_order = (htonl(42) == 42) ? order::big_endian : order::little_endian; - - if (order::big_endian == host_order) - { - return value_to_check; - } - - union { - uint64_t integer; - uint8_t bytes[8]; - } value { value_to_check }; - - std::swap(value.bytes[0], value.bytes[7]); - std::swap(value.bytes[1], value.bytes[6]); - std::swap(value.bytes[2], value.bytes[5]); - std::swap(value.bytes[3], value.bytes[4]); - - return value.integer; -} - -/*! - * 64 bit version of the htons/htonl - * - * I've used the name htonll to try and keep with the htonl naming scheme. - * - * \param hostlonglong unsigned 64 bit host order integer - * \return unsigned 64 bit network order integer - */ -inline uint64_t htonll(uint64_t const hostlonglong) -{ - return zmqpp::swap_if_needed(hostlonglong); -} - -/*! - * 64 bit version of the ntohs/ntohl - * - * I've used the name htonll to try and keep with the htonl naming scheme. - * - * \param networklonglong unsigned 64 bit network order integer - * \return unsigned 64 bit host order integer - */ -inline uint64_t ntohll(uint64_t const networklonglong) -{ - return zmqpp::swap_if_needed(networklonglong); -} - -/*! - * floating point version of the htons/htonl - * - * \param value host order floating point - * \returns network order floating point - */ -inline float htonf(float value) -{ - assert(sizeof(float) == sizeof(uint32_t)); - - uint32_t temp; - memcpy(&temp, &value, sizeof(uint32_t)); - temp = htonl( temp ); - memcpy(&value, &temp, sizeof(uint32_t)); - - return value; -} - -/*! - * floating point version of the ntohs/ntohl - * - * \param value network order float - * \returns host order float - */ -inline float ntohf(float value) -{ - assert(sizeof(float) == sizeof(uint32_t)); - - uint32_t temp; - memcpy(&temp, &value, sizeof(uint32_t)); - temp = ntohl( temp ); - memcpy(&value, &temp, sizeof(uint32_t)); - - return value; -} - -/*! - * double precision floating point version of the htons/htonl - * - * \param value host order double precision floating point - * \returns network order double precision floating point - */ -inline double htond(double value) -{ - assert(sizeof(double) == sizeof(uint64_t)); - - uint64_t temp; - memcpy(&temp, &value, sizeof(uint64_t)); - temp = zmqpp::htonll(temp); - memcpy(&value, &temp, sizeof(uint64_t)); - - return value; -} - -/*! - * double precision floating point version of the ntohs/ntohl - * - * \param value network order double precision floating point - * \returns host order double precision floating point - */ -inline double ntohd(double value) -{ - assert(sizeof(double) == sizeof(uint64_t)); - - uint64_t temp; - memcpy(&temp, &value, sizeof(uint64_t)); - temp = zmqpp::ntohll(temp); - memcpy(&value, &temp, sizeof(uint64_t)); - - return value; -} - -} - -#endif /* INET_HPP_ */ diff --git a/dep/zmqpp/zmqpp/message.cpp b/dep/zmqpp/zmqpp/message.cpp deleted file mode 100644 index 5858730736..0000000000 --- a/dep/zmqpp/zmqpp/message.cpp +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Created on: 9 Aug 2011 - * Author: Ben Gray (@benjamg) - */ - -#include -#include - -#include "exception.hpp" -#include "inet.hpp" -#include "message.hpp" - -namespace zmqpp -{ - -/*! - * \brief internal construct - * \internal handles bubbling callback from zmq c style to the c++ functor provided - */ -struct callback_releaser -{ - message::release_function func; -}; - -message::message() - : _parts() - , _read_cursor(0) -{ -} - -message::~message() -{ - _parts.clear(); -} - -size_t message::parts() const -{ - return _parts.size(); -} - -/* - * The two const_casts in size and raw_data are a little bit hacky - * but neither of these methods called this way actually modify data - * so accurately represent the intent of these calls. - */ - -size_t message::size(size_t const part /* = 0 */) const -{ - if(part >= _parts.size()) - { - throw exception("attempting to request a message part outside the valid range"); - } - - return _parts[part].size(); -} - -void const* message::raw_data(size_t const part /* = 0 */) const -{ - if(part >= _parts.size()) - { - throw exception("attempting to request a message part outside the valid range"); - } - - return _parts[part].data(); -} - -zmq_msg_t& message::raw_msg(size_t const part /* = 0 */) -{ - if(part >= _parts.size()) - { - throw exception("attempting to request a message part outside the valid range"); - } - - return _parts[part].msg(); -} - -zmq_msg_t& message::raw_new_msg() -{ - _parts.push_back( frame() ); - - return _parts.back().msg(); -} - -zmq_msg_t& message::raw_new_msg(size_t const reserve_data_size) -{ - _parts.push_back( frame(reserve_data_size) ); - - return _parts.back().msg(); -} - -std::string message::get(size_t const part /* = 0 */) const -{ - return std::string(static_cast(raw_data(part)), size(part)); -} - - -// Move operators will take ownership of message parts without copying -void message::move(void* part, size_t const size, release_function const& release) -{ - callback_releaser* hint = new callback_releaser(); - hint->func = release; - - _parts.push_back( frame( part, size, &message::release_callback, hint ) ); -} - -// Stream reader style -void message::reset_read_cursor() -{ - _read_cursor = 0; -} - -void message::get(int8_t& integer, size_t const part) const -{ - assert(sizeof(int8_t) == size(part)); - - int8_t const* byte = static_cast(raw_data(part)); - integer = *byte; -} - -void message::get(int16_t& integer, size_t const part) const -{ - assert(sizeof(int16_t) == size(part)); - - uint16_t const* network_order = static_cast(raw_data(part)); - integer = static_cast(ntohs(*network_order)); -} - -void message::get(int32_t& integer, size_t const part) const -{ - assert(sizeof(int32_t) == size(part)); - - uint32_t const* network_order = static_cast(raw_data(part)); - integer = static_cast(htonl(*network_order)); -} - -void message::get(int64_t& integer, size_t const part) const -{ - assert(sizeof(int64_t) == size(part)); - - uint64_t const* network_order = static_cast(raw_data(part)); - integer = static_cast(zmqpp::htonll(*network_order)); -} - -void message::get(uint8_t& unsigned_integer, size_t const part) const -{ - assert(sizeof(uint8_t) == size(part)); - - uint8_t const* byte = static_cast(raw_data(part)); - unsigned_integer = *byte; -} - -void message::get(uint16_t& unsigned_integer, size_t const part) const -{ - assert(sizeof(uint16_t) == size(part)); - - uint16_t const* network_order = static_cast(raw_data(part)); - unsigned_integer = ntohs(*network_order); -} - -void message::get(uint32_t& unsigned_integer, size_t const part) const -{ - assert(sizeof(uint32_t) == size(part)); - - uint32_t const* network_order = static_cast(raw_data(part)); - unsigned_integer = ntohl(*network_order); -} - -void message::get(uint64_t& unsigned_integer, size_t const part) const -{ - assert(sizeof(uint64_t) == size(part)); - - uint64_t const* network_order = static_cast(raw_data(part)); - unsigned_integer = zmqpp::ntohll(*network_order); -} - -void message::get(float& floating_point, size_t const part) const -{ - assert(sizeof(float) == size(part)); - - float const* network_order = static_cast(raw_data(part)); - floating_point = zmqpp::ntohf(*network_order); -} - -void message::get(double& double_precision, size_t const part) const -{ - assert(sizeof(double) == size(part)); - - double const* network_order = static_cast(raw_data(part)); - double_precision = zmqpp::ntohd(*network_order); -} - -void message::get(bool& boolean, size_t const part) const -{ - assert(sizeof(uint8_t) == size(part)); - - uint8_t const* byte = static_cast(raw_data(part)); - boolean = (*byte != 0); -} - -void message::get(std::string& string, size_t const part) const -{ - string.assign( get(part) ); -} - - -// Stream writer style - these all use copy styles -message& message::operator<<(int8_t const integer) -{ - add(reinterpret_cast(&integer), sizeof(int8_t)); - return *this; -} - -message& message::operator<<(int16_t const integer) -{ - uint16_t network_order = htons(static_cast(integer)); - add(reinterpret_cast(&network_order), sizeof(uint16_t)); - - return *this; -} - -message& message::operator<<(int32_t const integer) -{ - uint32_t network_order = htonl(static_cast(integer)); - add(reinterpret_cast(&network_order), sizeof(uint32_t)); - - return *this; -} - -message& message::operator<<(int64_t const integer) -{ - uint64_t network_order = zmqpp::htonll(static_cast(integer)); - add(reinterpret_cast(&network_order), sizeof(uint64_t)); - - return *this; -} - - -message& message::operator<<(uint8_t const unsigned_integer) -{ - add(reinterpret_cast(&unsigned_integer), sizeof(uint8_t)); - return *this; -} - -message& message::operator<<(uint16_t const unsigned_integer) -{ - uint16_t network_order = htons(unsigned_integer); - add(reinterpret_cast(&network_order), sizeof(uint16_t)); - - return *this; -} - -message& message::operator<<(uint32_t const unsigned_integer) -{ - uint32_t network_order = htonl(unsigned_integer); - add(reinterpret_cast(&network_order), sizeof(uint32_t)); - - return *this; -} - -message& message::operator<<(uint64_t const unsigned_integer) -{ - uint64_t network_order = zmqpp::htonll(unsigned_integer); - add(reinterpret_cast(&network_order), sizeof(uint64_t)); - - return *this; -} - -message& message::operator<<(float const floating_point) -{ - assert(sizeof(float) == 4); - - float network_order = zmqpp::htonf(floating_point); - add(&network_order, sizeof(float)); - - return *this; -} - -message& message::operator<<(double const double_precision) -{ - assert(sizeof(double) == 8); - - double network_order = zmqpp::htond(double_precision); - add(&network_order, sizeof(double)); - - return *this; -} - -message& message::operator<<(bool const boolean) -{ - uint8_t byte = (boolean) ? 1 : 0; - add(reinterpret_cast(&byte), sizeof(uint8_t)); - - return *this; -} - -message& message::operator<<(char const* c_string) -{ - add(reinterpret_cast(c_string), strlen(c_string)); - return *this; -} - -message& message::operator<<(std::string const& string) -{ - add(reinterpret_cast(string.data()), string.size()); - return *this; -} - -void message::push_front(void const* part, size_t const size) -{ - _parts.emplace( _parts.begin(), part, size ); -} - -void message::push_front(int8_t const integer) -{ - push_front(&integer, sizeof(int8_t)); -} - -void message::push_front(int16_t const integer) -{ - uint16_t network_order = htons(static_cast(integer)); - push_front(&network_order, sizeof(uint16_t)); -} - -void message::push_front(int32_t const integer) -{ - uint32_t network_order = htonl(static_cast(integer)); - push_front(&network_order, sizeof(uint32_t)); -} - -void message::push_front(int64_t const integer) -{ - uint64_t network_order = zmqpp::htonll(static_cast(integer)); - push_front(&network_order, sizeof(uint64_t)); -} - - -void message::push_front(uint8_t const unsigned_integer) -{ - push_front(&unsigned_integer, sizeof(uint8_t)); -} - -void message::push_front(uint16_t const unsigned_integer) -{ - uint16_t network_order = htons(unsigned_integer); - push_front(&network_order, sizeof(uint16_t)); -} - -void message::push_front(uint32_t const unsigned_integer) -{ - uint32_t network_order = htonl(unsigned_integer); - push_front(&network_order, sizeof(uint32_t)); -} - -void message::push_front(uint64_t const unsigned_integer) -{ - uint64_t network_order = zmqpp::htonll(unsigned_integer); - push_front(&network_order, sizeof(uint64_t)); -} - -void message::push_front(float const floating_point) -{ - assert(sizeof(float) == 4); - - float network_order = zmqpp::htonf(floating_point); - push_front(&network_order, sizeof(float)); -} - -void message::push_front(double const double_precision) -{ - assert(sizeof(double) == 8); - - double network_order = zmqpp::htond(double_precision); - push_front(&network_order, sizeof(double)); -} - -void message::push_front(bool const boolean) -{ - uint8_t byte = (boolean) ? 1 : 0; - push_front(&byte, sizeof(uint8_t)); -} - -void message::push_front(char const* c_string) -{ - push_front(c_string, strlen(c_string)); -} - -void message::push_front(std::string const& string) -{ - push_front(string.data(), string.size()); -} - -void message::pop_front() -{ - _parts.erase( _parts.begin() ); -} - -void message::pop_back() -{ - _parts.pop_back(); -} - -message::message(message&& source) NOEXCEPT - : _parts() - , _read_cursor(0) -{ - std::swap(_parts, source._parts); -} - -message& message::operator=(message&& source) NOEXCEPT -{ - std::swap(_parts, source._parts); - return *this; -} - -message message::copy() const -{ - message msg; - msg.copy(*this); - return msg; -} - -void message::copy(message const& source) -{ - _parts.resize( source._parts.size() ); - for(size_t i = 0; i < source._parts.size(); ++i) - { - _parts[i] = source._parts[i].copy(); - } - - // we don't need a copy of the releasers as we did data copies of the internal data, - //_releasers = source._releasers; - //_strings = source._strings -} - -// Used for internal tracking -void message::sent(size_t const part) -{ - // sanity check - assert(!_parts[part].is_sent()); - _parts[part].mark_sent(); -} - -// Note that these releasers are not thread safe, the only safety is provided by -// the socket class taking ownership so no updates can happen while zmq does it's thing -// If used in a custom class this has to be dealt with. -void message::release_callback(void* data, void* hint) -{ - callback_releaser* releaser = static_cast(hint); - releaser->func(data); - - delete releaser; -} - -} diff --git a/dep/zmqpp/zmqpp/message.hpp b/dep/zmqpp/zmqpp/message.hpp deleted file mode 100644 index 2a747bfd1d..0000000000 --- a/dep/zmqpp/zmqpp/message.hpp +++ /dev/null @@ -1,254 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_MESSAGE_HPP_ -#define ZMQPP_MESSAGE_HPP_ - -#include -#include -#include -#include -#include -#include - -#include - -#include "compatibility.hpp" -#include "frame.hpp" - -namespace zmqpp -{ - -/*! - * \brief a zmq message with optional multipart support - * - * A zmq message is made up of one or more parts which are sent together to - * the target endpoints. zmq guarantees either the whole message or none - * of the message will be delivered. - */ -class message -{ -public: - /*! - * \brief callback to release user allocated data. - * - * The release function will be called on any void* moved part. - * It must be thread safe to the extent that the callback may occur on - * one of the context threads. - * - * The function called will be passed a single variable which is the - * pointer to the memory allocated. - */ - typedef std::function release_function; - - message(); - ~message(); - - template - message(T const &part, Args &&...args) - : message() - { - add(part, std::forward(args)...); - } - - size_t parts() const; - size_t size(size_t const part) const; - std::string get(size_t const part) const; - - void get(int8_t& integer, size_t const part) const; - void get(int16_t& integer, size_t const part) const; - void get(int32_t& integer, size_t const part) const; - void get(int64_t& integer, size_t const part) const; - - void get(uint8_t& unsigned_integer, size_t const part) const; - void get(uint16_t& unsigned_integer, size_t const part) const; - void get(uint32_t& unsigned_integer, size_t const part) const; - void get(uint64_t& unsigned_integer, size_t const part) const; - - void get(float& floating_point, size_t const part) const; - void get(double& double_precision, size_t const part) const; - void get(bool& boolean, size_t const part) const; - - void get(std::string& string, size_t const part) const; - - // Warn: If a pointer type is requested the message (well zmq) still 'owns' - // the data and will release it when the message object is freed. - template - Type get(size_t const part) - { - Type value; - get(value, part); - return value; - } - - template - void extract(T &nextpart, Args &...args) - { - assert(part < parts()); - get(nextpart,part); - extract(args...); - } - - template - void extract(T &nextpart) - { - assert(part < parts()); - get(nextpart,part); - } - - // Raw get data operations, useful with data structures more than anything else - // Warn: The message (well zmq) still 'owns' the data and will release it - // when the message object is freed. - template - void get(Type*& value, size_t const part) const - { - value = static_cast(raw_data(part)); - } - - // Warn: The message (well zmq) still 'owns' the data and will release it - // when the message object is freed. - template - void get(Type** value, size_t const part) const - { - *value = static_cast(raw_data(part)); - } - - // Move operators will take ownership of message parts without copying - void move(void* part, size_t const size, release_function const& release); - - // Raw move data operation, useful with data structures more than anything else - template - void move(Object *part) - { - move(part, sizeof(Object), &deleter_callback); - } - - // Copy operators will take copies of any data - template - void add(Type *part, size_t const size) - { - _parts.push_back( frame( part, size ) ); - } - - - template - void add(Type const& part, Args &&...args) - { - *this << part; - add(std::forward(args)...); - } - - template - void add(Type const part) - { - *this << part; - } - - // Stream reader style - void reset_read_cursor(); - - template - message& operator>>(Type& value) - { - get(value, _read_cursor++); - return *this; - } - - // Stream writer style - these all use copy styles - message& operator<<(int8_t const integer); - message& operator<<(int16_t const integer); - message& operator<<(int32_t const integer); - message& operator<<(int64_t const integer); - - message& operator<<(uint8_t const unsigned_integer); - message& operator<<(uint16_t const unsigned_integer); - message& operator<<(uint32_t const unsigned_integer); - message& operator<<(uint64_t const unsigned_integer); - - message& operator<<(float const floating_point); - message& operator<<(double const double_precision); - message& operator<<(bool const boolean); - - message& operator<<(char const* c_string); - message& operator<<(std::string const& string); - - // Queue manipulation - void push_front(void const* part, size_t const size); - - // TODO: unify conversion of types with the stream operators - void push_front(int8_t const integer); - void push_front(int16_t const integer); - void push_front(int32_t const integer); - void push_front(int64_t const integer); - - void push_front(uint8_t const unsigned_integer); - void push_front(uint16_t const unsigned_integer); - void push_front(uint32_t const unsigned_integer); - void push_front(uint64_t const unsigned_integer); - - void push_front(float const floating_point); - void push_front(double const double_precision); - void push_front(bool const boolean); - - void push_front(char const* c_string); - void push_front(std::string const& string); - - void pop_front(); - - void push_back(void const* part, size_t const size) - { - add( part, size ); - } - - template - void push_back(Type const part) - { - *this << part; - } - - void pop_back(); - - void remove(size_t const part); - - // Move supporting - message(message&& source) NOEXCEPT; - message& operator=(message&& source) NOEXCEPT; - - // Copy support - message copy() const; - void copy(message const& source); - - // Used for internal tracking - void sent(size_t const part); - - // Access to raw zmq details - void const* raw_data(size_t const part = 0) const; - zmq_msg_t& raw_msg(size_t const part = 0); - zmq_msg_t& raw_new_msg(); - zmq_msg_t& raw_new_msg(size_t const reserve_data_size); - -private: - typedef std::vector parts_type; - parts_type _parts; - size_t _read_cursor; - - // Disable implicit copy support, code must request a copy to clone - message(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; - message& operator=(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; - - static void release_callback(void* data, void* hint); - - template - static void deleter_callback(void* data) - { - delete static_cast(data); - } -}; - -} - -#endif /* ZMQPP_MESSAGE_HPP_ */ diff --git a/dep/zmqpp/zmqpp/poller.cpp b/dep/zmqpp/zmqpp/poller.cpp deleted file mode 100644 index a6340c9bd6..0000000000 --- a/dep/zmqpp/zmqpp/poller.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Created on: 16 Aug 2011 - * Author: Ben Gray (@benjamg) - */ - -#include "exception.hpp" -#include "socket.hpp" -#include "poller.hpp" - -#include - -namespace zmqpp -{ - -const long poller::wait_forever = -1; -const short poller::poll_none = 0; -const short poller::poll_in = ZMQ_POLLIN; -const short poller::poll_out = ZMQ_POLLOUT; -const short poller::poll_error = ZMQ_POLLERR; - -poller::poller() - : _items() - , _index() - , _fdindex() -{ - -} - -poller::~poller() -{ - _items.clear(); - _index.clear(); - _fdindex.clear(); -} - -void poller::add(socket& socket, short const event /* = POLL_IN */) -{ - zmq_pollitem_t item { socket, 0, event, 0 }; - - size_t index = _items.size(); - _items.push_back(item); - _index[socket] = index; -} - -void poller::add(int const descriptor, short const event /* = POLL_IN */) -{ - zmq_pollitem_t item { nullptr, descriptor, event, 0 }; - - size_t index = _items.size(); - _items.push_back(item); - _fdindex[descriptor] = index; -} - -bool poller::has(socket_t const& socket) -{ - return _index.find(socket) != _index.end(); -} - -bool poller::has(int const descriptor) -{ - return _fdindex.find(descriptor) != _fdindex.end(); -} - -void poller::reindex(size_t const index) -{ - if ( nullptr != _items[index].socket ) - { - auto found = _index.find( _items[index].socket ); - if (_index.end() == found) { throw exception("unable to reindex socket in poller"); } - found->second = index; - } - else - { - auto found = _fdindex.find( _items[index].fd ); - if (_fdindex.end() == found) { throw exception("unable to reindex file descriptor in poller"); } - found->second = index; - } -} - -void poller::remove(socket_t const& socket) -{ - auto found = _index.find(socket); - if (_index.end() == found) { return; } - - if ( _items.size() - 1 == found->second ) - { - _items.pop_back(); - _index.erase(found); - return; - } - - std::swap(_items[found->second], _items.back()); - _items.pop_back(); - - auto index = found->second; - _index.erase(found); - - reindex( index ); -} - -void poller::remove(int const descriptor) -{ - auto found = _fdindex.find(descriptor); - if (_fdindex.end() == found) { return; } - - if ( _items.size() - 1 == found->second ) - { - _items.pop_back(); - _fdindex.erase(found); - return; - } - - std::swap(_items[found->second], _items.back()); - _items.pop_back(); - - auto index = found->second; - _fdindex.erase(found); - - reindex( index ); -} - -void poller::check_for(socket const& socket, short const event) -{ - auto found = _index.find(socket); - if (_index.end() == found) - { - throw exception("this socket is not represented within this poller"); - } - - _items[found->second].events = event; -} - -void poller::check_for(int const descriptor, short const event) -{ - auto found = _fdindex.find(descriptor); - if (_fdindex.end() == found) - { - throw exception("this socket is not represented within this poller"); - } - - _items[found->second].events = event; -} - -bool poller::poll(long timeout /* = WAIT_FOREVER */) -{ - int result = zmq_poll(_items.data(), _items.size(), timeout); - if (result < 0) - { - if(EINTR == zmq_errno()) - { - return false; - } - - throw zmq_internal_exception(); - } - - return (result > 0); -} - -short poller::events(socket const& socket) const -{ - auto found = _index.find(socket); - if (_index.end() == found) - { - throw exception("this socket is not represented within this poller"); - } - - return _items[found->second].revents; -} - -short poller::events(int const descriptor) const -{ - auto found = _fdindex.find(descriptor); - if (_fdindex.end() == found) - { - throw exception("this file descriptor is not represented within this poller"); - } - - return _items[found->second].revents; -} - -} diff --git a/dep/zmqpp/zmqpp/poller.hpp b/dep/zmqpp/zmqpp/poller.hpp deleted file mode 100644 index a19063a091..0000000000 --- a/dep/zmqpp/zmqpp/poller.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_POLLER_HPP_ -#define ZMQPP_POLLER_HPP_ - -#include -#include - -#include "compatibility.hpp" - -namespace zmqpp -{ - -class socket; -typedef socket socket_t; - -/*! - * Polling wrapper. - * - * Allows access to polling for any number of sockets or file descriptors. - */ -class poller -{ -public: - static const long wait_forever; /*!< Block forever flag, default setting. */ - - static const short poll_none; /*!< No polling flags set. */ - static const short poll_in; /*!< Monitor inbound flag. */ - static const short poll_out; /*!< Monitor output flag. */ - static const short poll_error; /*!< Monitor error flag.\n Only for file descriptors. */ - - /*! - * Construct an empty polling model. - */ - poller(); - - /*! - * Cleanup poller. - * - * Any sockets will need to be closed separately. - */ - ~poller(); - - /*! - * Add a socket to the polling model and set which events to monitor. - * - * \param socket the socket to monitor. - * \param event the event flags to monitor on the socket. - */ - void add(socket_t& socket, short const event = poll_in); - - /*! - * Add a file descriptor to the polling model and set which events to monitor. - * - * \param descriptor the file descriptor to monitor. - * \param event the event flags to monitor. - */ - void add(int const descriptor, short const event = poll_in | poll_error); - - /*! - * Check if we are monitoring a given socket with this poller. - * - * \param socket the socket to check. - * \return true if it is there. - */ - bool has(socket_t const& socket); - - /*! - * Check if we are monitoring a given file descriptor with this poller. - * - * \param descriptor the file descriptor to check. - * \return true if it is there. - */ - bool has(int const descriptor); - - /*! - * Stop monitoring a socket. - * - * \param socket the socket to stop monitoring. - */ - void remove(socket_t const& socket); - - /*! - * Stop monitoring a file descriptor. - * - * \param descriptor the file descriptor to stop monitoring. - */ - void remove(int const descriptor); - - /*! - * Update the monitored event flags for a given socket. - * - * \param socket the socket to update event flags. - * \param event the event flags to monitor on the socket. - */ - void check_for(socket_t const& socket, short const event); - - /*! - * Update the monitored event flags for a given file descriptor. - * - * \param descriptor the file descriptor to update event flags. - * \param event the event flags to monitor on the socket. - */ - void check_for(int const descriptor, short const event); - - /*! - * Poll for monitored events. - * - * By default this method will block forever or until at least one of the monitored - * sockets or file descriptors has events. - * - * If a timeout is set and was reached then this function returns false. - * - * \param timeout milliseconds to timeout. - * \return true if there is an event.. - */ - bool poll(long timeout = wait_forever); - - /*! - * Get the event flags triggered for a socket. - * - * \param socket the socket to get triggered event flags for. - * \return the event flags. - */ - short events(socket_t const& socket) const; - - /*! - * Get the event flags triggered for a file descriptor. - * - * \param descriptor the file descriptor to get triggered event flags for. - * \return the event flags. - */ - short events(int const descriptor) const; - - /*! - * Check either a file descriptor or socket for input events. - * - * Templated helper method that calls through to event and checks for a given flag - * - * \param watchable either a file descriptor or socket known to the poller. - * \return true if there is input. - */ - template - bool has_input(Watched const& watchable) const { return events(watchable) & poll_in; } - - /*! - * Check either a file descriptor or socket for output events. - * - * Templated helper method that calls through to event and checks for a given flag - * - * \param watchable either a file descriptor or socket known to the poller. - * \return true if there is output. - */ - template - bool has_output(Watched const& watchable) const { return events(watchable) & poll_out; } - - /*! - * Check a file descriptor. - * - * Templated helper method that calls through to event and checks for a given flag - * - * Technically this template works for sockets as well but the error flag is never set for - * sockets so I have no idea why someone would call it. - * - * \param watchable a file descriptor know to the poller. - * \return true if there is an error. - */ - template - bool has_error(Watched const& watchable) const { return events(watchable) & poll_error; } - -private: - std::vector _items; - std::unordered_map _index; - std::unordered_map _fdindex; - - void reindex(size_t const index); -}; - -} - -#endif /* ZMQPP_POLLER_HPP_ */ diff --git a/dep/zmqpp/zmqpp/socket.cpp b/dep/zmqpp/zmqpp/socket.cpp deleted file mode 100644 index 8b4efe4f1d..0000000000 --- a/dep/zmqpp/zmqpp/socket.cpp +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Created on: 9 Aug 2011 - * Author: Ben Gray (@benjamg) - */ - -#include -#include -#include -#include - -#include "context.hpp" -#include "exception.hpp" -#include "message.hpp" -#include "socket.hpp" - -namespace zmqpp -{ - -const int socket::normal = 0; -#if (ZMQ_VERSION_MAJOR == 2) -const int socket::dont_wait = ZMQ_NOBLOCK; -#else -const int socket::dont_wait = ZMQ_DONTWAIT; -#endif -const int socket::send_more = ZMQ_SNDMORE; -#ifdef ZMQ_EXPERIMENTAL_LABELS -const int socket::send_label = ZMQ_SNDLABEL; -#endif - -const int max_socket_option_buffer_size = 256; -const int max_stream_buffer_size = 4096; - -socket::socket(const context& context, socket_type const type) - : _socket(nullptr) - , _type(type) - , _recv_buffer() -{ - _socket = zmq_socket(context, static_cast(type)); - if(nullptr == _socket) - { - throw zmq_internal_exception(); - } - - zmq_msg_init(&_recv_buffer); -} - -socket::~socket() -{ - zmq_msg_close(&_recv_buffer); - - if (nullptr != _socket) - { - -#ifndef NDEBUG // unused assert variable in release - int result = zmq_close(_socket); - assert(0 == result); -#else - zmq_close(_socket); -#endif // NDEBUG - - _socket = nullptr; - } -} - -void socket::bind(endpoint_t const& endpoint) -{ - int result = zmq_bind(_socket, endpoint.c_str()); - - if (0 != result) - { - throw zmq_internal_exception(); - } -} - -void socket::unbind(endpoint_t const& endpoint) -{ -#if (ZMQ_VERSION_MAJOR > 3 || (ZMQ_VERSION_MAJOR == 3 && ZMQ_VERSION_MINOR >= 2)) - int result = zmq_unbind(_socket, endpoint.c_str()); - - if (0 != result) - { - throw zmq_internal_exception(); - } -#endif -} - -void socket::connect(endpoint_t const& endpoint) -{ - int result = zmq_connect(_socket, endpoint.c_str()); - - if (0 != result) - { - throw zmq_internal_exception(); - } -} - -void socket::disconnect(endpoint_t const& endpoint) -{ -#if (ZMQ_VERSION_MAJOR > 3 || (ZMQ_VERSION_MAJOR == 3 && ZMQ_VERSION_MINOR >= 2)) - int result = zmq_disconnect(_socket, endpoint.c_str()); - - if (0 != result) - { - throw zmq_internal_exception(); - } -#endif -} - -void socket::close() -{ - int result = zmq_close(_socket); - - if (0 != result) - { - throw zmq_internal_exception(); - } - - _socket = nullptr; -} - -bool socket::send(message& message, bool const dont_block /* = false */) -{ - size_t parts = message.parts(); - if (parts == 0) - { - throw std::invalid_argument("sending requires messages have at least one part"); - } - - bool dont_wait = dont_block; - for(size_t i = 0; i < parts; ++i) - { - int flag = socket::normal; - if(dont_wait) { flag |= socket::dont_wait; } - if(i < (parts - 1)) { flag |= socket::send_more; } - -#if (ZMQ_VERSION_MAJOR == 2) - int result = zmq_send( _socket, &message.raw_msg(i), flag ); -#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - int result = zmq_sendmsg( _socket, &message.raw_msg(i), flag ); -#else - int result = zmq_msg_send( &message.raw_msg(i), _socket, flag ); -#endif - - if (result < 0) - { - // the zmq framework should not block if the first part is accepted - // so we should only ever get this error on the first part - if((0 == i) && (EAGAIN == zmq_errno())) - { - return false; - } - - if(EINTR == zmq_errno()) - { - if (0 == message.parts()) - { - return false; - } - - // If we have an interrupt but it's not on the first part then we - // know we can safely send out the rest of the message as we can - // enforce that it won't wait on a blocking action - dont_wait = true; - continue; - } - - // sanity checking - assert(EAGAIN != zmq_errno()); - - throw zmq_internal_exception(); - } - - message.sent(i); - } - - // Leave message reference in a stable state - zmqpp::message local; - std::swap(local, message); - return true; -} - -bool socket::receive(message& message, bool const dont_block /* = false */) -{ - if (message.parts() > 0) - { - // swap and discard old message - zmqpp::message local; - std::swap(local, message); - } - - int flags = (dont_block) ? socket::dont_wait : socket::normal; - bool more = true; - - while(more) - { -#if (ZMQ_VERSION_MAJOR == 2) - int result = zmq_recv( _socket, &_recv_buffer, flags ); -#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - int result = zmq_recvmsg( _socket, &_recv_buffer, flags ); -#else - int result = zmq_msg_recv( &_recv_buffer, _socket, flags ); -#endif - - if(result < 0) - { - if ((0 == message.parts()) && (EAGAIN == zmq_errno())) - { - return false; - } - - if(EINTR == zmq_errno()) - { - if (0 == message.parts()) - { - return false; - } - - // If we have an interrupt but it's not on the first part then we - // know we can safely pull out the rest of the message as it will - // not be blocking - continue; - } - - assert(EAGAIN != zmq_errno()); - - throw zmq_internal_exception(); - } - - zmq_msg_t& dest = message.raw_new_msg(); - zmq_msg_move(&dest, &_recv_buffer); - - get(socket_option::receive_more, more); - } - - return true; -} - - -bool socket::send(std::string const& string, int const flags /* = NORMAL */) -{ - return send_raw(string.data(), string.size(), flags); -} - -bool socket::receive(std::string& string, int const flags /* = NORMAL */) -{ -#if (ZMQ_VERSION_MAJOR == 2) - int result = zmq_recv( _socket, &_recv_buffer, flags ); -#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - int result = zmq_recvmsg( _socket, &_recv_buffer, flags ); -#else - int result = zmq_msg_recv( &_recv_buffer, _socket, flags ); -#endif - - if(result >= 0) - { - string.reserve(zmq_msg_size(&_recv_buffer)); - string.assign(static_cast(zmq_msg_data(&_recv_buffer)), zmq_msg_size(&_recv_buffer)); - - return true; - } - - if (EAGAIN == zmq_errno() || EINTR == zmq_errno()) - { - return false; - } - - throw zmq_internal_exception(); -} - - -bool socket::send_raw(char const* buffer, int const length, int const flags /* = NORMAL */) -{ -#if (ZMQ_VERSION_MAJOR == 2) - zmq_msg_t msg; - int result = zmq_msg_init_size(&msg, length); - if (result != 0) - { - zmq_internal_exception(); - } - - memcpy(zmq_msg_data(&msg), buffer, length); - result = zmq_send(_socket, &msg, flags); -#else - int result = zmq_send(_socket, buffer, length, flags); -#endif - if(result >= 0) - { - return true; - } - -#if (ZMQ_VERSION_MAJOR == 2) - // only actually need to close this on error - zmq_msg_close(&msg); -#endif - - if (EAGAIN == zmq_errno() || EINTR == zmq_errno()) - { - return false; - } - - throw zmq_internal_exception(); -} - -bool socket::receive_raw(char* buffer, int& length, int const flags /* = NORMAL */) -{ -#if (ZMQ_VERSION_MAJOR == 2) - int result = zmq_recv( _socket, &_recv_buffer, flags ); -#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) - int result = zmq_recvmsg( _socket, &_recv_buffer, flags ); -#else - int result = zmq_msg_recv( &_recv_buffer, _socket, flags ); -#endif - - if(result >= 0) - { - length = zmq_msg_size(&_recv_buffer); - memcpy(buffer, zmq_msg_data(&_recv_buffer), length); - - return true; - } - - if (EAGAIN == zmq_errno() || EINTR == zmq_errno()) - { - return false; - } - - throw zmq_internal_exception(); -} - - -// Helper -void socket::subscribe(std::string const& topic) -{ - set(socket_option::subscribe, topic); -} - -void socket::unsubscribe(std::string const& topic) -{ - set(socket_option::unsubscribe, topic); -} - -bool socket::has_more_parts() const -{ - return get(socket_option::receive_more); -} - - -// Set socket options for different types of option -void socket::set(socket_option const option, int const value) -{ - switch(option) - { - // unsigned 64bit Integers -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::high_water_mark: - case socket_option::send_buffer_size: - case socket_option::receive_buffer_size: -#endif - case socket_option::affinity: - if (value < 0) { throw exception("attempting to set an unsigned 64 bit integer option with a negative integer"); } - set(option, static_cast(value)); - break; - - // 64bit Integers -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::rate: - case socket_option::recovery_interval: - case socket_option::recovery_interval_seconds: - case socket_option::swap_size: -#else - case socket_option::max_messsage_size: -#endif - set(option, static_cast(value)); - break; - - // Boolean -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) - case socket_option::ipv4_only: -#endif -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::multicast_loopback: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -#if (ZMQ_VERSION_MINOR == 2) - case socket_option::delay_attach_on_connect: -#else - case socket_option::immediate: -#endif - case socket_option::router_mandatory: - case socket_option::xpub_verbose: -#endif - if (value == 0) { set(option, false); } - else if (value == 1) { set(option, true); } - else { throw exception("attempting to set a boolean option with a non 0 or 1 integer"); } - break; - - // Default or Boolean -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) - case socket_option::tcp_keepalive: - if (value < -1 || value > 1) { throw exception("attempting to set a default or boolean option with a non -1, 0 or 1 integer"); } - if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) - { - throw zmq_internal_exception(); - } - break; -#endif - - // Integers that require +ve numbers -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::reconnect_interval_max: -#else - case socket_option::reconnect_interval_max: - case socket_option::send_buffer_size: - case socket_option::recovery_interval: - case socket_option::receive_buffer_size: - case socket_option::send_high_water_mark: - case socket_option::receive_high_water_mark: - case socket_option::multicast_hops: - case socket_option::rate: -#endif - case socket_option::backlog: - if (value < 0) { throw exception("attempting to set a positive only integer option with a negative integer"); } - // Integers - case socket_option::reconnect_interval: - case socket_option::linger: - case socket_option::receive_timeout: - case socket_option::send_timeout: -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) - case socket_option::tcp_keepalive_idle: - case socket_option::tcp_keepalive_count: - case socket_option::tcp_keepalive_interval: -#endif - if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) - { - throw zmq_internal_exception(); - } - break; - default: - throw exception("attempting to set a non signed integer option with a signed integer value"); - } -} - -void socket::set(socket_option const option, bool const value) -{ - switch(option) - { -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::multicast_loopback: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) - case socket_option::ipv4_only: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -#if (ZMQ_VERSION_MINOR == 2) - case socket_option::delay_attach_on_connect: -#else - case socket_option::immediate: -#endif - case socket_option::router_mandatory: - case socket_option::xpub_verbose: -#endif - { - int ivalue = value ? 1 : 0; - if (0 != zmq_setsockopt(_socket, static_cast(option), &ivalue, sizeof(ivalue))) - { - throw zmq_internal_exception(); - } - break; - } - default: - throw exception("attempting to set a non boolean option with a boolean value"); - } -} - -void socket::set(socket_option const option, uint64_t const value) -{ - switch(option) - { -#if (ZMQ_VERSION_MAJOR == 2) - // unsigned 64bit Integers - case socket_option::high_water_mark: - case socket_option::send_buffer_size: - case socket_option::receive_buffer_size: -#endif - case socket_option::affinity: - if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) - { - throw zmq_internal_exception(); - } - break; - default: - throw exception("attempting to set a non unsigned 64 bit integer option with a unsigned 64 bit integer value"); - } -} - -void socket::set(socket_option const option, int64_t const value) -{ - switch(option) - { -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::rate: - case socket_option::recovery_interval: - case socket_option::recovery_interval_seconds: - case socket_option::swap_size: -#else - case socket_option::max_messsage_size: -#endif - // zmq only allowed +ve int64_t options - if (value < 0) { throw exception("attempting to set a positive only 64 bit integer option with a negative 64bit integer"); } - if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) - { - throw zmq_internal_exception(); - } - break; - default: - throw exception("attempting to set a non 64 bit integer option with a 64 bit integer value"); - } -} - -void socket::set(socket_option const option, char const* value, size_t const length) -{ - switch(option) - { - case socket_option::identity: - case socket_option::subscribe: - case socket_option::unsubscribe: -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) - case socket_option::tcp_accept_filter: -#endif - if (0 != zmq_setsockopt(_socket, static_cast(option), value, length)) - { - throw zmq_internal_exception(); - } - break; - default: - throw exception("attempting to set a non string option with a string value"); - } -} - -// Get socket options, multiple versions for easy of use -void socket::get(socket_option const option, int& value) const -{ - size_t value_size = sizeof(int); - - switch(option) - { -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::receive_more: - case socket_option::multicast_loopback: - value = static_cast(get(option)); - break; -#endif - case socket_option::type: - case socket_option::linger: - case socket_option::backlog: - case socket_option::reconnect_interval: - case socket_option::reconnect_interval_max: - case socket_option::receive_timeout: - case socket_option::send_timeout: - case socket_option::file_descriptor: - case socket_option::events: -#if (ZMQ_VERSION_MAJOR > 2) - case socket_option::receive_more: - case socket_option::send_buffer_size: - case socket_option::receive_buffer_size: - case socket_option::rate: - case socket_option::recovery_interval: - case socket_option::send_high_water_mark: - case socket_option::receive_high_water_mark: - case socket_option::multicast_hops: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) - case socket_option::ipv4_only: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -#if (ZMQ_VERSION_MINOR == 2) - case socket_option::delay_attach_on_connect: -#else - case socket_option::immediate: -#endif - case socket_option::tcp_keepalive: - case socket_option::tcp_keepalive_idle: - case socket_option::tcp_keepalive_count: - case socket_option::tcp_keepalive_interval: -#endif -#ifdef ZMQ_EXPERIMENTAL_LABELS - case socket_option::receive_label: -#endif - if (0 != zmq_getsockopt(_socket, static_cast(option), &value, &value_size)) - { - throw zmq_internal_exception(); - } - - // sanity check - assert(value_size <= sizeof(int)); - break; - default: - throw exception("attempting to get a non integer option with an integer value"); - } -} - -void socket::get(socket_option const option, bool& value) const -{ -#if (ZMQ_VERSION_MAJOR == 2) - int64_t int_value = 0; - size_t value_size = sizeof(int64_t); -#else - int int_value = 0; - size_t value_size = sizeof(int); -#endif - - switch(option) - { - case socket_option::receive_more: -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::multicast_loopback: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) - case socket_option::ipv4_only: -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -#if (ZMQ_VERSION_MINOR == 2) - case socket_option::delay_attach_on_connect: -#else - case socket_option::immediate: -#endif -#endif -#ifdef ZMQ_EXPERIMENTAL_LABELS - case socket_option::receive_label: -#endif - if (0 != zmq_getsockopt(_socket, static_cast(option), &int_value, &value_size)) - { - throw zmq_internal_exception(); - } - - value = (int_value == 1) ? true : false; - break; - default: - throw exception("attempting to get a non boolean option with a boolean value"); - } -} - -void socket::get(socket_option const option, uint64_t& value) const -{ - size_t value_size = sizeof(uint64_t); - - switch(option) - { -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::high_water_mark: - case socket_option::send_buffer_size: - case socket_option::receive_buffer_size: -#endif - case socket_option::affinity: - if(0 != zmq_getsockopt(_socket, static_cast(option), &value, &value_size)) - { - throw zmq_internal_exception(); - } - break; - default: - throw exception("attempting to get a non unsigned 64 bit integer option with an unsigned 64 bit integer value"); - } -} - -void socket::get(socket_option const option, int64_t& value) const -{ - size_t value_size = sizeof(int64_t); - - switch(option) - { -#if (ZMQ_VERSION_MAJOR == 2) - case socket_option::rate: - case socket_option::recovery_interval: - case socket_option::recovery_interval_seconds: - case socket_option::swap_size: - case socket_option::receive_more: - case socket_option::multicast_loopback: -#else - case socket_option::max_messsage_size: -#endif - if(0 != zmq_getsockopt(_socket, static_cast(option), &value, &value_size)) - { - throw zmq_internal_exception(); - } - break; - default: - throw exception("attempting to get a non 64 bit integer option with an 64 bit integer value"); - } -} - -void socket::get(socket_option const option, std::string& value) const -{ - static std::array buffer; - size_t size = max_socket_option_buffer_size; - - switch(option) - { - case socket_option::identity: -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) - case socket_option::last_endpoint: -#endif - if(0 != zmq_getsockopt(_socket, static_cast(option), buffer.data(), &size)) - { - throw zmq_internal_exception(); - } - - value.assign(buffer.data(), size); - break; - default: - throw exception("attempting to get a non string option with a string value"); - } -} - -socket::socket(socket&& source) NOEXCEPT - : _socket(source._socket) - , _type(source._type) - , _recv_buffer() -{ - // we steal the zmq_msg_t from the valid socket, we only init our own because it's cheap - // and zmq_msg_move does a valid check - zmq_msg_init(&_recv_buffer); - zmq_msg_move(&_recv_buffer, &source._recv_buffer); - - // Clean up source a little, we will handle the deinit, it doesn't need to - source._socket = nullptr; -} - -socket& socket::operator=(socket&& source) NOEXCEPT -{ - std::swap(_socket, source._socket); - - _type = source._type; // just clone? - - // we steal the zmq_msg_t from the valid socket, we only init our own because it's cheap - // and zmq_msg_move does a valid check - zmq_msg_init(&_recv_buffer); - zmq_msg_move(&_recv_buffer, &source._recv_buffer); - - return *this; -} - - -socket::operator bool() const -{ - return nullptr != _socket; -} - - -socket::operator void*() const -{ - return _socket; -} - -void socket::track_message(message const& /* message */, uint32_t const parts, bool& should_delete) -{ - if (parts == 0) - { - should_delete = true; - } -} - -} diff --git a/dep/zmqpp/zmqpp/socket.hpp b/dep/zmqpp/zmqpp/socket.hpp deleted file mode 100644 index 279bf801f7..0000000000 --- a/dep/zmqpp/zmqpp/socket.hpp +++ /dev/null @@ -1,500 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_SOCKET_HPP_ -#define ZMQPP_SOCKET_HPP_ - -#include -#include -#include - -#include - -#include "compatibility.hpp" - -#include "socket_types.hpp" -#include "socket_options.hpp" - -namespace zmqpp -{ - -class context; -class message; - -typedef std::string endpoint_t; -typedef context context_t; -typedef message message_t; - -/*! - * The socket class represents the zmq sockets. - * - * A socket can be bound and/or connected to as many endpoints as required - * with the sole exception of a ::pair socket. - * - * The routing is handled by zmq based on the type set. - * - * The bound side of an inproc connection must occur first and inproc can only - * connect to other inproc sockets of the same context. - * - * This class is c++0x move supporting and cannot be copied. - */ -class socket -{ -public: - static const int normal; /*!< /brief default send type, no flags set */ -#if (ZMQ_VERSION_MAJOR == 2) - static const int dont_wait; /*!< /brief don't block if sending is not currently possible */ -#else - static const int dont_wait; /*!< /brief don't block if sending is not currently possible */ -#endif - static const int send_more; /*!< /brief more parts will follow this one */ -#ifdef ZMQ_EXPERIMENTAL_LABELS - static const int send_label; /*!< /brief this message part is an internal zmq label */ -#endif - - /*! - * Create a socket for a given type. - * - * \param context the zmq context under which the socket will live - * \param type a valid ::socket_type for the socket - */ - socket(context_t const& context, socket_type const type); - - /*! - * This will close any socket still open before returning - */ - ~socket(); - - /*! - * Get the type of the socket, this works on zmqpp types and not the zmq internal types. - * Use the socket::get method if you wish to intergoate the zmq internal ones. - * - * \return the type of the socket - */ - socket_type type() const { return _type; } - - /*! - * Asynchronously binds to an endpoint. - * - * \param endpoint the zmq endpoint to bind to - */ - void bind(endpoint_t const& endpoint); - - /*! - * Unbinds from a previously bound endpoint. - * - * \param endpoint the zmq endpoint to bind to - */ - void unbind(endpoint_t const& endpoint); - - /*! - * Asynchronously connects to an endpoint. - * If the endpoint is not inproc then zmq will happily keep trying - * to connect until there is something there. - * - * Inproc sockets must have a valid target already bound before connection - * will work. - * - * \param endpoint the zmq endpoint to connect to - */ - void connect(endpoint_t const& endpoint); - - /*! - * Asynchronously connects to multiple endpoints. - * If the endpoint is not inproc then zmq will happily keep trying - * to connect until there is something there. - * - * Inproc sockets must have a valid target already bound before connection - * will work. - * - * This is a helper function that wraps the single item connect in a loop - * - * \param connections_begin the starting iterator for zmq endpoints. - * \param connections_end the final iterator for zmq endpoints. - */ - template - void connect(InputIterator const& connections_begin, InputIterator const& connections_end) - { - for(InputIterator it = connections_begin; it != connections_end; ++it) - { - connect(*it); - } - } - - - /*! - * Disconnects a previously connected endpoint. - * - * \param endpoint the zmq endpoint to disconnect from - */ - void disconnect(endpoint_t const& endpoint); - - /*! - * Disconnects from multiple previously connected endpoints. - * - * This is a helper function that wraps the single item disconnect in a loop - * - * \param disconnections_begin the starting iterator for zmq endpoints. - * \param disconnections_end the final iterator for zmq endpoints. - */ - template - void disconnect(InputIterator const& disconnections_begin, InputIterator const& disconnections_end) - { - for(InputIterator it = disconnections_begin; it != disconnections_end; ++it) - { - disconnect(*it); - } - } - - /*! - * Closes the internal zmq socket and marks this instance - * as invalid. - */ - void close(); - - /*! - * Sends the message over the connection, this may be a multipart message. - * - * If dont_block is true and we are unable to add a new message then this - * function will return false. - * - * \param message message to send - * \param dont_block boolean to dictate if we wait while sending. - * \return true if message sent, false if it would have blocked - */ - bool send(message_t& message, bool const dont_block = false); - - /*! - * Gets a message from the connection, this may be a multipart message. - * - * If dont_block is true and we are unable to get a message then this - * function will return false. - * - * \param message reference to fill with received data - * \param dont_block boolean to dictate if we wait for data. - * \return true if message sent, false if it would have blocked - */ - bool receive(message_t& message, bool const dont_block = false); - - /*! - * Sends the byte data held by the string as the next message part. - * - * If the socket::DONT_WAIT flag and we are unable to add a new message to - * socket then this function will return false. - * - * \param string message part to send - * \param flags message send flags - * \return true if message part sent, false if it would have blocked - */ - bool send(std::string const& string, int const flags = normal); - - /*! - * If there is a message ready then get the next part as a string - * - * If the socket::DONT_WAIT flag and there is no message ready to receive - * then this function will return false. - * - * \param string message part to receive into - * \param flags message receive flags - * \return true if message part received, false if it would have blocked - */ - bool receive(std::string& string, int const flags = normal); - - /*! - * Sends the byte data pointed to by buffer as the next part of the message. - * - * If the socket::DONT_WAIT flag and we are unable to add a new message to - * socket then this function will return false. - * - * \param buffer byte buffer pointer to start writing from - * \param length max length of the buffer - * \param flags message send flags - * \return true if message part sent, false if it would have blocked - */ - bool send_raw(char const* buffer, int const length, int const flags = normal); - - /*! - * \warning If the buffer is not large enough for the message part then the - * data will be truncated. The rest of the part is lost forever. - * - * If there is a message ready then get the next part of it as a raw - * byte buffer. - * - * If the socket::DONT_WAIT flag and there is no message ready to receive - * then this function will return false. - * - * \param buffer byte buffer pointer to start writing to - * \param length max length of the buffer - * \param flags message receive flags - * \return true if message part received, false if it would have blocked - */ - bool receive_raw(char* buffer, int& length, int const flags = normal); - - /*! - * - * Subscribe to a topic - * - * Helper function that is equivalent of calling - * \code - * set(zmqpp::socket_option::subscribe, topic); - * \endcode - * - * This method is only useful for subscribe type sockets. - * - * \param topic the topic to subscribe to. - */ - void subscribe(std::string const& topic); - - /*! - * Subscribe to a topic - * - * Helper function that is equivalent of a loop calling - * \code - * set(zmqpp::socket_option::subscribe, topic); - * \endcode - * - * This method is only useful for subscribe type sockets. - * - * Generally this will be used with stl collections using begin() and - * end() functions to get the iterators. - * For this reason the end loop runs until the end iterator, not inclusive - * of it. - * - * \param topics_begin the starting iterator for topics. - * \param topics_end the final iterator for topics. - */ - template - void subscribe(InputIterator const& topics_begin, InputIterator const& topics_end) - { - for(InputIterator it = topics_begin; it != topics_end; ++it) - { - subscribe(*it); - } - } - - /*! - * Unsubscribe from a topic - * - * Helper function that is equivalent of calling - * \code - * set(zmqpp::socket_option::unsubscribe, topic); - * \endcode - * - * This method is only useful for subscribe type sockets. - * - * \param topic the topic to unsubscribe from. - */ - void unsubscribe(std::string const& topic); - - /*! - * Unsubscribe from a topic - * - * Helper function that is equivalent of a loop calling - * \code - * set(zmqpp::socket_option::unsubscribe, topic); - * \endcode - * - * This method is only useful for subscribe type sockets. - * - * Generally this will be used with stl collections using begin() and - * end() functions to get the iterators. - * For this reason the end loop runs until the end iterator, not inclusive - * of it. - * - * \param topics_begin the starting iterator for topics. - * \param topics_end the final iterator for topics. - */ - template - void unsubscribe(InputIterator const& topics_begin, InputIterator const& topics_end) - { - for(InputIterator it = topics_begin; it != topics_end; ++it) - { - unsubscribe(*it); - } - } - - /*! - * If the last receive part call to the socket resulted - * in a label or a non-terminating part of a multipart - * message this will return true. - * - * \return true if there are more parts - */ - bool has_more_parts() const; - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value to set the option to - */ - void set(socket_option const option, int const value); - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \since 2.0.0 (built against 0mq version 3.1.x or later) - * - * \param option a valid ::socket_option - * \param value to set the option to - */ - void set(socket_option const option, bool const value); - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value to set the option to - */ - void set(socket_option const option, uint64_t const value); - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value to set the option to - */ - void set(socket_option const option, int64_t const value); - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param pointer to raw byte value to set the option to - * \param length the size of the raw byte value - */ - void set(socket_option const option, char const* value, size_t const length); - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param pointer to null terminated cstring value to set the option to - */ - inline void set(socket_option const option, char const* value) { set(option, value, strlen(value)); } - - /*! - * Set the value of an option in the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value to set the option to - */ - inline void set(socket_option const option, std::string const value) { set(option, value.c_str(), value.length()); } - - /*! - * Get a socket option from the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value referenced int to return value in - */ - void get(socket_option const option, int& value) const; - - /*! - * Get a socket option from the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value referenced bool to return value in - */ - void get(socket_option const option, bool& value) const; - - /*! - * Get a socket option from the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value referenced uint64_t to return value in - */ - void get(socket_option const option, uint64_t& value) const; - - /*! - * Get a socket option from the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value referenced uint64_t to return value in - */ - void get(socket_option const option, int64_t& value) const; - - /*! - * Get a socket option from the underlaying zmq socket. - * - * \param option a valid ::socket_option - * \param value referenced std::string to return value in - */ - void get(socket_option const option, std::string& value) const; - - /*! - * For those that don't want to get into a referenced value this templated method - * will return the value instead. - * - * \param option a valid ::socket_option - * \return socket option value - */ - template - Type get(socket_option const option) const - { - Type value = Type(); - get(option, value); - return value; - } - - /*! - * Move constructor - * - * Moves the internals of source to this object, there is no guarantee - * that source will be left in a valid state. - * - * This constructor is noexcept and so will not throw exceptions - * - * \param source target socket to steal internals from - */ - socket(socket&& source) NOEXCEPT; - - /*! - * Move operator - * - * Moves the internals of source to this object, there is no guarantee - * that source will be left in a valid state. - * - * This function is noexcept and so will not throw exceptions - * - * \param source target socket to steal internals from - * \return socket reference to this - */ - socket& operator=(socket&& source) NOEXCEPT; - - /*! - * Check the socket is still valid - * - * This tests the internal state of the socket. - * If creation failed for some reason or if the move functions were used - * to move the socket internals to another instance this will return false. - * - * \return true if the socket is valid - */ - operator bool() const; - - /*! - * Access to the raw 0mq context - * - * \return void pointer to the underlying 0mq socket - */ - operator void*() const; - -private: - void* _socket; - socket_type _type; - zmq_msg_t _recv_buffer; - - // No copy - socket(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; - socket& operator=(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; - - void track_message(message_t const&, uint32_t const, bool&); -}; - -} - -#endif /* ZMQPP_SOCKET_HPP_ */ diff --git a/dep/zmqpp/zmqpp/socket_options.hpp b/dep/zmqpp/zmqpp/socket_options.hpp deleted file mode 100644 index c5c8586cbc..0000000000 --- a/dep/zmqpp/zmqpp/socket_options.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/** - * \file - * - * \date 23 Sep 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_SOCKET_OPTIONS_HPP_ -#define ZMQPP_SOCKET_OPTIONS_HPP_ - -namespace zmqpp -{ - -/** \todo Expand the information on the options to make it actually useful. */ -/*! - * \brief possible Socket options in zmq - */ - -enum class socket_option { - affinity = ZMQ_AFFINITY, /*!< I/O thread affinity */ - identity = ZMQ_IDENTITY, /*!< Socket identity */ - subscribe = ZMQ_SUBSCRIBE, /*!< Add topic subscription - set only */ - unsubscribe = ZMQ_UNSUBSCRIBE, /*!< Remove topic subscription - set only */ - rate = ZMQ_RATE, /*!< Multicast data rate */ - send_buffer_size = ZMQ_SNDBUF, /*!< Kernel transmission buffer size */ - receive_buffer_size = ZMQ_RCVBUF, /*!< Kernel receive buffer size */ - receive_more = ZMQ_RCVMORE, /*!< Can receive more parts - get only */ - file_descriptor = ZMQ_FD, /*!< Socket file descriptor - get only */ - events = ZMQ_EVENTS, /*!< Socket event flags - get only */ - type = ZMQ_TYPE, /*!< Socket type - get only */ - linger = ZMQ_LINGER, /*!< Socket linger timeout */ - backlog = ZMQ_BACKLOG, /*!< Maximum length of outstanding connections - get only */ -#if (ZMQ_VERSION_MAJOR == 2) - // Note that this is inverse of the zmq names for version 2.x - recovery_interval_seconds = ZMQ_RECOVERY_IVL, /*!< Multicast recovery interval in seconds */ - recovery_interval = ZMQ_RECOVERY_IVL_MSEC, /*!< Multicast recovery interval in milliseconds */ -#else - recovery_interval = ZMQ_RECOVERY_IVL, /*!< Multicast recovery interval in milliseconds */ -#endif - reconnect_interval = ZMQ_RECONNECT_IVL, /*!< Reconnection interval */ - reconnect_interval_max = ZMQ_RECONNECT_IVL_MAX, /*!< Maximum reconnection interval */ - receive_timeout = ZMQ_RCVTIMEO, /*!< Maximum inbound block timeout */ - send_timeout = ZMQ_SNDTIMEO, /*!< Maximum outbound block timeout */ -#if (ZMQ_VERSION_MAJOR == 2) - high_water_mark = ZMQ_HWM, /*!< High-water mark for all messages */ - swap_size = ZMQ_SWAP, /*!< Maximum socket swap size in bytes */ - multicast_loopback = ZMQ_MCAST_LOOP, /*!< Allow multicast packet loopback */ -#else - max_messsage_size = ZMQ_MAXMSGSIZE, /*!< Maximum inbound message size */ - send_high_water_mark = ZMQ_SNDHWM, /*!< High-water mark for outbound messages */ - receive_high_water_mark = ZMQ_RCVHWM, /*!< High-water mark for inbound messages */ - multicast_hops = ZMQ_MULTICAST_HOPS, /*!< Maximum number of multicast hops */ -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) - ipv4_only = ZMQ_IPV4ONLY, -#endif -#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) -#if (ZMQ_VERSION_MINOR == 2) - delay_attach_on_connect = ZMQ_DELAY_ATTACH_ON_CONNECT, /*!< Delay buffer attachment until connect complete */ -#else - // ZMQ_DELAY_ATTACH_ON_CONNECT is renamed in ZeroMQ starting 3.3.x - immediate = ZMQ_IMMEDIATE, /*!< Block message sending until connect complete */ -#endif - last_endpoint = ZMQ_LAST_ENDPOINT, /*!< Last bound endpoint - get only */ - router_mandatory = ZMQ_ROUTER_MANDATORY, /*!< Require routable messages - set only */ - xpub_verbose = ZMQ_XPUB_VERBOSE, /*!< Pass on existing subscriptions - set only */ - tcp_keepalive = ZMQ_TCP_KEEPALIVE, /*!< Enable TCP keepalives */ - tcp_keepalive_idle = ZMQ_TCP_KEEPALIVE_IDLE, /*!< TCP keepalive idle count (generally retry count) */ - tcp_keepalive_count = ZMQ_TCP_KEEPALIVE_CNT, /*!< TCP keepalive retry count */ - tcp_keepalive_interval = ZMQ_TCP_KEEPALIVE_INTVL, /*!< TCP keepalive interval */ - tcp_accept_filter = ZMQ_TCP_ACCEPT_FILTER, /*!< Filter inbound connections - set only */ -#endif -#ifdef ZMQ_EXPERIMENTAL_LABELS - receive_label = ZMQ_RCVLABEL, /*!< Received label part - get only */ -#endif -}; - -} - -#endif /* ZMQPP_SOCKET_OPTIONS_HPP_ */ diff --git a/dep/zmqpp/zmqpp/socket_types.hpp b/dep/zmqpp/zmqpp/socket_types.hpp deleted file mode 100644 index e59e71ca0e..0000000000 --- a/dep/zmqpp/zmqpp/socket_types.hpp +++ /dev/null @@ -1,148 +0,0 @@ -/** - * \file - * - * \date 23 Sep 2011 - * \author Ben Gray (\@benjamg) - */ - -#ifndef ZMQPP_SOCKET_TYPES_HPP_ -#define ZMQPP_SOCKET_TYPES_HPP_ - -namespace zmqpp -{ - -/*! - * \brief Socket types allowed by zmq - * - * The socket type choose at creation must be one of these types. - * - * Each is designed for a different use and has different limitations. - */ -enum class socket_type { - /*! - * One to one - two way connection.\n - * Connect to ::pair.\n - * A \c pair socket has to be connected only one other pair socket and allows - * two way communication between them. - */ - pair = ZMQ_PAIR, - - /*! - * One to many - fan out.\n - * Connect to ::subscribe or ::xsubscribe.\n - * Socket is send only.\n - * Socket will drop messages and not block.\n - * \c publish sockets allow sending of the same message to many subscribers - * each subscriber can limit what is sent through the socket_option::subscribe - * settings. - */ - publish = ZMQ_PUB, - - /*! - * \note It seems doxygen can't work out which data is for the socket type and - * which is for the socket option so both get listed for both. - * - * One to many - fair-queued.\n - * Connect to ::publish or ::xpublish.\n - * Socket is receive only.\n - * The \c subscribe socket can connection to any number of publishers and will - * fairly pull messages from each. The socket_option::subscribe settings can - * be use to limit which messages are received and by default none are. - */ - subscribe = ZMQ_SUB, - - /*! - * One to many - fair-queued.\n - * Connect to ::push.\n - * Socket is receive only.\n - * The \c pull socket fairly pulls messages from all pushers it is connected - * to. - */ - pull = ZMQ_PULL, - - /*! - * One to many - load-balanced.\n - * Connect to ::pull.\n - * Socket is send only.\n - * Socket will block if unable to send.\n - * The \c push socket fairly distributes messages between any connected - * puller sockets. - */ - push = ZMQ_PUSH, - - /*! - * One to many - fair-queued outgoing, last peer incoming.\n - * Connect to ::reply or ::xreply.\n - * Socket flips between send and receive only.\n - * Socket will block if unable to send.\n - * The \c request socket will fairly balance requests sent out to a - * replier and then can only be used to receive until that replier - * sends a reply. - */ - request = ZMQ_REQ, - - /*! - * One to many - load-balanced incoming, last peer outgoing.\n - * Connect to ::request or ::xrequest.\n - * Socket flips between send and receive only.\n - * Socket will drop messages and not block.\n - * The \c reply socket can only receive until it pulls a message from a - * requester at which point it can only send until the reply is sent. - */ - reply = ZMQ_REP, - - /*! - * One to many - fan out.\n - * Connect to ::subscribe or ::xsubscribe.\n - * Socket is send only with the exception of special subscription messages.\n - * Socket will drop messages and not block.\n - * \c xpublish act the same as ::publish sockets however also allow special - * subscription messages to be received from subscribers. - */ - xpublish = ZMQ_XPUB, - - /*! - * One to many - fair-queued.\n - * Connect to ::publish or ::xpublish.\n - * Socket is receive only with the exception of special subscription messages\n - * \c xsubscribe act the same as ::subscribe sockets however also allow special - * subscription messages to be send to connected publishers. - */ - xsubscribe = ZMQ_XSUB, - - /*! - * One to many - fair-queued incoming, load-balanced outgoing.\n - * Connect to ::reply or ::xreply.\n - * Socket will block if unable to send.\n - * An \c xrequest socket balances requests between repliers and pulls replies - * back in a fair manner. Each request is expected to have exactly one reply. - */ - xrequest = ZMQ_XREQ, - - /*! - * One to many - fair-queued incoming, targeted outgoing.\n - * Connect to ::request or ::xrequest.\n - * Socket will drop messages and not block.\n - * An \c xreply socket fairly pulls in requests from requesters and will - * label requests so it can return replies back to the correct target. - */ - xreply = ZMQ_XREP, - - // To match for people who prefer the shorter versions - pub = ZMQ_PUB, /*!< version of ::publish to match zmq name convention */ - sub = ZMQ_SUB, /*!< version of ::subscribe to match zmq name convention */ - req = ZMQ_REQ, /*!< version of ::request to match zmq name convention */ - rep = ZMQ_REP, /*!< version of ::reply to match zmq name convention */ - xpub = ZMQ_XPUB, /*!< version of ::xpublish to match zmq name convention */ - xsub = ZMQ_XSUB, /*!< version of ::xsubscribe to match zmq name convention */ - xreq = ZMQ_XREQ, /*!< version of ::xrequest to match zmq name convention */ - xrep = ZMQ_XREP, /*!< version of ::xreply to match zmq name convention */ - - // For completion - router = ZMQ_ROUTER, /*!< \deprecated Matches zmq 2.x xrep functionality. */ - dealer = ZMQ_DEALER /*!< \deprecated Matches zmq 2.x xreq functionality. */ -}; - -} - -#endif /* ZMQPP_SOCKET_TYPES_HPP_ */ diff --git a/dep/zmqpp/zmqpp/zmqpp.cpp b/dep/zmqpp/zmqpp/zmqpp.cpp deleted file mode 100644 index 216948e73e..0000000000 --- a/dep/zmqpp/zmqpp/zmqpp.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Created on: 18 Aug 2011 - * Author: Ben Gray (@benjamg) - */ - -#include "zmqpp.hpp" - -namespace zmqpp -{ - -std::string version() -{ - return BUILD_VERSION; -} - -void version(uint8_t& major, uint8_t& minor, uint8_t& revision) -{ - major = ZMQPP_VERSION_MAJOR; - minor = ZMQPP_VERSION_MINOR; - revision = ZMQPP_VERSION_REVISION; -} - -void zmq_version(uint8_t& major, uint8_t& minor, uint8_t& patch) -{ - major = ZMQ_VERSION_MAJOR; - minor = ZMQ_VERSION_MINOR; - patch = ZMQ_VERSION_PATCH; -} - -} diff --git a/dep/zmqpp/zmqpp/zmqpp.hpp b/dep/zmqpp/zmqpp/zmqpp.hpp deleted file mode 100644 index 92a47ce38b..0000000000 --- a/dep/zmqpp/zmqpp/zmqpp.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/** - * \file - * - * \date 9 Aug 2011 - * \author Ben Gray (\@benjamg) - * - * License: http://www.opensource.org/licenses/MIT - * - * Copyright (C) 2011 by Ben Gray - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef ZMQPP_ZMQPP_HPP_ -#define ZMQPP_ZMQPP_HPP_ - -/** - * \def ZMQPP_VERSION_MAJOR - * zmqpp major version number, generated at compile time - */ -#define ZMQPP_VERSION_MAJOR BUILD_VERSION_MAJOR - -/** - * \def ZMQPP_VERSION_MINOR - * zmqpp minor version number, generated at compile time - */ -#define ZMQPP_VERSION_MINOR BUILD_VERSION_MINOR - -/** - * \def ZMQPP_VERSION_REVISION - * zmqpp version revision number, generated at compile time - */ -#define ZMQPP_VERSION_REVISION BUILD_VERSION_REVISION - -#include - -#include "compatibility.hpp" -#include "context.hpp" -#include "exception.hpp" -#include "message.hpp" -#include "poller.hpp" -#include "socket.hpp" - -/*! - * \brief C++ wrapper around zmq - * - * All zmq++ / zmqpp functions, constants and classes live within this namespace, - */ -namespace zmqpp -{ - -/*! - * Returns the current major.minor.revision version number as a string. - * - * \return string version number. - */ -std::string version(); - -/*! - * Retrieve the parts of the zmqpp version number. - * - * Set the three parameters to values representing the zmqpp version number. - * These values are generated at library compile time. - * - * \param major an unsigned 8 bit reference to set to the major version. - * \param minor an unsigned 8 bit reference to set to the minor version. - * \param revision an unsigned 8 bit reference to set the current revision. - */ -void version(uint8_t& major, uint8_t& minor, uint8_t& revision); - -/*! - * Retrieve the parts of the 0mq version this library was built against. - * - * Because sections of the library are optionally compiled in or ignored - * depending on the version of 0mq it was compiled against this method is - * provided to allow sanity checking for usage. - * - * Set the three parameters to values representing the 0mq version number. - * These values are generated at library compile time. - * - * \param major an unsigned 8 bit reference to set to the major version. - * \param minor an unsigned 8 bit reference to set to the minor version. - * \param revision an unsigned 8 bit reference to set the current revision. - */ -void zmq_version(uint8_t& major, uint8_t& minor, uint8_t& patch); - -typedef context context_t; /*!< \brief context type */ -typedef std::string endpoint_t; /*!< \brief endpoint type */ -typedef message message_t; /*!< \brief message type */ -typedef poller poller_t; /*!< \brief poller type */ -typedef socket socket_t; /*!< \brief socket type */ - -} - -#endif /* ZMQPP_ZMQPP_HPP_ */ diff --git a/issue_template.md b/issue_template.md index c52ad57f1f..1ecacea4f9 100644 --- a/issue_template.md +++ b/issue_template.md @@ -23,8 +23,8 @@ CHANGEME Tell us what should happen instead. **TC rev. hash/commit:** -CHANGEME Copy the first line of the `worldserver` or `bnetserver` startup. -For example: TrinityCore rev. 0000000000 2000-01-09 11:31:41 +0100 (my branch) (Win64, RelWithDebInfo, Static) (bnetserver) +CHANGEME Copy the first line of the `worldserver` or `authserver` startup. +For example: TrinityCore rev. 0000000000 2000-01-09 11:31:41 +0100 (my branch) (Win64, RelWithDebInfo, Static) (authserver) **TDB version:** CHANGEME Version of the TrinityCore database diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 5f9e2c1d61..1217e277d6 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -1,13 +1,14 @@ --- MySQL dump 10.13 Distrib 8.0.26, for Linux (x86_64) + +-- MariaDB dump 10.19 Distrib 10.11.11-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: auth -- ------------------------------------------------------ --- Server version 8.0.26 +-- Server version 10.11.11-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!50503 SET NAMES utf8mb4 */; +/*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -21,38 +22,38 @@ DROP TABLE IF EXISTS `account`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `account` ( - `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier', - `username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `sha_pass_hash` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `sessionkey` varchar(80) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `v` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `s` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `token_key` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `reg_mail` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `joindate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `last_ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `last_attempt_ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `failed_logins` int unsigned NOT NULL DEFAULT '0', - `locked` tinyint unsigned NOT NULL DEFAULT '0', - `lock_country` varchar(2) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '00', + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier', + `username` varchar(32) NOT NULL DEFAULT '', + `salt` binary(32) NOT NULL, + `verifier` binary(32) NOT NULL, + `session_key_auth` binary(40) DEFAULT NULL, + `session_key_bnet` varbinary(64) DEFAULT NULL, + `totp_secret` varbinary(128) DEFAULT NULL, + `v` varchar(64) NOT NULL DEFAULT '', + `s` varchar(64) NOT NULL DEFAULT '', + `token_key` varchar(100) NOT NULL DEFAULT '', + `email` varchar(255) NOT NULL DEFAULT '', + `reg_mail` varchar(255) NOT NULL DEFAULT '', + `joindate` timestamp NOT NULL DEFAULT current_timestamp(), + `last_ip` varchar(15) NOT NULL DEFAULT '127.0.0.1', + `last_attempt_ip` varchar(15) NOT NULL DEFAULT '127.0.0.1', + `failed_logins` int(10) unsigned NOT NULL DEFAULT 0, + `locked` tinyint(3) unsigned NOT NULL DEFAULT 0, + `lock_country` varchar(2) NOT NULL DEFAULT '00', `last_login` timestamp NULL DEFAULT NULL, - `online` tinyint unsigned NOT NULL DEFAULT '0', - `expansion` tinyint unsigned NOT NULL DEFAULT '3', - `mutetime` bigint NOT NULL DEFAULT '0', - `mutereason` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `muteby` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `locale` tinyint unsigned NOT NULL DEFAULT '0', - `os` varchar(5) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `recruiter` int unsigned NOT NULL DEFAULT '0', - `battlenet_account` int unsigned DEFAULT NULL, - `battlenet_index` tinyint unsigned DEFAULT NULL, + `online` tinyint(3) unsigned NOT NULL DEFAULT 0, + `expansion` tinyint(3) unsigned NOT NULL DEFAULT 3, + `mutetime` bigint(20) NOT NULL DEFAULT 0, + `mutereason` varchar(255) NOT NULL DEFAULT '', + `muteby` varchar(50) NOT NULL DEFAULT '', + `locale` tinyint(3) unsigned NOT NULL DEFAULT 0, + `os` varchar(5) DEFAULT NULL, + `timezone_offset` smallint(6) NOT NULL DEFAULT 0, + `recruiter` int(10) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), - UNIQUE KEY `idx_username` (`username`), - UNIQUE KEY `uk_bnet_acc` (`battlenet_account`,`battlenet_index`), - CONSTRAINT `fk_bnet_acc` FOREIGN KEY (`battlenet_account`) REFERENCES `battlenet_accounts` (`id`) + UNIQUE KEY `idx_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Account System'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -71,12 +72,12 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `account_access`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `account_access` ( - `id` int unsigned NOT NULL, - `gmlevel` tinyint unsigned NOT NULL, - `RealmID` int NOT NULL DEFAULT '-1', - PRIMARY KEY (`id`,`RealmID`) + `AccountID` int(10) unsigned NOT NULL, + `SecurityLevel` tinyint(3) unsigned NOT NULL, + `RealmID` int(11) NOT NULL DEFAULT -1, + PRIMARY KEY (`AccountID`,`RealmID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -95,14 +96,14 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `account_banned`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `account_banned` ( - `id` int unsigned NOT NULL DEFAULT '0' COMMENT 'Account id', - `bandate` int unsigned NOT NULL DEFAULT '0', - `unbandate` int unsigned NOT NULL DEFAULT '0', - `bannedby` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, - `banreason` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `active` tinyint unsigned NOT NULL DEFAULT '1', + `id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'Account id', + `bandate` int(10) unsigned NOT NULL DEFAULT 0, + `unbandate` int(10) unsigned NOT NULL DEFAULT 0, + `bannedby` varchar(50) NOT NULL, + `banreason` varchar(255) NOT NULL, + `active` tinyint(3) unsigned NOT NULL DEFAULT 1, PRIMARY KEY (`id`,`bandate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Ban List'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -122,13 +123,13 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `account_muted`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `account_muted` ( - `guid` int unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', - `mutedate` int unsigned NOT NULL DEFAULT '0', - `mutetime` int unsigned NOT NULL DEFAULT '0', - `mutedby` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, - `mutereason` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `guid` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'Global Unique Identifier', + `mutedate` int(10) unsigned NOT NULL DEFAULT 0, + `mutetime` int(10) unsigned NOT NULL DEFAULT 0, + `mutedby` varchar(50) NOT NULL, + `mutereason` varchar(255) NOT NULL, PRIMARY KEY (`guid`,`mutedate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='mute List'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -148,12 +149,12 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `autobroadcast`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `autobroadcast` ( - `realmid` int NOT NULL DEFAULT '-1', - `id` tinyint unsigned NOT NULL AUTO_INCREMENT, - `weight` tinyint unsigned DEFAULT '1', - `text` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `realmid` int(11) NOT NULL DEFAULT -1, + `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT, + `weight` tinyint(3) unsigned DEFAULT 1, + `text` longtext NOT NULL, PRIMARY KEY (`id`,`realmid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -168,189 +169,621 @@ LOCK TABLES `autobroadcast` WRITE; UNLOCK TABLES; -- --- Table structure for table `battlenet_account_bans` +-- Table structure for table `build_auth_key` -- -DROP TABLE IF EXISTS `battlenet_account_bans`; +DROP TABLE IF EXISTS `build_auth_key`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `battlenet_account_bans` ( - `id` int unsigned NOT NULL DEFAULT '0' COMMENT 'Account id', - `bandate` int unsigned NOT NULL DEFAULT '0', - `unbandate` int unsigned NOT NULL DEFAULT '0', - `bannedby` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, - `banreason` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - PRIMARY KEY (`id`,`bandate`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Ban List'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `battlenet_account_bans` --- - -LOCK TABLES `battlenet_account_bans` WRITE; -/*!40000 ALTER TABLE `battlenet_account_bans` DISABLE KEYS */; -/*!40000 ALTER TABLE `battlenet_account_bans` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `battlenet_accounts` --- - -DROP TABLE IF EXISTS `battlenet_accounts`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `battlenet_accounts` ( - `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier', - `email` varchar(320) COLLATE utf8mb4_unicode_ci NOT NULL, - `sha_pass_hash` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `v` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `s` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `sessionKey` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `joindate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `last_ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `failed_logins` int unsigned NOT NULL DEFAULT '0', - `locked` tinyint unsigned NOT NULL DEFAULT '0', - `lock_country` varchar(2) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '00', - `last_login` timestamp NULL DEFAULT NULL, - `online` tinyint unsigned NOT NULL DEFAULT '0', - `locale` tinyint unsigned NOT NULL DEFAULT '0', - `os` varchar(5) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Account System'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `battlenet_accounts` --- - -LOCK TABLES `battlenet_accounts` WRITE; -/*!40000 ALTER TABLE `battlenet_accounts` DISABLE KEYS */; -/*!40000 ALTER TABLE `battlenet_accounts` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `battlenet_components` --- - -DROP TABLE IF EXISTS `battlenet_components`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `battlenet_components` ( - `Program` varchar(4) COLLATE utf8mb4_unicode_ci NOT NULL, - `Platform` varchar(4) COLLATE utf8mb4_unicode_ci NOT NULL, - `Build` int unsigned NOT NULL, - PRIMARY KEY (`Program`,`Platform`,`Build`) +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `build_auth_key` ( + `build` int(11) NOT NULL, + `platform` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `arch` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `type` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `key` binary(16) NOT NULL, + PRIMARY KEY (`build`,`platform`,`arch`,`type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- --- Dumping data for table `battlenet_components` +-- Dumping data for table `build_auth_key` -- -LOCK TABLES `battlenet_components` WRITE; -/*!40000 ALTER TABLE `battlenet_components` DISABLE KEYS */; -INSERT INTO `battlenet_components` VALUES -('Bnet','Cmp1',3), -('Bnet','Mac',26487), -('Bnet','Mc64',26487), -('Bnet','Win',26487), -('Bnet','Wn64',26487), -('Tool','Mac',0), -('Tool','Mc64',0), -('Tool','Win',0), -('Tool','Wn64',0), -('WoW','base',15595), -('WoW','deDE',15595), -('WoW','enCN',15595), -('WoW','enGB',15595), -('WoW','enTW',15595), -('WoW','enUS',15595), -('WoW','esES',15595), -('WoW','esMX',15595), -('WoW','frFR',15595), -('WoW','koKR',15595), -('WoW','Mac',15595), -('WoW','Mc64',15595), -('WoW','ptBR',15595), -('WoW','ptPT',15595), -('WoW','ruRU',15595), -('WoW','Win',15595), -('WoW','Wn64',15595), -('WoW','zhCN',15595), -('WoW','zhTW',15595); -/*!40000 ALTER TABLE `battlenet_components` ENABLE KEYS */; +LOCK TABLES `build_auth_key` WRITE; +/*!40000 ALTER TABLE `build_auth_key` DISABLE KEYS */; +INSERT INTO `build_auth_key` VALUES +(25549,'Mac','x64','WoW',0x66FC5E09B8706126795F140308C8C1D8), +(25549,'Win','x64','WoW',0x1252624ED8CBD6FAC7D33F5D67A535F3), +(25549,'Win','x86','WoW',0xFE594FC35E7F9AFF86D99D8A364AB297), +(25996,'Mac','x64','WoW',0x210B970149D6F56CAC9BADF2AAC91E8E), +(25996,'Win','x64','WoW',0xC7FF932D6A2174A3D538CA7212136D2B), +(25996,'Win','x86','WoW',0x23C59C5963CBEF5B728D13A50878DFCB), +(26124,'Mac','x64','WoW',0xC9CA997AB8EDE1C65465CB2920869C4E), +(26124,'Win','x64','WoW',0x46DF06D0147BA67BA49AF553435E093F), +(26124,'Win','x86','WoW',0xF8C05AE372DECA1D6C81DA7A8D1C5C39), +(26365,'Mac','x64','WoW',0xDBE7F860276D6B400AAA86B35D51A417), +(26365,'Win','x64','WoW',0x59A53F307288454B419B13E694DF503C), +(26365,'Win','x86','WoW',0x2AAC82C80E829E2CA902D70CFA1A833A), +(26654,'Mac','x64','WoW',0x9234C1BD5E9687ADBD19F764F2E0E811), +(26654,'Win','x64','WoW',0xA752640E8B99FE5B57C1320BC492895A), +(26654,'Win','x86','WoW',0xFAC2D693E702B9EC9F750F17245696D8), +(26822,'Mac','x64','WoW',0x91003668C245D14ECD8DF094E065E06B), +(26822,'Win','x64','WoW',0x2B05F6D746C0C6CC7EF79450B309E595), +(26822,'Win','x86','WoW',0x283E8D77ECF7060BE6347BE4EB99C7C7), +(26899,'Mac','x64','WoW',0x8368EFC2021329110A16339D298200D4), +(26899,'Win','x64','WoW',0x3551EF0028B51E92170559BD25644B03), +(26899,'Win','x86','WoW',0xF462CD2FE4EA3EADF875308FDBB18C99), +(26972,'Mac','x64','WoW',0x341CFEFE3D72ACA9A4407DC535DED66A), +(26972,'Win','x64','WoW',0x6E212DEF6A0124A3D9AD07F5E322F7AE), +(26972,'Win','x86','WoW',0x797ECC19662DCBD5090A4481173F1D26), +(28153,'Win','x64','WoW',0xDD626517CC6D31932B479934CCDC0ABF), +(30706,'Win','x64','WoW',0xBB6D9866FE4A19A568015198783003FC), +(30993,'Win','x64','WoW',0x2BAD61655ABC2FC3D04893B536403A91), +(31229,'Win','x64','WoW',0x8A46F23670309F2AAE85C9A47276382B), +(31429,'Win','x64','WoW',0x7795A507AF9DC3525EFF724FEE17E70C), +(31478,'Win','x64','WoW',0x7973A8D54BDB8B798D9297B096E771EF), +(32305,'Win','x64','WoW',0x21F5A6FC7AD89FBF411FDA8B8738186A), +(32494,'Win','x64','WoW',0x58984ACE04919401835C61309A848F8A), +(32580,'Win','x64','WoW',0x87C2FAA0D7931BF016299025C0DDCA14), +(32638,'Win','x64','WoW',0x5D07ECE7D4A867DDDE615DAD22B76D4E), +(32722,'Win','x64','WoW',0x1A09BE1D38A122586B4931BECCEAD4AA), +(32750,'Mac','x64','WoW',0xEF1F4E4D099EA2A81FD4C0DEBC1E7086), +(32750,'Win','x64','WoW',0xC5CB669F5A5B237D1355430877173207), +(32978,'Mac','x64','WoW',0x1852C1F847E795D6EB45278CD433F339), +(32978,'Win','x64','WoW',0x76AE2EA03E525D97F5688843F5489000), +(33369,'Mac','x64','WoW',0xF5A849C70A1054F07EA3AB833EBF6671), +(33369,'Win','x64','WoW',0x5986AC18B04D3C403F56A0CF8C4F0A14), +(33528,'Win','x64','WoW',0x0ECE033CA9B11D92F7D2792C785B47DF), +(33724,'Win','x64','WoW',0x38F7BBCF284939DD20E8C64CDBF9FE77), +(33775,'Mac','x64','WoW',0x354D2DE619D124EE1398F76B0436FCFC), +(33775,'Win','x64','WoW',0xB826300A8449ED0F6EF16EA747FA2D2E), +(33941,'Win','x64','WoW',0x88AF1A36D2770D0A6CA086497096A889), +(34220,'Win','x64','WoW',0xB5E35B976C6BAF82505700E7D9666A2C), +(34601,'Win','x64','WoW',0x0D7DF38F725FABA4F009257799A10563), +(34769,'Win','x64','WoW',0x93F9B9AF6397E3E4EED94D36D16907D2), +(34963,'Mac','x64','WoW',0xC5658A17E702163447BAAAE46D130A1B), +(34963,'Win','x64','WoW',0x7BA50C879C5D04221423B02AC3603A11), +(35249,'Win','x64','WoW',0xC7B11F9AE9FF1409F5582902B3D10D1C), +(35284,'Mac','x64','WoW',0xA6201B0AC5A73D13AB2FDCC79BB252AF), +(35284,'Win','x64','WoW',0xEA3818E7DCFD2009DBFC83EE3C1E4F1B), +(35435,'Mac','x64','WoW',0x8FE657C14A46BCDB2CE6DA37E430450E), +(35435,'Win','x64','WoW',0xBB397A92FE23740EA52FC2B5BA2EC8E0), +(35662,'Mac','x64','WoW',0x5966016C368ED9F7AAB603EE6703081C), +(35662,'Win','x64','WoW',0x578BC94870C278CB6962F30E6DC203BB), +(36753,'Win','x64','WoW',0x386FDE8559B5EAD67B791B490B200B88), +(36839,'Win','x64','WoW',0x356EB4412B8EFCF72E3AF50D5181D529), +(36949,'Win','x64','WoW',0x51C074CD8A09A75384B9B44188C56981), +(37142,'Win','x64','WoW',0x5D9CFB3139F0D1B6C2B304261F9EABC9), +(37176,'Win','x64','WoW',0x3C725EA504EC3DAED143EB6FF3B48CDA), +(37474,'Mac','x64','WoW',0x024C9BE7E44237B7E81C6D42E678D433), +(37474,'Win','x64','WoW',0x0DE685BBB0551086E7FBDC0B4BB06A5B), +(38134,'Win','x64','WoW',0x32275ED0F13B357C28BDB0E611EF9E31), +(38556,'Win','x64','WoW',0xEC7D5AF64364AC3E7181F3FBA1B3A882), +(39653,'Win','x64','WoW',0x10D015AB1EEB91310428D9C57EE24632), +(39804,'Win','x64','WoW',0xE42D2BBA12ED260A76F9B1E477E19EA5), +(40000,'Win','x64','WoW',0x4CB1433AB637F09F03FBBD1B221B04B0), +(40120,'Mac','x64','WoW',0x853F0F2985CEAED46DF422583CD07A7C), +(40120,'Win','x64','WoW',0x04F47EAEFD8BDEFE14AA0350EA336678), +(40443,'Win','x64','WoW',0x8597BB43E8AB38C85504E8BFB72ABBF5), +(40593,'Win','x64','WoW',0xBA14570F2D62D5F61953394164A8DAE2), +(40725,'Win','x64','WoW',0xC1EBDBEB9BB2956EBCCEF7C9D27A1B3B), +(40906,'Win','x64','WoW',0xF5FC259C8635488AFE0D0CD023F361D4), +(40944,'Win','x64','WoW',0x368FC7FABAF487A8A049C11970657074), +(40966,'Win','x64','WoW',0xD90F47AF21F381D2D8F3763B994BAC88), +(41031,'Win','x64','WoW',0x019A0FACD6B0D6374B7BA69A5B677449), +(41079,'Win','x64','WoW',0xF8853CF823BC0BBE8A9677A762DFAEE1), +(41288,'Win','x64','WoW',0x871C0C9691DBC536EB24B68EC73FAD5B), +(41323,'Win','x64','WoW',0xE53D0DF1FAC1A59A1C8071B295A04A1D), +(41359,'Win','x64','WoW',0x5F8D7F2A690A4375A1B52A28D6D681FA), +(41488,'Win','x64','WoW',0x1BC91EC368705815F3F532B553DAD981), +(41793,'Win','x64','WoW',0xB3B47DA3B7615570742A55B96614EE1C), +(42010,'Win','x64','WoW',0x302970161D16417B5BE553CC530E011A), +(42423,'Win','x64','WoW',0x0B03614A7E94DD57548596BE420E9DC2), +(42488,'Win','x64','WoW',0xA78755E6928D83A271C5D1EE3CDB6F15), +(42521,'Win','x64','WoW',0x5FE6C12FC407C6B15B4A5D3B5B4A5D3B), +(42538,'Win','x64','WoW',0x71A7504BD53F8DE518F24265D37310AE), +(42560,'Win','x64','WoW',0x115FE8C38A8D67CA4664BB192E0F0DFE), +(42614,'Win','x64','WoW',0x772BE726FEEF42124255D2EA7973CA18), +(42698,'Win','x64','WoW',0xB4497B1CD11FC974C5FB09548AC27269), +(42825,'Win','x64','WoW',0xA14DA228C6A6AFF1DDBA51218939E557), +(42852,'Win','x64','WoW',0xDE9F9F0C3CC8FD54D3AFF99CEFFCE129), +(42937,'Win','x64','WoW',0xF5FC75E70874752C92846B3333920E63), +(42979,'Win','x64','WoW',0xE1DD38AE6450FC4D2AE4609233C59E54), +(43114,'Win','x64','WoW',0xF75C9380CCB24A48A24EEE52C1594A7E), +(43206,'Win','x64','WoW',0xDDE806532C7704FFB75F256DC5F1F3D9), +(43340,'Win','x64','WoW',0x70E46D2D888E84DF9316EA849B068CF4), +(43345,'Win','x64','WoW',0xD911ABFCDA030DEE8CAF4EE3F60DEE13), +(43971,'Win','x64','WoW',0x681CF99E61FB0005A5C7D31D0AAD1ED9), +(44015,'Win','x64','WoW',0xFCF0BDA7C98BFEF92AE6D8C39A217ABD), +(44061,'Win','x64','WoW',0xFD2B5C0B3293FE0E9CAA6EB0B7788119), +(44127,'Win','x64','WoW',0x787887CEC9FCC9B516481F60E4FC34A8), +(44232,'Win','x64','WoW',0x81F0A71DF7E9873BB3750022D64D33CF), +(44325,'Win','x64','WoW',0x138A7D524D268A7F9934C3D148E8F01B), +(44730,'Win','x64','WoW',0xFC0B18C47BB4C79F4300CA0FF3E5CAC7), +(44908,'Win','x64','WoW',0xBFFAEC40C9BCD591C7C959A9D5A8BA8C), +(45114,'Win','x64','WoW',0xD7AFE240BD00F06C30D0C2D16E54A8BE), +(45161,'Win','x64','WoW',0x74BD2E787A98B145B063BDA9A98F6CBD), +(45338,'Win','x64','WoW',0x5CE2094A41B61EDA9DF56378BC3B1DE0), +(45745,'Win','x64','WoW',0x0F6DC90161694D765A595A3AF603166B), +(46479,'Win','x64','WoW',0xCB9AF4D89B60A3ABA288D395D315D932), +(46658,'Win','x64','WoW',0x3F8EFB085428D75360E9EFE25CD8639A), +(46689,'Win','x64','WoW',0xD9A11D188D6AD60906F5467510EFD3AA), +(46702,'Win','x64','WoW',0x01B4D1688FF97DC9AAFCCD0A0B842C0B), +(46741,'Win','x64','WoW',0x4C0F4A7EC2098AF1FBA745848EC79A78), +(46801,'Win','x64','WoW',0xE6AC18D1EA5D36ABFFAE5EDED80630DF), +(46879,'Win','x64','WoW',0xEFEC43936051DD1A210633AF1F6B63DB), +(46924,'Win','x64','WoW',0xE6CE0B1A8119F069ECF1E7DBAA7BB2F8), +(47067,'Win','x64','WoW',0x63862CFCDEA6BD2BD7F740EB36B65657), +(47187,'Win','x64','WoW',0x711F8455C5000C237292E1E6E90631E1), +(47213,'Win','x64','WoW',0x23C50D88CEAC0A8696ADDE8DD244D4A2), +(47631,'Win','x64','WoW',0xF986AB91D0AEB20822EFB72F4256713C), +(47777,'Win','x64','WoW',0xA88C04915AB9E035A104E55C4DCF5F9F), +(47799,'Win','x64','WoW',0x7364EB093C23DB2CDC9513D5A7B4933E), +(47825,'Win','x64','WoW',0x82A3B94E5E727AF3A208B471FF2054C0), +(47849,'Win','x64','WoW',0xDD8BBE2087A28C0AF4984CBE23A1C707), +(47871,'Win','x64','WoW',0x8E4F7D30EE4982B02B3B3F8837C2C4F2), +(47884,'Win','x64','WoW',0x2B7A002BC359F2C31104BC2DE04302BF), +(47936,'Win','x64','WoW',0x833D30D8FBC43B3FAE99CD3898D70849), +(47967,'Win','x64','WoW',0xCFE225D0089E224D9E7541D3B5C26478), +(48001,'Win','x64','WoW',0x4B0260A37BD95B615E71048469E6D5BB), +(48069,'Win','x64','WoW',0x558CDF958FA082E95849779C7C6945E5), +(48317,'Win','x64','WoW',0xC096E37B45B43244E9C79916604DD4AF), +(48397,'Win','x64','WoW',0x64BA8779EAA97E6C57982B6B1A5B32E7), +(48526,'Win','x64','WoW',0xD5B7D3303A2A741E6913EE1AEB0BCB65), +(48676,'Win','x64','WoW',0xE059FB74DFF6438CC20C7F28900F64CA), +(48749,'Win','x64','WoW',0x92DBCCA0E33DFB8A17A2B6A39246B288), +(48838,'Win','x64','WoW',0x9E6F4E1E46EF228D2DE90F7BC48AAA96), +(48865,'Win','x64','WoW',0x4B774ABE7B34D6702571B4279A4B6A13), +(48892,'Win','x64','WoW',0xAA31BF27458321B03A1A346964DD7B9D), +(48966,'Win','x64','WoW',0x823142CA131FBB715FF55D4343E55C6D), +(48999,'Win','x64','WoW',0x79BA6FF0F9672EEF875F64155C8B62D4), +(49267,'Win','x64','WoW',0xEEE77EA5A216E0731ADBB41AEFB1DF31), +(49318,'Win','x64','WoW',0xAF439AEE62EE48B36C1725111E3D9BBF), +(49343,'Win','x64','WoW',0x301A0B4C0942B9B6F605B903AD6C1F60), +(49407,'Win','x64','WoW',0x6413820DC9885BB0693B37090CBB2F30), +(49426,'Win','x64','WoW',0xD85EDFBFE9A94A55E2B4510BE41C19B2), +(49444,'Win','x64','WoW',0x363B2B05285BDD8857419D2866316D3C), +(49474,'Win','x64','WoW',0x44A7D2B352EE3D098A3CB4C2F1065E37), +(49570,'Win','x64','WoW',0xB024DE67ACAEB9E8EE6DB38DC53E8281), +(49679,'Win','x64','WoW',0x9CE59B68D8797EBF00581F41138F4316), +(49741,'Win','x64','WoW',0x0EF181E2BB0E946CF3B7422ADEB6CD1A), +(49801,'Win','x64','WoW',0x0832179567B66CA85DBD5678B604C683), +(49890,'Win','x64','WoW',0x22A5B8A1EB797A64995F705B3DBCB14C), +(50000,'Win','x64','WoW',0x02F06FFA2296FD66384295DBFD5A4C91), +(50401,'Win','x64','WoW',0x3EEF52D902CCE81D16D0E255F0AA4938), +(50438,'Win','x64','WoW',0x0B5F68F06B129CB4C57702F6D30F260B), +(50467,'Win','x64','WoW',0x5E996B1CDCEE68432D6340138E68D1EB), +(50469,'Win','x64','WoW',0x1768CCB6589E16AB3BEFA9D608A393A2), +(50504,'Win','x64','WoW',0x7D5FD20C0B32C9AF5DD65433B391D49C), +(50585,'Win','x64','WoW',0xC4F7CC38A3B84935A485F7EDAD3E764B), +(50622,'Win','x64','WoW',0xD23A26FD75FD9A6073EB7060AA28E6A7), +(50747,'Win','x64','WoW',0x2D3C386A9C45C27304ED3A3C6EB3F7C8), +(50791,'Win','x64','WoW',0x0BE7D0BB07EF37C25CBC682409091EA0), +(51130,'Win','x64','WoW',0x44CD2C91E4F0655DA387483726CE4035), +(51187,'Win','x64','WoW',0x74E2055D3965269447B5CB1B31FC71C6), +(51237,'Win','x64','WoW',0xC8660A21B766646FBD67F481CFCF55C3), +(51261,'Win','x64','WoW',0x1BEBB57AE450331E9F8C301AA7876FAB), +(51313,'Win','x64','WoW',0x35419ED0AB16735CF720858F45DC300C), +(51421,'Win','x64','WoW',0x45E24D6F3335269787DF2B2063939002), +(51485,'Win','x64','WoW',0xEC549E1D0A5DD85C03E7A9D93B7DC6D1), +(51536,'Win','x64','WoW',0x570EEA10A8EC169C3FF9621D1B635BB4), +(51754,'Win','x64','WoW',0xBED5A861C071AB41FEF6087E0C37BB1A), +(51886,'Win','x64','WoW',0x09CF8919FD2EABDEAEBC0C810F53B511), +(51972,'Win','x64','WoW',0x444DC7EF3544B6670C18884DADA00428), +(52038,'Win','x64','WoW',0xA8EF004ADED8A3AFF5A67D2BB8D95795), +(52068,'Win','x64','WoW',0xA44F842BACCC7EE8E2975FAF01F12474), +(52095,'Win','x64','WoW',0xBA36382887D16D274EA9149695F0C9C8), +(52106,'Win','x64','WoW',0x95F43869B7D881212CBC1690B8F393ED), +(52129,'Win','x64','WoW',0x02DD842F2A7162EEB8FD5B9D325606F8), +(52148,'Win','x64','WoW',0x8A969717C8CDC6E7FF4C54D5CB00C224), +(52188,'Win','x64','WoW',0x977DF9993E94855DED5E328BA7A2F21F), +(52301,'Win','x64','WoW',0x821AA3BB237B400B82F44970250539AA), +(52393,'Win','x64','WoW',0xB013ED23B7EF51B29A45594D9BBB0D03), +(52485,'Win','x64','WoW',0x5805CEB4650730AE489258DD30E34441), +(52545,'Win','x64','WoW',0xFB52179A8355A46EDBFBDC8E8E5CDAFD), +(52607,'Win','x64','WoW',0x8F002E4AADCAEABB08ABC2880B31AD60), +(52649,'Win','x64','WoW',0xD0B779FBECEBC1ED5A85D83F03C8A75B), +(52808,'Win','x64','WoW',0x6276712B6C8AEA21CD5D94D52FEE70EE), +(52902,'Win','x64','WoW',0xD4F0A24CDF165628538C1C387A326AF3), +(52968,'Win','x64','WoW',0x2D247FD440C44D4F1BF80B075B8720F2), +(52983,'Win','x64','WoW',0xB1E5ADA5FDD06C9AB5E5D8A6983324AC), +(53007,'Win','x64','WoW',0xA21AFB4D381C56AF471D994258C0EEF5), +(53040,'Win','x64','WoW',0x2F1283BF7B7F307B70DBBD75CC42D7C3), +(53104,'Win','x64','WoW',0xDBD79EC8DF044B53C78931B985CAB406), +(53162,'Win','x64','WoW',0x8A67511FBF8984EEE2B630F7CB23376A), +(53212,'Win','x64','WoW',0x08761EFF2F9B639364B9A9FBFFFFB949), +(53262,'Win','x64','WoW',0x614A72D53126348A4927EC0F53FD2B7A), +(53441,'Win','x64','WoW',0xBFDD7D0FE87D5F75E6DEB4F5C99D7C99), +(53584,'Win','x64','WoW',0xCDD7A93659A03460B5A6CE1C4ACE5554), +(53840,'Win','x64','WoW',0xAC97D745C60DD3DC5F973E55C0E3649E), +(53877,'Win','x64','WoW',0x16320F95B63846A2276E1D2612C34AD4), +(53913,'Win','x64','WoW',0x475680680B2192EBCF6744D14F755199), +(53989,'Win','x64','WoW',0x3AEB90ACB9E18B88BA1021F52D51B857), +(54070,'Win','x64','WoW',0xFDA08264B7587250CF78F9B960218169), +(54205,'Win','x64','WoW',0x589D59EB3F0D6D77C2175D9302F78FDD), +(54358,'Win','x64','WoW',0x89C733D366E845FB9264404CD48CCA89), +(54499,'Win','x64','WoW',0x6AC1F6180FC4C390F782DB933BD83326), +(54577,'Win','x64','WoW',0xCBBBBBFFB2C652F0F4A7848D86E1B063), +(54601,'Win','x64','WoW',0xF8B866CF7DB9A12273F35B3929627375), +(54604,'Win','x64','WoW',0xA5FF4CE535F69D4D7F638CB2C11F2243), +(54630,'Win','x64','WoW',0xF37935510BA6B559363C160E1DF18230), +(54673,'Win','x64','WoW',0xAF8B9C8A9C6128498E85228B965A004D), +(54717,'Win','x64','WoW',0x862BBA15158DFF6B56BCF71C1B34D41A), +(54736,'Win','x64','WoW',0xFE58F039D91E1C248886A2828127CA2F), +(54762,'Win','x64','WoW',0x5F7FDA560030255445B713456A286CFA), +(54847,'Win','x64','WoW',0x32FDA0353160EC51EB36195CFACEF2B7), +(54904,'Win','x64','WoW',0x09CBEC3C0DEA28BCA79F1FD9B879B0E3), +(54988,'Win','x64','WoW',0x8F2791553226871977B4F9D7F1137311), +(55142,'Win','x64','WoW',0x298B99B5AD67EA3D2AB4B3E07A415305), +(55165,'Win','x64','WoW',0x26D4D1C01434A8A6723DCABC944B6FD0), +(55261,'Win','x64','WoW',0x84E153A3DD1F8249274B91047AAC7AED), +(55461,'Win','x64','WoW',0xC4522674F854EFECC76C898EC9545099), +(55664,'Win','x64','WoW',0xDBCA58486FAAA0FE54EA287A3047E923), +(55666,'Win','x64','WoW',0xF7E5A88E4D3615B652C8B9D76E7F617C), +(55792,'Win','x64','WoW',0xC4DECDAA44BC548FF09EF3BB837D2147), +(55793,'Win','x64','WoW',0xF9CF3232AD1C38C2028668D5BB64198F), +(55818,'Win','x64','WoW',0x903A9B546248F71B16D9D9B06A072C24), +(55824,'Win','x64','WoW',0x8A6F13269A2896067A1E88789FB41BA7), +(55846,'Win','x64','WoW',0xBB5E1BED705872C226834B95A9E9F8A9), +(55933,'Win','x64','WoW',0xC34D42CB351C400D1319D221197CF18D), +(55939,'Win','x64','WoW',0x91529F4CE41DE4E54E132660ACDCADC5), +(55959,'Win','x64','WoW',0xED57E0538FD1CE99B171BE34823148A9), +(55960,'Win','x64','WoW',0x078C056CFC7B371BDE1BAF308E6C19AF), +(56008,'Win','x64','WoW',0x00FCD6BFFCCCBA7A8E71E307EA6EBD0C), +(56110,'Win','x64','WoW',0x800BCA228E2FAE37ED160F3C09E21F3A), +(56162,'Win','x64','WoW',0x6F5C93BA436665A94DB67CE5361D4EA8), +(56196,'Mac','A64','WoW',0x778F6A5DF79A4EF1B86F651F3B303CE7), +(56196,'Win','x64','WoW',0x81FC14274BFF0347FFF9C8B1AA6BED9B), +(56263,'Win','x64','WoW',0xEA8472C99236CC617BF518A924014D56), +(56288,'Mac','A64','WoW',0x41710C793EF021721F14B06EC1896D3F), +(56288,'Win','x64','WoW',0x03544E35D0480938E5C1238B3A26BDDD), +(56311,'Mac','A64','WoW',0x412D3200715AAFDC0522DF031A941F0E), +(56311,'Win','x64','WoW',0xAC6415575AEE4D32735FFAD0C57226B2), +(56313,'Mac','A64','WoW',0xA83ED19EE659BC95CC322D1E49BDEDBB), +(56313,'Win','x64','WoW',0xEAF769009A9AD3B1AA0414E1C344074B); +/*!40000 ALTER TABLE `build_auth_key` ENABLE KEYS */; UNLOCK TABLES; -- --- Table structure for table `battlenet_modules` +-- Table structure for table `build_executable_hash` -- -DROP TABLE IF EXISTS `battlenet_modules`; +DROP TABLE IF EXISTS `build_executable_hash`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `battlenet_modules` ( - `Hash` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, - `Name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `Type` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL, - `System` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL, - `Data` text COLLATE utf8mb4_unicode_ci, - PRIMARY KEY (`Name`,`System`), - UNIQUE KEY `uk_name_type_system` (`Name`,`Type`,`System`) +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `build_executable_hash` ( + `build` int(11) NOT NULL, + `platform` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `executableHash` binary(20) NOT NULL, + PRIMARY KEY (`build`,`platform`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- --- Dumping data for table `battlenet_modules` +-- Dumping data for table `build_executable_hash` -- -LOCK TABLES `battlenet_modules` WRITE; -/*!40000 ALTER TABLE `battlenet_modules` DISABLE KEYS */; -INSERT INTO `battlenet_modules` VALUES -('cc654428261322763f4cada5b7f4b3b67660e85639bea916986b3f366fe8adc2','ERRS','xml','enGB','AA6C50D3'), -('3c2f63e5949aa6fd6cf330b109ca5b9adcd215beac846b7462ed3aa01d5ad6bb','Password','auth','Mac',NULL), -('19c91b68752b7826df498bf73aca1103c86962a9a55a0a7033e5ad895f4d927c','Password','auth','Mc64',NULL), -('2e6d53adab37a41542b38e01f62cd365eab8805ed0de73c307cc6d9d1dfe478c','Password','auth','Win',NULL), -('851c1d2ef926e9b9a345a460874e65517195129b9e3bdec7cc77710fa0b1fad6','Password','auth','Wn64',NULL), -('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38','PFTY','pfty','csCZ','DF6C50D3'), -('047329d08d433da2622e9fc2ee96c8dd8f35e7770699d07cf74855b9c8ea9125','PFTY','pfty','deDE','DF6C50D3'), -('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enAU','DF6C50D3'), -('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enGB','DF6C50D3'), -('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enSG','DF6C50D3'), -('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enTH','DF6C50D3'), -('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enUS','DF6C50D3'), -('870f53d10b4e1b09d6b622cd5671ba4ff1ad69512dfa2c676072c52e45c7f0f9','PFTY','pfty','esES','DF6C50D3'), -('e8b82becbe0a0a1bbb5561df69320edbd770897a8deaab23caa6736255e0dc33','PFTY','pfty','esMX','DF6C50D3'), -('305bbdab1953e65974a249e276867e13ad2c3cabca3668983cb5ed406251bb7b','PFTY','pfty','frFR','DF6C50D3'), -('b72e65b6b34d8f859e79b5f28952e26553a796d5e1d75c2b5930bc0daeaa728c','PFTY','pfty','itIT','DF6C50D3'), -('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38','PFTY','pfty','jaJP','DF6C50D3'), -('7466b2db3f03768aa2527535d4b3c6c9ef9e8fb07c6db88b1019f3d25a2942e8','PFTY','pfty','koKR','DF6C50D3'), -('a8c77051991b1a6c5dfe412e9f46d8f584349996fbde37c4f2a527c192163502','PFTY','pfty','plPL','DF6C50D3'), -('0a3f6f3f0535ea21dbe620085192afc796203047e270e0e1b76f15a739fe1797','PFTY','pfty','ptBR','DF6C50D3'), -('5813f318f7e40a07a7cdfeeec9827942e6fdc5ccee0d4171148443e429ad0ead','PFTY','pfty','ruRU','DF6C50D3'), -('2753d31092f1978bdd78ebd4fae2d189364ad7108ceb22fbf1413be1f43bef04','PFTY','pfty','zhCN','DF6C50D3'), -('3e381d4f83201f4e3c482eb74da12e5ff9dd924da2413d8fb33f5eea9a02c2c2','PFTY','pfty','zhTW','DF6C50D3'), -('00ffd88a437afbb88d7d4b74be2e3b43601605ee229151aa9f4bebb29ef66280','Resume','auth','Mac',NULL), -('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL), -('bfe4ceb47700aa872e815e007e27df955d4cd4bc1fe731039ee6498ce209f368','Resume','auth','Win',NULL), -('898166926805f897804bdbbf40662c9d768590a51a0b26c40dbcdf332ba11974','Resume','auth','Wn64',NULL), -('c0f38d05aa1b83065e839c9bd96c831e9f7e42477085138752657a6a9bb9c520','RiskFingerprint','auth','Mac',NULL), -('1af5418a448f8ad05451e3f7dbb2d9af9cb13458eea2368ebfc539476b954f1c','RiskFingerprint','auth','Mc64',NULL), -('5e298e530698af905e1247e51ef0b109b352ac310ce7802a1f63613db980ed17','RiskFingerprint','auth','Win',NULL), -('8c43bda10be33a32abbc09fb2279126c7f5953336391276cff588565332fcd40','RiskFingerprint','auth','Wn64',NULL), -('207640724f4531d3b2a21532224d1486e8c4d2d805170381cbc3093264157960','SelectGameAccount','auth','Mac',NULL), -('52e2978db6468dfade7c61da89513f443c9225692b5085fbe956749870993703','SelectGameAccount','auth','Mc64',NULL), -('abc6bb719a73ec1055296001910e26afa561f701ad9995b1ecd7f55f9d3ca37c','SelectGameAccount','auth','Win',NULL), -('894d25d3219d97d085ea5a8b98e66df5bd9f460ec6f104455246a12b8921409d','SelectGameAccount','auth','Wn64',NULL), -('548b5ef9e0dd5c2f89f59c3e0979249b27505c51f0c77d2b27133726eaee0ad0','Thumbprint','auth','Mac','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'), -('b37136b39add83cfdbafa81857de3dd8f15b34e0135ec6cd9c3131d3a578d8c2','Thumbprint','auth','Mc64','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'), -('36b27cd911b33c61730a8b82c8b2495fd16e8024fc3b2dde08861c77a852941c','Thumbprint','auth','Win','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'), -('c3a1ac0694979e709c3b5486927e558af1e2be02ca96e5615c5a65aacc829226','Thumbprint','auth','Wn64','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'), -('393ca8d75aff6f04f79532cf95a88b91e5743bc59121520ac31fc4508019fe60','Token','auth','Mac',NULL), -('a1edab845d9e13e9c84531369be2f61b930a37c8e7a9c66d11ef8963380e178a','Token','auth','Mc64',NULL), -('fbe675a99fb5f4b7fb3eb5e5a22add91a4cabf83e3c5930c6659ad13c457ba18','Token','auth','Win',NULL), -('a330f388b6687f8a42fe8fbb592a3df724b20b65fb0989342bb8261f2f452318','Token','auth','Wn64',NULL); -/*!40000 ALTER TABLE `battlenet_modules` ENABLE KEYS */; +LOCK TABLES `build_executable_hash` WRITE; +/*!40000 ALTER TABLE `build_executable_hash` DISABLE KEYS */; +INSERT INTO `build_executable_hash` VALUES +(5875,'OSX',0x8D173CC381961EEBABF336F5E6675B101BB513E5), +(5875,'Win',0x95EDB27C7823B363CBDDAB56A392E7CB73FCCA20), +(8606,'OSX',0xD8B0ECFE534BC1131E19BAD1D4C0E813EEE4994F), +(8606,'Win',0x319AFAA3F2559682F9FF658BE01456255F456FB1), +(12340,'OSX',0xB706D13FF2F4018839729461E3F8A0E2B5FDC034), +(12340,'Win',0xCDCBBD5188315E6B4D19449D492DBCFAF156A347); +/*!40000 ALTER TABLE `build_executable_hash` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `build_info` +-- + +DROP TABLE IF EXISTS `build_info`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `build_info` ( + `build` int(11) NOT NULL, + `majorVersion` int(11) DEFAULT NULL, + `minorVersion` int(11) DEFAULT NULL, + `bugfixVersion` int(11) DEFAULT NULL, + `hotfixVersion` char(3) DEFAULT NULL, + PRIMARY KEY (`build`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `build_info` +-- + +LOCK TABLES `build_info` WRITE; +/*!40000 ALTER TABLE `build_info` DISABLE KEYS */; +INSERT INTO `build_info` VALUES +(5875,1,12,1,NULL), +(6005,1,12,2,NULL), +(6141,1,12,3,NULL), +(8606,2,4,3,NULL), +(9947,3,1,3,NULL), +(10505,3,2,2,'a'), +(11159,3,3,0,'a'), +(11403,3,3,2,NULL), +(11723,3,3,3,'a'), +(12340,3,3,5,'a'), +(13623,4,0,6,'a'), +(13930,3,3,5,'a'), +(14545,4,2,2,NULL), +(15595,4,3,4,NULL), +(19116,6,0,3,NULL), +(19243,6,0,3,NULL), +(19342,6,0,3,NULL), +(19702,6,1,0,NULL), +(19802,6,1,2,NULL), +(19831,6,1,2,NULL), +(19865,6,1,2,NULL), +(20182,6,2,0,'a'), +(20201,6,2,0,NULL), +(20216,6,2,0,NULL), +(20253,6,2,0,NULL), +(20338,6,2,0,NULL), +(20444,6,2,2,NULL), +(20490,6,2,2,'a'), +(20574,6,2,2,'a'), +(20726,6,2,3,NULL), +(20779,6,2,3,NULL), +(20886,6,2,3,NULL), +(21355,6,2,4,NULL), +(21463,6,2,4,NULL), +(21742,6,2,4,NULL), +(22248,7,0,3,NULL), +(22293,7,0,3,NULL), +(22345,7,0,3,NULL), +(22410,7,0,3,NULL), +(22423,7,0,3,NULL), +(22498,7,0,3,NULL), +(22522,7,0,3,NULL), +(22566,7,0,3,NULL), +(22594,7,0,3,NULL), +(22624,7,0,3,NULL), +(22747,7,0,3,NULL), +(22810,7,0,3,NULL), +(22900,7,1,0,NULL), +(22908,7,1,0,NULL), +(22950,7,1,0,NULL), +(22995,7,1,0,NULL), +(22996,7,1,0,NULL), +(23171,7,1,0,NULL), +(23222,7,1,0,NULL), +(23360,7,1,5,NULL), +(23420,7,1,5,NULL), +(23911,7,2,0,NULL), +(23937,7,2,0,NULL), +(24015,7,2,0,NULL), +(24330,7,2,5,NULL), +(24367,7,2,5,NULL), +(24415,7,2,5,NULL), +(24430,7,2,5,NULL), +(24461,7,2,5,NULL), +(24742,7,2,5,NULL), +(25549,7,3,2,NULL), +(25996,7,3,5,NULL), +(26124,7,3,5,NULL), +(26365,7,3,5,NULL), +(26654,7,3,5,NULL), +(26822,7,3,5,NULL), +(26899,7,3,5,NULL), +(26972,7,3,5,NULL), +(28153,8,0,1,NULL), +(30706,8,1,5,NULL), +(30993,8,2,0,NULL), +(31229,8,2,0,NULL), +(31429,8,2,0,NULL), +(31478,8,2,0,NULL), +(32305,8,2,5,NULL), +(32494,8,2,5,NULL), +(32580,8,2,5,NULL), +(32638,8,2,5,NULL), +(32722,8,2,5,NULL), +(32750,8,2,5,NULL), +(32978,8,2,5,NULL), +(33369,8,3,0,NULL), +(33528,8,3,0,NULL), +(33724,8,3,0,NULL), +(33775,8,3,0,NULL), +(33941,8,3,0,NULL), +(34220,8,3,0,NULL), +(34601,8,3,0,NULL), +(34769,8,3,0,NULL), +(34963,8,3,0,NULL), +(35249,8,3,7,NULL), +(35284,8,3,7,NULL), +(35435,8,3,7,NULL), +(35662,8,3,7,NULL), +(36753,9,0,2,NULL), +(36839,9,0,2,NULL), +(36949,9,0,2,NULL), +(37142,9,0,2,NULL), +(37176,9,0,2,NULL), +(37474,9,0,2,NULL), +(38134,9,0,5,NULL), +(38556,9,0,5,NULL), +(39653,9,1,0,NULL), +(39804,9,1,0,NULL), +(40000,9,1,0,NULL), +(40120,9,1,0,NULL), +(40443,9,1,0,NULL), +(40593,9,1,0,NULL), +(40725,9,1,0,NULL), +(40906,9,1,5,NULL), +(40944,9,1,5,NULL), +(40966,9,1,5,NULL), +(41031,9,1,5,NULL), +(41079,9,1,5,NULL), +(41288,9,1,5,NULL), +(41323,9,1,5,NULL), +(41359,9,1,5,NULL), +(41488,9,1,5,NULL), +(41793,9,1,5,NULL), +(42010,9,1,5,NULL), +(42423,9,2,0,NULL), +(42488,9,2,0,NULL), +(42521,9,2,0,NULL), +(42538,9,2,0,NULL), +(42560,9,2,0,NULL), +(42614,9,2,0,NULL), +(42698,9,2,0,NULL), +(42825,9,2,0,NULL), +(42852,9,2,0,NULL), +(42937,9,2,0,NULL), +(42979,9,2,0,NULL), +(43114,9,2,0,NULL), +(43206,9,2,0,NULL), +(43340,9,2,0,NULL), +(43345,9,2,0,NULL), +(43971,9,2,5,NULL), +(44015,9,2,5,NULL), +(44061,9,2,5,NULL), +(44127,9,2,5,NULL), +(44232,9,2,5,NULL), +(44325,9,2,5,NULL), +(44730,9,2,5,NULL), +(44908,9,2,5,NULL), +(45114,9,2,7,NULL), +(45161,9,2,7,NULL), +(45338,9,2,7,NULL), +(45745,9,2,7,NULL), +(46479,10,0,2,NULL), +(46658,10,0,2,NULL), +(46689,10,0,2,NULL), +(46702,10,0,2,NULL), +(46741,10,0,2,NULL), +(46801,10,0,2,NULL), +(46879,10,0,2,NULL), +(46924,10,0,2,NULL), +(47067,10,0,2,NULL), +(47187,10,0,2,NULL), +(47213,10,0,2,NULL), +(47631,10,0,2,NULL), +(47777,10,0,5,NULL), +(47799,10,0,5,NULL), +(47825,10,0,5,NULL), +(47849,10,0,5,NULL), +(47871,10,0,5,NULL), +(47884,10,0,5,NULL), +(47936,10,0,5,NULL), +(47967,10,0,5,NULL), +(48001,10,0,5,NULL), +(48069,10,0,5,NULL), +(48317,10,0,5,NULL), +(48397,10,0,5,NULL), +(48526,10,0,5,NULL), +(48676,10,0,7,NULL), +(48749,10,0,7,NULL), +(48838,10,0,7,NULL), +(48865,10,0,7,NULL), +(48892,10,0,7,NULL), +(48966,10,0,7,NULL), +(48999,10,0,7,NULL), +(49267,10,0,7,NULL), +(49318,10,1,0,NULL), +(49343,10,0,7,NULL), +(49407,10,1,0,NULL), +(49426,10,1,0,NULL), +(49444,10,1,0,NULL), +(49474,10,1,0,NULL), +(49570,10,1,0,NULL), +(49679,10,1,0,NULL), +(49741,10,1,0,NULL), +(49801,10,1,0,NULL), +(49890,10,1,0,NULL), +(50000,10,1,0,NULL), +(50401,10,1,5,NULL), +(50438,10,1,5,NULL), +(50467,10,1,5,NULL), +(50469,10,1,5,NULL), +(50504,10,1,5,NULL), +(50585,10,1,5,NULL), +(50622,10,1,5,NULL), +(50747,10,1,5,NULL), +(50791,10,1,5,NULL), +(51130,10,1,5,NULL), +(51187,10,1,7,NULL), +(51237,10,1,7,NULL), +(51261,10,1,7,NULL), +(51313,10,1,7,NULL), +(51421,10,1,7,NULL), +(51485,10,1,7,NULL), +(51536,10,1,7,NULL), +(51754,10,1,7,NULL), +(51886,10,1,7,NULL), +(51972,10,1,7,NULL), +(52038,10,2,0,NULL), +(52068,10,2,0,NULL), +(52095,10,2,0,NULL), +(52106,10,2,0,NULL), +(52129,10,2,0,NULL), +(52148,10,2,0,NULL), +(52188,10,2,0,NULL), +(52301,10,2,0,NULL), +(52393,10,2,0,NULL), +(52485,10,2,0,NULL), +(52545,10,2,0,NULL), +(52607,10,2,0,NULL), +(52649,10,2,0,NULL), +(52808,10,2,0,NULL), +(52902,10,2,5,NULL), +(52968,10,2,5,NULL), +(52983,10,2,5,NULL), +(53007,10,2,5,NULL), +(53040,10,2,5,NULL), +(53104,10,2,5,NULL), +(53162,10,2,5,NULL), +(53212,10,2,5,NULL), +(53262,10,2,5,NULL), +(53441,10,2,5,NULL), +(53584,10,2,5,NULL), +(53840,10,2,6,NULL), +(53877,10,2,6,NULL), +(53913,10,2,6,NULL), +(53989,10,2,6,NULL), +(54070,10,2,6,NULL), +(54205,10,2,6,NULL), +(54358,10,2,6,NULL), +(54499,10,2,6,NULL), +(54577,10,2,7,NULL), +(54601,10,2,7,NULL), +(54604,10,2,7,NULL), +(54630,10,2,7,NULL), +(54673,10,2,7,NULL), +(54717,10,2,7,NULL), +(54736,10,2,7,NULL), +(54762,10,2,7,NULL), +(54847,10,2,7,NULL), +(54904,10,2,7,NULL), +(54988,10,2,7,NULL), +(55142,10,2,7,NULL), +(55165,10,2,7,NULL), +(55261,10,2,7,NULL), +(55461,10,2,7,NULL), +(55664,10,2,7,NULL), +(55666,11,0,0,NULL), +(55792,11,0,0,NULL), +(55793,11,0,0,NULL), +(55818,11,0,0,NULL), +(55824,11,0,0,NULL), +(55846,11,0,0,NULL), +(55933,11,0,0,NULL), +(55939,11,0,0,NULL), +(55959,11,0,2,NULL), +(55960,11,0,0,NULL), +(56008,11,0,0,NULL), +(56110,11,0,2,NULL), +(56162,11,0,2,NULL), +(56196,11,0,2,NULL), +(56263,11,0,2,NULL), +(56288,11,0,2,NULL), +(56311,11,0,2,NULL), +(56313,11,0,2,NULL); +/*!40000 ALTER TABLE `build_info` ENABLE KEYS */; UNLOCK TABLES; -- @@ -359,13 +792,13 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `ip_banned`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `ip_banned` ( - `ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `bandate` int unsigned NOT NULL, - `unbandate` int unsigned NOT NULL, - `bannedby` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '[Console]', - `banreason` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'no reason', + `ip` varchar(15) NOT NULL DEFAULT '127.0.0.1', + `bandate` int(10) unsigned NOT NULL, + `unbandate` int(10) unsigned NOT NULL, + `bannedby` varchar(50) NOT NULL DEFAULT '[Console]', + `banreason` varchar(255) NOT NULL DEFAULT 'no reason', PRIMARY KEY (`ip`,`bandate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Banned IPs'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -385,13 +818,13 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `logs`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `logs` ( - `time` int unsigned NOT NULL, - `realm` int unsigned NOT NULL, - `type` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL, - `level` tinyint unsigned NOT NULL DEFAULT '0', - `string` text CHARACTER SET latin1 COLLATE latin1_swedish_ci + `time` int(10) unsigned NOT NULL, + `realm` int(10) unsigned NOT NULL, + `type` varchar(250) NOT NULL, + `level` tinyint(3) unsigned NOT NULL DEFAULT 0, + `string` text CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -410,17 +843,17 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `logs_ip_actions`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `logs_ip_actions` ( - `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique Identifier', - `account_id` int unsigned NOT NULL COMMENT 'Account ID', - `character_guid` int unsigned NOT NULL COMMENT 'Character Guid', - `type` tinyint unsigned NOT NULL, - `ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `systemnote` text COLLATE utf8mb4_unicode_ci COMMENT 'Notes inserted by system', - `unixtime` int unsigned NOT NULL COMMENT 'Unixtime', - `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Timestamp', - `comment` text COLLATE utf8mb4_unicode_ci COMMENT 'Allows users to add a comment', + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique Identifier', + `account_id` int(10) unsigned NOT NULL COMMENT 'Account ID', + `character_guid` int(10) unsigned NOT NULL COMMENT 'Character Guid', + `type` tinyint(3) unsigned NOT NULL, + `ip` varchar(15) NOT NULL DEFAULT '127.0.0.1', + `systemnote` text DEFAULT NULL COMMENT 'Notes inserted by system', + `unixtime` int(10) unsigned NOT NULL COMMENT 'Unixtime', + `time` timestamp NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp', + `comment` text DEFAULT NULL COMMENT 'Allows users to add a comment', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Used to log ips of individual actions'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -440,12 +873,12 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `rbac_account_permissions`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `rbac_account_permissions` ( - `accountId` int unsigned NOT NULL COMMENT 'Account id', - `permissionId` int unsigned NOT NULL COMMENT 'Permission id', - `granted` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Granted = 1, Denied = 0', - `realmId` int NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + `granted` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT -1 COMMENT 'Realm Id, -1 means all', PRIMARY KEY (`accountId`,`permissionId`,`realmId`), KEY `fk__rbac_account_roles__rbac_permissions` (`permissionId`), CONSTRAINT `fk__rbac_account_permissions__account` FOREIGN KEY (`accountId`) REFERENCES `account` (`id`) ON DELETE CASCADE, @@ -468,11 +901,11 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `rbac_default_permissions`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `rbac_default_permissions` ( - `secId` int unsigned NOT NULL COMMENT 'Security Level id', - `permissionId` int unsigned NOT NULL COMMENT 'permission id', - `realmId` int NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + `secId` int(10) unsigned NOT NULL COMMENT 'Security Level id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'permission id', + `realmId` int(11) NOT NULL DEFAULT -1 COMMENT 'Realm Id, -1 means all', PRIMARY KEY (`secId`,`permissionId`,`realmId`), KEY `fk__rbac_default_permissions__rbac_permissions` (`permissionId`), CONSTRAINT `fk__rbac_default_permissions__rbac_permissions` FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions` (`id`) @@ -486,10 +919,10 @@ CREATE TABLE `rbac_default_permissions` ( LOCK TABLES `rbac_default_permissions` WRITE; /*!40000 ALTER TABLE `rbac_default_permissions` DISABLE KEYS */; INSERT INTO `rbac_default_permissions` VALUES -(3,192,-1), -(2,193,-1), +(0,195,-1), (1,194,-1), -(0,195,-1); +(2,193,-1), +(3,192,-1); /*!40000 ALTER TABLE `rbac_default_permissions` ENABLE KEYS */; UNLOCK TABLES; @@ -499,10 +932,10 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `rbac_linked_permissions`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `rbac_linked_permissions` ( - `id` int unsigned NOT NULL COMMENT 'Permission id', - `linkedId` int unsigned NOT NULL COMMENT 'Linked Permission id', + `id` int(10) unsigned NOT NULL COMMENT 'Permission id', + `linkedId` int(10) unsigned NOT NULL COMMENT 'Linked Permission id', PRIMARY KEY (`id`,`linkedId`), KEY `fk__rbac_linked_permissions__rbac_permissions1` (`id`), KEY `fk__rbac_linked_permissions__rbac_permissions2` (`linkedId`), @@ -1161,6 +1594,9 @@ INSERT INTO `rbac_linked_permissions` VALUES (199,223), (199,225), (199,263), +(199,378), +(199,379), +(199,380), (199,496), (199,507), (199,525), @@ -1174,10 +1610,10 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `rbac_permissions`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `rbac_permissions` ( - `id` int unsigned NOT NULL DEFAULT '0' COMMENT 'Permission id', - `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Permission name', + `id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'Permission id', + `name` varchar(100) NOT NULL COMMENT 'Permission name', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Permission List'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1418,6 +1854,10 @@ INSERT INTO `rbac_permissions` VALUES (375,'Command: gm list'), (376,'Command: gm visible'), (377,'Command: go'), +(378,'Command: account 2fa'), +(379,'Command: account 2fa setup'), +(380,'Command: account 2fa remove'), +(381,'Command: account set 2fa'), (387,'Command: gobject'), (388,'Command: gobject activate'), (389,'Command: gobject add'), @@ -1860,11 +2300,11 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `realmcharacters`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `realmcharacters` ( - `realmid` int unsigned NOT NULL DEFAULT '0', - `acctid` int unsigned NOT NULL, - `numchars` tinyint unsigned NOT NULL DEFAULT '0', + `realmid` int(10) unsigned NOT NULL DEFAULT 0, + `acctid` int(10) unsigned NOT NULL, + `numchars` tinyint(3) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`realmid`,`acctid`), KEY `acctid` (`acctid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Realm Character Tracker'; @@ -1885,22 +2325,22 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `realmlist`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `realmlist` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `localAddress` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '127.0.0.1', - `localSubnetMask` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '255.255.255.0', - `port` smallint unsigned NOT NULL DEFAULT '8085', - `icon` tinyint unsigned NOT NULL DEFAULT '0', - `flag` tinyint unsigned NOT NULL DEFAULT '2', - `timezone` tinyint unsigned NOT NULL DEFAULT '0', - `allowedSecurityLevel` tinyint unsigned NOT NULL DEFAULT '0', - `population` float unsigned NOT NULL DEFAULT '0', - `gamebuild` int unsigned NOT NULL DEFAULT '15595', - `Region` tinyint unsigned NOT NULL DEFAULT '2', - `Battlegroup` tinyint unsigned NOT NULL DEFAULT '1', + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(32) NOT NULL DEFAULT '', + `address` varchar(255) NOT NULL DEFAULT '127.0.0.1', + `localAddress` varchar(255) NOT NULL DEFAULT '127.0.0.1', + `localSubnetMask` varchar(255) NOT NULL DEFAULT '255.255.255.0', + `port` smallint(5) unsigned NOT NULL DEFAULT 8085, + `icon` tinyint(3) unsigned NOT NULL DEFAULT 0, + `flag` tinyint(3) unsigned NOT NULL DEFAULT 2, + `timezone` tinyint(3) unsigned NOT NULL DEFAULT 0, + `allowedSecurityLevel` tinyint(3) unsigned NOT NULL DEFAULT 0, + `population` float unsigned NOT NULL DEFAULT 0, + `gamebuild` int(10) unsigned NOT NULL DEFAULT 15595, + `Region` tinyint(3) unsigned NOT NULL DEFAULT 2, + `Battlegroup` tinyint(3) unsigned NOT NULL DEFAULT 1, PRIMARY KEY (`id`), UNIQUE KEY `idx_name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Realm System'; @@ -1913,23 +2353,46 @@ CREATE TABLE `realmlist` ( LOCK TABLES `realmlist` WRITE; /*!40000 ALTER TABLE `realmlist` DISABLE KEYS */; INSERT INTO `realmlist` VALUES -(1,'Trinity','127.0.0.1','127.0.0.1','255.255.255.0',8085,0,2,1,0,0,15595,2,1); +(1,'Trinity','127.0.0.1','127.0.0.1','255.255.255.0',8085,0,0,1,0,0,15595,2,1); /*!40000 ALTER TABLE `realmlist` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `secret_digest` +-- + +DROP TABLE IF EXISTS `secret_digest`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `secret_digest` ( + `id` int(10) unsigned NOT NULL, + `digest` varchar(100) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `secret_digest` +-- + +LOCK TABLES `secret_digest` WRITE; +/*!40000 ALTER TABLE `secret_digest` DISABLE KEYS */; +/*!40000 ALTER TABLE `secret_digest` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `updates` -- DROP TABLE IF EXISTS `updates`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `updates` ( - `name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'filename with extension of the update.', - `hash` char(40) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'sha1 hash of the sql file.', - `state` enum('RELEASED','ARCHIVED') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', - `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', - `speed` int unsigned NOT NULL DEFAULT '0' COMMENT 'time the query takes to apply in ms.', + `name` varchar(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` char(40) DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` timestamp NOT NULL DEFAULT current_timestamp() COMMENT 'timestamp when the query was applied.', + `speed` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', PRIMARY KEY (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='List of all applied updates in this database.'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2012,7 +2475,11 @@ INSERT INTO `updates` VALUES ('2021_07_06_00_auth.sql','D3E1354B64589894890430A8AA009178FC79F4CD','ARCHIVED','2021-07-06 05:02:44',0), ('2021_12_31_00_auth.sql','D5B6B3800A57163901ACFCE1C25463768F5B82D0','ARCHIVED','2021-12-31 18:36:14',0), ('2022_01_01_00_auth.sql','336E62A8850A3E78A1D0BD3E81FFD5769184BDF8','ARCHIVED','2022-01-01 11:08:01',0), -('2022_01_09_00_auth.sql','3A662EEEC4361A0CA23B78FA01698A3FC2C69CE8','ARCHIVED','2022-01-09 00:12:22',0); +('2022_01_09_00_auth.sql','3A662EEEC4361A0CA23B78FA01698A3FC2C69CE8','RELEASED','2022-01-09 00:12:22',0), +('2025_07_20_00_auth.sql','A5A79F621B623CCF8AAB6B33CB34B6BE68F5CF5E','RELEASED','2025-07-21 15:24:45',14), +('2025_07_20_01_auth.sql','18A6E6305DC423314DD46AA2F71F9347AA407701','RELEASED','2025-07-21 15:24:45',44), +('2025_07_20_02_auth.sql','72BF9569E47FB21BA6A6A7BA2C344C123751E5DF','RELEASED','2025-07-21 15:24:45',141), +('2025_07_20_03_auth.sql','5CB50B378C7C0B5855A1F7AD0DE4F0D4AEA7EEB2','RELEASED','2025-07-21 15:24:45',162); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; @@ -2022,10 +2489,10 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `updates_include`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `updates_include` ( - `path` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', - `state` enum('RELEASED','ARCHIVED') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + `path` varchar(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` enum('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', PRIMARY KEY (`path`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='List of directories where we want to include sql updates.'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2049,13 +2516,13 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `uptime`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `uptime` ( - `realmid` int unsigned NOT NULL, - `starttime` int unsigned NOT NULL DEFAULT '0', - `uptime` int unsigned NOT NULL DEFAULT '0', - `maxplayers` smallint unsigned NOT NULL DEFAULT '0', - `revision` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'Trinitycore', + `realmid` int(10) unsigned NOT NULL, + `starttime` int(10) unsigned NOT NULL DEFAULT 0, + `uptime` int(10) unsigned NOT NULL DEFAULT 0, + `maxplayers` smallint(5) unsigned NOT NULL DEFAULT 0, + `revision` varchar(255) NOT NULL DEFAULT 'Trinitycore', PRIMARY KEY (`realmid`,`starttime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Uptime system'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2082,4 +2549,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-09 0:15:07 +-- Dump completed on 2025-07-21 17:47:48 diff --git a/sql/updates/auth/4.3.4/2025_07_20_00_auth.sql b/sql/updates/auth/4.3.4/2025_07_20_00_auth.sql new file mode 100644 index 0000000000..b78df904c7 --- /dev/null +++ b/sql/updates/auth/4.3.4/2025_07_20_00_auth.sql @@ -0,0 +1,13 @@ +-- +DELETE FROM `rbac_permissions` WHERE `id` BETWEEN 378 AND 381; +INSERT INTO `rbac_permissions` (`id`,`name`) VALUES +(378, 'Command: account 2fa'), +(379, 'Command: account 2fa setup'), +(380, 'Command: account 2fa remove'), +(381, 'Command: account set 2fa'); + +DELETE FROM `rbac_linked_permissions` WHERE `linkedId` BETWEEN 378 AND 381; +INSERT INTO `rbac_linked_permissions` (`id`,`linkedId`) VALUES +(199, 378), +(199, 379), +(199, 380); diff --git a/sql/updates/auth/4.3.4/2025_07_20_01_auth.sql b/sql/updates/auth/4.3.4/2025_07_20_01_auth.sql new file mode 100644 index 0000000000..6b04bef7fa --- /dev/null +++ b/sql/updates/auth/4.3.4/2025_07_20_01_auth.sql @@ -0,0 +1,12 @@ +-- + +START TRANSACTION; -- we're messing with the accounts table here, let's play it safe + +DROP TABLE IF EXISTS `secret_digest`; +CREATE TABLE `secret_digest` ( + `id` int(10) unsigned not null, + `digest` varchar(100) not null, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + +COMMIT; -- safety gloves off diff --git a/sql/updates/auth/4.3.4/2025_07_20_02_auth.sql b/sql/updates/auth/4.3.4/2025_07_20_02_auth.sql new file mode 100644 index 0000000000..477b5928dd --- /dev/null +++ b/sql/updates/auth/4.3.4/2025_07_20_02_auth.sql @@ -0,0 +1,617 @@ +-- +-- Table structure for table `build_auth_key` +-- + +DROP TABLE IF EXISTS `build_auth_key`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `build_auth_key` ( + `build` int NOT NULL, + `platform` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `arch` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `type` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `key` binary(16) NOT NULL, + PRIMARY KEY (`build`,`platform`,`arch`,`type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `build_auth_key` +-- + +LOCK TABLES `build_auth_key` WRITE; +/*!40000 ALTER TABLE `build_auth_key` DISABLE KEYS */; +INSERT INTO `build_auth_key` VALUES +(25549,'Mac','x64','WoW',0x66FC5E09B8706126795F140308C8C1D8), +(25549,'Win','x64','WoW',0x1252624ED8CBD6FAC7D33F5D67A535F3), +(25549,'Win','x86','WoW',0xFE594FC35E7F9AFF86D99D8A364AB297), +(25996,'Mac','x64','WoW',0x210B970149D6F56CAC9BADF2AAC91E8E), +(25996,'Win','x64','WoW',0xC7FF932D6A2174A3D538CA7212136D2B), +(25996,'Win','x86','WoW',0x23C59C5963CBEF5B728D13A50878DFCB), +(26124,'Mac','x64','WoW',0xC9CA997AB8EDE1C65465CB2920869C4E), +(26124,'Win','x64','WoW',0x46DF06D0147BA67BA49AF553435E093F), +(26124,'Win','x86','WoW',0xF8C05AE372DECA1D6C81DA7A8D1C5C39), +(26365,'Mac','x64','WoW',0xDBE7F860276D6B400AAA86B35D51A417), +(26365,'Win','x64','WoW',0x59A53F307288454B419B13E694DF503C), +(26365,'Win','x86','WoW',0x2AAC82C80E829E2CA902D70CFA1A833A), +(26654,'Mac','x64','WoW',0x9234C1BD5E9687ADBD19F764F2E0E811), +(26654,'Win','x64','WoW',0xA752640E8B99FE5B57C1320BC492895A), +(26654,'Win','x86','WoW',0xFAC2D693E702B9EC9F750F17245696D8), +(26822,'Mac','x64','WoW',0x91003668C245D14ECD8DF094E065E06B), +(26822,'Win','x64','WoW',0x2B05F6D746C0C6CC7EF79450B309E595), +(26822,'Win','x86','WoW',0x283E8D77ECF7060BE6347BE4EB99C7C7), +(26899,'Mac','x64','WoW',0x8368EFC2021329110A16339D298200D4), +(26899,'Win','x64','WoW',0x3551EF0028B51E92170559BD25644B03), +(26899,'Win','x86','WoW',0xF462CD2FE4EA3EADF875308FDBB18C99), +(26972,'Mac','x64','WoW',0x341CFEFE3D72ACA9A4407DC535DED66A), +(26972,'Win','x64','WoW',0x6E212DEF6A0124A3D9AD07F5E322F7AE), +(26972,'Win','x86','WoW',0x797ECC19662DCBD5090A4481173F1D26), +(28153,'Win','x64','WoW',0xDD626517CC6D31932B479934CCDC0ABF), +(30706,'Win','x64','WoW',0xBB6D9866FE4A19A568015198783003FC), +(30993,'Win','x64','WoW',0x2BAD61655ABC2FC3D04893B536403A91), +(31229,'Win','x64','WoW',0x8A46F23670309F2AAE85C9A47276382B), +(31429,'Win','x64','WoW',0x7795A507AF9DC3525EFF724FEE17E70C), +(31478,'Win','x64','WoW',0x7973A8D54BDB8B798D9297B096E771EF), +(32305,'Win','x64','WoW',0x21F5A6FC7AD89FBF411FDA8B8738186A), +(32494,'Win','x64','WoW',0x58984ACE04919401835C61309A848F8A), +(32580,'Win','x64','WoW',0x87C2FAA0D7931BF016299025C0DDCA14), +(32638,'Win','x64','WoW',0x5D07ECE7D4A867DDDE615DAD22B76D4E), +(32722,'Win','x64','WoW',0x1A09BE1D38A122586B4931BECCEAD4AA), +(32750,'Mac','x64','WoW',0xEF1F4E4D099EA2A81FD4C0DEBC1E7086), +(32750,'Win','x64','WoW',0xC5CB669F5A5B237D1355430877173207), +(32978,'Mac','x64','WoW',0x1852C1F847E795D6EB45278CD433F339), +(32978,'Win','x64','WoW',0x76AE2EA03E525D97F5688843F5489000), +(33369,'Mac','x64','WoW',0xF5A849C70A1054F07EA3AB833EBF6671), +(33369,'Win','x64','WoW',0x5986AC18B04D3C403F56A0CF8C4F0A14), +(33528,'Win','x64','WoW',0x0ECE033CA9B11D92F7D2792C785B47DF), +(33724,'Win','x64','WoW',0x38F7BBCF284939DD20E8C64CDBF9FE77), +(33775,'Mac','x64','WoW',0x354D2DE619D124EE1398F76B0436FCFC), +(33775,'Win','x64','WoW',0xB826300A8449ED0F6EF16EA747FA2D2E), +(33941,'Win','x64','WoW',0x88AF1A36D2770D0A6CA086497096A889), +(34220,'Win','x64','WoW',0xB5E35B976C6BAF82505700E7D9666A2C), +(34601,'Win','x64','WoW',0x0D7DF38F725FABA4F009257799A10563), +(34769,'Win','x64','WoW',0x93F9B9AF6397E3E4EED94D36D16907D2), +(34963,'Mac','x64','WoW',0xC5658A17E702163447BAAAE46D130A1B), +(34963,'Win','x64','WoW',0x7BA50C879C5D04221423B02AC3603A11), +(35249,'Win','x64','WoW',0xC7B11F9AE9FF1409F5582902B3D10D1C), +(35284,'Mac','x64','WoW',0xA6201B0AC5A73D13AB2FDCC79BB252AF), +(35284,'Win','x64','WoW',0xEA3818E7DCFD2009DBFC83EE3C1E4F1B), +(35435,'Mac','x64','WoW',0x8FE657C14A46BCDB2CE6DA37E430450E), +(35435,'Win','x64','WoW',0xBB397A92FE23740EA52FC2B5BA2EC8E0), +(35662,'Mac','x64','WoW',0x5966016C368ED9F7AAB603EE6703081C), +(35662,'Win','x64','WoW',0x578BC94870C278CB6962F30E6DC203BB), +(36753,'Win','x64','WoW',0x386FDE8559B5EAD67B791B490B200B88), +(36839,'Win','x64','WoW',0x356EB4412B8EFCF72E3AF50D5181D529), +(36949,'Win','x64','WoW',0x51C074CD8A09A75384B9B44188C56981), +(37142,'Win','x64','WoW',0x5D9CFB3139F0D1B6C2B304261F9EABC9), +(37176,'Win','x64','WoW',0x3C725EA504EC3DAED143EB6FF3B48CDA), +(37474,'Mac','x64','WoW',0x024C9BE7E44237B7E81C6D42E678D433), +(37474,'Win','x64','WoW',0x0DE685BBB0551086E7FBDC0B4BB06A5B), +(38134,'Win','x64','WoW',0x32275ED0F13B357C28BDB0E611EF9E31), +(38556,'Win','x64','WoW',0xEC7D5AF64364AC3E7181F3FBA1B3A882), +(39653,'Win','x64','WoW',0x10D015AB1EEB91310428D9C57EE24632), +(39804,'Win','x64','WoW',0xE42D2BBA12ED260A76F9B1E477E19EA5), +(40000,'Win','x64','WoW',0x4CB1433AB637F09F03FBBD1B221B04B0), +(40120,'Mac','x64','WoW',0x853F0F2985CEAED46DF422583CD07A7C), +(40120,'Win','x64','WoW',0x04F47EAEFD8BDEFE14AA0350EA336678), +(40443,'Win','x64','WoW',0x8597BB43E8AB38C85504E8BFB72ABBF5), +(40593,'Win','x64','WoW',0xBA14570F2D62D5F61953394164A8DAE2), +(40725,'Win','x64','WoW',0xC1EBDBEB9BB2956EBCCEF7C9D27A1B3B), +(40906,'Win','x64','WoW',0xF5FC259C8635488AFE0D0CD023F361D4), +(40944,'Win','x64','WoW',0x368FC7FABAF487A8A049C11970657074), +(40966,'Win','x64','WoW',0xD90F47AF21F381D2D8F3763B994BAC88), +(41031,'Win','x64','WoW',0x019A0FACD6B0D6374B7BA69A5B677449), +(41079,'Win','x64','WoW',0xF8853CF823BC0BBE8A9677A762DFAEE1), +(41288,'Win','x64','WoW',0x871C0C9691DBC536EB24B68EC73FAD5B), +(41323,'Win','x64','WoW',0xE53D0DF1FAC1A59A1C8071B295A04A1D), +(41359,'Win','x64','WoW',0x5F8D7F2A690A4375A1B52A28D6D681FA), +(41488,'Win','x64','WoW',0x1BC91EC368705815F3F532B553DAD981), +(41793,'Win','x64','WoW',0xB3B47DA3B7615570742A55B96614EE1C), +(42010,'Win','x64','WoW',0x302970161D16417B5BE553CC530E011A), +(42423,'Win','x64','WoW',0x0B03614A7E94DD57548596BE420E9DC2), +(42488,'Win','x64','WoW',0xA78755E6928D83A271C5D1EE3CDB6F15), +(42521,'Win','x64','WoW',0x5FE6C12FC407C6B15B4A5D3B5B4A5D3B), +(42538,'Win','x64','WoW',0x71A7504BD53F8DE518F24265D37310AE), +(42560,'Win','x64','WoW',0x115FE8C38A8D67CA4664BB192E0F0DFE), +(42614,'Win','x64','WoW',0x772BE726FEEF42124255D2EA7973CA18), +(42698,'Win','x64','WoW',0xB4497B1CD11FC974C5FB09548AC27269), +(42825,'Win','x64','WoW',0xA14DA228C6A6AFF1DDBA51218939E557), +(42852,'Win','x64','WoW',0xDE9F9F0C3CC8FD54D3AFF99CEFFCE129), +(42937,'Win','x64','WoW',0xF5FC75E70874752C92846B3333920E63), +(42979,'Win','x64','WoW',0xE1DD38AE6450FC4D2AE4609233C59E54), +(43114,'Win','x64','WoW',0xF75C9380CCB24A48A24EEE52C1594A7E), +(43206,'Win','x64','WoW',0xDDE806532C7704FFB75F256DC5F1F3D9), +(43340,'Win','x64','WoW',0x70E46D2D888E84DF9316EA849B068CF4), +(43345,'Win','x64','WoW',0xD911ABFCDA030DEE8CAF4EE3F60DEE13), +(43971,'Win','x64','WoW',0x681CF99E61FB0005A5C7D31D0AAD1ED9), +(44015,'Win','x64','WoW',0xFCF0BDA7C98BFEF92AE6D8C39A217ABD), +(44061,'Win','x64','WoW',0xFD2B5C0B3293FE0E9CAA6EB0B7788119), +(44127,'Win','x64','WoW',0x787887CEC9FCC9B516481F60E4FC34A8), +(44232,'Win','x64','WoW',0x81F0A71DF7E9873BB3750022D64D33CF), +(44325,'Win','x64','WoW',0x138A7D524D268A7F9934C3D148E8F01B), +(44730,'Win','x64','WoW',0xFC0B18C47BB4C79F4300CA0FF3E5CAC7), +(44908,'Win','x64','WoW',0xBFFAEC40C9BCD591C7C959A9D5A8BA8C), +(45114,'Win','x64','WoW',0xD7AFE240BD00F06C30D0C2D16E54A8BE), +(45161,'Win','x64','WoW',0x74BD2E787A98B145B063BDA9A98F6CBD), +(45338,'Win','x64','WoW',0x5CE2094A41B61EDA9DF56378BC3B1DE0), +(45745,'Win','x64','WoW',0x0F6DC90161694D765A595A3AF603166B), +(46479,'Win','x64','WoW',0xCB9AF4D89B60A3ABA288D395D315D932), +(46658,'Win','x64','WoW',0x3F8EFB085428D75360E9EFE25CD8639A), +(46689,'Win','x64','WoW',0xD9A11D188D6AD60906F5467510EFD3AA), +(46702,'Win','x64','WoW',0x01B4D1688FF97DC9AAFCCD0A0B842C0B), +(46741,'Win','x64','WoW',0x4C0F4A7EC2098AF1FBA745848EC79A78), +(46801,'Win','x64','WoW',0xE6AC18D1EA5D36ABFFAE5EDED80630DF), +(46879,'Win','x64','WoW',0xEFEC43936051DD1A210633AF1F6B63DB), +(46924,'Win','x64','WoW',0xE6CE0B1A8119F069ECF1E7DBAA7BB2F8), +(47067,'Win','x64','WoW',0x63862CFCDEA6BD2BD7F740EB36B65657), +(47187,'Win','x64','WoW',0x711F8455C5000C237292E1E6E90631E1), +(47213,'Win','x64','WoW',0x23C50D88CEAC0A8696ADDE8DD244D4A2), +(47631,'Win','x64','WoW',0xF986AB91D0AEB20822EFB72F4256713C), +(47777,'Win','x64','WoW',0xA88C04915AB9E035A104E55C4DCF5F9F), +(47799,'Win','x64','WoW',0x7364EB093C23DB2CDC9513D5A7B4933E), +(47825,'Win','x64','WoW',0x82A3B94E5E727AF3A208B471FF2054C0), +(47849,'Win','x64','WoW',0xDD8BBE2087A28C0AF4984CBE23A1C707), +(47871,'Win','x64','WoW',0x8E4F7D30EE4982B02B3B3F8837C2C4F2), +(47884,'Win','x64','WoW',0x2B7A002BC359F2C31104BC2DE04302BF), +(47936,'Win','x64','WoW',0x833D30D8FBC43B3FAE99CD3898D70849), +(47967,'Win','x64','WoW',0xCFE225D0089E224D9E7541D3B5C26478), +(48001,'Win','x64','WoW',0x4B0260A37BD95B615E71048469E6D5BB), +(48069,'Win','x64','WoW',0x558CDF958FA082E95849779C7C6945E5), +(48317,'Win','x64','WoW',0xC096E37B45B43244E9C79916604DD4AF), +(48397,'Win','x64','WoW',0x64BA8779EAA97E6C57982B6B1A5B32E7), +(48526,'Win','x64','WoW',0xD5B7D3303A2A741E6913EE1AEB0BCB65), +(48676,'Win','x64','WoW',0xE059FB74DFF6438CC20C7F28900F64CA), +(48749,'Win','x64','WoW',0x92DBCCA0E33DFB8A17A2B6A39246B288), +(48838,'Win','x64','WoW',0x9E6F4E1E46EF228D2DE90F7BC48AAA96), +(48865,'Win','x64','WoW',0x4B774ABE7B34D6702571B4279A4B6A13), +(48892,'Win','x64','WoW',0xAA31BF27458321B03A1A346964DD7B9D), +(48966,'Win','x64','WoW',0x823142CA131FBB715FF55D4343E55C6D), +(48999,'Win','x64','WoW',0x79BA6FF0F9672EEF875F64155C8B62D4), +(49267,'Win','x64','WoW',0xEEE77EA5A216E0731ADBB41AEFB1DF31), +(49318,'Win','x64','WoW',0xAF439AEE62EE48B36C1725111E3D9BBF), +(49343,'Win','x64','WoW',0x301A0B4C0942B9B6F605B903AD6C1F60), +(49407,'Win','x64','WoW',0x6413820DC9885BB0693B37090CBB2F30), +(49426,'Win','x64','WoW',0xD85EDFBFE9A94A55E2B4510BE41C19B2), +(49444,'Win','x64','WoW',0x363B2B05285BDD8857419D2866316D3C), +(49474,'Win','x64','WoW',0x44A7D2B352EE3D098A3CB4C2F1065E37), +(49570,'Win','x64','WoW',0xB024DE67ACAEB9E8EE6DB38DC53E8281), +(49679,'Win','x64','WoW',0x9CE59B68D8797EBF00581F41138F4316), +(49741,'Win','x64','WoW',0x0EF181E2BB0E946CF3B7422ADEB6CD1A), +(49801,'Win','x64','WoW',0x0832179567B66CA85DBD5678B604C683), +(49890,'Win','x64','WoW',0x22A5B8A1EB797A64995F705B3DBCB14C), +(50000,'Win','x64','WoW',0x02F06FFA2296FD66384295DBFD5A4C91), +(50401,'Win','x64','WoW',0x3EEF52D902CCE81D16D0E255F0AA4938), +(50438,'Win','x64','WoW',0x0B5F68F06B129CB4C57702F6D30F260B), +(50467,'Win','x64','WoW',0x5E996B1CDCEE68432D6340138E68D1EB), +(50469,'Win','x64','WoW',0x1768CCB6589E16AB3BEFA9D608A393A2), +(50504,'Win','x64','WoW',0x7D5FD20C0B32C9AF5DD65433B391D49C), +(50585,'Win','x64','WoW',0xC4F7CC38A3B84935A485F7EDAD3E764B), +(50622,'Win','x64','WoW',0xD23A26FD75FD9A6073EB7060AA28E6A7), +(50747,'Win','x64','WoW',0x2D3C386A9C45C27304ED3A3C6EB3F7C8), +(50791,'Win','x64','WoW',0x0BE7D0BB07EF37C25CBC682409091EA0), +(51130,'Win','x64','WoW',0x44CD2C91E4F0655DA387483726CE4035), +(51187,'Win','x64','WoW',0x74E2055D3965269447B5CB1B31FC71C6), +(51237,'Win','x64','WoW',0xC8660A21B766646FBD67F481CFCF55C3), +(51261,'Win','x64','WoW',0x1BEBB57AE450331E9F8C301AA7876FAB), +(51313,'Win','x64','WoW',0x35419ED0AB16735CF720858F45DC300C), +(51421,'Win','x64','WoW',0x45E24D6F3335269787DF2B2063939002), +(51485,'Win','x64','WoW',0xEC549E1D0A5DD85C03E7A9D93B7DC6D1), +(51536,'Win','x64','WoW',0x570EEA10A8EC169C3FF9621D1B635BB4), +(51754,'Win','x64','WoW',0xBED5A861C071AB41FEF6087E0C37BB1A), +(51886,'Win','x64','WoW',0x09CF8919FD2EABDEAEBC0C810F53B511), +(51972,'Win','x64','WoW',0x444DC7EF3544B6670C18884DADA00428), +(52038,'Win','x64','WoW',0xA8EF004ADED8A3AFF5A67D2BB8D95795), +(52068,'Win','x64','WoW',0xA44F842BACCC7EE8E2975FAF01F12474), +(52095,'Win','x64','WoW',0xBA36382887D16D274EA9149695F0C9C8), +(52106,'Win','x64','WoW',0x95F43869B7D881212CBC1690B8F393ED), +(52129,'Win','x64','WoW',0x02DD842F2A7162EEB8FD5B9D325606F8), +(52148,'Win','x64','WoW',0x8A969717C8CDC6E7FF4C54D5CB00C224), +(52188,'Win','x64','WoW',0x977DF9993E94855DED5E328BA7A2F21F), +(52301,'Win','x64','WoW',0x821AA3BB237B400B82F44970250539AA), +(52393,'Win','x64','WoW',0xB013ED23B7EF51B29A45594D9BBB0D03), +(52485,'Win','x64','WoW',0x5805CEB4650730AE489258DD30E34441), +(52545,'Win','x64','WoW',0xFB52179A8355A46EDBFBDC8E8E5CDAFD), +(52607,'Win','x64','WoW',0x8F002E4AADCAEABB08ABC2880B31AD60), +(52649,'Win','x64','WoW',0xD0B779FBECEBC1ED5A85D83F03C8A75B), +(52808,'Win','x64','WoW',0x6276712B6C8AEA21CD5D94D52FEE70EE), +(52902,'Win','x64','WoW',0xD4F0A24CDF165628538C1C387A326AF3), +(52968,'Win','x64','WoW',0x2D247FD440C44D4F1BF80B075B8720F2), +(52983,'Win','x64','WoW',0xB1E5ADA5FDD06C9AB5E5D8A6983324AC), +(53007,'Win','x64','WoW',0xA21AFB4D381C56AF471D994258C0EEF5), +(53040,'Win','x64','WoW',0x2F1283BF7B7F307B70DBBD75CC42D7C3), +(53104,'Win','x64','WoW',0xDBD79EC8DF044B53C78931B985CAB406), +(53162,'Win','x64','WoW',0x8A67511FBF8984EEE2B630F7CB23376A), +(53212,'Win','x64','WoW',0x08761EFF2F9B639364B9A9FBFFFFB949), +(53262,'Win','x64','WoW',0x614A72D53126348A4927EC0F53FD2B7A), +(53441,'Win','x64','WoW',0xBFDD7D0FE87D5F75E6DEB4F5C99D7C99), +(53584,'Win','x64','WoW',0xCDD7A93659A03460B5A6CE1C4ACE5554), +(53840,'Win','x64','WoW',0xAC97D745C60DD3DC5F973E55C0E3649E), +(53877,'Win','x64','WoW',0x16320F95B63846A2276E1D2612C34AD4), +(53913,'Win','x64','WoW',0x475680680B2192EBCF6744D14F755199), +(53989,'Win','x64','WoW',0x3AEB90ACB9E18B88BA1021F52D51B857), +(54070,'Win','x64','WoW',0xFDA08264B7587250CF78F9B960218169), +(54205,'Win','x64','WoW',0x589D59EB3F0D6D77C2175D9302F78FDD), +(54358,'Win','x64','WoW',0x89C733D366E845FB9264404CD48CCA89), +(54499,'Win','x64','WoW',0x6AC1F6180FC4C390F782DB933BD83326), +(54577,'Win','x64','WoW',0xCBBBBBFFB2C652F0F4A7848D86E1B063), +(54601,'Win','x64','WoW',0xF8B866CF7DB9A12273F35B3929627375), +(54604,'Win','x64','WoW',0xA5FF4CE535F69D4D7F638CB2C11F2243), +(54630,'Win','x64','WoW',0xF37935510BA6B559363C160E1DF18230), +(54673,'Win','x64','WoW',0xAF8B9C8A9C6128498E85228B965A004D), +(54717,'Win','x64','WoW',0x862BBA15158DFF6B56BCF71C1B34D41A), +(54736,'Win','x64','WoW',0xFE58F039D91E1C248886A2828127CA2F), +(54762,'Win','x64','WoW',0x5F7FDA560030255445B713456A286CFA), +(54847,'Win','x64','WoW',0x32FDA0353160EC51EB36195CFACEF2B7), +(54904,'Win','x64','WoW',0x09CBEC3C0DEA28BCA79F1FD9B879B0E3), +(54988,'Win','x64','WoW',0x8F2791553226871977B4F9D7F1137311), +(55142,'Win','x64','WoW',0x298B99B5AD67EA3D2AB4B3E07A415305), +(55165,'Win','x64','WoW',0x26D4D1C01434A8A6723DCABC944B6FD0), +(55261,'Win','x64','WoW',0x84E153A3DD1F8249274B91047AAC7AED), +(55461,'Win','x64','WoW',0xC4522674F854EFECC76C898EC9545099), +(55664,'Win','x64','WoW',0xDBCA58486FAAA0FE54EA287A3047E923), +(55666,'Win','x64','WoW',0xF7E5A88E4D3615B652C8B9D76E7F617C), +(55792,'Win','x64','WoW',0xC4DECDAA44BC548FF09EF3BB837D2147), +(55793,'Win','x64','WoW',0xF9CF3232AD1C38C2028668D5BB64198F), +(55818,'Win','x64','WoW',0x903A9B546248F71B16D9D9B06A072C24), +(55824,'Win','x64','WoW',0x8A6F13269A2896067A1E88789FB41BA7), +(55846,'Win','x64','WoW',0xBB5E1BED705872C226834B95A9E9F8A9), +(55933,'Win','x64','WoW',0xC34D42CB351C400D1319D221197CF18D), +(55939,'Win','x64','WoW',0x91529F4CE41DE4E54E132660ACDCADC5), +(55959,'Win','x64','WoW',0xED57E0538FD1CE99B171BE34823148A9), +(55960,'Win','x64','WoW',0x078C056CFC7B371BDE1BAF308E6C19AF), +(56008,'Win','x64','WoW',0x00FCD6BFFCCCBA7A8E71E307EA6EBD0C), +(56110,'Win','x64','WoW',0x800BCA228E2FAE37ED160F3C09E21F3A), +(56162,'Win','x64','WoW',0x6F5C93BA436665A94DB67CE5361D4EA8), +(56196,'Mac','A64','WoW',0x778F6A5DF79A4EF1B86F651F3B303CE7), +(56196,'Win','x64','WoW',0x81FC14274BFF0347FFF9C8B1AA6BED9B), +(56263,'Win','x64','WoW',0xEA8472C99236CC617BF518A924014D56), +(56288,'Mac','A64','WoW',0x41710C793EF021721F14B06EC1896D3F), +(56288,'Win','x64','WoW',0x03544E35D0480938E5C1238B3A26BDDD), +(56311,'Mac','A64','WoW',0x412D3200715AAFDC0522DF031A941F0E), +(56311,'Win','x64','WoW',0xAC6415575AEE4D32735FFAD0C57226B2), +(56313,'Mac','A64','WoW',0xA83ED19EE659BC95CC322D1E49BDEDBB), +(56313,'Win','x64','WoW',0xEAF769009A9AD3B1AA0414E1C344074B); +/*!40000 ALTER TABLE `build_auth_key` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `build_executable_hash` +-- + +DROP TABLE IF EXISTS `build_executable_hash`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `build_executable_hash` ( + `build` int NOT NULL, + `platform` char(4) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `executableHash` binary(20) NOT NULL, + PRIMARY KEY (`build`,`platform`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `build_executable_hash` +-- + +LOCK TABLES `build_executable_hash` WRITE; +/*!40000 ALTER TABLE `build_executable_hash` DISABLE KEYS */; +INSERT INTO `build_executable_hash` VALUES +(5875,'OSX',0x8D173CC381961EEBABF336F5E6675B101BB513E5), +(5875,'Win',0x95EDB27C7823B363CBDDAB56A392E7CB73FCCA20), +(8606,'OSX',0xD8B0ECFE534BC1131E19BAD1D4C0E813EEE4994F), +(8606,'Win',0x319AFAA3F2559682F9FF658BE01456255F456FB1), +(12340,'OSX',0xB706D13FF2F4018839729461E3F8A0E2B5FDC034), +(12340,'Win',0xCDCBBD5188315E6B4D19449D492DBCFAF156A347); +/*!40000 ALTER TABLE `build_executable_hash` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `build_info` +-- + +DROP TABLE IF EXISTS `build_info`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `build_info` ( + `build` int NOT NULL, + `majorVersion` int DEFAULT NULL, + `minorVersion` int DEFAULT NULL, + `bugfixVersion` int DEFAULT NULL, + `hotfixVersion` char(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, + PRIMARY KEY (`build`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `build_info` +-- + +LOCK TABLES `build_info` WRITE; +/*!40000 ALTER TABLE `build_info` DISABLE KEYS */; +INSERT INTO `build_info` VALUES +(5875,1,12,1,NULL), +(6005,1,12,2,NULL), +(6141,1,12,3,NULL), +(8606,2,4,3,NULL), +(9947,3,1,3,NULL), +(10505,3,2,2,'a'), +(11159,3,3,0,'a'), +(11403,3,3,2,NULL), +(11723,3,3,3,'a'), +(12340,3,3,5,'a'), +(13623,4,0,6,'a'), +(13930,3,3,5,'a'), +(14545,4,2,2,NULL), +(15595,4,3,4,NULL), +(19116,6,0,3,NULL), +(19243,6,0,3,NULL), +(19342,6,0,3,NULL), +(19702,6,1,0,NULL), +(19802,6,1,2,NULL), +(19831,6,1,2,NULL), +(19865,6,1,2,NULL), +(20182,6,2,0,'a'), +(20201,6,2,0,NULL), +(20216,6,2,0,NULL), +(20253,6,2,0,NULL), +(20338,6,2,0,NULL), +(20444,6,2,2,NULL), +(20490,6,2,2,'a'), +(20574,6,2,2,'a'), +(20726,6,2,3,NULL), +(20779,6,2,3,NULL), +(20886,6,2,3,NULL), +(21355,6,2,4,NULL), +(21463,6,2,4,NULL), +(21742,6,2,4,NULL), +(22248,7,0,3,NULL), +(22293,7,0,3,NULL), +(22345,7,0,3,NULL), +(22410,7,0,3,NULL), +(22423,7,0,3,NULL), +(22498,7,0,3,NULL), +(22522,7,0,3,NULL), +(22566,7,0,3,NULL), +(22594,7,0,3,NULL), +(22624,7,0,3,NULL), +(22747,7,0,3,NULL), +(22810,7,0,3,NULL), +(22900,7,1,0,NULL), +(22908,7,1,0,NULL), +(22950,7,1,0,NULL), +(22995,7,1,0,NULL), +(22996,7,1,0,NULL), +(23171,7,1,0,NULL), +(23222,7,1,0,NULL), +(23360,7,1,5,NULL), +(23420,7,1,5,NULL), +(23911,7,2,0,NULL), +(23937,7,2,0,NULL), +(24015,7,2,0,NULL), +(24330,7,2,5,NULL), +(24367,7,2,5,NULL), +(24415,7,2,5,NULL), +(24430,7,2,5,NULL), +(24461,7,2,5,NULL), +(24742,7,2,5,NULL), +(25549,7,3,2,NULL), +(25996,7,3,5,NULL), +(26124,7,3,5,NULL), +(26365,7,3,5,NULL), +(26654,7,3,5,NULL), +(26822,7,3,5,NULL), +(26899,7,3,5,NULL), +(26972,7,3,5,NULL), +(28153,8,0,1,NULL), +(30706,8,1,5,NULL), +(30993,8,2,0,NULL), +(31229,8,2,0,NULL), +(31429,8,2,0,NULL), +(31478,8,2,0,NULL), +(32305,8,2,5,NULL), +(32494,8,2,5,NULL), +(32580,8,2,5,NULL), +(32638,8,2,5,NULL), +(32722,8,2,5,NULL), +(32750,8,2,5,NULL), +(32978,8,2,5,NULL), +(33369,8,3,0,NULL), +(33528,8,3,0,NULL), +(33724,8,3,0,NULL), +(33775,8,3,0,NULL), +(33941,8,3,0,NULL), +(34220,8,3,0,NULL), +(34601,8,3,0,NULL), +(34769,8,3,0,NULL), +(34963,8,3,0,NULL), +(35249,8,3,7,NULL), +(35284,8,3,7,NULL), +(35435,8,3,7,NULL), +(35662,8,3,7,NULL), +(36753,9,0,2,NULL), +(36839,9,0,2,NULL), +(36949,9,0,2,NULL), +(37142,9,0,2,NULL), +(37176,9,0,2,NULL), +(37474,9,0,2,NULL), +(38134,9,0,5,NULL), +(38556,9,0,5,NULL), +(39653,9,1,0,NULL), +(39804,9,1,0,NULL), +(40000,9,1,0,NULL), +(40120,9,1,0,NULL), +(40443,9,1,0,NULL), +(40593,9,1,0,NULL), +(40725,9,1,0,NULL), +(40906,9,1,5,NULL), +(40944,9,1,5,NULL), +(40966,9,1,5,NULL), +(41031,9,1,5,NULL), +(41079,9,1,5,NULL), +(41288,9,1,5,NULL), +(41323,9,1,5,NULL), +(41359,9,1,5,NULL), +(41488,9,1,5,NULL), +(41793,9,1,5,NULL), +(42010,9,1,5,NULL), +(42423,9,2,0,NULL), +(42488,9,2,0,NULL), +(42521,9,2,0,NULL), +(42538,9,2,0,NULL), +(42560,9,2,0,NULL), +(42614,9,2,0,NULL), +(42698,9,2,0,NULL), +(42825,9,2,0,NULL), +(42852,9,2,0,NULL), +(42937,9,2,0,NULL), +(42979,9,2,0,NULL), +(43114,9,2,0,NULL), +(43206,9,2,0,NULL), +(43340,9,2,0,NULL), +(43345,9,2,0,NULL), +(43971,9,2,5,NULL), +(44015,9,2,5,NULL), +(44061,9,2,5,NULL), +(44127,9,2,5,NULL), +(44232,9,2,5,NULL), +(44325,9,2,5,NULL), +(44730,9,2,5,NULL), +(44908,9,2,5,NULL), +(45114,9,2,7,NULL), +(45161,9,2,7,NULL), +(45338,9,2,7,NULL), +(45745,9,2,7,NULL), +(46479,10,0,2,NULL), +(46658,10,0,2,NULL), +(46689,10,0,2,NULL), +(46702,10,0,2,NULL), +(46741,10,0,2,NULL), +(46801,10,0,2,NULL), +(46879,10,0,2,NULL), +(46924,10,0,2,NULL), +(47067,10,0,2,NULL), +(47187,10,0,2,NULL), +(47213,10,0,2,NULL), +(47631,10,0,2,NULL), +(47777,10,0,5,NULL), +(47799,10,0,5,NULL), +(47825,10,0,5,NULL), +(47849,10,0,5,NULL), +(47871,10,0,5,NULL), +(47884,10,0,5,NULL), +(47936,10,0,5,NULL), +(47967,10,0,5,NULL), +(48001,10,0,5,NULL), +(48069,10,0,5,NULL), +(48317,10,0,5,NULL), +(48397,10,0,5,NULL), +(48526,10,0,5,NULL), +(48676,10,0,7,NULL), +(48749,10,0,7,NULL), +(48838,10,0,7,NULL), +(48865,10,0,7,NULL), +(48892,10,0,7,NULL), +(48966,10,0,7,NULL), +(48999,10,0,7,NULL), +(49267,10,0,7,NULL), +(49318,10,1,0,NULL), +(49343,10,0,7,NULL), +(49407,10,1,0,NULL), +(49426,10,1,0,NULL), +(49444,10,1,0,NULL), +(49474,10,1,0,NULL), +(49570,10,1,0,NULL), +(49679,10,1,0,NULL), +(49741,10,1,0,NULL), +(49801,10,1,0,NULL), +(49890,10,1,0,NULL), +(50000,10,1,0,NULL), +(50401,10,1,5,NULL), +(50438,10,1,5,NULL), +(50467,10,1,5,NULL), +(50469,10,1,5,NULL), +(50504,10,1,5,NULL), +(50585,10,1,5,NULL), +(50622,10,1,5,NULL), +(50747,10,1,5,NULL), +(50791,10,1,5,NULL), +(51130,10,1,5,NULL), +(51187,10,1,7,NULL), +(51237,10,1,7,NULL), +(51261,10,1,7,NULL), +(51313,10,1,7,NULL), +(51421,10,1,7,NULL), +(51485,10,1,7,NULL), +(51536,10,1,7,NULL), +(51754,10,1,7,NULL), +(51886,10,1,7,NULL), +(51972,10,1,7,NULL), +(52038,10,2,0,NULL), +(52068,10,2,0,NULL), +(52095,10,2,0,NULL), +(52106,10,2,0,NULL), +(52129,10,2,0,NULL), +(52148,10,2,0,NULL), +(52188,10,2,0,NULL), +(52301,10,2,0,NULL), +(52393,10,2,0,NULL), +(52485,10,2,0,NULL), +(52545,10,2,0,NULL), +(52607,10,2,0,NULL), +(52649,10,2,0,NULL), +(52808,10,2,0,NULL), +(52902,10,2,5,NULL), +(52968,10,2,5,NULL), +(52983,10,2,5,NULL), +(53007,10,2,5,NULL), +(53040,10,2,5,NULL), +(53104,10,2,5,NULL), +(53162,10,2,5,NULL), +(53212,10,2,5,NULL), +(53262,10,2,5,NULL), +(53441,10,2,5,NULL), +(53584,10,2,5,NULL), +(53840,10,2,6,NULL), +(53877,10,2,6,NULL), +(53913,10,2,6,NULL), +(53989,10,2,6,NULL), +(54070,10,2,6,NULL), +(54205,10,2,6,NULL), +(54358,10,2,6,NULL), +(54499,10,2,6,NULL), +(54577,10,2,7,NULL), +(54601,10,2,7,NULL), +(54604,10,2,7,NULL), +(54630,10,2,7,NULL), +(54673,10,2,7,NULL), +(54717,10,2,7,NULL), +(54736,10,2,7,NULL), +(54762,10,2,7,NULL), +(54847,10,2,7,NULL), +(54904,10,2,7,NULL), +(54988,10,2,7,NULL), +(55142,10,2,7,NULL), +(55165,10,2,7,NULL), +(55261,10,2,7,NULL), +(55461,10,2,7,NULL), +(55664,10,2,7,NULL), +(55666,11,0,0,NULL), +(55792,11,0,0,NULL), +(55793,11,0,0,NULL), +(55818,11,0,0,NULL), +(55824,11,0,0,NULL), +(55846,11,0,0,NULL), +(55933,11,0,0,NULL), +(55939,11,0,0,NULL), +(55959,11,0,2,NULL), +(55960,11,0,0,NULL), +(56008,11,0,0,NULL), +(56110,11,0,2,NULL), +(56162,11,0,2,NULL), +(56196,11,0,2,NULL), +(56263,11,0,2,NULL), +(56288,11,0,2,NULL), +(56311,11,0,2,NULL), +(56313,11,0,2,NULL); +/*!40000 ALTER TABLE `build_info` ENABLE KEYS */; +UNLOCK TABLES; diff --git a/sql/updates/auth/4.3.4/2025_07_20_03_auth.sql b/sql/updates/auth/4.3.4/2025_07_20_03_auth.sql new file mode 100644 index 0000000000..8875137bba --- /dev/null +++ b/sql/updates/auth/4.3.4/2025_07_20_03_auth.sql @@ -0,0 +1,23 @@ +ALTER TABLE `account` + DROP FOREIGN KEY `fk_bnet_acc`, + DROP CONSTRAINT `uk_bnet_acc`, + DROP COLUMN `sha_pass_hash`, + DROP COLUMN `sessionKey`, + DROP COLUMN `battlenet_account`, + DROP COLUMN `battlenet_index`, + ADD `salt` binary(32) NOT NULL AFTER `username`, + ADD `verifier` binary(32) NOT NULL AFTER `salt`, + ADD `session_key_auth` binary(40) DEFAULT NULL AFTER `verifier`, + ADD `session_key_bnet` varbinary(64) DEFAULT NULL AFTER `session_key_auth`, + ADD `totp_secret` varbinary(128) DEFAULT NULL AFTER `session_key_bnet`, + ADD `timezone_offset` smallint NOT NULL DEFAULT '0' AFTER `os`; + +ALTER TABLE `account_access` + CHANGE `id` `AccountID` int unsigned NOT NULL, + CHANGE `gmlevel` `SecurityLevel` tinyint unsigned NOT NULL; + +-- Wipe all remaining traces of bnet +DROP TABLE IF EXISTS `battlenet_account_bans`; +DROP TABLE IF EXISTS `battlenet_components`; +DROP TABLE IF EXISTS `battlenet_modules`; +DROP TABLE IF EXISTS `battlenet_accounts`; diff --git a/sql/updates/world/4.3.4/2025_07_20_00_world.sql b/sql/updates/world/4.3.4/2025_07_20_00_world.sql new file mode 100644 index 0000000000..05952591d3 --- /dev/null +++ b/sql/updates/world/4.3.4/2025_07_20_00_world.sql @@ -0,0 +1,36 @@ +-- +DELETE FROM `command` WHERE `name` LIKE 'account 2fa%'; +DELETE FROM `command` WHERE `name`='account set 2fa'; +INSERT INTO `command` (`name`, `permission`, `help`) VALUES +('account 2fa', 378, 'Syntax: .account 2fa '), +('account 2fa setup', 379, 'Syntax: .account 2fa setup + +Sets up two-factor authentication for this account.'), +('account 2fa remove', 380, 'Syntax: .account 2fa remove + +Disables two-factor authentication for this account, if enabled.'), +('account set 2fa', 381, 'Syntax: .account set 2fa + +Provide a base32 encoded secret to setup two-factor authentication for the account. +Specify \'off\' to disable two-factor authentication for the account.'); + + + +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 88 AND 95; +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 188 AND 190; +INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES +(88, "Two-factor authentication commands are not properly setup."), +(89, "Two-factor authentication is already enabled for this account."), +(90, "Invalid two-factor authentication token specified."), +(91, "In order to complete setup, you'll need to set up the device you'll be using as your second factor. + +Your 2FA key: %s + +Once you have set up your device, confirm by running .account 2fa setup with the generated token."), +(92, "Two-factor authentication has been successfully set up."), +(93, "Two-factor authentication is not enabled for this account."), +(94, "To remove two-factor authentication, please specify a fresh two-factor token from your authentication device."), +(95, "Two-factor authentication has been successfully disabled."), +(188, "The provided two-factor authentication secret is too long."), +(189, "The provided two-factor authentication secret is not valid."), +(190, "Successfully enabled two-factor authentication for '%s' with the specified secret."); diff --git a/sql/updates/world/4.3.4/2025_07_21_00_world.sql b/sql/updates/world/4.3.4/2025_07_21_00_world.sql new file mode 100644 index 0000000000..10b0b39879 --- /dev/null +++ b/sql/updates/world/4.3.4/2025_07_21_00_world.sql @@ -0,0 +1 @@ +DELETE FROM `command` WHERE `permission` IN (207,208,216,214,830,209,210,211,212,213,215); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index a8531bc7fb..a792cc4820 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -62,6 +62,7 @@ target_link_libraries(common PRIVATE trinity-core-interface PUBLIC + argon2 boost fmt g3dlib diff --git a/src/common/Cryptography/AES.cpp b/src/common/Cryptography/AES.cpp new file mode 100644 index 0000000000..f744f0f69e --- /dev/null +++ b/src/common/Cryptography/AES.cpp @@ -0,0 +1,65 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AES.h" +#include "Errors.h" +#include + +Trinity::Crypto::AES::AES(bool encrypting) : _ctx(EVP_CIPHER_CTX_new()), _encrypting(encrypting) +{ + EVP_CIPHER_CTX_init(_ctx); + int status = EVP_CipherInit_ex(_ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr, _encrypting ? 1 : 0); + ASSERT(status); +} + +Trinity::Crypto::AES::~AES() +{ + EVP_CIPHER_CTX_free(_ctx); +} + +void Trinity::Crypto::AES::Init(Key const& key) +{ + int status = EVP_CipherInit_ex(_ctx, nullptr, nullptr, key.data(), nullptr, -1); + ASSERT(status); +} + +bool Trinity::Crypto::AES::Process(IV const& iv, uint8* data, size_t length, Tag& tag) +{ + ASSERT(length <= static_cast(std::numeric_limits::max())); + int len = static_cast(length); + if (!EVP_CipherInit_ex(_ctx, nullptr, nullptr, nullptr, iv.data(), -1)) + return false; + + int outLen; + if (!EVP_CipherUpdate(_ctx, data, &outLen, data, len)) + return false; + + len -= outLen; + + if (!_encrypting && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag)) + return false; + + if (!EVP_CipherFinal_ex(_ctx, data + outLen, &outLen)) + return false; + + ASSERT(len == outLen); + + if (_encrypting && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag)) + return false; + + return true; +} diff --git a/src/common/Cryptography/AES.h b/src/common/Cryptography/AES.h new file mode 100644 index 0000000000..c8a646340b --- /dev/null +++ b/src/common/Cryptography/AES.h @@ -0,0 +1,51 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef Trinity_AES_h__ +#define Trinity_AES_h__ + +#include "Define.h" +#include +#include + +namespace Trinity::Crypto +{ + class TC_COMMON_API AES + { + public: + static constexpr size_t IV_SIZE_BYTES = 12; + static constexpr size_t KEY_SIZE_BYTES = 16; + static constexpr size_t TAG_SIZE_BYTES = 12; + + using IV = std::array; + using Key = std::array; + using Tag = uint8[TAG_SIZE_BYTES]; + + AES(bool encrypting); + ~AES(); + + void Init(Key const& key); + + bool Process(IV const& iv, uint8* data, size_t length, Tag& tag); + + private: + EVP_CIPHER_CTX* _ctx; + bool _encrypting; + }; +} + +#endif // Trinity_AES_h__ diff --git a/src/common/Cryptography/ARC4.cpp b/src/common/Cryptography/ARC4.cpp index c6b052b578..e8addab380 100644 --- a/src/common/Cryptography/ARC4.cpp +++ b/src/common/Cryptography/ARC4.cpp @@ -1,5 +1,5 @@ /* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,34 +18,20 @@ #include "ARC4.h" #include "Errors.h" -ARC4::ARC4(uint32 len) : _ctx(EVP_CIPHER_CTX_new()) +Trinity::Crypto::ARC4::ARC4() : _ctx(EVP_CIPHER_CTX_new()) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L _cipher = EVP_CIPHER_fetch(nullptr, "RC4", nullptr); #else - EVP_CIPHER const *_cipher = EVP_rc4(); + EVP_CIPHER const* _cipher = EVP_rc4(); #endif EVP_CIPHER_CTX_init(_ctx); - EVP_EncryptInit_ex(_ctx, _cipher, nullptr, nullptr, nullptr); - EVP_CIPHER_CTX_set_key_length(_ctx, len); + int result = EVP_EncryptInit_ex(_ctx, _cipher, nullptr, nullptr, nullptr); + ASSERT(result == 1); } -ARC4::ARC4(uint8* seed, uint32 len) : _ctx(EVP_CIPHER_CTX_new()) -{ -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - _cipher = EVP_CIPHER_fetch(nullptr, "RC4", nullptr); -#else - EVP_CIPHER const *_cipher = EVP_rc4(); -#endif - - EVP_CIPHER_CTX_init(_ctx); - EVP_EncryptInit_ex(_ctx, _cipher, nullptr, nullptr, nullptr); - EVP_CIPHER_CTX_set_key_length(_ctx, len); - EVP_EncryptInit_ex(_ctx, nullptr, nullptr, seed, nullptr); -} - -ARC4::~ARC4() +Trinity::Crypto::ARC4::~ARC4() { EVP_CIPHER_CTX_free(_ctx); @@ -54,14 +40,19 @@ ARC4::~ARC4() #endif } -void ARC4::Init(uint8* seed) +void Trinity::Crypto::ARC4::Init(uint8 const* seed, size_t len) { - EVP_EncryptInit_ex(_ctx, nullptr, nullptr, seed, nullptr); + int result1 = EVP_CIPHER_CTX_set_key_length(_ctx, len); + ASSERT(result1 == 1); + int result2 = EVP_EncryptInit_ex(_ctx, nullptr, nullptr, seed, nullptr); + ASSERT(result2 == 1); } -void ARC4::UpdateData(int len, uint8* data) +void Trinity::Crypto::ARC4::UpdateData(uint8* data, size_t len) { int outlen = 0; - EVP_EncryptUpdate(_ctx, data, &outlen, data, len); - EVP_EncryptFinal_ex(_ctx, data, &outlen); + int result1 = EVP_EncryptUpdate(_ctx, data, &outlen, data, len); + ASSERT(result1 == 1); + int result2 = EVP_EncryptFinal_ex(_ctx, data, &outlen); + ASSERT(result2 == 1); } diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h index d919de71c3..82ea09ee4f 100644 --- a/src/common/Cryptography/ARC4.h +++ b/src/common/Cryptography/ARC4.h @@ -1,5 +1,5 @@ /* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -22,19 +22,27 @@ #include #include -class TC_COMMON_API ARC4 +namespace Trinity::Crypto { + class TC_COMMON_API ARC4 + { public: - ARC4(uint32 len); - ARC4(uint8* seed, uint32 len); + ARC4(); ~ARC4(); - void Init(uint8* seed); - void UpdateData(int len, uint8* data); + + void Init(uint8 const* seed, size_t len); + template + void Init(Container const& c) { Init(std::data(c), std::size(c)); } + + void UpdateData(uint8* data, size_t len); + template + void UpdateData(Container& c) { UpdateData(std::data(c), std::size(c)); } private: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_CIPHER *_cipher; + EVP_CIPHER* _cipher; #endif EVP_CIPHER_CTX* _ctx; -}; + }; +} #endif diff --git a/src/common/Cryptography/Argon2Hash.cpp b/src/common/Cryptography/Argon2Hash.cpp new file mode 100644 index 0000000000..9b798a4a27 --- /dev/null +++ b/src/common/Cryptography/Argon2Hash.cpp @@ -0,0 +1,44 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Argon2Hash.h" +#include + +/*static*/ Optional Trinity::Crypto::Argon2::Hash(std::string const& password, BigNumber const& salt, uint32 nIterations, uint32 kibMemoryCost) +{ + char buf[ENCODED_HASH_LEN]; + std::vector saltBytes = salt.ToByteVector(); + int status = argon2id_hash_encoded( + nIterations, + kibMemoryCost, + PARALLELISM, + password.c_str(), password.length(), + saltBytes.data(), saltBytes.size(), + HASH_LEN, buf, ENCODED_HASH_LEN + ); + + if (status == ARGON2_OK) + return std::string(buf); + + return {}; +} + +/*static*/ bool Trinity::Crypto::Argon2::Verify(std::string const& password, std::string const& hash) +{ + int status = argon2id_verify(hash.c_str(), password.c_str(), password.length()); + return (status == ARGON2_OK); +} diff --git a/src/common/Cryptography/Argon2Hash.h b/src/common/Cryptography/Argon2Hash.h new file mode 100644 index 0000000000..26dd20a135 --- /dev/null +++ b/src/common/Cryptography/Argon2Hash.h @@ -0,0 +1,41 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_ARGON2_H +#define TRINITY_ARGON2_H + +#include "BigNumber.h" +#include "Define.h" +#include "Optional.h" +#include + +namespace Trinity::Crypto +{ + struct TC_COMMON_API Argon2 + { + static constexpr uint32 HASH_LEN = 16; // 128 bits, in bytes + static constexpr uint32 ENCODED_HASH_LEN = 100; // in chars + static constexpr uint32 DEFAULT_ITERATIONS = 10; // determined by dice roll, guaranteed to be secure (not really) + static constexpr uint32 DEFAULT_MEMORY_COST = (1u << 17); // 2^17 kibibytes is 2^7 mebibytes is ~100MB + static constexpr uint32 PARALLELISM = 1; // we don't support threaded hashing + + static Optional Hash(std::string const& password, BigNumber const& salt, uint32 nIterations = DEFAULT_ITERATIONS, uint32 kibMemoryCost = DEFAULT_MEMORY_COST); + static bool Verify(std::string const& password, std::string const& hash); + }; +} + +#endif diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h b/src/common/Cryptography/Authentication/AuthDefines.h similarity index 68% rename from src/server/bnetserver/PrecompiledHeaders/bnetPCH.h rename to src/common/Cryptography/Authentication/AuthDefines.h index 845bdf053a..fef2189703 100644 --- a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h +++ b/src/common/Cryptography/Authentication/AuthDefines.h @@ -1,5 +1,5 @@ /* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,10 +15,13 @@ * with this program. If not, see . */ -#include "BNetRealmList.h" -#include "Common.h" -#include "ComponentManager.h" -#include "Configuration/Config.h" -#include "Log.h" -#include "ModuleManager.h" -#include "SessionManager.h" +#ifndef TRINITY_AUTHDEFINES_H +#define TRINITY_AUTHDEFINES_H + +#include "Define.h" +#include + +constexpr size_t SESSION_KEY_LENGTH = 40; +using SessionKey = std::array; + +#endif diff --git a/src/common/Cryptography/Authentication/PacketCrypt.cpp b/src/common/Cryptography/Authentication/PacketCrypt.cpp index f02c6a5227..94db303815 100644 --- a/src/common/Cryptography/Authentication/PacketCrypt.cpp +++ b/src/common/Cryptography/Authentication/PacketCrypt.cpp @@ -17,8 +17,8 @@ #include "PacketCrypt.h" -PacketCrypt::PacketCrypt(uint32 rc4InitSize) - : _clientDecrypt(rc4InitSize), _serverEncrypt(rc4InitSize), _initialized(false) +PacketCrypt::PacketCrypt() : + _initialized(false) { } @@ -27,7 +27,7 @@ void PacketCrypt::DecryptRecv(uint8* data, size_t len) if (!_initialized) return; - _clientDecrypt.UpdateData(len, data); + _clientDecrypt.UpdateData(data, len); } void PacketCrypt::EncryptSend(uint8* data, size_t len) @@ -35,5 +35,5 @@ void PacketCrypt::EncryptSend(uint8* data, size_t len) if (!_initialized) return; - _serverEncrypt.UpdateData(len, data); + _serverEncrypt.UpdateData(data, len); } diff --git a/src/common/Cryptography/Authentication/PacketCrypt.h b/src/common/Cryptography/Authentication/PacketCrypt.h index 05d897a712..e22c5edf94 100644 --- a/src/common/Cryptography/Authentication/PacketCrypt.h +++ b/src/common/Cryptography/Authentication/PacketCrypt.h @@ -18,25 +18,27 @@ #ifndef _PACKETCRYPT_H #define _PACKETCRYPT_H -#include "Cryptography/ARC4.h" +#include "ARC4.h" +#include "AuthDefines.h" +#include -class BigNumber; +constexpr uint8 SEED_KEY_SIZE = 16; class TC_COMMON_API PacketCrypt { public: - PacketCrypt(uint32 rc4InitSize); + PacketCrypt(); virtual ~PacketCrypt() { } - virtual void Init(BigNumber* K) = 0; + virtual void Init(SessionKey const& K) = 0; void DecryptRecv(uint8* data, size_t length); void EncryptSend(uint8* data, size_t length); bool IsInitialized() const { return _initialized; } protected: - ARC4 _clientDecrypt; - ARC4 _serverEncrypt; + Trinity::Crypto::ARC4 _clientDecrypt; + Trinity::Crypto::ARC4 _serverEncrypt; bool _initialized; }; diff --git a/src/common/Cryptography/Authentication/SRP6.cpp b/src/common/Cryptography/Authentication/SRP6.cpp new file mode 100644 index 0000000000..daaa115586 --- /dev/null +++ b/src/common/Cryptography/Authentication/SRP6.cpp @@ -0,0 +1,109 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "SRP6.h" +#include "CryptoRandom.h" +#include "Util.h" +#include +#include + +using SHA1 = Trinity::Crypto::SHA1; +using SRP6 = Trinity::Crypto::SRP6; + +/*static*/ std::array const SRP6::g = { 7 }; +/*static*/ std::array const SRP6::N = HexStrToByteArray<32>("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", true); +/*static*/ BigNumber const SRP6::_g(SRP6::g); +/*static*/ BigNumber const SRP6::_N(N); + +/*static*/ std::pair SRP6::MakeRegistrationData(std::string const& username, std::string const& password) +{ + std::pair res; + Crypto::GetRandomBytes(res.first); // random salt + res.second = CalculateVerifier(username, password, res.first); + return res; +} + +/*static*/ SRP6::Verifier SRP6::CalculateVerifier(std::string const& username, std::string const& password, SRP6::Salt const& salt) +{ + // v = g ^ H(s || H(u || ':' || p)) mod N + return _g.ModExp( + SHA1::GetDigestOf( + salt, + SHA1::GetDigestOf(username, ":", password) + ) + ,_N).ToByteArray<32>(); +} + +/*static*/ SessionKey SRP6::SHA1Interleave(SRP6::EphemeralKey const& S) +{ + // split S into two buffers + std::array buf0, buf1; + for (size_t i = 0; i < EPHEMERAL_KEY_LENGTH/2; ++i) + { + buf0[i] = S[2 * i + 0]; + buf1[i] = S[2 * i + 1]; + } + + // find position of first nonzero byte + size_t p = 0; + while (p < EPHEMERAL_KEY_LENGTH && !S[p]) ++p; + if (p & 1) ++p; // skip one extra byte if p is odd + p /= 2; // offset into buffers + + // hash each of the halves, starting at the first nonzero byte + SHA1::Digest const hash0 = SHA1::GetDigestOf(buf0.data() + p, EPHEMERAL_KEY_LENGTH/2 - p); + SHA1::Digest const hash1 = SHA1::GetDigestOf(buf1.data() + p, EPHEMERAL_KEY_LENGTH/2 - p); + + // stick the two hashes back together + SessionKey K; + for (size_t i = 0; i < SHA1::DIGEST_LENGTH; ++i) + { + K[2 * i + 0] = hash0[i]; + K[2 * i + 1] = hash1[i]; + } + return K; +} + +SRP6::SRP6(std::string const& username, Salt const& salt, Verifier const& verifier) + : _I(SHA1::GetDigestOf(username)), _b(Crypto::GetRandomBytes<32>()), _v(verifier), s(salt), B(_B(_b, _v)) {} + +std::optional SRP6::VerifyChallengeResponse(EphemeralKey const& A, SHA1::Digest const& clientM) +{ + ASSERT(!_used, "A single SRP6 object must only ever be used to verify ONCE!"); + _used = true; + + BigNumber const _A(A); + if ((_A % _N).IsZero()) + return std::nullopt; + + BigNumber const u(SHA1::GetDigestOf(A, B)); + EphemeralKey const S = (_A * (_v.ModExp(u, _N))).ModExp(_b, N).ToByteArray<32>(); + + SessionKey K = SHA1Interleave(S); + + // NgHash = H(N) xor H(g) + SHA1::Digest const NHash = SHA1::GetDigestOf(N); + SHA1::Digest const gHash = SHA1::GetDigestOf(g); + SHA1::Digest NgHash; + std::transform(NHash.begin(), NHash.end(), gHash.begin(), NgHash.begin(), std::bit_xor<>()); + + SHA1::Digest const ourM = SHA1::GetDigestOf(NgHash, _I, s, A, B, K); + if (ourM == clientM) + return K; + else + return std::nullopt; +} diff --git a/src/common/Cryptography/Authentication/SRP6.h b/src/common/Cryptography/Authentication/SRP6.h new file mode 100644 index 0000000000..7014c26607 --- /dev/null +++ b/src/common/Cryptography/Authentication/SRP6.h @@ -0,0 +1,83 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_SRP6_H +#define TRINITY_SRP6_H + +#include "AuthDefines.h" +#include "BigNumber.h" +#include "Define.h" +#include "Common.h" +#include "CryptoHash.h" +#include +#include + +namespace Trinity::Crypto +{ + class TC_COMMON_API SRP6 + { + public: + static constexpr size_t SALT_LENGTH = 32; + using Salt = std::array; + static constexpr size_t VERIFIER_LENGTH = 32; + using Verifier = std::array; + static constexpr size_t EPHEMERAL_KEY_LENGTH = 32; + using EphemeralKey = std::array; + + static std::array const g; + static std::array const N; + + // username + password must be passed through Utf8ToUpperOnlyLatin FIRST! + static std::pair MakeRegistrationData(std::string const& username, std::string const& password); + // username + password must be passed through Utf8ToUpperOnlyLatin FIRST! + static bool CheckLogin(std::string const& username, std::string const& password, Salt const& salt, Verifier const& verifier) + { + return (verifier == CalculateVerifier(username, password, salt)); + } + + static SHA1::Digest GetSessionVerifier(EphemeralKey const& A, SHA1::Digest const& clientM, SessionKey const& K) + { + return SHA1::GetDigestOf(A, clientM, K); + } + + SRP6(std::string const& username, Salt const& salt, Verifier const& verifier); + std::optional VerifyChallengeResponse(EphemeralKey const& A, SHA1::Digest const& clientM); + + private: + bool _used = false; // a single instance can only be used to verify once + + static Verifier CalculateVerifier(std::string const& username, std::string const& password, Salt const& salt); + static SessionKey SHA1Interleave(EphemeralKey const& S); + + /* global algorithm parameters */ + static BigNumber const _g; // a [g]enerator for the ring of integers mod N, algorithm parameter + static BigNumber const _N; // the modulus, an algorithm parameter; all operations are mod this + + static EphemeralKey _B(BigNumber const& b, BigNumber const& v) { return ((_g.ModExp(b,_N) + (v * 3)) % N).ToByteArray(); } + + /* per-instantiation parameters, set on construction */ + SHA1::Digest const _I; // H(I) - the username, all uppercase + BigNumber const _b; // b - randomly chosen by the server, 19 bytes, never given out + BigNumber const _v; // v - the user's password verifier, derived from s + H(USERNAME || ":" || PASSWORD) + + public: + Salt const s; // s - the user's password salt, random, used to calculate v on registration + EphemeralKey const B; // B = 3v + g^b + }; +} + +#endif diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp b/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp index 3f329315a9..98ce5848b7 100644 --- a/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp +++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp @@ -16,42 +16,30 @@ */ #include "WorldPacketCrypt.h" -#include "Cryptography/HmacHash.h" -#include "Cryptography/BigNumber.h" - +#include "CryptoHash.h" +#include "HMAC.h" #include -WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt(SHA_DIGEST_LENGTH) +WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt() { } -void WorldPacketCrypt::Init(BigNumber* K) +void WorldPacketCrypt::Init(SessionKey const& K) { - uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 }; - uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE }; + std::array ServerEncryptionKey = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 }; + std::array ServerDecryptionKey = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE }; Init(K, ServerEncryptionKey, ServerDecryptionKey); } -void WorldPacketCrypt::Init(BigNumber* k, uint8 const* serverKey, uint8 const* clientKey) +void WorldPacketCrypt::Init(SessionKey const& K, std::array const& serverKey, std::array const& clientKey) { - HmacSha1 serverEncryptHmac(SEED_KEY_SIZE, (uint8*)serverKey); - uint8* encryptHash = serverEncryptHmac.ComputeHash(k); - - HmacSha1 clientDecryptHmac(SEED_KEY_SIZE, (uint8*)clientKey); - uint8* decryptHash = clientDecryptHmac.ComputeHash(k); - - _clientDecrypt.Init(decryptHash); - _serverEncrypt.Init(encryptHash); + _serverEncrypt.Init(Trinity::Crypto::HMAC_SHA1::GetDigestOf(serverKey, K)); + _clientDecrypt.Init(Trinity::Crypto::HMAC_SHA1::GetDigestOf(clientKey, K)); // Drop first 1024 bytes, as WoW uses ARC4-drop1024. - uint8 syncBuf[1024]; - memset(syncBuf, 0, 1024); - - _serverEncrypt.UpdateData(1024, syncBuf); - - memset(syncBuf, 0, 1024); - - _clientDecrypt.UpdateData(1024, syncBuf); + std::array syncBuf; + _serverEncrypt.UpdateData(syncBuf); + _clientDecrypt.UpdateData(syncBuf); _initialized = true; } diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.h b/src/common/Cryptography/Authentication/WorldPacketCrypt.h index 3c41a06898..9f33f62e3c 100644 --- a/src/common/Cryptography/Authentication/WorldPacketCrypt.h +++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.h @@ -19,16 +19,16 @@ #define _WORLDPACKETCRYPT_H #include "PacketCrypt.h" - -class BigNumber; +#include "AuthDefines.h" +#include class TC_COMMON_API WorldPacketCrypt : public PacketCrypt { public: WorldPacketCrypt(); - void Init(BigNumber* K) override; - void Init(BigNumber* k, uint8 const* serverKey, uint8 const* clientKey); + void Init(SessionKey const& K) override; + void Init(SessionKey const& K, std::array const& serverKey, std::array const& clientKey); }; #endif // _WORLDPACKETCRYPT_H diff --git a/src/common/Cryptography/BigNumber.cpp b/src/common/Cryptography/BigNumber.cpp index 1d639dd477..da54cfcb37 100644 --- a/src/common/Cryptography/BigNumber.cpp +++ b/src/common/Cryptography/BigNumber.cpp @@ -16,6 +16,7 @@ */ #include "Cryptography/BigNumber.h" +#include "Errors.h" #include #include #include @@ -26,20 +27,21 @@ BigNumber::BigNumber() { } BigNumber::BigNumber(BigNumber const& bn) - : _bn(BN_dup(bn._bn)) + : _bn(BN_dup(bn.BN())) { } -BigNumber::BigNumber(uint32 val) - : _bn(BN_new()) -{ - BN_set_word(_bn, val); -} - BigNumber::~BigNumber() { BN_free(_bn); } +void BigNumber::SetDword(int32 val) +{ + SetDword(uint32(abs(val))); + if (val < 0) + BN_set_negative(_bn, 1); +} + void BigNumber::SetDword(uint32 val) { BN_set_word(_bn, val); @@ -52,21 +54,18 @@ void BigNumber::SetQword(uint64 val) BN_add_word(_bn, (uint32)(val & 0xFFFFFFFF)); } -void BigNumber::SetBinary(uint8 const* bytes, int32 len) +void BigNumber::SetBinary(uint8 const* bytes, int32 len, bool littleEndian) { - uint8* array = new uint8[len]; - - for (int i = 0; i < len; i++) - array[i] = bytes[len - 1 - i]; - - BN_bin2bn(array, len, _bn); - - delete[] array; + if (littleEndian) + BN_lebin2bn(bytes, len, _bn); + else + BN_bin2bn(bytes, len, _bn); } -void BigNumber::SetHexStr(char const* str) +bool BigNumber::SetHexStr(char const* str) { - BN_hex2bn(&_bn, str); + int n = BN_hex2bn(&_bn, str); + return (n > 0); } void BigNumber::SetRand(int32 numbits) @@ -83,19 +82,19 @@ BigNumber& BigNumber::operator=(BigNumber const& bn) return *this; } -BigNumber BigNumber::operator+=(BigNumber const& bn) +BigNumber& BigNumber::operator+=(BigNumber const& bn) { BN_add(_bn, _bn, bn._bn); return *this; } -BigNumber BigNumber::operator-=(BigNumber const& bn) +BigNumber& BigNumber::operator-=(BigNumber const& bn) { BN_sub(_bn, _bn, bn._bn); return *this; } -BigNumber BigNumber::operator*=(BigNumber const& bn) +BigNumber& BigNumber::operator*=(BigNumber const& bn) { BN_CTX *bnctx; @@ -106,7 +105,7 @@ BigNumber BigNumber::operator*=(BigNumber const& bn) return *this; } -BigNumber BigNumber::operator/=(BigNumber const& bn) +BigNumber& BigNumber::operator/=(BigNumber const& bn) { BN_CTX *bnctx; @@ -117,7 +116,7 @@ BigNumber BigNumber::operator/=(BigNumber const& bn) return *this; } -BigNumber BigNumber::operator%=(BigNumber const& bn) +BigNumber& BigNumber::operator%=(BigNumber const& bn) { BN_CTX *bnctx; @@ -128,7 +127,18 @@ BigNumber BigNumber::operator%=(BigNumber const& bn) return *this; } -BigNumber BigNumber::Exp(BigNumber const& bn) +BigNumber& BigNumber::operator<<=(int n) +{ + BN_lshift(_bn, _bn, n); + return *this; +} + +int32 BigNumber::CompareTo(BigNumber const& bn) const +{ + return BN_cmp(_bn, bn._bn); +} + +BigNumber BigNumber::Exp(BigNumber const& bn) const { BigNumber ret; BN_CTX *bnctx; @@ -140,7 +150,7 @@ BigNumber BigNumber::Exp(BigNumber const& bn) return ret; } -BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2) +BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2) const { BigNumber ret; BN_CTX *bnctx; @@ -152,12 +162,12 @@ BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2) return ret; } -int32 BigNumber::GetNumBytes(void) +int32 BigNumber::GetNumBytes() const { return BN_num_bytes(_bn); } -uint32 BigNumber::AsDword() +uint32 BigNumber::AsDword() const { return (uint32)BN_get_word(_bn); } @@ -172,25 +182,19 @@ bool BigNumber::IsNegative() const return BN_is_negative(_bn); } -std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) +void BigNumber::GetBytes(uint8* buf, size_t bufsize, bool littleEndian) const { - int numBytes = GetNumBytes(); - int length = (minSize >= numBytes) ? minSize : numBytes; + int res = littleEndian ? BN_bn2lebinpad(_bn, buf, bufsize) : BN_bn2binpad(_bn, buf, bufsize); + ASSERT(res > 0, "Buffer of size %zu is too small to hold bignum with %d bytes.\n", bufsize, BN_num_bytes(_bn)); +} - uint8* array = new uint8[length]; - - // If we need more bytes than length of BigNumber set the rest to 0 - if (length > numBytes) - memset((void*)array, 0, length); - - BN_bn2bin(_bn, array + (length-numBytes)); - - // openssl's BN stores data internally in big endian format, reverse if little endian desired - if (littleEndian) - std::reverse(array, array + length); - - std::unique_ptr ret(array); - return ret; +std::vector BigNumber::ToByteVector(int32 minSize, bool littleEndian) const +{ + std::size_t length = std::max(GetNumBytes(), minSize); + std::vector v; + v.resize(length); + GetBytes(v.data(), length, littleEndian); + return v; } std::string BigNumber::AsHexStr() const diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h index 450f119e60..bbe2bebb42 100644 --- a/src/common/Cryptography/BigNumber.h +++ b/src/common/Cryptography/BigNumber.h @@ -18,9 +18,11 @@ #ifndef _AUTH_BIGNUMBER_H #define _AUTH_BIGNUMBER_H -#include #include "Define.h" +#include +#include #include +#include struct bignum_st; @@ -29,72 +31,110 @@ class TC_COMMON_API BigNumber public: BigNumber(); BigNumber(BigNumber const& bn); - BigNumber(uint32); + BigNumber(uint32 v) : BigNumber() { SetDword(v); } + BigNumber(int32 v) : BigNumber() { SetDword(v); } + BigNumber(std::string const& v) : BigNumber() { SetHexStr(v); } + template + BigNumber(std::array const& v, bool littleEndian = true) : BigNumber() { SetBinary(v.data(), Size, littleEndian); } + ~BigNumber(); + void SetDword(int32); void SetDword(uint32); void SetQword(uint64); - void SetBinary(uint8 const* bytes, int32 len); - void SetHexStr(char const* str); + void SetBinary(uint8 const* bytes, int32 len, bool littleEndian = true); + template + auto SetBinary(Container const& c, bool littleEndian = true) -> std::enable_if_t>> { SetBinary(std::data(c), std::size(c), littleEndian); } + bool SetHexStr(char const* str); + bool SetHexStr(std::string const& str) { return SetHexStr(str.c_str()); } void SetRand(int32 numbits); BigNumber& operator=(BigNumber const& bn); - BigNumber operator+=(BigNumber const& bn); - BigNumber operator+(BigNumber const& bn) + BigNumber& operator+=(BigNumber const& bn); + BigNumber operator+(BigNumber const& bn) const { BigNumber t(*this); return t += bn; } - BigNumber operator-=(BigNumber const& bn); - BigNumber operator-(BigNumber const& bn) + BigNumber& operator-=(BigNumber const& bn); + BigNumber operator-(BigNumber const& bn) const { BigNumber t(*this); return t -= bn; } - BigNumber operator*=(BigNumber const& bn); - BigNumber operator*(BigNumber const& bn) + BigNumber& operator*=(BigNumber const& bn); + BigNumber operator*(BigNumber const& bn) const { BigNumber t(*this); return t *= bn; } - BigNumber operator/=(BigNumber const& bn); - BigNumber operator/(BigNumber const& bn) + BigNumber& operator/=(BigNumber const& bn); + BigNumber operator/(BigNumber const& bn) const { BigNumber t(*this); return t /= bn; } - BigNumber operator%=(BigNumber const& bn); - BigNumber operator%(BigNumber const& bn) + BigNumber& operator%=(BigNumber const& bn); + BigNumber operator%(BigNumber const& bn) const { BigNumber t(*this); return t %= bn; } + BigNumber& operator<<=(int n); + BigNumber operator<<(int n) const + { + BigNumber t(*this); + return t <<= n; + } + + int32 CompareTo(BigNumber const& bn) const; + bool operator==(BigNumber const& bn) const { return (CompareTo(bn) == 0); } + std::strong_ordering operator<=>(BigNumber const& other) const + { + int32 cmp = CompareTo(other); + if (cmp < 0) + return std::strong_ordering::less; + if (cmp > 0) + return std::strong_ordering::greater; + return std::strong_ordering::equal; + } + bool IsZero() const; bool IsNegative() const; - BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2); - BigNumber Exp(BigNumber const&); + BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2) const; + BigNumber Exp(BigNumber const&) const; - int32 GetNumBytes(void); + int32 GetNumBytes() const; - struct bignum_st *BN() { return _bn; } + struct bignum_st* BN() { return _bn; } + struct bignum_st const* BN() const { return _bn; } - uint32 AsDword(); + uint32 AsDword() const; - std::unique_ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); + void GetBytes(uint8* buf, size_t bufsize, bool littleEndian = true) const; + std::vector ToByteVector(int32 minSize = 0, bool littleEndian = true) const; + + template + std::array ToByteArray(bool littleEndian = true) const + { + std::array buf; + GetBytes(buf.data(), Size, littleEndian); + return buf; + } std::string AsHexStr() const; std::string AsDecStr() const; private: - struct bignum_st *_bn; + struct bignum_st* _bn; }; #endif diff --git a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h b/src/common/Cryptography/CryptoConstants.h similarity index 61% rename from src/server/bnetserver/Authentication/BattlenetPacketCrypt.h rename to src/common/Cryptography/CryptoConstants.h index 72eb4ad8f2..65fd4d1b8c 100644 --- a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h +++ b/src/common/Cryptography/CryptoConstants.h @@ -1,5 +1,5 @@ /* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,21 +15,19 @@ * with this program. If not, see . */ -#ifndef BattlenetPacketCrypt_h__ -#define BattlenetPacketCrypt_h__ +#ifndef TRINITY_CRYPTO_CONSTANTS_H +#define TRINITY_CRYPTO_CONSTANTS_H -#include "PacketCrypt.h" +#include "Define.h" -class BigNumber; - -namespace Battlenet +namespace Trinity::Crypto { - class PacketCrypt : public ::PacketCrypt + struct Constants { - public: - PacketCrypt(); - - void Init(BigNumber* K) override; + static constexpr size_t MD5_DIGEST_LENGTH_BYTES = 16; + static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20; + static constexpr size_t SHA256_DIGEST_LENGTH_BYTES = 32; }; } -#endif // BattlenetPacketCrypt_h__ + +#endif diff --git a/src/common/Cryptography/CryptoGenerics.h b/src/common/Cryptography/CryptoGenerics.h new file mode 100644 index 0000000000..75ad443b32 --- /dev/null +++ b/src/common/Cryptography/CryptoGenerics.h @@ -0,0 +1,111 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_CRYPTO_GENERICS_HPP +#define TRINITY_CRYPTO_GENERICS_HPP + +#include "BigNumber.h" +#include "CryptoRandom.h" +#include "Define.h" +#include "Errors.h" +#include +#include + +namespace Trinity::Impl +{ + struct CryptoGenericsImpl + { + template + static typename Cipher::IV GenerateRandomIV() + { + typename Cipher::IV iv; + Trinity::Crypto::GetRandomBytes(iv); + return iv; + } + + template + static void AppendToBack(std::vector& data, Container const& tail) + { + data.insert(data.end(), std::begin(tail), std::end(tail)); + } + + template + static void SplitFromBack(std::vector& data, Container& tail) + { + ASSERT(data.size() >= std::size(tail)); + for (size_t i = 1, N = std::size(tail); i <= N; ++i) + { + tail[N - i] = data.back(); + data.pop_back(); + } + } + }; +} + +namespace Trinity::Crypto +{ + template + void AEEncryptWithRandomIV(std::vector& data, typename Cipher::Key const& key) + { + using IV = typename Cipher::IV; + using Tag = typename Cipher::Tag; + // select random IV + IV iv = Trinity::Impl::CryptoGenericsImpl::GenerateRandomIV(); + Tag tag; + + // encrypt data + Cipher cipher(true); + cipher.Init(key); + bool success = cipher.Process(iv, data.data(), data.size(), tag); + ASSERT(success); + + // append trailing IV and tag + Trinity::Impl::CryptoGenericsImpl::AppendToBack(data, iv); + Trinity::Impl::CryptoGenericsImpl::AppendToBack(data, tag); + } + + template + void AEEncryptWithRandomIV(std::vector& data, BigNumber const& key) + { + AEEncryptWithRandomIV(data, key.ToByteArray()); + } + + template + bool AEDecrypt(std::vector& data, typename Cipher::Key const& key) + { + using IV = typename Cipher::IV; + using Tag = typename Cipher::Tag; + // extract trailing IV and tag + IV iv; + Tag tag; + Trinity::Impl::CryptoGenericsImpl::SplitFromBack(data, tag); + Trinity::Impl::CryptoGenericsImpl::SplitFromBack(data, iv); + + // decrypt data + Cipher cipher(false); + cipher.Init(key); + return cipher.Process(iv, data.data(), data.size(), tag); + } + + template + bool AEDecrypt(std::vector& data, BigNumber const& key) + { + return AEDecrypt(data, key.ToByteArray()); + } +} + +#endif diff --git a/src/common/Cryptography/CryptoHash.h b/src/common/Cryptography/CryptoHash.h new file mode 100644 index 0000000000..19bb776438 --- /dev/null +++ b/src/common/Cryptography/CryptoHash.h @@ -0,0 +1,145 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_CRYPTOHASH_H +#define TRINITY_CRYPTOHASH_H + +#include "CryptoConstants.h" +#include "Define.h" +#include "Errors.h" +#include +#include +#include +#include +#include + +class BigNumber; + +namespace Trinity::Impl +{ + struct GenericHashImpl + { + typedef EVP_MD const* (*HashCreator)(); + + static EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_new(); } + static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_free(ctx); } + }; + + template + class GenericHash + { + public: + static constexpr size_t DIGEST_LENGTH = DigestLength; + using Digest = std::array; + + static Digest GetDigestOf(uint8 const* data, size_t len) + { + GenericHash hash; + hash.UpdateData(data, len); + hash.Finalize(); + return hash.GetDigest(); + } + + template + static auto GetDigestOf(Ts&&... pack) -> std::enable_if_t> || ...), Digest> + { + GenericHash hash; + (hash.UpdateData(std::forward(pack)), ...); + hash.Finalize(); + return hash.GetDigest(); + } + + GenericHash() : _ctx(GenericHashImpl::MakeCTX()) + { + int result = EVP_DigestInit_ex(_ctx, HashCreator(), nullptr); + ASSERT(result == 1); + } + + GenericHash(GenericHash const& right) : _ctx(GenericHashImpl::MakeCTX()) + { + *this = right; + } + + GenericHash(GenericHash&& right) noexcept + { + *this = std::move(right); + } + + ~GenericHash() + { + if (!_ctx) + return; + GenericHashImpl::DestroyCTX(_ctx); + _ctx = nullptr; + } + + GenericHash& operator=(GenericHash const& right) + { + if (this == &right) + return *this; + + int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx); + ASSERT(result == 1); + _digest = right._digest; + return *this; + } + + GenericHash& operator=(GenericHash&& right) noexcept + { + if (this == &right) + return *this; + + _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX()); + _digest = std::exchange(right._digest, Digest{}); + return *this; + } + + void UpdateData(uint8 const* data, size_t len) + { + int result = EVP_DigestUpdate(_ctx, data, len); + ASSERT(result == 1); + } + void UpdateData(std::string_view str) { UpdateData(reinterpret_cast(str.data()), str.size()); } + void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + template + void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); } + + void Finalize() + { + uint32 length; + int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length); + ASSERT(result == 1); + ASSERT(length == DIGEST_LENGTH); + } + + Digest const& GetDigest() const { return _digest; } + + private: + EVP_MD_CTX* _ctx; + Digest _digest = { }; + }; +} + +namespace Trinity::Crypto +{ + using MD5 = Trinity::Impl::GenericHash; + using SHA1 = Trinity::Impl::GenericHash; + using SHA256 = Trinity::Impl::GenericHash; +} + +#endif diff --git a/src/common/Cryptography/CryptoRandom.cpp b/src/common/Cryptography/CryptoRandom.cpp new file mode 100644 index 0000000000..a83eeb14b3 --- /dev/null +++ b/src/common/Cryptography/CryptoRandom.cpp @@ -0,0 +1,26 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "CryptoRandom.h" +#include "Errors.h" +#include + +void Trinity::Crypto::GetRandomBytes(uint8* buf, size_t len) +{ + int result = RAND_bytes(buf, len); + ASSERT(result == 1, "Not enough randomness in OpenSSL's entropy pool. What in the world are you running on?"); +} diff --git a/src/common/Cryptography/CryptoRandom.h b/src/common/Cryptography/CryptoRandom.h new file mode 100644 index 0000000000..1deb94e0f6 --- /dev/null +++ b/src/common/Cryptography/CryptoRandom.h @@ -0,0 +1,43 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_CRYPTORANDOM_H +#define TRINITY_CRYPTORANDOM_H + +#include "Define.h" +#include + +namespace Trinity::Crypto +{ + void TC_COMMON_API GetRandomBytes(uint8* buf, size_t len); + + template + void GetRandomBytes(Container& c) + { + GetRandomBytes(std::data(c), std::size(c)); + } + + template + std::array GetRandomBytes() + { + std::array arr; + GetRandomBytes(arr); + return arr; + } +} + +#endif diff --git a/src/common/Cryptography/HMAC.h b/src/common/Cryptography/HMAC.h new file mode 100644 index 0000000000..4f58f57c94 --- /dev/null +++ b/src/common/Cryptography/HMAC.h @@ -0,0 +1,140 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_HMAC_H +#define TRINITY_HMAC_H + +#include "CryptoConstants.h" +#include "CryptoHash.h" +#include "Define.h" +#include "Errors.h" +#include +#include +#include + +class BigNumber; + +namespace Trinity::Impl +{ + template + class GenericHMAC + { + public: + static constexpr size_t DIGEST_LENGTH = DigestLength; + using Digest = std::array; + + template + static Digest GetDigestOf(Container const& seed, uint8 const* data, size_t len) + { + GenericHMAC hash(seed); + hash.UpdateData(data, len); + hash.Finalize(); + return hash.GetDigest(); + } + + template + static auto GetDigestOf(Container const& seed, Ts&&... pack) -> std::enable_if_t> || ...), Digest> + { + GenericHMAC hash(seed); + (hash.UpdateData(std::forward(pack)), ...); + hash.Finalize(); + return hash.GetDigest(); + } + + GenericHMAC(uint8 const* seed, size_t len) : _ctx(GenericHashImpl::MakeCTX()), _key(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, seed, len)) + { + int result = EVP_DigestSignInit(_ctx, nullptr, HashCreator(), nullptr, _key); + ASSERT(result == 1); + } + template + GenericHMAC(Container const& container) : GenericHMAC(std::data(container), std::size(container)) {} + + GenericHMAC(GenericHMAC const& right) : _ctx(GenericHashImpl::MakeCTX()) + { + *this = right; + } + + GenericHMAC(GenericHMAC&& right) noexcept + { + *this = std::move(right); + } + + ~GenericHMAC() + { + GenericHashImpl::DestroyCTX(_ctx); + _ctx = nullptr; + EVP_PKEY_free(_key); + _key = nullptr; + } + + GenericHMAC& operator=(GenericHMAC const& right) + { + if (this == &right) + return *this; + + int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx); + ASSERT(result == 1); + _key = right._key; // EVP_PKEY uses reference counting internally, just copy the pointer + EVP_PKEY_up_ref(_key); // Bump reference count for PKEY, as every instance of this class holds two references to PKEY and destructor decrements it twice + _digest = right._digest; + return *this; + } + + GenericHMAC& operator=(GenericHMAC&& right) noexcept + { + if (this == &right) + return *this; + + _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX()); + _key = std::exchange(right._key, EVP_PKEY_new()); + _digest = std::exchange(right._digest, Digest{}); + return *this; + } + + void UpdateData(uint8 const* data, size_t len) + { + int result = EVP_DigestSignUpdate(_ctx, data, len); + ASSERT(result == 1); + } + void UpdateData(std::string_view str) { UpdateData(reinterpret_cast(str.data()), str.size()); } + void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + template + void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); } + + void Finalize() + { + size_t length = DIGEST_LENGTH; + int result = EVP_DigestSignFinal(_ctx, _digest.data(), &length); + ASSERT(result == 1); + ASSERT(length == DIGEST_LENGTH); + } + + Digest const& GetDigest() const { return _digest; } + private: + EVP_MD_CTX* _ctx; + EVP_PKEY* _key; + Digest _digest = { }; + }; +} + +namespace Trinity::Crypto +{ + using HMAC_SHA1 = Trinity::Impl::GenericHMAC; + using HMAC_SHA256 = Trinity::Impl::GenericHMAC; +} +#endif diff --git a/src/common/Cryptography/HmacHash.cpp b/src/common/Cryptography/HmacHash.cpp deleted file mode 100644 index 192610a7dc..0000000000 --- a/src/common/Cryptography/HmacHash.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "HmacHash.h" -#include "BigNumber.h" -#include "Errors.h" -#include - -template -HmacHash::HmacHash(uint32 len, uint8 const* seed) : _ctx(EVP_MD_CTX_create()), _key(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, seed, len)) -{ - EVP_DigestSignInit(_ctx, nullptr, HashCreator(), nullptr, _key); - memset(_digest, 0, DigestLength); -} - -template -HmacHash::~HmacHash() -{ - EVP_MD_CTX_destroy(_ctx); - _ctx = nullptr; - EVP_PKEY_free(_key); - _key = nullptr; -} - -template -void HmacHash::UpdateData(std::string const& str) -{ - EVP_DigestSignUpdate(_ctx, reinterpret_cast(str.c_str()), str.length()); -} - -template -void HmacHash::UpdateData(uint8 const* data, size_t len) -{ - EVP_DigestSignUpdate(_ctx, data, len); -} - -template -void HmacHash::Finalize() -{ - size_t length = DigestLength; - EVP_DigestSignFinal(_ctx, _digest, &length); - ASSERT(length == DigestLength); -} - -template -uint8* HmacHash::ComputeHash(BigNumber* bn) -{ - EVP_DigestSignUpdate(_ctx, bn->AsByteArray().get(), bn->GetNumBytes()); - Finalize(); - return _digest; -} - -template class TC_COMMON_API HmacHash; -template class TC_COMMON_API HmacHash; diff --git a/src/common/Cryptography/HmacHash.h b/src/common/Cryptography/HmacHash.h deleted file mode 100644 index 8e8de8ae3f..0000000000 --- a/src/common/Cryptography/HmacHash.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef _AUTH_HMAC_H -#define _AUTH_HMAC_H - -#include "Define.h" -#include -#include -#include - -class BigNumber; - -#define SEED_KEY_SIZE 16 - -typedef EVP_MD const* (*HashCreateFn)(); - -template -class TC_COMMON_API HmacHash -{ - public: - HmacHash(uint32 len, uint8 const* seed); - ~HmacHash(); - void UpdateData(std::string const& str); - void UpdateData(uint8 const* data, size_t len); - void Finalize(); - uint8* ComputeHash(BigNumber* bn); - uint8* GetDigest() { return _digest; } - uint32 GetLength() const { return DigestLength; } - private: - EVP_MD_CTX* _ctx; - EVP_PKEY* _key; - uint8 _digest[DigestLength]; -}; - -typedef HmacHash HmacSha1; -typedef HmacHash HmacSha256; - -#endif diff --git a/src/common/Cryptography/SHA1.cpp b/src/common/Cryptography/SHA1.cpp deleted file mode 100644 index a9eab8ed0a..0000000000 --- a/src/common/Cryptography/SHA1.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "SHA1.h" -#include "BigNumber.h" -#include "Util.h" -#include -#include -#include - -SHA1Hash::SHA1Hash() noexcept -{ - m_ctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex(m_ctx, EVP_sha1(), nullptr); -} - -SHA1Hash::SHA1Hash(const SHA1Hash &other) : SHA1Hash() // copy -{ - EVP_MD_CTX_copy_ex(m_ctx, other.m_ctx); - std::memcpy(m_digest, other.m_digest, SHA_DIGEST_LENGTH); -} - -SHA1Hash::SHA1Hash(SHA1Hash &&other) noexcept : SHA1Hash() // move -{ - Swap(other); -} - -SHA1Hash &SHA1Hash::operator=(SHA1Hash other) // assign -{ - Swap(other); - return *this; -} - -SHA1Hash::~SHA1Hash() -{ - EVP_MD_CTX_free(m_ctx); -} - -void SHA1Hash::Swap(SHA1Hash &other) throw() -{ - std::swap(m_ctx, other.m_ctx); - std::swap(m_digest, other.m_digest); -} - -void SHA1Hash::UpdateData(const uint8 *dta, int len) -{ - EVP_DigestUpdate(m_ctx, dta, len); -} - -void SHA1Hash::UpdateData(const std::string &str) -{ - UpdateData((uint8 const*)str.c_str(), str.length()); -} - -void SHA1Hash::UpdateBigNumbers(BigNumber* bn0, ...) -{ - va_list v; - BigNumber* bn; - - va_start(v, bn0); - bn = bn0; - while (bn) - { - UpdateData(bn->AsByteArray().get(), bn->GetNumBytes()); - bn = va_arg(v, BigNumber*); - } - va_end(v); -} - -void SHA1Hash::Initialize() -{ - EVP_DigestInit(m_ctx, EVP_sha1()); -} - -void SHA1Hash::Finalize(void) -{ - uint32 length = SHA_DIGEST_LENGTH; - EVP_DigestFinal_ex(m_ctx, m_digest, &length); -} - -std::string CalculateSHA1Hash(std::string const& content) -{ - EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex(mdctx, EVP_sha1(), nullptr); - EVP_DigestUpdate(mdctx, content.c_str(), content.size()); - uint8 digest[SHA_DIGEST_LENGTH]; - uint32 shaDigestLength = SHA_DIGEST_LENGTH; - EVP_DigestFinal_ex(mdctx, digest, &shaDigestLength); - EVP_MD_CTX_free(mdctx); - - return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); -} diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h deleted file mode 100644 index e6ccf88cbe..0000000000 --- a/src/common/Cryptography/SHA1.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef _AUTH_SHA1_H -#define _AUTH_SHA1_H - -#include "Define.h" -#include -#include -#include - -class BigNumber; - -class TC_COMMON_API SHA1Hash -{ - public: - SHA1Hash() noexcept; - SHA1Hash(SHA1Hash const& other); // copy - SHA1Hash(SHA1Hash&& other) noexcept; // move - SHA1Hash &operator=(SHA1Hash other); // assign - ~SHA1Hash(); - - void Swap(SHA1Hash& other) throw(); - friend void Swap(SHA1Hash& left, SHA1Hash &right) { left.Swap(right); } - - void UpdateBigNumbers(BigNumber* bn0, ...); - - void UpdateData(const uint8* dta, int len); - void UpdateData(const std::string& str); - - void Initialize(); - void Finalize(); - - uint8 *GetDigest(void) { return m_digest; } - int GetLength() const { return SHA_DIGEST_LENGTH; } - - private: - EVP_MD_CTX* m_ctx; - uint8 m_digest[SHA_DIGEST_LENGTH]; -}; - -/// Returns the SHA1 hash of the given content as hex string. -TC_COMMON_API std::string CalculateSHA1Hash(std::string const& content); - -#endif diff --git a/src/common/Cryptography/SHA256.cpp b/src/common/Cryptography/SHA256.cpp deleted file mode 100644 index 3cceeb21d3..0000000000 --- a/src/common/Cryptography/SHA256.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "SHA256.h" -#include "BigNumber.h" -#include "Errors.h" -#include -#include - -SHA256Hash::SHA256Hash() : _ctx(EVP_MD_CTX_create()) -{ - EVP_DigestInit_ex(_ctx, EVP_sha256(), nullptr); - memset(mDigest, 0, SHA256_DIGEST_LENGTH * sizeof(uint8)); -} - -SHA256Hash::~SHA256Hash() -{ - EVP_MD_CTX_destroy(_ctx); - _ctx = nullptr; -} - -void SHA256Hash::UpdateData(const uint8 *dta, int len) -{ - EVP_DigestUpdate(_ctx, dta, len); -} - -void SHA256Hash::UpdateData(const std::string &str) -{ - UpdateData((uint8 const*)str.c_str(), str.length()); -} - -void SHA256Hash::UpdateBigNumbers(BigNumber* bn0, ...) -{ - va_list v; - BigNumber* bn; - - va_start(v, bn0); - bn = bn0; - while (bn) - { - UpdateData(bn->AsByteArray().get(), bn->GetNumBytes()); - bn = va_arg(v, BigNumber*); - } - va_end(v); -} - -void SHA256Hash::Initialize() -{ - EVP_DigestInit_ex(_ctx, EVP_sha256(), nullptr); -} - -void SHA256Hash::Finalize(void) -{ - uint32 length = SHA256_DIGEST_LENGTH; - EVP_DigestFinal_ex(_ctx, mDigest, &length); - ASSERT(length == SHA256_DIGEST_LENGTH); -} diff --git a/src/common/Cryptography/SHA256.h b/src/common/Cryptography/SHA256.h deleted file mode 100644 index e0298d1052..0000000000 --- a/src/common/Cryptography/SHA256.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef SHA256_h__ -#define SHA256_h__ - -#include "Define.h" -#include -#include -#include - -class BigNumber; - -class TC_COMMON_API SHA256Hash -{ - public: - SHA256Hash(); - ~SHA256Hash(); - - void UpdateBigNumbers(BigNumber* bn0, ...); - - void UpdateData(const uint8 *dta, int len); - void UpdateData(const std::string &str); - - void Initialize(); - void Finalize(); - - uint8 *GetDigest(void) { return mDigest; }; - int GetLength(void) const { return SHA256_DIGEST_LENGTH; }; - - private: - EVP_MD_CTX* _ctx; - uint8 mDigest[SHA256_DIGEST_LENGTH]; -}; - -#endif // SHA256_h__ diff --git a/src/common/Cryptography/SessionKeyGenerator.h b/src/common/Cryptography/SessionKeyGenerator.h new file mode 100644 index 0000000000..662da97d42 --- /dev/null +++ b/src/common/Cryptography/SessionKeyGenerator.h @@ -0,0 +1,62 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_SESSIONKEYGENERATOR_HPP +#define TRINITY_SESSIONKEYGENERATOR_HPP + +#include +#include "CryptoHash.h" + +template +class SessionKeyGenerator +{ +public: + template + SessionKeyGenerator(C const& buf) : + o0it(o0.begin()) + { + uint8 const* data = std::data(buf); + size_t const len = std::size(buf); + size_t const halflen = (len / 2); + + o1 = Hash::GetDigestOf(data, halflen); + o2 = Hash::GetDigestOf(data + halflen, len - halflen); + o0 = Hash::GetDigestOf(o1, o0, o2); + } + + void Generate(uint8* buf, uint32 sz) + { + for (uint32 i = 0; i < sz; ++i) + { + if (o0it == o0.end()) + { + o0 = Hash::GetDigestOf(o1, o0, o2); + o0it = o0.begin(); + } + + buf[i] = *(o0it++); + } + } + +private: + typename Hash::Digest o0 = { }; + typename Hash::Digest o1 = { }; + typename Hash::Digest o2 = { }; + typename Hash::Digest::const_iterator o0it; +}; + +#endif diff --git a/src/common/Cryptography/TOTP.cpp b/src/common/Cryptography/TOTP.cpp new file mode 100644 index 0000000000..b599d2ff4a --- /dev/null +++ b/src/common/Cryptography/TOTP.cpp @@ -0,0 +1,51 @@ +/* +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "TOTP.h" +#include +#include +#include + +constexpr std::size_t Trinity::Crypto::TOTP::RECOMMENDED_SECRET_LENGTH; +static constexpr uint32 TOTP_INTERVAL = 30; +static constexpr uint32 HMAC_RESULT_SIZE = 20; +/*static*/ uint32 Trinity::Crypto::TOTP::GenerateToken(Secret const& secret, time_t timestamp) +{ + timestamp /= TOTP_INTERVAL; + unsigned char challenge[8]; + for (int i = 8; i--; timestamp >>= 8) + challenge[i] = timestamp; + + unsigned char digest[HMAC_RESULT_SIZE]; + uint32 digestSize = HMAC_RESULT_SIZE; + HMAC(EVP_sha1(), secret.data(), secret.size(), challenge, 8, digest, &digestSize); + + uint32 offset = digest[19] & 0xF; + uint32 truncated = (digest[offset] << 24) | (digest[offset + 1] << 16) | (digest[offset + 2] << 8) | (digest[offset + 3]); + truncated &= 0x7FFFFFFF; + return (truncated % 1000000); +} + +/*static*/ bool Trinity::Crypto::TOTP::ValidateToken(Secret const& secret, uint32 token) +{ + time_t now = time(nullptr); + return ( + (token == GenerateToken(secret, now - TOTP_INTERVAL)) || + (token == GenerateToken(secret, now)) || + (token == GenerateToken(secret, now + TOTP_INTERVAL)) + ); +} diff --git a/src/server/bnetserver/Packets/PresencePackets.cpp b/src/common/Cryptography/TOTP.h similarity index 56% rename from src/server/bnetserver/Packets/PresencePackets.cpp rename to src/common/Cryptography/TOTP.h index b538ae74dd..b3cf994608 100644 --- a/src/server/bnetserver/Packets/PresencePackets.cpp +++ b/src/common/Cryptography/TOTP.h @@ -1,5 +1,5 @@ /* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,24 +15,23 @@ * with this program. If not, see . */ -#include "Session.h" -#include "PresencePackets.h" +#ifndef TRINITY_TOTP_H +#define TRINITY_TOTP_H -void Battlenet::Presence::UpdateRequest::Read() +#include "Define.h" +#include +#include + +namespace Trinity::Crypto { + struct TC_COMMON_API TOTP + { + static constexpr size_t RECOMMENDED_SECRET_LENGTH = 20; + using Secret = std::vector; + static uint32 GenerateToken(Secret const& key, time_t timestamp); + static bool ValidateToken(Secret const& key, uint32 token); + }; } -std::string Battlenet::Presence::UpdateRequest::ToString() const -{ - return "Battlenet::Presence::UpdateRequest"; -} - -void Battlenet::Presence::StatisticSubscribe::Read() -{ -} - -std::string Battlenet::Presence::StatisticSubscribe::ToString() const -{ - return "Battlenet::Presence::StatisticSubscribe"; -} +#endif diff --git a/src/common/Cryptography/WardenKeyGeneration.h b/src/common/Cryptography/WardenKeyGeneration.h deleted file mode 100644 index 6f507dd58c..0000000000 --- a/src/common/Cryptography/WardenKeyGeneration.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "SHA1.h" - -#include - -#ifndef _WARDEN_KEY_GENERATION_H -#define _WARDEN_KEY_GENERATION_H - -class SHA1Randx -{ -public: - SHA1Randx(uint8* buff, uint32 size) - { - uint32 halfSize = size / 2; - - sh.Initialize(); - sh.UpdateData(buff, halfSize); - sh.Finalize(); - - memcpy(o1, sh.GetDigest(), 20); - - sh.Initialize(); - sh.UpdateData(buff + halfSize, size - halfSize); - sh.Finalize(); - - memcpy(o2, sh.GetDigest(), 20); - - memset(o0, 0x00, 20); - - FillUp(); - } - - void Generate(uint8* buf, uint32 sz) - { - for (uint32 i = 0; i < sz; ++i) - { - if (taken == 20) - FillUp(); - - buf[i] = o0[taken]; - taken++; - } - } - -private: - void FillUp() - { - sh.Initialize(); - sh.UpdateData(o1, 20); - sh.UpdateData(o0, 20); - sh.UpdateData(o2, 20); - sh.Finalize(); - - memcpy(o0, sh.GetDigest(), 20); - - taken = 0; - } - - SHA1Hash sh; - uint32 taken; - uint8 o0[20], o1[20], o2[20]; -}; - -#endif diff --git a/src/common/Define.h b/src/common/Define.h index 73248a536d..a049d90fb5 100644 --- a/src/common/Define.h +++ b/src/common/Define.h @@ -121,12 +121,6 @@ # define TC_SHARED_API TC_API_IMPORT #endif -#ifdef TRINITY_API_EXPORT_IPC -# define TC_IPC_API TC_API_EXPORT -#else -# define TC_IPC_API TC_API_IMPORT -#endif - #ifdef TRINITY_API_EXPORT_GAME # define TC_GAME_API TC_API_EXPORT #else diff --git a/src/common/Encoding/Base32.cpp b/src/common/Encoding/Base32.cpp new file mode 100644 index 0000000000..a091ed1ca1 --- /dev/null +++ b/src/common/Encoding/Base32.cpp @@ -0,0 +1,55 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Base32.h" +#include "BaseEncoding.h" +#include "Errors.h" + +struct B32Impl +{ + static constexpr std::size_t BITS_PER_CHAR = 5; + + static constexpr char PADDING = '='; + static constexpr char Encode(uint8 v) + { + ASSERT(v < 0x20); + if (v < 26) return 'A'+v; + else return '2' + (v-26); + } + + static constexpr uint8 DECODE_ERROR = 0xff; + static constexpr uint8 Decode(uint8 v) + { + if (v == '0') return Decode('O'); + if (v == '1') return Decode('l'); + if (v == '8') return Decode('B'); + if (('A' <= v) && (v <= 'Z')) return (v-'A'); + if (('a' <= v) && (v <= 'z')) return (v-'a'); + if (('2' <= v) && (v <= '7')) return (v-'2')+26; + return DECODE_ERROR; + } +}; + +/*static*/ std::string Trinity::Encoding::Base32::Encode(std::vector const& data) +{ + return Trinity::Impl::GenericBaseEncoding::Encode(data); +} + +/*static*/ Optional> Trinity::Encoding::Base32::Decode(std::string const& data) +{ + return Trinity::Impl::GenericBaseEncoding::Decode(data); +} diff --git a/src/server/bnetserver/Packets/BitStream.cpp b/src/common/Encoding/Base32.h similarity index 68% rename from src/server/bnetserver/Packets/BitStream.cpp rename to src/common/Encoding/Base32.h index 8098691661..23705ddfeb 100644 --- a/src/server/bnetserver/Packets/BitStream.cpp +++ b/src/common/Encoding/Base32.h @@ -15,16 +15,24 @@ * with this program. If not, see . */ -#include "BitStream.h" +#ifndef TRINITY_BASE32_H +#define TRINITY_BASE32_H -template<> -bool Battlenet::BitStream::Read(uint32 /*bitCount*/) +#include "Define.h" +#include "Optional.h" +#include +#include + +namespace Trinity { - return Read(1) != 0; +namespace Encoding +{ +struct TC_COMMON_API Base32 +{ + static std::string Encode(std::vector const& data); + static Optional> Decode(std::string const& data); +}; +} } -template<> -void Battlenet::BitStream::Write(bool value, uint32 /*bitCount*/) -{ - Write(value ? 1 : 0, 1); -} +#endif diff --git a/src/common/Encoding/Base64.cpp b/src/common/Encoding/Base64.cpp new file mode 100644 index 0000000000..1b1860375e --- /dev/null +++ b/src/common/Encoding/Base64.cpp @@ -0,0 +1,57 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Base64.h" +#include "BaseEncoding.h" +#include "Errors.h" + +struct B64Impl +{ + static constexpr std::size_t BITS_PER_CHAR = 6; + + static constexpr char PADDING = '='; + static constexpr char Encode(uint8 v) + { + ASSERT(v < 0x40); + if (v < 26) return 'A' + v; + if (v < 52) return 'a' + (v - 26); + if (v < 62) return '0' + (v - 52); + if (v == 62) return '+'; + else return '/'; + } + + static constexpr uint8 DECODE_ERROR = 0xff; + static constexpr uint8 Decode(uint8 v) + { + if (('A' <= v) && (v <= 'Z')) return (v - 'A'); + if (('a' <= v) && (v <= 'z')) return (v - 'a') + 26; + if (('0' <= v) && (v <= '9')) return (v - '0') + 52; + if (v == '+') return 62; + if (v == '/') return 63; + return DECODE_ERROR; + } +}; + +/*static*/ std::string Trinity::Encoding::Base64::Encode(std::vector const& data) +{ + return Trinity::Impl::GenericBaseEncoding::Encode(data); +} + +/*static*/ Optional> Trinity::Encoding::Base64::Decode(std::string const& data) +{ + return Trinity::Impl::GenericBaseEncoding::Decode(data); +} diff --git a/src/server/bnetserver/Packets/SupportPackets.h b/src/common/Encoding/Base64.h similarity index 68% rename from src/server/bnetserver/Packets/SupportPackets.h rename to src/common/Encoding/Base64.h index 6173131886..43ef5da65e 100644 --- a/src/server/bnetserver/Packets/SupportPackets.h +++ b/src/common/Encoding/Base64.h @@ -15,20 +15,24 @@ * with this program. If not, see . */ -#ifndef SupportPackets_h__ -#define SupportPackets_h__ +#ifndef TRINITY_BASE64_H +#define TRINITY_BASE64_H -#include "PacketsBase.h" +#include "Define.h" +#include "Optional.h" +#include +#include -namespace Battlenet +namespace Trinity { - namespace Support - { - enum Opcode - { - CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented - }; - } +namespace Encoding +{ +struct TC_COMMON_API Base64 +{ + static std::string Encode(std::vector const& data); + static Optional> Decode(std::string const& data); +}; +} } -#endif // SupportPackets_h__ +#endif diff --git a/src/common/Encoding/BaseEncoding.h b/src/common/Encoding/BaseEncoding.h new file mode 100644 index 0000000000..7dfe3fd499 --- /dev/null +++ b/src/common/Encoding/BaseEncoding.h @@ -0,0 +1,160 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_BASE_ENCODING_HPP +#define TRINITY_BASE_ENCODING_HPP + +#include "Define.h" +#include "Optional.h" +#include +#include +#include + +namespace Trinity +{ +namespace Impl +{ +template +struct GenericBaseEncoding +{ + static constexpr std::size_t BITS_PER_CHAR = Encoding::BITS_PER_CHAR; + static constexpr std::size_t PAD_TO = std::lcm(8u, BITS_PER_CHAR); + + static_assert(BITS_PER_CHAR < 8, "Encoding parameters are invalid"); + + static constexpr uint8 DECODE_ERROR = Encoding::DECODE_ERROR; + static constexpr char PADDING = Encoding::PADDING; + + static constexpr std::size_t EncodedSize(std::size_t size) + { + size *= 8; // bits in input + if (size % PAD_TO) // pad to boundary + size += (PAD_TO - (size % PAD_TO)); + return (size / BITS_PER_CHAR); + } + + static constexpr std::size_t DecodedSize(std::size_t size) + { + size *= BITS_PER_CHAR; // bits in input + if (size % PAD_TO) // pad to boundary + size += (PAD_TO - (size % PAD_TO)); + return (size / 8); + } + + static std::string Encode(std::vector const& data) + { + auto it = data.begin(), end = data.end(); + if (it == end) + return ""; + + std::string s; + s.reserve(EncodedSize(data.size())); + + uint8 bitsLeft = 8; // in current byte + do + { + uint8 thisC = 0; + if (bitsLeft >= BITS_PER_CHAR) + { + bitsLeft -= BITS_PER_CHAR; + thisC = ((*it >> bitsLeft) & ((1 << BITS_PER_CHAR)-1)); + if (!bitsLeft) + { + ++it; + bitsLeft = 8; + } + } + else + { + thisC = (*it & ((1 << bitsLeft) - 1)) << (BITS_PER_CHAR - bitsLeft); + bitsLeft += (8 - BITS_PER_CHAR); + if ((++it) != end) + thisC |= (*it >> bitsLeft); + } + s.append(1, Encoding::Encode(thisC)); + } while (it != end); + + while (bitsLeft != 8) + { + if (bitsLeft > BITS_PER_CHAR) + bitsLeft -= BITS_PER_CHAR; + else + bitsLeft += (8 - BITS_PER_CHAR); + s.append(1, PADDING); + } + + return s; + } + + static Optional> Decode(std::string const& data) + { + auto it = data.begin(), end = data.end(); + if (it == end) + return std::vector(); + + std::vector v; + v.reserve(DecodedSize(data.size())); + + uint8 currentByte = 0; + uint8 bitsLeft = 8; // in current byte + while ((it != end) && (*it != PADDING)) + { + uint8 cur = Encoding::Decode(*(it++)); + if (cur == DECODE_ERROR) + return {}; + + if (bitsLeft > BITS_PER_CHAR) + { + bitsLeft -= BITS_PER_CHAR; + currentByte |= (cur << bitsLeft); + } + else + { + bitsLeft = BITS_PER_CHAR - bitsLeft; // in encoded char + currentByte |= (cur >> bitsLeft); + v.push_back(currentByte); + currentByte = (cur & ((1 << bitsLeft) - 1)); + bitsLeft = 8 - bitsLeft; // in byte again + currentByte <<= bitsLeft; + } + } + + if (currentByte) + return {}; // decode error, trailing non-zero bits + + // process padding + while ((it != end) && (*it == PADDING) && (bitsLeft != 8)) + { + if (bitsLeft > BITS_PER_CHAR) + bitsLeft -= BITS_PER_CHAR; + else + bitsLeft += (8 - BITS_PER_CHAR); + ++it; + } + + // ok, all padding should be consumed, and we should be at end of string + if (it == end) + return v; + + // anything else is an error + return {}; + } +}; +} +} + +#endif diff --git a/src/common/IPLocation/IPLocation.cpp b/src/common/IPLocation/IPLocation.cpp index 92fdc73e9b..9c32aca0c1 100644 --- a/src/common/IPLocation/IPLocation.cpp +++ b/src/common/IPLocation/IPLocation.cpp @@ -21,6 +21,7 @@ #include "Errors.h" #include "IpAddress.h" #include "Log.h" +#include #include #include @@ -115,4 +116,3 @@ IpLocationStore* IpLocationStore::Instance() static IpLocationStore instance; return &instance; } - diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 10e8bf16d5..ed22356cff 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -584,7 +584,7 @@ bool Utf8ToUpperOnlyLatin(std::string& utf8String) return WStrToUtf8(wstr, utf8String); } -std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */) +std::string Trinity::Impl::ByteArrayToHexStr(uint8 const* bytes, size_t arrayLen, bool reverse /* = false */) { int32 init = 0; int32 end = arrayLen; @@ -608,19 +608,17 @@ std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse return ss.str(); } -void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/) +void Trinity::Impl::HexStrToByteArray(std::string_view str, uint8* out, size_t outlen, bool reverse /*= false*/) { - // string must have even number of characters - if (str.length() & 1) - return; + ASSERT(str.size() == (2 * outlen)); int32 init = 0; - int32 end = str.length(); + int32 end = int32(str.length()); int8 op = 1; if (reverse) { - init = str.length() - 2; + init = int32(str.length() - 2); end = -2; op = -1; } @@ -629,7 +627,7 @@ void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= fals for (int32 i = init; i != end; i += 2 * op) { char buffer[3] = { str[i], str[i + 1], '\0' }; - out[j++] = strtoul(buffer, nullptr, 16); + out[j++] = uint8(strtoul(buffer, nullptr, 16)); } } diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index d75c7c3169..11fc403b78 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -302,8 +302,39 @@ TC_COMMON_API bool IsIPAddress(char const* ipaddress); TC_COMMON_API uint32 CreatePIDFile(std::string const& filename); TC_COMMON_API uint32 GetPID(); -TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); -TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false); +namespace Trinity::Impl +{ + TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, size_t length, bool reverse = false); + TC_COMMON_API void HexStrToByteArray(std::string_view str, uint8* out, size_t outlen, bool reverse = false); +} + +template +std::string ByteArrayToHexStr(Container const& c, bool reverse = false) +{ + return Trinity::Impl::ByteArrayToHexStr(std::data(c), std::size(c), reverse); +} + +template +void HexStrToByteArray(std::string_view str, std::array& buf, bool reverse = false) +{ + Trinity::Impl::HexStrToByteArray(str, buf.data(), Size, reverse); +} +template +std::array HexStrToByteArray(std::string_view str, bool reverse = false) +{ + std::array arr; + HexStrToByteArray(str, arr, reverse); + return arr; +} + +inline std::vector HexStrToByteVector(std::string_view str, bool reverse = false) +{ + std::vector buf; + size_t const sz = (str.size() / 2); + buf.resize(sz); + Trinity::Impl::HexStrToByteArray(str, buf.data(), sz, reverse); + return buf; +} TC_COMMON_API bool StringToBool(std::string const& str); diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index aba4edbad8..350a99ad4b 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -29,9 +29,7 @@ endif(WIN32) add_subdirectory(database) add_subdirectory(shared) -add_subdirectory(ipc) add_subdirectory(authserver) -add_subdirectory(bnetserver) add_subdirectory(game) add_subdirectory(scripts) add_subdirectory(worldserver) diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp index 98d61ce2c4..93b87958c9 100644 --- a/src/server/authserver/Authentication/AuthCodes.cpp +++ b/src/server/authserver/Authentication/AuthCodes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,72 +16,24 @@ */ #include "AuthCodes.h" -#include +#include "ClientBuildInfo.h" namespace AuthHelper { - static RealmBuildInfo const PostBcAcceptedClientBuilds[] = - { - {15595, 4, 3, 4, ' '}, - {14545, 4, 2, 2, ' '}, - {13623, 4, 0, 6, 'a'}, - {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build - {12340, 3, 3, 5, 'a'}, - {11723, 3, 3, 3, 'a'}, - {11403, 3, 3, 2, ' '}, - {11159, 3, 3, 0, 'a'}, - {10505, 3, 2, 2, 'a'}, - {9947, 3, 1, 3, ' '}, - {8606, 2, 4, 3, ' '}, - {0, 0, 0, 0, ' '} // terminator - }; + constexpr static uint32 MAX_PRE_BC_CLIENT_BUILD = 6141; - static RealmBuildInfo const PreBcAcceptedClientBuilds[] = + bool IsPreBCAcceptedClientBuild(uint32 build) { - {6141, 1, 12, 3, ' '}, - {6005, 1, 12, 2, ' '}, - {5875, 1, 12, 1, ' '}, - {0, 0, 0, 0, ' '} // terminator - }; - - bool IsPreBCAcceptedClientBuild(int build) - { - for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i) - if (PreBcAcceptedClientBuilds[i].Build == build) - return true; - - return false; + return build <= MAX_PRE_BC_CLIENT_BUILD && ClientBuild::GetBuildInfo(build); } - bool IsPostBCAcceptedClientBuild(int build) + bool IsPostBCAcceptedClientBuild(uint32 build) { - for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) - if (PostBcAcceptedClientBuilds[i].Build == build) - return true; - - return false; + return build > MAX_PRE_BC_CLIENT_BUILD && ClientBuild::GetBuildInfo(build); } - bool IsAcceptedClientBuild(int build) + bool IsAcceptedClientBuild(uint32 build) { - return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); - } - - RealmBuildInfo const* GetBuildInfo(int build) - { - for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) - if (PostBcAcceptedClientBuilds[i].Build == build) - return &PostBcAcceptedClientBuilds[i]; - - for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i) - if (PreBcAcceptedClientBuilds[i].Build == build) - return &PreBcAcceptedClientBuilds[i]; - - return nullptr; - } - - bool IsBuildSupportingBattlenet(int build) - { - return build >= 15595; + return ClientBuild::GetBuildInfo(build) != nullptr; } } diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index 80efec90c4..e1eea106b1 100644 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore - * Copyright (C) 2005-2009 MaNGOS + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -19,6 +18,9 @@ #ifndef _AUTHCODES_H #define _AUTHCODES_H +#include "Define.h" +#include + enum AuthResult { WOW_SUCCESS = 0x00, @@ -70,40 +72,6 @@ enum LoginResult LOGIN_LOCKED_ENFORCED = 0x10 }; -enum GameAccountFlags -{ - GAMEACCOUNT_FLAG_GM = 0x00000001, - GAMEACCOUNT_FLAG_NOKICK = 0x00000002, - GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004, - GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008, - GAMEACCOUNT_FLAG_CANCELLED = 0x00000010, - GAMEACCOUNT_FLAG_IGR = 0x00000020, - GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040, - GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080, - GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100, - GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200, - GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400, - GAMEACCOUNT_FLAG_REFERRAL = 0x00000800, - GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000, - GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000, - GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000, - GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000, - GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000, - GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000, - GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000, - GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000, - GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000, - GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000, - GAMEACCOUNT_FLAG_PROPASS = 0x00400000, - GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000, - GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000, - GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000, - GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000, - GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000, - GAMEACCOUNT_FLAG_DEMOS = 0x10000000, - GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000, -}; - enum ExpansionFlags { POST_BC_EXP_FLAG = 0x2, @@ -111,22 +79,13 @@ enum ExpansionFlags NO_VALID_EXP_FLAG = 0x0 }; -struct RealmBuildInfo -{ - int Build; - int MajorVersion; - int MinorVersion; - int BugfixVersion; - int HotfixVersion; -}; +struct RealmBuildInfo; namespace AuthHelper { - RealmBuildInfo const* GetBuildInfo(int build); - bool IsAcceptedClientBuild(int build); - bool IsPostBCAcceptedClientBuild(int build); - bool IsPreBCAcceptedClientBuild(int build); - bool IsBuildSupportingBattlenet(int build); + bool IsAcceptedClientBuild(uint32 build); + bool IsPostBCAcceptedClientBuild(uint32 build); + bool IsPreBCAcceptedClientBuild(uint32 build); } #endif diff --git a/src/server/authserver/Authentication/TOTP.cpp b/src/server/authserver/Authentication/TOTP.cpp deleted file mode 100644 index 76df2f653e..0000000000 --- a/src/server/authserver/Authentication/TOTP.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2008-2018 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "TOTP.h" -#include - -int base32_decode(char const* encoded, char* result, int bufSize) -{ - // Base32 implementation - // Copyright 2010 Google Inc. - // Author: Markus Gutschke - // Licensed under the Apache License, Version 2.0 - int buffer = 0; - int bitsLeft = 0; - int count = 0; - for (const char *ptr = encoded; count < bufSize && *ptr; ++ptr) - { - char ch = *ptr; - if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') - continue; - buffer <<= 5; - - // Deal with commonly mistyped characters - if (ch == '0') - ch = 'O'; - else if (ch == '1') - ch = 'L'; - else if (ch == '8') - ch = 'B'; - - // Look up one base32 digit - if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) - ch = (ch & 0x1F) - 1; - else if (ch >= '2' && ch <= '7') - ch -= '2' - 26; - else - return -1; - - buffer |= ch; - bitsLeft += 5; - if (bitsLeft >= 8) - { - result[count++] = buffer >> (bitsLeft - 8); - bitsLeft -= 8; - } - } - - if (count < bufSize) - result[count] = '\000'; - return count; -} - -#define HMAC_RES_SIZE 20 - -namespace TOTP -{ - unsigned int GenerateToken(char const* b32key) - { - size_t keySize = strlen(b32key); - int bufsize = (keySize + 7)/8*5; - char* encoded = new char[bufsize]; - memset(encoded, 0, bufsize); - unsigned int hmacResSize = HMAC_RES_SIZE; - unsigned char hmacRes[HMAC_RES_SIZE]; - unsigned long timestamp = time(nullptr)/30; - unsigned char challenge[8]; - - for (int i = 8; i--;timestamp >>= 8) - challenge[i] = timestamp; - - base32_decode(b32key, encoded, bufsize); - HMAC(EVP_sha1(), encoded, bufsize, challenge, 8, hmacRes, &hmacResSize); - unsigned int offset = hmacRes[19] & 0xF; - unsigned int truncHash = (hmacRes[offset] << 24) | (hmacRes[offset+1] << 16 )| (hmacRes[offset+2] << 8) | (hmacRes[offset+3]); - truncHash &= 0x7FFFFFFF; - - delete[] encoded; - - return truncHash % 1000000; - } -} diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index cc97860fe9..e9a3885a77 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -1,6 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore - * Copyright (C) 2005-2009 MaNGOS +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -37,6 +36,7 @@ #include "IPLocation.h" #include "MySQLThreading.h" #include "ProcessPriority.h" +#include "SharedDefines.h" #include "Util.h" #include #include @@ -79,6 +79,7 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, s int main(int argc, char** argv) { + Trinity::Impl::CurrentServerProcessHolder::_type = SERVER_PROCESS_AUTHSERVER; signal(SIGABRT, &Trinity::AbortHandler); auto configFile = fs::absolute(_TRINITY_REALM_CONFIG); diff --git a/src/server/authserver/PrecompiledHeaders/authPCH.h b/src/server/authserver/PrecompiledHeaders/authPCH.h index b2be78a8a3..3a87b9f335 100644 --- a/src/server/authserver/PrecompiledHeaders/authPCH.h +++ b/src/server/authserver/PrecompiledHeaders/authPCH.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/authserver/Realms/GruntRealmList.cpp b/src/server/authserver/Realms/GruntRealmList.cpp index 8064c4cc09..218de8439b 100644 --- a/src/server/authserver/Realms/GruntRealmList.cpp +++ b/src/server/authserver/Realms/GruntRealmList.cpp @@ -1,6 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore - * Copyright (C) 2005-2009 MaNGOS +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,6 +16,7 @@ */ #include "GruntRealmList.h" +#include "ClientBuildInfo.h" #include "DatabaseEnv.h" #include "DeadlineTimer.h" #include "IoContext.h" @@ -46,6 +46,7 @@ void GruntRealmList::Initialize(Trinity::Asio::IoContext& ioContext, uint32 upda _updateTimer = Trinity::make_unique(ioContext); _resolver = Trinity::make_unique(ioContext); + ClientBuild::LoadBuildInfo(); // Get the content of the realmlist table in the database UpdateRealms(boost::system::error_code()); } diff --git a/src/server/authserver/Realms/GruntRealmList.h b/src/server/authserver/Realms/GruntRealmList.h index ceefdcc5b1..df7b4d6ed2 100644 --- a/src/server/authserver/Realms/GruntRealmList.h +++ b/src/server/authserver/Realms/GruntRealmList.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore - * Copyright (C) 2005-2009 MaNGOS +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp index 31853d4f98..f0d1f1d3a9 100644 --- a/src/server/authserver/Server/AuthSession.cpp +++ b/src/server/authserver/Server/AuthSession.cpp @@ -1,40 +1,45 @@ /* -* Copyright (C) 2008-2018 TrinityCore -* Copyright (C) 2005-2009 MaNGOS -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at your -* option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along -* with this program. If not, see . -*/ + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ #include "AuthSession.h" +#include "AES.h" #include "AuthCodes.h" #include "ByteBuffer.h" +#include "ClientBuildInfo.h" #include "Config.h" +#include "CryptoGenerics.h" +#include "CryptoHash.h" +#include "CryptoRandom.h" #include "DatabaseEnv.h" -#include "Errors.h" #include "IPLocation.h" -#include "GruntRealmList.h" +#include "IoContext.h" #include "Log.h" -#include "Realm.h" -#include "SHA1.h" +#include "GruntRealmList.h" +#include "SecretMgr.h" #include "TOTP.h" #include "Util.h" +#include #include -#include using boost::asio::ip::tcp; +using boost::endian::little_uint16_t; +using boost::endian::little_uint32_t; -enum eAuthCmd +enum eAuthCmd : uint8 { AUTH_LOGON_CHALLENGE = 0x00, AUTH_LOGON_PROOF = 0x01, @@ -54,99 +59,135 @@ typedef struct AUTH_LOGON_CHALLENGE_C { uint8 cmd; uint8 error; - uint16 size; - uint8 gamename[4]; + little_uint16_t size; + little_uint32_t gamename; uint8 version1; uint8 version2; uint8 version3; - uint16 build; - uint8 platform[4]; - uint8 os[4]; - uint8 country[4]; - uint32 timezone_bias; - uint32 ip; + little_uint16_t build; + little_uint32_t platform; + little_uint32_t os; + little_uint32_t country; + little_uint32_t timezone_bias; + little_uint32_t ip; uint8 I_len; - uint8 I[1]; + char I[1]; } sAuthLogonChallenge_C; +static_assert(sizeof(sAuthLogonChallenge_C) == (1 + 1 + 2 + 4 + 1 + 1 + 1 + 2 + 4 + 4 + 4 + 4 + 4 + 1 + 1)); typedef struct AUTH_LOGON_PROOF_C { uint8 cmd; - uint8 A[32]; - uint8 M1[20]; - uint8 crc_hash[20]; + Trinity::Crypto::SRP6::EphemeralKey A; + Trinity::Crypto::SHA1::Digest clientM; + Trinity::Crypto::SHA1::Digest crc_hash; uint8 number_of_keys; uint8 securityFlags; } sAuthLogonProof_C; +static_assert(sizeof(sAuthLogonProof_C) == (1 + 32 + 20 + 20 + 1 + 1)); typedef struct AUTH_LOGON_PROOF_S { uint8 cmd; uint8 error; - uint8 M2[20]; - uint32 AccountFlags; - uint32 SurveyId; - uint16 unk3; + Trinity::Crypto::SHA1::Digest M2; + little_uint32_t AccountFlags; + little_uint32_t SurveyId; + little_uint16_t LoginFlags; } sAuthLogonProof_S; +static_assert(sizeof(sAuthLogonProof_S) == (1 + 1 + 20 + 4 + 4 + 2)); typedef struct AUTH_LOGON_PROOF_S_OLD { uint8 cmd; uint8 error; - uint8 M2[20]; - uint32 unk2; + Trinity::Crypto::SHA1::Digest M2; + little_uint32_t unk2; } sAuthLogonProof_S_Old; +static_assert(sizeof(sAuthLogonProof_S_Old) == (1 + 1 + 20 + 4)); typedef struct AUTH_RECONNECT_PROOF_C { uint8 cmd; uint8 R1[16]; - uint8 R2[20]; - uint8 R3[20]; + Trinity::Crypto::SHA1::Digest R2, R3; uint8 number_of_keys; } sAuthReconnectProof_C; +static_assert(sizeof(sAuthReconnectProof_C) == (1 + 16 + 20 + 20 + 1)); #pragma pack(pop) -enum class BufferSizes : uint32 -{ - SRP_6_V = 0x20, - SRP_6_S = 0x20, -}; +std::array VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B, 0x21, 0x57, 0xFC, 0x37, 0x3F, 0xB3, 0x69, 0xCD, 0xD2, 0xF1 } }; #define MAX_ACCEPTED_CHALLENGE_SIZE (sizeof(AUTH_LOGON_CHALLENGE_C) + 16) #define AUTH_LOGON_CHALLENGE_INITIAL_SIZE 4 #define REALM_LIST_PACKET_SIZE 5 -std::unordered_map AuthSession::InitHandlers() +struct AuthHandler { - std::unordered_map handlers; + eAuthCmd cmd = { }; + AuthStatus status = STATUS_CLOSED; + size_t packetSize = 0; + bool (*handler)(AuthSession*) = nullptr; +}; - handlers[AUTH_LOGON_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleLogonChallenge }; - handlers[AUTH_LOGON_PROOF] = { STATUS_LOGON_PROOF, sizeof(AUTH_LOGON_PROOF_C), &AuthSession::HandleLogonProof }; - handlers[AUTH_RECONNECT_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleReconnectChallenge }; - handlers[AUTH_RECONNECT_PROOF] = { STATUS_RECONNECT_PROOF, sizeof(AUTH_RECONNECT_PROOF_C), &AuthSession::HandleReconnectProof }; - handlers[REALM_LIST] = { STATUS_AUTHED, REALM_LIST_PACKET_SIZE, &AuthSession::HandleRealmList }; +class AuthHandlerTable +{ +public: + consteval AuthHandlerTable() + { + InitializeHandler(AUTH_LOGON_CHALLENGE, STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, [](AuthSession* session) { return session->HandleLogonChallenge(); }); + InitializeHandler(AUTH_LOGON_PROOF, STATUS_LOGON_PROOF, sizeof(AUTH_LOGON_PROOF_C), [](AuthSession* session) { return session->HandleLogonProof(); }); + InitializeHandler(AUTH_RECONNECT_CHALLENGE, STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, [](AuthSession* session) { return session->HandleReconnectChallenge(); }); + InitializeHandler(AUTH_RECONNECT_PROOF, STATUS_RECONNECT_PROOF, sizeof(AUTH_RECONNECT_PROOF_C), [](AuthSession* session) { return session->HandleReconnectProof(); }); + InitializeHandler(REALM_LIST, STATUS_AUTHED, REALM_LIST_PACKET_SIZE, [](AuthSession* session) { return session->HandleRealmList(); }); + InitializeHandler(XFER_ACCEPT, STATUS_XFER, 1, [](AuthSession* session) { return session->HandleXferAccept(); }); + InitializeHandler(XFER_RESUME, STATUS_XFER, 9, [](AuthSession* session) { return session->HandleXferResume(); }); + InitializeHandler(XFER_CANCEL, STATUS_XFER, 1, [](AuthSession* session) { return session->HandleXferCancel(); }); + } - return handlers; -} + constexpr AuthHandler const* operator[](eAuthCmd cmd) const + { + std::size_t index = GetOpcodeArrayIndex(cmd); + if (index >= _handlers.size()) + return nullptr; -std::unordered_map const Handlers = AuthSession::InitHandlers(); + AuthHandler const& handler = _handlers[index]; + if (handler.cmd != cmd) + return nullptr; + + return &handler; + } + +private: + // perfect hash function for all valid values of eAuthCmd + inline static constexpr std::size_t GetOpcodeArrayIndex(eAuthCmd c) + { + return (c & 0x7) + ((c & 0x10) >> 2) + ((c & 0x20) >> 5); + } + + constexpr void InitializeHandler(eAuthCmd cmd, AuthStatus status, std::size_t packetSize, bool (*handler)(AuthSession*)) + { + _handlers[GetOpcodeArrayIndex(cmd)] = { .cmd = cmd, .status = status, .packetSize = packetSize, .handler = handler, }; + } + + std::array _handlers; +} inline constexpr Handlers; void AccountInfo::LoadResult(Field* fields) { // 0 1 2 3 4 5 6 //SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, - // 7 8 9 10 11 12 - // ab.unbandate = ab.bandate, aa.gmlevel, a.token_key, a.sha_pass_hash, a.v, a.s - //FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ? + // 7 8 + // ab.unbandate = ab.bandate, aa.SecurityLevel (, more query-specific fields) + //FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ? Id = fields[0].GetUInt32(); - Login = fields[1].GetString(); + Login = fields[1].GetStringView(); IsLockedToIP = fields[2].GetBool(); - LockCountry = fields[3].GetString(); - LastIP = fields[4].GetString(); + LockCountry = fields[3].GetStringView(); + LastIP = fields[4].GetStringView(); FailedLogins = fields[5].GetUInt32(); IsBanned = fields[6].GetUInt64() != 0; IsPermanenetlyBanned = fields[7].GetUInt64() != 0; @@ -159,10 +200,9 @@ void AccountInfo::LoadResult(Field* fields) } AuthSession::AuthSession(tcp::socket&& socket) : Socket(std::move(socket)), -_status(STATUS_CHALLENGE), _build(0), _expversion(0) + _timeout(*underlying_stream().get_executor().target()), + _status(STATUS_CHALLENGE), _locale(LOCALE_enUS), _os(0), _build(0), _expversion(0), _timezoneOffset(0min) { - N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword(7); } void AuthSession::Start() @@ -206,12 +246,13 @@ void AuthSession::CheckIpCallback(PreparedQueryResult result) pkt << uint8(0x00); pkt << uint8(WOW_FAIL_BANNED); SendPacket(pkt); - TC_LOG_DEBUG("session", "[AuthSession::CheckIpCallback] Banned ip '%s:%d' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort()); + TC_LOG_DEBUG("session", "[AuthSession::CheckIpCallback] Banned ip '%s:%u' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort()); return; } } AsyncRead(); + SetTimeout(); } void AuthSession::ReadHandler() @@ -219,22 +260,15 @@ void AuthSession::ReadHandler() MessageBuffer& packet = GetReadBuffer(); while (packet.GetActiveSize()) { - uint8 cmd = packet.GetReadPointer()[0]; - auto itr = Handlers.find(cmd); - if (itr == Handlers.end()) - { - // well we dont handle this, lets just ignore it - packet.Reset(); - break; - } - - if (_status != itr->second.status) + eAuthCmd cmd = eAuthCmd(packet.GetReadPointer()[0]); + AuthHandler const* itr = Handlers[cmd]; + if (!itr || _status != itr->status) { CloseSocket(); return; } - uint16 size = uint16(itr->second.packetSize); + std::size_t size = itr->packetSize; if (packet.GetActiveSize() < size) break; @@ -252,13 +286,14 @@ void AuthSession::ReadHandler() if (packet.GetActiveSize() < size) break; - if (!(*this.*itr->second.handler)()) + if (!itr->handler(this)) { CloseSocket(); return; } packet.ReadCompleted(size); + SetTimeout(); } AsyncRead(); @@ -271,7 +306,7 @@ void AuthSession::SendPacket(ByteBuffer& packet) if (!packet.empty()) { - MessageBuffer buffer; + MessageBuffer buffer(packet.size()); buffer.Write(packet.contents(), packet.size()); QueuePacket(std::move(buffer)); } @@ -285,28 +320,22 @@ bool AuthSession::HandleLogonChallenge() if (challenge->size - (sizeof(sAuthLogonChallenge_C) - AUTH_LOGON_CHALLENGE_INITIAL_SIZE - 1) != challenge->I_len) return false; - std::string login((char const*)challenge->I, challenge->I_len); - TC_LOG_DEBUG("server.authserver", "[AuthChallenge] '%s'", login.c_str()); + std::string_view login(challenge->I, challenge->I_len); + TC_LOG_DEBUG("server.authserver", "[AuthChallenge] '%s'", login.data()); _build = challenge->build; _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); - std::array os; - os.fill('\0'); - memcpy(os.data(), challenge->os, sizeof(challenge->os)); - _os = os.data(); + _os = challenge->os; + _locale = GetLocaleByName(ClientBuild::ToCharArray(challenge->country).data()); - // Restore string order as its byte order is reversed - std::reverse(_os.begin(), _os.end()); - - _localizationName.resize(4); - for (int i = 0; i < 4; ++i) - _localizationName[i] = challenge->country[4 - i - 1]; + _timezoneOffset = Minutes(challenge->timezone_bias); // Get the account details from the account table LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGONCHALLENGE); - stmt->setString(0, login); + stmt->setStringView(0, login); - _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::LogonChallengeCallback, this, std::placeholders::_1))); + _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt) + .WithPreparedCallback([this](PreparedQueryResult result) { LogonChallengeCallback(std::move(result)); })); return true; } @@ -333,7 +362,7 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result) // If the IP is 'locked', check that the player comes indeed from the correct IP address if (_accountInfo.IsLockedToIP) { - TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountInfo.Login.c_str(), _accountInfo.LastIP.c_str(), ipAddress.c_str()); + TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountInfo.Login.c_str(), _accountInfo.LastIP.c_str(), ipAddress.data()); if (_accountInfo.LastIP != ipAddress) { pkt << uint8(WOW_FAIL_LOCKED_ENFORCED); @@ -349,9 +378,9 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result) TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to ip", _accountInfo.Login.c_str()); if (_accountInfo.LockCountry.empty() || _accountInfo.LockCountry == "00") TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to country", _accountInfo.Login.c_str()); - else if (!_accountInfo.LockCountry.empty() && !_ipCountry.empty()) + else if (!_ipCountry.empty()) { - TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo.Login.c_str(), _accountInfo.LockCountry.c_str(), _ipCountry.c_str()); + TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo.Login.c_str(), _accountInfo.LockCountry.c_str(), _ipCountry.data()); if (_ipCountry != _accountInfo.LockCountry) { pkt << uint8(WOW_FAIL_UNLOCKABLE_LOCK); @@ -368,94 +397,83 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result) { pkt << uint8(WOW_FAIL_BANNED); SendPacket(pkt); - TC_LOG_INFO("server.authserver.banned", "'%s:%d' [AuthChallenge] Banned account %s tried to login!", ipAddress.c_str(), port, _accountInfo.Login.c_str()); + TC_LOG_INFO("server.authserver.banned", "'%s:%u' [AuthChallenge] Banned account %s tried to login!", ipAddress.c_str(), port, _accountInfo.Login.c_str()); return; } else { pkt << uint8(WOW_FAIL_SUSPENDED); SendPacket(pkt); - TC_LOG_INFO("server.authserver.banned", "'%s:%d' [AuthChallenge] Temporarily banned account %s tried to login!", ipAddress.c_str(), port, _accountInfo.Login.c_str()); + TC_LOG_INFO("server.authserver.banned", "'%s:%u' [AuthChallenge] Temporarily banned account %s tried to login!", ipAddress.c_str(), port, _accountInfo.Login.c_str()); return; } } - // Get the password from the account table, upper it, and make the SRP6 calculation - std::string rI = fields[10].GetString(); - - // Don't calculate (v, s) if there are already some in the database - std::string databaseV = fields[11].GetString(); - std::string databaseS = fields[12].GetString(); - - TC_LOG_DEBUG("network", "database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); - - // multiply with 2 since bytes are stored as hexstring - if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2) - SetVSFields(rI); - else + uint8 securityFlags = 0; + // Check if a TOTP token is needed + if (!fields[9].IsNull()) { - s.SetHexStr(databaseS.c_str()); - v.SetHexStr(databaseV.c_str()); + securityFlags = 4; + _totpSecret = fields[9].GetBinary(); + if (auto const& secret = sSecretMgr->GetSecret(SECRET_TOTP_MASTER_KEY)) + { + bool success = Trinity::Crypto::AEDecrypt(*_totpSecret, *secret); + if (!success) + { + pkt << uint8(WOW_FAIL_DB_BUSY); + TC_LOG_ERROR("server.authserver", "[AuthChallenge] Account '%s' has invalid ciphertext for TOTP token key stored", _accountInfo.Login.c_str()); + SendPacket(pkt); + return; + } + } } - b.SetRand(19 * 8); - BigNumber gmod = g.ModExp(b, N); - B = ((v * 3) + gmod) % N; - - ASSERT(gmod.GetNumBytes() <= 32); - - BigNumber unk3; - unk3.SetRand(16 * 8); + _srp6.emplace( + _accountInfo.Login, + fields[10].GetBinary(), + fields[11].GetBinary() + ); // Fill the response packet with the result - if (fields[13].GetUInt32() && AuthHelper::IsBuildSupportingBattlenet(_build)) - pkt << uint8(WOW_FAIL_USE_BATTLENET); - else if (AuthHelper::IsAcceptedClientBuild(_build)) + if (AuthHelper::IsAcceptedClientBuild(_build)) { pkt << uint8(WOW_SUCCESS); + + pkt.append(_srp6->B); + pkt << uint8(1); + pkt.append(_srp6->g); + pkt << uint8(32); + pkt.append(_srp6->N); + pkt.append(_srp6->s); + pkt.append(VersionChallenge.data(), VersionChallenge.size()); + pkt << uint8(securityFlags); // security flags (0x0...0x04) + + if (securityFlags & 0x01) // PIN input + { + pkt << uint32(0); + pkt << uint64(0) << uint64(0); // 16 bytes hash? + } + + if (securityFlags & 0x02) // Matrix input + { + pkt << uint8(0); + pkt << uint8(0); + pkt << uint8(0); + pkt << uint8(0); + pkt << uint64(0); + } + + if (securityFlags & 0x04) // Security token input + pkt << uint8(1); + + TC_LOG_DEBUG("server.authserver", "'%s:%u' [AuthChallenge] account %s is using '%s' locale (%u)", + ipAddress.c_str(), port, _accountInfo.Login.c_str(), localeNames[_locale], uint32(_locale)); + _status = STATUS_LOGON_PROOF; } else pkt << uint8(WOW_FAIL_VERSION_INVALID); - // B may be calculated < 32B so we force minimal length to 32B - pkt.append(B.AsByteArray(32).get(), 32); // 32 bytes - pkt << uint8(1); - pkt.append(g.AsByteArray(1).get(), 1); - pkt << uint8(32); - pkt.append(N.AsByteArray(32).get(), 32); - pkt.append(s.AsByteArray(int32(BufferSizes::SRP_6_S)).get(), size_t(BufferSizes::SRP_6_S)); // 32 bytes - pkt.append(unk3.AsByteArray(16).get(), 16); - uint8 securityFlags = 0; - - // Check if token is used - _tokenKey = fields[9].GetString(); - if (!_tokenKey.empty()) - securityFlags = 4; - - pkt << uint8(securityFlags); // security flags (0x0...0x04) - - if (securityFlags & 0x01) // PIN input - { - pkt << uint32(0); - pkt << uint64(0) << uint64(0); // 16 bytes hash? - } - - if (securityFlags & 0x02) // Matrix input - { - pkt << uint8(0); - pkt << uint8(0); - pkt << uint8(0); - pkt << uint8(0); - pkt << uint64(0); - } - - if (securityFlags & 0x04) // Security token input - pkt << uint8(1); - - TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s is using '%s' locale (%u)", - ipAddress.c_str(), port, _accountInfo.Login.c_str(), _localizationName.c_str(), GetLocaleByName(_localizationName)); - SendPacket(pkt); } @@ -476,160 +494,101 @@ bool AuthSession::HandleLogonProof() return false; } - // Continue the SRP6 calculation based on data received from the client - BigNumber A; - - A.SetBinary(logonProof->A, 32); - - // SRP safeguard: abort if A == 0 - if ((A % N).IsZero()) - return false; - - SHA1Hash sha; - sha.UpdateBigNumbers(&A, &B, nullptr); - sha.Finalize(); - BigNumber u; - u.SetBinary(sha.GetDigest(), 20); - BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); - - uint8 t[32]; - uint8 t1[16]; - uint8 vK[40]; - memcpy(t, S.AsByteArray(32).get(), 32); - - for (int i = 0; i < 16; ++i) - t1[i] = t[i * 2]; - - sha.Initialize(); - sha.UpdateData(t1, 16); - sha.Finalize(); - - for (int i = 0; i < 20; ++i) - vK[i * 2] = sha.GetDigest()[i]; - - for (int i = 0; i < 16; ++i) - t1[i] = t[i * 2 + 1]; - - sha.Initialize(); - sha.UpdateData(t1, 16); - sha.Finalize(); - - for (int i = 0; i < 20; ++i) - vK[i * 2 + 1] = sha.GetDigest()[i]; - - K.SetBinary(vK, 40); - - uint8 hash[20]; - - sha.Initialize(); - sha.UpdateBigNumbers(&N, nullptr); - sha.Finalize(); - memcpy(hash, sha.GetDigest(), 20); - sha.Initialize(); - sha.UpdateBigNumbers(&g, nullptr); - sha.Finalize(); - - for (int i = 0; i < 20; ++i) - hash[i] ^= sha.GetDigest()[i]; - - BigNumber t3; - t3.SetBinary(hash, 20); - - sha.Initialize(); - sha.UpdateData(_accountInfo.Login); - sha.Finalize(); - uint8 t4[SHA_DIGEST_LENGTH]; - memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); - - sha.Initialize(); - sha.UpdateBigNumbers(&t3, nullptr); - sha.UpdateData(t4, SHA_DIGEST_LENGTH); - sha.UpdateBigNumbers(&s, &A, &B, &K, nullptr); - sha.Finalize(); - BigNumber M; - M.SetBinary(sha.GetDigest(), sha.GetLength()); - // Check if SRP6 results match (password is correct), else send an error - if (!memcmp(M.AsByteArray(sha.GetLength()).get(), logonProof->M1, 20)) + if (std::optional K = _srp6->VerifyChallengeResponse(logonProof->A, logonProof->clientM)) { + _sessionKey = *K; // Check auth token - if ((logonProof->securityFlags & 0x04) || !_tokenKey.empty()) + bool tokenSuccess = false; + bool sentToken = (logonProof->securityFlags & 0x04); + if (sentToken && _totpSecret) { uint8 size = *(GetReadBuffer().GetReadPointer() + sizeof(sAuthLogonProof_C)); std::string token(reinterpret_cast(GetReadBuffer().GetReadPointer() + sizeof(sAuthLogonProof_C) + sizeof(size)), size); GetReadBuffer().ReadCompleted(sizeof(size) + size); - uint32 validToken = TOTP::GenerateToken(_tokenKey.c_str()); - _tokenKey.clear(); + uint32 incomingToken = atoi(token.c_str()); - if (validToken != incomingToken) - { - ByteBuffer packet; - packet << uint8(AUTH_LOGON_PROOF); - packet << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); - packet << uint8(3); - packet << uint8(0); - SendPacket(packet); - return true; - } + tokenSuccess = Trinity::Crypto::TOTP::ValidateToken(*_totpSecret, incomingToken); + memset(_totpSecret->data(), 0, _totpSecret->size()); + } + else if (!sentToken && !_totpSecret) + tokenSuccess = true; + + if (!tokenSuccess) + { + ByteBuffer packet; + packet << uint8(AUTH_LOGON_PROOF); + packet << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); + packet << uint16(0); // LoginFlags, 1 has account message + SendPacket(packet); + return true; } - TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str()); + if (!VerifyVersion(logonProof->A, logonProof->crc_hash, false)) + { + ByteBuffer packet; + packet << uint8(AUTH_LOGON_PROOF); + packet << uint8(WOW_FAIL_VERSION_INVALID); + SendPacket(packet); + return true; + } + + TC_LOG_DEBUG("server.authserver", "'%s:%u' User '%s' successfully authenticated", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str()); // Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket - LoginDatabasePreparedStatement*stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF); - stmt->setString(0, K.AsHexStr()); - stmt->setString(1, GetRemoteIpAddress().to_string()); - stmt->setUInt32(2, GetLocaleByName(_localizationName)); - stmt->setString(3, _os); - stmt->setString(4, _accountInfo.Login); - LoginDatabase.DirectExecute(stmt); - - // Finish SRP6 and send the final result to the client - sha.Initialize(); - sha.UpdateBigNumbers(&A, &M, &K, nullptr); - sha.Finalize(); - - ByteBuffer packet; - if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + std::string address = sConfigMgr->GetBoolDefault("AllowLoggingIPAddressesInDatabase", true) ? GetRemoteIpAddress().to_string() : "127.0.0.1"; + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF); + stmt->setBinary(0, _sessionKey); + stmt->setString(1, address); + stmt->setUInt32(2, _locale); + stmt->setStringView(3, ClientBuild::ToCharArray(_os).data()); + stmt->setInt16(4, _timezoneOffset.count()); + stmt->setString(5, _accountInfo.Login); + _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt) + .WithPreparedCallback([this, M2 = Trinity::Crypto::SRP6::GetSessionVerifier(logonProof->A, logonProof->clientM, _sessionKey)](PreparedQueryResult const&) { - sAuthLogonProof_S proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.AccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; - proof.SurveyId = 0; - proof.unk3 = 0; + // Finish SRP6 and send the final result to the client + ByteBuffer packet; + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + { + sAuthLogonProof_S proof; + proof.M2 = M2; + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.AccountFlags = 0x00800000; // 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) + proof.SurveyId = 0; + proof.LoginFlags = 0; // 0x1 = has account message - packet.resize(sizeof(proof)); - std::memcpy(packet.contents(), &proof, sizeof(proof)); - } - else - { - sAuthLogonProof_S_Old proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk2 = 0x00; + packet.resize(sizeof(proof)); + std::memcpy(packet.contents(), &proof, sizeof(proof)); + } + else + { + sAuthLogonProof_S_Old proof; + proof.M2 = M2; + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk2 = 0x00; - packet.resize(sizeof(proof)); - std::memcpy(packet.contents(), &proof, sizeof(proof)); - } + packet.resize(sizeof(proof)); + std::memcpy(packet.contents(), &proof, sizeof(proof)); + } - SendPacket(packet); - _status = STATUS_AUTHED; + SendPacket(packet); + _status = STATUS_AUTHED; + })); } else { ByteBuffer packet; packet << uint8(AUTH_LOGON_PROOF); packet << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); - packet << uint8(3); - packet << uint8(0); + packet << uint16(0); // LoginFlags, 1 has account message SendPacket(packet); - TC_LOG_INFO("server.authserver.hack", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", + TC_LOG_INFO("server.authserver.hack", "'%s:%u' [AuthChallenge] account %s tried to login with invalid password!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str()); uint32 MaxWrongPassCount = sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0); @@ -640,7 +599,7 @@ bool AuthSession::HandleLogonProof() LoginDatabasePreparedStatement* logstmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FALP_IP_LOGGING); logstmt->setUInt32(0, _accountInfo.Id); logstmt->setString(1, GetRemoteIpAddress().to_string()); - logstmt->setString(2, "Logged on failed AccountLogin due wrong password"); + logstmt->setString(2, "Login to WoW Failed - Incorrect Password"); LoginDatabase.Execute(logstmt); } @@ -664,7 +623,7 @@ bool AuthSession::HandleLogonProof() stmt->setUInt32(1, WrongPassBanTime); LoginDatabase.Execute(stmt); - TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", + TC_LOG_DEBUG("server.authserver", "'%s:%u' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str(), WrongPassBanTime, _accountInfo.FailedLogins); } else @@ -674,7 +633,7 @@ bool AuthSession::HandleLogonProof() stmt->setUInt32(1, WrongPassBanTime); LoginDatabase.Execute(stmt); - TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] IP got banned for '%u' seconds because account %s failed to authenticate '%u' times", + TC_LOG_DEBUG("server.authserver", "'%s:%u' [AuthChallenge] IP got banned for '%u' seconds because account %s failed to authenticate '%u' times", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), WrongPassBanTime, _accountInfo.Login.c_str(), _accountInfo.FailedLogins); } } @@ -692,28 +651,22 @@ bool AuthSession::HandleReconnectChallenge() if (challenge->size - (sizeof(sAuthLogonChallenge_C) - AUTH_LOGON_CHALLENGE_INITIAL_SIZE - 1) != challenge->I_len) return false; - std::string login((char const*)challenge->I, challenge->I_len); - TC_LOG_DEBUG("server.authserver", "[ReconnectChallenge] '%s'", login.c_str()); + std::string_view login(challenge->I, challenge->I_len); + TC_LOG_DEBUG("server.authserver", "[ReconnectChallenge] '%s'", login.data()); _build = challenge->build; _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); - std::array os; - os.fill('\0'); - memcpy(os.data(), challenge->os, sizeof(challenge->os)); - _os = os.data(); + _os = challenge->os; + _locale = GetLocaleByName(ClientBuild::ToCharArray(challenge->country).data()); - // Restore string order as its byte order is reversed - std::reverse(_os.begin(), _os.end()); - - _localizationName.resize(4); - for (int i = 0; i < 4; ++i) - _localizationName[i] = challenge->country[4 - i - 1]; + _timezoneOffset = Minutes(challenge->timezone_bias); // Get the account details from the account table LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RECONNECTCHALLENGE); - stmt->setString(0, login); + stmt->setStringView(0, login); - _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::ReconnectChallengeCallback, this, std::placeholders::_1))); + _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt) + .WithPreparedCallback([this](PreparedQueryResult result) { ReconnectChallengeCallback(std::move(result)); })); return true; } @@ -732,13 +685,13 @@ void AuthSession::ReconnectChallengeCallback(PreparedQueryResult result) Field* fields = result->Fetch(); _accountInfo.LoadResult(fields); - K.SetHexStr(fields[9].GetCString()); - _reconnectProof.SetRand(16 * 8); + _sessionKey = fields[9].GetBinary(); + Trinity::Crypto::GetRandomBytes(_reconnectProof); _status = STATUS_RECONNECT_PROOF; pkt << uint8(WOW_SUCCESS); - pkt.append(_reconnectProof.AsByteArray(16).get(), 16); // 16 bytes random - pkt << uint64(0x00) << uint64(0x00); // 16 bytes zeros + pkt.append(_reconnectProof); + pkt.append(VersionChallenge.data(), VersionChallenge.size()); SendPacket(pkt); } @@ -750,33 +703,40 @@ bool AuthSession::HandleReconnectProof() sAuthReconnectProof_C *reconnectProof = reinterpret_cast(GetReadBuffer().GetReadPointer()); - if (_accountInfo.Login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) + if (_accountInfo.Login.empty()) return false; - BigNumber t1; - t1.SetBinary(reconnectProof->R1, 16); - - SHA1Hash sha; - sha.Initialize(); + Trinity::Crypto::SHA1 sha; sha.UpdateData(_accountInfo.Login); - sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, nullptr); + sha.UpdateData(reconnectProof->R1, 16); + sha.UpdateData(_reconnectProof); + sha.UpdateData(_sessionKey); sha.Finalize(); - if (!memcmp(sha.GetDigest(), reconnectProof->R2, SHA_DIGEST_LENGTH)) + if (sha.GetDigest() == reconnectProof->R2) { + if (!VerifyVersion(reconnectProof->R1, reconnectProof->R3, true)) + { + ByteBuffer packet; + packet << uint8(AUTH_RECONNECT_PROOF); + packet << uint8(WOW_FAIL_VERSION_INVALID); + SendPacket(packet); + return true; + } + // Sending response ByteBuffer pkt; pkt << uint8(AUTH_RECONNECT_PROOF); - pkt << uint8(0x00); - pkt << uint16(0x00); // 2 bytes zeros + pkt << uint8(WOW_SUCCESS); + pkt << uint16(0); // LoginFlags, 1 has account message SendPacket(pkt); _status = STATUS_AUTHED; return true; } else { - TC_LOG_ERROR("server.authserver.hack", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.", GetRemoteIpAddress().to_string().c_str(), - GetRemotePort(), _accountInfo.Login.c_str()); + TC_LOG_ERROR("server.authserver.hack", "'%s:%u' [ERROR] user %s tried to login, but session is invalid.", + GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str()); return false; } } @@ -809,7 +769,7 @@ void AuthSession::RealmListCallback(PreparedQueryResult result) ByteBuffer pkt; size_t RealmListSize = 0; - for (auto const& i : sGruntRealmList->GetRealms()) + for (GruntRealmList::RealmMap::value_type const& i : sGruntRealmList->GetRealms()) { Realm const& realm = i.second; // don't work with realms which not compatible with the client @@ -817,7 +777,7 @@ void AuthSession::RealmListCallback(PreparedQueryResult result) // No SQL injection. id of realm is controlled by the database. uint32 flag = realm.Flags; - RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.Build); + ClientBuild::Info const* buildInfo = ClientBuild::GetBuildInfo(realm.Build); if (!okBuild) { if (!buildInfo) @@ -893,32 +853,87 @@ void AuthSession::RealmListCallback(PreparedQueryResult result) _status = STATUS_AUTHED; } -// Make the SRP6 calculation from hash in dB -void AuthSession::SetVSFields(const std::string& rI) +bool AuthSession::HandleXferAccept() { - s.SetRand(int32(BufferSizes::SRP_6_S) * 8); + TC_LOG_DEBUG("server.authserver", "Entering _HandleXferAccept"); - BigNumber I; - I.SetHexStr(rI.c_str()); - - // In case of leading zeros in the rI hash, restore them - uint8 mDigest[SHA_DIGEST_LENGTH]; - memcpy(mDigest, I.AsByteArray(SHA_DIGEST_LENGTH).get(), SHA_DIGEST_LENGTH); - - std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH); - - SHA1Hash sha; - sha.UpdateData(s.AsByteArray(uint32(BufferSizes::SRP_6_S)).get(), (uint32(BufferSizes::SRP_6_S))); - sha.UpdateData(mDigest, SHA_DIGEST_LENGTH); - sha.Finalize(); - BigNumber x; - x.SetBinary(sha.GetDigest(), sha.GetLength()); - v = g.ModExp(x, N); - - // No SQL injection (username escaped) - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS); - stmt->setString(0, v.AsHexStr()); - stmt->setString(1, s.AsHexStr()); - stmt->setString(2, _accountInfo.Login); - LoginDatabase.Execute(stmt); + // empty handler meant to close the connection if received + return false; +} + +bool AuthSession::HandleXferResume() +{ + TC_LOG_DEBUG("server.authserver", "Entering _HandleXferResume"); + + // empty handler meant to close the connection if received + return false; +} + +bool AuthSession::HandleXferCancel() +{ + TC_LOG_DEBUG("server.authserver", "Entering _HandleXferCancel"); + + // empty handler meant to close the connection if received + return false; +} + +bool AuthSession::VerifyVersion(std::span a, Trinity::Crypto::SHA1::Digest const& versionProof, bool isReconnect) +{ + if (!sConfigMgr->GetBoolDefault("StrictVersionCheck", false)) + return true; + + Trinity::Crypto::SHA1::Digest zeros = { }; + Trinity::Crypto::SHA1::Digest const* versionHash = nullptr; + if (!isReconnect) + { + ClientBuild::Info const* buildInfo = ClientBuild::GetBuildInfo(_build); + if (!buildInfo) + return false; + + auto platformItr = std::ranges::find(buildInfo->ExecutableHashes, _os, &ClientBuild::ExecutableHash::Platform); + if (platformItr == buildInfo->ExecutableHashes.end()) + return true; // not filled serverside + + versionHash = &platformItr->Hash; + } + else + versionHash = &zeros; + + Trinity::Crypto::SHA1 version; + version.UpdateData(a); + version.UpdateData(*versionHash); + version.Finalize(); + + return versionProof == version.GetDigest(); +} + +void AuthSession::SetTimeout() +{ + _timeout.cancel(); + + switch (_status) + { + case STATUS_AUTHED: + case STATUS_WAITING_FOR_REALM_LIST: + _timeout.expires_after(1min); + break; + case STATUS_XFER: + return; + default: + _timeout.expires_after(10s); + break; + } + + _timeout.async_wait([selfRef = weak_from_this()](boost::system::error_code const& error) + { + std::shared_ptr self = selfRef.lock(); + if (!self) + return; + + if (error == boost::asio::error::operation_aborted) + return; + + TC_LOG_DEBUG("server.authserver", "%s:%u session timed out.", self->GetRemoteIpAddress().to_string().c_str(), self->GetRemotePort()); + self->CloseSocket(); + }); } diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h index 6ab94b82b1..400d08c5a1 100644 --- a/src/server/authserver/Server/AuthSession.h +++ b/src/server/authserver/Server/AuthSession.h @@ -1,37 +1,39 @@ /* -* Copyright (C) 2008-2018 TrinityCore -* Copyright (C) 2005-2009 MaNGOS -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at your -* option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along -* with this program. If not, see . -*/ + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ #ifndef __AUTHSESSION_H__ #define __AUTHSESSION_H__ #include "AsyncCallbackProcessor.h" -#include "DatabaseEnvFwd.h" #include "Common.h" -#include "BigNumber.h" +#include "CryptoHash.h" +#include "DatabaseEnvFwd.h" +#include "DeadlineTimer.h" +#include "Duration.h" +#include "Optional.h" #include "Socket.h" +#include "SRP6.h" #include -#include +#include using boost::asio::ip::tcp; +class AuthHandlerTable; class ByteBuffer; -class Field; -struct AuthHandler; enum AuthStatus { @@ -40,6 +42,7 @@ enum AuthStatus STATUS_RECONNECT_PROOF, STATUS_AUTHED, STATUS_WAITING_FOR_REALM_LIST, + STATUS_XFER, STATUS_CLOSED }; @@ -56,7 +59,6 @@ struct AccountInfo bool IsBanned = false; bool IsPermanenetlyBanned = false; AccountTypes SecurityLevel = SEC_PLAYER; - std::string TokenKey; }; class AuthSession : public Socket @@ -64,8 +66,6 @@ class AuthSession : public Socket typedef Socket AuthSocket; public: - static std::unordered_map InitHandlers(); - AuthSession(tcp::socket&& socket); void Start() override; @@ -77,45 +77,40 @@ protected: void ReadHandler() override; private: + friend AuthHandlerTable; bool HandleLogonChallenge(); bool HandleLogonProof(); bool HandleReconnectChallenge(); bool HandleReconnectProof(); bool HandleRealmList(); + bool HandleXferAccept(); + bool HandleXferResume(); + bool HandleXferCancel(); void CheckIpCallback(PreparedQueryResult result); void LogonChallengeCallback(PreparedQueryResult result); void ReconnectChallengeCallback(PreparedQueryResult result); void RealmListCallback(PreparedQueryResult result); - void SetVSFields(const std::string& rI); + bool VerifyVersion(std::span a, Trinity::Crypto::SHA1::Digest const& versionProof, bool isReconnect); + void SetTimeout(); - BigNumber N, s, g, v; - BigNumber b, B; - BigNumber K; - BigNumber _reconnectProof; + Optional _srp6; + SessionKey _sessionKey = {}; + std::array _reconnectProof = {}; + Trinity::Asio::DeadlineTimer _timeout; AuthStatus _status; AccountInfo _accountInfo; - std::string _tokenKey; - std::string _localizationName; - std::string _os; - std::string _ipCountry; + Optional> _totpSecret; + LocaleConstant _locale; + uint32 _os; + std::string_view _ipCountry; uint16 _build; uint8 _expversion; + Minutes _timezoneOffset; QueryCallbackProcessor _queryProcessor; }; -#pragma pack(push, 1) - -struct AuthHandler -{ - AuthStatus status; - size_t packetSize; - bool (AuthSession::*handler)(); -}; - -#pragma pack(pop) - #endif diff --git a/src/server/authserver/Server/AuthSocketMgr.h b/src/server/authserver/Server/AuthSocketMgr.h index 04d65d396b..956550e018 100644 --- a/src/server/authserver/Server/AuthSocketMgr.h +++ b/src/server/authserver/Server/AuthSocketMgr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/bnetserver/Authentication/AuthCodes.cpp b/src/server/bnetserver/Authentication/AuthCodes.cpp deleted file mode 100644 index f84543e4e1..0000000000 --- a/src/server/bnetserver/Authentication/AuthCodes.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "AuthCodes.h" -#include - -namespace AuthHelper -{ - static RealmBuildInfo const PostBcAcceptedClientBuilds[] = - { - {15595, 4, 3, 4, ' '}, - {14545, 4, 2, 2, ' '}, - {13623, 4, 0, 6, 'a'}, - {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build - {12340, 3, 3, 5, 'a'}, - {11723, 3, 3, 3, 'a'}, - {11403, 3, 3, 2, ' '}, - {11159, 3, 3, 0, 'a'}, - {10505, 3, 2, 2, 'a'}, - {9947, 3, 1, 3, ' '}, - {8606, 2, 4, 3, ' '}, - {6141, 1, 12, 3, ' '}, - {6005, 1, 12, 2, ' '}, - {5875, 1, 12, 1, ' '}, - {0, 0, 0, 0, ' '} // terminator - }; - - RealmBuildInfo const* GetBuildInfo(int build) - { - for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) - if (PostBcAcceptedClientBuilds[i].Build == build) - return &PostBcAcceptedClientBuilds[i]; - - return nullptr; - } - - bool IsBuildSupportingBattlenet(int build) - { - return build >= 15595; - } -} diff --git a/src/server/bnetserver/Authentication/AuthCodes.h b/src/server/bnetserver/Authentication/AuthCodes.h deleted file mode 100644 index ca1b46eb31..0000000000 --- a/src/server/bnetserver/Authentication/AuthCodes.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef _AUTHCODES_H -#define _AUTHCODES_H - -enum GameAccountFlags -{ - GAMEACCOUNT_FLAG_GM = 0x00000001, - GAMEACCOUNT_FLAG_NOKICK = 0x00000002, - GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004, - GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008, - GAMEACCOUNT_FLAG_CANCELLED = 0x00000010, - GAMEACCOUNT_FLAG_IGR = 0x00000020, - GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040, - GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080, - GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100, - GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200, - GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400, - GAMEACCOUNT_FLAG_REFERRAL = 0x00000800, - GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000, - GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000, - GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000, - GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000, - GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000, - GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000, - GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000, - GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000, - GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000, - GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000, - GAMEACCOUNT_FLAG_PROPASS = 0x00400000, - GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000, - GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000, - GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000, - GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000, - GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000, - GAMEACCOUNT_FLAG_DEMOS = 0x10000000, - GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000, -}; - -namespace Battlenet -{ - enum AuthResult - { - AUTH_OK = 0, - AUTH_INTERNAL_ERROR = 100, - AUTH_CORRUPTED_MODULE = 101, - AUTH_NO_BATTLETAGS = 102, - AUTH_BAD_SERVER_PROOF = 103, - AUTH_UNKNOWN_ACCOUNT = 104, - AUTH_CLOSED = 105, - AUTH_LOGIN_TIMEOUT = 106, - AUTH_NO_GAME_ACCOUNTS = 107, - AUTH_INVALID_TOKEN = 108, - AUTH_INVALID_PROGRAM = 109, - AUTH_INVALID_OS = 110, - AUTH_UNSUPPORTED_LANGUAGE = 111, - AUTH_REGION_BAD_VERSION = 112, - AUTH_TEMP_OUTAGE = 113, - AUTH_CANT_DOWNLOAD_MODULE = 114, - AUTH_DUPLICATE_LOGON = 115, - AUTH_BAD_CREDENTIALS_2 = 116, - AUTH_VERSION_CHECK_SUCCEEDED = 117, - AUTH_BAD_VERSION_HASH = 118, - AUTH_CANT_RETRIEVE_PORTAL_LIST = 119, - AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120, - AUTH_DARK_PORTAL_FILE_CORRUPTED = 121, - AUTH_BATTLENET_MAINTENANCE = 122, - AUTH_LOGON_TOO_FAST = 123, - AUTH_USE_GRUNT_LOGON = 124, - AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140, - AUTH_ACCOUNT_LOCKED = 141, - - LOGIN_SERVER_BUSY = 200, - LOGIN_NO_GAME_ACCOUNT = 201, - LOGIN_BANNED = 202, - LOGIN_SUSPENDED = 203, - LOGIN_GAME_ACCOUNT_LOCKED = 204, - LOGIN_ALREADY_ONLINE = 205, - LOGIN_NOTIME = 206, - LOGIN_EXPIRED = 207, - LOGIN_EXPIRED_2 = 208, - LOGIN_PARENTALCONTROL = 209, - LOGIN_TRIAL_EXPIRED = 210, - LOGIN_ANTI_INDULGENCE = 211, - LOGIN_INCORRECT_REGION = 212, - LOGIN_LOCKED_ENFORCED = 213, - LOGIN_CHARGEBACK = 214, - LOGIN_IGR_WITHOUT_BNET = 215, - LOGIN_UNLOCKABLE_LOCK = 216, - LOGIN_IGR_REQUIRED = 217, - LOGIN_PAYMENT_CHANGED = 218, - LOGIN_INVALID_PAYMENT = 219, - LOGIN_INVALID_ACCOUNT_STATE = 220 - }; -} - -struct RealmBuildInfo -{ - int Build; - int MajorVersion; - int MinorVersion; - int BugfixVersion; - int HotfixVersion; -}; - -namespace AuthHelper -{ - RealmBuildInfo const* GetBuildInfo(int build); - bool IsBuildSupportingBattlenet(int build); -} - -#endif diff --git a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp deleted file mode 100644 index 219ce3fc1e..0000000000 --- a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetPacketCrypt.h" -#include "Cryptography/HmacHash.h" -#include "Cryptography/BigNumber.h" - -Battlenet::PacketCrypt::PacketCrypt() : ::PacketCrypt(SHA256_DIGEST_LENGTH) -{ -} - -void Battlenet::PacketCrypt::Init(BigNumber* K) -{ - uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x68, 0xE0, 0xC7, 0x2E, 0xDD, 0xD6, 0xD2, 0xF3, 0x1E, 0x5A, 0xB1, 0x55, 0xB1, 0x8B, 0x63, 0x1E }; - uint8 ClientDecryptionKey[SEED_KEY_SIZE] = { 0xDE, 0xA9, 0x65, 0xAE, 0x54, 0x3A, 0x1E, 0x93, 0x9E, 0x69, 0x0C, 0xAA, 0x68, 0xDE, 0x78, 0x39 }; - - HmacSha256 serverEncryptHmac(K->GetNumBytes(), K->AsByteArray().get()); - serverEncryptHmac.UpdateData(ServerEncryptionKey, SEED_KEY_SIZE); - serverEncryptHmac.Finalize(); - - HmacSha256 clientDecryptHmac(K->GetNumBytes(), K->AsByteArray().get()); - clientDecryptHmac.UpdateData(ClientDecryptionKey, SEED_KEY_SIZE); - clientDecryptHmac.Finalize(); - - _clientDecrypt.Init(clientDecryptHmac.GetDigest()); - _serverEncrypt.Init(serverEncryptHmac.GetDigest()); - _initialized = true; -} diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt deleted file mode 100644 index 57a9f1cdfa..0000000000 --- a/src/server/bnetserver/CMakeLists.txt +++ /dev/null @@ -1,107 +0,0 @@ -# This file is part of the TrinityCore Project. See AUTHORS file for Copyright information -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -########### bnetserver ############### - -CollectSourceFiles( - ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE_SOURCES - # Exclude - ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) - -if (WIN32) - list(APPEND PRIVATE_SOURCES ${sources_windows}) - if (MSVC) - list(APPEND PRIVATE_SOURCES bnetserver.rc) - endif() -endif() - -if (USE_COREPCH) - set(PRIVATE_PCH_HEADER PrecompiledHeaders/bnetPCH.h) -endif() - -GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) - -add_executable(bnetserver - ${PRIVATE_SOURCES} -) - -if (NOT WIN32) - set_target_properties(bnetserver PROPERTIES - COMPILE_DEFINITIONS _TRINITY_BNET_CONFIG="${CONF_DIR}/bnetserver.conf" - ) -endif() - -if( UNIX AND NOT NOJEM AND NOT APPLE ) - set(bnetserver_LINK_FLAGS "-pthread -lncurses ${bnetserver_LINK_FLAGS}") -endif() - -set_target_properties(bnetserver PROPERTIES LINK_FLAGS "${bnetserver_LINK_FLAGS}") - -target_link_libraries(bnetserver - PRIVATE - trinity-core-interface - PUBLIC - shared - ipc - ${READLINE_LIBRARY}) - -CollectIncludeDirectories( - ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC_INCLUDES - # Exclude - ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) - -target_include_directories(bnetserver - PUBLIC - ${PUBLIC_INCLUDES} - PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}) - -set_target_properties(bnetserver - PROPERTIES - FOLDER - "server") - -if(UNITY_BUILDS) - set_target_properties(bnetserver - PROPERTIES UNITY_BUILD ON) - set_target_properties(bnetserver - PROPERTIES - UNITY_BUILD_MODE BATCH - UNITY_BUILD_BATCH_SIZE 8) -endif() - -if (WIN32) - if ("${CMAKE_MAKE_PROGRAM}" MATCHES "MSBuild") - add_custom_command(TARGET bnetserver - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/ - ) - elseif (MINGW) - add_custom_command(TARGET bnetserver - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/ - ) - endif() -endif() - -if (UNIX) - install(TARGETS bnetserver DESTINATION bin) - install(FILES bnetserver.conf.dist DESTINATION ${CONF_DIR}) -elseif (WIN32) - install(TARGETS bnetserver DESTINATION "${CMAKE_INSTALL_PREFIX}") - install(FILES bnetserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() - -# Generate precompiled header -if (USE_COREPCH) - add_cxx_pch(bnetserver ${PRIVATE_PCH_HEADER}) -endif() diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp deleted file mode 100644 index 6c641ac056..0000000000 --- a/src/server/bnetserver/Main.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/** -* @file main.cpp -* @brief Authentication Server main program -* -* This file contains the main program for the -* authentication server -*/ - -#include "AppenderDB.h" -#include "Banner.h" -#include "BNetRealmList.h" -#include "ComponentManager.h" -#include "Config.h" -#include "DatabaseEnv.h" -#include "DatabaseLoader.h" -#include "DeadlineTimer.h" -#include "GitRevision.h" -#include "IoContext.h" -#include "MySQLThreading.h" -#include "ModuleManager.h" -#include "OpenSSLCrypto.h" -#include "ProcessPriority.h" -#include "SessionManager.h" -#include "Util.h" -#include "ZmqContext.h" -#include -#include -#include -#include -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) -#include -#endif -#include -#include - -#ifdef _WIN32 // ugly as hell -#pragma comment(lib, "iphlpapi.lib") -#endif - -using boost::asio::ip::tcp; -using namespace boost::program_options; -namespace fs = boost::filesystem; - -#ifndef _TRINITY_BNET_CONFIG -# define _TRINITY_BNET_CONFIG "bnetserver.conf" -#endif - -#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS -#include "ServiceWin32.h" -char serviceName[] = "bnetserver"; -char serviceLongName[] = "TrinityCore bnet service"; -char serviceDescription[] = "TrinityCore Battle.net emulator authentication service"; -/* -* -1 - not in service mode -* 0 - stopped -* 1 - running -* 2 - paused -*/ -int m_ServiceStatus = -1; - -void ServiceStatusWatcher(std::weak_ptr serviceStatusWatchTimerRef, std::weak_ptr ioContextRef, boost::system::error_code const& error); -#endif - -bool StartDB(); -void StopDB(); -void SignalHandler(std::weak_ptr ioContextRef, boost::system::error_code const& error, int signalNumber); -void KeepDatabaseAliveHandler(std::weak_ptr dbPingTimerRef, int32 dbPingInterval, boost::system::error_code const& error); -variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, std::string& configService); - -int main(int argc, char** argv) -{ - signal(SIGABRT, &Trinity::AbortHandler); - - Trinity::VerifyOsVersion(); - - auto configFile = fs::absolute(_TRINITY_BNET_CONFIG); - std::string configService; - auto vm = GetConsoleArguments(argc, argv, configFile, configService); - // exit if help is enabled - if (vm.count("help") || vm.count("version")) - return 0; - -#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS - if (configService.compare("install") == 0) - return WinServiceInstall() ? 0 : 1; - else if (configService.compare("uninstall") == 0) - return WinServiceUninstall() ? 0 : 1; - else if (configService.compare("run") == 0) - return WinServiceRun() ? 0 : 1; -#endif - - std::string configError; - if (!sConfigMgr->LoadInitial(configFile.generic_string(), - std::vector(argv, argv + argc), - configError)) - { - printf("Error in config file: %s\n", configError.c_str()); - return 1; - } - - sLog->RegisterAppender(); - sLog->Initialize(nullptr); - - Trinity::Banner::Show("bnetserver", - [](char const* text) - { - TC_LOG_INFO("server.bnetserver", "%s", text); - }, - []() - { - TC_LOG_INFO("server.bnetserver", "Using configuration file %s.", sConfigMgr->GetFilename().c_str()); - TC_LOG_INFO("server.bnetserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); - TC_LOG_INFO("server.bnetserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); - } - ); - - OpenSSLCrypto::threadsSetup(boost::dll::program_location().remove_filename()); - - std::shared_ptr opensslHandle(nullptr, [](void*) { OpenSSLCrypto::threadsCleanup(); }); - - // Seed the OpenSSL's PRNG here. - // That way it won't auto-seed when calling BigNumber::SetRand and slow down the first world login - BigNumber seed; - seed.SetRand(16 * 8); - - // bnetserver PID file creation - std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); - if (!pidFile.empty()) - { - if (uint32 pid = CreatePIDFile(pidFile)) - TC_LOG_INFO("server.bnetserver", "Daemon PID: %u\n", pid); - else - { - TC_LOG_ERROR("server.bnetserver", "Cannot create PID file %s.\n", pidFile.c_str()); - return 1; - } - } - - int32 worldListenPort = sConfigMgr->GetIntDefault("WorldserverListenPort", 1118); - if (worldListenPort < 0 || worldListenPort > 0xFFFF) - { - TC_LOG_ERROR("server.bnetserver", "Specified worldserver listen port (%d) out of allowed range (1-65535)", worldListenPort); - return 1; - } - - // Initialize the database connection - if (!StartDB()) - return 1; - - std::shared_ptr dbHandle(nullptr, [](void*) { StopDB(); }); - - sIpcContext->Initialize(); - std::shared_ptr ipcHandle(nullptr, [](void*) { sIpcContext->Close(); }); - - std::shared_ptr ioContext = std::make_shared(); - - // Start the listening port (acceptor) for auth connections - int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); - if (bnport < 0 || bnport > 0xFFFF) - { - TC_LOG_ERROR("server.bnetserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport); - return 1; - } - - // Get the list of realms for the server - sBNetRealmList->Initialize(*ioContext, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10), worldListenPort); - - std::shared_ptr sBNetRealmListHandle(nullptr, [](void*) { sBNetRealmList->Close(); }); - - std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); - - if (!sSessionMgr.StartNetwork(*ioContext, bindIp, bnport)) - { - TC_LOG_ERROR("server.bnetserver", "Failed to initialize network"); - return 1; - } - - std::shared_ptr sSessionMgrHandle(nullptr, [](void*) { sSessionMgr.StopNetwork(); }); - - // Set signal handlers - boost::asio::signal_set signals(*ioContext, SIGINT, SIGTERM); -#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS - signals.add(SIGBREAK); -#endif - signals.async_wait(std::bind(&SignalHandler, std::weak_ptr(ioContext), std::placeholders::_1, std::placeholders::_2)); - - // Set process priority according to configuration settings - SetProcessPriority("server.bnetserver", sConfigMgr->GetIntDefault(CONFIG_PROCESSOR_AFFINITY, 0), sConfigMgr->GetBoolDefault(CONFIG_HIGH_PRIORITY, false)); - - // Enabled a timed callback for handling the database keep alive ping - int32 dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30); - std::shared_ptr dbPingTimer = std::make_shared(*ioContext); - dbPingTimer->expires_after(std::chrono::minutes(dbPingInterval)); - dbPingTimer->async_wait(std::bind(&KeepDatabaseAliveHandler, std::weak_ptr(dbPingTimer), dbPingInterval, std::placeholders::_1)); - -#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS - std::shared_ptr serviceStatusWatchTimer; - if (m_ServiceStatus != -1) - { - serviceStatusWatchTimer = std::make_shared(*ioContext); - serviceStatusWatchTimer->expires_after(1s); - serviceStatusWatchTimer->async_wait(std::bind(&ServiceStatusWatcher, - std::weak_ptr(serviceStatusWatchTimer), - std::weak_ptr(ioContext), - std::placeholders::_1)); - } -#endif - - sComponentMgr->Load(); - sModuleMgr->Load(); - - // Start the io service worker loop - ioContext->run(); - - dbPingTimer->cancel(); - - TC_LOG_INFO("server.bnetserver", "Halting process..."); - - signals.cancel(); - - return 0; -} - - -/// Initialize connection to the database -bool StartDB() -{ - MySQL::Library_Init(); - - // Load databases - DatabaseLoader loader("server.bnetserver", DatabaseLoader::DATABASE_NONE); - loader - .AddDatabase(LoginDatabase, "Login"); - - if (!loader.Load()) - return false; - - TC_LOG_INFO("server.bnetserver", "Started auth database connection pool."); - sLog->SetRealmId(0); // Enables DB appenders when realm is set. - return true; -} - -/// Close the connection to the database -void StopDB() -{ - LoginDatabase.Close(); - MySQL::Library_End(); -} - -void SignalHandler(std::weak_ptr ioContextRef, boost::system::error_code const& error, int /*signalNumber*/) -{ - if (!error) - if (std::shared_ptr ioContext = ioContextRef.lock()) - ioContext->stop(); -} - -void KeepDatabaseAliveHandler(std::weak_ptr dbPingTimerRef, int32 dbPingInterval, boost::system::error_code const& error) -{ - if (!error) - { - if (std::shared_ptr dbPingTimer = dbPingTimerRef.lock()) - { - TC_LOG_INFO("server.bnetserver", "Ping MySQL to keep connection alive"); - LoginDatabase.KeepAlive(); - - dbPingTimer->expires_after(std::chrono::minutes(dbPingInterval)); - dbPingTimer->async_wait(std::bind(&KeepDatabaseAliveHandler, dbPingTimerRef, dbPingInterval, std::placeholders::_1)); - } - } -} - -#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS -void ServiceStatusWatcher(std::weak_ptr serviceStatusWatchTimerRef, std::weak_ptr ioContextRef, boost::system::error_code const& error) -{ - if (!error) - { - if (std::shared_ptr ioContext = ioContextRef.lock()) - { - if (m_ServiceStatus == 0) - { - ioContext->stop(); - } - else if (std::shared_ptr serviceStatusWatchTimer = serviceStatusWatchTimerRef.lock()) - { - serviceStatusWatchTimer->expires_after(1s); - serviceStatusWatchTimer->async_wait(std::bind(&ServiceStatusWatcher, serviceStatusWatchTimerRef, ioContext, std::placeholders::_1)); - } - } - } -} -#endif - -variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, std::string& configService) -{ - (void)configService; - - options_description all("Allowed options"); - all.add_options() - ("help,h", "print usage message") - ("version,v", "print version build info") - ("config,c", value(&configFile)->default_value(fs::absolute(_TRINITY_BNET_CONFIG)), - "use as configuration file") - ; -#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS - options_description win("Windows platform specific options"); - win.add_options() - ("service,s", value(&configService)->default_value(""), "Windows service options: [install | uninstall]") - ; - - all.add(win); -#endif - variables_map variablesMap; - try - { - store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap); - notify(variablesMap); - } - catch (std::exception& e) { - std::cerr << e.what() << "\n"; - } - - if (variablesMap.count("help")) { - std::cout << all << "\n"; - } - else if (variablesMap.count("version")) - { - std::cout << GitRevision::GetFullVersion() << "\n"; - } - - return variablesMap; -} diff --git a/src/server/bnetserver/Packets/AchievementPackets.h b/src/server/bnetserver/Packets/AchievementPackets.h deleted file mode 100644 index edd3290fcf..0000000000 --- a/src/server/bnetserver/Packets/AchievementPackets.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef AchievementPackets_h__ -#define AchievementPackets_h__ - -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Achievement - { - enum Opcode - { - CMSG_LISTEN_REQUEST = 0x0, // Not implemented - CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented - CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented - - SMSG_DATA = 0x2, // Not implemented - SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented - SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented - SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented - }; - } -} - -#endif // AchievementPackets_h__ diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp deleted file mode 100644 index d048181d4a..0000000000 --- a/src/server/bnetserver/Packets/AuthenticationPackets.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "AuthenticationPackets.h" -#include "Session.h" -#include "Util.h" - -void Battlenet::Authentication::LogonRequest::Read() -{ - Program = _stream.ReadFourCC(); - Platform = _stream.ReadFourCC(); - Locale = _stream.ReadFourCC(); - - Components.resize(_stream.Read(6)); - for (size_t i = 0; i < Components.size(); ++i) - { - Component& component = Components[i]; - component.Program = _stream.ReadFourCC(); - component.Platform = _stream.ReadFourCC(); - component.Build = _stream.Read(32); - } - - if (_stream.Read(1)) - Login = _stream.ReadString(9, 3); -} - -std::string Battlenet::Authentication::LogonRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::LogonRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; - for (Component const& component : Components) - stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - - if (!Login.empty()) - stream << std::endl << "Battlenet::Authentication::LogonRequest Login: " << Login; - - return stream.str(); -} - -void Battlenet::Authentication::LogonRequest::CallHandler(Session* session) -{ - session->HandleLogonRequest(*this); -} - -void Battlenet::Authentication::ResumeRequest::Read() -{ - Program = _stream.ReadFourCC(); - Platform = _stream.ReadFourCC(); - Locale = _stream.ReadFourCC(); - - Components.resize(_stream.Read(6)); - for (size_t i = 0; i < Components.size(); ++i) - { - Component& component = Components[i]; - component.Program = _stream.ReadFourCC(); - component.Platform = _stream.ReadFourCC(); - component.Build = _stream.Read(32); - } - - Login = _stream.ReadString(9, 3); - GameAccountRegion = _stream.Read(8); - GameAccountName = _stream.ReadString(5, 1); -} - -std::string Battlenet::Authentication::ResumeRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ResumeRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; - for (Component const& component : Components) - stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - - stream << std::endl << "Login: " << Login; - stream << std::endl << "Region: " << uint32(GameAccountRegion); - stream << std::endl << "GameAccountName: " << GameAccountName; - - return stream.str(); -} - -void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) -{ - session->HandleResumeRequest(*this); -} - -Battlenet::Authentication::ProofRequest::~ProofRequest() -{ - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; -} - -void Battlenet::Authentication::ProofRequest::Write() -{ - _stream.Write(Modules.size(), 3); - for (ModuleInfo const* info : Modules) - { - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } -} - -std::string Battlenet::Authentication::ProofRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ProofRequest modules " << Modules.size(); - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - -Battlenet::Authentication::ProofResponse::~ProofResponse() -{ - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; -} - -void Battlenet::Authentication::ProofResponse::Read() -{ - Modules.resize(_stream.Read(3)); - for (size_t i = 0; i < Modules.size(); ++i) - { - BitStream*& dataStream = Modules[i]; - dataStream = new BitStream(_stream.Read(10)); - memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize()); - } -} - -std::string Battlenet::Authentication::ProofResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ProofResponse Modules " << Modules.size(); - for (BitStream* module : Modules) - { - std::string hexStr = ByteArrayToHexStr(module->GetBuffer(), module->GetSize()); - stream << std::endl << "Battlenet::Authentication::ProofResponse::ModuleData Size: " << module->GetSize() << ", Data: " << hexStr; - } - - return stream.str(); -} - -void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) -{ - session->HandleProofResponse(*this); -} - -Battlenet::Authentication::LogonResponse::~LogonResponse() -{ - for (ModuleInfo* m : Modules) - delete m; -} - -void Battlenet::Authentication::LogonResponse::Write() -{ - _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); - if (Result.ResultValue == ResponseFailure::UPDATE) - { - _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) - { - ModuleInfo* info = Modules[i]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } - - _stream.Write(PingTimeout + std::numeric_limits::min(), 32); - _stream.Write(1, 1); // RegulatorRules != nullptr (not a pointer for us, always write) - // if written == 1 - { - _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); - if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) - { - _stream.Write(RegulatorRules.Threshold, 32); - _stream.Write(RegulatorRules.Rate, 32); - } - } - - _stream.WriteString(FirstName, 8); // First name - _stream.WriteString(LastName, 8); // Last name - not set for WoW - - _stream.Write(AccountId, 32); - _stream.Write(Region, 8); - _stream.Write(Flags, 64); - - _stream.Write(GameAccountRegion, 8); - _stream.WriteString(GameAccountName, 5, -1); - _stream.Write(GameAccountFlags, 64); - - _stream.Write(FailedLogins, 32); - } - else - { - _stream.Write(!Modules.empty(), 1); - if (!Modules.empty()) - { - ModuleInfo* info = Modules[0]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - } - - _stream.Write(Result.ResultValue, 2); - if (Result.ResultValue == ResponseFailure::FAILURE) - { - _stream.Write(Result.Error, 16); - _stream.Write(Result.Wait + std::numeric_limits::min(), 32); - } - } -} - -std::string Battlenet::Authentication::LogonResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::LogonResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout - << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate - << " FirstName " << FirstName << " LastName " << LastName << " AccountId " << AccountId << " Region " << uint32(Region) << " GameAccountName " << GameAccountName - << " GameAccountFlags " << GameAccountFlags << " FailedLogins " << FailedLogins << " Modules " << Modules.size(); - - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - -void Battlenet::Authentication::LogonResponse::SetAuthResult(AuthResult result) -{ - Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; - Result.Error = result; -} - -Battlenet::Authentication::ResumeResponse::~ResumeResponse() -{ - for (ModuleInfo* m : Modules) - delete m; -} - -void Battlenet::Authentication::ResumeResponse::Write() -{ - _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); - if (Result.ResultValue == ResponseFailure::UPDATE) - { - _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) - { - ModuleInfo* info = Modules[i]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } - - _stream.Write(PingTimeout + std::numeric_limits::min(), 32); - _stream.Write(1, 1); // RegulatorRules != nullptr (not a pointer for us, always write) - // if written == 1 - { - _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); - if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) - { - _stream.Write(RegulatorRules.Threshold, 32); - _stream.Write(RegulatorRules.Rate, 32); - } - } - } - else - { - _stream.Write(!Modules.empty(), 1); - if (!Modules.empty()) - { - ModuleInfo* info = Modules[0]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - } - - _stream.Write(Result.ResultValue, 2); - if (Result.ResultValue == ResponseFailure::FAILURE) - { - _stream.Write(Result.Error, 16); - _stream.Write(Result.Wait + std::numeric_limits::min(), 32); - } - } -} - -std::string Battlenet::Authentication::ResumeResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ResumeResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout - << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate - << " Modules " << Modules.size(); - - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - -void Battlenet::Authentication::ResumeResponse::SetAuthResult(AuthResult result) -{ - Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; - Result.Error = result; -} diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h deleted file mode 100644 index 5a8e477b0a..0000000000 --- a/src/server/bnetserver/Packets/AuthenticationPackets.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef AuthenticationPackets_h__ -#define AuthenticationPackets_h__ - -#include "PacketsBase.h" -#include "ComponentManager.h" -#include "ModuleManager.h" - -namespace Battlenet -{ - namespace Authentication - { - enum Opcode - { - CMSG_LOGON_REQUEST = 0x0, - CMSG_RESUME_REQUEST = 0x1, - CMSG_PROOF_RESPONSE = 0x2, - - SMSG_LOGON_RESPONSE = 0x0, - SMSG_RESUME_RESPONSE = 0x1, - SMSG_PROOF_REQUEST = 0x2, - SMSG_PATCH = 0x3, // Not implemented - SMSG_AUTHORIZED_LICENSES = 0x4 // Not implemented - }; - - class LogonRequest final : public ClientPacket - { - public: - LogonRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST, AUTHENTICATION) && "Invalid packet header for LogonRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - std::string Program; - std::string Platform; - std::string Locale; - std::vector Components; - std::string Login; - }; - - class ResumeRequest final : public ClientPacket - { - public: - ResumeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_RESUME_REQUEST, AUTHENTICATION) && "Invalid packet header for ResumeRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - std::string Program; - std::string Platform; - std::string Locale; - std::vector Components; - std::string Login; - uint8 GameAccountRegion = 0; - std::string GameAccountName; - }; - - class ProofResponse final : public ClientPacket - { - public: - ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse"); - } - - ~ProofResponse(); - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - std::vector Modules; - }; - - class ResponseFailure - { - public: - enum Result - { - UPDATE = 0, - FAILURE = 1, - VERSION_CHECK_DISCONNECT = 2 - }; - - ResponseFailure() : ResultValue(UPDATE), Error(AUTH_OK), Wait(0) { } - - Result ResultValue; - AuthResult Error; - int32 Wait; - }; - - class Regulator - { - public: - enum Info - { - NONE = 0, - LEAKY_BUCKET = 1 - }; - - Regulator() : Type(LEAKY_BUCKET), Threshold(25000000), Rate(1000) { } - - Info Type; - uint32 Threshold; - uint32 Rate; - }; - - class LogonResponse final : public ServerPacket - { - public: - LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION)), - PingTimeout(120000), AccountId(0), Region(2), Flags(0), - GameAccountRegion(2), GameAccountFlags(0), FailedLogins(0) - { - } - - ~LogonResponse(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - void SetAuthResult(AuthResult result); - ResponseFailure Result; - - int32 PingTimeout; - Regulator RegulatorRules; - std::string FirstName; - std::string LastName; - uint32 AccountId; - uint8 Region; - uint64 Flags; - uint8 GameAccountRegion; - std::string GameAccountName; - uint64 GameAccountFlags; - - uint32 FailedLogins; - }; - - class ResumeResponse final : public ServerPacket - { - public: - ResumeResponse() : ServerPacket(PacketHeader(SMSG_RESUME_RESPONSE, AUTHENTICATION)), PingTimeout(120000) - { - } - - ~ResumeResponse(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - void SetAuthResult(AuthResult result); - ResponseFailure Result; - - int32 PingTimeout; - Regulator RegulatorRules; - }; - - class ProofRequest final : public ServerPacket - { - public: - ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { } - ~ProofRequest(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - }; - } -} - -#endif // AuthenticationPackets_h__ diff --git a/src/server/bnetserver/Packets/BitStream.h b/src/server/bnetserver/Packets/BitStream.h deleted file mode 100644 index db412048e6..0000000000 --- a/src/server/bnetserver/Packets/BitStream.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BitStream_h__ -#define BitStream_h__ - -#include "Common.h" -#include "ByteConverter.h" -#include "MessageBuffer.h" -#include -#include -#include -#include - -namespace Battlenet -{ - class BitStreamPositionException : public std::exception - { - static uint32 const MessageSize = 128; - - public: - BitStreamPositionException(bool read, uint32 operationSize, uint32 position, uint32 streamSize) - { - memset(_message, 0, MessageSize); - snprintf(_message, MessageSize, "Attempted to %s more bits (%u) %s stream than %s (%u)\n", - (read ? "read" : "write"), - operationSize + position, - (read ? "from" : "to"), - (read ? "exist" : "allowed"), - streamSize); - } - - char const* what() const throw() - { - return _message; - } - - private: - char _message[MessageSize]; - }; - - class BitStream - { - public: - static uint32 const MaxSize = 0x4000; - - // length : The maximum number of bytes to read - BitStream(uint32 length) : _writePos(length * 8), _readPos(0) - { - _buffer.resize(length, 0); - } - - BitStream(MessageBuffer&& buffer) : _writePos(buffer.GetActiveSize() * 8), _readPos(0), _buffer(buffer.Move()) - { - } - - BitStream() : _writePos(0), _readPos(0) - { - _buffer.reserve(0x1000); - } - - void AlignToNextByte() - { - _readPos = (_readPos + 7) & ~7; - _writePos = (_writePos + 7) & ~7; - } - - std::string ReadString(uint32 bitCount, int32 baseLength = 0) - { - uint32 len = Read(bitCount) + baseLength; - AlignToNextByte(); - std::string str(reinterpret_cast(&_buffer[_readPos >> 3]), len); - _readPos += len * 8; - return str; - } - - std::unique_ptr ReadBytes(uint32 count) - { - AlignToNextByte(); - if (_readPos + count * 8 > _writePos) - throw BitStreamPositionException(true, count * 8, _readPos, _writePos); - - std::unique_ptr buf(new uint8[count]); - memcpy(buf.get(), &_buffer[_readPos >> 3], count); - _readPos += count * 8; - return buf; - } - - float ReadFloat() - { - uint32 val = Read(32); - return *reinterpret_cast(&val); - } - - std::string ReadFourCC() - { - uint32 fcc = Read(32); - EndianConvertReverse(fcc); - size_t len = 4; - while (!(fcc & 0xFF) && len) - { - fcc >>= 8; - --len; - } - - return std::string(reinterpret_cast(&fcc), len); - } - - template - T Read(uint32 bitCount) - { - static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type"); - - if (_readPos + bitCount > _writePos) - throw BitStreamPositionException(true, bitCount, _readPos, _writePos); - - uint64 ret = 0; - while (bitCount != 0) - { - uint32 bitPos = (_readPos & 7); - uint32 bitsLeftInByte = 8 - bitPos; - if (bitsLeftInByte >= bitCount) - bitsLeftInByte = bitCount; - - bitCount -= bitsLeftInByte; - ret |= (uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount; - _readPos += bitsLeftInByte; - } - - return static_cast(ret); - } - - void WriteString(std::string const& str, uint32 bitCount, int32 baseLength = 0) - { - Write(str.length() + baseLength, bitCount); - WriteBytes(str.c_str(), str.length()); - } - - template - void WriteBytes(T* data, uint32 count) - { - AlignToNextByte(); - if (!count || !data) - return; - - if ((_writePos >> 3) + count > MaxSize) - throw BitStreamPositionException(false, count * 8, _writePos, MaxSize * 8); - - _buffer.resize(_buffer.size() + count); - memcpy(&_buffer[_writePos >> 3], data, count); - _writePos += count * 8; - } - - void WriteFloat(float value) - { - uint32 intVal = *reinterpret_cast(&value); - Write(intVal, 32); - } - - void WriteFourCC(std::string const& fcc) - { - uint32 intVal = *(uint32*)fcc.c_str(); - size_t len = fcc.length(); - EndianConvertReverse(intVal); - // Add padding - while (len++ < 4) - intVal >>= 8; - - Write(intVal, 32); - } - - template - void Write(T value, uint32 bitCount) - { - static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type"); - - if (_writePos + bitCount > 8 * MaxSize) - throw BitStreamPositionException(false, bitCount, _writePos, MaxSize * 8); - - while (bitCount != 0) - { - uint32 bitPos = (_writePos & 7); - uint32 bitsLeftInByte = 8 - bitPos; - if (bitsLeftInByte >= bitCount) - bitsLeftInByte = bitCount; - - bitCount -= bitsLeftInByte; - - uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos)); - uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos); - - if (_buffer.size() > (_writePos >> 3)) - _buffer[_writePos >> 3] = (uint8)((_buffer[_writePos >> 3] & firstHalf) | secondHalf); - else - _buffer.push_back(secondHalf); - - _writePos += bitsLeftInByte; - } - } - - bool IsRead() const { return _readPos >= _writePos; } - - uint8* GetBuffer() { return _buffer.data(); } - uint8 const* GetBuffer() const { return _buffer.data(); } - - uint32 GetReadPos() const { return _readPos; } - size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; } - - // These methods are meant to only be used when their corresponding actions in the client ignore the value completely - void ReadSkip(uint32 bitCount) { _readPos += bitCount; } - void WriteSkip(uint32 bitCount) { Write(0, bitCount); } - - private: - uint32 _writePos; - uint32 _readPos; - std::vector _buffer; - }; - - template<> - bool BitStream::Read(uint32 bitCount); - - template<> - void BitStream::Write(bool value, uint32 bitCount); -} - -#endif // BitStream_h__ diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp deleted file mode 100644 index b899896ebe..0000000000 --- a/src/server/bnetserver/Packets/CachePackets.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Session.h" -#include "Util.h" -#include "CachePackets.h" - -void Battlenet::Cache::GetStreamItemsRequest::Read() -{ - if (_stream.Read(1)) - { - _stream.Read(11); // padding - ItemName = _stream.ReadFourCC(); - Channel = _stream.ReadFourCC(); - } - else - _stream.Read(16); - - _stream.Read(1); // StreamDirection - ReferenceTime = _stream.Read(32) - std::numeric_limits::min(); - Locale = _stream.ReadFourCC(); - Index = _stream.Read(32); - _stream.Read(6); // Module count, always 0 -} - -std::string Battlenet::Cache::GetStreamItemsRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Cache::GetStreamItemsRequest Channel: " << Channel << ", ItemName: " << ItemName - << ", Locale: " << Locale << ", Index: " << Index; - return stream.str(); -} - -void Battlenet::Cache::GetStreamItemsRequest::CallHandler(Session* session) -{ - session->HandleGetStreamItemsRequest(*this); -} - -Battlenet::Cache::GetStreamItemsResponse::~GetStreamItemsResponse() -{ - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; -} - -void Battlenet::Cache::GetStreamItemsResponse::Write() -{ - _stream.Write(0, 16); - _stream.Write(Modules.size(), 6); - for (ModuleInfo const* info : Modules) - { - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.WriteBytes(info->Data, 4); - } - - _stream.Write(Index, 32); - _stream.Write(0, 17); // padding - _stream.Write(1, 16); - _stream.Write(0, 2); -} - -std::string Battlenet::Cache::GetStreamItemsResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Cache::GetStreamItemsResponse modules " << Modules.size(); - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h deleted file mode 100644 index 683ec90a10..0000000000 --- a/src/server/bnetserver/Packets/CachePackets.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CachePackets_h__ -#define CachePackets_h__ - -#include "ModuleManager.h" -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Cache - { - enum Opcode - { - CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented - CMSG_CONNECT_REQUEST = 0x4, // Not implemented - CMSG_DATA_CHUNK = 0x7, // Not implemented - CMSG_GET_STREAM_ITEMS_REQUEST = 0x9, - - SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented - SMSG_CONNECT_RESPONSE = 0x4, // Not implemented - SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented - SMSG_RESULT = 0x8, // Not implemented - SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 - }; - - class GetStreamItemsRequest final : public ClientPacket - { - public: - GetStreamItemsRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_GET_STREAM_ITEMS_REQUEST, CACHE) && "Invalid packet header for GetStreamItemsRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - std::string Channel; - std::string ItemName; - std::string Locale; - uint32 Index =0; - int32 ReferenceTime =0; - }; - - class GetStreamItemsResponse final : public ServerPacket - { - public: - GetStreamItemsResponse() : ServerPacket(PacketHeader(SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE)) - { - } - - ~GetStreamItemsResponse(); - - void Write() override; - std::string ToString() const override; - - uint32 Index =0; - std::vector Modules; - }; - } -} - -#endif // CachePackets_h__ diff --git a/src/server/bnetserver/Packets/ChatPackets.h b/src/server/bnetserver/Packets/ChatPackets.h deleted file mode 100644 index 78c8a5a3ae..0000000000 --- a/src/server/bnetserver/Packets/ChatPackets.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ChatPackets_h__ -#define ChatPackets_h__ - -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Chat - { - enum Opcode - { - CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented - CMSG_LEAVE_REQUEST = 0x02, // Not implemented - CMSG_INVITE_REQUEST = 0x03, // Not implemented - CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented - CMSG_MESSAGE_SEND = 0x0B, // Not implemented - CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented - CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented - CMSG_WHISPER_SEND = 0x13, // Not implemented - CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented - CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented - CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented - CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented - - SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented - SMSG_INVITE_NOTIFY = 0x04, // Not implemented - SMSG_INVITE_CANCELED = 0x07, // Not implemented - SMSG_MESSAGE_RECV = 0x0B, // Not implemented - SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented - SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented - SMSG_INVITE_FAILURE = 0x0F, // Not implemented - SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented - SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented - SMSG_WHISPER_RECV = 0x13, // Not implemented - SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented - SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented - SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented - SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented - SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented - SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Not implemented - SMSG_CONFIG_CHANGED = 0x1D // Not implemented - }; - } -} - -#endif // ChatPackets_h__ diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp deleted file mode 100644 index 1b49b851f3..0000000000 --- a/src/server/bnetserver/Packets/ConnectionPackets.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Session.h" -#include "ConnectionPackets.h" - -std::string Battlenet::Connection::Ping::ToString() const -{ - return "Battlenet::Connection::Ping"; -} - -void Battlenet::Connection::Ping::CallHandler(Session* session) -{ - session->HandlePing(*this); -} - -std::string Battlenet::Connection::EnableEncryption::ToString() const -{ - return "Battlenet::Connection::EnableEncryption"; -} - -void Battlenet::Connection::EnableEncryption::CallHandler(Session* session) -{ - session->HandleEnableEncryption(*this); -} - -std::string Battlenet::Connection::LogoutRequest::ToString() const -{ - return "Battlenet::Connection::LogoutRequest"; -} - -void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) -{ - session->HandleLogoutRequest(*this); -} - -void Battlenet::Connection::DisconnectRequest::Read() -{ - Timeout = _stream.Read(16); - Tick = _stream.Read(32); -} - -std::string Battlenet::Connection::DisconnectRequest::ToString() const -{ - std::ostringstream str; - str << "Battlenet::Connection::DisconnectRequest Timeout: " << Timeout << ", Tick: " << Tick; - return str.str(); -} - -void Battlenet::Connection::ConnectionClosing::Read() -{ - Reason = _stream.Read(4); - if (_stream.Read(1)) // HasHeader - { - Header.Opcode = _stream.Read(6); - if (_stream.Read(1)) - Header.Channel = _stream.Read(4); - } - - Now = _stream.Read(32); - _stream.Read(25); - auto bytes = _stream.ReadBytes(_stream.Read(8)); // BadData - Packets.resize(_stream.Read(6)); - for (size_t i = 0; i < Packets.size(); ++i) - { - PacketInfo& info = Packets[i]; - info.CommandName = _stream.ReadFourCC(); - info.LayerId = _stream.Read(16); - info.Channel = _stream.ReadFourCC(); - info.Timestamp = _stream.Read(32); - info.Size = _stream.Read(16); - } -} - -std::string Battlenet::Connection::ConnectionClosing::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Connection::ConnectionClosing Reason: " << Reason << ", Now: " << Now << ", Packet history size: " << Packets.size(); - for (PacketInfo const& packet : Packets) - stream << std::endl << "Battlenet::Connection::ConnectionClosing::PacketInfo LayerId: " << packet.LayerId - << ", Channel: " << packet.Channel << ", CommandName: " << packet.CommandName << ", Size: " << packet.Size << ", Timestamp: " << packet.Timestamp; - - return stream.str(); -} - -void Battlenet::Connection::ConnectionClosing::CallHandler(Session* session) -{ - session->HandleConnectionClosing(*this); -} - -std::string Battlenet::Connection::Pong::ToString() const -{ - return "Battlenet::Connection::Pong"; -} diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h deleted file mode 100644 index 104f59e055..0000000000 --- a/src/server/bnetserver/Packets/ConnectionPackets.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ConnectionPackets_h__ -#define ConnectionPackets_h__ - -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Connection - { - enum Opcode - { - CMSG_PING = 0x0, - CMSG_ENABLE_ENCRYPTION = 0x5, - CMSG_LOGOUT_REQUEST = 0x6, - CMSG_DISCONNECT_REQUEST = 0x7, // Not handled - CMSG_CONNECTION_CLOSING = 0x9, - - SMSG_PONG = 0x0, - SMSG_BOOM = 0x1, // Not implemented - SMSG_REGULATOR_UPDATE = 0x2, // Not implemented - SMSG_SERVER_VERSION = 0x3, // Not implemented - SMSG_STUN_SERVERS = 0x4 // Not implemented - }; - - class Ping final : public ClientPacket - { - public: - Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) override; - }; - - class EnableEncryption final : public ClientPacket - { - public: - EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) override; - uint8* GetRemainingData() { return _stream.GetBuffer() + (((_stream.GetReadPos() + 7) & ~7) / 8); } - size_t GetRemainingSize() const { return _stream.GetSize() - (((_stream.GetReadPos() + 7) & ~7) / 8); } - }; - - class LogoutRequest final : public ClientPacket - { - public: - LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) override; - }; - - class DisconnectRequest final : public ClientPacket - { - public: - DisconnectRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_DISCONNECT_REQUEST, CONNECTION) && "Invalid packet header for DisconnectRequest"); - } - - void Read() override; - std::string ToString() const override; - - uint16 Timeout =0; - uint32 Tick =0; - }; - - class ConnectionClosing final : public ClientPacket - { - public: - enum ClosingReason - { - PACKET_TOO_LARGE = 1, - PACKET_CORRUPT = 2, - PACKET_INVALID = 3, - PACKET_INCORRECT = 4, - HEADER_CORRUPT = 5, - HEADER_IGNORED = 6, - HEADER_INCORRECT = 7, - PACKET_REJECTED = 8, - CHANNEL_UNHANDLED = 9, - COMMAND_UNHANDLED = 10, - COMMAND_BAD_PERMISSIONS = 11, - DIRECT_CALL = 12, - TIMEOUT = 13 - }; - - struct PacketInfo - { - uint16 LayerId; - std::string Channel; - uint32 Timestamp; - std::string CommandName; - uint16 Size; - }; - - ConnectionClosing(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_CONNECTION_CLOSING, CONNECTION) && "Invalid packet header for ConnectionClosing"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - PacketHeader Header; - ClosingReason Reason = PACKET_CORRUPT; - std::vector Packets; - time_t Now = 0; - }; - - class Pong final : public ServerPacket - { - public: - Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION)) - { - } - - void Write() override { } - std::string ToString() const override; - }; - } -} - -#endif // ConnectionPackets_h__ diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp deleted file mode 100644 index d90d9f36d0..0000000000 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Session.h" -#include "FriendsPackets.h" - -void Battlenet::Friends::GetFriendsOfFriend::Read() -{ - _stream.Read(2); - _stream.Read(32); -} - -std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const -{ - return "Battlenet::Friends::GetFriendsOfFriend"; -} - -void Battlenet::Friends::SocialNetworkCheckConnected::Read() -{ - SocialNetworkId = _stream.Read(32); -} - -std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const -{ - return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); -} - -void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) -{ - session->HandleSocialNetworkCheckConnected(*this); -} - -void Battlenet::Friends::RealIdFriendInvite::Read() -{ - _stream.Read(32); - uint8 type = _stream.Read(3); - - switch (type) - { - case 0: - { - _stream.Read(32); // Presence Id? - break; - } - case 1: // GameAccount? - { - _stream.Read(8); - _stream.Read(32); - _stream.Read(32); - uint8 size = _stream.Read(7); // Only if *(a1 + 16) <= 0x64 - _stream.ReadBytes(size); - break; - } - case 2: - Email = _stream.ReadString(9, 3); - break; - case 3: - { - _stream.Read(32); - break; - } - case 4: - { - _stream.Read(64); - _stream.Read(32); - break; - } - } - - _stream.Read(1); - - if (_stream.Read(1)) - Message = _stream.ReadString(9); - - _stream.Read(32); -} - -std::string Battlenet::Friends::RealIdFriendInvite::ToString() const -{ - return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; -} - -std::string Battlenet::Friends::FriendInviteResult::ToString() const -{ - return "Battlenet::Friends::RealIdFriendInviteResult"; -} - -void Battlenet::Friends::FriendInviteResult::Write() -{ - bool hasNames = false; - _stream.Write(hasNames, 1); - if (hasNames) - { - _stream.WriteString("Testing1", 8); - _stream.WriteString("Testing2", 8); - } - _stream.Write(5, 32); - - _stream.Write(0, 0xC); // Ignored - - _stream.Write(1, 16); - - bool moreInfo = true; - _stream.Write(moreInfo, 1); - if (moreInfo) - { - _stream.Write(0, 8); - _stream.Write(4, 32); - _stream.Write(3, 32); - _stream.WriteString("Testing3", 7, 2); - } -} - -std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const -{ - return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; -} - -void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() -{ - _stream.WriteSkip(23); - _stream.Write(Result, 16); - _stream.Write(SocialNetworkId, 32); -} diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h deleted file mode 100644 index 1b628b2d19..0000000000 --- a/src/server/bnetserver/Packets/FriendsPackets.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef FriendsPackets_h__ -#define FriendsPackets_h__ - -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Friends - { - enum Opcode - { - CMSG_FRIEND_INVITE = 0x01, // Not implemented - CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented - CMSG_FRIEND_REMOVE = 0x04, // Not implemented - CMSG_FRIEND_NOTE = 0x05, // Not implemented - CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented - CMSG_BLOCK_ADD = 0x08, // Not implemented - CMSG_BLOCK_REMOVE = 0x0A, // Not implemented - CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented - CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Won't support - CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Won't support - CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Won't support - CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, - CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented - - SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented - SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented - SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented - SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented - SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented - SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented - SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Won't support - SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Won't support - SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Won't support - SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, - SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented - SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented - }; - - class GetFriendsOfFriend final : public ClientPacket - { - public: - GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); - } - - void Read() override; - std::string ToString() const override; - }; - - class SocialNetworkCheckConnected final : public ClientPacket - { - public: - SocialNetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - uint32 SocialNetworkId =0; - }; - - class RealIdFriendInvite final : public ClientPacket - { - public: - RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); - } - - void Read() override; - std::string ToString() const override; - - std::string Email; - std::string Message; - }; - - class FriendInviteResult final : public ServerPacket - { - public: - FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - - class FriendsOfFriend final : public ServerPacket - { - public: - FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - - class SocialNetworkCheckConnectedResult final : public ServerPacket - { - public: - SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), - Result(4601), SocialNetworkId(0) // 4601 = The Facebook add friend service is unavailable right now. Please try again later. - { - } - - void Write() override; - std::string ToString() const override; - - uint16 Result; - uint32 SocialNetworkId; - }; - } -} - -#endif // FriendsPackets_h__ diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp deleted file mode 100644 index 9daa777ecb..0000000000 --- a/src/server/bnetserver/Packets/PacketManager.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "PacketManager.h" - -Battlenet::ClientPacket* Battlenet::PacketManager::CreateClientPacket(PacketHeader const& header, BitStream& stream) -{ - auto packetInfo = _clientPacketTable.find(header); - if (packetInfo == _clientPacketTable.end()) - return nullptr; - - if (!packetInfo->second.Constructor) - return nullptr; - - ClientPacket* packet = packetInfo->second.Constructor(header, stream); - packet->Read(); - return packet; -} - -char const* Battlenet::PacketManager::GetClientPacketName(PacketHeader const& header) -{ - auto packetInfo = _clientPacketTable.find(header); - if (packetInfo == _clientPacketTable.end()) - return nullptr; - - return packetInfo->second.Name; -} - -char const* Battlenet::PacketManager::GetServerPacketName(PacketHeader const& header) -{ - auto packetInfo = _serverPacketTable.find(header); - if (packetInfo == _serverPacketTable.end()) - return nullptr; - - return packetInfo->second.Name; -} - -bool Battlenet::PacketManager::IsHandled(PacketHeader const& header) -{ - auto packetInfo = _clientPacketTable.find(header); - if (packetInfo == _clientPacketTable.end()) - return false; - - return packetInfo->second.HasHandler; -} - -Battlenet::PacketManager::PacketManager() -{ - RegisterAuthenticationPackets(); - RegisterConnectionPackets(); - RegisterWoWRealmPackets(); - RegisterFriendsPackets(); - RegisterPresencePackets(); - RegisterChatPackets(); - RegisterSupportPackets(); - RegisterCachePackets(); - RegisterAchievementPackets(); - RegisterProfilePackets(); -} - -#define REGISTER_CLIENT_PACKET(header, packetClass) RegisterClientPacket(header, #packetClass) -#define REGISTER_SERVER_PACKET(header, packetClass) RegisterPacketName(_serverPacketTable, header, #packetClass) -#define REGISTER_CLIENT_PACKET_NAME(header, name) RegisterPacketName(_clientPacketTable, header, name) -#define REGISTER_SERVER_PACKET_NAME(header, name) RegisterPacketName(_serverPacketTable, header, name) - -void Battlenet::PacketManager::RegisterAuthenticationPackets() -{ - REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), Authentication::LogonRequest); - REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION), Authentication::ResumeRequest); - REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION), Authentication::ProofResponse); - - REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_LOGON_RESPONSE, AUTHENTICATION), Authentication::LogonResponse); - REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_RESUME_RESPONSE, AUTHENTICATION), Authentication::ResumeResponse); - REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_PROOF_REQUEST, AUTHENTICATION), Authentication::ProofRequest); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_PATCH, AUTHENTICATION), "Authentication::Patch"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_AUTHORIZED_LICENSES, AUTHENTICATION), "Authentication::AuthorizedLicenses"); -} - -void Battlenet::PacketManager::RegisterConnectionPackets() -{ - REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_PING, CONNECTION), Connection::Ping); - REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION), Connection::EnableEncryption); - REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION), Connection::LogoutRequest); - REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION), Connection::DisconnectRequest); - REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION), Connection::ConnectionClosing); - - REGISTER_SERVER_PACKET(PacketHeader(Connection::SMSG_PONG, CONNECTION), Connection::Pong); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_BOOM, CONNECTION), "Connection::Boom"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_REGULATOR_UPDATE, CONNECTION), "Connection::RegulatorUpdate"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_SERVER_VERSION, CONNECTION), "Connection::ServerVersion"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_STUN_SERVERS, CONNECTION), "Connection::STUNServers"); -} - -void Battlenet::PacketManager::RegisterWoWRealmPackets() -{ - REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM), WoWRealm::ListSubscribeRequest); - REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM), WoWRealm::ListUnsubscribe); - REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM), WoWRealm::JoinRequestV2); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(WoWRealm::CMSG_MULTI_LOGON_REQUEST_V2, WOWREALM), "WoWRealm::MultiLogonRequestV2"); - - REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM), WoWRealm::ListSubscribeResponse); - REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_UPDATE, WOWREALM), WoWRealm::ListUpdate); - REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_COMPLETE, WOWREALM), WoWRealm::ListComplete); - REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), WoWRealm::ToonReady); - REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), WoWRealm::ToonLoggedOut); - REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_JOIN_RESPONSE_V2, WOWREALM), WoWRealm::JoinResponseV2); -} - -void Battlenet::PacketManager::RegisterFriendsPackets() -{ - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE, FRIENDS), "Friends::FriendInvite"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE_RESPONSE, FRIENDS), "Friends::FriendInviteResponse"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_REMOVE, FRIENDS), "Friends::FriendRemove"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_NOTE, FRIENDS), "Friends::FriendNote"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_TOONS_OF_FRIEND_REQUEST, FRIENDS), "Friends::ToonsOfFriendRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_ADD, FRIENDS), "Friends::BlockAdd"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_REMOVE, FRIENDS), "Friends::BlockRemove"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), "Friends::GetFriendsOfFriend"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::GetSocialNetworkFriends"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS), "Friends::SocialNetworkConnect"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_DISCONNECT, FRIENDS), "Friends::SocialNetworkDisconnect"); - REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), Friends::SocialNetworkCheckConnected); - REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), Friends::GetFriendsOfFriend); - REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS), Friends::RealIdFriendInvite); - - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITE_NOTIFY, FRIENDS), "Friends::FriendInviteNotify"); - REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_FRIEND_INVITE_RESULT, FRIENDS), Friends::FriendInviteResult); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_TOONS_OF_FRIEND_NOTIFY, FRIENDS), "Friends::ToonsOfFriendNotify"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_INVITE_NOTIFY, FRIENDS), "Friends::BlockInviteNotify"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_ADD_FAILURE, FRIENDS), "Friends::BlockAddFailure"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_OF_FRIEND, FRIENDS), "Friends::FriendsOfFriend"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::SocialNetworkFriends"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS), "Friends::SocialNetworkConnectResult"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT, FRIENDS), "Friends::SocialNetworkDisconnectResult"); - REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS), Friends::SocialNetworkCheckConnectedResult); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_MAX_FRIENDS_NOTIFY, FRIENDS), "Friends::MaxFriendsNotify"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_LIST_NOTIFY_3, FRIENDS), "Friends::FriendsListNotify3"); -} - -void Battlenet::PacketManager::RegisterPresencePackets() -{ - REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), Presence::UpdateRequest); - REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE), Presence::StatisticSubscribe); - - REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_UPDATE_NOTIFY, PRESENCE), "Presence::UpdateNotify"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_FIELD_SPEC_ANNOUNCE, PRESENCE), "Presence::FieldSpecAnnounce"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_STATISTICS_UPDATE, PRESENCE), "Presence::StatisticsUpdate"); -} - -void Battlenet::PacketManager::RegisterChatPackets() -{ - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_JOIN_REQUEST_2, CHAT), "Chat::JoinRequest2"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_LEAVE_REQUEST, CHAT), "Chat::LeaveRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_INVITE_REQUEST, CHAT), "Chat::InviteRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_CREATE_AND_INVITE_REQUEST, CHAT), "Chat::CreateAndInviteRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MESSAGE_SEND, CHAT), "Chat::MessageSend"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_REPORT_SPAM_REQUEST, CHAT), "Chat::ReportSpamRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_WHISPER_SEND, CHAT), "Chat::WhisperSend"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CATEGORY_DESCRIPTIONS, CHAT), "Chat::EnumCategoryDescriptions"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::EnumConferenceDescriptions"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::EnumConferenceMemberCounts"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MODIFY_CHANNEL_LIST_REQUEST, CHAT), "Chat::ModifyChannelListRequest"); - - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MEMBERSHIP_CHANGE_NOTIFY, CHAT), "Chat::MembershipChangeNotify"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_NOTIFY, CHAT), "Chat::InviteNotify"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_CANCELED, CHAT), "Chat::InviteCanceled"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_RECV, CHAT), "Chat::MessageRecv"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_UNDELIVERABLE, CHAT), "Chat::MessageUndeliverable"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_FAILURE, CHAT), "Chat::InviteFailed"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_SYSTEM_MESSAGE, CHAT), "Chat::SystemMessage"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_BLOCKED, CHAT), "Chat::MessageBlocked"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_RECV, CHAT), "Chat::WhisperRecv"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_UNDELIVERABLE, CHAT), "Chat::WhisperUndeliverable"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CATEGORY_DESCRIPTIONS, CHAT), "Chat::CategoryDescriptions"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::ConferenceDescriptions"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::ConferenceMemberCounts"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_JOIN_NOTIFY_2, CHAT), "Chat::JoinNotify2"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MODIFY_CHANNEL_LIST_RESPONSE, CHAT), "Chat::ModifyChannelListResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFIG_CHANGED, CHAT), "Chat::ConfigChanged"); -} - -void Battlenet::PacketManager::RegisterSupportPackets() -{ - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Support::CMSG_COMPLAINT_REQUEST, SUPPORT), "Support::ComplaintRequest"); -} - -void Battlenet::PacketManager::RegisterAchievementPackets() -{ - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_LISTEN_REQUEST, ACHIEVEMENT), "Achievement::ListenRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CRITERIA_FLUSH_REQUEST, ACHIEVEMENT), "Achievement::CriteriaFlushRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CHANGE_TROPHY_CASE_REQUEST, ACHIEVEMENT), "Achievement::ChangeTrophyCaseRequest"); - - REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_DATA, ACHIEVEMENT), "Achievement::Data"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CRITERIA_FLUSH_RESPONSE, ACHIEVEMENT), "Achievement::CriteriaFlushResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_ACHIEVEMENT_HANDLE_UPDATE, ACHIEVEMENT), "Achievement::AchievementHandleUpdate"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CHANGE_TROPHY_CASE_RESULT, ACHIEVEMENT), "Achievement::ChangeTrophyCaseResult"); -} - -void Battlenet::PacketManager::RegisterCachePackets() -{ - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_GATEWAY_LOOKUP_REQUEST, CACHE), "Cache::GatewayLookupRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_CONNECT_REQUEST, CACHE), "Cache::ConnectRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_DATA_CHUNK, CACHE), "Cache::DataChunk"); - REGISTER_CLIENT_PACKET(PacketHeader(Cache::CMSG_GET_STREAM_ITEMS_REQUEST, CACHE), Cache::GetStreamItemsRequest); - - REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GATEWAY_LOOKUP_RESPONSE, CACHE), "Cache::GatewayLookupResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_CONNECT_RESPONSE, CACHE), "Cache::ConnectResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_PUBLISH_LIST_RESPONSE, CACHE), "Cache::PublishListResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_RESULT, CACHE), "Cache::Result"); - REGISTER_SERVER_PACKET(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), Cache::GetStreamItemsResponse); -} - -void Battlenet::PacketManager::RegisterProfilePackets() -{ - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_READ_REQUEST, PROFILE), "Profile::ReadRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_ADDRESS_QUERY_REQUEST, PROFILE), "Profile::AddressQueryRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST, PROFILE), "Profile::ResolveHandleToToonNameRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST, PROFILE), "Profile::ResolveToonNameToHandleRequest"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_CHANGE_SETTINGS, PROFILE), "Profile::ChangeSettings"); - - REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_READ_RESPONSE, PROFILE), "Profile::ReadResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_ADDRESS_QUERY_RESPONSE, PROFILE), "Profile::AddressQueryResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE, PROFILE), "Profile::ResolveHandleToToonNameResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE, PROFILE), "Profile::ResolveToonNameToHandleResponse"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_SETTINGS_AVAILABLE, PROFILE), "Profile::SettingsAvailable"); -} diff --git a/src/server/bnetserver/Packets/PacketManager.h b/src/server/bnetserver/Packets/PacketManager.h deleted file mode 100644 index 90946d1c0c..0000000000 --- a/src/server/bnetserver/Packets/PacketManager.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef PacketManager_h__ -#define PacketManager_h__ - -#include "Packets.h" -#include -#include - -template -struct has_call_handler -{ - template struct test_has_call_handler { }; - template static char Test(test_has_call_handler*); - template static int Test(...); - static const bool value = sizeof(Test(nullptr)) == sizeof(char); -}; - -namespace Battlenet -{ - class PacketManager - { - typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream); - - struct PacketInfo - { - PacketCreateFn Constructor; - char const* Name; - bool HasHandler; - }; - - PacketManager(); - - void RegisterAuthenticationPackets(); - void RegisterConnectionPackets(); - void RegisterWoWRealmPackets(); - void RegisterFriendsPackets(); - void RegisterPresencePackets(); - void RegisterChatPackets(); - void RegisterSupportPackets(); - void RegisterAchievementPackets(); - void RegisterCachePackets(); - void RegisterProfilePackets(); - - template - static ClientPacket* New(PacketHeader const& header, BitStream& stream) - { - return new PacketType(header, stream); - } - - void RegisterPacketName(std::map& packetTable, PacketHeader const& header, char const* name) - { - PacketInfo& info = packetTable[header]; - info.Constructor = nullptr; - info.Name = name; - info.HasHandler = false; - } - - template - void RegisterClientPacket(PacketHeader const& header, char const* name) - { - PacketInfo& info = _clientPacketTable[header]; - info.Constructor = &New; - info.Name = name; - info.HasHandler = has_call_handler::value; - } - - public: - ClientPacket* CreateClientPacket(PacketHeader const& header, BitStream& stream); - - char const* GetClientPacketName(PacketHeader const& header); - char const* GetServerPacketName(PacketHeader const& header); - - bool IsHandled(PacketHeader const& header); - - static PacketManager& Instance() - { - static PacketManager instance; - return instance; - } - - private: - std::map _clientPacketTable; - std::map _serverPacketTable; - }; -} - -#define sPacketManager Battlenet::PacketManager::Instance() - -#endif // PacketManager_h__ diff --git a/src/server/bnetserver/Packets/Packets.h b/src/server/bnetserver/Packets/Packets.h deleted file mode 100644 index 7f659d8c45..0000000000 --- a/src/server/bnetserver/Packets/Packets.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef Packets_h__ -#define Packets_h__ - -#include "AuthenticationPackets.h" -#include "ConnectionPackets.h" -#include "WoWRealmPackets.h" -#include "FriendsPackets.h" -#include "PresencePackets.h" -#include "ChatPackets.h" -#include "SupportPackets.h" -#include "AchievementPackets.h" -#include "CachePackets.h" -#include "ProfilePackets.h" - -#endif // Packets_h__ diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp deleted file mode 100644 index 19cc450376..0000000000 --- a/src/server/bnetserver/Packets/PacketsBase.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Packets.h" -#include "Session.h" -#include - -std::string Battlenet::PacketHeader::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel; - return stream.str(); -} - -Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream()) -{ - _stream.Write(header.Opcode, 6); - _stream.Write(1, 1); - _stream.Write(header.Channel, 4); -} - -Battlenet::ServerPacket::~ServerPacket() -{ - delete &_stream; -} - -void Battlenet::ClientPacket::CallHandler(Session* session) -{ - session->LogUnhandledPacket(GetHeader()); -} diff --git a/src/server/bnetserver/Packets/PacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h deleted file mode 100644 index bae5886608..0000000000 --- a/src/server/bnetserver/Packets/PacketsBase.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef PacketsBase_h__ -#define PacketsBase_h__ - -#include "AuthCodes.h" -#include "BitStream.h" -#include "Define.h" -#include "Errors.h" -#include -#include - -using boost::asio::ip::tcp; - -namespace Battlenet -{ - class BitStream; - class Session; - - enum Channel - { - AUTHENTICATION = 0, - CONNECTION = 1, - WOWREALM = 2, - FRIENDS = 3, - PRESENCE = 4, - CHAT = 5, - SUPPORT = 7, - ACHIEVEMENT = 8, - CACHE = 11, - PROFILE = 14 - }; - - struct PacketHeader - { - PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { } - PacketHeader() : Opcode(0), Channel(AUTHENTICATION) { } - - uint32 Opcode; - int32 Channel; - - bool operator<(PacketHeader const& right) const - { - if (Opcode < right.Opcode) - return true; - if (Opcode > right.Opcode) - return false; - - return Channel < right.Channel; - } - - bool operator==(PacketHeader const& right) const - { - return Opcode == right.Opcode && Channel == right.Channel; - } - - std::string ToString() const; - }; - - class Packet - { - public: - Packet(PacketHeader const& header, BitStream& stream) : _header(header), _stream(stream) { } - virtual ~Packet() { } - - PacketHeader const& GetHeader() const { return _header; } - - virtual void Write() = 0; - virtual void Read() = 0; - - virtual std::string ToString() const = 0; - - protected: - PacketHeader _header; - BitStream& _stream; - - private: - Packet(Packet const& right); - Packet& operator=(Packet const& right); - }; - - class ClientPacket : public Packet - { - public: - ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } - - void Write() override final { ASSERT(!"Write not implemented for client packets."); } - virtual void CallHandler(Session* session); - }; - - class ServerPacket : public Packet - { - public: - ServerPacket(PacketHeader const& header); - ~ServerPacket(); - - void Read() override final { ASSERT(!"Read not implemented for server packets."); } - - uint8* GetData() { return _stream.GetBuffer(); } - uint8 const* GetData() const { return _stream.GetBuffer(); } - size_t GetSize() const { return _stream.GetSize(); } - }; -} - -#endif // PacketsBase_h__ diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Packets/PresencePackets.h deleted file mode 100644 index 7b2d67b824..0000000000 --- a/src/server/bnetserver/Packets/PresencePackets.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef PresencePackets_h__ -#define PresencePackets_h__ - -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Presence - { - enum Opcode - { - CMSG_UPDATE_REQUEST = 0x0, // Not implemented - CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented - - SMSG_UPDATE_NOTIFY = 0x0, // Not implemented - SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented - SMSG_STATISTICS_UPDATE = 0x3 // Not implemented - }; - - class UpdateRequest final : public ClientPacket - { - public: - UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest"); - } - - void Read() override; - std::string ToString() const override; - }; - - class StatisticSubscribe final : public ClientPacket - { - public: - StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe"); - } - - void Read() override; - std::string ToString() const override; - }; - } -} - -#endif // PresencePackets_h__ diff --git a/src/server/bnetserver/Packets/ProfilePackets.h b/src/server/bnetserver/Packets/ProfilePackets.h deleted file mode 100644 index 5a277929ed..0000000000 --- a/src/server/bnetserver/Packets/ProfilePackets.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ProfilePackets_h__ -#define ProfilePackets_h__ - -#include "PacketsBase.h" - -namespace Battlenet -{ - namespace Profile - { - enum Opcode - { - CMSG_READ_REQUEST = 0x0, // Not implemented - CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented - CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented - CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented - CMSG_CHANGE_SETTINGS = 0x5, // Not implemented - - SMSG_READ_RESPONSE = 0x0, // Not implemented - SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented - SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented - SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented - SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented - }; - } -} - -#endif // ProfilePackets_h__ diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp deleted file mode 100644 index c44df63cc0..0000000000 --- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "WoWRealmPackets.h" -#include "Session.h" -#include -#include - -std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const -{ - return "Battlenet::WoWRealm::ListSubscribeRequest"; -} - -void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) -{ - session->HandleListSubscribeRequest(*this); -} - -std::string Battlenet::WoWRealm::ListUnsubscribe::ToString() const -{ - return "Battlenet::WoWRealm::ListUnsubscribe"; -} - -void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) -{ - session->HandleListUnsubscribe(*this); -} - -void Battlenet::WoWRealm::JoinRequestV2::Read() -{ - Realm.Site = _stream.Read(8); - Realm.Realm = _stream.Read(32); - Realm.Region = _stream.Read(8); - ClientSeed = _stream.Read(32); -} - -std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Site) << " Index " << Realm.Realm; - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) -{ - session->HandleJoinRequestV2(*this); -} - -Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() -{ - for (ServerPacket* realmData : RealmData) - delete realmData; -} - -void Battlenet::WoWRealm::ListSubscribeResponse::Write() -{ - _stream.Write(Response, 1); - if (Response == SUCCESS) - { - _stream.Write(CharacterCounts.size(), 7); - for (CharacterCountEntry const& entry : CharacterCounts) - { - _stream.Write(entry.Realm.Site, 8); - _stream.Write(entry.Realm.Realm, 32); - _stream.Write(entry.Realm.Region, 8); - _stream.Write(entry.CharacterCount, 16); - } - - for (ServerPacket* realmData : RealmData) - { - realmData->Write(); - _stream.WriteBytes(realmData->GetData(), realmData->GetSize()); - } - } - else - _stream.Write(ResponseCode, 8); -} - -std::string Battlenet::WoWRealm::ListSubscribeResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListSubscribeResponse"; - - if (Response == SUCCESS) - { - stream << " Realms " << CharacterCounts.size(); - - for (CharacterCountEntry const& entry : CharacterCounts) - stream << std::endl << "Region " << uint32(entry.Realm.Region) << " Battlegroup " << uint32(entry.Realm.Region) << " Index " << entry.Realm.Realm << " Characters " << entry.CharacterCount; - - for (ServerPacket* realmData : RealmData) - stream << std::endl << realmData->ToString(); - } - else - stream << " Failure"; - - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::ListUpdate::Write() -{ - _stream.Write(UpdateState, 1); - if (UpdateState == UPDATE) - { - _stream.Write(uint32(Type + std::numeric_limits::max()), 32); - _stream.WriteFloat(Population); - _stream.Write(Flags, 8); - _stream.Write(Lock, 8); - _stream.Write(Timezone, 32); - _stream.Write(!Version.empty(), 1); - if (!Version.empty()) - { - _stream.WriteString(Version, 5); - _stream.Write(Build, 32); - - boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes(); - uint16 port = Address.port(); - - EndianConvertReverse(ip); - EndianConvertReverse(port); - - _stream.WriteBytes(ip.data(), 4); - _stream.WriteBytes(&port, 2); - } - - _stream.WriteString(Name, 10); - } - - _stream.Write(Id.Site, 8); - _stream.Write(Id.Realm, 32); - _stream.Write(Id.Region, 8); -} - -std::string Battlenet::WoWRealm::ListUpdate::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListUpdate"; - if (UpdateState == UPDATE) - { - stream << " Timezone: " << Timezone << " Population: " << Population << " Lock: " << uint32(Lock) << " Type: " << Type << " Name: " << Name - << " Flags: " << uint32(Flags) << " Region: " << uint32(Id.Region) << " Battlegroup: " << uint32(Id.Site) << " Index: " << Id.Realm; - - if (!Version.empty()) - stream << " Version: " << Version; - } - else - stream << " Delete realm [Region: " << uint32(Id.Region) << " Battlegroup : " << uint32(Id.Site) << " Index : " << Id.Realm << "]"; - - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::ToonReady::Write() -{ - _stream.Write(Realm.Region, 8); - _stream.WriteFourCC(Game); - uint32 realmAddress = ((Realm.Site << 16) & 0xFF0000) | uint16(Realm.Realm); - _stream.Write(realmAddress, 32); - _stream.WriteString(Name, 7, -2); - _stream.WriteSkip(7); - _stream.Write(Guid, 64); - _stream.WriteFourCC(Game); - _stream.Write(Realm.Region, 8); - _stream.WriteSkip(21); - _stream.Write(realmAddress, 32); - _stream.WriteSkip(9); - _stream.Write(0, 64); // Unknown - _stream.Write(0, 32); // Unknown -} - -std::string Battlenet::WoWRealm::ToonReady::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::ToonReady" << " Game: " << Game - << ", Region: " << uint32(Realm.Region) << ", Battlegroup: " << uint32(Realm.Site) << ", Index: " << Realm.Realm - << ", Guid: " << Guid << ", Name: " << Name; - - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::JoinResponseV2::Write() -{ - _stream.Write(0, 27); - _stream.Write(Response, 1); - if (Response == SUCCESS) - { - _stream.Write(ServerSeed, 32); - _stream.Write(IPv6.size(), 5); - for (tcp::endpoint const& addr : IPv6) - { - boost::asio::ip::address_v6::bytes_type ip = addr.address().to_v6().to_bytes(); - uint16 port = addr.port(); - - EndianConvertReverse(port); - - _stream.WriteBytes(ip.data(), 16); - _stream.WriteBytes(&port, 2); - } - - _stream.Write(IPv4.size(), 5); - for (tcp::endpoint const& addr : IPv4) - { - boost::asio::ip::address_v4::bytes_type ip = addr.address().to_v4().to_bytes(); - uint16 port = addr.port(); - - EndianConvertReverse(port); - - _stream.WriteBytes(ip.data(), 4); - _stream.WriteBytes(&port, 2); - } - } - else - _stream.Write(ResponseCode, 8); -} - -std::string Battlenet::WoWRealm::JoinResponseV2::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinResponseV2"; - if (Response == SUCCESS) - { - stream << " ServerSeed " << ServerSeed << " IPv4 Addresses " << IPv4.size() << " IPv6 Addresses " << IPv6.size(); - for (tcp::endpoint const& addr : IPv4) - stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast(addr); - - for (tcp::endpoint const& addr : IPv6) - stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast(addr); - } - else - stream << " Failure"; - - return stream.str().c_str(); -} diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h deleted file mode 100644 index 82e5750f9a..0000000000 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WoWRealmPackets_h__ -#define WoWRealmPackets_h__ - -#include "PacketsBase.h" -#include "Realm.h" - -namespace Battlenet -{ - namespace WoWRealm - { - enum Opcode - { - CMSG_LIST_SUBSCRIBE_REQUEST = 0x0, - CMSG_LIST_UNSUBSCRIBE = 0x1, - CMSG_JOIN_REQUEST_V2 = 0x8, - CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented - - SMSG_LIST_SUBSCRIBE_RESPONSE = 0x0, - SMSG_LIST_UPDATE = 0x2, - SMSG_LIST_COMPLETE = 0x3, - SMSG_TOON_READY = 0x6, // Not implemented - SMSG_TOON_LOGGED_OUT = 0x7, // Not implemented - SMSG_JOIN_RESPONSE_V2 = 0x8 - }; - - class ListSubscribeRequest final : public ClientPacket - { - public: - ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) override; - }; - - class ListUnsubscribe final : public ClientPacket - { - public: - ListUnsubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LIST_UNSUBSCRIBE, WOWREALM) && "Invalid packet header for ListUnsubscribe"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) override; - }; - - class JoinRequestV2 final : public ClientPacket - { - public: - JoinRequestV2(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_JOIN_REQUEST_V2, WOWREALM) && "Invalid packet header for RealmJoinRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) override; - - uint32 ClientSeed =0; - Battlenet::RealmHandle Realm; - }; - - class ListSubscribeResponse final : public ServerPacket - { - public: - enum Result - { - SUCCESS = 0, - FAILURE = 1 - }; - - ListSubscribeResponse() : ServerPacket(PacketHeader(SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM)), - Response(SUCCESS), ResponseCode(26) - { - } - - ~ListSubscribeResponse(); - - struct CharacterCountEntry - { - Battlenet::RealmHandle Realm; - uint32 CharacterCount; - }; - - void Write() override; - std::string ToString() const override; - - Result Response; - uint8 ResponseCode; - std::vector CharacterCounts; - std::vector RealmData; - }; - - class ListUpdate final : public ServerPacket - { - public: - enum State - { - DELETED = 0, - UPDATE = 1 - }; - - ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE), - Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), Flags(0) - { - } - - void Write() override; - std::string ToString() const override; - - int UpdateState; - uint32 Timezone; - float Population; - uint8 Lock; - uint32 Type; - std::string Name; - std::string Version; - tcp::endpoint Address; - uint8 Flags; - Battlenet::RealmHandle Id; - uint32 Build; - }; - - class ListComplete final : public ServerPacket - { - public: - ListComplete() : ServerPacket(PacketHeader(SMSG_LIST_COMPLETE, WOWREALM)) - { - } - - void Write() override { } - std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; } - }; - - class ToonReady final : public ServerPacket - { - public: - ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM)), Game("WoW"), Guid(0) - { - } - - void Write() override; - std::string ToString() const override; - - std::string Game; - Battlenet::RealmHandle Realm; - uint64 Guid; - std::string Name; - }; - - class ToonLoggedOut final : public ServerPacket - { - public: - ToonLoggedOut() : ServerPacket(PacketHeader(SMSG_TOON_LOGGED_OUT, WOWREALM)) - { - } - - void Write() override { } - std::string ToString() const override { return "Battlenet::WoWRealm::ToonLoggedOut"; } - }; - - class JoinResponseV2 final : public ServerPacket - { - public: - enum Result - { - SUCCESS = 0, - FAILURE = 1 - }; - - JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)), - Response(SUCCESS), ResponseCode(26), ServerSeed(0) - { - } - - void Write() override; - std::string ToString() const override; - - Result Response; - uint8 ResponseCode; - uint32 ServerSeed; - std::vector IPv4; - std::vector IPv6; - }; - } -} - -#endif // WoWRealmPackets_h__ diff --git a/src/server/bnetserver/Realms/BNetRealmList.cpp b/src/server/bnetserver/Realms/BNetRealmList.cpp deleted file mode 100644 index 34665c01a1..0000000000 --- a/src/server/bnetserver/Realms/BNetRealmList.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BNetRealmList.h" -#include "DatabaseEnv.h" -#include "DeadlineTimer.h" -#include "DeadlineTimer.h" -#include "IoContext.h" -#include "Log.h" -#include "Resolver.h" -#include "SessionManager.h" -#include "Util.h" -#include "WorldListener.h" -#include - -BNetRealmList::BNetRealmList() : _updateInterval(0) -{ -} - -BNetRealmList::~BNetRealmList() = default; - -BNetRealmList* BNetRealmList::Instance() -{ - static BNetRealmList instance; - return &instance; -} - -// Load the realm list from the database -void BNetRealmList::Initialize(Trinity::Asio::IoContext& ioContext, uint32 updateInterval, uint16 worldListenPort) -{ - _updateInterval = updateInterval; - _updateTimer = Trinity::make_unique(ioContext); - _resolver = Trinity::make_unique(ioContext); - - // Get the content of the realmlist table in the database - UpdateRealms(boost::system::error_code()); - - _worldListener = Trinity::make_unique(worldListenPort); - _worldListener->Start(); -} - -void BNetRealmList::Close() -{ - _worldListener->End(); - _updateTimer->cancel(); -} - -template -inline void UpdateField(FieldType& out, FieldType const& in, bool& changed) -{ - if (out != in) - { - out = in; - changed = true; - } -} - -inline void UpdateAddress(std::unique_ptr& out, boost::asio::ip::address&& in, bool& changed) -{ - if (!out || *out != in) - { - out = Trinity::make_unique(std::move(in)); - changed = true; - } -} - -void BNetRealmList::UpdateRealm(Battlenet::RealmHandle const& id, uint32 build, std::string const& name, - boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr, boost::asio::ip::address&& localSubmask, - uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population) -{ - // Create new if not exist or update existed - Realm& realm = _realms[id]; - realm.Keep = true; - realm.Updated = false; - - realm.Id = id; - UpdateField(realm.Build, build, realm.Updated); - UpdateField(realm.Name, name, realm.Updated); - UpdateField(realm.Type, icon, realm.Updated); - UpdateField(realm.Flags, flag, realm.Updated); - UpdateField(realm.Timezone, timezone, realm.Updated); - UpdateField(realm.AllowedSecurityLevel, allowedSecurityLevel, realm.Updated); - UpdateField(realm.PopulationLevel, population, realm.Updated); - - UpdateAddress(realm.ExternalAddress, std::forward(address), realm.Updated); - UpdateAddress(realm.LocalAddress, std::forward(localAddr), realm.Updated); - UpdateAddress(realm.LocalSubnetMask, std::forward(localSubmask), realm.Updated); - - UpdateField(realm.Port, port, realm.Updated); -} - -void BNetRealmList::UpdateRealms(boost::system::error_code const& error) -{ - if (error) - return; - - TC_LOG_DEBUG("server.bnetserver", "Updating Realm List..."); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - // Circle through results and add them to the realm map - if (result) - { - do - { - try - { - Field* fields = result->Fetch(); - uint32 realmId = fields[0].GetUInt32(); - std::string name = fields[1].GetString(); - std::string externalAddressString = fields[2].GetString(); - std::string localAddressString = fields[3].GetString(); - std::string localSubmaskString = fields[4].GetString(); - - Optional externalAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), externalAddressString, ""); - if (!externalAddress) - { - TC_LOG_ERROR("realmlist", "Could not resolve address %s", externalAddressString.c_str()); - continue; - } - - Optional localAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), localAddressString, ""); - if (!localAddress) - { - TC_LOG_ERROR("realmlist", "Could not resolve address %s", localAddressString.c_str()); - continue; - } - - Optional localSubmask =_resolver->Resolve(boost::asio::ip::tcp::v4(), localSubmaskString, ""); - if (!localSubmask) - { - TC_LOG_ERROR("realmlist", "Could not resolve address %s", localSubmaskString.c_str()); - continue; - } - - uint16 port = fields[5].GetUInt16(); - uint8 icon = fields[6].GetUInt8(); - if (icon == REALM_TYPE_FFA_PVP) - icon = REALM_TYPE_PVP; - if (icon >= MAX_CLIENT_REALM_TYPE) - icon = REALM_TYPE_NORMAL; - RealmFlags flag = RealmFlags(fields[7].GetUInt8()); - uint8 timezone = fields[8].GetUInt8(); - uint8 allowedSecurityLevel = fields[9].GetUInt8(); - float pop = fields[10].GetFloat(); - uint32 build = fields[11].GetUInt32(); - uint8 region = fields[12].GetUInt8(); - uint8 battlegroup = fields[13].GetUInt8(); - - Battlenet::RealmHandle id{ region, battlegroup, realmId }; - - UpdateRealm(id, build, name, externalAddress->address(), localAddress->address(), localSubmask->address(), port, icon, flag, - timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); - - TC_LOG_TRACE("server.bnetserver", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddressString.c_str(), port); - } - catch (std::exception& ex) - { - TC_LOG_ERROR("server.bnetserver", "BNetRealmList::UpdateRealms has thrown an exception: %s", ex.what()); - ABORT(); - } - } - while (result->NextRow()); - } - - std::vector updatedRealms; - std::vector deletedRealms; - - for (RealmMap::value_type& pair : _realms) - { - if (pair.second.Updated) - updatedRealms.push_back(&pair.second); - else if (!pair.second.Keep) - deletedRealms.push_back(pair.first); - - pair.second.Updated = false; - pair.second.Keep = false; - } - - for (Battlenet::RealmHandle const& deleted : deletedRealms) - _realms.erase(deleted); - - if (!updatedRealms.empty() || !deletedRealms.empty()) - { - sSessionMgr.LockedForEach([&updatedRealms, &deletedRealms](Battlenet::Session* session) - { - if (session->IsSubscribedToRealmListUpdates()) - session->UpdateRealms(updatedRealms, deletedRealms); - }); - } - - if (_updateInterval) - { - _updateTimer->expires_after(std::chrono::seconds(_updateInterval)); - _updateTimer->async_wait(std::bind(&BNetRealmList::UpdateRealms, this, std::placeholders::_1)); - } -} - -Realm const* BNetRealmList::GetRealm(Battlenet::RealmHandle const& id) const -{ - auto itr = _realms.find(id); - if (itr != _realms.end()) - return &itr->second; - - return nullptr; -} diff --git a/src/server/bnetserver/Realms/BNetRealmList.h b/src/server/bnetserver/Realms/BNetRealmList.h deleted file mode 100644 index 601778b706..0000000000 --- a/src/server/bnetserver/Realms/BNetRealmList.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BNetRealmList_h__ -#define BNetRealmList_h__ - -#include "Define.h" -#include "Realm.h" -#include -#include -#include - -class WorldListener; - -namespace boost -{ - namespace system - { - class error_code; - } -} - -/// Storage object for the list of realms on the server -class BNetRealmList -{ - public: - typedef std::map RealmMap; - - static BNetRealmList* Instance(); - - ~BNetRealmList(); - - void Initialize(Trinity::Asio::IoContext& ioContext, uint32 updateInterval, uint16 worldListenPort); - void Close(); - - RealmMap const& GetRealms() const { return _realms; } - Realm const* GetRealm(Battlenet::RealmHandle const& id) const; - - private: - BNetRealmList(); - - void UpdateRealms(boost::system::error_code const& error); - void UpdateRealm(Battlenet::RealmHandle const& id, uint32 build, std::string const& name, - boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr, boost::asio::ip::address&& localSubmask, - uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population); - - RealmMap _realms; - uint32 _updateInterval; - std::unique_ptr _updateTimer; - std::unique_ptr _resolver; - std::unique_ptr _worldListener; -}; - -#define sBNetRealmList BNetRealmList::Instance() - -#endif // BNetRealmList_h__ diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp deleted file mode 100644 index 5cd69ead07..0000000000 --- a/src/server/bnetserver/Realms/WorldListener.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Log.h" -#include "SessionManager.h" -#include "WoWRealmPackets.h" -#include "ZmqContext.h" -#include "WorldListener.h" - -WorldListener::HandlerTable const WorldListener::_handlers; - -WorldListener::HandlerTable::HandlerTable() -{ -#define DEFINE_HANDLER(opc, func) _handlers[opc] = { func, #opc } - - DEFINE_HANDLER(BNET_CHANGE_TOON_ONLINE_STATE, &WorldListener::HandleToonOnlineStatusChange); - -#undef DEFINE_HANDLER -} - -WorldListener::WorldListener(uint16 worldListenPort) : _worldListenPort(worldListenPort) -{ - _worldSocket = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull); -} - -WorldListener::~WorldListener() -{ - delete _worldSocket; -} - -void WorldListener::Run() -{ - while (!ProcessExit()) - { - _poller->poll(); - if (_poller->events(*_worldSocket) & zmqpp::poller::poll_in) - { - int32 op1; - do - { - zmqpp::message msg; - _worldSocket->receive(msg); - Dispatch(msg); - _worldSocket->get(zmqpp::socket_option::events, op1); - } while (op1 & zmqpp::poller::poll_in); - } - } -} - -void WorldListener::HandleOpen() -{ - try - { - _worldSocket->bind(std::string("tcp://*:") + std::to_string(_worldListenPort)); - } - catch (zmqpp::zmq_internal_exception& ex) - { - TC_LOG_FATAL("server.ipc", "Could not bind to WorldserverListenPort %u. Exception: %s. Shutting down bnetserver.", _worldListenPort, ex.what()); - abort(); - } - - _poller->add(*_worldSocket); - TC_LOG_INFO("server.ipc", "Listening on connections from worldservers on port %u...", _worldListenPort); -} - -void WorldListener::HandleClose() -{ - _worldSocket->close(); - TC_LOG_INFO("server.ipc", "Shutting down connections from worldservers..."); -} - -void WorldListener::Dispatch(zmqpp::message& msg) const -{ - IPC::BattlenetComm::Header ipcHeader; - msg >> ipcHeader; - - if (ipcHeader.Ipc.Channel != IPC_CHANNEL_BNET) - return; - - if (ipcHeader.Ipc.Command < IPC_BNET_MAX_COMMAND) - (this->*_handlers[ipcHeader.Ipc.Command].Handler)(ipcHeader.Realm, msg); -} - -void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const -{ - IPC::BattlenetComm::ToonHandle toonHandle; - bool online; - msg >> toonHandle; - msg >> online; - - if (Battlenet::Session* session = sSessionMgr.GetSession(toonHandle.AccountId, toonHandle.GameAccountId)) - { - if (online) - { - if (!session->IsToonOnline()) - { - Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady(); - toonReady->Realm = realm; - toonReady->Guid = toonHandle.Guid; - toonReady->Name = toonHandle.Name; - session->SetToonOnline(true); - session->AsyncWrite(toonReady); - } - } - else if (session->IsToonOnline()) - { - session->AsyncWrite(new Battlenet::WoWRealm::ToonLoggedOut()); - session->SetToonOnline(false); - } - } -} diff --git a/src/server/bnetserver/Realms/WorldListener.h b/src/server/bnetserver/Realms/WorldListener.h deleted file mode 100644 index a72788ca96..0000000000 --- a/src/server/bnetserver/Realms/WorldListener.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WorldListener_h__ -#define WorldListener_h__ - -#include "ZMQTask.h" -#include "Commands.h" - -class WorldListener : public ZMQTask -{ -public: - explicit WorldListener(uint16 worldListenPort); - ~WorldListener(); - void Run() override; - -protected: - void HandleOpen() override; - void HandleClose() override; - -private: - void Dispatch(zmqpp::message& msg) const; - - typedef void(WorldListener::*PacketHandler)(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const; - class HandlerTable - { - public: - HandlerTable(); - - struct HandlerInfo - { - PacketHandler Handler; - char const* Name; - }; - - HandlerInfo const& operator[](uint8 opcode) const { return _handlers[opcode]; } - - private: - HandlerInfo _handlers[IPC_BNET_MAX_COMMAND]; - }; - - void HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const; - - zmqpp::socket* _worldSocket; - uint16 _worldListenPort; - static HandlerTable const _handlers; -}; - -#endif // WorldListener_h__ diff --git a/src/server/bnetserver/Server/ComponentManager.cpp b/src/server/bnetserver/Server/ComponentManager.cpp deleted file mode 100644 index 1d57ac2e21..0000000000 --- a/src/server/bnetserver/Server/ComponentManager.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ComponentManager.h" -#include "DatabaseEnv.h" - -Battlenet::ComponentMgr::~ComponentMgr() -{ - for (Component* component : _components) - delete component; -} - -void Battlenet::ComponentMgr::Load() -{ - QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components"); - if (result) - { - do - { - Field* fields = result->Fetch(); - Component* component = new Component(); - component->Program = fields[0].GetString(); - component->Platform = fields[1].GetString(); - component->Build = fields[2].GetUInt32(); - - _components.insert(component); - _programs.insert(component->Program); - _platforms.insert(component->Platform); - - } while (result->NextRow()); - } -} - -bool Battlenet::ComponentMgr::HasComponent(Battlenet::Component const* component) const -{ - for (Component const* c : _components) - if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build) - return true; - - return false; -} diff --git a/src/server/bnetserver/Server/ComponentManager.h b/src/server/bnetserver/Server/ComponentManager.h deleted file mode 100644 index 9fc2e5b4d8..0000000000 --- a/src/server/bnetserver/Server/ComponentManager.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ComponentManager_h__ -#define ComponentManager_h__ - -#include "Define.h" -#include -#include -#include - -namespace Battlenet -{ - struct Component - { - std::string Program; - std::string Platform; - uint32 Build; - }; - - class ComponentMgr - { - ComponentMgr() { } - ~ComponentMgr(); - - public: - void Load(); - bool HasComponent(Component const* component) const; - bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; } - bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; } - - static ComponentMgr* instance() - { - static ComponentMgr instance; - return &instance; - } - - private: - std::set _components; - std::set _programs; - std::set _platforms; - }; -} - -#define sComponentMgr Battlenet::ComponentMgr::instance() - -#endif // ComponentManager_h__ diff --git a/src/server/bnetserver/Server/ModuleManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp deleted file mode 100644 index 6a9e5add18..0000000000 --- a/src/server/bnetserver/Server/ModuleManager.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ModuleManager.h" -#include "DatabaseEnv.h" -#include "Util.h" - -Battlenet::ModuleManager::~ModuleManager() -{ - for (auto const& m : _modules) - delete m.second; -} - -void Battlenet::ModuleManager::Load() -{ - QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules"); - if (result) - { - do - { - Field* fields = result->Fetch(); - ModuleInfo* module = new ModuleInfo(); - module->Type = fields[2].GetString(); - HexStrToByteArray(fields[0].GetString(), module->ModuleId); - std::string data = fields[4].GetString(); - module->DataSize = data.length() / 2; - if (module->DataSize) - { - module->Data = new uint8[data.length() / 2]; - HexStrToByteArray(data, module->Data); - } - - _modules[{ fields[3].GetString(), fields[1].GetString() }] = module; - } while (result->NextRow()); - } -} - -Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& os, std::string const& name) const -{ - ModuleKey key { os, name }; - if (!_modules.count(key)) - return nullptr; - - return new ModuleInfo(*_modules.at(key)); -} diff --git a/src/server/bnetserver/Server/ModuleManager.h b/src/server/bnetserver/Server/ModuleManager.h deleted file mode 100644 index 001b07ba31..0000000000 --- a/src/server/bnetserver/Server/ModuleManager.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ModuleManager_h__ -#define ModuleManager_h__ - -#include "Define.h" -#include -#include -#include - -namespace Battlenet -{ - struct ModuleKey - { - std::string Platform; - std::string Name; - - bool operator<(ModuleKey const& right) const - { - int32 res = Platform.compare(right.Platform); - if (res < 0) - return true; - else if (res > 0) - return false; - - return Name < right.Name; - } - }; - - struct ModuleInfo - { - ModuleInfo() : Region("EU"), DataSize(0), Data(nullptr) { } - ModuleInfo(ModuleInfo const& right) : Type(right.Type), Region(right.Region), DataSize(right.DataSize), Data(nullptr) - { - memcpy(ModuleId, right.ModuleId, 32); - if (DataSize) - { - Data = new uint8[DataSize]; - memcpy(Data, right.Data, DataSize); - } - } - ~ModuleInfo() - { - delete Data; - } - - std::string Type; - std::string Region; - uint8 ModuleId[32]; - uint32 DataSize; - uint8* Data; - }; - - class ModuleManager - { - ModuleManager() { } - ~ModuleManager(); - - public: - void Load(); - ModuleInfo* CreateModule(std::string const& os, std::string const& name) const; - - static ModuleManager* instance() - { - static ModuleManager instance; - return &instance; - } - - private: - void LoadComponents(); - void LoadModules(); - - std::map _modules; - }; -} - -#define sModuleMgr Battlenet::ModuleManager::instance() - -#endif // ModuleManager_h__ diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp deleted file mode 100644 index 44a7656496..0000000000 --- a/src/server/bnetserver/Server/Session.cpp +++ /dev/null @@ -1,1152 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Session.h" -#include "AuthCodes.h" -#include "BitStream.h" -#include "BNetRealmList.h" -#include "Database/DatabaseEnv.h" -#include "HmacHash.h" -#include "Log.h" -#include "PacketManager.h" -#include "QueryCallback.h" -#include "Random.h" -#include "Realm.h" -#include "SessionManager.h" -#include "SHA256.h" -#include "Util.h" - -Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] = -{ - &Battlenet::Session::HandlePasswordModule, - &Battlenet::Session::UnhandledModule, - &Battlenet::Session::UnhandledModule, - &Battlenet::Session::HandleSelectGameAccountModule, - &Battlenet::Session::HandleRiskFingerprintModule, - &Battlenet::Session::HandleResumeModule, -}; - -void Battlenet::AccountInfo::LoadResult(Field* fields) -{ - // ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab WHERE email = ? - Id = fields[0].GetUInt32(); - Login = fields[1].GetString(); - IsLockedToIP = fields[2].GetBool(); - LockCountry = fields[3].GetString(); - LastIP = fields[4].GetString(); - FailedLogins = fields[5].GetUInt32(); - IsBanned = fields[6].GetUInt64() != 0; - IsPermanentlyBanned = fields[7].GetUInt64() != 0; -} - -void Battlenet::GameAccountInfo::LoadResult(Field* fields) -{ - // a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel - Id = fields[0].GetUInt32(); - Name = fields[1].GetString(); - IsBanned = fields[2].GetUInt64() != 0; - IsPermanentlyBanned = fields[3].GetUInt64() != 0; - SecurityLevel = AccountTypes(fields[4].GetUInt8()); - - std::size_t hashPos = Name.find('#'); - if (hashPos != std::string::npos) - DisplayName = std::string("WoW") + Name.substr(hashPos + 1); - else - DisplayName = Name; -} - -Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountInfo(new AccountInfo()), _gameAccountInfo(nullptr), _locale(), - _os(), _build(0), _ipCountry(), I(), s(), v(), b(), B(), K(), - _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false), _toonOnline(false) -{ - static uint8 const N_Bytes[] = - { - 0xAB, 0x24, 0x43, 0x63, 0xA9, 0xC2, 0xA6, 0xC3, 0x3B, 0x37, 0xE4, 0x61, 0x84, 0x25, 0x9F, 0x8B, - 0x3F, 0xCB, 0x8A, 0x85, 0x27, 0xFC, 0x3D, 0x87, 0xBE, 0xA0, 0x54, 0xD2, 0x38, 0x5D, 0x12, 0xB7, - 0x61, 0x44, 0x2E, 0x83, 0xFA, 0xC2, 0x21, 0xD9, 0x10, 0x9F, 0xC1, 0x9F, 0xEA, 0x50, 0xE3, 0x09, - 0xA6, 0xE5, 0x5E, 0x23, 0xA7, 0x77, 0xEB, 0x00, 0xC7, 0xBA, 0xBF, 0xF8, 0x55, 0x8A, 0x0E, 0x80, - 0x2B, 0x14, 0x1A, 0xA2, 0xD4, 0x43, 0xA9, 0xD4, 0xAF, 0xAD, 0xB5, 0xE1, 0xF5, 0xAC, 0xA6, 0x13, - 0x1C, 0x69, 0x78, 0x64, 0x0B, 0x7B, 0xAF, 0x9C, 0xC5, 0x50, 0x31, 0x8A, 0x23, 0x08, 0x01, 0xA1, - 0xF5, 0xFE, 0x31, 0x32, 0x7F, 0xE2, 0x05, 0x82, 0xD6, 0x0B, 0xED, 0x4D, 0x55, 0x32, 0x41, 0x94, - 0x29, 0x6F, 0x55, 0x7D, 0xE3, 0x0F, 0x77, 0x19, 0xE5, 0x6C, 0x30, 0xEB, 0xDE, 0xF6, 0xA7, 0x86 - }; - - N.SetBinary(N_Bytes, sizeof(N_Bytes)); - g.SetDword(2); - - SHA256Hash sha; - sha.UpdateBigNumbers(&N, &g, nullptr); - sha.Finalize(); - k.SetBinary(sha.GetDigest(), sha.GetLength()); -} - -Battlenet::Session::~Session() -{ - if (_authed) - sSessionMgr.RemoveSession(this); - - delete _accountInfo; -} - -void Battlenet::Session::_SetVSFields(std::string const& pstr) -{ - s.SetRand(uint32(BufferSizes::SRP_6_S) * 8); - - BigNumber p; - p.SetHexStr(pstr.c_str()); - - SHA256Hash sha; - sha.UpdateBigNumbers(&s, &p, nullptr); - sha.Finalize(); - BigNumber x; - x.SetBinary(sha.GetDigest(), sha.GetLength()); - v = g.ModExp(x, N); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_VS_FIELDS); - stmt->setString(0, v.AsHexStr()); - stmt->setString(1, s.AsHexStr()); - stmt->setString(2, _accountInfo->Login); - - LoginDatabase.Execute(stmt); -} - -void Battlenet::Session::LogUnhandledPacket(PacketHeader const& header) -{ - TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), sPacketManager.GetClientPacketName(header)); -} - -void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& logonRequest) -{ - if (logonRequest.Program != "WoW") - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with game other than WoW (using %s)!", GetClientInfo().c_str(), logonRequest.Program.c_str()); - return; - } - - if (!sComponentMgr->HasPlatform(logonRequest.Platform)) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_INVALID_OS); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in from an unsupported platform (using %s)!", GetClientInfo().c_str(), logonRequest.Platform.c_str()); - return; - } - - if (!sComponentMgr->HasPlatform(logonRequest.Locale)) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with unsupported locale (using %s)!", GetClientInfo().c_str(), logonRequest.Locale.c_str()); - return; - } - - for (Component const& component : logonRequest.Components) - { - if (!sComponentMgr->HasComponent(&component)) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (!sComponentMgr->HasProgram(component.Program)) - { - logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component program %s!", GetClientInfo().c_str(), component.Program.c_str()); - } - else if (!sComponentMgr->HasPlatform(component.Platform)) - { - logonResponse->SetAuthResult(AUTH_INVALID_OS); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component platform %s!", GetClientInfo().c_str(), component.Platform.c_str()); - } - else - { - if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build)) - logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION); - else - logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON); - - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component %s version %u!", GetClientInfo().c_str(), component.Program.c_str(), component.Build); - } - - AsyncWrite(logonResponse); - return; - } - - if (component.Platform == "base") - _build = component.Build; - } - - std::string login = logonRequest.Login; - _locale = logonRequest.Locale; - _os = logonRequest.Platform; - - Utf8ToUpperOnlyLatin(login); - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); - stmt->setString(0, login); - - _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&Battlenet::Session::HandleLogonRequestCallback, this, std::placeholders::_1))); -} - -void Battlenet::Session::HandleLogonRequestCallback(PreparedQueryResult result) -{ - if (!result) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is trying to log in from unknown account!", GetClientInfo().c_str()); - return; - } - - Field* fields = result->Fetch(); - _accountInfo->LoadResult(fields); - - std::string pStr = fields[8].GetString(); - std::string databaseV = fields[9].GetString(); - std::string databaseS = fields[10].GetString(); - - _gameAccounts.resize(result->GetRowCount()); - uint32 i = 0; - do - { - _gameAccounts[i++].LoadResult(result->Fetch() + 11); - - } while (result->NextRow()); - - std::string ip_address = GetRemoteIpAddress().to_string(); - // If the IP is 'locked', check that the player comes indeed from the correct IP address - if (_accountInfo->IsLockedToIP) - { - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str()); - - if (_accountInfo->LastIP != ip_address) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(logonResponse); - return; - } - } - else - { - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountInfo->Login.c_str()); - if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00") - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountInfo->Login.c_str()); - else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty()) - { - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str()); - if (_ipCountry != _accountInfo->LockCountry) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(logonResponse); - return; - } - } - } - - // If the account is banned, reject the logon attempt - if (_accountInfo->IsBanned) - { - if (_accountInfo->IsPermanentlyBanned) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(LOGIN_BANNED); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str()); - return; - } - else - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(LOGIN_SUSPENDED); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str()); - return; - } - } - - SHA256Hash sha; - sha.UpdateData(_accountInfo->Login); - sha.Finalize(); - - I.SetBinary(sha.GetDigest(), sha.GetLength()); - - ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password"); - ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); - - if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2) - _SetVSFields(pStr); - else - { - s.SetHexStr(databaseS.c_str()); - v.SetHexStr(databaseV.c_str()); - } - - b.SetRand(128 * 8); - B = ((v * k) + g.ModExp(b, N)) % N; - BigNumber unk; - unk.SetRand(128 * 8); - - BitStream passwordData; - uint8 state = 0; - passwordData.WriteBytes(&state, 1); - passwordData.WriteBytes(I.AsByteArray(32).get(), 32); - passwordData.WriteBytes(s.AsByteArray(32).get(), 32); - passwordData.WriteBytes(B.AsByteArray(128).get(), 128); - passwordData.WriteBytes(unk.AsByteArray(128).get(), 128); - - password->DataSize = passwordData.GetSize(); - password->Data = new uint8[password->DataSize]; - memcpy(password->Data, passwordData.GetBuffer(), password->DataSize); - - _modulesWaitingForData.push(MODULE_PASSWORD); - - Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); - proofRequest->Modules.push_back(password); - // if has authenticator, send Token module - proofRequest->Modules.push_back(thumbprint); - AsyncWrite(proofRequest); -} - -void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest) -{ - std::string login = resumeRequest.Login; - _locale = resumeRequest.Locale; - _os = resumeRequest.Platform; - auto baseComponent = std::find_if(resumeRequest.Components.begin(), resumeRequest.Components.end(), [](Component const& c) { return c.Program == "base"; }); - if (baseComponent != resumeRequest.Components.end()) - _build = baseComponent->Build; - - Utf8ToUpperOnlyLatin(login); - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); - stmt->setString(0, login); - stmt->setString(1, resumeRequest.GameAccountName); - - _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&Battlenet::Session::HandleResumeRequestCallback, this, std::placeholders::_1))); -} - -void Battlenet::Session::HandleResumeRequestCallback(PreparedQueryResult result) -{ - if (!result) - { - Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); - resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - AsyncWrite(resumeResponse); - return; - } - - Field* fields = result->Fetch(); - _accountInfo->LoadResult(fields); - K.SetHexStr(fields[8].GetString().c_str()); - - _gameAccounts.resize(1); - _gameAccountInfo = &_gameAccounts[0]; - _gameAccountInfo->LoadResult(fields + 9); - - ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); - ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume"); - BitStream resumeData; - uint8 state = 0; - _reconnectProof.SetRand(16 * 8); - - resumeData.WriteBytes(&state, 1); - resumeData.WriteBytes(_reconnectProof.AsByteArray().get(), 16); - - resume->DataSize = resumeData.GetSize(); - resume->Data = new uint8[resume->DataSize]; - memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); - - _modulesWaitingForData.push(MODULE_RESUME); - - Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); - proofRequest->Modules.push_back(thumbprint); - proofRequest->Modules.push_back(resume); - AsyncWrite(proofRequest); -} - -void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proofResponse) -{ - if (_modulesWaitingForData.size() < proofResponse.Modules.size()) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - AsyncWrite(complete); - return; - } - - ServerPacket* response = nullptr; - for (size_t i = 0; i < proofResponse.Modules.size(); ++i) - { - if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Modules[i], &response)) - break; - - _modulesWaitingForData.pop(); - } - - if (!response) - { - response = new Authentication::LogonResponse(); - static_cast(response)->SetAuthResult(AUTH_INTERNAL_ERROR); - } - - AsyncWrite(response); -} - -void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/) -{ - AsyncWrite(new Connection::Pong()); -} - -void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption& enableEncryption) -{ - _crypt.Init(&K); - _crypt.DecryptRecv(enableEncryption.GetRemainingData(), enableEncryption.GetRemainingSize()); -} - -void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/) -{ - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); - stmt->setString(0, ""); - stmt->setBool(1, false); - stmt->setUInt32(2, _accountInfo->Id); - LoginDatabase.Execute(stmt); -} - -void Battlenet::Session::HandleConnectionClosing(Connection::ConnectionClosing const& /*connectionClosing*/) -{ -} - -void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) -{ - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS); - stmt->setUInt32(0, _gameAccountInfo->Id); - - _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&Battlenet::Session::HandleListSubscribeRequestCallback, this, std::placeholders::_1))); -} - -void Battlenet::Session::HandleListSubscribeRequestCallback(PreparedQueryResult result) -{ - WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse(); - - if (result) - { - do - { - Field* fields = result->Fetch(); - listSubscribeResponse->CharacterCounts.push_back({ Battlenet::RealmHandle(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32()), fields[0].GetUInt8() }); - } while (result->NextRow()); - } - - AsyncWrite(listSubscribeResponse); - - for (auto const& i : sBNetRealmList->GetRealms()) - AsyncWrite(BuildListUpdate(&i.second)); - - AsyncWrite(new WoWRealm::ListComplete()); - - _subscribedToRealmListUpdates = true; -} - -void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& /*listUnsubscribe*/) -{ - _subscribedToRealmListUpdates = false; -} - -void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest) -{ - WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2(); - Realm const* realm = sBNetRealmList->GetRealm(joinRequest.Realm); - if (!realm || realm->Flags & (REALM_FLAG_VERSION_MISMATCH | REALM_FLAG_OFFLINE) || realm->Build != _build) - { - joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE; - AsyncWrite(joinResponse); - return; - } - - joinResponse->ServerSeed = rand32(); - - uint8 sessionKey[40]; - HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get()); - hmac.UpdateData((uint8*)"WoW\0", 4); - hmac.UpdateData((uint8*)&joinRequest.ClientSeed, 4); - hmac.UpdateData((uint8*)&joinResponse->ServerSeed, 4); - hmac.Finalize(); - - memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength()); - - HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get()); - hmac2.UpdateData((uint8*)"WoW\0", 4); - hmac2.UpdateData((uint8*)&joinResponse->ServerSeed, 4); - hmac2.UpdateData((uint8*)&joinRequest.ClientSeed, 4); - hmac2.Finalize(); - - memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength()); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF); - stmt->setString(0, ByteArrayToHexStr(sessionKey, 40, true).c_str()); - stmt->setString(1, GetRemoteIpAddress().to_string()); - stmt->setUInt32(2, GetLocaleByName(_locale)); - stmt->setString(3, _os); - stmt->setString(4, _gameAccountInfo->Name); - LoginDatabase.DirectExecute(stmt); - - joinResponse->IPv4.push_back(realm->GetAddressForClient(GetRemoteIpAddress())); - - AsyncWrite(joinResponse); -} - -void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected) -{ - Friends::SocialNetworkCheckConnectedResult* socialNetworkCheckConnectedResult = new Friends::SocialNetworkCheckConnectedResult(); - socialNetworkCheckConnectedResult->SocialNetworkId = socialNetworkCheckConnected.SocialNetworkId; - AsyncWrite(socialNetworkCheckConnectedResult); -} - -void Battlenet::Session::HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest) -{ - if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.ItemName)) - { - Cache::GetStreamItemsResponse* getStreamItemsResponse = new Cache::GetStreamItemsResponse(); - getStreamItemsResponse->Index = getStreamItemsRequest.Index; - getStreamItemsResponse->Modules.push_back(module); - AsyncWrite(getStreamItemsResponse); - } -} - -inline std::string PacketToStringHelper(Battlenet::ClientPacket const* packet) -{ - if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE)) - return packet->ToString(); - - return sPacketManager.GetClientPacketName(packet->GetHeader()); -} - -inline std::string PacketToStringHelper(Battlenet::ServerPacket const* packet) -{ - if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE)) - return packet->ToString(); - - return sPacketManager.GetServerPacketName(packet->GetHeader()); -} - -void Battlenet::Session::ReadHandler() -{ - BitStream stream(std::move(GetReadBuffer())); - _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize()); - - while (!stream.IsRead()) - { - try - { - PacketHeader header; - header.Opcode = stream.Read(6); - if (stream.Read(1)) - header.Channel = stream.Read(4); - - if (header.Channel != AUTHENTICATION && (header.Channel != CONNECTION || header.Opcode != Connection::CMSG_PING) && !_authed) - { - TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str()); - CloseSocket(); - return; - } - - if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream)) - { - if (sPacketManager.IsHandled(header)) - TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str()); - - packet->CallHandler(this); - delete packet; - } - else if (sPacketManager.GetClientPacketName(header)) - { - LogUnhandledPacket(header); - break; - } - else - { - TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str()); - break; - } - - stream.AlignToNextByte(); - } - catch (BitStreamPositionException const& e) - { - TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what()); - CloseSocket(); - return; - } - } - - GetReadBuffer().Resize(size_t(BufferSizes::Read)); - AsyncRead(); -} - -void Battlenet::Session::Start() -{ - std::string ip_address = GetRemoteIpAddress().to_string(); - TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str()); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO); - stmt->setString(0, ip_address); - - _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1))); -} - -void Battlenet::Session::CheckIpCallback(PreparedQueryResult result) -{ - if (result) - { - bool banned = false; - do - { - Field* fields = result->Fetch(); - if (fields[0].GetUInt64() != 0) - banned = true; - - if (!fields[1].GetString().empty()) - _ipCountry = fields[1].GetString(); - - } while (result->NextRow()); - - if (banned) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_INTERNAL_ERROR); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort()); - return; - } - } - - AsyncRead(); -} - -bool Battlenet::Session::Update() -{ - EncryptableBuffer* queued; - MessageBuffer buffer((std::size_t(BufferSizes::Read))); - while (_bufferQueue.Dequeue(queued)) - { - std::size_t packetSize = queued->Buffer.GetActiveSize(); - if (queued->Encrypt) - _crypt.EncryptSend(queued->Buffer.GetReadPointer(), packetSize); - - if (buffer.GetRemainingSpace() < packetSize) - { - QueuePacket(std::move(buffer)); - buffer.Resize(std::size_t(BufferSizes::Read)); - } - - if (buffer.GetRemainingSpace() >= packetSize) - buffer.Write(queued->Buffer.GetReadPointer(), packetSize); - else // single packet larger than 16384 bytes - client will reject. - QueuePacket(std::move(queued->Buffer)); - - delete queued; - } - - if (buffer.GetActiveSize() > 0) - QueuePacket(std::move(buffer)); - - if (!BattlenetSocket::Update()) - return false; - - _queryProcessor.ProcessReadyCallbacks(); - - return true; -} - -void Battlenet::Session::AsyncWrite(ServerPacket* packet) -{ - if (!IsOpen()) - { - delete packet; - return; - } - - TC_LOG_DEBUG("session.packets", "%s Sending %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str()); - - packet->Write(); - - EncryptableBuffer* buffer = new EncryptableBuffer(); - buffer->Buffer.Write(packet->GetData(), packet->GetSize()); - buffer->Encrypt = _crypt.IsInitialized(); - delete packet; - - _bufferQueue.Enqueue(buffer); -} - -inline void ReplaceResponse(Battlenet::ServerPacket** oldResponse, Battlenet::ServerPacket* newResponse) -{ - if (*oldResponse) - delete *oldResponse; - - *oldResponse = newResponse; -} - -bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacket** response) -{ - if (dataStream->GetSize() != 1 + 128 + 32 + 128) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, logonResponse); - return false; - } - - if (dataStream->Read(8) != 2) // State - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, logonResponse); - return false; - } - - BigNumber A, clientM1, clientChallenge; - A.SetBinary(dataStream->ReadBytes(128).get(), 128); - clientM1.SetBinary(dataStream->ReadBytes(32).get(), 32); - clientChallenge.SetBinary(dataStream->ReadBytes(128).get(), 128); - - if ((A % N).IsZero()) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, logonResponse); - return false; - } - - SHA256Hash sha; - sha.UpdateBigNumbers(&A, &B, nullptr); - sha.Finalize(); - - BigNumber u; - u.SetBinary(sha.GetDigest(), sha.GetLength()); - - BigNumber S = ((A * v.ModExp(u, N)) % N).ModExp(b, N); - - uint8 S_bytes[128]; - memcpy(S_bytes, S.AsByteArray(128).get(), 128); - - uint8 part1[64]; - uint8 part2[64]; - - for (int i = 0; i < 64; ++i) - { - part1[i] = S_bytes[i * 2]; - part2[i] = S_bytes[i * 2 + 1]; - } - - SHA256Hash part1sha, part2sha; - part1sha.UpdateData(part1, 64); - part1sha.Finalize(); - part2sha.UpdateData(part2, 64); - part2sha.Finalize(); - - uint8 sessionKey[SHA256_DIGEST_LENGTH * 2]; - for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) - { - sessionKey[i * 2] = part1sha.GetDigest()[i]; - sessionKey[i * 2 + 1] = part2sha.GetDigest()[i]; - } - - K.SetBinary(sessionKey, SHA256_DIGEST_LENGTH * 2); - - BigNumber M1; - - uint8 hash[SHA256_DIGEST_LENGTH]; - sha.Initialize(); - sha.UpdateBigNumbers(&N, nullptr); - sha.Finalize(); - memcpy(hash, sha.GetDigest(), sha.GetLength()); - - sha.Initialize(); - sha.UpdateBigNumbers(&g, nullptr); - sha.Finalize(); - - for (int i = 0; i < sha.GetLength(); ++i) - hash[i] ^= sha.GetDigest()[i]; - - SHA256Hash shaI; - shaI.UpdateData(ByteArrayToHexStr(I.AsByteArray().get(), 32)); - shaI.Finalize(); - - // Concat all variables for M1 hash - sha.Initialize(); - sha.UpdateData(hash, SHA256_DIGEST_LENGTH); - sha.UpdateData(shaI.GetDigest(), shaI.GetLength()); - sha.UpdateBigNumbers(&s, &A, &B, &K, nullptr); - sha.Finalize(); - - M1.SetBinary(sha.GetDigest(), sha.GetLength()); - - if (memcmp(M1.AsByteArray().get(), clientM1.AsByteArray().get(), 32)) - { - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setString(0, _accountInfo->Login); - LoginDatabase.Execute(stmt); - - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - ReplaceResponse(response, logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::Password] %s attempted to log in with invalid password!", GetClientInfo().c_str()); - return false; - } - - if (_gameAccounts.empty()) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::Password] %s does not have any linked game accounts!", GetClientInfo().c_str()); - return false; - } - - BigNumber M; - sha.Initialize(); - sha.UpdateBigNumbers(&A, &M1, &K, nullptr); - sha.Finalize(); - M.SetBinary(sha.GetDigest(), sha.GetLength()); - - BigNumber serverProof; - serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client - - BitStream stream; - ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password"); - uint8 state = 3; - - stream.WriteBytes(&state, 1); - stream.WriteBytes(M.AsByteArray(32).get(), 32); - stream.WriteBytes(serverProof.AsByteArray(128).get(), 128); - - password->DataSize = stream.GetSize(); - password->Data = new uint8[password->DataSize]; - memcpy(password->Data, stream.GetBuffer(), password->DataSize); - - Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); - proofRequest->Modules.push_back(password); - if (_gameAccounts.size() > 1) - { - BitStream accounts; - state = 0; - accounts.WriteBytes(&state, 1); - accounts.Write(_gameAccounts.size(), 8); - for (GameAccountInfo const& gameAccount : _gameAccounts) - { - accounts.Write(2, 8); - accounts.WriteString(gameAccount.DisplayName, 8); - } - - ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount"); - selectGameAccount->DataSize = accounts.GetSize(); - selectGameAccount->Data = new uint8[selectGameAccount->DataSize]; - memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize); - proofRequest->Modules.push_back(selectGameAccount); - _modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT); - } - else - { - _gameAccountInfo = &_gameAccounts[0]; - - if (_gameAccountInfo->IsBanned) - { - delete proofRequest; - - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (_gameAccountInfo->IsPermanentlyBanned) - { - logonResponse->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); - } - else - { - logonResponse->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); - } - - ReplaceResponse(response, logonResponse); - return false; - } - - proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); - _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); - } - - ReplaceResponse(response, proofRequest); - return true; -} - -bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response) -{ - if (dataStream->Read(8) != 1) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, logonResponse); - return false; - } - - dataStream->Read(8); - std::string account = dataStream->ReadString(8); - if (account.empty()) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, logonResponse); - return false; - } - - for (std::size_t i = 0; i < _gameAccounts.size(); ++i) - { - if (_gameAccounts[i].DisplayName == account) - { - _gameAccountInfo = &_gameAccounts[i]; - break; - } - } - - if (!_gameAccountInfo) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, complete); - TC_LOG_DEBUG("session", "[Battlenet::SelectGameAccount] %s attempted to log in with invalid game account name %s!", GetClientInfo().c_str(), account.c_str()); - return false; - } - - if (_gameAccountInfo->IsBanned) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (_gameAccountInfo->IsPermanentlyBanned) - { - logonResponse->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); - } - else - { - logonResponse->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); - } - - ReplaceResponse(response, logonResponse); - return false; - } - - Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); - proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); - ReplaceResponse(response, proofRequest); - - _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); - return true; -} - -bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response) -{ - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (dataStream->Read(8) == 1 && _accountInfo && _gameAccountInfo) - { - logonResponse->AccountId = _accountInfo->Id; - logonResponse->GameAccountName = _gameAccountInfo->Name; - logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS; - logonResponse->FailedLogins = _accountInfo->FailedLogins; - - LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); - stmt->setString(0, GetRemoteIpAddress().to_string()); - stmt->setUInt8(1, GetLocaleByName(_locale)); - stmt->setString(2, _os); - stmt->setUInt32(3, _accountInfo->Id); - trans->Append(stmt); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); - stmt->setString(0, K.AsHexStr()); - stmt->setBool(1, true); - stmt->setUInt32(2, _accountInfo->Id); - trans->Append(stmt); - - LoginDatabase.CommitTransaction(trans); - - _authed = true; - sSessionMgr.AddSession(this); - } - else - logonResponse->SetAuthResult(AUTH_BAD_VERSION_HASH); - - ReplaceResponse(response, logonResponse); - return true; -} - -bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket** response) -{ - if (dataStream->Read(8) != 1) - { - Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); - resumeResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, resumeResponse); - return false; - } - - static uint8 const ResumeClient = 0; - static uint8 const ResumeServer = 1; - - std::unique_ptr clientChallenge = dataStream->ReadBytes(16); - std::unique_ptr clientProof = dataStream->ReadBytes(32); - std::unique_ptr serverChallenge = _reconnectProof.AsByteArray(16); - std::unique_ptr sessionKey = K.AsByteArray(64); - - HmacSha256 clientPart(64, sessionKey.get()); - clientPart.UpdateData(&ResumeClient, 1); - clientPart.UpdateData(clientChallenge.get(), 16); - clientPart.UpdateData(serverChallenge.get(), 16); - clientPart.Finalize(); - - HmacSha256 serverPart(64, sessionKey.get()); - serverPart.UpdateData(&ResumeServer, 1); - serverPart.UpdateData(serverChallenge.get(), 16); - serverPart.UpdateData(clientChallenge.get(), 16); - serverPart.Finalize(); - - uint8 newSessionKey[64]; - memcpy(&newSessionKey[0], clientPart.GetDigest(), clientPart.GetLength()); - memcpy(&newSessionKey[32], serverPart.GetDigest(), serverPart.GetLength()); - - K.SetBinary(newSessionKey, 64); - - HmacSha256 proof(64, newSessionKey); - proof.UpdateData(&ResumeClient, 1); - proof.UpdateData(clientChallenge.get(), 16); - proof.UpdateData(serverChallenge.get(), 16); - proof.Finalize(); - - if (memcmp(proof.GetDigest(), clientProof.get(), serverPart.GetLength())) - { - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setString(0, _accountInfo->Login); - LoginDatabase.Execute(stmt); - - TC_LOG_DEBUG("session", "[Battlenet::Resume] %s attempted to reconnect with invalid password!", GetClientInfo().c_str()); - Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); - resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - ReplaceResponse(response, resumeResponse); - return false; - } - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); - stmt->setString(0, K.AsHexStr()); - stmt->setBool(1, true); - stmt->setUInt32(2, _accountInfo->Id); - LoginDatabase.Execute(stmt); - - HmacSha256 serverProof(64, newSessionKey); - serverProof.UpdateData(&ResumeServer, 1); - serverProof.UpdateData(serverChallenge.get(), 16); - serverProof.UpdateData(clientChallenge.get(), 16); - serverProof.Finalize(); - - ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume"); - - BitStream resumeData; - uint8 state = 2; - resumeData.WriteBytes(&state, 1); - resumeData.WriteBytes(serverProof.GetDigest(), serverProof.GetLength()); - - resume->DataSize = resumeData.GetSize(); - resume->Data = new uint8[resume->DataSize]; - memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); - - Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); - resumeResponse->Modules.push_back(resume); - ReplaceResponse(response, resumeResponse); - _authed = true; - sSessionMgr.AddSession(this); - return true; -} - -bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response) -{ - TC_LOG_ERROR("session.packets", "Unhandled module."); - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, logonResponse); - return false; -} - -void Battlenet::Session::UpdateRealms(std::vector& realms, std::vector& deletedRealms) -{ - for (Realm const* realm : realms) - AsyncWrite(BuildListUpdate(realm)); - - for (Battlenet::RealmHandle& deleted : deletedRealms) - { - WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); - listUpdate->UpdateState = WoWRealm::ListUpdate::DELETED; - listUpdate->Id = deleted; - AsyncWrite(listUpdate); - } -} - -Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const -{ - uint32 flag = realm->Flags & ~REALM_FLAG_SPECIFYBUILD; - RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Build); - if (realm->Build != _build) - { - flag |= REALM_FLAG_VERSION_MISMATCH; - if (buildInfo) - flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for - } - - WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); - listUpdate->Timezone = realm->Timezone; - listUpdate->Population = realm->PopulationLevel; - listUpdate->Lock = (realm->AllowedSecurityLevel > _gameAccountInfo->SecurityLevel) ? 1 : 0; - listUpdate->Type = realm->Type; - listUpdate->Name = realm->Name; - - if (flag & REALM_FLAG_SPECIFYBUILD) - { - std::ostringstream version; - version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; - - listUpdate->Version = version.str(); - listUpdate->Address = realm->GetAddressForClient(GetRemoteIpAddress()); - listUpdate->Build = realm->Build; - } - - listUpdate->Flags = flag; - listUpdate->Id = realm->Id; - return listUpdate; -} - -std::string Battlenet::Session::GetClientInfo() const -{ - std::ostringstream stream; - stream << '[' << GetRemoteIpAddress() << ':' << GetRemotePort(); - if (_accountInfo && !_accountInfo->Login.empty()) - stream << ", Account: " << _accountInfo->Login; - - if (_gameAccountInfo) - stream << ", Game account: " << _gameAccountInfo->Name; - - stream << ']'; - - return stream.str(); -} diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h deleted file mode 100644 index e489208ee6..0000000000 --- a/src/server/bnetserver/Server/Session.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef Session_h__ -#define Session_h__ - -#include "AsyncCallbackProcessor.h" -#include "Packets.h" -#include "BattlenetPacketCrypt.h" -#include "Socket.h" -#include "BigNumber.h" -#include "QueryResult.h" -#include "MPSCQueue.h" -#include -#include - -struct Realm; -using boost::asio::ip::tcp; - -namespace Battlenet -{ - struct PacketHeader; - class BitStream; - - enum ModuleType - { - MODULE_PASSWORD, - MODULE_TOKEN, - MODULE_THUMBPRINT, - MODULE_SELECT_GAME_ACCOUNT, - MODULE_RISK_FINGERPRINT, - MODULE_RESUME, - - MODULE_COUNT - }; - - enum class BufferSizes : uint32 - { - SRP_6_V = 0x80, - SRP_6_S = 0x20, - Read = 0x4000 - }; - - struct AccountInfo - { - void LoadResult(Field* fields); - - uint32 Id; - std::string Login; - bool IsLockedToIP; - std::string LockCountry; - std::string LastIP; - uint32 FailedLogins; - bool IsBanned; - bool IsPermanentlyBanned; - }; - - struct GameAccountInfo - { - void LoadResult(Field* fields); - - uint32 Id; - std::string Name; - std::string DisplayName; - bool IsBanned; - bool IsPermanentlyBanned; - AccountTypes SecurityLevel; - }; - - class Session : public Socket - { - typedef Socket BattlenetSocket; - - public: - explicit Session(tcp::socket&& socket); - ~Session(); - - void LogUnhandledPacket(PacketHeader const& header); - - // Authentication - void HandleLogonRequest(Authentication::LogonRequest const& logonRequest); - void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest); - void HandleProofResponse(Authentication::ProofResponse const& proofResponse); - - // Connection - void HandlePing(Connection::Ping const& ping); - void HandleEnableEncryption(Connection::EnableEncryption& enableEncryption); - void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest); - void HandleConnectionClosing(Connection::ConnectionClosing const& connectionClosing); - - // WoWRealm - void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest); - void HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& listUnsubscribe); - void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest); - - // Friends - void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected); - - // Cache - void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest); - - void Start() override; - bool Update() override; - - void UpdateRealms(std::vector& realms, std::vector& deletedRealms); - - uint32 GetAccountId() const { return _accountInfo->Id; } - uint32 GetGameAccountId() const { return _gameAccountInfo->Id; } - - bool IsToonOnline() const { return _toonOnline; } - void SetToonOnline(bool online) { _toonOnline = online; } - - bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; } - - void AsyncWrite(ServerPacket* packet); - - protected: - void ReadHandler() override; - - private: - void _SetVSFields(std::string const& rI); - - typedef bool(Session::*ModuleHandler)(BitStream* dataStream, ServerPacket** response); - static ModuleHandler const ModuleHandlers[MODULE_COUNT]; - - void CheckIpCallback(PreparedQueryResult result); - void HandleLogonRequestCallback(PreparedQueryResult result); - void HandleResumeRequestCallback(PreparedQueryResult result); - void HandleListSubscribeRequestCallback(PreparedQueryResult result); - - bool HandlePasswordModule(BitStream* dataStream, ServerPacket** response); - bool HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response); - bool HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response); - bool HandleResumeModule(BitStream* dataStream, ServerPacket** response); - bool UnhandledModule(BitStream* dataStream, ServerPacket** response); - - WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const; - std::string GetClientInfo() const; - - AccountInfo* _accountInfo; - GameAccountInfo* _gameAccountInfo; // Points at selected game account (inside _gameAccounts) - std::vector _gameAccounts; - - std::string _locale; - std::string _os; - uint32 _build; - - std::string _ipCountry; - - BigNumber N; - BigNumber g; - BigNumber k; - - BigNumber I; - BigNumber s; - BigNumber v; - - BigNumber b; - BigNumber B; - BigNumber K; // session key - - BigNumber _reconnectProof; - - std::queue _modulesWaitingForData; - - struct EncryptableBuffer - { - MessageBuffer Buffer; - bool Encrypt; - }; - - MPSCQueue _bufferQueue; - - PacketCrypt _crypt; - bool _authed; - bool _subscribedToRealmListUpdates; - bool _toonOnline; - - QueryCallbackProcessor _queryProcessor; - }; - -} - -#endif // Session_h__ diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp deleted file mode 100644 index 64b0dc42e5..0000000000 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "SessionManager.h" -#include "Containers.h" -#include "Hash.h" -#include -#include - -namespace -{ - std::unordered_map, Battlenet::Session*> _sessions; - std::unordered_map> _sessionsByAccountId; - boost::shared_mutex _sessionMutex; -} - -Battlenet::SessionManager::SessionManager() : SocketMgr() -{ -} - -Battlenet::SessionManager::~SessionManager() -{ -} - -Battlenet::SessionManager& Battlenet::SessionManager::Instance() -{ - static SessionManager instance; - return instance; -} - -bool Battlenet::SessionManager::StartNetwork(Trinity::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, int threadCount /*= 1*/) -{ - if (!BaseSocketMgr::StartNetwork(ioContext, bindIp, port, threadCount)) - return false; - - _acceptor->SetSocketFactory(std::bind(&BaseSocketMgr::GetSocketForAccept, this)); - _acceptor->AsyncAcceptWithCallback<&OnSocketAccept>(); - return true; -} - -NetworkThread* Battlenet::SessionManager::CreateThreads() const -{ - return new NetworkThread[GetNetworkThreadCount()]; -} - -void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock, uint32 threadIndex) -{ - sSessionMgr.OnSocketOpen(std::forward(sock), threadIndex); -} - -void Battlenet::SessionManager::AddSession(Session* session) -{ - std::unique_lock lock(_sessionMutex); - _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session; - _sessionsByAccountId[session->GetAccountId()].push_back(session); -} - -void Battlenet::SessionManager::RemoveSession(Session* session) -{ - std::unique_lock lock(_sessionMutex); - auto itr = _sessions.find({ session->GetAccountId(), session->GetGameAccountId() }); - // Remove old session only if it was not overwritten by reconnecting - if (itr != _sessions.end() && itr->second == session) - _sessions.erase(itr); - - _sessionsByAccountId[session->GetAccountId()].remove(session); -} - -Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint32 gameAccountId) const -{ - boost::shared_lock lock(_sessionMutex); - return Trinity::Containers::MapGetValuePtr(_sessions, { accountId, gameAccountId }); -} - -std::list* Battlenet::SessionManager::GetSessions(uint32 accountId) const -{ - boost::shared_lock lock(_sessionMutex); - return Trinity::Containers::MapGetValuePtr(_sessionsByAccountId, accountId); -} - -void Battlenet::SessionManager::LockedForEach(std::function&& iterator) const -{ - boost::shared_lock lock(_sessionMutex); - for (auto const& pair : _sessions) - iterator(pair.second); -} diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h deleted file mode 100644 index e832b24e7d..0000000000 --- a/src/server/bnetserver/Server/SessionManager.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef SessionManager_h__ -#define SessionManager_h__ - -#include "SocketMgr.h" -#include "Session.h" -#include -#include - -namespace Battlenet -{ - class SessionManager : public SocketMgr - { - typedef SocketMgr BaseSocketMgr; - - public: - static SessionManager& Instance(); - - bool StartNetwork(Trinity::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, int threadCount = 1) override; - - void AddSession(Session* session); - void RemoveSession(Session* session); - - Session* GetSession(uint32 accountId, uint32 gameAccountId) const; - std::list* GetSessions(uint32 accountId) const; - - void LockedForEach(std::function&& iterator) const; - - protected: - NetworkThread* CreateThreads() const override; - - private: - static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex); - - SessionManager(); - ~SessionManager(); - }; -} - -#define sSessionMgr Battlenet::SessionManager::Instance() - -#endif // SessionManager_h__ diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist deleted file mode 100644 index 35dcb1dcb5..0000000000 --- a/src/server/bnetserver/bnetserver.conf.dist +++ /dev/null @@ -1,350 +0,0 @@ -############################################### -# Trinity Core Auth Server configuration file # -############################################### -[authserver] - -################################################################################################### -# SECTION INDEX -# -# EXAMPLE CONFIG -# AUTH SERVER SETTINGS -# MYSQL SETTINGS -# LOGGING SYSTEM SETTINGS -# -################################################################################################### - -################################################################################################### -# EXAMPLE CONFIG -# -# Variable -# Description: Brief description what the variable is doing. -# Important: Annotation for important things about this variable. -# Example: "Example, i.e. if the value is a string" -# Default: 10 - (Enabled|Comment|Variable name in case of grouped config options) -# 0 - (Disabled|Comment|Variable name in case of grouped config options) -# -# Note to developers: -# - Copy this example to keep the formatting. -# - Line breaks should be at column 100. -################################################################################################### - -################################################################################################### -# AUTH SERVER SETTINGS -# -# LogsDir -# Description: Logs directory setting. -# Important: LogsDir needs to be quoted, as the string might contain space characters. -# Logs directory must exists, or log file creation will be disabled. -# Default: "" - (Log files will be stored in the current path) - -LogsDir = "" - -# -# MaxPingTime -# Description: Time (in minutes) between database pings. -# Default: 30 - -MaxPingTime = 30 - -# -# WorldserverListenPort -# Description: TCP port to listen on for incoming worldserver IPC. -# Default: 1118 - -WorldserverListenPort = 1118 - -# -# BattlenetPort -# Description: TCP port to reach the auth server for battle.net connections. -# Default: 1119 - -BattlenetPort = 1119 - -# -# -# BindIP -# Description: Bind auth server to IP/hostname -# Default: "0.0.0.0" - (Bind to all IPs on the system) - -BindIP = "0.0.0.0" - -# -# PidFile -# Description: Auth server PID file. -# Example: "./authserver.pid" - (Enabled) -# Default: "" - (Disabled) - -PidFile = "" - -# -# UseProcessors -# Description: Processors mask for Windows and Linux based multi-processor systems. -# Example: A computer with 2 CPUs: -# 1 - 1st CPU only, 2 - 2nd CPU only, 3 - 1st and 2nd CPU, because 1 | 2 is 3 -# Default: 0 - (Selected by OS) -# 1+ - (Bit mask value of selected processors) - -UseProcessors = 0 - -# -# ProcessPriority -# Description: Process priority setting for Windows and Linux based systems. -# Details: On Linux, a nice value of -15 is used. (requires superuser). On Windows, process is set to HIGH class. -# Default: 0 - (Normal) -# 1 - (High) - -ProcessPriority = 0 - -# -# RealmsStateUpdateDelay -# Description: Time (in seconds) between realm list updates. -# Default: 10 -# 0 - (Disabled) - -RealmsStateUpdateDelay = 10 - -# -# WrongPass.MaxCount -# Description: Number of login attemps with wrong password before the account or IP will be -# banned. -# Default: 0 - (Disabled) -# 1+ - (Enabled) - -WrongPass.MaxCount = 0 - -# -# WrongPass.BanTime -# Description: Time (in seconds) for banning account or IP for invalid login attempts. -# Default: 600 - (10 minutes) -# 0 - (Permanent ban) - -WrongPass.BanTime = 600 - -# -# WrongPass.BanType -# Description: Ban type for invalid login attempts. -# Default: 0 - (Ban IP) -# 1 - (Ban Account) - -WrongPass.BanType = 0 - -# -# SourceDirectory -# Description: The path to your TrinityCore source directory. -# If the path is left empty, the built-in CMAKE_SOURCE_DIR is used. -# Example: "../TrinityCore" -# Default: "" - -SourceDirectory = "" - -# -# MySQLExecutable -# Description: The path to your mysql cli binary. -# If the path is left empty, built-in path from cmake is used. -# Example: "C:/Program Files/MySQL/MySQL Server 5.7/bin/mysql.exe" -# "mysql.exe" -# "/usr/bin/mysql" -# Default: "" - -MySQLExecutable = "" - -# -################################################################################################### - -################################################################################################### -# MYSQL SETTINGS -# -# LoginDatabaseInfo -# Description: Database connection settings for the realm server. -# Example: "hostname;port;username;password;database" -# ".;somenumber;username;password;database" - (Use named pipes on Windows -# "enable-named-pipe" to [mysqld] -# section my.ini) -# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on -# Unix/Linux) -# Default: "127.0.0.1;3306;trinity;trinity;auth" - -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" - -# -# LoginDatabase.WorkerThreads -# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL -# statements. Each worker thread is mirrored with its own connection to the -# Default: 1 - -LoginDatabase.WorkerThreads = 1 - -# -# LoginDatabase.SynchThreads -# Description: The amount of MySQL connections spawned to handle. -# Default: 1 - (LoginDatabase.WorkerThreads) - -LoginDatabase.SynchThreads = 1 - -# -# Wrong.Password.Login.Logging -# Description: Additionally log attempted wrong password logging -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Wrong.Password.Login.Logging = 0 -# -################################################################################################### - -################################################################################################### -# UPDATE SETTINGS -# -# Updates.EnableDatabases -# Description: A mask that describes which databases shall be updated. -# -# Following flags are available -# DATABASE_LOGIN = 1, // Auth database -# -# Default: 0 - (All Disabled) -# 1 - (All Enabled) - -Updates.EnableDatabases = 0 - -# -# Updates.AutoSetup -# Description: Auto populate empty databases. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -Updates.AutoSetup = 1 - -# -# Updates.Redundancy -# Description: Perform data redundancy checks through hashing -# to detect changes on sql updates and reapply it. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -Updates.Redundancy = 1 - -# -# Updates.ArchivedRedundancy -# Description: Check hashes of archived updates (slows down startup). -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Updates.ArchivedRedundancy = 0 - -# -# Updates.AllowRehash -# Description: Inserts the current file hash in the database if it is left empty. -# Useful if you want to mark a file as applied but you don't know its hash. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -Updates.AllowRehash = 1 - -# -# Updates.CleanDeadRefMaxCount -# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step. -# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value. -# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision). -# Disable this if you want to know if the database is in a possible "dirty state". -# Default: 3 - (Enabled) -# 0 - (Disabled) -# -1 - (Enabled - unlimited) - -Updates.CleanDeadRefMaxCount = 3 - -# -################################################################################################### - -################################################################################################### -# -# LOGGING SYSTEM SETTINGS -# -# Appender config values: Given a appender "name" -# Appender.name -# Description: Defines 'where to log' -# Format: Type,LogLevel,Flags,optional1,optional2,optional3 -# -# Type -# 0 - (None) -# 1 - (Console) -# 2 - (File) -# 3 - (DB) -# -# LogLevel -# 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Flags: -# 0 - None -# 1 - Prefix Timestamp to the text -# 2 - Prefix Log Level to the text -# 4 - Prefix Log Filter type to the text -# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) -# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) -# -# Colors (read as optional1 if Type = Console) -# Format: "fatal error warn info debug trace" -# 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "13 11 9 5 3 1" -# -# File: Name of the file (read as optional1 if Type = File) -# Allows to use one "%s" to create dynamic files -# -# Mode: Mode to open the file (read as optional2 if Type = File) -# a - (Append) -# w - (Overwrite) -# -# MaxFileSize: Maximum file size of the log file before creating a new log file -# (read as optional3 if Type = File) -# Size is measured in bytes expressed in a 64-bit unsigned integer. -# Maximum value is 4294967295 (4 gb). Leave blank for no limit. -# NOTE: Does not work with dynamic filenames. -# Example: 536870912 (512 mb) -# - -Appender.Console=1,2,0 -Appender.Bnet=2,2,0,Bnet.log,w - -# Logger config values: Given a logger "name" -# Logger.name -# Description: Defines 'What to log' -# Format: LogLevel,AppenderList -# -# LogLevel -# 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# AppenderList: List of appenders linked to logger -# (Using spaces as separator). -# - -Logger.root=3,Console Bnet -Logger.realmlist=3,Console Bnet -Logger.session=3,Console Bnet -Logger.session.packets=3,Console Bnet - -# -################################################################################################### diff --git a/src/server/bnetserver/bnetserver.ico b/src/server/bnetserver/bnetserver.ico deleted file mode 100644 index da318f48a8..0000000000 Binary files a/src/server/bnetserver/bnetserver.ico and /dev/null differ diff --git a/src/server/bnetserver/bnetserver.rc b/src/server/bnetserver/bnetserver.rc deleted file mode 100644 index 89316fb94e..0000000000 --- a/src/server/bnetserver/bnetserver.rc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "resource.h" -#include "revision_data.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" //"afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APPICON ICON "bnetserver.ico" - -///////////////////////////////////////////////////////////////////////////// -// Neutre (Par défaut système) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO -FILEVERSION VER_FILEVERSION -PRODUCTVERSION VER_PRODUCTVERSION - -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - -#ifndef _DEBUG - FILEFLAGS 0 -#else - #define VER_PRERELEASE VS_FF_PRERELEASE - #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD - #define VER_DEBUG 0 - FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) -#endif - -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080004b0" - BEGIN - VALUE "CompanyName", VER_COMPANYNAME_STR - VALUE "FileDescription", "TrinityCore Battle.net Server Daemon" - VALUE "FileVersion", VER_FILEVERSION_STR - VALUE "InternalName", "bnetserver" - VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR - VALUE "OriginalFilename", "bnetserver.exe" - VALUE "ProductName", "TrinityCore Battle.net Server" - VALUE "ProductVersion", VER_PRODUCTVERSION_STR - END - END - - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x800, 1200 - END -END -#endif diff --git a/src/server/bnetserver/resource.h b/src/server/bnetserver/resource.h deleted file mode 100644 index 7dc5cb9ef7..0000000000 --- a/src/server/bnetserver/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by TrinityCore.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/server/database/Database/Field.cpp b/src/server/database/Database/Field.cpp index e47d362929..b07273fdc4 100644 --- a/src/server/database/Database/Field.cpp +++ b/src/server/database/Database/Field.cpp @@ -16,6 +16,7 @@ */ #include "Field.h" +#include "Errors.h" #include "Log.h" #include "MySQLHacks.h" #include @@ -237,6 +238,18 @@ std::string Field::GetString() const return std::string(string, data.length); } +std::string_view Field::GetStringView() const +{ + if (!data.value) + return {}; + + char const* const string = GetCString(); + if (!string) + return {}; + + return { string, data.length }; +} + std::vector Field::GetBinary() const { std::vector result; @@ -289,3 +302,9 @@ void Field::SetMetadata(QueryResultFieldMetadata const* fieldMeta) { meta = fieldMeta; } + +void Field::GetBinarySizeChecked(uint8* buf, size_t length) const +{ + ASSERT(data.value && (data.length == length), "Expected %zu-byte binary blob, got %sdata (%u bytes) instead", length, data.value ? "" : "no ", data.length); + memcpy(buf, data.value, length); +} diff --git a/src/server/database/Database/Field.h b/src/server/database/Database/Field.h index ea7c82d187..a665f802d1 100644 --- a/src/server/database/Database/Field.h +++ b/src/server/database/Database/Field.h @@ -103,7 +103,15 @@ class TC_DATABASE_API Field double GetDouble() const; char const* GetCString() const; std::string GetString() const; + std::string_view GetStringView() const; std::vector GetBinary() const; + template + std::array GetBinary() const + { + std::array buf; + GetBinarySizeChecked(buf.data(), S); + return buf; + } bool IsNull() const { @@ -129,6 +137,8 @@ class TC_DATABASE_API Field QueryResultFieldMetadata const* meta; void LogWrongType(char const* getter) const; void SetMetadata(QueryResultFieldMetadata const* fieldMeta); + + void GetBinarySizeChecked(uint8* buf, size_t size) const; }; #endif diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index dd726d30dd..e12bc52f68 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -34,24 +34,21 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 AND username LIKE CONCAT('%%', ?, '%%') GROUP BY account.id", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned (id, bandate, unbandate, bannedby, banreason, active) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban', 1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION, "SELECT username, sessionkey FROM account WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION, "SELECT username, session_key_auth FROM account WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_LOGON, "UPDATE account SET salt = ?, verifier = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET session_key_auth = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ?, timezone_offset = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, " - "ab.unbandate = ab.bandate, aa.gmlevel, a.token_key, a.sha_pass_hash, a.v, a.s, a.battlenet_account " - "FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?", CONNECTION_ASYNC); + "ab.unbandate = ab.bandate, aa.SecurityLevel, a.totp_secret, a.salt, a.verifier " + "FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_RECONNECTCHALLENGE, "SELECT a.id, UPPER(a.username), a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, " - "ab.unbandate = ab.bandate, aa.gmlevel, a.sessionKey " - "FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?", CONNECTION_ASYNC); + "ab.unbandate = ab.bandate, aa.SecurityLevel, a.session_key_auth " + "FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ? AND a.session_key_auth IS NOT NULL", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.sessionkey, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.battlenet_account, aa.gmLevel, " - "bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id " - "FROM account a LEFT JOIN account r ON a.id = r.recruiter LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id " - "LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?) LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 " - "WHERE a.username = ? ORDER BY aa.RealmID DESC LIMIT 1", CONNECTION_ASYNC); - + PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key_auth, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.timezone_offset, aa.SecurityLevel, " + "ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?) " + "LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account r ON a.id = r.recruiter WHERE a.username = ? AND a.session_key_auth IS NOT NULL ORDER BY aa.RealmID DESC LIMIT 1", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_REALM_CHARACTER_COUNTS, "SELECT realmid, numchars FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); @@ -60,18 +57,16 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_IP_NOT_BANNED, "DELETE FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_ACCOUNT_BANNED, "INSERT INTO account_banned (id, bandate, unbandate, bannedby, banreason, active) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM, "DELETE FROM realmcharacters WHERE acctid = ? AND realmid = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_REP_REALM_CHARACTERS, "REPLACE INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_SUM_REALM_CHARACTERS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, reg_mail, email, joindate, battlenet_account, battlenet_index) VALUES(?, ?, ?, ?, NOW(), ?, ?)", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, salt, verifier, reg_mail, email, joindate) VALUES(?, ?, ?, ?, ?, NOW())", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid = account.id WHERE acctid IS NULL", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK_COUNTRY, "UPDATE account SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET username = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EMAIL, "UPDATE account SET email = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_REG_EMAIL, "UPDATE account SET reg_mail = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? , mutereason = ? , muteby = ? WHERE id = ?", CONNECTION_ASYNC); @@ -81,20 +76,20 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_UPD_ACCOUNT_ONLINE, "UPDATE account SET online = 1 WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_UPTIME_PLAYERS, "UPDATE uptime SET uptime = ?, maxplayers = ? WHERE realmid = ? AND starttime = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_OLD_LOGS, "DELETE FROM logs WHERE (time + ?) < ? AND realm = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS, "DELETE FROM account_access WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, "DELETE FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT_ACCESS, "INSERT INTO account_access (id,gmlevel,RealmID) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS, "DELETE FROM account_access WHERE AccountID = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, "DELETE FROM account_access WHERE AccountID = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_ACCOUNT_ACCESS, "INSERT INTO account_access (AccountID,SecurityLevel,RealmID) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_GET_GMLEVEL_BY_REALMID, "SELECT gmlevel FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1) ORDER BY RealmID DESC", CONNECTION_BOTH); + PrepareStatement(LOGIN_GET_GMLEVEL_BY_REALMID, "SELECT SecurityLevel FROM account_access WHERE AccountID = ? AND (RealmID = ? OR RealmID = -1) ORDER BY RealmID DESC", CONNECTION_BOTH); PrepareStatement(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT 1 FROM account WHERE id = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT 1 FROM account WHERE username = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.reg_mail, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby, a.failed_logins, a.locked, a.OS FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT salt, verifier FROM account WHERE id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT salt, verifier FROM account WHERE username = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.SecurityLevel, a.email, a.reg_mail, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby, a.failed_logins, a.locked, a.OS FROM account a LEFT JOIN account_access aa ON (a.id = aa.AccountID AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id = aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.gmlevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST, "SELECT 1 FROM account_access WHERE id = ? AND gmlevel > ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS, "SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.SecurityLevel FROM account a, account_access aa WHERE a.id = aa.AccountID AND aa.SecurityLevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.SecurityLevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.AccountID) WHERE a.id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST, "SELECT 1 FROM account_access WHERE AccountID = ? AND SecurityLevel > ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS, "SELECT a.id, aa.SecurityLevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.AccountID) WHERE a.username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_LAST_ATTEMPT_IP, "SELECT last_attempt_ip FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_LAST_IP, "SELECT last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); @@ -110,7 +105,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_INS_CHAR_IP_LOGGING, "INSERT INTO logs_ip_actions (account_id,character_guid,type,ip,systemnote,unixtime,time) VALUES (?, ?, ?, ?, ?, unix_timestamp(NOW()), NOW())", CONNECTION_ASYNC); // 0: uint32, 1: string, 2: string // Complete name: "Login_Insert_Failed_Account_Login_due_password_IP_Logging" PrepareStatement(LOGIN_INS_FALP_IP_LOGGING, "INSERT INTO logs_ip_actions (account_id,character_guid,type,ip,systemnote,unixtime,time) VALUES (?, 0, 1, ?, ?, unix_timestamp(NOW()), NOW())", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT SecurityLevel, RealmID FROM account_access WHERE AccountID = ? and (RealmID = ? OR RealmID = -1) ORDER BY SecurityLevel desc", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_BOTH); PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); @@ -120,34 +115,12 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT_MUTED, "DELETE FROM account_muted WHERE guid = ?", CONNECTION_ASYNC); -#define BnetAccountInfo "ba.id, UPPER(ba.email), ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate" -#define BnetGameAccountInfo "a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel" + PrepareStatement(LOGIN_SEL_SECRET_DIGEST, "SELECT digest FROM secret_digest WHERE id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_SECRET_DIGEST, "INSERT INTO secret_digest (id, digest) VALUES (?,?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_SECRET_DIGEST, "DELETE FROM secret_digest WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", ba.sha_pass_hash, ba.v, ba.s, " BnetGameAccountInfo - " FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account" - " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ?, online = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT " BnetAccountInfo ", ba.sessionKey, " BnetGameAccountInfo - " FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account" - " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? AND a.username = ?", CONNECTION_ASYNC); - -#undef BnetGameAccountInfo -#undef BnetAccountInfo - PrepareStatement(LOGIN_UPD_BNET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE email = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_BNET_ACCOUNT, "INSERT INTO battlenet_accounts (`email`,`sha_pass_hash`) VALUES (?, ?)", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID, "SELECT email FROM battlenet_accounts WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL, "SELECT id FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_UPD_BNET_PASSWORD, "UPDATE battlenet_accounts SET v = '', s = '', sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_CHECK_PASSWORD, "SELECT 1 FROM battlenet_accounts WHERE id = ? AND sha_pass_hash = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK, "UPDATE battlenet_accounts SET locked = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_COUNTRY, "UPDATE battlenet_accounts SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT, "SELECT battlenet_account FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LINK, "UPDATE account SET battlenet_account = ?, battlenet_index = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX, "SELECT MAX(battlenet_index) FROM account WHERE battlenet_account = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_LIST, "SELECT a.id, a.username FROM account a LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id WHERE ba.email = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_TOTP_SECRET, "SELECT totp_secret FROM account WHERE id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET, "UPDATE account SET totp_secret = ? WHERE id = ?", CONNECTION_ASYNC); } LoginDatabaseConnection::LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index 237ccfe68e..3957053e28 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -38,7 +38,7 @@ enum LoginDatabaseStatements : uint32 LOGIN_INS_ACCOUNT_AUTO_BANNED, LOGIN_DEL_ACCOUNT_BANNED, LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION, - LOGIN_UPD_VS, + LOGIN_UPD_LOGON, LOGIN_UPD_LOGONPROOF, LOGIN_SEL_LOGONCHALLENGE, LOGIN_SEL_RECONNECTCHALLENGE, @@ -56,9 +56,8 @@ enum LoginDatabaseStatements : uint32 LOGIN_SEL_ACCOUNT_BY_ID, LOGIN_INS_ACCOUNT_BANNED, LOGIN_UPD_ACCOUNT_NOT_BANNED, - LOGIN_DEL_REALM_CHARACTERS_BY_REALM, LOGIN_DEL_REALM_CHARACTERS, - LOGIN_INS_REALM_CHARACTERS, + LOGIN_REP_REALM_CHARACTERS, LOGIN_SEL_SUM_REALM_CHARACTERS, LOGIN_INS_ACCOUNT, LOGIN_INS_REALM_CHARACTERS_INIT, @@ -67,7 +66,6 @@ enum LoginDatabaseStatements : uint32 LOGIN_UPD_ACCOUNT_LOCK_COUNTRY, LOGIN_INS_LOG, LOGIN_UPD_USERNAME, - LOGIN_UPD_PASSWORD, LOGIN_UPD_EMAIL, LOGIN_UPD_REG_EMAIL, LOGIN_UPD_MUTE_TIME, @@ -112,24 +110,12 @@ enum LoginDatabaseStatements : uint32 LOGIN_SEL_ACCOUNT_MUTE_INFO, LOGIN_DEL_ACCOUNT_MUTED, - LOGIN_SEL_BNET_ACCOUNT_INFO, - LOGIN_UPD_BNET_VS_FIELDS, - LOGIN_UPD_BNET_SESSION_KEY, - LOGIN_SEL_BNET_RECONNECT_INFO, - LOGIN_UPD_BNET_FAILED_LOGINS, - LOGIN_UPD_BNET_LAST_LOGIN_INFO, - LOGIN_SEL_BNET_CHARACTER_COUNTS, - LOGIN_INS_BNET_ACCOUNT, - LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID, - LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL, - LOGIN_UPD_BNET_PASSWORD, - LOGIN_SEL_BNET_CHECK_PASSWORD, - LOGIN_UPD_BNET_ACCOUNT_LOCK, - LOGIN_UPD_BNET_ACCOUNT_LOCK_COUNTRY, - LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT, - LOGIN_UPD_BNET_GAME_ACCOUNT_LINK, - LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX, - LOGIN_SEL_BNET_GAME_ACCOUNT_LIST, + LOGIN_SEL_SECRET_DIGEST, + LOGIN_INS_SECRET_DIGEST, + LOGIN_DEL_SECRET_DIGEST, + + LOGIN_SEL_ACCOUNT_TOTP_SECRET, + LOGIN_UPD_ACCOUNT_TOTP_SECRET, MAX_LOGINDATABASE_STATEMENTS }; diff --git a/src/server/database/Database/PreparedStatement.cpp b/src/server/database/Database/PreparedStatement.cpp index 6b33a8fcca..197d692362 100644 --- a/src/server/database/Database/PreparedStatement.cpp +++ b/src/server/database/Database/PreparedStatement.cpp @@ -174,6 +174,14 @@ void PreparedStatementBase::setString(const uint8 index, const std::string& valu statement_data[index].type = TYPE_STRING; } +void PreparedStatementBase::setStringView(uint8 index, std::string_view value) +{ + ASSERT(index < statement_data.size()); + statement_data[index].binary.resize(value.length() + 1); + memcpy(statement_data[index].binary.data(), value.data(), value.length() + 1); + statement_data[index].type = TYPE_STRING; +} + void PreparedStatementBase::setBinary(const uint8 index, const std::vector& value) { ASSERT(index < statement_data.size()); diff --git a/src/server/database/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h index 000c8d629a..26bc10e9d3 100644 --- a/src/server/database/Database/PreparedStatement.h +++ b/src/server/database/Database/PreparedStatement.h @@ -96,7 +96,14 @@ class TC_DATABASE_API PreparedStatementBase void setFloat(uint8 index, float value); void setDouble(uint8 index, double value); void setString(uint8 index, std::string const& value); + void setStringView(uint8 index, std::string_view value); void setBinary(uint8 index, std::vector const& value); + template + void setBinary(const uint8 index, std::array const& value) + { + std::vector vec(value.begin(), value.end()); + setBinary(index, vec); + } uint32 GetIndex() const { return m_index; } protected: diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp index 1305dc409e..644af64786 100644 --- a/src/server/database/Updater/UpdateFetcher.cpp +++ b/src/server/database/Updater/UpdateFetcher.cpp @@ -17,13 +17,13 @@ #include "UpdateFetcher.h" #include "Common.h" +#include "CryptoHash.h" #include "Duration.h" #include "DBUpdater.h" #include "Field.h" #include "Log.h" #include "QueryResult.h" #include "Util.h" -#include "SHA1.h" #include #include #include @@ -224,7 +224,7 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks, } // Calculate a Sha1 hash based on query content. - std::string const hash = CalculateSHA1Hash(ReadSQLUpdate(availableQuery.first)); + std::string const hash = ByteArrayToHexStr(Trinity::Crypto::SHA1::GetDigestOf(ReadSQLUpdate(availableQuery.first))); UpdateMode mode = MODE_APPLY; diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 9b548ab658..edfb1d74f6 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -18,12 +18,13 @@ #include "AccountMgr.h" #include "Config.h" #include "DatabaseEnv.h" +#include "CryptoHash.h" #include "Log.h" #include "ObjectAccessor.h" #include "Player.h" #include "Realm.h" #include "ScriptMgr.h" -#include "SHA1.h" +#include "SRP6.h" #include "Util.h" #include "World.h" #include "WorldSession.h" @@ -41,7 +42,7 @@ AccountMgr* AccountMgr::instance() return &instance; } -AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email /*= ""*/, uint32 bnetAccountId /*= 0*/, uint8 bnetIndex /*= 0*/) +AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email /*= ""*/) { if (utf8length(username) > MAX_ACCOUNT_STR) return AccountOpResult::AOR_NAME_TOO_LONG; // username's too long @@ -59,19 +60,11 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT); stmt->setString(0, username); - stmt->setString(1, CalculateShaPassHash(username, password)); - stmt->setString(2, email); + auto [salt, verifier] = Trinity::Crypto::SRP6::MakeRegistrationData(username, password); + stmt->setBinary(1, salt); + stmt->setBinary(2, verifier); stmt->setString(3, email); - if (bnetAccountId && bnetIndex) - { - stmt->setUInt32(4, bnetAccountId); - stmt->setUInt8(5, bnetIndex); - } - else - { - stmt->setNull(4); - stmt->setNull(5); - } + stmt->setString(4, email); LoginDatabase.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail @@ -129,6 +122,10 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId) stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES); + stmt->setUInt32(0, accountId); + CharacterDatabase.Execute(stmt); + LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT); @@ -176,11 +173,15 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUser Utf8ToUpperOnlyLatin(newPassword); stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_USERNAME); - stmt->setString(0, newUsername); - stmt->setString(1, CalculateShaPassHash(newUsername, newPassword)); - stmt->setUInt32(2, accountId); + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + auto [salt, verifier] = Trinity::Crypto::SRP6::MakeRegistrationData(newUsername, newPassword); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGON); + stmt->setBinary(0, salt); + stmt->setBinary(1, verifier); + stmt->setUInt32(2, accountId); LoginDatabase.Execute(stmt); return AccountOpResult::AOR_OK; @@ -204,20 +205,12 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass Utf8ToUpperOnlyLatin(username); Utf8ToUpperOnlyLatin(newPassword); + auto [salt, verifier] = Trinity::Crypto::SRP6::MakeRegistrationData(username, newPassword); - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_PASSWORD); - - stmt->setString(0, CalculateShaPassHash(username, newPassword)); - stmt->setUInt32(1, accountId); - - LoginDatabase.Execute(stmt); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS); - - stmt->setString(0, ""); - stmt->setString(1, ""); - stmt->setString(2, username); - + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGON); + stmt->setBinary(0, salt); + stmt->setBinary(1, verifier); + stmt->setUInt32(2, accountId);; LoginDatabase.Execute(stmt); sScriptMgr->OnPasswordChange(accountId); @@ -353,10 +346,16 @@ bool AccountMgr::CheckPassword(uint32 accountId, std::string password) LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD); stmt->setUInt32(0, accountId); - stmt->setString(1, CalculateShaPassHash(username, password)); - PreparedQueryResult result = LoginDatabase.Query(stmt); - return (result) ? true : false; + if (PreparedQueryResult result = LoginDatabase.Query(stmt)) + { + Trinity::Crypto::SRP6::Salt salt = (*result)[0].GetBinary(); + Trinity::Crypto::SRP6::Verifier verifier = (*result)[1].GetBinary(); + if (Trinity::Crypto::SRP6::CheckLogin(username, password, salt, verifier)) + return true; + } + + return false; } bool AccountMgr::CheckEmail(uint32 accountId, std::string newEmail) @@ -386,18 +385,6 @@ uint32 AccountMgr::GetCharactersCount(uint32 accountId) return (result) ? (*result)[0].GetUInt64() : 0; } -std::string AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password) -{ - SHA1Hash sha; - sha.Initialize(); - sha.UpdateData(name); - sha.UpdateData(":"); - sha.UpdateData(password); - sha.Finalize(); - - return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength()); -} - bool AccountMgr::IsBannedAccount(std::string const& name) { LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME); diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 97fbf7d79b..fc8cd49e60 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -58,7 +58,7 @@ class TC_GAME_API AccountMgr public: static AccountMgr* instance(); - AccountOpResult CreateAccount(std::string username, std::string password, std::string email = "", uint32 bnetAccountId = 0, uint8 bnetIndex = 0); + AccountOpResult CreateAccount(std::string username, std::string password, std::string email = ""); static AccountOpResult DeleteAccount(uint32 accountId); static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); @@ -74,7 +74,6 @@ class TC_GAME_API AccountMgr static bool GetEmail(uint32 accountId, std::string& email); static uint32 GetCharactersCount(uint32 accountId); - static std::string CalculateShaPassHash(std::string const& name, std::string const& password); static bool IsBannedAccount(std::string const& name); static bool IsPlayerAccount(uint32 gmlevel); static bool IsAdminAccount(uint32 gmlevel); diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp deleted file mode 100644 index fc78a26415..0000000000 --- a/src/server/game/Accounts/BattlenetAccountMgr.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetAccountMgr.h" -#include "AccountMgr.h" -#include "DatabaseEnv.h" -#include "Util.h" -#include "SHA256.h" - -using GameAccountMgr = AccountMgr; - -AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email, std::string password, bool withGameAccount, std::string* gameAccountName) -{ - if (utf8length(email) > MAX_BNET_EMAIL_STR) - return AccountOpResult::AOR_NAME_TOO_LONG; - - if (utf8length(password) > MAX_PASS_STR) - return AccountOpResult::AOR_PASS_TOO_LONG; - - Utf8ToUpperOnlyLatin(email); - Utf8ToUpperOnlyLatin(password); - - if (GetId(email)) - return AccountOpResult::AOR_NAME_ALREADY_EXIST; - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ACCOUNT); - stmt->setString(0, email); - stmt->setString(1, CalculateShaPassHash(email, password)); - LoginDatabase.DirectExecute(stmt); - - uint32 newAccountId = GetId(email); - ASSERT(newAccountId); - - if (withGameAccount) - { - *gameAccountName = std::to_string(newAccountId) + "#1"; - GameAccountMgr::instance()->CreateAccount(*gameAccountName, password, email, newAccountId, 1); - } - - return AccountOpResult::AOR_OK; -} - -AccountOpResult Battlenet::AccountMgr::ChangePassword(uint32 accountId, std::string newPassword) -{ - std::string username; - if (!GetName(accountId, username)) - return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist - - Utf8ToUpperOnlyLatin(username); - Utf8ToUpperOnlyLatin(newPassword); - if (utf8length(newPassword) > MAX_PASS_STR) - return AccountOpResult::AOR_PASS_TOO_LONG; - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_PASSWORD); - stmt->setString(0, CalculateShaPassHash(username, newPassword)); - stmt->setUInt32(1, accountId); - LoginDatabase.Execute(stmt); - - return AccountOpResult::AOR_OK; -} - -bool Battlenet::AccountMgr::CheckPassword(uint32 accountId, std::string password) -{ - std::string username; - - if (!GetName(accountId, username)) - return false; - - Utf8ToUpperOnlyLatin(username); - Utf8ToUpperOnlyLatin(password); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHECK_PASSWORD); - stmt->setUInt32(0, accountId); - stmt->setString(1, CalculateShaPassHash(username, password)); - - return LoginDatabase.Query(stmt) != nullptr; -} - -AccountOpResult Battlenet::AccountMgr::LinkWithGameAccount(std::string const& email, std::string const& gameAccountName) -{ - uint32 bnetAccountId = GetId(email); - if (!bnetAccountId) - return AccountOpResult::AOR_NAME_NOT_EXIST; - - uint32 gameAccountId = GameAccountMgr::GetId(gameAccountName); - if (!gameAccountId) - return AccountOpResult::AOR_NAME_NOT_EXIST; - - if (GetIdByGameAccount(gameAccountId)) - return AccountOpResult::AOR_ACCOUNT_BAD_LINK; - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LINK); - stmt->setUInt32(0, bnetAccountId); - stmt->setUInt8(1, GetMaxIndex(bnetAccountId) + 1); - stmt->setUInt32(2, gameAccountId); - LoginDatabase.Execute(stmt); - return AccountOpResult::AOR_OK; -} - -AccountOpResult Battlenet::AccountMgr::UnlinkGameAccount(std::string const& gameAccountName) -{ - uint32 gameAccountId = GameAccountMgr::GetId(gameAccountName); - if (!gameAccountId) - return AccountOpResult::AOR_NAME_NOT_EXIST; - - if (!GetIdByGameAccount(gameAccountId)) - return AccountOpResult::AOR_ACCOUNT_BAD_LINK; - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LINK); - stmt->setNull(0); - stmt->setNull(1); - stmt->setUInt32(2, gameAccountId); - LoginDatabase.Execute(stmt); - return AccountOpResult::AOR_OK; -} - -uint32 Battlenet::AccountMgr::GetId(std::string const& username) -{ - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL); - stmt->setString(0, username); - if (PreparedQueryResult result = LoginDatabase.Query(stmt)) - return (*result)[0].GetUInt32(); - - return 0; -} - -bool Battlenet::AccountMgr::GetName(uint32 accountId, std::string& name) -{ - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID); - stmt->setUInt32(0, accountId); - if (PreparedQueryResult result = LoginDatabase.Query(stmt)) - { - name = (*result)[0].GetString(); - return true; - } - - return false; -} - -uint32 Battlenet::AccountMgr::GetIdByGameAccount(uint32 gameAccountId) -{ - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT); - stmt->setUInt32(0, gameAccountId); - if (PreparedQueryResult result = LoginDatabase.Query(stmt)) - return (*result)[0].GetUInt32(); - - return 0; -} - -uint8 Battlenet::AccountMgr::GetMaxIndex(uint32 accountId) -{ - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX); - stmt->setUInt32(0, accountId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (result) - return (*result)[0].GetUInt8(); - - return 0; -} - -std::string Battlenet::AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password) -{ - SHA256Hash email; - email.UpdateData(name); - email.Finalize(); - - SHA256Hash sha; - sha.UpdateData(ByteArrayToHexStr(email.GetDigest(), email.GetLength())); - sha.UpdateData(":"); - sha.UpdateData(password); - sha.Finalize(); - - return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true); -} diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h deleted file mode 100644 index fb2e333d4b..0000000000 --- a/src/server/game/Accounts/BattlenetAccountMgr.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BattlenetAccountMgr_h__ -#define BattlenetAccountMgr_h__ - -#include "Define.h" -#include - -enum class AccountOpResult : uint8; - -#define MAX_BNET_EMAIL_STR 320 - -namespace Battlenet -{ - namespace AccountMgr - { - TC_GAME_API AccountOpResult CreateBattlenetAccount(std::string email, std::string password, bool withGameAccount, std::string* gameAccountName); - TC_GAME_API AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); - TC_GAME_API bool CheckPassword(uint32 accountId, std::string password); - TC_GAME_API AccountOpResult LinkWithGameAccount(std::string const& email, std::string const& gameAccountName); - TC_GAME_API AccountOpResult UnlinkGameAccount(std::string const& gameAccountName); - - TC_GAME_API uint32 GetId(std::string const& username); - TC_GAME_API bool GetName(uint32 accountId, std::string& name); - TC_GAME_API uint32 GetIdByGameAccount(uint32 gameAccountId); - TC_GAME_API uint8 GetMaxIndex(uint32 accountId); - - std::string CalculateShaPassHash(std::string const& name, std::string const& password); - } -} - -#endif // BattlenetAccountMgr_h__ diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index f136a24c5c..1513672941 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -283,7 +283,11 @@ enum RBACPermissions RBAC_PERM_COMMAND_GM_LIST = 375, RBAC_PERM_COMMAND_GM_VISIBLE = 376, RBAC_PERM_COMMAND_GO = 377, - // unused 378-386 + RBAC_PERM_COMMAND_ACCOUNT_2FA = 378, + RBAC_PERM_COMMAND_ACCOUNT_2FA_SETUP = 379, + RBAC_PERM_COMMAND_ACCOUNT_2FA_REMOVE = 380, + RBAC_PERM_COMMAND_ACCOUNT_SET_2FA = 381, + // unused 382-386 RBAC_PERM_COMMAND_GOBJECT = 387, RBAC_PERM_COMMAND_GOBJECT_ACTIVATE = 388, RBAC_PERM_COMMAND_GOBJECT_ADD = 389, diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index bf10ff2c7d..7e082555c2 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -53,7 +53,6 @@ target_link_libraries(game trinity-core-interface efsw PUBLIC - ipc game-interface) set_target_properties(game diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index a9513b71ff..cce71a199d 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2194,8 +2194,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool _LogBankEvent(trans, cashFlow ? GUILD_BANK_LOG_CASH_FLOW_DEPOSIT : GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUID().GetCounter(), amount); CharacterDatabase.CommitTransaction(trans); - std::string aux = ByteArrayToHexStr(reinterpret_cast(&m_bankMoney), 8, true); - _BroadcastEvent(GE_BANK_MONEY_SET, player->GetGUID(), aux.c_str()); + _BroadcastEvent(GE_BANK_MONEY_SET, player->GetGUID(), Trinity::StringFormat("%016llX", m_bankMoney).c_str()); if (player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { @@ -2247,8 +2246,7 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool _LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUID().GetCounter(), amount); CharacterDatabase.CommitTransaction(trans); - std::string aux = ByteArrayToHexStr(reinterpret_cast(&m_bankMoney), 8, true); - _BroadcastEvent(GE_BANK_MONEY_SET, player->GetGUID(), aux.c_str()); + _BroadcastEvent(GE_BANK_MONEY_SET, player->GetGUID(), Trinity::StringFormat("%016llX", m_bankMoney).c_str()); if (repair) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS, amount, 0, 0, nullptr, player); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 8315735476..86b51c6743 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -20,7 +20,6 @@ #include "AccountMgr.h" #include "ArenaTeam.h" #include "ArenaTeamMgr.h" -#include "BattlenetServerManager.h" #include "CalendarMgr.h" #include "CharacterCache.h" #include "CharacterPackets.h" @@ -49,6 +48,7 @@ #include "QueryPackets.h" #include "PlayerDump.h" #include "QueryHolder.h" +#include "Realm.h" #include "ReputationMgr.h" #include "ScriptMgr.h" #include "SharedDefines.h" @@ -617,18 +617,13 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction(); + LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); + // Player created, save it now newChar->SaveToDB(characterTransaction, true); createInfo->CharCount += 1; - LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); - stmt->setUInt32(0, GetAccountId()); - stmt->setUInt32(1, realm.Id.Realm); - trans->Append(stmt); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_REALM_CHARACTERS); stmt->setUInt32(0, createInfo->CharCount); stmt->setUInt32(1, GetAccountId()); stmt->setUInt32(2, realm.Id.Realm); @@ -1122,8 +1117,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder) sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName()); - - sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), true); } void WorldSession::HandleSetFactionAtWar(WorldPacket& recvData) diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index f98d748edc..c4c589be45 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -17,7 +17,6 @@ #include "WorldSession.h" #include "AccountMgr.h" -#include "BattlenetAccountMgr.h" #include "CharacterCache.h" #include "DatabaseEnv.h" #include "DBCStores.h" @@ -205,7 +204,6 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails uint8 receiverLevel = 0; uint32 receiverAccountId = 0; - uint32 receiverBnetAccountId = 0; if (receiver) { @@ -213,7 +211,6 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) mailsCount = receiver->GetMailSize(); receiverLevel = receiver->getLevel(); receiverAccountId = receiver->GetSession()->GetAccountId(); - receiverBnetAccountId = receiver->GetSession()->GetBattlenetAccountId(); } else { @@ -233,8 +230,6 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) Field* fields = result->Fetch(); mailsCount = fields[0].GetUInt64(); } - - receiverBnetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(receiverAccountId); } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. @@ -296,6 +291,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } + /* if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { if (!item->IsBattlenetAccountBound() || !player->GetSession()->GetBattlenetAccountId() || player->GetSession()->GetBattlenetAccountId() != receiverBnetAccountId) @@ -304,6 +300,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } } + */ if (item->GetTemplate()->GetFlags() & ITEM_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION)) { diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 802ac92be7..0159d03079 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -36,8 +36,7 @@ void WorldSession::SendTradeStatus(WorldPackets::Trade::TradeStatus& info) { info.Clear(); // reuse packet - Player* trader = _player->GetTrader(); - info.PartnerIsSameBnetAccount = trader && trader->GetSession()->GetBattlenetAccountId() == GetBattlenetAccountId(); + info.PartnerIsSameBnetAccount = false; //trader && trader->GetSession()->GetBattlenetAccountId() == GetBattlenetAccountId(); SendPacket(info.Write()); } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 56b88eb9aa..35010292f5 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -116,9 +116,15 @@ enum TrinityStrings LANG_GOINFO_SIZE = 84, LANG_GOINFO_ADDON = 85, LANG_GOINFO_MODEL = 86, - // Free 87 - 95 - - + LANG_UNKNOWN_ERROR = 87, + LANG_2FA_COMMANDS_NOT_SETUP = 88, + LANG_2FA_ALREADY_SETUP = 89, + LANG_2FA_INVALID_TOKEN = 90, + LANG_2FA_SECRET_SUGGESTION = 91, + LANG_2FA_SETUP_COMPLETE = 92, + LANG_2FA_NOT_SETUP = 93, + LANG_2FA_REMOVE_NEED_TOKEN = 94, + LANG_2FA_REMOVE_COMPLETE = 95, LANG_GUILD_RENAME_ALREADY_EXISTS = 96, LANG_GUILD_RENAME_DONE = 97, LANG_RENAME_PLAYER_ALREADY_EXISTS = 98, @@ -221,7 +227,10 @@ enum TrinityStrings // 185 not used LANG_TRANSPORT_POSITION = 186, LANG_PARTIAL_GROUP_SUMMON = 187, - // Room for more level 1 188-199 not used + LANG_2FA_SECRET_TOO_LONG = 188, + LANG_2FA_SECRET_INVALID = 189, + LANG_2FA_SECRET_SET_COMPLETE = 190, + // Room for more level 1 190-199 not used // level 2 chat LANG_NO_SELECTION = 200, diff --git a/src/server/game/Server/BattlenetServerManager.cpp b/src/server/game/Server/BattlenetServerManager.cpp deleted file mode 100644 index cb86b4648a..0000000000 --- a/src/server/game/Server/BattlenetServerManager.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Config.h" -#include "World.h" -#include "ZmqContext.h" -#include "BattlenetServerManager.h" - -void IPC::BattlenetComm::ServerManager::InitializeConnection() -{ - std::string bnetserverAddress = sConfigMgr->GetStringDefault("BnetServer.Address", "127.0.0.1"); - int32 bnetserverPort = sConfigMgr->GetIntDefault("BnetServer.Port", 1118); - _socket = new ZmqMux("inproc://bnetmgr", "tcp://" + bnetserverAddress + ":" + std::to_string(bnetserverPort)); - _socket->Start(); -} - -void IPC::BattlenetComm::ServerManager::CloseConnection() -{ - _socket->End(); - delete _socket; - _socket = nullptr; -} - -IPC::BattlenetComm::ServerManager& IPC::BattlenetComm::ServerManager::Instance() -{ - static ServerManager instance; - return instance; -} - -IPC::BattlenetComm::Header IPC::BattlenetComm::ServerManager::CreateHeader(BnetCommands command) -{ - Header header; - header.Ipc.Channel = IPC_CHANNEL_BNET; - header.Ipc.Command = command; - header.Realm = realm.Id; - return header; -} - -void IPC::BattlenetComm::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online) -{ - // Do nothing for Grunt login - if (!battlenetAccountId) - return; - - Header header = CreateHeader(BNET_CHANGE_TOON_ONLINE_STATE); - ToonHandle toon; - toon.AccountId = battlenetAccountId; - toon.GameAccountId = gameAccountId; - toon.Guid = guid.GetCounter(); - toon.Name = name; - - zmqpp::message msg; - msg << header; - msg << toon; - msg << online; - - Send(&msg); -} - -void IPC::BattlenetComm::ServerManager::Send(zmqpp::message* msg) -{ - if (!_socket) - return; - - _socket->Send(msg); -} diff --git a/src/server/game/Server/BattlenetServerManager.h b/src/server/game/Server/BattlenetServerManager.h deleted file mode 100644 index c7e5ba7829..0000000000 --- a/src/server/game/Server/BattlenetServerManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BattlenetMgr_h__ -#define BattlenetMgr_h__ - -#include "ZmqMux.h" -#include "Commands.h" - -namespace zmqpp -{ - class socket; - class message; -} - -namespace IPC -{ - namespace BattlenetComm - { - class TC_GAME_API ServerManager - { - ServerManager() : _socket(nullptr) { } - - public: - void InitializeConnection(); - void CloseConnection(); - - static ServerManager& Instance(); - - void SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online); - - private: - void Send(zmqpp::message* msg); - - static Header CreateHeader(BnetCommands command); - ZmqMux* _socket; - }; - } -} - -#define sBattlenetServer IPC::BattlenetComm::ServerManager::Instance() - -#endif // BattlenetMgr_h__ diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index 1d59f747f5..0687b0b40c 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -16,7 +16,8 @@ */ #include "AuthenticationPackets.h" -#include "HmacHash.h" + +#include "HMAC.h" bool WorldPackets::Auth::EarlyProcessClientPacket::ReadNoThrow() { @@ -47,7 +48,7 @@ WorldPacket const* WorldPackets::Auth::Pong::Write() WorldPacket const* WorldPackets::Auth::AuthChallenge::Write() { _worldPacket.append(DosChallenge.data(), DosChallenge.size()); - _worldPacket << uint32(Challenge); + _worldPacket.append(Challenge.data(), Challenge.size()); _worldPacket << uint8(DosZeroBits); return &_worldPacket; } @@ -87,7 +88,7 @@ void WorldPackets::Auth::AuthSession::Read() _worldPacket >> Digest[1]; _worldPacket >> Digest[11]; - _worldPacket >> LocalChallenge; + _worldPacket.read(LocalChallenge); _worldPacket >> Digest[2]; @@ -335,16 +336,16 @@ WorldPacket const* WorldPackets::Auth::ConnectTo::Write() addressType = 2; } - HmacSha1 hmacHash(64, WherePacketHmac); - hmacHash.UpdateData(address, 16); + Trinity::Crypto::HMAC_SHA1 hmacHash(WherePacketHmac, 64); + hmacHash.UpdateData(address); hmacHash.UpdateData(reinterpret_cast(&addressType), 4); hmacHash.UpdateData(reinterpret_cast(&port), 2); hmacHash.UpdateData(reinterpret_cast(Haiku.c_str()), 73); - hmacHash.UpdateData(PiDigits, 142); + hmacHash.UpdateData(PiDigits); hmacHash.UpdateData(&Payload.XorMagic, 1); hmacHash.Finalize(); - uint8* hmac = hmacHash.GetDigest(); + Trinity::Crypto::HMAC_SHA1::Digest const& hmac = hmacHash.GetDigest(); payload << uint8(PiDigits[30]); payload << uint8(Haiku[31]); @@ -616,7 +617,7 @@ WorldPacket const* WorldPackets::Auth::ConnectTo::Write() _worldPacket << uint64(Key); _worldPacket << uint32(Serial); - _worldPacket.append(m.AsByteArray(256).get(), 256); + _worldPacket.append(m.ToByteArray<256>().data(), 256); _worldPacket << uint8(Con); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h index 82726bf67a..271a294196 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.h +++ b/src/server/game/Server/Packets/AuthenticationPackets.h @@ -19,10 +19,11 @@ #define AuthenticationPacketsWorld_h__ #include "Packet.h" +#include "BigNumber.h" +#include "CryptoConstants.h" +#include "CryptoHash.h" #include "ObjectMgr.h" #include "Util.h" -#include "BigNumber.h" -#include "SHA1.h" #include #include @@ -70,7 +71,7 @@ namespace WorldPackets WorldPacket const* Write() override; std::array DosChallenge = { }; - uint32 Challenge = 0; + std::array Challenge = { }; uint8 DosZeroBits = 0; }; @@ -79,7 +80,6 @@ namespace WorldPackets public: AuthSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_SESSION, std::move(packet)) { - Digest.fill(0); } uint32 BattlegroupID = 0; @@ -87,11 +87,11 @@ namespace WorldPackets int8 BuildType = 0; uint32 RealmID = 0; uint16 Build = 0; - uint32 LocalChallenge = 0; + std::array LocalChallenge = { }; int32 LoginServerID = 0; uint32 RegionID = 0; uint64 DosResponse = 0; - std::array Digest; + Trinity::Crypto::SHA1::Digest Digest = { }; std::string Account; bool UseIPv6 = false; ByteBuffer AddonInfo; @@ -149,14 +149,11 @@ namespace WorldPackets class AuthContinuedSession final : public EarlyProcessClientPacket { public: - AuthContinuedSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_CONTINUED_SESSION, std::move(packet)) - { - Digest.fill(0); - } + AuthContinuedSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_CONTINUED_SESSION, std::move(packet)) { } uint64 DosResponse = 0; uint64 Key = 0; - std::array Digest; + Trinity::Crypto::SHA1::Digest Digest = { }; private: void Read() override; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index ea6d66535a..de8e726877 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -24,7 +24,6 @@ #include "AddonMgr.h" #include "AuthenticationPackets.h" #include "BattlegroundMgr.h" -#include "BattlenetServerManager.h" #include "Common.h" #include "Config.h" #include "DatabaseEnv.h" @@ -46,6 +45,7 @@ #include "Player.h" #include "QueryCallback.h" #include "QueryHolder.h" +#include "Realm.h" #include "ScriptMgr.h" #include "SocialMgr.h" #include "Transport.h" @@ -117,7 +117,6 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun _security(sec), _accountId(id), _accountName(std::move(name)), - _battlenetAccountId(battlenetAccountId), m_accountExpansion(expansion), m_expansion(std::min(expansion, sWorld->getIntConfig(CONFIG_EXPANSION))), _warden(nullptr), @@ -664,8 +663,6 @@ void WorldSession::LogoutPlayer(bool save) TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUID().GetCounter(), _player->getLevel()); - sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), false); - if (Map* _map = _player->FindMap()) _map->RemovePlayerFromMap(_player, true); @@ -1165,7 +1162,7 @@ SQLQueryHolderCallback& WorldSession::AddQueryHolderCallback(SQLQueryHolderCallb return _queryHolderProcessor.AddCallback(std::move(callback)); } -void WorldSession::InitWarden(BigNumber* k, std::string const& os) +void WorldSession::InitWarden(SessionKey const& k, std::string const& os) { if (os == "Win") { @@ -1214,7 +1211,7 @@ public: AccountInfoQueryHolderPerRealm() { SetSize(MAX_QUERIES); } - bool Initialize(uint32 accountId, uint32 /*battlenetAccountId*/) + bool Initialize(uint32 accountId) { bool ok = true; @@ -1233,7 +1230,7 @@ public: void WorldSession::InitializeSession() { std::shared_ptr realmHolder = std::make_shared(); - if (!realmHolder->Initialize(GetAccountId(), GetBattlenetAccountId())) + if (!realmHolder->Initialize(GetAccountId())) { SendAuthResponse(AUTH_SYSTEM_ERROR, false); return; diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index fe2a05008d..cccae39f24 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -22,16 +22,18 @@ #ifndef __WORLDSESSION_H #define __WORLDSESSION_H -#include "Common.h" +#include +#include +#include + #include "AsyncCallbackProcessor.h" +#include "AuthDefines.h" +#include "Common.h" #include "DatabaseEnvFwd.h" #include "LockedQueue.h" #include "ObjectGuid.h" #include "Packet.h" #include "SharedDefines.h" -#include -#include -#include class BigNumber; class Creature; @@ -511,7 +513,6 @@ class TC_GAME_API WorldSession AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } - uint32 GetBattlenetAccountId() const { return _battlenetAccountId; } Player* GetPlayer() const { return _player; } std::string const& GetPlayerName() const; std::string GetPlayerInfo() const; @@ -523,7 +524,7 @@ class TC_GAME_API WorldSession uint8 GetAccountExpansion() const { return m_accountExpansion; } uint8 GetExpansion() const { return m_expansion; } - void InitWarden(BigNumber* k, std::string const& os); + void InitWarden(SessionKey const& k, std::string const& os); /// Session in auth.queue currently void SetInQueue(bool state) { m_inQueue = state; } @@ -1359,7 +1360,6 @@ class TC_GAME_API WorldSession AccountTypes _security; uint32 _accountId; std::string _accountName; - uint32 _battlenetAccountId; uint8 m_accountExpansion; uint8 m_expansion; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 8f61c00505..77e64bf04b 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -16,10 +16,13 @@ */ #include "WorldSocket.h" +#include "AuthDefines.h" #include "AuthenticationPackets.h" -#include "BattlenetAccountMgr.h" #include "BigNumber.h" #include "CharacterPackets.h" +#include "ClientBuildInfo.h" +#include "CryptoGenerics.h" +#include "CryptoHash.h" #include "DatabaseEnv.h" #include "GameTime.h" #include "IPLocation.h" @@ -30,7 +33,6 @@ #include "RBAC.h" #include "Realm.h" #include "ScriptMgr.h" -#include "SHA1.h" #include "Util.h" #include "World.h" #include @@ -42,9 +44,10 @@ std::string const WorldSocket::ServerConnectionInitialize("WORLD OF WARCRAFT CON std::string const WorldSocket::ClientConnectionInitialize("WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER"); WorldSocket::WorldSocket(tcp::socket&& socket) : Socket(std::move(socket)), - _type(CONNECTION_TYPE_REALM), _authSeed(rand32()), _OverSpeedPings(0), _worldSession(nullptr), + _type(CONNECTION_TYPE_REALM), _OverSpeedPings(0), _worldSession(nullptr), _authed(false), _compressionStream(nullptr), _sendBufferSize(4096) { + Trinity::Crypto::GetRandomBytes(_authSeed); _headerBuffer.Resize(2); } @@ -243,8 +246,8 @@ void WorldSocket::HandleSendAuthSession() WorldPackets::Auth::AuthChallenge challenge; challenge.Challenge = _authSeed; - memcpy(&challenge.DosChallenge[0], _encryptSeed.AsByteArray(16).get(), 16); - memcpy(&challenge.DosChallenge[4], _decryptSeed.AsByteArray(16).get(), 16); + memcpy(&challenge.DosChallenge[0], _encryptSeed.ToByteArray<16>().data(), 16); + memcpy(&challenge.DosChallenge[4], _decryptSeed.ToByteArray<16>().data(), 16); challenge.DosZeroBits = 1; SendPacketAndLogOpcode(*challenge.Write()); @@ -354,62 +357,54 @@ bool WorldSocket::ReadHeaderHandler(bool initialized) struct AccountInfo { - struct - { - uint32 Id; - bool IsLockedToIP; - std::string LastIP; - std::string LockCountry; - LocaleConstant Locale; - std::string OS; - bool IsBanned; - } BattleNet; - struct - { - uint32 Id; - BigNumber SessionKey; - uint8 Expansion; - int64 MuteTime; - uint32 Recruiter; - bool IsRecruiter; - AccountTypes Security; - bool IsBanned; - } Game; - - bool IsBanned() const { return BattleNet.IsBanned || Game.IsBanned; } + uint32 Id; + ::SessionKey SessionKey; + std::string LastIP; + bool IsLockedToIP; + std::string LockCountry; + uint8 Expansion; + int64 MuteTime; + LocaleConstant Locale; + uint32 Recruiter; + std::string OS; + Minutes TimezoneOffset; + bool IsRecruiter; + AccountTypes Security; + bool IsBanned; explicit AccountInfo(Field* fields) { - // 0 1 2 3 4 5 6 7 8 9 10 11 - // SELECT a.id, a.sessionkey, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, ba.os, ba.id, aa.gmLevel, - // 12 13 14 - // bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id - // FROM account a LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?) - // LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account r ON a.id = r.recruiter + // 0 1 2 3 4 5 6 7 8 9 10 11 + // SELECT a.id, a.sessionkey, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.timezone_offset, aa.SecurityLevel, + // 12 13 + // ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id + // FROM account a + // LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?) + // LEFT JOIN account_banned ab ON a.id = ab.id + // LEFT JOIN account r ON a.id = r.recruiter // WHERE a.username = ? ORDER BY aa.RealmID DESC LIMIT 1 - Game.Id = fields[0].GetUInt32(); - Game.SessionKey.SetHexStr(fields[1].GetCString()); - BattleNet.LastIP = fields[2].GetString(); - BattleNet.IsLockedToIP = fields[3].GetBool(); - BattleNet.LockCountry = fields[4].GetString(); - Game.Expansion = fields[5].GetUInt8(); - Game.MuteTime = fields[6].GetInt64(); - BattleNet.Locale = LocaleConstant(fields[7].GetUInt8()); - Game.Recruiter = fields[8].GetUInt32(); - BattleNet.OS = fields[9].GetString(); - BattleNet.Id = fields[10].GetUInt32(); - Game.Security = AccountTypes(fields[11].GetUInt8()); - BattleNet.IsBanned = fields[12].GetUInt64() != 0; - Game.IsBanned = fields[13].GetUInt64() != 0; - Game.IsRecruiter = fields[14].GetUInt32() != 0; + Id = fields[0].GetUInt32(); + SessionKey = fields[1].GetBinary(); + LastIP = fields[2].GetString(); + IsLockedToIP = fields[3].GetBool(); + LockCountry = fields[4].GetString(); + Expansion = fields[5].GetUInt8(); + MuteTime = fields[6].GetInt64(); + Locale = LocaleConstant(fields[7].GetUInt8()); + Recruiter = fields[8].GetUInt32(); + OS = fields[9].GetString(); + TimezoneOffset = Minutes(fields[10].GetInt16()); + Security = AccountTypes(fields[11].GetUInt8()); + IsBanned = fields[12].GetUInt64() != 0; + IsRecruiter = fields[13].GetUInt32() != 0; uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION); - if (Game.Expansion > world_expansion) - Game.Expansion = world_expansion; + if (Expansion > world_expansion) + Expansion = world_expansion; - if (BattleNet.Locale >= TOTAL_LOCALES) - BattleNet.Locale = LOCALE_enUS; + if (Locale >= TOTAL_LOCALES) + Locale = LOCALE_enUS; } }; @@ -611,7 +606,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrIsClosed()) @@ -633,29 +628,29 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrgetBoolConfig(CONFIG_WARDEN_ENABLED); - if (wardenActive && account.BattleNet.OS != "Win" && account.BattleNet.OS != "OSX") + if (wardenActive && !ClientBuild::Platform::IsValid(account.OS)) { SendAuthResponseError(AUTH_REJECT); - TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), account.BattleNet.OS.c_str()); + TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), account.OS.c_str()); DelayedCloseSocket(); return; } // Check that Key and account name are the same on client and server - uint32 t = 0; + uint8 t[4] = { 0x00,0x00,0x00,0x00 }; - SHA1Hash sha; + Trinity::Crypto::SHA1 sha; sha.UpdateData(authSession->Account); - sha.UpdateData((uint8*)&t, 4); - sha.UpdateData((uint8*)&authSession->LocalChallenge, 4); - sha.UpdateData((uint8*)&_authSeed, 4); - sha.UpdateBigNumbers(&account.Game.SessionKey, nullptr); + sha.UpdateData(t); + sha.UpdateData(authSession->LocalChallenge); + sha.UpdateData(_authSeed); + sha.UpdateData(account.SessionKey); sha.Finalize(); - if (memcmp(sha.GetDigest(), authSession->Digest.data(), SHA_DIGEST_LENGTH) != 0) + if (sha.GetDigest() != authSession->Digest) { SendAuthResponseError(AUTH_FAILED); - TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", account.Game.Id, authSession->Account.c_str(), address.c_str()); + TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", account.Id, authSession->Account.c_str(), address.c_str()); DelayedCloseSocket(); return; } @@ -664,32 +659,32 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrCountryCode; ///- Re-check ip locking (same check as in auth). - if (account.BattleNet.IsLockedToIP) // if ip is locked + if (account.IsLockedToIP) { - if (account.BattleNet.LastIP != address) + if (account.LastIP != address) { SendAuthResponseError(AUTH_FAILED); - TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: %s, new IP: %s).", account.BattleNet.LastIP.c_str(), address.c_str()); + TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: %s, new IP: %s).", account.LastIP.c_str(), address.c_str()); // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well - sScriptMgr->OnFailedAccountLogin(account.Game.Id); + sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } } - else if (!account.BattleNet.LockCountry.empty() && account.BattleNet.LockCountry != "00" && !_ipCountry.empty()) + else if (!account.LockCountry.empty() && account.LockCountry != "00" && !_ipCountry.empty()) { - if (account.BattleNet.LockCountry != _ipCountry) + if (account.LockCountry != _ipCountry) { SendAuthResponseError(AUTH_FAILED); - TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account country differs. Original country: %s, new country: %s).", account.BattleNet.LockCountry.c_str(), _ipCountry.c_str()); + TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account country differs. Original country: %s, new country: %s).", account.LockCountry.c_str(), _ipCountry.c_str()); // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well - sScriptMgr->OnFailedAccountLogin(account.Game.Id); + sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } } - int64 mutetime = account.Game.MuteTime; + int64 mutetime = account.MuteTime; //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { @@ -697,27 +692,27 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrsetInt64(0, mutetime); - stmt->setUInt32(1, account.Game.Id); + stmt->setUInt32(1, account.Id); LoginDatabase.Execute(stmt); } - if (account.IsBanned()) + if (account.IsBanned) { SendAuthResponseError(AUTH_BANNED); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); - sScriptMgr->OnFailedAccountLogin(account.Game.Id); + sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } // Check locked state for server AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); - TC_LOG_DEBUG("network", "Allowed Level: %u Player Level %u", allowedAccountType, account.Game.Security); - if (allowedAccountType > SEC_PLAYER && account.Game.Security < allowedAccountType) + TC_LOG_DEBUG("network", "Allowed Level: %u Player Level %u", allowedAccountType, account.Security); + if (allowedAccountType > SEC_PLAYER && account.Security < allowedAccountType) { SendAuthResponseError(AUTH_UNAVAILABLE); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); - sScriptMgr->OnFailedAccountLogin(account.Game.Id); + sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } @@ -731,16 +726,16 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrOnAccountLogin(account.Game.Id); + sScriptMgr->OnAccountLogin(account.Id); _authed = true; - _worldSession = new WorldSession(account.Game.Id, std::move(authSession->Account), account.BattleNet.Id, shared_from_this(), account.Game.Security, - account.Game.Expansion, mutetime, account.BattleNet.Locale, account.Game.Recruiter, account.Game.IsRecruiter); + _worldSession = new WorldSession(account.Id, std::move(authSession->Account), account.Id, shared_from_this(), account.Security, + account.Expansion, mutetime, account.Locale, account.Recruiter, account.IsRecruiter); _worldSession->ReadAddonsInfo(authSession->AddonInfo); // Initialize Warden system only if it is enabled by config if (wardenActive) - _worldSession->InitWarden(&account.Game.SessionKey, account.BattleNet.OS); + _worldSession->InitWarden(account.SessionKey, account.OS); _queryProcessor.AddCallback(_worldSession->LoadPermissionsAsync().WithPreparedCallback(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1))); AsyncRead(); @@ -793,18 +788,17 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptrFetch(); std::string login = fields[0].GetString(); Utf8ToUpperOnlyLatin(login); - BigNumber k; - k.SetHexStr(fields[1].GetCString()); + ::SessionKey k = fields[1].GetBinary(); - _authCrypt.Init(&k, _encryptSeed.AsByteArray().get(), _decryptSeed.AsByteArray().get()); + _authCrypt.Init(k, _encryptSeed.ToByteArray<16>(), _decryptSeed.ToByteArray<16>()); - SHA1Hash sha; + Trinity::Crypto::SHA1 sha; sha.UpdateData(login); - sha.UpdateBigNumbers(&k, nullptr); - sha.UpdateData((uint8*)&_authSeed, 4); + sha.UpdateData(k); + sha.UpdateData(_authSeed); sha.Finalize(); - if (memcmp(sha.GetDigest(), authSession->Digest.data(), sha.GetLength())) + if (sha.GetDigest() != authSession->Digest) { SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthContinuedSession: Authentication failed for account: %u ('%s') address: %s", accountId, login.c_str(), GetRemoteIpAddress().to_string().c_str()); diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index e04e15445e..d8247958ec 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -136,7 +136,7 @@ private: ConnectionType _type; - uint32 _authSeed; + std::array _authSeed; WorldPacketCrypt _authCrypt; BigNumber _encryptSeed; BigNumber _decryptSeed; diff --git a/src/server/game/Warden/Modules/WardenModuleWin.h b/src/server/game/Warden/Modules/WardenModuleWin.h index d282e0090b..452b1dd201 100644 --- a/src/server/game/Warden/Modules/WardenModuleWin.h +++ b/src/server/game/Warden/Modules/WardenModuleWin.h @@ -28,12 +28,12 @@ New Cerver Key: C2 B7 AD ED FC CC A9 C2 BF B3 F8 56 02 BA 80 9B struct Module_79C0768D657977D697E10BAD956CCED1 { - uint8 Module[18756]; - uint8 ModuleKey[16]; - uint8 Seed[16]; - uint8 ServerKeySeed[16]; - uint8 ClientKeySeed[16]; - uint8 ClientKeySeedHash[20]; + std::array Module; + std::array ModuleKey; + std::array Seed; + std::array ServerKeySeed; + std::array ClientKeySeed; + std::array ClientKeySeedHash; } Module = { { diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index ab40a606e2..4cb10f066c 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -28,12 +28,12 @@ #include "WorldSession.h" #include -Warden::Warden() : _session(nullptr), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), +Warden::Warden() : _session(nullptr), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), _dataSent(false), _previousTimestamp(0), _module(nullptr), _initialized(false) { - memset(_inputKey, 0, sizeof(_inputKey)); - memset(_outputKey, 0, sizeof(_outputKey)); - memset(_seed, 0, sizeof(_seed)); + _inputKey = { }; + _outputKey = { }; + _seed = { }; } Warden::~Warden() @@ -129,12 +129,12 @@ void Warden::Update() void Warden::DecryptData(uint8* buffer, uint32 length) { - _inputCrypto.UpdateData(length, buffer); + _inputCrypto.UpdateData(buffer, length); } void Warden::EncryptData(uint8* buffer, uint32 length) { - _outputCrypto.UpdateData(length, buffer); + _outputCrypto.UpdateData(buffer, length); } bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length) diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index 24d6cf9bc3..b24f7952f5 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -18,11 +18,11 @@ #ifndef _WARDEN_BASE_H #define _WARDEN_BASE_H -#include -#include "Cryptography/ARC4.h" -#include "Cryptography/BigNumber.h" +#include "ARC4.h" +#include "AuthDefines.h" #include "ByteBuffer.h" #include "WardenCheckMgr.h" +#include enum WardenOpcodes { @@ -100,7 +100,7 @@ class TC_GAME_API Warden Warden(); virtual ~Warden(); - virtual void Init(WorldSession* session, BigNumber* k) = 0; + virtual void Init(WorldSession* session, SessionKey const& K) = 0; virtual ClientWardenModule* GetModuleForClient() = 0; virtual void InitializeModule() = 0; virtual void RequestHash() = 0; @@ -122,11 +122,11 @@ class TC_GAME_API Warden private: WorldSession* _session; - uint8 _inputKey[16]; - uint8 _outputKey[16]; - uint8 _seed[16]; - ARC4 _inputCrypto; - ARC4 _outputCrypto; + std::array _inputKey; + std::array _outputKey; + std::array _seed; + Trinity::Crypto::ARC4 _inputCrypto; + Trinity::Crypto::ARC4 _outputCrypto; uint32 _checkTimer; // Timer for sending check requests uint32 _clientResponseTimer; // Timer for client response delay bool _dataSent; diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index 0d90f11400..e913ca1a02 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -92,7 +92,7 @@ void WardenCheckMgr::LoadWardenChecks() { uint8 temp[24]; memset(temp, 0, len); - memcpy(temp, wardenCheck->Data.AsByteArray().get(), wardenCheck->Data.GetNumBytes()); + memcpy(temp, wardenCheck->Data.ToByteVector().data(), wardenCheck->Data.GetNumBytes()); std::reverse(temp, temp + len); wardenCheck->Data.SetBinary((uint8*)temp, len); } @@ -124,7 +124,7 @@ void WardenCheckMgr::LoadWardenChecks() { uint8 *temp = new uint8[len]; memset(temp, 0, len); - memcpy(temp, wr->Result.AsByteArray().get(), wr->Result.GetNumBytes()); + memcpy(temp, wr->Result.ToByteVector().data(), wr->Result.GetNumBytes()); std::reverse(temp, temp + len); wr->Result.SetBinary((uint8*)temp, len); delete [] temp; diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index 5f2d05a227..650bbeafa5 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#include "Cryptography/WardenKeyGeneration.h" #include "Common.h" +#include "CryptoHash.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Log.h" @@ -24,6 +24,7 @@ #include "ByteBuffer.h" #include "GameTime.h" #include "Player.h" +#include "SessionKeyGenerator.h" #include "Util.h" #include "WardenMac.h" #include "WardenModuleMac.h" @@ -34,13 +35,13 @@ WardenMac::WardenMac() : Warden() { } WardenMac::~WardenMac() { } -void WardenMac::Init(WorldSession* pClient, BigNumber* K) +void WardenMac::Init(WorldSession* pClient, SessionKey const& K) { _session = pClient; // Generate Warden Key - SHA1Randx WK(K->AsByteArray().get(), K->GetNumBytes()); - WK.Generate(_inputKey, 16); - WK.Generate(_outputKey, 16); + SessionKeyGenerator WK(K); + WK.Generate(_inputKey.data(), 16); + WK.Generate(_outputKey.data(), 16); /* Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet) Hash: (0x04 packet) @@ -50,7 +51,7 @@ void WardenMac::Init(WorldSession* pClient, BigNumber* K) */ uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE }; - memcpy(_seed, mod_seed, 16); + memcpy(_seed.data(), mod_seed, 16); _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); @@ -101,7 +102,7 @@ void WardenMac::RequestHash() // Create packet structure WardenHashRequest Request; Request.Command = WARDEN_SMSG_HASH_REQUEST; - memcpy(Request.Seed, _seed, 16); + memcpy(Request.Seed, _seed.data(), 16); // Encrypt with warden RC4 key. EncryptData((uint8*)&Request, sizeof(WardenHashRequest)); @@ -130,7 +131,7 @@ void WardenMac::HandleHashResult(ByteBuffer &buff) { // test - int keyIn[4]; + std::array keyIn = {}; keyDataMac mod_seed = { { { { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE } } } }; @@ -155,18 +156,14 @@ void WardenMac::HandleHashResult(ByteBuffer &buff) buff.rpos(buff.wpos()); - SHA1Hash sha1; - sha1.UpdateData((uint8*)keyIn, 16); - sha1.Finalize(); - //const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E }; // Verify key - if (memcmp(buff.contents() + 1, sha1.GetDigest(), 20) != 0) - { - TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); - return; - } + //if (memcmp(buff.contents() + 1, Trinity::Crypto::SHA1::GetDigestOf(keyIn).data(), 20) != 0) + //{ + // TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); + // return; + //} TC_LOG_DEBUG("warden", "Request hash reply: succeed"); @@ -177,8 +174,8 @@ void WardenMac::HandleHashResult(ByteBuffer &buff) //const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B }; // change keys here - memcpy(_inputKey, keyIn, 16); - memcpy(_outputKey, keyOut, 16); + memcpy(_inputKey.data(), keyIn.data(), 16); + memcpy(_outputKey.data(), keyOut, 16); _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); @@ -236,16 +233,16 @@ void WardenMac::HandleData(ByteBuffer &buff) std::string str = "Test string!"; - SHA1Hash sha1; + Trinity::Crypto::SHA1 sha1; sha1.UpdateData(str); uint32 magic = 0xFEEDFACE; // unsure - sha1.UpdateData((uint8*)&magic, 4); + sha1.UpdateData(reinterpret_cast(magic), 4); sha1.Finalize(); uint8 sha1Hash[20]; buff.read(sha1Hash, 20); - if (memcmp(sha1Hash, sha1.GetDigest(), 20) != 0) + if (memcmp(sha1Hash, sha1.GetDigest().data(), 20) != 0) { TC_LOG_DEBUG("warden", "Handle data failed: SHA1 hash is wrong!"); //found = true; diff --git a/src/server/game/Warden/WardenMac.h b/src/server/game/Warden/WardenMac.h index 24e9201177..ae11648b42 100644 --- a/src/server/game/Warden/WardenMac.h +++ b/src/server/game/Warden/WardenMac.h @@ -31,7 +31,7 @@ class TC_GAME_API WardenMac : public Warden WardenMac(); ~WardenMac(); - void Init(WorldSession* session, BigNumber* k) override; + void Init(WorldSession* session, SessionKey const& K) override; ClientWardenModule* GetModuleForClient() override; void InitializeModule() override; void RequestHash() override; diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 5ea93d5a78..5e4c26397a 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -15,8 +15,6 @@ * with this program. If not, see . */ -#include "Cryptography/HmacHash.h" -#include "Cryptography/WardenKeyGeneration.h" #include "Common.h" #include "WorldPacket.h" #include "WorldSession.h" @@ -31,33 +29,34 @@ #include "WardenModuleWin.h" #include "WardenCheckMgr.h" #include "Random.h" +#include "SessionKeyGenerator.h" WardenWin::WardenWin() : Warden(), _serverTicks(0) {} WardenWin::~WardenWin() { } -void WardenWin::Init(WorldSession* session, BigNumber* k) +void WardenWin::Init(WorldSession* session, SessionKey const& K) { _session = session; // Generate Warden Key - SHA1Randx WK(k->AsByteArray().get(), k->GetNumBytes()); - WK.Generate(_inputKey, 16); - WK.Generate(_outputKey, 16); + SessionKeyGenerator WK(K); + WK.Generate(_inputKey.data(), _inputKey.size()); + WK.Generate(_outputKey.data(), _outputKey.size()); - memcpy(_seed, Module.Seed, 16); + _seed = Module.Seed; _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); TC_LOG_DEBUG("warden", "Server side warden for client %u initializing...", session->GetAccountId()); - TC_LOG_DEBUG("warden", "C->S Key: %s", ByteArrayToHexStr(_inputKey, 16).c_str()); - TC_LOG_DEBUG("warden", "S->C Key: %s", ByteArrayToHexStr(_outputKey, 16).c_str()); - TC_LOG_DEBUG("warden", " Seed: %s", ByteArrayToHexStr(_seed, 16).c_str()); + TC_LOG_DEBUG("warden", "C->S Key: %s", ByteArrayToHexStr(_inputKey).c_str()); + TC_LOG_DEBUG("warden", "S->C Key: %s", ByteArrayToHexStr(_outputKey).c_str()); + TC_LOG_DEBUG("warden", " Seed: %s", ByteArrayToHexStr(_seed).c_str()); TC_LOG_DEBUG("warden", "Loading Module..."); _module = GetModuleForClient(); - TC_LOG_DEBUG("warden", "Module Key: %s", ByteArrayToHexStr(_module->Key, 16).c_str()); - TC_LOG_DEBUG("warden", "Module ID: %s", ByteArrayToHexStr(_module->Id, 16).c_str()); + TC_LOG_DEBUG("warden", "Module Key: %s", ByteArrayToHexStr(_module->Key).c_str()); + TC_LOG_DEBUG("warden", "Module ID: %s", ByteArrayToHexStr(_module->Id).c_str()); RequestModule(); } @@ -70,8 +69,8 @@ ClientWardenModule* WardenWin::GetModuleForClient() // data assign mod->CompressedSize = length; mod->CompressedData = new uint8[length]; - memcpy(mod->CompressedData, Module.Module, length); - memcpy(mod->Key, Module.ModuleKey, 16); + memcpy(mod->CompressedData, Module.Module.data(), length); + memcpy(mod->Key, Module.ModuleKey.data(), 16); // md5 hash EVP_MD_CTX *md5 = EVP_MD_CTX_new(); @@ -134,7 +133,7 @@ void WardenWin::RequestHash() // Create packet structure WardenHashRequest Request; Request.Command = WARDEN_SMSG_HASH_REQUEST; - memcpy(Request.Seed, _seed, 16); + memcpy(Request.Seed, _seed.data(), 16); // Encrypt with warden RC4 key. EncryptData((uint8*)&Request, sizeof(WardenHashRequest)); @@ -149,7 +148,7 @@ void WardenWin::HandleHashResult(ByteBuffer &buff) buff.rpos(buff.wpos()); // Verify key - if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, 20) != 0) + if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash.data(), 20) != 0) { TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; @@ -158,8 +157,8 @@ void WardenWin::HandleHashResult(ByteBuffer &buff) TC_LOG_DEBUG("warden", "Request hash reply: succeed"); // Change keys here - memcpy(_inputKey, Module.ClientKeySeed, 16); - memcpy(_outputKey, Module.ServerKeySeed, 16); + _inputKey = Module.ClientKeySeed; + _outputKey = Module.ServerKeySeed; _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); @@ -261,7 +260,7 @@ void WardenWin::RequestData() case PAGE_CHECK_A: case PAGE_CHECK_B: { - buff.append(wd->Data.AsByteArray(0, false).get(), wd->Data.GetNumBytes()); + buff.append(wd->Data.ToByteArray<0>(false).data(), wd->Data.GetNumBytes()); buff << uint32(wd->Address); buff << uint8(wd->Length); break; @@ -274,10 +273,11 @@ void WardenWin::RequestData() } case DRIVER_CHECK: { - buff.append(wd->Data.AsByteArray(0, false).get(), wd->Data.GetNumBytes()); + buff.append(wd->Data.ToByteArray<0>(false).data(), wd->Data.GetNumBytes()); buff << uint8(index++); break; } + /* case MODULE_CHECK: { uint32 seed = rand32(); @@ -288,6 +288,7 @@ void WardenWin::RequestData() buff.append(hmac.GetDigest(), hmac.GetLength()); break; } + */ /*case PROC_CHECK: { buff.append(wd->i.AsByteArray(0, false).get(), wd->i.GetNumBytes()); @@ -390,7 +391,7 @@ void WardenWin::HandleData(ByteBuffer &buff) continue; } - if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false).get(), rd->Length) != 0) + if (memcmp(buff.contents() + buff.rpos(), rs->Result.ToByteArray<0>(false).data(), rd->Length) != 0) { TC_LOG_DEBUG("warden", "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; @@ -469,7 +470,7 @@ void WardenWin::HandleData(ByteBuffer &buff) continue; } - if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false).get(), 20) != 0) // SHA1 + if (memcmp(buff.contents() + buff.rpos(), rs->Result.ToByteArray<0>(false).data(), 20) != 0) // SHA1 { TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; diff --git a/src/server/game/Warden/WardenWin.h b/src/server/game/Warden/WardenWin.h index 051892c7ca..5b133d0db0 100644 --- a/src/server/game/Warden/WardenWin.h +++ b/src/server/game/Warden/WardenWin.h @@ -65,7 +65,7 @@ class TC_GAME_API WardenWin : public Warden WardenWin(); ~WardenWin(); - void Init(WorldSession* session, BigNumber* K) override; + void Init(WorldSession* session, SessionKey const& K) override; ClientWardenModule* GetModuleForClient() override; void InitializeModule() override; void RequestHash() override; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index daf3a151c6..6cd8992f48 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -3262,12 +3262,7 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); - stmt->setUInt32(0, accountId); - stmt->setUInt32(1, realm.Id.Realm); - trans->Append(stmt); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_REALM_CHARACTERS); stmt->setUInt8(0, charCount); stmt->setUInt32(1, accountId); stmt->setUInt32(2, realm.Id.Realm); diff --git a/src/server/ipc/CMakeLists.txt b/src/server/ipc/CMakeLists.txt deleted file mode 100644 index fd5570daa6..0000000000 --- a/src/server/ipc/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -# This file is part of the TrinityCore Project. See AUTHORS file for Copyright information -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -CollectSourceFiles( - ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE_SOURCES) - -GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) - -add_definitions(-DTRINITY_API_EXPORT_IPC) - -add_library(ipc ${PRIVATE_SOURCES}) - -CollectIncludeDirectories( - ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC_INCLUDES) - -target_include_directories(ipc - PUBLIC - ${PUBLIC_INCLUDES} - PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}) - -target_link_libraries(ipc - PRIVATE - trinity-core-interface - PUBLIC - shared - zmqpp) - -set_target_properties(ipc - PROPERTIES - FOLDER - "server") - -if( BUILD_SHARED_LIBS ) - if( UNIX ) - install(TARGETS ipc - LIBRARY - DESTINATION lib) - elseif( WIN32 ) - install(TARGETS ipc - RUNTIME - DESTINATION "${CMAKE_INSTALL_PREFIX}") - endif() -endif() diff --git a/src/server/ipc/Commands.cpp b/src/server/ipc/Commands.cpp deleted file mode 100644 index 58695aa550..0000000000 --- a/src/server/ipc/Commands.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Commands.h" -#include - -zmqpp::message& operator>>(zmqpp::message& msg, IPC::Header& header) -{ - msg >> header.Channel; - msg >> header.Command; - return msg; -} - -zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm) -{ - msg >> realm.Region; - msg >> realm.Site; - msg >> realm.Realm; - return msg; -} - -zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::Header& header) -{ - msg >> header.Ipc; - msg >> header.Realm; - return msg; -} - -zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle& toonHandle) -{ - msg >> toonHandle.AccountId; - msg >> toonHandle.GameAccountId; - msg >> toonHandle.Guid; - msg >> toonHandle.Name; - return msg; -} - -zmqpp::message& operator<<(zmqpp::message& msg, IPC::Header const& header) -{ - msg << header.Channel; - msg << header.Command; - return msg; -} - -zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle const& realm) -{ - msg << realm.Region; - msg << realm.Site; - msg << realm.Realm; - return msg; -} - -zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::Header const& header) -{ - msg << header.Ipc; - msg << header.Realm; - return msg; -} - -zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle const& toonHandle) -{ - msg << toonHandle.AccountId; - msg << toonHandle.GameAccountId; - msg << toonHandle.Guid; - msg << toonHandle.Name; - return msg; -} diff --git a/src/server/ipc/Commands.h b/src/server/ipc/Commands.h deleted file mode 100644 index a0c00135e0..0000000000 --- a/src/server/ipc/Commands.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef _COMMANDS_H -#define _COMMANDS_H - -#include "Define.h" -#include "Realm/Realm.h" -#include - -enum Channels -{ - IPC_CHANNEL_BNET, - - MAX_IPC_CHANNELS, -}; - -enum BnetCommands -{ - BNET_CHANGE_TOON_ONLINE_STATE, - - IPC_BNET_MAX_COMMAND -}; - -namespace IPC -{ - struct Header - { - uint8 Channel; - uint8 Command; - }; - - namespace BattlenetComm - { - struct Header - { - IPC::Header Ipc; - Battlenet::RealmHandle Realm; - }; - - struct ToonHandle - { - uint32 AccountId; - uint32 GameAccountId; - uint64 Guid; - std::string Name; - }; - } -} - -namespace zmqpp -{ - class message; -} - -TC_IPC_API zmqpp::message& operator>>(zmqpp::message& msg, IPC::Header& header); -TC_IPC_API zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm); -TC_IPC_API zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::Header& header); -TC_IPC_API zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle& toonHandle); - -TC_IPC_API zmqpp::message& operator<<(zmqpp::message& msg, IPC::Header const& header); -TC_IPC_API zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle const& realm); -TC_IPC_API zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::Header const& header); -TC_IPC_API zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle const& toonHandle); - -#endif // _COMMANDS_H diff --git a/src/server/ipc/ZMQTask.cpp b/src/server/ipc/ZMQTask.cpp deleted file mode 100644 index cbeae5b792..0000000000 --- a/src/server/ipc/ZMQTask.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ZMQTask.h" -#include "ZmqContext.h" -#include - -ZMQTask::ZMQTask() -{ - _poller = new zmqpp::poller(); -} - -ZMQTask::~ZMQTask() -{ - delete _poller; - _poller = nullptr; - delete _inproc; - delete _thread; -} - -void ZMQTask::Start() -{ - _inproc = sIpcContext->CreateInprocSubscriber(); - _poller->add(*_inproc); - - HandleOpen(); - _thread = new std::thread(&ZMQTask::Run, this); -} - -void ZMQTask::End() -{ - _thread->join(); - _poller->remove(*_inproc); - _inproc->close(); - HandleClose(); -} - -bool ZMQTask::ProcessExit() -{ - if (_poller->events(*_inproc) == zmqpp::poller::poll_in) - { - int op1; - do - { - zmqpp::message msg; - if (!_inproc->receive(msg, true)) - return false; //No more messages to read from sock. This shouldn't happen. - - // strip 'internalmq.' from message - std::string cmd = msg.get(0).substr(11); - if (cmd == "kill") - return true; - - _inproc->get(zmqpp::socket_option::events, op1); - } while (op1 & zmqpp::poller::poll_in); - } - - return false; -} - -void ZMQTask::Pipeline(zmqpp::socket* from, zmqpp::socket* to) -{ - /* - Push messages from socket to socket. - */ - if (_poller->events(*from) == zmqpp::poller::poll_in) - { - int32 op1, op2; - do - { - zmqpp::message msg; - if (!from->receive(msg, true)) - return; //No more messages to read from socket. This shouldn't happen. - - to->send(msg); - from->get(zmqpp::socket_option::events, op1); - to->get(zmqpp::socket_option::events, op2); - } while(op1 & zmqpp::poller::poll_in && op2 & zmqpp::poller::poll_out); - } -} diff --git a/src/server/ipc/ZMQTask.h b/src/server/ipc/ZMQTask.h deleted file mode 100644 index 4d0de0c420..0000000000 --- a/src/server/ipc/ZMQTask.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __ZMQTASK_H -#define __ZMQTASK_H - -#include "Define.h" -#include -#include -#include - -/* - This class serves as a base for all long running tasks - It is set up to terminate its running task upon receiving "kill" command -*/ -class TC_IPC_API ZMQTask -{ -public: - ZMQTask(); - virtual ~ZMQTask(); - - void Start(); - void End(); - virtual void Run() = 0; - -protected: - virtual void HandleOpen() { } - virtual void HandleClose() { } - void Pipeline(zmqpp::socket* from, zmqpp::socket* to); - bool ProcessExit(); - - zmqpp::poller* _poller; - - zmqpp::socket* _inproc; - std::thread* _thread; -}; - -#endif // __ZMQTASK_H diff --git a/src/server/ipc/ZmqContext.cpp b/src/server/ipc/ZmqContext.cpp deleted file mode 100644 index 3001bdf8f1..0000000000 --- a/src/server/ipc/ZmqContext.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ZmqContext.h" - -ZmqContext::ZmqContext() : _inproc(nullptr) -{ -} - -ZmqContext::~ZmqContext() -{ -} - -ZmqContext* ZmqContext::Instance() -{ - static ZmqContext instance; - return &instance; -} - -zmqpp::socket* ZmqContext::CreateNewSocket(zmqpp::socket_type type) -{ - std::unique_lock lock(_mutex); - zmqpp::socket* socket = new zmqpp::socket(_context, type); - socket->set(zmqpp::socket_option::linger, 0); - return socket; -} - -void ZmqContext::Initialize() -{ - _inproc = new zmqpp::socket(_context, zmqpp::socket_type::pub); - _inproc->bind("inproc://workers"); -} - -zmqpp::socket* ZmqContext::CreateInprocSubscriber() -{ - zmqpp::socket* sub = CreateNewSocket(zmqpp::socket_type::sub); - sub->connect("inproc://workers"); - sub->subscribe("internalmq."); - return sub; -} - -void ZmqContext::Close() -{ - _inproc->send("internalmq.kill"); - delete _inproc; - _inproc = nullptr; -} diff --git a/src/server/ipc/ZmqContext.h b/src/server/ipc/ZmqContext.h deleted file mode 100644 index 6a717327ed..0000000000 --- a/src/server/ipc/ZmqContext.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __ZMQCONTEX_H -#define __ZMQCONTEX_H - -#include "Common.h" -#include -#include - -/* - * We need to serialize access to zmq context otherwise stuff blows up. - */ -class TC_IPC_API ZmqContext -{ -public: - static ZmqContext* Instance(); - - ~ZmqContext(); - - zmqpp::socket* CreateNewSocket(zmqpp::socket_type); - void Initialize(); - zmqpp::socket* CreateInprocSubscriber(); - void Close(); - -private: - ZmqContext(); - ZmqContext(ZmqContext const&) = delete; - ZmqContext& operator=(ZmqContext const&) = delete; - - zmqpp::context _context; - std::mutex _mutex; - zmqpp::socket* _inproc; -}; - -#define sIpcContext ZmqContext::Instance() - -#endif diff --git a/src/server/ipc/ZmqListener.cpp b/src/server/ipc/ZmqListener.cpp deleted file mode 100644 index 7fe9cb3dcc..0000000000 --- a/src/server/ipc/ZmqListener.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ZmqListener.h" -#include "ZmqContext.h" - -ZmqListener::ZmqListener(std::string const& from, std::string const& to) -{ - _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::sub); - _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push); - _from->connect(from); - _to->bind(to); -} - -ZmqListener::~ZmqListener() -{ - delete _from; - delete _to; -} - -void ZmqListener::HandleOpen() -{ -} - -void ZmqListener::HandleClose() -{ - _from->close(); - _to->close(); -} - -void ZmqListener::Run() -{ - while (!ProcessExit()) - { - _poller->poll(); - - while (_poller->events(*_from) & zmqpp::poller::poll_in && - _poller->events(*_to) & zmqpp::poller::poll_out) - { - zmqpp::message msg; - _from->receive(msg); - _to->send(msg); - } - } -} - -void ZmqListener::Subscribe(std::string const& keyword) -{ - _from->subscribe(keyword); -} - -void ZmqListener::Unsubscribe(std::string const& keyword) -{ - _from->unsubscribe(keyword); -} diff --git a/src/server/ipc/ZmqListener.h b/src/server/ipc/ZmqListener.h deleted file mode 100644 index ad5263b73e..0000000000 --- a/src/server/ipc/ZmqListener.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __ZMQLISTENER_H -#define __ZMQLISTENER_H - -#include "ZMQTask.h" -#include - -class TC_IPC_API ZmqListener : public ZMQTask -{ -/* - * Read broadcasts from remote PUB socket, and forward them to - * another socket. - * - * from - client SUB socket - * to - listen PUSH socket - * - */ -public: - ZmqListener(std::string const& from, std::string const& to); - ~ZmqListener(); - void Run() override; - - void Subscribe(std::string const& keyword); - void Unsubscribe(std::string const& keyword); - -protected: - void HandleOpen() override; - void HandleClose() override; - -private: - zmqpp::socket* _from; - zmqpp::socket* _to; -}; - -#endif diff --git a/src/server/ipc/ZmqMux.cpp b/src/server/ipc/ZmqMux.cpp deleted file mode 100644 index 63d32568a1..0000000000 --- a/src/server/ipc/ZmqMux.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ZmqMux.h" -#include "ZmqContext.h" - -ZmqMux::ZmqMux(std::string from_uri, std::string to_uri): - _fromAddress(from_uri) -{ - printf("Opening muxer thread from %s to %s\n", from_uri.c_str(), to_uri.c_str()); - _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull); - _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push); - - _from->bind(from_uri); - _to->connect(to_uri); -} - -ZmqMux::~ZmqMux() -{ - delete _from; - delete _to; -} - -void ZmqMux::HandleOpen() -{ - _poller->add(*_from); - _poller->add(*_to, zmqpp::poller::poll_out); -} - -bool ZmqMux::Send(zmqpp::message* m, bool dont_block) -{ - if (_socket.get() == nullptr) - { - _socket.reset(sIpcContext->CreateNewSocket(zmqpp::socket_type::push)); - _socket->connect(_fromAddress); - } - - return _socket->send(*m, dont_block); -} - -void ZmqMux::Run() -{ - for (;;) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - if (!_poller->poll()) - break; - - if (ProcessExit()) - break; - - Pipeline(_from, _to); - } -} diff --git a/src/server/ipc/ZmqMux.h b/src/server/ipc/ZmqMux.h deleted file mode 100644 index 0f1c8cf206..0000000000 --- a/src/server/ipc/ZmqMux.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __ZMQMUX_H -#define __ZMQMUX_H - -#include "ZMQTask.h" -#include -#include - -/* - * Multiplexes zmq messages from many threads, - * and then passes them to another socket. - */ -class TC_IPC_API ZmqMux : public ZMQTask -{ -public: - ZmqMux(std::string from, std::string to); - ~ZmqMux(); - bool Send(zmqpp::message*, bool dont_block = false); - void Run() override; - -protected: - void HandleOpen() override; - -private: - boost::thread_specific_ptr _socket; - zmqpp::socket* _from; - zmqpp::socket* _to; - std::string const _fromAddress; -}; - -#endif diff --git a/src/server/ipc/ZmqWorker.cpp b/src/server/ipc/ZmqWorker.cpp deleted file mode 100644 index 6bb706e4a9..0000000000 --- a/src/server/ipc/ZmqWorker.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ZmqWorker.h" -#include "ZmqContext.h" - -ZmqWorker::ZmqWorker(std::string const& taskUri, std::string const& resUri) : - _taskUri(taskUri), _resultsUri(resUri) -{ -} - -ZmqWorker::~ZmqWorker() -{ - delete _taskQueue; - delete _results; -} - -void ZmqWorker::HandleOpen() -{ - _taskQueue = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull); - _results = sIpcContext->CreateNewSocket(zmqpp::socket_type::push); - - _taskQueue->connect(_taskUri); - _results->connect(_resultsUri); - - _poller->add(*_taskQueue); -} - -void ZmqWorker::HandleClose() -{ - _taskQueue->close(); - _results->close(); -} - -void ZmqWorker::Run() -{ - while (!ProcessExit()) - { - _poller->poll(); - if (_poller->events(*_taskQueue) & zmqpp::poller::poll_in) - PerformWork(); - } -} - -void ZmqWorker::PerformWork() -{ - int32 op1; - do - { - zmqpp::message msg; - _taskQueue->receive(msg); - Dispatch(msg); - _taskQueue->get(zmqpp::socket_option::events, op1); - } while (op1 & zmqpp::poller::poll_in); -} diff --git a/src/server/ipc/ZmqWorker.h b/src/server/ipc/ZmqWorker.h deleted file mode 100644 index 80b4a99212..0000000000 --- a/src/server/ipc/ZmqWorker.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __ZMQWORKER_H -#define __ZMQWORKER_H - -#include "ZMQTask.h" -#include - -class TC_IPC_API ZmqWorker : public ZMQTask -{ -public: - ZmqWorker(std::string const& taskUri, std::string const& resUri); - ~ZmqWorker(); - void Run() override; - -protected: - void HandleOpen() override; - void HandleClose() override; - zmqpp::socket* _results = nullptr; - -private: - void PerformWork(); - virtual void Dispatch(zmqpp::message const&) = 0; - zmqpp::socket* _taskQueue = nullptr; - std::string _taskUri; - std::string _resultsUri; -}; - -#endif diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index d6fffc5866..1223b6d04d 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -23,7 +23,10 @@ Category: commandscripts EndScriptData */ #include "AccountMgr.h" +#include "AES.h" +#include "Base32.h" #include "Chat.h" +#include "CryptoGenerics.h" #include "DatabaseEnv.h" #include "IpAddress.h" #include "IPLocation.h" @@ -31,8 +34,12 @@ EndScriptData */ #include "Log.h" #include "Player.h" #include "ScriptMgr.h" +#include "SecretMgr.h" +#include "TOTP.h" #include "World.h" #include "WorldSession.h" +#include +#include using namespace Trinity::ChatCommands; @@ -54,6 +61,12 @@ public: { "sec", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_SEC, true, nullptr, "", accountSetSecTable }, { "gmlevel", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_GMLEVEL, true, &HandleAccountSetGmLevelCommand, "" }, { "password", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "" }, + { "2fa", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_2FA, true, &HandleAccountSet2FACommand, "" }, + }; + static std::vector account2FACommandTable = + { + { "setup", rbac::RBAC_PERM_COMMAND_ACCOUNT_2FA_SETUP, false, &HandleAccount2FASetupCommand, "" }, + { "remove", rbac::RBAC_PERM_COMMAND_ACCOUNT_2FA_REMOVE, false, &HandleAccount2FARemoveCommand, "" }, }; static std::vector accountLockCommandTable = { @@ -62,6 +75,7 @@ public: }; static std::vector accountCommandTable = { + { "2fa", rbac::RBAC_PERM_COMMAND_ACCOUNT_2FA, false, nullptr, "", account2FACommandTable }, { "addon", rbac::RBAC_PERM_COMMAND_ACCOUNT_ADDON, false, &HandleAccountAddonCommand, "" }, { "create", rbac::RBAC_PERM_COMMAND_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "" }, { "delete", rbac::RBAC_PERM_COMMAND_ACCOUNT_DELETE, true, &HandleAccountDeleteCommand, "" }, @@ -79,6 +93,138 @@ public: return commandTable; } + static bool HandleAccount2FASetupCommand(ChatHandler* handler, Optional token) + { + auto const& masterKey = sSecretMgr->GetSecret(SECRET_TOTP_MASTER_KEY); + if (!masterKey.IsAvailable()) + { + handler->SendSysMessage(LANG_2FA_COMMANDS_NOT_SETUP); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 const accountId = handler->GetSession()->GetAccountId(); + + { // check if 2FA already enabled + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_TOTP_SECRET); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + { + TC_LOG_ERROR("misc", "Account %u not found in login database when processing .account 2fa setup command.", accountId); + handler->SendSysMessage(LANG_UNKNOWN_ERROR); + handler->SetSentErrorMessage(true); + return false; + } + + if (!result->Fetch()->IsNull()) + { + handler->SendSysMessage(LANG_2FA_ALREADY_SETUP); + handler->SetSentErrorMessage(true); + return false; + } + } + + // store random suggested secrets + static std::unordered_map suggestions; + auto pair = suggestions.emplace(std::piecewise_construct, std::make_tuple(accountId), std::make_tuple(Trinity::Crypto::TOTP::RECOMMENDED_SECRET_LENGTH)); // std::vector 1-argument size_t constructor invokes resize + if (pair.second) // no suggestion yet, generate random secret + RAND_bytes(pair.first->second.data(), pair.first->second.size()); + + if (!pair.second && token) // suggestion already existed and token specified - validate + { + if (Trinity::Crypto::TOTP::ValidateToken(pair.first->second, *token)) + { + if (masterKey) + Trinity::Crypto::AEEncryptWithRandomIV(pair.first->second, *masterKey); + + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET); + stmt->setBinary(0, pair.first->second); + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + suggestions.erase(pair.first); + handler->SendSysMessage(LANG_2FA_SETUP_COMPLETE); + return true; + } + else + handler->SendSysMessage(LANG_2FA_INVALID_TOKEN); + } + + // new suggestion, or no token specified, output TOTP parameters + handler->PSendSysMessage(LANG_2FA_SECRET_SUGGESTION, Trinity::Encoding::Base32::Encode(pair.first->second)); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleAccount2FARemoveCommand(ChatHandler* handler, Optional token) + { + auto const& masterKey = sSecretMgr->GetSecret(SECRET_TOTP_MASTER_KEY); + if (!masterKey.IsAvailable()) + { + handler->SendSysMessage(LANG_2FA_COMMANDS_NOT_SETUP); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 const accountId = handler->GetSession()->GetAccountId(); + Trinity::Crypto::TOTP::Secret secret; + { // get current TOTP secret + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_TOTP_SECRET); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + { + TC_LOG_ERROR("misc", "Account %u not found in login database when processing .account 2fa setup command.", accountId); + handler->SendSysMessage(LANG_UNKNOWN_ERROR); + handler->SetSentErrorMessage(true); + return false; + } + + Field* field = result->Fetch(); + if (field->IsNull()) + { // 2FA not enabled + handler->SendSysMessage(LANG_2FA_NOT_SETUP); + handler->SetSentErrorMessage(true); + return false; + } + + secret = field->GetBinary(); + } + + if (token) + { + if (masterKey) + { + bool success = Trinity::Crypto::AEDecrypt(secret, *masterKey); + if (!success) + { + TC_LOG_ERROR("misc", "Account %u has invalid ciphertext in TOTP token.", accountId); + handler->SendSysMessage(LANG_UNKNOWN_ERROR); + handler->SetSentErrorMessage(true); + return false; + } + } + + if (Trinity::Crypto::TOTP::ValidateToken(secret, *token)) + { + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET); + stmt->setNull(0); + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + handler->SendSysMessage(LANG_2FA_REMOVE_COMPLETE); + return true; + } + else + handler->SendSysMessage(LANG_2FA_INVALID_TOKEN); + } + + handler->SendSysMessage(LANG_2FA_REMOVE_NEED_TOKEN); + handler->SetSentErrorMessage(true); + return false; + } + static bool HandleAccountAddonCommand(ChatHandler* handler, uint8 expansion) { if (expansion > sWorld->getIntConfig(CONFIG_EXPANSION)) @@ -658,6 +804,69 @@ public: return true; } + static bool HandleAccountSet2FACommand(ChatHandler* handler, std::string accountName, std::string secret) + { + if (!Utf8ToUpperOnlyLatin(accountName)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = AccountMgr::GetId(accountName); + if (!targetAccountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (handler->HasLowerSecurityAccount(nullptr, targetAccountId, true)) + return false; + + if (secret == "off") + { + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET); + stmt->setNull(0); + stmt->setUInt32(1, targetAccountId); + LoginDatabase.Execute(stmt); + handler->PSendSysMessage(LANG_2FA_REMOVE_COMPLETE); + return true; + } + + auto const& masterKey = sSecretMgr->GetSecret(SECRET_TOTP_MASTER_KEY); + if (!masterKey.IsAvailable()) + { + handler->SendSysMessage(LANG_2FA_COMMANDS_NOT_SETUP); + handler->SetSentErrorMessage(true); + return false; + } + + Optional> decoded = Trinity::Encoding::Base32::Decode(secret); + if (!decoded) + { + handler->SendSysMessage(LANG_2FA_SECRET_INVALID); + handler->SetSentErrorMessage(true); + return false; + } + if (128 < (decoded->size() + Trinity::Crypto::AES::IV_SIZE_BYTES + Trinity::Crypto::AES::TAG_SIZE_BYTES)) + { + handler->SendSysMessage(LANG_2FA_SECRET_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + } + + if (masterKey) + Trinity::Crypto::AEEncryptWithRandomIV(*decoded, *masterKey); + + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET); + stmt->setBinary(0, *decoded); + stmt->setUInt32(1, targetAccountId); + LoginDatabase.Execute(stmt); + handler->PSendSysMessage(LANG_2FA_SECRET_SET_COMPLETE, accountName.c_str()); + return true; + } + /// Set normal email for account static bool HandleAccountSetEmailCommand(ChatHandler* handler, std::string accountName, std::string const& email, std::string const& confirmEmail) { diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp deleted file mode 100644 index 22819f2fa2..0000000000 --- a/src/server/scripts/Commands/cs_battlenet_account.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "AccountMgr.h" -#include "BattlenetAccountMgr.h" -#include "BigNumber.h" -#include "Chat.h" -#include "DatabaseEnv.h" -#include "IpAddress.h" -#include "IPLocation.h" -#include "Language.h" -#include "Log.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "Util.h" -#include "WorldSession.h" - -class battlenet_account_commandscript : public CommandScript -{ -public: - battlenet_account_commandscript() : CommandScript("battlenet_account_commandscript") { } - - std::vector GetCommands() const override - { - static std::vector accountSetCommandTable = - { - { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "" }, - }; - - static std::vector accountLockCommandTable = - { - { "country", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "" }, - { "ip", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "" }, - }; - - static std::vector accountCommandTable = - { - { "create", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "" }, - { "gameaccountcreate", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE_GAME, true, &HandleGameAccountCreateCommand, "", }, - { "lock", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, false, nullptr, "", accountLockCommandTable }, - { "set", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET, true, nullptr, "", accountSetCommandTable }, - { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "" }, - { "link", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LINK, true, &HandleAccountLinkCommand, "", }, - { "unlink", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_UNLINK, true, &HandleAccountUnlinkCommand, "", }, - { "listgameaccounts", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LIST_GAME_ACCOUNTS, true, &HandleListGameAccountsCommand, "" } - }; - - static std::vector commandTable = - { - { "bnetaccount", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, true, nullptr, "", accountCommandTable }, - }; - - return commandTable; - } - - /// Create an account - static bool HandleAccountCreateCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - ///- %Parse the command line arguments - char* accountName = strtok((char*)args, " "); - char* password = strtok(nullptr, " "); - if (!accountName || !password) - return false; - - if (!strchr(accountName, '@')) - { - handler->SendSysMessage(LANG_ACCOUNT_INVALID_BNET_NAME); - handler->SetSentErrorMessage(true); - return false; - } - - char* createGameAccountParam = strtok(nullptr, " "); - bool createGameAccount = true; - if (createGameAccountParam) - createGameAccount = StringToBool(createGameAccountParam); - - std::string gameAccountName; - switch (Battlenet::AccountMgr::CreateBattlenetAccount(std::string(accountName), std::string(password), createGameAccount, &gameAccountName)) - { - case AccountOpResult::AOR_OK: - { - if (createGameAccount) - handler->PSendSysMessage(LANG_ACCOUNT_CREATED_BNET_WITH_GAME, accountName, gameAccountName.c_str()); - else - handler->PSendSysMessage(LANG_ACCOUNT_CREATED_BNET, accountName); - - if (handler->GetSession()) - { - TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (%s) created Battle.net account %s%s%s", - handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(), - accountName, createGameAccount ? " with game account " : "", createGameAccount ? gameAccountName.c_str() : ""); - } - break; - } - case AccountOpResult::AOR_NAME_TOO_LONG: - handler->SendSysMessage(LANG_ACCOUNT_NAME_TOO_LONG); - handler->SetSentErrorMessage(true); - return false; - case AccountOpResult::AOR_PASS_TOO_LONG: - handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); - handler->SetSentErrorMessage(true); - return false; - case AccountOpResult::AOR_NAME_ALREADY_EXIST: - handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); - handler->SetSentErrorMessage(true); - return false; - default: - break; - } - - return true; - } - - // Sets country lock on own account - static bool HandleAccountLockCountryCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - std::string param = (char*)args; - if (!param.empty()) - { - if (param == "on") - { - if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(handler->GetSession()->GetRemoteAddress())) - { - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_COUNTRY); - stmt->setString(0, location->CountryCode); - stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId()); - LoginDatabase.Execute(stmt); - handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); - } - else - { - handler->PSendSysMessage("IP2Location] No information"); - TC_LOG_DEBUG("server.authserver", "IP2Location] No information"); - } - } - else if (param == "off") - { - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_COUNTRY); - stmt->setString(0, "00"); - stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId()); - LoginDatabase.Execute(stmt); - handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); - } - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - // Sets ip lock on own account - static bool HandleAccountLockIpCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - std::string param = (char*)args; - - if (!param.empty()) - { - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK); - - if (param == "on") - { - stmt->setBool(0, true); // locked - handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); - } - else if (param == "off") - { - stmt->setBool(0, false); // unlocked - handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); - } - - stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId()); - - LoginDatabase.Execute(stmt); - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - static bool HandleAccountPasswordCommand(ChatHandler* handler, char const* args) - { - // If no args are given at all, we can return false right away. - if (!*args) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } - - // Command is supposed to be: .account password [$oldpassword] [$newpassword] [$newpasswordconfirmation] [$emailconfirmation] - char* oldPassword = strtok((char*)args, " "); // This extracts [$oldpassword] - char* newPassword = strtok(nullptr, " "); // This extracts [$newpassword] - char* passwordConfirmation = strtok(nullptr, " "); // This extracts [$newpasswordconfirmation] - - //Is any of those variables missing for any reason ? We return false. - if (!oldPassword || !newPassword || !passwordConfirmation) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } - - // We compare the old, saved password to the entered old password - no chance for the unauthorized. - if (!Battlenet::AccountMgr::CheckPassword(handler->GetSession()->GetBattlenetAccountId(), std::string(oldPassword))) - { - handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); - handler->SetSentErrorMessage(true); - TC_LOG_INFO("entities.player.character", "Battle.net account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but the provided old password is wrong.", - handler->GetSession()->GetBattlenetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter()); - return false; - } - - // Making sure that newly entered password is correctly entered. - if (strcmp(newPassword, passwordConfirmation) != 0) - { - handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); - handler->SetSentErrorMessage(true); - return false; - } - - // Changes password and prints result. - AccountOpResult result = Battlenet::AccountMgr::ChangePassword(handler->GetSession()->GetBattlenetAccountId(), std::string(newPassword)); - switch (result) - { - case AccountOpResult::AOR_OK: - handler->SendSysMessage(LANG_COMMAND_PASSWORD); - TC_LOG_INFO("entities.player.character", "Battle.net account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Password.", - handler->GetSession()->GetBattlenetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter()); - break; - case AccountOpResult::AOR_PASS_TOO_LONG: - handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); - handler->SetSentErrorMessage(true); - return false; - default: - handler->SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); - handler->SetSentErrorMessage(true); - return false; - } - - return true; - } - - /// Set password for account - static bool HandleAccountSetPasswordCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } - - ///- Get the command line arguments - char* account = strtok((char*)args, " "); - char* password = strtok(nullptr, " "); - char* passwordConfirmation = strtok(nullptr, " "); - - if (!account || !password || !passwordConfirmation) - return false; - - std::string accountName = account; - if (!Utf8ToUpperOnlyLatin(accountName)) - { - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 targetAccountId = Battlenet::AccountMgr::GetId(accountName); - if (!targetAccountId) - { - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - if (strcmp(password, passwordConfirmation)) - { - handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); - handler->SetSentErrorMessage(true); - return false; - } - - AccountOpResult result = Battlenet::AccountMgr::ChangePassword(targetAccountId, password); - - switch (result) - { - case AccountOpResult::AOR_OK: - handler->SendSysMessage(LANG_COMMAND_PASSWORD); - break; - case AccountOpResult::AOR_NAME_NOT_EXIST: - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - case AccountOpResult::AOR_PASS_TOO_LONG: - handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); - handler->SetSentErrorMessage(true); - return false; - default: - return false; - } - return true; - } - - static bool HandleAccountLinkCommand(ChatHandler* handler, char const* args) - { - Tokenizer tokens(args, ' ', 2); - if (tokens.size() != 2) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } - - std::string bnetAccountName = tokens[0]; - std::string gameAccountName = tokens[1]; - - switch (Battlenet::AccountMgr::LinkWithGameAccount(bnetAccountName, gameAccountName)) - { - case AccountOpResult::AOR_OK: - handler->PSendSysMessage(LANG_ACCOUNT_BNET_LINKED, bnetAccountName.c_str(), gameAccountName.c_str()); - break; - case AccountOpResult::AOR_NAME_NOT_EXIST: - handler->PSendSysMessage(LANG_ACCOUNT_OR_BNET_DOES_NOT_EXIST, bnetAccountName.c_str(), gameAccountName.c_str()); - handler->SetSentErrorMessage(true); - break; - case AccountOpResult::AOR_ACCOUNT_BAD_LINK: - handler->PSendSysMessage(LANG_ACCOUNT_ALREADY_LINKED, gameAccountName.c_str()); - handler->SetSentErrorMessage(true); - break; - default: - break; - } - - return true; - } - - static bool HandleAccountUnlinkCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } - - std::string gameAccountName = args; - - switch (Battlenet::AccountMgr::UnlinkGameAccount(gameAccountName)) - { - case AccountOpResult::AOR_OK: - handler->PSendSysMessage(LANG_ACCOUNT_BNET_UNLINKED, gameAccountName.c_str()); - break; - case AccountOpResult::AOR_NAME_NOT_EXIST: - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, gameAccountName.c_str()); - handler->SetSentErrorMessage(true); - break; - case AccountOpResult::AOR_ACCOUNT_BAD_LINK: - handler->PSendSysMessage(LANG_ACCOUNT_BNET_NOT_LINKED, gameAccountName.c_str()); - handler->SetSentErrorMessage(true); - break; - default: - break; - } - - return true; - } - - static bool HandleGameAccountCreateCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } - - std::string bnetAccountName = args; - uint32 accountId = Battlenet::AccountMgr::GetId(bnetAccountName); - if (!accountId) - { - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, bnetAccountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - uint8 index = Battlenet::AccountMgr::GetMaxIndex(accountId) + 1; - std::string accountName = std::to_string(accountId) + '#' + std::to_string(uint32(index)); - - // Generate random hex string for password, these accounts must not be logged on with GRUNT - BigNumber randPassword; - randPassword.SetRand(8 * 16); - - switch (sAccountMgr->CreateAccount(accountName, ByteArrayToHexStr(randPassword.AsByteArray().get(), randPassword.GetNumBytes()), bnetAccountName, accountId, index)) - { - case AccountOpResult::AOR_OK: - handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName.c_str()); - if (handler->GetSession()) - { - TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (%s) created Account %s (Email: '%s')", - handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(), - accountName.c_str(), bnetAccountName.c_str()); - } - break; - case AccountOpResult::AOR_NAME_TOO_LONG: - handler->SendSysMessage(LANG_ACCOUNT_NAME_TOO_LONG); - handler->SetSentErrorMessage(true); - return false; - case AccountOpResult::AOR_PASS_TOO_LONG: - handler->SendSysMessage(LANG_ACCOUNT_PASS_TOO_LONG); - handler->SetSentErrorMessage(true); - return false; - case AccountOpResult::AOR_NAME_ALREADY_EXIST: - handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); - handler->SetSentErrorMessage(true); - return false; - case AccountOpResult::AOR_DB_INTERNAL_ERROR: - handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - default: - handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - return true; - } - - static bool HandleListGameAccountsCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char* battlenetAccountName = strtok((char*)args, " "); - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_LIST); - stmt->setString(0, battlenetAccountName); - if (PreparedQueryResult accountList = LoginDatabase.Query(stmt)) - { - auto formatDisplayName = [](char const* name) -> std::string - { - if (char const* hashPos = strchr(name, '#')) - return std::string("WoW") + ++hashPos; - else - return name; - }; - - handler->SendSysMessage("----------------------------------------------------"); - handler->SendSysMessage(LANG_ACCOUNT_BNET_LIST_HEADER); - handler->SendSysMessage("----------------------------------------------------"); - do - { - Field* fields = accountList->Fetch(); - handler->PSendSysMessage("| %10u | %-16.16s | %-16.16s |", fields[0].GetUInt32(), fields[1].GetCString(), formatDisplayName(fields[1].GetCString()).c_str()); - } while (accountList->NextRow()); - handler->SendSysMessage("----------------------------------------------------"); - } - else - handler->PSendSysMessage(LANG_ACCOUNT_BNET_LIST_NO_ACCOUNTS, battlenetAccountName); - - return true; - } -}; - -void AddSC_battlenet_account_commandscript() -{ - new battlenet_account_commandscript(); -} diff --git a/src/server/scripts/Commands/cs_script_loader.cpp b/src/server/scripts/Commands/cs_script_loader.cpp index 38651abc8d..dd8fb48f22 100644 --- a/src/server/scripts/Commands/cs_script_loader.cpp +++ b/src/server/scripts/Commands/cs_script_loader.cpp @@ -21,7 +21,6 @@ void AddSC_achievement_commandscript(); void AddSC_ahbot_commandscript(); void AddSC_arena_commandscript(); void AddSC_ban_commandscript(); -void AddSC_battlenet_account_commandscript(); void AddSC_bf_commandscript(); void AddSC_cast_commandscript(); void AddSC_character_commandscript(); @@ -67,7 +66,6 @@ void AddCommandsScripts() AddSC_ahbot_commandscript(); AddSC_arena_commandscript(); AddSC_ban_commandscript(); - AddSC_battlenet_account_commandscript(); AddSC_bf_commandscript(); AddSC_cast_commandscript(); AddSC_character_commandscript(); diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h index 2842875f5e..9f1372449f 100644 --- a/src/server/shared/Networking/Socket.h +++ b/src/server/shared/Networking/Socket.h @@ -138,6 +138,11 @@ public: MessageBuffer& GetReadBuffer() { return _readBuffer; } + tcp::socket& underlying_stream() + { + return _socket; + } + protected: virtual void OnClose() { } diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index e4c97e3778..0a9a2a6da3 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -20,6 +20,7 @@ #include "Define.h" #include "ByteConverter.h" +#include #include #include #include @@ -486,6 +487,12 @@ class TC_SHARED_API ByteBuffer _rpos += len; } + template + void read(std::array& arr) + { + read(arr.data(), Size); + } + void readPackGUID(uint64& guid) { if (rpos() + 1 > size()) @@ -590,6 +597,12 @@ class TC_SHARED_API ByteBuffer append(buffer.contents(), buffer.wpos()); } + template + void append(std::array const& arr) + { + append(arr.data(), Size); + } + // can be used in SMSG_MONSTER_MOVE opcode void appendPackXYZ(float x, float y, float z) { diff --git a/src/server/shared/Realm/ClientBuildInfo.cpp b/src/server/shared/Realm/ClientBuildInfo.cpp new file mode 100644 index 0000000000..346a3d5175 --- /dev/null +++ b/src/server/shared/Realm/ClientBuildInfo.cpp @@ -0,0 +1,139 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ClientBuildInfo.h" +#include "DatabaseEnv.h" +#include "Log.h" +#include "Util.h" +#include +#include + +namespace +{ +std::vector Builds; +} + +namespace ClientBuild +{ +std::array ToCharArray(uint32 value) +{ + auto normalize = [](uint8 c) -> char + { + if (!c || std::isprint(c)) + return char(c); + return ' '; + }; + + std::array chars = { char((value >> 24) & 0xFF), char((value >> 16) & 0xFF), char((value >> 8) & 0xFF), char(value & 0xFF), '\0' }; + + auto firstNonZero = std::ranges::find_if(chars, [](char c) { return c != '\0'; }); + if (firstNonZero != chars.end()) + { + // move leading zeros to end + std::rotate(chars.begin(), firstNonZero, chars.end()); + + // ensure we only have printable characters remaining + std::ranges::transform(chars, chars.begin(), normalize); + } + + return chars; +} + +bool Platform::IsValid(std::string_view platform) +{ + if (platform.length() > sizeof(uint32)) + return false; + + switch (ToFourCC(platform)) + { + case Win_x86: + case Mac_x86: + return true; + default: + break; + } + + return false; +} + +void LoadBuildInfo() +{ + Builds.clear(); + + // 0 1 2 3 4 + if (QueryResult result = LoginDatabase.Query("SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build FROM build_info ORDER BY build ASC")) + { + do + { + Field* fields = result->Fetch(); + Info& build = Builds.emplace_back(); + build.MajorVersion = fields[0].GetUInt32(); + build.MinorVersion = fields[1].GetUInt32(); + build.BugfixVersion = fields[2].GetUInt32(); + std::string hotfixVersion = fields[3].GetString(); + if (hotfixVersion.length() < build.HotfixVersion.size()) + std::ranges::copy(hotfixVersion, build.HotfixVersion.begin()); + else + build.HotfixVersion = { }; + + build.Build = fields[4].GetUInt32(); + + } while (result->NextRow()); + } + + // 0 1 2 + if (QueryResult result = LoginDatabase.Query("SELECT `build`, `platform`, `executableHash` FROM `build_executable_hash`")) + { + do + { + Field* fields = result->Fetch(); + + uint32 build = fields[0].GetInt32(); + auto buildInfo = std::ranges::find(Builds, build, &Info::Build); + if (buildInfo == Builds.end()) + { + TC_LOG_ERROR("sql.sql", "ClientBuild::LoadBuildInfo: Unknown `build` %u in `build_executable_hash` - missing from `build_info`, skipped.", build); + continue; + } + + std::string_view platform = fields[1].GetStringView(); + if (!Platform::IsValid(platform)) + { + TC_LOG_ERROR("sql.sql", "ClientBuild::LoadBuildInfo: Invalid platform %s for `build` %u in `build_executable_hash`, skipped.", platform.data(), build); + continue; + } + + ExecutableHash& buildKey = buildInfo->ExecutableHashes.emplace_back(); + buildKey.Platform = ToFourCC(platform); + buildKey.Hash = fields[2].GetBinary(); + + } while (result->NextRow()); + } +} + +Info const* GetBuildInfo(uint32 build) +{ + auto buildInfo = std::ranges::find(Builds, build, &Info::Build); + return buildInfo != Builds.end() ? &*buildInfo : nullptr; +} + +uint32 GetMinorMajorBugfixVersionForBuild(uint32 build) +{ + auto buildInfo = std::ranges::lower_bound(Builds, build, {}, &Info::Build); + return buildInfo != Builds.end() ? (buildInfo->MajorVersion * 10000 + buildInfo->MinorVersion * 100 + buildInfo->BugfixVersion) : 0; +} +} diff --git a/src/server/shared/Realm/ClientBuildInfo.h b/src/server/shared/Realm/ClientBuildInfo.h new file mode 100644 index 0000000000..2889470b9c --- /dev/null +++ b/src/server/shared/Realm/ClientBuildInfo.h @@ -0,0 +1,79 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITYCORE_CLIENT_BUILD_INFO_H +#define TRINITYCORE_CLIENT_BUILD_INFO_H + +#include "Define.h" +#include +#include +#include + +namespace ClientBuild +{ +inline constexpr uint32 ToFourCC(std::string_view text) +{ + uint32 uintValue = 0; + for (uint8 c : text) + { + uintValue <<= 8; + uintValue |= c; + } + return uintValue; +} + +consteval uint32 operator""_fourcc(char const* chars, std::size_t length) +{ + if (length > sizeof(uint32)) + throw "Text can only be max 4 characters long"; + + return ToFourCC({ chars, length }); +} + +TC_SHARED_API std::array ToCharArray(uint32 value); + +namespace Platform +{ + inline constexpr uint32 Win_x86 = "Win"_fourcc; + inline constexpr uint32 Mac_x86 = "OSX"_fourcc; + + TC_SHARED_API bool IsValid(std::string_view platform); +} + +struct ExecutableHash +{ + static constexpr std::size_t Size = 20; + + uint32 Platform; + std::array Hash; +}; + +struct Info +{ + uint32 Build; + uint32 MajorVersion; + uint32 MinorVersion; + uint32 BugfixVersion; + std::array HotfixVersion; + std::vector ExecutableHashes; +}; + +TC_SHARED_API void LoadBuildInfo(); +TC_SHARED_API Info const* GetBuildInfo(uint32 build); +} + +#endif // TRINITYCORE_CLIENT_BUILD_INFO_H diff --git a/src/server/shared/Secrets/SecretMgr.cpp b/src/server/shared/Secrets/SecretMgr.cpp new file mode 100644 index 0000000000..9031d8f209 --- /dev/null +++ b/src/server/shared/Secrets/SecretMgr.cpp @@ -0,0 +1,236 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "SecretMgr.h" +#include "AES.h" +#include "Argon2Hash.h" +#include "Config.h" +#include "CryptoGenerics.h" +#include "DatabaseEnv.h" +#include "Errors.h" +#include "Log.h" +#include "SharedDefines.h" +#include +#include + +#define SECRET_FLAG_FOR(key, val, server) server ## _ ## key = (val ## ull << (16*SERVER_PROCESS_ ## server)) +#define SECRET_FLAG(key, val) SECRET_FLAG_ ## key = val, SECRET_FLAG_FOR(key, val, AUTHSERVER), SECRET_FLAG_FOR(key, val, WORLDSERVER) +enum SecretFlags : uint64 +{ + SECRET_FLAG(DEFER_LOAD, 0x1) +}; +#undef SECRET_FLAG_FOR +#undef SECRET_FLAG + +struct SecretInfo +{ + char const* configKey; + char const* oldKey; + int bits; + ServerProcessTypes owner; + uint64 _flags; + uint16 flags() const { return static_cast(_flags >> (16*THIS_SERVER_PROCESS)); } +}; + +static constexpr SecretInfo secret_info[NUM_SECRETS] = +{ + { "TOTPMasterSecret", "TOTPOldMasterSecret", 128, SERVER_PROCESS_AUTHSERVER, WORLDSERVER_DEFER_LOAD } +}; + +/*static*/ SecretMgr* SecretMgr::instance() +{ + static SecretMgr instance; + return &instance; +} + +static Optional GetHexFromConfig(char const* configKey, int bits) +{ + ASSERT(bits > 0); + std::string str = sConfigMgr->GetStringDefault(configKey, ""); + if (str.empty()) + return {}; + + BigNumber secret; + if (!secret.SetHexStr(str.c_str())) + { + TC_LOG_FATAL("server.loading", "Invalid value for '{}' - specify a hexadecimal integer of up to {} bits with no prefix.", configKey, bits); + ABORT(); + } + + BigNumber threshold(2); + threshold <<= bits; + if (!((BigNumber(0) <= secret) && (secret < threshold))) + { + TC_LOG_ERROR("server.loading", "Value for '{}' is out of bounds (should be an integer of up to {} bits with no prefix). Truncated to {} bits.", configKey, bits, bits); + secret %= threshold; + } + ASSERT(((BigNumber(0) <= secret) && (secret < threshold))); + + return secret; +} + +void SecretMgr::Initialize() +{ + for (uint32 i = 0; i < NUM_SECRETS; ++i) + { + if (secret_info[i].flags() & SECRET_FLAG_DEFER_LOAD) + continue; + std::unique_lock lock(_secrets[i].lock); + AttemptLoad(Secrets(i), LOG_LEVEL_FATAL, lock); + if (!_secrets[i].IsAvailable()) + ABORT(); // load failed + } +} + +SecretMgr::Secret const& SecretMgr::GetSecret(Secrets i) +{ + std::unique_lock lock(_secrets[i].lock); + + if (_secrets[i].state == Secret::NOT_LOADED_YET) + AttemptLoad(i, LOG_LEVEL_ERROR, lock); + return _secrets[i]; +} + +void SecretMgr::AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock const&) +{ + auto const& info = secret_info[i]; + Optional oldDigest; + { + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SECRET_DIGEST); + stmt->setUInt32(0, i); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + oldDigest = result->Fetch()->GetString(); + } + Optional currentValue = GetHexFromConfig(info.configKey, info.bits); + + // verify digest + if ( + ((!oldDigest) != (!currentValue)) || // there is an old digest, but no current secret (or vice versa) + (oldDigest && !Trinity::Crypto::Argon2::Verify(currentValue->AsHexStr(), *oldDigest)) // there is an old digest, and the current secret does not match it + ) + { + if (info.owner != THIS_SERVER_PROCESS) + { + if (currentValue) + TC_LOG_MESSAGE_BODY("server.loading", errorLevel, "Invalid value for '{}' specified - this is not actually the secret being used in your auth DB.", info.configKey); + else + TC_LOG_MESSAGE_BODY("server.loading", errorLevel, "No value for '{}' specified - please specify the secret currently being used in your auth DB.", info.configKey); + _secrets[i].state = Secret::LOAD_FAILED; + return; + } + + Optional oldSecret; + if (oldDigest && info.oldKey) // there is an old digest, so there might be an old secret (if possible) + { + oldSecret = GetHexFromConfig(info.oldKey, info.bits); + if (oldSecret && !Trinity::Crypto::Argon2::Verify(oldSecret->AsHexStr(), *oldDigest)) + { + TC_LOG_MESSAGE_BODY("server.loading", errorLevel, "Invalid value for '{}' specified - this is not actually the secret previously used in your auth DB.", info.oldKey); + _secrets[i].state = Secret::LOAD_FAILED; + return; + } + } + + // attempt to transition us to the new key, if possible + Optional error = AttemptTransition(Secrets(i), currentValue, oldSecret, !!oldDigest); + if (error) + { + TC_LOG_MESSAGE_BODY("server.loading", errorLevel, "Your value of '{}' changed, but we cannot transition your database to the new value:\n{}", info.configKey, error->c_str()); + _secrets[i].state = Secret::LOAD_FAILED; + return; + } + + TC_LOG_INFO("server.loading", "Successfully transitioned database to new '{}' value.", info.configKey); + } + + if (currentValue) + { + _secrets[i].state = Secret::PRESENT; + _secrets[i].value = *currentValue; + } + else + _secrets[i].state = Secret::NOT_PRESENT; +} + +Optional SecretMgr::AttemptTransition(Secrets i, Optional const& newSecret, Optional const& oldSecret, bool hadOldSecret) const +{ + LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); + + switch (i) + { + case SECRET_TOTP_MASTER_KEY: + { + QueryResult result = LoginDatabase.Query("SELECT id, totp_secret FROM account"); + if (result) do + { + Field* fields = result->Fetch(); + if (fields[1].IsNull()) + continue; + + uint32 id = fields[0].GetUInt32(); + std::vector totpSecret = fields[1].GetBinary(); + + if (hadOldSecret) + { + if (!oldSecret) + return Trinity::StringFormat("Cannot decrypt old TOTP tokens - add config key '{}' to authserver.conf!", secret_info[i].oldKey); + + bool success = Trinity::Crypto::AEDecrypt(totpSecret, oldSecret->ToByteArray()); + if (!success) + return Trinity::StringFormat("Cannot decrypt old TOTP tokens - value of '{}' is incorrect for some users!", secret_info[i].oldKey); + } + + if (newSecret) + Trinity::Crypto::AEEncryptWithRandomIV(totpSecret, newSecret->ToByteArray()); + + LoginDatabasePreparedStatement* updateStmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET); + updateStmt->setBinary(0, totpSecret); + updateStmt->setUInt32(1, id); + trans->Append(updateStmt); + } while (result->NextRow()); + + break; + } + default: + return std::string("Unknown secret index - huh?"); + } + + if (hadOldSecret) + { + LoginDatabasePreparedStatement* deleteStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_SECRET_DIGEST); + deleteStmt->setUInt32(0, i); + trans->Append(deleteStmt); + } + + if (newSecret) + { + BigNumber salt; + salt.SetRand(128); + Optional hash = Trinity::Crypto::Argon2::Hash(newSecret->AsHexStr(), salt); + if (!hash) + return std::string("Failed to hash new secret"); + + LoginDatabasePreparedStatement* insertStmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_SECRET_DIGEST); + insertStmt->setUInt32(0, i); + insertStmt->setString(1, *hash); + trans->Append(insertStmt); + } + + LoginDatabase.CommitTransaction(trans); + return {}; +} diff --git a/src/server/shared/Secrets/SecretMgr.h b/src/server/shared/Secrets/SecretMgr.h new file mode 100644 index 0000000000..daa0592771 --- /dev/null +++ b/src/server/shared/Secrets/SecretMgr.h @@ -0,0 +1,75 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __TRINITY_SECRETMGR_H__ +#define __TRINITY_SECRETMGR_H__ + +#include "BigNumber.h" +#include "Common.h" +#include "LogCommon.h" +#include "Optional.h" +#include +#include +#include + +enum Secrets : uint32 +{ + SECRET_TOTP_MASTER_KEY = 0, + + // only add new indices right above this line + NUM_SECRETS +}; + +class TC_SHARED_API SecretMgr +{ + private: + SecretMgr() {} + ~SecretMgr() {} + + public: + SecretMgr(SecretMgr const&) = delete; + static SecretMgr* instance(); + + struct Secret + { + public: + explicit operator bool() const { return (state == PRESENT); } + BigNumber const& operator*() const { return value; } + BigNumber const* operator->() const { return &value; } + bool IsAvailable() const { return (state != NOT_LOADED_YET) && (state != LOAD_FAILED); } + + private: + std::mutex lock; + enum { NOT_LOADED_YET, LOAD_FAILED, NOT_PRESENT, PRESENT } state = NOT_LOADED_YET; + BigNumber value; + + friend class SecretMgr; + }; + + void Initialize(); + Secret const& GetSecret(Secrets i); + + private: + void AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock const&); + Optional AttemptTransition(Secrets i, Optional const& newSecret, Optional const& oldSecret, bool hadOldSecret) const; + + std::array _secrets; +}; + +#define sSecretMgr SecretMgr::instance() + +#endif diff --git a/src/server/authserver/Authentication/TOTP.h b/src/server/shared/SharedDefines.cpp similarity index 73% rename from src/server/authserver/Authentication/TOTP.h rename to src/server/shared/SharedDefines.cpp index 2c274a222b..fc47dedf9b 100644 --- a/src/server/authserver/Authentication/TOTP.h +++ b/src/server/shared/SharedDefines.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2018 TrinityCore +* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,15 +15,6 @@ * with this program. If not, see . */ -#ifndef _TOTP_H -#define _TOTP_H +#include "SharedDefines.h" -#include "openssl/hmac.h" -#include "openssl/evp.h" - -namespace TOTP -{ - unsigned int GenerateToken(char const* b32key); -} - -#endif +ServerProcessTypes Trinity::Impl::CurrentServerProcessHolder::_type = NUM_SERVER_PROCESS_TYPES; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/shared/SharedDefines.h similarity index 99% rename from src/server/game/Miscellaneous/SharedDefines.h rename to src/server/shared/SharedDefines.h index e7a687c8df..8ad096d5ff 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -4351,6 +4351,14 @@ enum UpdateCollisionHeightReason : uint8 UPDATE_COLLISION_HEIGHT_SCALE = 1 }; +enum ServerProcessTypes +{ + SERVER_PROCESS_AUTHSERVER = 0, + SERVER_PROCESS_WORLDSERVER = 1, + + NUM_SERVER_PROCESS_TYPES +}; + enum class MountResult : uint32 { InvalidMountee = 0, @@ -4501,6 +4509,19 @@ enum class SummonRaidMemberValidateReasonCode : int32 Offline = 5 }; +namespace Trinity +{ + namespace Impl + { + struct TC_SHARED_API CurrentServerProcessHolder + { + static ServerProcessTypes type() { return _type; } + static ServerProcessTypes _type; + }; + } +} +#define THIS_SERVER_PROCESS (Trinity::Impl::CurrentServerProcessHolder::type()) + #define MAX_CREATURE_SPELL_DATA_SLOT 4 #endif diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index 15581f45bf..7773667a6d 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -49,10 +49,7 @@ target_link_libraries(worldserver PUBLIC scripts game - ipc gsoap - libzmq - zmqpp ${READLINE_LIBRARY}) CollectIncludeDirectories( @@ -64,7 +61,6 @@ CollectIncludeDirectories( target_include_directories(worldserver PUBLIC ${PUBLIC_INCLUDES} - libzmq PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 73860ac635..5e6d7d38b8 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -24,7 +24,6 @@ #include "AsyncAcceptor.h" #include "Banner.h" #include "BattlegroundMgr.h" -#include "BattlenetServerManager.h" #include "BigNumber.h" #include "CliRunnable.h" #include "Configuration/Config.h" @@ -42,17 +41,19 @@ #include "OutdoorPvP/OutdoorPvPMgr.h" #include "ProcessPriority.h" #include "RASession.h" +#include "Realm.h" #include "Resolver.h" #include "ScriptLoader.h" #include "ScriptMgr.h" #include "ScriptReloadMgr.h" +#include "SecretMgr.h" +#include "SharedDefines.h" #include "TCSoap.h" #include "TerrainMgr.h" #include "ThreadPool.h" #include "World.h" #include "WorldSocket.h" #include "WorldSocketMgr.h" -#include "ZmqContext.h" #include #include #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) @@ -131,6 +132,7 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, s /// Launch the Trinity server extern int main(int argc, char** argv) { + Trinity::Impl::CurrentServerProcessHolder::_type = SERVER_PROCESS_WORLDSERVER; signal(SIGABRT, &Trinity::AbortHandler); Trinity::VerifyOsVersion(); @@ -299,6 +301,7 @@ extern int main(int argc, char** argv) }); // Initialize the World + sSecretMgr->Initialize(); sWorld->SetInitialWorldSettings(); std::shared_ptr mapManagementHandle(nullptr, [](void*) @@ -385,12 +388,8 @@ extern int main(int argc, char** argv) TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", coreStuckTime); } - sIpcContext->Initialize(); TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", GitRevision::GetFullVersion()); - sBattlenetServer.InitializeConnection(); - - sScriptMgr->OnStartup(); WorldUpdateLoop(); @@ -404,10 +403,6 @@ extern int main(int argc, char** argv) sScriptMgr->OnShutdown(); - sIpcContext->Close(); - - sBattlenetServer.CloseConnection(); - // set server offline LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm); diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp index 74b5fc28c8..2efee20689 100644 --- a/src/server/worldserver/RemoteAccess/RASession.cpp +++ b/src/server/worldserver/RemoteAccess/RASession.cpp @@ -20,6 +20,7 @@ #include "Config.h" #include "DatabaseEnv.h" #include "Log.h" +#include "SRP6.h" #include "Util.h" #include "World.h" #include @@ -153,27 +154,28 @@ bool RASession::CheckAccessLevel(const std::string& user) bool RASession::CheckPassword(const std::string& user, const std::string& pass) { std::string safe_user = user; + std::transform(safe_user.begin(), safe_user.end(), safe_user.begin(), ::toupper); Utf8ToUpperOnlyLatin(safe_user); std::string safe_pass = pass; Utf8ToUpperOnlyLatin(safe_pass); - - std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass); + std::transform(safe_pass.begin(), safe_pass.end(), safe_pass.begin(), ::toupper); LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME); stmt->setString(0, safe_user); - stmt->setString(1, hash); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (!result) + if (PreparedQueryResult result = LoginDatabase.Query(stmt)) { - TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str()); - return false; + Trinity::Crypto::SRP6::Salt salt = (*result)[0].GetBinary(); + Trinity::Crypto::SRP6::Verifier verifier = (*result)[1].GetBinary(); + + if (Trinity::Crypto::SRP6::CheckLogin(safe_user, safe_pass, salt, verifier)) + return true; } - return true; + TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str()); + return false; } bool RASession::ProcessCommand(std::string& command) diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 9c3d1022c8..8de8a30c67 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1312,6 +1312,25 @@ CacheDataQueries = 1 # ################################################################################################### +################################################################################################### +# CRYPTOGRAPHY +# +# TOTPMasterSecret +# Description: The key used by authserver to decrypt TOTP secrets from database storage. +# You only need to set this here if you plan to use the in-game 2FA +# management commands (.account 2fa), otherwise this can be left blank. +# +# The server will auto-detect if this does not match your authserver setting, +# in which case any commands reliant on the secret will be disabled. +# +# Default: +# + +TOTPMasterSecret = + +# +################################################################################################### + ################################################################################################### # UPDATE SETTINGS # @@ -4266,27 +4285,6 @@ AntiCheat.PendingMoveChangesTimeoutTime = 0 # ################################################################################################### -################################################################################################### -# IPC SETTINGS -# -# BnetServer.Address -# Description: Determines IP address of battle.net server to connect to. -# Default: 127.0.0.1 -# - -BnetServer.Address = 127.0.0.1 - -# -# BnetServer.Port -# Description: Determines port to use when connecting to battle.net server. -# Default: 1118 -# - -BnetServer.Port = 1118 - -# -################################################################################################### - ################################################################################################### # METRIC SETTINGS # diff --git a/src/tools/connection_patcher/Helper.cpp b/src/tools/connection_patcher/Helper.cpp index dab4f5c740..c518d167ae 100644 --- a/src/tools/connection_patcher/Helper.cpp +++ b/src/tools/connection_patcher/Helper.cpp @@ -17,10 +17,8 @@ */ #include "Helper.hpp" - -#include +#include "CryptoHash.h" #include - #include namespace Connection_Patcher @@ -48,11 +46,11 @@ namespace Connection_Patcher std::string GetFileChecksum(std::vector const& data) { - SHA256Hash h; + Trinity::Crypto::SHA256 h; h.UpdateData(data.data(), data.size()); h.Finalize(); - return ByteArrayToHexStr(h.GetDigest(), h.GetLength()); + return Trinity::Impl::ByteArrayToHexStr(h.GetDigest().data(), h.GetDigest().size()); } } }