diff options
author | George Hazan <ghazan@miranda.im> | 2020-03-26 20:45:32 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-03-26 20:45:32 +0300 |
commit | 57bf1c3a69d5b52f0f61172ddff50f24dbe8351e (patch) | |
tree | 9702e1a3e848bffb1ff4d71bbf9096b00d9c3596 /protocols/Tox/libtox | |
parent | c89b7af83f86699b0f7b2564d8c301c9f60aaf4e (diff) |
fixes #2286 (Update libtox to 0.2.11)
Diffstat (limited to 'protocols/Tox/libtox')
58 files changed, 2537 insertions, 2787 deletions
diff --git a/protocols/Tox/libtox/docs/CHANGELOG.md b/protocols/Tox/libtox/docs/CHANGELOG.md index d597dc7211..91c807793c 100644 --- a/protocols/Tox/libtox/docs/CHANGELOG.md +++ b/protocols/Tox/libtox/docs/CHANGELOG.md @@ -1,8 +1,68 @@ +## v0.2.11 + +### Merged PRs: + +- [#1403](https://github.com/TokTok/c-toxcore/pull/1403) Install libsodium from apt instead of from source. +- [#1402](https://github.com/TokTok/c-toxcore/pull/1402) Remove bazel build from Travis. +- [#1400](https://github.com/TokTok/c-toxcore/pull/1400) Disable bazel remote cache on CI. +- [#1399](https://github.com/TokTok/c-toxcore/pull/1399) Periodically try to send direct packets when connected by TCP. +- [#1398](https://github.com/TokTok/c-toxcore/pull/1398) Minor cleanup: use `assoc_timeout` function where possible. +- [#1397](https://github.com/TokTok/c-toxcore/pull/1397) Check that LOGGER macros are only called with string literals. +- [#1396](https://github.com/TokTok/c-toxcore/pull/1396) Make function defns match their decls regarding storage class. +- [#1395](https://github.com/TokTok/c-toxcore/pull/1395) Mark file-local function definitions as `static`. +- [#1394](https://github.com/TokTok/c-toxcore/pull/1394) Enable remote cache for bazel builds. +- [#1393](https://github.com/TokTok/c-toxcore/pull/1393) Add another bootstrap node to the bootstrap test. +- [#1392](https://github.com/TokTok/c-toxcore/pull/1392) Clear out old conference connections. +- [#1391](https://github.com/TokTok/c-toxcore/pull/1391) Minor cleanups in network code. +- [#1390](https://github.com/TokTok/c-toxcore/pull/1390) Avoid casting back and forth between void-ptr. +- [#1389](https://github.com/TokTok/c-toxcore/pull/1389) Standardise on having a comma at the end of enums. +- [#1388](https://github.com/TokTok/c-toxcore/pull/1388) Fix up comments a bit to start being more uniform. +- [#1387](https://github.com/TokTok/c-toxcore/pull/1387) Use rules_cc instead of native cc_library rules. +- [#1386](https://github.com/TokTok/c-toxcore/pull/1386) Use spdx license identifier instead of GPL blurb. +- [#1383](https://github.com/TokTok/c-toxcore/pull/1383) Pass packet ID to custom packet handlers. +- [#1382](https://github.com/TokTok/c-toxcore/pull/1382) Add a mutex lock/unlock inside every public API function. +- [#1381](https://github.com/TokTok/c-toxcore/pull/1381) Use `net_pack` instead of casting bytes to ints. +- [#1380](https://github.com/TokTok/c-toxcore/pull/1380) Disable FreeBSD travis build until it is fixed. +- [#1379](https://github.com/TokTok/c-toxcore/pull/1379) Update and fix FreeBSD setup on Travis-CI +- [#1378](https://github.com/TokTok/c-toxcore/pull/1378) Use ninja build system for the cmake-linux build. +- [#1376](https://github.com/TokTok/c-toxcore/pull/1376) Remove testing/av_test.c. +- [#1375](https://github.com/TokTok/c-toxcore/pull/1375) Add "cimple_test" to the bazel build. +- [#1374](https://github.com/TokTok/c-toxcore/pull/1374) Handle invite to existing conference +- [#1372](https://github.com/TokTok/c-toxcore/pull/1372) Upgrade bazel to 2.1.1. +- [#1371](https://github.com/TokTok/c-toxcore/pull/1371) Bump to astyle-3.1 in travis build. +- [#1370](https://github.com/TokTok/c-toxcore/pull/1370) use -1 rather than ~0 in unsigned integer types +- [#1362](https://github.com/TokTok/c-toxcore/pull/1362) Workaround for message number saving +- [#1358](https://github.com/TokTok/c-toxcore/pull/1358) Allow Bazel to rerun tests marked as flaky +- [#1352](https://github.com/TokTok/c-toxcore/pull/1352) Update tests to use a working bootstrap node +- [#1349](https://github.com/TokTok/c-toxcore/pull/1349) Fix tox-bootstrapd's README and update Dockerfile +- [#1347](https://github.com/TokTok/c-toxcore/pull/1347) Fix pthread_mutex_destroy getting too many arguments +- [#1346](https://github.com/TokTok/c-toxcore/pull/1346) Fix most TSAN failures +- [#1345](https://github.com/TokTok/c-toxcore/pull/1345) fix concurrency issues in mono_time +- [#1343](https://github.com/TokTok/c-toxcore/pull/1343) Fix TSAN failures in tests +- [#1334](https://github.com/TokTok/c-toxcore/pull/1334) fix missing group title length check +- [#1330](https://github.com/TokTok/c-toxcore/pull/1330) Force IPv4 for cirrus-ci tests +- [#1329](https://github.com/TokTok/c-toxcore/pull/1329) bump libsodium version in appveyor.yml +- [#1322](https://github.com/TokTok/c-toxcore/pull/1322) Clean-up of group.c code +- [#1321](https://github.com/TokTok/c-toxcore/pull/1321) Some small fixes to groups. +- [#1299](https://github.com/TokTok/c-toxcore/pull/1299) Add VScode folder to .gitignore +- [#1297](https://github.com/TokTok/c-toxcore/pull/1297) Use net_pack/unpack instead of host_to_net. + +### Closed issues: + +- [#1373](https://github.com/TokTok/c-toxcore/issues/1373) handle crashes after group invites +- [#1368](https://github.com/TokTok/c-toxcore/issues/1368) Are tox clients also open source +- [#1366](https://github.com/TokTok/c-toxcore/issues/1366) Generate a link for websites (Friendship and proxy) +- [#1354](https://github.com/TokTok/c-toxcore/issues/1354) Unstable Tests +- [#1316](https://github.com/TokTok/c-toxcore/issues/1316) Documentation claims toxav_iteration_interval is threadsafe but it's not +- [#1274](https://github.com/TokTok/c-toxcore/issues/1274) build error +- [#850](https://github.com/TokTok/c-toxcore/issues/850) GPG App Usage + ## v0.2.10 ### Merged PRs: +- [#1324](https://github.com/TokTok/c-toxcore/pull/1324) Release 0.2.10 - [#1320](https://github.com/TokTok/c-toxcore/pull/1320) add undef guard in tox_many_tcp_test - [#1314](https://github.com/TokTok/c-toxcore/pull/1314) Fix bazel build version at 0.22.0 for CI. - [#1311](https://github.com/TokTok/c-toxcore/pull/1311) Disable failing TCP server test @@ -13,6 +73,7 @@ ### Closed issues: +- [#1325](https://github.com/TokTok/c-toxcore/issues/1325) Question: ETA of v0.2.10? - [#1313](https://github.com/TokTok/c-toxcore/issues/1313) CirrusCI is failing and blocking PRs - [#1312](https://github.com/TokTok/c-toxcore/issues/1312) Onion client review - [#1306](https://github.com/TokTok/c-toxcore/issues/1306) Persistent conference's offline peer list always grows and never decreases @@ -139,6 +200,7 @@ - [#1214](https://github.com/TokTok/c-toxcore/issues/1214) Massive red shutdown of nodes - [#1201](https://github.com/TokTok/c-toxcore/issues/1201) Windows cross-compilation is broken +- [#961](https://github.com/TokTok/c-toxcore/issues/961) Can't send messages in persistent group chat - [#960](https://github.com/TokTok/c-toxcore/issues/960) Persistent groups don't work properly when using toxync bot - [#838](https://github.com/TokTok/c-toxcore/issues/838) How to get groupchat identifier? diff --git a/protocols/Tox/libtox/docs/LICENSE b/protocols/Tox/libtox/docs/LICENSE new file mode 100644 index 0000000000..10926e87f1 --- /dev/null +++ b/protocols/Tox/libtox/docs/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 3 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 <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. + diff --git a/protocols/Tox/libtox/docs/LICENSE.md b/protocols/Tox/libtox/docs/LICENSE.md deleted file mode 100644 index 1110e89874..0000000000 --- a/protocols/Tox/libtox/docs/LICENSE.md +++ /dev/null @@ -1,595 +0,0 @@ -GNU General Public License -========================== - -_Version 3, 29 June 2007_ -_Copyright © 2007 Free Software Foundation, Inc. <<http://fsf.org/>>_ - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -## Preamble - -The GNU General Public License is a free, copyleft license for software and other -kinds of works. - -The licenses for most software and other practical works are designed to take away -your freedom to share and change the works. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change all versions of a -program--to make sure it remains free software for all its users. We, the Free -Software Foundation, use the GNU General Public License for most of our software; it -applies also to any other work released this way by its authors. You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General -Public Licenses are designed to make sure that you have the freedom to distribute -copies of free software (and charge for them if you wish), that you receive source -code or can get it if you want it, that you can change the software or use pieces of -it in new free programs, and that you know you can do these things. - -To protect your rights, we need to prevent others from denying you these rights or -asking you to surrender the rights. Therefore, you have certain responsibilities if -you distribute copies of the software, or if you modify it: responsibilities to -respect the freedom of others. - -For example, if you distribute copies of such a program, whether gratis or for a fee, -you must pass on to the recipients the same freedoms that you received. You must make -sure that they, too, receive or can get the source code. And you must show them these -terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: **(1)** assert -copyright on the software, and **(2)** offer you this License giving you legal permission -to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains that there is -no warranty for this free software. For both users' and authors' sake, the GPL -requires that modified versions be marked as changed, so that their problems will not -be attributed erroneously to authors of previous versions. - -Some devices are designed to deny users access to install or run modified versions of -the software inside them, although the manufacturer can do so. This is fundamentally -incompatible with the aim of protecting users' freedom to change the software. The -systematic pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we have designed -this version of the GPL to prohibit the practice for those products. If such problems -arise substantially in other domains, we stand ready to extend this provision to -those domains in future versions of the GPL, as needed to protect the freedom of -users. - -Finally, every program is threatened constantly by software patents. States should -not allow patents to restrict development and use of software on general-purpose -computers, but in those that do, we wish to avoid the special danger that patents -applied to a free program could make it effectively proprietary. To prevent this, the -GPL assures that patents cannot be used to render the program non-free. - -The precise terms and conditions for copying, distribution and modification follow. - -## TERMS AND CONDITIONS - -### 0. Definitions - -“This License” refers to version 3 of the GNU General Public License. - -“Copyright” also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - -“The Program” refers to any copyrightable work licensed under this -License. Each licensee is addressed as “you”. “Licensees” and -“recipients” may be individuals or organizations. - -To “modify” a work means to copy from or adapt all or part of the work in -a fashion requiring copyright permission, other than the making of an exact copy. The -resulting work is called a “modified version” of the earlier work or a -work “based on” the earlier work. - -A “covered work” means either the unmodified Program or a work based on -the Program. - -To “propagate” a work means to do anything with it that, without -permission, would make you directly or secondarily liable for infringement under -applicable copyright law, except executing it on a computer or modifying a private -copy. Propagation includes copying, distribution (with or without modification), -making available to the public, and in some countries other activities as well. - -To “convey” a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through a computer -network, with no transfer of a copy, is not conveying. - -An interactive user interface displays “Appropriate Legal Notices” to the -extent that it includes a convenient and prominently visible feature that **(1)** -displays an appropriate copyright notice, and **(2)** tells the user that there is no -warranty for the work (except to the extent that warranties are provided), that -licensees may convey the work under this License, and how to view a copy of this -License. If the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -### 1. Source Code - -The “source code” for a work means the preferred form of the work for -making modifications to it. “Object code” means any non-source form of a -work. - -A “Standard Interface” means an interface that either is an official -standard defined by a recognized standards body, or, in the case of interfaces -specified for a particular programming language, one that is widely used among -developers working in that language. - -The “System Libraries” of an executable work include anything, other than -the work as a whole, that **(a)** is included in the normal form of packaging a Major -Component, but which is not part of that Major Component, and **(b)** serves only to -enable use of the work with that Major Component, or to implement a Standard -Interface for which an implementation is available to the public in source code form. -A “Major Component”, in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system (if any) on which -the executable work runs, or a compiler used to produce the work, or an object code -interpreter used to run it. - -The “Corresponding Source” for a work in object code form means all the -source code needed to generate, install, and (for an executable work) run the object -code and to modify the work, including scripts to control those activities. However, -it does not include the work's System Libraries, or general-purpose tools or -generally available free programs which are used unmodified in performing those -activities but which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for the work, and -the source code for shared libraries and dynamically linked subprograms that the work -is specifically designed to require, such as by intimate data communication or -control flow between those subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can regenerate -automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same work. - -### 2. Basic Permissions - -All rights granted under this License are granted for the term of copyright on the -Program, and are irrevocable provided the stated conditions are met. This License -explicitly affirms your unlimited permission to run the unmodified Program. The -output from running a covered work is covered by this License only if the output, -given its content, constitutes a covered work. This License acknowledges your rights -of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, without -conditions so long as your license otherwise remains in force. You may convey covered -works to others for the sole purpose of having them make modifications exclusively -for you, or provide you with facilities for running those works, provided that you -comply with the terms of this License in conveying all material for which you do not -control copyright. Those thus making or running the covered works for you must do so -exclusively on your behalf, under your direction and control, on terms that prohibit -them from making any copies of your copyrighted material outside their relationship -with you. - -Conveying under any other circumstances is permitted solely under the conditions -stated below. Sublicensing is not allowed; section 10 makes it unnecessary. - -### 3. Protecting Users' Legal Rights From Anti-Circumvention Law - -No covered work shall be deemed part of an effective technological measure under any -applicable law fulfilling obligations under article 11 of the WIPO copyright treaty -adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention -of such measures. - -When you convey a covered work, you waive any legal power to forbid circumvention of -technological measures to the extent such circumvention is effected by exercising -rights under this License with respect to the covered work, and you disclaim any -intention to limit operation or modification of the work as a means of enforcing, -against the work's users, your or third parties' legal rights to forbid circumvention -of technological measures. - -### 4. Conveying Verbatim Copies - -You may convey verbatim copies of the Program's source code as you receive it, in any -medium, provided that you conspicuously and appropriately publish on each copy an -appropriate copyright notice; keep intact all notices stating that this License and -any non-permissive terms added in accord with section 7 apply to the code; keep -intact all notices of the absence of any warranty; and give all recipients a copy of -this License along with the Program. - -You may charge any price or no price for each copy that you convey, and you may offer -support or warranty protection for a fee. - -### 5. Conveying Modified Source Versions - -You may convey a work based on the Program, or the modifications to produce it from -the Program, in the form of source code under the terms of section 4, provided that -you also meet all of these conditions: - -* **a)** The work must carry prominent notices stating that you modified it, and giving a -relevant date. -* **b)** The work must carry prominent notices stating that it is released under this -License and any conditions added under section 7. This requirement modifies the -requirement in section 4 to “keep intact all notices”. -* **c)** You must license the entire work, as a whole, under this License to anyone who -comes into possession of a copy. This License will therefore apply, along with any -applicable section 7 additional terms, to the whole of the work, and all its parts, -regardless of how they are packaged. This License gives no permission to license the -work in any other way, but it does not invalidate such permission if you have -separately received it. -* **d)** If the work has interactive user interfaces, each must display Appropriate Legal -Notices; however, if the Program has interactive interfaces that do not display -Appropriate Legal Notices, your work need not make them do so. - -A compilation of a covered work with other separate and independent works, which are -not by their nature extensions of the covered work, and which are not combined with -it such as to form a larger program, in or on a volume of a storage or distribution -medium, is called an “aggregate” if the compilation and its resulting -copyright are not used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work in an aggregate -does not cause this License to apply to the other parts of the aggregate. - -### 6. Conveying Non-Source Forms - -You may convey a covered work in object code form under the terms of sections 4 and -5, provided that you also convey the machine-readable Corresponding Source under the -terms of this License, in one of these ways: - -* **a)** Convey the object code in, or embodied in, a physical product (including a -physical distribution medium), accompanied by the Corresponding Source fixed on a -durable physical medium customarily used for software interchange. -* **b)** Convey the object code in, or embodied in, a physical product (including a -physical distribution medium), accompanied by a written offer, valid for at least -three years and valid for as long as you offer spare parts or customer support for -that product model, to give anyone who possesses the object code either **(1)** a copy of -the Corresponding Source for all the software in the product that is covered by this -License, on a durable physical medium customarily used for software interchange, for -a price no more than your reasonable cost of physically performing this conveying of -source, or **(2)** access to copy the Corresponding Source from a network server at no -charge. -* **c)** Convey individual copies of the object code with a copy of the written offer to -provide the Corresponding Source. This alternative is allowed only occasionally and -noncommercially, and only if you received the object code with such an offer, in -accord with subsection 6b. -* **d)** Convey the object code by offering access from a designated place (gratis or for -a charge), and offer equivalent access to the Corresponding Source in the same way -through the same place at no further charge. You need not require recipients to copy -the Corresponding Source along with the object code. If the place to copy the object -code is a network server, the Corresponding Source may be on a different server -(operated by you or a third party) that supports equivalent copying facilities, -provided you maintain clear directions next to the object code saying where to find -the Corresponding Source. Regardless of what server hosts the Corresponding Source, -you remain obligated to ensure that it is available for as long as needed to satisfy -these requirements. -* **e)** Convey the object code using peer-to-peer transmission, provided you inform -other peers where the object code and Corresponding Source of the work are being -offered to the general public at no charge under subsection 6d. - -A separable portion of the object code, whose source code is excluded from the -Corresponding Source as a System Library, need not be included in conveying the -object code work. - -A “User Product” is either **(1)** a “consumer product”, which -means any tangible personal property which is normally used for personal, family, or -household purposes, or **(2)** anything designed or sold for incorporation into a -dwelling. In determining whether a product is a consumer product, doubtful cases -shall be resolved in favor of coverage. For a particular product received by a -particular user, “normally used” refers to a typical or common use of -that class of product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected to use, the -product. A product is a consumer product regardless of whether the product has -substantial commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - -“Installation Information” for a User Product means any methods, -procedures, authorization keys, or other information required to install and execute -modified versions of a covered work in that User Product from a modified version of -its Corresponding Source. The information must suffice to ensure that the continued -functioning of the modified object code is in no case prevented or interfered with -solely because modification has been made. - -If you convey an object code work under this section in, or with, or specifically for -use in, a User Product, and the conveying occurs as part of a transaction in which -the right of possession and use of the User Product is transferred to the recipient -in perpetuity or for a fixed term (regardless of how the transaction is -characterized), the Corresponding Source conveyed under this section must be -accompanied by the Installation Information. But this requirement does not apply if -neither you nor any third party retains the ability to install modified object code -on the User Product (for example, the work has been installed in ROM). - -The requirement to provide Installation Information does not include a requirement to -continue to provide support service, warranty, or updates for a work that has been -modified or installed by the recipient, or for the User Product in which it has been -modified or installed. Access to a network may be denied when the modification itself -materially and adversely affects the operation of the network or violates the rules -and protocols for communication across the network. - -Corresponding Source conveyed, and Installation Information provided, in accord with -this section must be in a format that is publicly documented (and with an -implementation available to the public in source code form), and must require no -special password or key for unpacking, reading or copying. - -### 7. Additional Terms - -“Additional permissions” are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. Additional -permissions that are applicable to the entire Program shall be treated as though they -were included in this License, to the extent that they are valid under applicable -law. If additional permissions apply only to part of the Program, that part may be -used separately under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option remove any -additional permissions from that copy, or from any part of it. (Additional -permissions may be written to require their own removal in certain cases when you -modify the work.) You may place additional permissions on material, added by you to a -covered work, for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you add to a -covered work, you may (if authorized by the copyright holders of that material) -supplement the terms of this License with terms: - -* **a)** Disclaiming warranty or limiting liability differently from the terms of -sections 15 and 16 of this License; or -* **b)** Requiring preservation of specified reasonable legal notices or author -attributions in that material or in the Appropriate Legal Notices displayed by works -containing it; or -* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that -modified versions of such material be marked in reasonable ways as different from the -original version; or -* **d)** Limiting the use for publicity purposes of names of licensors or authors of the -material; or -* **e)** Declining to grant rights under trademark law for use of some trade names, -trademarks, or service marks; or -* **f)** Requiring indemnification of licensors and authors of that material by anyone -who conveys the material (or modified versions of it) with contractual assumptions of -liability to the recipient, for any liability that these contractual assumptions -directly impose on those licensors and authors. - -All other non-permissive additional terms are considered “further -restrictions” within the meaning of section 10. If the Program as you received -it, or any part of it, contains a notice stating that it is governed by this License -along with a term that is a further restriction, you may remove that term. If a -license document contains a further restriction but permits relicensing or conveying -under this License, you may add to a covered work material governed by the terms of -that license document, provided that the further restriction does not survive such -relicensing or conveying. - -If you add terms to a covered work in accord with this section, you must place, in -the relevant source files, a statement of the additional terms that apply to those -files, or a notice indicating where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the form of a -separately written license, or stated as exceptions; the above requirements apply -either way. - -### 8. Termination - -You may not propagate or modify a covered work except as expressly provided under -this License. Any attempt otherwise to propagate or modify it is void, and will -automatically terminate your rights under this License (including any patent licenses -granted under the third paragraph of section 11). - -However, if you cease all violation of this License, then your license from a -particular copyright holder is reinstated **(a)** provisionally, unless and until the -copyright holder explicitly and finally terminates your license, and **(b)** permanently, -if the copyright holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is reinstated permanently -if the copyright holder notifies you of the violation by some reasonable means, this -is the first time you have received notice of violation of this License (for any -work) from that copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the licenses of -parties who have received copies or rights from you under this License. If your -rights have been terminated and not permanently reinstated, you do not qualify to -receive new licenses for the same material under section 10. - -### 9. Acceptance Not Required for Having Copies - -You are not required to accept this License in order to receive or run a copy of the -Program. Ancillary propagation of a covered work occurring solely as a consequence of -using peer-to-peer transmission to receive a copy likewise does not require -acceptance. However, nothing other than this License grants you permission to -propagate or modify any covered work. These actions infringe copyright if you do not -accept this License. Therefore, by modifying or propagating a covered work, you -indicate your acceptance of this License to do so. - -### 10. Automatic Licensing of Downstream Recipients - -Each time you convey a covered work, the recipient automatically receives a license -from the original licensors, to run, modify and propagate that work, subject to this -License. You are not responsible for enforcing compliance by third parties with this -License. - -An “entity transaction” is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an organization, or -merging organizations. If propagation of a covered work results from an entity -transaction, each party to that transaction who receives a copy of the work also -receives whatever licenses to the work the party's predecessor in interest had or -could give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if the predecessor -has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the rights granted or -affirmed under this License. For example, you may not impose a license fee, royalty, -or other charge for exercise of rights granted under this License, and you may not -initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging -that any patent claim is infringed by making, using, selling, offering for sale, or -importing the Program or any portion of it. - -### 11. Patents - -A “contributor” is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The work thus -licensed is called the contributor's “contributor version”. - -A contributor's “essential patent claims” are all patent claims owned or -controlled by the contributor, whether already acquired or hereafter acquired, that -would be infringed by some manner, permitted by this License, of making, using, or -selling its contributor version, but do not include claims that would be infringed -only as a consequence of further modification of the contributor version. For -purposes of this definition, “control” includes the right to grant patent -sublicenses in a manner consistent with the requirements of this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free patent license -under the contributor's essential patent claims, to make, use, sell, offer for sale, -import and otherwise run, modify and propagate the contents of its contributor -version. - -In the following three paragraphs, a “patent license” is any express -agreement or commitment, however denominated, not to enforce a patent (such as an -express permission to practice a patent or covenant not to sue for patent -infringement). To “grant” such a patent license to a party means to make -such an agreement or commitment not to enforce a patent against the party. - -If you convey a covered work, knowingly relying on a patent license, and the -Corresponding Source of the work is not available for anyone to copy, free of charge -and under the terms of this License, through a publicly available network server or -other readily accessible means, then you must either **(1)** cause the Corresponding -Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the -patent license for this particular work, or **(3)** arrange, in a manner consistent with -the requirements of this License, to extend the patent license to downstream -recipients. “Knowingly relying” means you have actual knowledge that, but -for the patent license, your conveying the covered work in a country, or your -recipient's use of the covered work in a country, would infringe one or more -identifiable patents in that country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or arrangement, you -convey, or propagate by procuring conveyance of, a covered work, and grant a patent -license to some of the parties receiving the covered work authorizing them to use, -propagate, modify or convey a specific copy of the covered work, then the patent -license you grant is automatically extended to all recipients of the covered work and -works based on it. - -A patent license is “discriminatory” if it does not include within the -scope of its coverage, prohibits the exercise of, or is conditioned on the -non-exercise of one or more of the rights that are specifically granted under this -License. You may not convey a covered work if you are a party to an arrangement with -a third party that is in the business of distributing software, under which you make -payment to the third party based on the extent of your activity of conveying the -work, and under which the third party grants, to any of the parties who would receive -the covered work from you, a discriminatory patent license **(a)** in connection with -copies of the covered work conveyed by you (or copies made from those copies), or **(b)** -primarily for and in connection with specific products or compilations that contain -the covered work, unless you entered into that arrangement, or that patent license -was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting any implied -license or other defenses to infringement that may otherwise be available to you -under applicable patent law. - -### 12. No Surrender of Others' Freedom - -If conditions are imposed on you (whether by court order, agreement or otherwise) -that contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot convey a covered work so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not convey it at all. For example, if you -agree to terms that obligate you to collect a royalty for further conveying from -those to whom you convey the Program, the only way you could satisfy both those terms -and this License would be to refrain entirely from conveying the Program. - -### 13. Use with the GNU Affero General Public License - -Notwithstanding any other provision of this License, you have permission to link or -combine any covered work with a work licensed under version 3 of the GNU Affero -General Public License into a single combined work, and to convey the resulting work. -The terms of this License will continue to apply to the part which is the covered -work, but the special requirements of the GNU Affero General Public License, section -13, concerning interaction through a network will apply to the combination as such. - -### 14. Revised Versions of this License - -The Free Software Foundation may publish revised and/or new versions of the GNU -General Public License from time to time. Such new versions will be similar in spirit -to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies that -a certain numbered version of the GNU General Public License “or any later -version” applies to it, you have the option of following the terms and -conditions either of that numbered version or of any later version published by the -Free Software Foundation. If the Program does not specify a version number of the GNU -General Public License, you may choose any version ever published by the Free -Software Foundation. - -If the Program specifies that a proxy can decide which future versions of the GNU -General Public License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the Program. - -Later license versions may give you additional or different permissions. However, no -additional obligations are imposed on any author or copyright holder as a result of -your choosing to follow a later version. - -### 15. Disclaimer of Warranty - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE -QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -### 16. Limitation of Liability - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY -COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS -PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, -INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE -OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE -WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -### 17. Interpretation of Sections 15 and 16 - -If the disclaimer of warranty and limitation of liability provided above cannot be -given local legal effect according to their terms, reviewing courts shall apply local -law that most closely approximates an absolute waiver of all civil liability in -connection with the Program, unless a warranty or assumption of liability accompanies -a copy of the Program in return for a fee. - -_END OF TERMS AND CONDITIONS_ - -## How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to -the public, the best way to achieve this is to make it free software which everyone -can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them -to the start of each source file to most effectively state the exclusion of warranty; -and each file should have at least the “copyright” line and a pointer to -where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - 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 3 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 <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice like this -when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type 'show c' for details. - -The hypothetical commands `show w` and `show c` should show the appropriate parts of -the General Public License. Of course, your program's commands might be different; -for a GUI interface, you would use an “about box”. - -You should also get your employer (if you work as a programmer) or school, if any, to -sign a “copyright disclaimer” for the program, if necessary. For more -information on this, and how to apply and follow the GNU GPL, see -<<http://www.gnu.org/licenses/>>. - -The GNU General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may consider it -more useful to permit linking proprietary applications with the library. If this is -what you want to do, use the GNU Lesser General Public License instead of this -License. But first, please read -<<http://www.gnu.org/philosophy/why-not-lgpl.html>>. diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c index 79925552ac..191ebc0ed5 100644 --- a/protocols/Tox/libtox/src/toxcore/DHT.c +++ b/protocols/Tox/libtox/src/toxcore/DHT.c @@ -1,25 +1,10 @@ -/* - * An implementation of the DHT as seen in docs/updates/DHT.md +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * An implementation of the DHT as seen in docs/updates/DHT.md */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -188,6 +173,11 @@ const uint8_t *dht_get_friend_public_key(const DHT *dht, uint32_t friend_num) return dht->friends_list[friend_num].public_key; } +static bool assoc_timeout(const Mono_Time *mono_time, const IPPTsPng *assoc) +{ + return mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT); +} + /* Compares pk1 and pk2 with pk. * * return 0 if both are same distance. @@ -247,7 +237,7 @@ static unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2) void get_shared_key(const Mono_Time *mono_time, Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t *secret_key, const uint8_t *public_key) { - uint32_t num = ~0; + uint32_t num = -1; uint32_t curr = 0; for (uint32_t i = 0; i < MAX_KEYS_PER_SLOT; ++i) { @@ -625,7 +615,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed return num; } -/* Find index of ##type with public_key equal to pk. +/* Find index in an array with public_key equal to pk. * * return index or UINT32_MAX if not found. */ @@ -793,6 +783,7 @@ static uint8_t hardening_correct(const Hardening *h) { return h->routes_requests_ok + (h->send_nodes_ok << 1) + (h->testing_requests << 2); } + /* * helper for get_close_nodes(). argument list is a monster :D */ @@ -814,7 +805,7 @@ static void get_close_nodes_inner(const Mono_Time *mono_time, const uint8_t *pub continue; } - const IPPTsPng *ipptp = nullptr; + const IPPTsPng *ipptp; if (net_family_is_ipv4(sa_family)) { ipptp = &client->assoc4; @@ -827,7 +818,7 @@ static void get_close_nodes_inner(const Mono_Time *mono_time, const uint8_t *pub } /* node not in a good condition? */ - if (mono_time_is_timeout(mono_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) { + if (assoc_timeout(mono_time, ipptp)) { continue; } @@ -901,11 +892,6 @@ typedef struct DHT_Cmp_data { Client_data entry; } DHT_Cmp_data; -static bool assoc_timeout(const Mono_Time *mono_time, const IPPTsPng *assoc) -{ - return mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT); -} - static bool incorrect_hardening(const IPPTsPng *assoc) { return hardening_correct(&assoc->hardening) != HARDENING_ALL_OK; @@ -967,8 +953,8 @@ static int cmp_dht_entry(const void *a, const void *b) static unsigned int store_node_ok(const Client_data *client, const Mono_Time *mono_time, const uint8_t *public_key, const uint8_t *comp_public_key) { - return (mono_time_is_timeout(mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) - && mono_time_is_timeout(mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) + return (assoc_timeout(mono_time, &client->assoc4) + && assoc_timeout(mono_time, &client->assoc6)) || id_closest(comp_public_key, client->public_key, public_key) == 2; } @@ -1074,8 +1060,8 @@ static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, bo * index is left as >= LCLIENT_LENGTH */ Client_data *const client = &dht->close_clientlist[(index * LCLIENT_NODES) + i]; - if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) || - !mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(dht->mono_time, &client->assoc4) || + !assoc_timeout(dht->mono_time, &client->assoc6)) { continue; } @@ -1111,7 +1097,7 @@ static bool is_pk_in_client_list(const Client_data *list, unsigned int client_li ? &list[index].assoc4 : &list[index].assoc6; - return !mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT); + return !assoc_timeout(mono_time, assoc); } static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port) @@ -1127,7 +1113,7 @@ static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_ } /* Check if the node obtained with a get_nodes with public_key should be pinged. - * NOTE: for best results call it after addto_lists; + * NOTE: for best results call it after addto_lists. * * return false if the node should not be pinged. * return true if it should. @@ -1690,7 +1676,7 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port) for (const IPPTsPng * const *it = assocs; *it; ++it) { const IPPTsPng *const assoc = *it; - if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(dht->mono_time, assoc)) { *ip_port = assoc->ip_port; return 1; } @@ -1731,7 +1717,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co } /* If node is good. */ - if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(dht->mono_time, assoc)) { client_list[num_nodes] = client; assoc_list[num_nodes] = assoc; ++num_nodes; @@ -1932,8 +1918,8 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n } if (id_equal(client->public_key, dht_friend->public_key)) { - if (!mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT) - || !mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(dht->mono_time, &client->assoc6) + || !assoc_timeout(dht->mono_time, &client->assoc4)) { return 0; /* direct connectivity */ } } @@ -2403,7 +2389,7 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num) const IPPTsPng *const temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family); if (temp) { - if (!mono_time_is_timeout(dht->mono_time, temp->timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(dht->mono_time, temp)) { ++counter; } } @@ -2534,11 +2520,11 @@ static uint16_t list_nodes(Client_data *list, size_t length, const Mono_Time *mo for (size_t i = length; i != 0; --i) { const IPPTsPng *assoc = nullptr; - if (!mono_time_is_timeout(mono_time, list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(mono_time, &list[i - 1].assoc4)) { assoc = &list[i - 1].assoc4; } - if (!mono_time_is_timeout(mono_time, list[i - 1].assoc6.timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(mono_time, &list[i - 1].assoc6)) { if (assoc == nullptr) { assoc = &list[i - 1].assoc6; } else if (random_u08() % 2) { @@ -2610,7 +2596,7 @@ static void do_hardening(DHT *dht) sa_family = net_family_ipv6; } - if (mono_time_is_timeout(dht->mono_time, cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) { + if (assoc_timeout(dht->mono_time, cur_iptspng)) { continue; } @@ -2976,8 +2962,8 @@ bool dht_isconnected(const DHT *dht) for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { const Client_data *const client = &dht->close_clientlist[i]; - if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) || - !mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { + if (!assoc_timeout(dht->mono_time, &client->assoc4) || + !assoc_timeout(dht->mono_time, &client->assoc6)) { return true; } } @@ -2993,12 +2979,12 @@ bool dht_non_lan_connected(const DHT *dht) for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { const Client_data *const client = &dht->close_clientlist[i]; - if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) + if (!assoc_timeout(dht->mono_time, &client->assoc4) && !ip_is_lan(client->assoc4.ip_port.ip)) { return true; } - if (!mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT) + if (!assoc_timeout(dht->mono_time, &client->assoc6) && !ip_is_lan(client->assoc6.ip_port.ip)) { return true; } diff --git a/protocols/Tox/libtox/src/toxcore/DHT.h b/protocols/Tox/libtox/src/toxcore/DHT.h index 5feb74d275..13f7ce20ed 100644 --- a/protocols/Tox/libtox/src/toxcore/DHT.h +++ b/protocols/Tox/libtox/src/toxcore/DHT.h @@ -1,25 +1,10 @@ -/* - * An implementation of the DHT as seen in docs/updates/DHT.md +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * An implementation of the DHT as seen in docs/updates/DHT.md */ #ifndef C_TOXCORE_TOXCORE_DHT_H #define C_TOXCORE_TOXCORE_DHT_H @@ -286,8 +271,6 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count); * ip must be 4 bytes long. * port must be 2 bytes long. * - * int dht_getfriendip(DHT *dht, uint8_t *public_key, IP_Port *ip_port); - * * return -1, -- if public_key does NOT refer to a friend * return 0, -- if public_key refers to a friend and we failed to find the friend (yet) * return 1, ip if public_key refers to a friend and we found him diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h index 31d6a5f64b..5c25b67b98 100644 --- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h @@ -1,26 +1,11 @@ %{ -/* - * LAN discovery implementation. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * LAN discovery implementation. */ #ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H #define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c index 1137fc3d2f..c3d060145f 100644 --- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c @@ -1,25 +1,10 @@ -/* - * LAN discovery implementation. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * LAN discovery implementation. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -72,8 +57,8 @@ static void fetch_broadcast_info(uint16_t port) } } - /* We copy these to the static variables broadcast_* only at the end of fetch_broadcast_info(). - * The intention is to ensure that even if multiple threads enter fetch_broadcast_info() concurrently, only valid + /* We copy these to the static variables `broadcast_*` only at the end of `fetch_broadcast_info()`. + * The intention is to ensure that even if multiple threads enter `fetch_broadcast_info()` concurrently, only valid * interfaces will be set to be broadcast to. * */ int count = 0; @@ -138,7 +123,7 @@ static void fetch_broadcast_info(uint16_t port) static void fetch_broadcast_info(uint16_t port) { /* Not sure how many platforms this will run on, - * so it's wrapped in __linux for now. + * so it's wrapped in `__linux__` for now. * Definitely won't work like this on Windows... */ broadcast_count = 0; @@ -161,15 +146,15 @@ static void fetch_broadcast_info(uint16_t port) return; } - /* We copy these to the static variables broadcast_* only at the end of fetch_broadcast_info(). - * The intention is to ensure that even if multiple threads enter fetch_broadcast_info() concurrently, only valid + /* We copy these to the static variables `broadcast_*` only at the end of `fetch_broadcast_info()`. + * The intention is to ensure that even if multiple threads enter `fetch_broadcast_info()` concurrently, only valid * interfaces will be set to be broadcast to. * */ int count = 0; IP_Port ip_ports[MAX_INTERFACES]; - /* ifc.ifc_len is set by the ioctl() to the actual length used; - * on usage of the complete array the call should be repeated with + /* `ifc.ifc_len` is set by the `ioctl()` to the actual length used. + * On usage of the complete array the call should be repeated with * a larger array, not done (640kB and 16 interfaces shall be * enough, for everybody!) */ @@ -186,7 +171,7 @@ static void fetch_broadcast_info(uint16_t port) continue; } - struct sockaddr_in *sock4 = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; + struct sockaddr_in *sock4 = (struct sockaddr_in *)(void *)&i_faces[i].ifr_broadaddr; if (count >= MAX_INTERFACES) { break; @@ -254,8 +239,8 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast) if (net_family_is_ipv6(family_socket)) { if (net_family_is_ipv6(family_broadcast)) { ip.family = net_family_ipv6; - /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ - /* FE80::*: MUST be exact, for that we would need to look over all + /* `FF02::1` is - according to RFC 4291 - multicast all-nodes link-local */ + /* `FE80::*:` MUST be exact, for that we would need to look over all * interfaces and check in which status they are */ ip.ip.v6.uint8[ 0] = 0xFF; ip.ip.v6.uint8[ 1] = 0x02; @@ -343,8 +328,8 @@ bool ip_is_lan(IP ip) } if (net_family_is_ipv6(ip.family)) { - /* autogenerated for each interface: FE80::* (up to FEBF::*) - FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ + /* autogenerated for each interface: `FE80::*` (up to `FEBF::*`) + `FF02::1` is - according to RFC 4291 - multicast all-nodes link-local */ if (((ip.ip.v6.uint8[0] == 0xFF) && (ip.ip.v6.uint8[1] < 3) && (ip.ip.v6.uint8[15] == 1)) || ((ip.ip.v6.uint8[0] == 0xFE) && ((ip.ip.v6.uint8[1] & 0xC0) == 0x80))) { return true; diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h index 1364a28078..7e049b9961 100644 --- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h @@ -1,25 +1,10 @@ -/* - * LAN discovery implementation. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * LAN discovery implementation. */ #ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H #define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c index ae2d1d3bb0..ddd04518a5 100644 --- a/protocols/Tox/libtox/src/toxcore/Messenger.c +++ b/protocols/Tox/libtox/src/toxcore/Messenger.c @@ -1,25 +1,10 @@ -/* - * An implementation of a simple text chat only messenger on the tox network core. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * An implementation of a simple text chat only messenger on the tox network core. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -140,7 +125,7 @@ static uint16_t address_checksum(const uint8_t *address, uint32_t len) return check; } -/* Format: [real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] +/* Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]` * * return FRIEND_ADDRESS_SIZE byte address to give to others. */ @@ -458,6 +443,8 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber) bool direct_connected = 0; unsigned int num_online_relays = 0; int crypt_conn_id = friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id); + + // FIXME(sudden6): handle return value crypto_connection_status(m->net_crypto, crypt_conn_id, &direct_connected, &num_online_relays); if (direct_connected) { @@ -984,12 +971,10 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_ m->friendlist[friendnumber].friendcon_id), packet, length + 1, congestion_control) != -1; } -/**********CONFERENCES************/ +/** CONFERENCES */ /* Set the callback for conference invites. - * - * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) */ void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function) { @@ -1007,12 +992,10 @@ int send_conference_invite_packet(const Messenger *m, int32_t friendnumber, cons return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_CONFERENCE, data, length, 0); } -/****************FILE SENDING*****************/ +/** FILE SENDING */ /* Set the callback for file send requests. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint32_t filetype, uint64_t filesize, uint8_t *filename, size_t filename_length, void *userdata) */ void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function) { @@ -1020,9 +1003,6 @@ void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function) } /* Set the callback for file control requests. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, unsigned int control_type, void *userdata) - * */ void callback_file_control(Messenger *m, m_file_recv_control_cb *function) { @@ -1030,9 +1010,6 @@ void callback_file_control(Messenger *m, m_file_recv_control_cb *function) } /* Set the callback for file data. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, uint8_t *data, size_t length, void *userdata) - * */ void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function) { @@ -1040,9 +1017,6 @@ void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function) } /* Set the callback for file request chunk. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata) - * */ void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function) { @@ -1120,8 +1094,7 @@ static int file_sendrequest(const Messenger *m, int32_t friendnumber, uint8_t fi packet[0] = filenumber; file_type = net_htonl(file_type); memcpy(packet + 1, &file_type, sizeof(file_type)); - host_to_net((uint8_t *)&filesize, sizeof(filesize)); - memcpy(packet + 1 + sizeof(file_type), &filesize, sizeof(filesize)); + net_pack_u64(packet + 1 + sizeof(file_type), filesize); memcpy(packet + 1 + sizeof(file_type) + sizeof(filesize), file_id, FILE_ID_LENGTH); if (filename_length) { @@ -1360,10 +1333,10 @@ int file_seek(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin return -6; } - uint64_t sending_pos = position; - host_to_net((uint8_t *)&sending_pos, sizeof(sending_pos)); + uint8_t sending_pos[sizeof(uint64_t)]; + net_pack_u64(sending_pos, position); - if (send_file_control_packet(m, friendnumber, 1, file_number, FILECONTROL_SEEK, (uint8_t *)&sending_pos, + if (send_file_control_packet(m, friendnumber, 1, file_number, FILECONTROL_SEEK, sending_pos, sizeof(sending_pos))) { ft->transferred = position; } else { @@ -1758,8 +1731,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv return -1; } - memcpy(&position, data, sizeof(position)); - net_to_host((uint8_t *) &position, sizeof(position)); + net_unpack_u64(data, &position); if (position >= ft->size) { LOGGER_DEBUG(m->log, @@ -1781,11 +1753,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv } } -/**************************************/ - /* Set the callback for msi packets. - * - * Function(Messenger *m, int friendnumber, uint8_t *data, uint16_t length, void *userdata) */ void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata) { @@ -1824,7 +1792,7 @@ static int m_handle_lossy_packet(void *object, int friend_num, const uint8_t *pa } if (m->lossy_packethandler) { - m->lossy_packethandler(m, friend_num, packet, length, userdata); + m->lossy_packethandler(m, friend_num, packet[0], packet, length, userdata); } return 1; @@ -1900,7 +1868,7 @@ static int handle_custom_lossless_packet(void *object, int friend_num, const uin } if (m->lossless_packethandler) { - m->lossless_packethandler(m, friend_num, packet, length, userdata); + m->lossless_packethandler(m, friend_num, packet[0], packet, length, userdata); } return 1; @@ -2325,8 +2293,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le memcpy(&file_type, data + 1, sizeof(file_type)); file_type = net_ntohl(file_type); - memcpy(&filesize, data + 1 + sizeof(uint32_t), sizeof(filesize)); - net_to_host((uint8_t *) &filesize, sizeof(filesize)); + net_unpack_u64(data + 1 + sizeof(uint32_t), &filesize); struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; if (ft->status != FILESTATUS_NONE) { @@ -2753,7 +2720,7 @@ struct Saved_Friend { uint16_t statusmessage_length; uint8_t userstatus; uint32_t friendrequest_nospam; - uint64_t last_seen_time; + uint8_t last_seen_time[sizeof(uint64_t)]; }; static uint32_t friend_size(void) @@ -2778,7 +2745,7 @@ static uint32_t friend_size(void) VALUE_MEMBER(userstatus); data += 3; // padding VALUE_MEMBER(friendrequest_nospam); - VALUE_MEMBER(last_seen_time); + ARRAY_MEMBER(last_seen_time); #undef VALUE_MEMBER #undef ARRAY_MEMBER @@ -2812,7 +2779,7 @@ static uint8_t *friend_save(const struct Saved_Friend *temp, uint8_t *data) VALUE_MEMBER(userstatus); data += 3; // padding VALUE_MEMBER(friendrequest_nospam); - VALUE_MEMBER(last_seen_time); + ARRAY_MEMBER(last_seen_time); #undef VALUE_MEMBER #undef ARRAY_MEMBER @@ -2847,7 +2814,7 @@ static const uint8_t *friend_load(struct Saved_Friend *temp, const uint8_t *data VALUE_MEMBER(userstatus); data += 3; // padding VALUE_MEMBER(friendrequest_nospam); - VALUE_MEMBER(last_seen_time); + ARRAY_MEMBER(last_seen_time); #undef VALUE_MEMBER #undef ARRAY_MEMBER @@ -3026,10 +2993,7 @@ static uint8_t *friends_list_save(const Messenger *m, uint8_t *data) temp.statusmessage_length = net_htons(m->friendlist[i].statusmessage_length); temp.userstatus = m->friendlist[i].userstatus; - uint8_t last_seen_time[sizeof(uint64_t)]; - memcpy(last_seen_time, &m->friendlist[i].last_seen_time, sizeof(uint64_t)); - host_to_net(last_seen_time, sizeof(uint64_t)); - memcpy(&temp.last_seen_time, last_seen_time, sizeof(uint64_t)); + net_pack_u64(temp.last_seen_time, m->friendlist[i].last_seen_time); } uint8_t *next_data = friend_save(&temp, cur_data); @@ -3077,10 +3041,7 @@ static State_Load_Status friends_list_load(Messenger *m, const uint8_t *data, ui setfriendname(m, fnum, temp.name, net_ntohs(temp.name_length)); set_friend_statusmessage(m, fnum, temp.statusmessage, net_ntohs(temp.statusmessage_length)); set_friend_userstatus(m, fnum, temp.userstatus); - uint8_t last_seen_time[sizeof(uint64_t)]; - memcpy(last_seen_time, &temp.last_seen_time, sizeof(uint64_t)); - net_to_host(last_seen_time, sizeof(uint64_t)); - memcpy(&m->friendlist[fnum].last_seen_time, last_seen_time, sizeof(uint64_t)); + net_unpack_u64(temp.last_seen_time, &m->friendlist[fnum].last_seen_time); } else if (temp.status != 0) { /* TODO(irungentoo): This is not a good way to do this. */ uint8_t address[FRIEND_ADDRESS_SIZE]; diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.h b/protocols/Tox/libtox/src/toxcore/Messenger.h index a3376e237a..74c19e09c8 100644 --- a/protocols/Tox/libtox/src/toxcore/Messenger.h +++ b/protocols/Tox/libtox/src/toxcore/Messenger.h @@ -1,26 +1,11 @@ -/* - * An implementation of a simple text chat only messenger on the tox network - * core. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * An implementation of a simple text chat only messenger on the tox network + * core. */ #ifndef C_TOXCORE_TOXCORE_MESSENGER_H #define C_TOXCORE_TOXCORE_MESSENGER_H @@ -34,7 +19,7 @@ #define MAX_NAME_LENGTH 128 /* TODO(irungentoo): this must depend on other variable. */ #define MAX_STATUSMESSAGE_LENGTH 1007 -/* Used for TCP relays in Messenger struct (may need to be % 2 == 0)*/ +/* Used for TCP relays in Messenger struct (may need to be `% 2 == 0`)*/ #define NUM_SAVED_TCP_RELAYS 8 /* This cannot be bigger than 256 */ #define MAX_CONCURRENT_FILE_PIPES 256 @@ -48,7 +33,7 @@ typedef enum Message_Type { MESSAGE_NORMAL, - MESSAGE_ACTION + MESSAGE_ACTION, } Message_Type; typedef struct Messenger Messenger; @@ -113,7 +98,7 @@ typedef enum Friend_Add_Error { FAERR_ALREADYSENT = -4, FAERR_BADCHECKSUM = -6, FAERR_SETNEWNOSPAM = -7, - FAERR_NOMEM = -8 + FAERR_NOMEM = -8, } Friend_Add_Error; @@ -124,7 +109,7 @@ typedef enum Connection_Status { CONNECTION_NONE, CONNECTION_TCP, CONNECTION_UDP, - CONNECTION_UNKNOWN + CONNECTION_UNKNOWN, } Connection_Status; /* USERSTATUS - @@ -135,7 +120,7 @@ typedef enum Userstatus { USERSTATUS_NONE, USERSTATUS_AWAY, USERSTATUS_BUSY, - USERSTATUS_INVALID + USERSTATUS_INVALID, } Userstatus; #define FILE_ID_LENGTH 32 @@ -155,26 +140,26 @@ typedef enum Filestatus { FILESTATUS_NOT_ACCEPTED, FILESTATUS_TRANSFERRING, // FILESTATUS_BROKEN, - FILESTATUS_FINISHED + FILESTATUS_FINISHED, } Filestatus; typedef enum File_Pause { FILE_PAUSE_NOT, FILE_PAUSE_US, FILE_PAUSE_OTHER, - FILE_PAUSE_BOTH + FILE_PAUSE_BOTH, } File_Pause; typedef enum Filecontrol { FILECONTROL_ACCEPT, FILECONTROL_PAUSE, FILECONTROL_KILL, - FILECONTROL_SEEK + FILECONTROL_SEEK, } Filecontrol; typedef enum Filekind { FILEKIND_DATA, - FILEKIND_AVATAR + FILEKIND_AVATAR, } Filekind; @@ -200,10 +185,10 @@ typedef void m_file_chunk_request_cb(Messenger *m, uint32_t friend_number, uint3 size_t length, void *user_data); typedef void m_file_recv_chunk_cb(Messenger *m, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, size_t length, void *user_data); -typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, size_t length, - void *user_data); -typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, size_t length, - void *user_data); +typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, uint8_t packet_id, const uint8_t *data, + size_t length, void *user_data); +typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, uint8_t packet_id, const uint8_t *data, + size_t length, void *user_data); typedef void m_friend_connectionstatuschange_internal_cb(Messenger *m, uint32_t friend_number, uint8_t connection_status, void *user_data); typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length, @@ -315,7 +300,7 @@ struct Messenger { Messenger_Options options; }; -/* Format: [real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] +/* Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]` * * return FRIEND_ADDRESS_SIZE byte address to give to others. */ @@ -505,40 +490,40 @@ int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing); int m_get_istyping(const Messenger *m, int32_t friendnumber); /* Set the function that will be executed when a friend request is received. - * Function format is function(uint8_t * public_key, uint8_t * data, size_t length) + * Function format is `function(uint8_t * public_key, uint8_t * data, size_t length)` */ void m_callback_friendrequest(Messenger *m, m_friend_request_cb *function); /* Set the function that will be executed when a message from a friend is received. - * Function format is: function(uint32_t friendnumber, unsigned int type, uint8_t * message, uint32_t length) + * Function format is: `function(uint32_t friendnumber, unsigned int type, uint8_t * message, uint32_t length)` */ void m_callback_friendmessage(Messenger *m, m_friend_message_cb *function); /* Set the callback for name changes. - * Function(uint32_t friendnumber, uint8_t *newname, size_t length) + * `Function(uint32_t friendnumber, uint8_t *newname, size_t length)` * You are not responsible for freeing newname. */ void m_callback_namechange(Messenger *m, m_friend_name_cb *function); /* Set the callback for status message changes. - * Function(uint32_t friendnumber, uint8_t *newstatus, size_t length) + * `Function(uint32_t friendnumber, uint8_t *newstatus, size_t length)` * * You are not responsible for freeing newstatus */ void m_callback_statusmessage(Messenger *m, m_friend_status_message_cb *function); /* Set the callback for status type changes. - * Function(uint32_t friendnumber, Userstatus kind) + * `Function(uint32_t friendnumber, Userstatus kind)` */ void m_callback_userstatus(Messenger *m, m_friend_status_cb *function); /* Set the callback for typing changes. - * Function(uint32_t friendnumber, uint8_t is_typing) + * `Function(uint32_t friendnumber, uint8_t is_typing)` */ void m_callback_typingchange(Messenger *m, m_friend_typing_cb *function); /* Set the callback for read receipts. - * Function(uint32_t friendnumber, uint32_t receipt) + * `Function(uint32_t friendnumber, uint32_t receipt)` * * If you are keeping a record of returns from m_sendmessage, * receipt might be one of those values, meaning the message @@ -549,14 +534,14 @@ void m_callback_typingchange(Messenger *m, m_friend_typing_cb *function); void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb *function); /* Set the callback for connection status changes. - * function(uint32_t friendnumber, uint8_t status) + * `function(uint32_t friendnumber, uint8_t status)` * * Status: * 0 -- friend went offline after being previously online. * 1 -- friend went online. * - * Note that this callback is not called when adding friends, thus the "after - * being previously online" part. + * Note that this callback is not called when adding friends, thus the + * "after being previously online" part. * It's assumed that when adding friends, their connection status is offline. */ void m_callback_connectionstatus(Messenger *m, m_friend_connection_status_cb *function); @@ -571,11 +556,9 @@ void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionst */ void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function); -/**********CONFERENCES************/ +/** CONFERENCES */ /* Set the callback for conference invites. - * - * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) */ void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function); @@ -586,34 +569,23 @@ void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function */ int send_conference_invite_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length); -/****************FILE SENDING*****************/ +/** FILE SENDING */ /* Set the callback for file send requests. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint32_t filetype, uint64_t filesize, uint8_t *filename, size_t filename_length, void *userdata) */ void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function); /* Set the callback for file control requests. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, unsigned int control_type, void *userdata) - * */ void callback_file_control(Messenger *m, m_file_recv_control_cb *function); /* Set the callback for file data. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, uint8_t *data, size_t length, void *userdata) - * */ void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function); /* Set the callback for file request chunk. - * - * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata) - * */ void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function); @@ -688,11 +660,9 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin */ uint64_t file_dataremaining(const Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive); -/*************** A/V related ******************/ +/** A/V related */ /* Set the callback for msi packets. - * - * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) */ void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata); @@ -711,7 +681,7 @@ int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lossy_rtp_packet_cb *function, void *object); -/**********************************************/ +/** CUSTOM PACKETS */ /* Set handlers for custom lossy packets. * @@ -746,13 +716,13 @@ void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_pack */ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length); -/**********************************************/ +/** Messenger constructor/destructor/operations. */ typedef enum Messenger_Error { MESSENGER_ERROR_NONE, MESSENGER_ERROR_PORT, MESSENGER_ERROR_TCP_SERVER, - MESSENGER_ERROR_OTHER + MESSENGER_ERROR_OTHER, } Messenger_Error; /* Run this at startup. @@ -798,7 +768,7 @@ uint8_t *messenger_save(const Messenger *m, uint8_t *data); * * @param data Data to load. * @param length Length of data. - * @param type Type of section (STATE_TYPE_*). + * @param type Type of section (`STATE_TYPE_*`). * @param status Result of loading section is stored here if the section is handled. * @return true iff section handled. */ diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.c b/protocols/Tox/libtox/src/toxcore/TCP_client.c index 6eae84086a..408ec4891a 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_client.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_client.c @@ -1,25 +1,10 @@ -/* - * Implementation of the TCP relay client part of Tox. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the TCP relay client part of Tox. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -555,7 +540,7 @@ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const /* Set the number that will be used as an argument in the callbacks related to con_id. * - * When not set by this function, the number is ~0. + * When not set by this function, the number is -1. * * return 0 on success. * return -1 on failure. @@ -785,7 +770,7 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t * } conn->connections[con_id].status = 1; - conn->connections[con_id].number = ~0; + conn->connections[con_id].number = -1; memcpy(conn->connections[con_id].public_key, data + 2, CRYPTO_PUBLIC_KEY_SIZE); if (conn->response_callback) { @@ -1038,7 +1023,7 @@ void do_TCP_connection(Mono_Time *mono_time, TCP_Client_Connection *tcp_connecti if (sizeof(data) == len) { if (handle_handshake(tcp_connection, data) == 0) { - tcp_connection->kill_at = ~0; + tcp_connection->kill_at = -1; tcp_connection->status = TCP_CLIENT_CONFIRMED; } else { tcp_connection->kill_at = 0; diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.h b/protocols/Tox/libtox/src/toxcore/TCP_client.h index 9d43d642b3..cecf5a6d5f 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_client.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_client.h @@ -1,25 +1,10 @@ -/* - * Implementation of the TCP relay client part of Tox. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the TCP relay client part of Tox. */ #ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H #define C_TOXCORE_TOXCORE_TCP_CLIENT_H @@ -32,7 +17,7 @@ typedef enum TCP_Proxy_Type { TCP_PROXY_NONE, TCP_PROXY_HTTP, - TCP_PROXY_SOCKS5 + TCP_PROXY_SOCKS5, } TCP_Proxy_Type; typedef struct TCP_Proxy_Info { @@ -103,7 +88,7 @@ int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id); /* Set the number that will be used as an argument in the callbacks related to con_id. * - * When not set by this function, the number is ~0. + * When not set by this function, the number is -1. * * return 0 on success. * return -1 on failure. diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.c b/protocols/Tox/libtox/src/toxcore/TCP_connection.c index b11b1e3b08..3dd8652ead 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_connection.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.c @@ -1,25 +1,10 @@ -/* - * Handles TCP relay connections between two Tox clients. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2015 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2015 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Handles TCP relay connections between two Tox clients. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.h b/protocols/Tox/libtox/src/toxcore/TCP_connection.h index 1962fb1aca..a8e522d343 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_connection.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.h @@ -1,25 +1,10 @@ -/* - * Handles TCP relay connections between two Tox clients. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2015 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2015 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Handles TCP relay connections between two Tox clients. */ #ifndef C_TOXCORE_TOXCORE_TCP_CONNECTION_H #define C_TOXCORE_TOXCORE_TCP_CONNECTION_H diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.c b/protocols/Tox/libtox/src/toxcore/TCP_server.c index 23b9594015..b22bdb8084 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_server.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_server.c @@ -1,25 +1,10 @@ -/* - * Implementation of the TCP relay server part of Tox. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the TCP relay server part of Tox. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -288,7 +273,7 @@ static int del_accepted(TCP_Server *tcp_server, int index) * * return length on success * return 0 if nothing has been read from socket. - * return ~0 on failure. + * return -1 on failure. */ uint16_t read_TCP_length(Socket sock) { @@ -306,7 +291,7 @@ uint16_t read_TCP_length(Socket sock) length = net_ntohs(length); if (length > MAX_PACKET_SIZE) { - return ~0; + return -1; } return length; @@ -348,7 +333,7 @@ int read_packet_TCP_secure_connection(Socket sock, uint16_t *next_packet_length, if (*next_packet_length == 0) { uint16_t len = read_TCP_length(sock); - if (len == (uint16_t)~0) { + if (len == (uint16_t) -1) { return -1; } @@ -684,7 +669,7 @@ static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key) { uint32_t i; - uint32_t index = ~0; + uint32_t index = -1; TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; /* If person tries to cennect to himself we deny the request*/ @@ -705,12 +690,12 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const return 0; } - } else if (index == (uint32_t)~0) { + } else if (index == (uint32_t) -1) { index = i; } } - if (index == (uint32_t)~0) { + if (index == (uint32_t) -1) { if (send_routing_response(con, 0, public_key) == -1) { return -1; } @@ -733,7 +718,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const int other_index = get_TCP_connection_index(tcp_server, public_key); if (other_index != -1) { - uint32_t other_id = ~0; + uint32_t other_id = -1; TCP_Secure_Connection *other_conn = &tcp_server->accepted_connection_array[other_index]; for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { @@ -744,7 +729,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const } } - if (other_id != (uint32_t)~0) { + if (other_id != (uint32_t) -1) { con->connections[index].status = 2; con->connections[index].index = other_index; con->connections[index].other_id = other_id; diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.h b/protocols/Tox/libtox/src/toxcore/TCP_server.h index 252df9faf2..5862a4733f 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_server.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_server.h @@ -1,25 +1,10 @@ -/* - * Implementation of the TCP relay server part of Tox. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the TCP relay server part of Tox. */ #ifndef C_TOXCORE_TOXCORE_TCP_SERVER_H #define C_TOXCORE_TOXCORE_TCP_SERVER_H @@ -100,7 +85,7 @@ void kill_TCP_server(TCP_Server *tcp_server); * * return length on success * return 0 if nothing has been read from socket. - * return ~0 on failure. + * return -1 on failure. */ uint16_t read_TCP_length(Socket sock); diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h index b6b49624e3..44f541fc18 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h @@ -1,26 +1,11 @@ %{ -/* - * Functions for the core crypto. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Functions for the core crypto. */ #ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H #define C_TOXCORE_TOXCORE_CRYPTO_CORE_H diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.c b/protocols/Tox/libtox/src/toxcore/crypto_core.c index 0e53100acd..5538b1b8ee 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.c +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.c @@ -1,27 +1,12 @@ -/* - * Functions for the core crypto. - * - * NOTE: This code has to be perfect. We don't mess around with encryption. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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. + * Functions for the core crypto. * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see <http://www.gnu.org/licenses/>. + * NOTE: This code has to be perfect. We don't mess around with encryption. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -257,7 +242,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const /* Increment the given nonce by 1. */ void increment_nonce(uint8_t *nonce) { - /* TODO(irungentoo): use increment_nonce_number(nonce, 1) or + /* TODO(irungentoo): use `increment_nonce_number(nonce, 1)` or * sodium_increment (change to little endian). * * NOTE don't use breaks inside this loop. diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.h b/protocols/Tox/libtox/src/toxcore/crypto_core.h index c2f0296e15..07412e7e8c 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.h +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.h @@ -1,25 +1,10 @@ -/* - * Functions for the core crypto. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Functions for the core crypto. */ #ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H #define C_TOXCORE_TOXCORE_CRYPTO_CORE_H diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.c b/protocols/Tox/libtox/src/toxcore/friend_connection.c index 69533def1e..af5d09e370 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_connection.c +++ b/protocols/Tox/libtox/src/toxcore/friend_connection.c @@ -1,25 +1,10 @@ -/* - * Connection to friends. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Connection to friends. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.h b/protocols/Tox/libtox/src/toxcore/friend_connection.h index 166c731b84..92e3870345 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_connection.h +++ b/protocols/Tox/libtox/src/toxcore/friend_connection.h @@ -1,25 +1,10 @@ -/* - * Connection to friends. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Connection to friends. */ #ifndef C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H #define C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H @@ -58,7 +43,7 @@ typedef enum Friendconn_Status { FRIENDCONN_STATUS_NONE, FRIENDCONN_STATUS_CONNECTING, - FRIENDCONN_STATUS_CONNECTED + FRIENDCONN_STATUS_CONNECTED, } Friendconn_Status; typedef struct Friend_Connections Friend_Connections; diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.c b/protocols/Tox/libtox/src/toxcore/friend_requests.c index fa1defc843..c6c9a0e048 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_requests.c +++ b/protocols/Tox/libtox/src/toxcore/friend_requests.c @@ -1,25 +1,10 @@ -/* - * Handle friend requests. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Handle friend requests. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.h b/protocols/Tox/libtox/src/toxcore/friend_requests.h index 7fcd3f0d35..e3a03a51e8 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_requests.h +++ b/protocols/Tox/libtox/src/toxcore/friend_requests.h @@ -1,25 +1,10 @@ -/* - * Handle friend requests. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Handle friend requests. */ #ifndef C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H #define C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H @@ -45,14 +30,12 @@ typedef void fr_friend_request_cb(void *object, const uint8_t *public_key, const void *user_data); /* Set the function that will be executed when a friend request for us is received. - * Function format is function(uint8_t * public_key, uint8_t * data, size_t length, void * userdata) */ void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object); typedef int filter_function_cb(const uint8_t *public_key, void *user_data); /* Set the function used to check if a friend request should be displayed to the user or not. - * Function format is int function(uint8_t * public_key, void * userdata) * It must return 0 if the request is ok (anything else if it is bad.) */ void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void *userdata); diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c index f6f8c70431..3e04f181c8 100644 --- a/protocols/Tox/libtox/src/toxcore/group.c +++ b/protocols/Tox/libtox/src/toxcore/group.c @@ -1,25 +1,10 @@ -/* - * Slightly better groupchats implementation. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Slightly better groupchats implementation. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,11 +39,13 @@ typedef enum Group_Message_Id { typedef enum Invite_Id { INVITE_ID = 0, - INVITE_RESPONSE_ID = 1, + INVITE_ACCEPT_ID = 1, + INVITE_MEMBER_ID = 2, } Invite_Id; #define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + 1 + GROUP_ID_LENGTH) -#define INVITE_RESPONSE_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH) +#define INVITE_ACCEPT_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH) +#define INVITE_MEMBER_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH + sizeof(uint16_t)) #define ONLINE_PACKET_DATA_SIZE (sizeof(uint16_t) + 1 + GROUP_ID_LENGTH) @@ -76,19 +63,9 @@ typedef enum Peer_Id { */ static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber) { - if (groupnumber >= g_c->num_chats) { - return false; - } - - if (g_c->chats == nullptr) { - return false; - } - - if (g_c->chats[groupnumber].status == GROUPCHAT_STATUS_NONE) { - return false; - } - - return true; + return groupnumber < g_c->num_chats + && g_c->chats != nullptr + && g_c->chats[groupnumber].status != GROUPCHAT_STATUS_NONE; } @@ -135,27 +112,25 @@ static int32_t create_group_chat(Group_Chats *g_c) } } - int32_t id = -1; - if (realloc_conferences(g_c, g_c->num_chats + 1)) { - id = g_c->num_chats; + uint16_t id = g_c->num_chats; ++g_c->num_chats; setup_conference(&g_c->chats[id]); + return id; } - return id; + return -1; } /* Wipe a groupchat. * - * return -1 on failure. - * return 0 on success. + * return true on success. */ -static int wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) +static bool wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) { if (!is_groupnumber_valid(g_c, groupnumber)) { - return -1; + return false; } uint16_t i; @@ -172,7 +147,7 @@ static int wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) realloc_conferences(g_c, g_c->num_chats); } - return 0; + return true; } static Group_c *get_group_c(const Group_Chats *g_c, uint32_t groupnumber) @@ -187,16 +162,16 @@ static Group_c *get_group_c(const Group_Chats *g_c, uint32_t groupnumber) /* * check if peer with real_pk is in peer array. * - * return peer index if peer is in chat. - * return -1 if peer is not in chat. + * return peer index if peer is in group. + * return -1 if peer is not in group. * * TODO(irungentoo): make this more efficient. */ -static int peer_in_chat(const Group_c *chat, const uint8_t *real_pk) +static int peer_in_group(const Group_c *g, const uint8_t *real_pk) { - for (uint32_t i = 0; i < chat->numpeers; ++i) { - if (id_equal(chat->group[i].real_pk, real_pk)) { + for (uint32_t i = 0; i < g->numpeers; ++i) { + if (id_equal(g->group[i].real_pk, real_pk)) { return i; } } @@ -204,10 +179,10 @@ static int peer_in_chat(const Group_c *chat, const uint8_t *real_pk) return -1; } -static int frozen_in_chat(const Group_c *chat, const uint8_t *real_pk) +static int frozen_in_group(const Group_c *g, const uint8_t *real_pk) { - for (uint32_t i = 0; i < chat->numfrozen; ++i) { - if (id_equal(chat->frozen[i].real_pk, real_pk)) { + for (uint32_t i = 0; i < g->numfrozen; ++i) { + if (id_equal(g->frozen[i].real_pk, real_pk)) { return i; } } @@ -277,47 +252,39 @@ static uint64_t calculate_comp_value(const uint8_t *pk1, const uint8_t *pk2) return cmp1 - cmp2; } -typedef enum Groupchat_Closest { - GROUPCHAT_CLOSEST_NONE, - GROUPCHAT_CLOSEST_ADDED, - GROUPCHAT_CLOSEST_REMOVED -} Groupchat_Closest; +typedef enum Groupchat_Closest_Change { + GROUPCHAT_CLOSEST_CHANGE_NONE, + GROUPCHAT_CLOSEST_CHANGE_ADDED, + GROUPCHAT_CLOSEST_CHANGE_REMOVED, +} Groupchat_Closest_Change; -static int add_to_closest(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk, const uint8_t *temp_pk) +static bool add_to_closest(Group_c *g, const uint8_t *real_pk, const uint8_t *temp_pk) { - Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return -1; - } - if (public_key_cmp(g->real_pk, real_pk) == 0) { - return -1; + return false; } - unsigned int i; - unsigned int index = DESIRED_CLOSE_CONNECTIONS; + unsigned int index = DESIRED_CLOSEST; - for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { + for (unsigned int i = 0; i < DESIRED_CLOSEST; ++i) { if (g->closest_peers[i].entry && public_key_cmp(real_pk, g->closest_peers[i].real_pk) == 0) { - return 0; + return true; } } - for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { + for (unsigned int i = 0; i < DESIRED_CLOSEST; ++i) { if (g->closest_peers[i].entry == 0) { index = i; break; } } - if (index == DESIRED_CLOSE_CONNECTIONS) { + if (index == DESIRED_CLOSEST) { uint64_t comp_val = calculate_comp_value(g->real_pk, real_pk); uint64_t comp_d = 0; - for (i = 0; i < (DESIRED_CLOSE_CONNECTIONS / 2); ++i) { - uint64_t comp; - comp = calculate_comp_value(g->real_pk, g->closest_peers[i].real_pk); + for (unsigned int i = 0; i < (DESIRED_CLOSEST / 2); ++i) { + uint64_t comp = calculate_comp_value(g->real_pk, g->closest_peers[i].real_pk); if (comp > comp_val && comp > comp_d) { index = i; @@ -327,7 +294,7 @@ static int add_to_closest(Group_Chats *g_c, uint32_t groupnumber, const uint8_t comp_val = calculate_comp_value(real_pk, g->real_pk); - for (i = (DESIRED_CLOSE_CONNECTIONS / 2); i < DESIRED_CLOSE_CONNECTIONS; ++i) { + for (unsigned int i = (DESIRED_CLOSEST / 2); i < DESIRED_CLOSEST; ++i) { uint64_t comp = calculate_comp_value(g->closest_peers[i].real_pk, g->real_pk); if (comp > comp_val && comp > comp_d) { @@ -337,8 +304,8 @@ static int add_to_closest(Group_Chats *g_c, uint32_t groupnumber, const uint8_t } } - if (index == DESIRED_CLOSE_CONNECTIONS) { - return -1; + if (index == DESIRED_CLOSEST) { + return false; } uint8_t old_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; @@ -356,89 +323,85 @@ static int add_to_closest(Group_Chats *g_c, uint32_t groupnumber, const uint8_t memcpy(g->closest_peers[index].temp_pk, temp_pk, CRYPTO_PUBLIC_KEY_SIZE); if (old) { - add_to_closest(g_c, groupnumber, old_real_pk, old_temp_pk); + add_to_closest(g, old_real_pk, old_temp_pk); } if (!g->changed) { - g->changed = GROUPCHAT_CLOSEST_ADDED; + g->changed = GROUPCHAT_CLOSEST_CHANGE_ADDED; } - return 0; + return true; } -static unsigned int pk_in_closest_peers(const Group_c *g, uint8_t *real_pk) +static bool pk_in_closest_peers(const Group_c *g, uint8_t *real_pk) { - unsigned int i; - - for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { + for (unsigned int i = 0; i < DESIRED_CLOSEST; ++i) { if (!g->closest_peers[i].entry) { continue; } if (public_key_cmp(g->closest_peers[i].real_pk, real_pk) == 0) { - return 1; + return true; } } - return 0; + return false; } -static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t reason, - uint8_t lock); - -static void remove_conn_reason(Group_Chats *g_c, uint32_t groupnumber, uint16_t i, uint8_t reason); - -static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16_t group_num, uint8_t type, - const uint8_t *id); +static void remove_connection_reason(Group_Chats *g_c, Group_c *g, uint16_t i, uint8_t reason); -static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *userdata) +static void purge_closest(Group_Chats *g_c, uint32_t groupnumber) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; - } - - if (!g->changed) { - return 0; - } - - if (g->changed == GROUPCHAT_CLOSEST_REMOVED) { - for (uint32_t i = 0; i < g->numpeers; ++i) { - add_to_closest(g_c, groupnumber, g->group[i].real_pk, g->group[i].temp_pk); - } + return; } for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { continue; } - if (!(g->close[i].reasons & GROUPCHAT_CLOSE_REASON_CLOSEST)) { + if (!(g->connections[i].reasons & GROUPCHAT_CONNECTION_REASON_CLOSEST)) { continue; } uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; - get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[i].number); + get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->connections[i].number); if (!pk_in_closest_peers(g, real_pk)) { - remove_conn_reason(g_c, groupnumber, i, GROUPCHAT_CLOSE_REASON_CLOSEST); + remove_connection_reason(g_c, g, i, GROUPCHAT_CONNECTION_REASON_CLOSEST); } } +} + +static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16_t group_num, uint8_t type, + const uint8_t *id); + +static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, Group_c *g, uint8_t reason, + uint8_t lock); + +static void add_closest_connections(Group_Chats *g_c, uint32_t groupnumber, void *userdata) +{ + Group_c *g = get_group_c(g_c, groupnumber); + + if (!g) { + return; + } - for (uint32_t i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { + for (uint32_t i = 0; i < DESIRED_CLOSEST; ++i) { if (!g->closest_peers[i].entry) { continue; } int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, g->closest_peers[i].real_pk); - uint8_t lock = 1; + uint8_t fresh = 0; if (friendcon_id == -1) { friendcon_id = new_friend_connection(g_c->fr_c, g->closest_peers[i].real_pk); - lock = 0; + fresh = 1; if (friendcon_id == -1) { continue; @@ -447,16 +410,49 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user set_dht_temp_pk(g_c->fr_c, friendcon_id, g->closest_peers[i].temp_pk, userdata); } - add_conn_to_groupchat(g_c, friendcon_id, groupnumber, GROUPCHAT_CLOSE_REASON_CLOSEST, lock); + const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, + GROUPCHAT_CONNECTION_REASON_CLOSEST, !fresh); - if (friend_con_connected(g_c->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { + if (connection_index == -1) { + if (fresh) { + kill_friend_connection(g_c->fr_c, friendcon_id); + } + + continue; + } + + if (friend_con_connected(g_c->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED + && g->connections[connection_index].type == GROUPCHAT_CONNECTION_CONNECTING) { send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->type, g->id); } } +} - g->changed = GROUPCHAT_CLOSEST_NONE; +static bool connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *userdata) +{ + Group_c *g = get_group_c(g_c, groupnumber); - return 0; + if (!g) { + return false; + } + + if (!g->changed) { + return true; + } + + if (g->changed == GROUPCHAT_CLOSEST_CHANGE_REMOVED) { + for (uint32_t i = 0; i < g->numpeers; ++i) { + add_to_closest(g, g->group[i].real_pk, g->group[i].temp_pk); + } + } + + purge_closest(g_c, groupnumber); + + add_closest_connections(g_c, groupnumber, userdata); + + g->changed = GROUPCHAT_CLOSEST_CHANGE_NONE; + + return true; } static int get_frozen_index(const Group_c *g, uint16_t peer_number) @@ -532,12 +528,14 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee return -1; } + const uint32_t thawed_index = g->numpeers; + g->group = temp; - g->group[g->numpeers] = g->frozen[frozen_index]; - g->group[g->numpeers].temp_pk_updated = false; - g->group[g->numpeers].last_active = mono_time_get(g_c->mono_time); + g->group[thawed_index] = g->frozen[frozen_index]; + g->group[thawed_index].temp_pk_updated = false; + g->group[thawed_index].last_active = mono_time_get(g_c->mono_time); - add_to_closest(g_c, groupnumber, g->group[g->numpeers].real_pk, g->group[g->numpeers].temp_pk); + add_to_closest(g, g->group[thawed_index].real_pk, g->group[thawed_index].temp_pk); ++g->numpeers; @@ -548,15 +546,15 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee } if (g->peer_on_join) { - g->peer_on_join(g->object, groupnumber, g->numpeers - 1); + g->peer_on_join(g->object, groupnumber, thawed_index); } g->need_send_name = true; - return g->numpeers - 1; + return thawed_index; } -static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata, bool keep_connection); +static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata); static void delete_any_peer_with_pk(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk, void *userdata) { @@ -566,16 +564,16 @@ static void delete_any_peer_with_pk(Group_Chats *g_c, uint32_t groupnumber, cons return; } - const int prev_peer_index = peer_in_chat(g, real_pk); + const int peer_index = peer_in_group(g, real_pk); - if (prev_peer_index >= 0) { - delpeer(g_c, groupnumber, prev_peer_index, userdata, false); + if (peer_index >= 0) { + delpeer(g_c, groupnumber, peer_index, userdata); } - const int prev_frozen_index = frozen_in_chat(g, real_pk); + const int frozen_index = frozen_in_group(g, real_pk); - if (prev_frozen_index >= 0) { - delete_frozen(g, prev_frozen_index); + if (frozen_index >= 0) { + delete_frozen(g, frozen_index); } } @@ -642,59 +640,46 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p memset(&temp[g->numpeers], 0, sizeof(Group_Peer)); g->group = temp; - id_copy(g->group[g->numpeers].real_pk, real_pk); - id_copy(g->group[g->numpeers].temp_pk, temp_pk); - g->group[g->numpeers].temp_pk_updated = true; - g->group[g->numpeers].peer_number = peer_number; - g->group[g->numpeers].last_active = mono_time_get(g_c->mono_time); - g->group[g->numpeers].is_friend = (getfriend_id(g_c->m, real_pk) != -1); + const uint32_t new_index = g->numpeers; + + id_copy(g->group[new_index].real_pk, real_pk); + id_copy(g->group[new_index].temp_pk, temp_pk); + g->group[new_index].temp_pk_updated = true; + g->group[new_index].peer_number = peer_number; + g->group[new_index].last_active = mono_time_get(g_c->mono_time); + g->group[new_index].is_friend = (getfriend_id(g_c->m, real_pk) != -1); ++g->numpeers; - add_to_closest(g_c, groupnumber, real_pk, temp_pk); + add_to_closest(g, real_pk, temp_pk); if (do_gc_callback && g_c->peer_list_changed_callback) { g_c->peer_list_changed_callback(g_c->m, groupnumber, userdata); } if (g->peer_on_join) { - g->peer_on_join(g->object, groupnumber, g->numpeers - 1); + g->peer_on_join(g->object, groupnumber, new_index); } - return g->numpeers - 1; + return new_index; } -static int remove_close_conn(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id) +static void remove_connection(Group_Chats *g_c, Group_c *g, uint16_t i) { - Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return -1; - } - - uint32_t i; - - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { - continue; - } - - if (g->close[i].number == (unsigned int)friendcon_id) { - g->close[i].type = GROUPCHAT_CLOSE_NONE; - kill_friend_connection(g_c->fr_c, friendcon_id); - return 0; - } + if (g->connections[i].reasons & GROUPCHAT_CONNECTION_REASON_INTRODUCER) { + --g->num_introducer_connections; } - return -1; + kill_friend_connection(g_c->fr_c, g->connections[i].number); + g->connections[i].type = GROUPCHAT_CONNECTION_NONE; } - static void remove_from_closest(Group_c *g, int peer_index) { - for (uint32_t i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { - if (g->closest_peers[i].entry && id_equal(g->closest_peers[i].real_pk, g->group[peer_index].real_pk)) { + for (uint32_t i = 0; i < DESIRED_CLOSEST; ++i) { + if (g->closest_peers[i].entry + && id_equal(g->closest_peers[i].real_pk, g->group[peer_index].real_pk)) { g->closest_peers[i].entry = 0; - g->changed = GROUPCHAT_CLOSEST_REMOVED; + g->changed = GROUPCHAT_CLOSEST_CHANGE_REMOVED; break; } } @@ -703,23 +688,31 @@ static void remove_from_closest(Group_c *g, int peer_index) /* * Delete a peer from the group chat. * - * return 0 if success - * return -1 if error. + * return true on success */ -static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata, bool keep_connection) +static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; + return false; } remove_from_closest(g, peer_index); const int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, g->group[peer_index].real_pk); - if (friendcon_id != -1 && !keep_connection) { - remove_close_conn(g_c, groupnumber, friendcon_id); + if (friendcon_id != -1) { + for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { + continue; + } + + if (g->connections[i].number == (unsigned int)friendcon_id) { + remove_connection(g_c, g, i); + break; + } + } } --g->numpeers; @@ -737,7 +730,7 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers)); if (temp == nullptr) { - return -1; + return false; } g->group = temp; @@ -751,7 +744,7 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void g->peer_on_leave(g->object, groupnumber, peer_object); } - return 0; + return true; } static int cmp_u64(uint64_t a, uint64_t b) @@ -804,37 +797,37 @@ static bool delete_old_frozen(Group_c *g) return true; } -static bool try_send_rejoin(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk); +static bool try_send_rejoin(Group_Chats *g_c, Group_c *g, const uint8_t *real_pk); -static int freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata) +static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; + return false; } Group_Peer *temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen + 1)); if (temp == nullptr) { - return -1; + return false; } g->frozen = temp; g->frozen[g->numfrozen] = g->group[peer_index]; g->frozen[g->numfrozen].object = nullptr; - if (delpeer(g_c, groupnumber, peer_index, userdata, true) != 0) { - return -1; + if (!delpeer(g_c, groupnumber, peer_index, userdata)) { + return false; } - try_send_rejoin(g_c, groupnumber, g->frozen[g->numfrozen].real_pk); + try_send_rejoin(g_c, g, g->frozen[g->numfrozen].real_pk); ++g->numfrozen; delete_old_frozen(g); - return 0; + return true; } @@ -844,29 +837,27 @@ static int freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, v * via the public API. This should be set to false if this function is called * from outside of the tox_iterate() loop. * - * return 0 on success. - * return -1 if error. + * return true on success. */ -static int setnick(Group_Chats *g_c, uint32_t groupnumber, int peer_index, const uint8_t *nick, uint16_t nick_len, - void *userdata, bool do_gc_callback) +static bool setnick(Group_Chats *g_c, uint32_t groupnumber, int peer_index, const uint8_t *nick, uint16_t nick_len, + void *userdata, bool do_gc_callback) { if (nick_len > MAX_NAME_LENGTH) { - return -1; + return false; } Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; + return false; } g->group[peer_index].nick_updated = true; - /* same name as already stored? */ - if (g->group[peer_index].nick_len == nick_len) { - if (nick_len == 0 || !memcmp(g->group[peer_index].nick, nick, nick_len)) { - return 0; - } + if (g->group[peer_index].nick_len == nick_len + && (nick_len == 0 || !memcmp(g->group[peer_index].nick, nick, nick_len))) { + /* same name as already stored */ + return true; } if (nick_len) { @@ -879,25 +870,29 @@ static int setnick(Group_Chats *g_c, uint32_t groupnumber, int peer_index, const g_c->peer_name_callback(g_c->m, groupnumber, peer_index, nick, nick_len, userdata); } - return 0; + return true; } -static int settitle(Group_Chats *g_c, uint32_t groupnumber, int peer_index, const uint8_t *title, uint8_t title_len, - void *userdata) +/* Set the title for a group. + * + * return true on success. + */ +static bool settitle(Group_Chats *g_c, uint32_t groupnumber, int peer_index, const uint8_t *title, uint8_t title_len, + void *userdata) { if (title_len > MAX_NAME_LENGTH || title_len == 0) { - return -1; + return false; } Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; + return false; } - /* same as already set? */ if (g->title_len == title_len && !memcmp(g->title, title, title_len)) { - return 0; + /* same title as already set */ + return true; } memcpy(g->title, title, title_len); @@ -909,7 +904,7 @@ static int settitle(Group_Chats *g_c, uint32_t groupnumber, int peer_index, cons g_c->title_callback(g_c->m, groupnumber, peer_index, title, title_len, userdata); } - return 0; + return true; } /* Check if the group has no online connection, and freeze all peers if so */ @@ -922,7 +917,7 @@ static void check_disconnected(Group_Chats *g_c, uint32_t groupnumber, void *use } for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_ONLINE) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_ONLINE) { return; } } @@ -934,7 +929,8 @@ static void check_disconnected(Group_Chats *g_c, uint32_t groupnumber, void *use } } -static void set_conns_type_close(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id, uint8_t type, void *userdata) +static void set_conns_type_connections(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id, uint8_t type, + void *userdata) { Group_c *g = get_group_c(g_c, groupnumber); @@ -942,30 +938,29 @@ static void set_conns_type_close(Group_Chats *g_c, uint32_t groupnumber, int fri return; } - uint32_t i; - - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { + for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { continue; } - if (g->close[i].number != (unsigned int)friendcon_id) { + if (g->connections[i].number != (unsigned int)friendcon_id) { continue; } - if (type == GROUPCHAT_CLOSE_ONLINE) { + if (type == GROUPCHAT_CONNECTION_ONLINE) { send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->type, g->id); } else { - g->close[i].type = type; + g->connections[i].type = type; check_disconnected(g_c, groupnumber, userdata); } } } -/* Set the type for all close connections with friendcon_id */ + +/* Set the type for all connections with friendcon_id */ static void set_conns_status_groups(Group_Chats *g_c, int friendcon_id, uint8_t type, void *userdata) { for (uint16_t i = 0; i < g_c->num_chats; ++i) { - set_conns_type_close(g_c, i, friendcon_id, type, userdata); + set_conns_type_connections(g_c, i, friendcon_id, type, userdata); } } @@ -983,7 +978,7 @@ static void rejoin_frozen_friend(Group_Chats *g_c, int friendcon_id) for (uint32_t j = 0; j < g->numfrozen; ++j) { if (id_equal(g->frozen[j].real_pk, real_pk)) { - try_send_rejoin(g_c, i, real_pk); + try_send_rejoin(g_c, g, real_pk); break; } } @@ -1006,9 +1001,9 @@ static int g_handle_status(void *object, int friendcon_id, uint8_t status, void Group_Chats *g_c = (Group_Chats *)object; if (status) { /* Went online */ - set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_ONLINE, userdata); + set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CONNECTION_ONLINE, userdata); } else { /* Went offline */ - set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_CONNECTION, userdata); + set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CONNECTION_CONNECTING, userdata); // TODO(irungentoo): remove timedout connections? } @@ -1020,55 +1015,49 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin /* Add friend to group chat. * - * return close index on success + * return connections index on success * return -1 on failure. */ -static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t reason, +static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, Group_c *g, uint8_t reason, uint8_t lock) { - Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return -1; - } - uint16_t empty = MAX_GROUP_CONNECTIONS; uint16_t ind = MAX_GROUP_CONNECTIONS; for (uint16_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { empty = i; continue; } - if (g->close[i].number == (uint32_t)friendcon_id) { + if (g->connections[i].number == (uint32_t)friendcon_id) { ind = i; /* Already in list. */ break; } } - if (ind == MAX_GROUP_CONNECTIONS && empty != MAX_GROUP_CONNECTIONS) { + if (ind == MAX_GROUP_CONNECTIONS) { + if (empty == MAX_GROUP_CONNECTIONS) { + return -1; + } + if (lock) { friend_connection_lock(g_c->fr_c, friendcon_id); } - g->close[empty].type = GROUPCHAT_CLOSE_CONNECTION; - g->close[empty].number = friendcon_id; - g->close[empty].reasons = 0; + g->connections[empty].type = GROUPCHAT_CONNECTION_CONNECTING; + g->connections[empty].number = friendcon_id; + g->connections[empty].reasons = 0; // TODO(irungentoo): friend_connection_callbacks(g_c->m->fr_c, friendcon_id, GROUPCHAT_CALLBACK_INDEX, &g_handle_status, &g_handle_packet, &handle_lossy, g_c, friendcon_id); ind = empty; } - if (ind == MAX_GROUP_CONNECTIONS) { - return -1; - } - - if (!(g->close[ind].reasons & reason)) { - g->close[ind].reasons |= reason; + if (!(g->connections[ind].reasons & reason)) { + g->connections[ind].reasons |= reason; - if (reason == GROUPCHAT_CLOSE_REASON_INTRODUCER) { + if (reason == GROUPCHAT_CONNECTION_REASON_INTRODUCER) { ++g->num_introducer_connections; } } @@ -1082,37 +1071,31 @@ static unsigned int send_peer_introduced(Group_Chats *g_c, int friendcon_id, uin * * Kills connection if this was the last reason. */ -static void remove_conn_reason(Group_Chats *g_c, uint32_t groupnumber, uint16_t i, uint8_t reason) +static void remove_connection_reason(Group_Chats *g_c, Group_c *g, uint16_t i, uint8_t reason) { - Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { + if (!(g->connections[i].reasons & reason)) { return; } - if (!(g->close[i].reasons & reason)) { - return; - } - - g->close[i].reasons &= ~reason; + g->connections[i].reasons &= ~reason; - if (reason == GROUPCHAT_CLOSE_REASON_INTRODUCER) { + if (reason == GROUPCHAT_CONNECTION_REASON_INTRODUCER) { --g->num_introducer_connections; - if (g->close[i].type == GROUPCHAT_CLOSE_ONLINE) { - send_peer_introduced(g_c, g->close[i].number, g->close[i].group_number); + if (g->connections[i].type == GROUPCHAT_CONNECTION_ONLINE) { + send_peer_introduced(g_c, g->connections[i].number, g->connections[i].group_number); } } - if (g->close[i].reasons == 0) { - kill_friend_connection(g_c->fr_c, g->close[i].number); - g->close[i].type = GROUPCHAT_CLOSE_NONE; + if (g->connections[i].reasons == 0) { + kill_friend_connection(g_c->fr_c, g->connections[i].number); + g->connections[i].type = GROUPCHAT_CONNECTION_NONE; } } /* Creates a new groupchat and puts it in the chats array. * - * type is one of GROUPCHAT_TYPE_* + * type is one of `GROUPCHAT_TYPE_*` * * return group number on success. * return -1 on failure. @@ -1163,12 +1146,12 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently group_leave(g_c, groupnumber, leave_permanently); for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { continue; } - g->close[i].type = GROUPCHAT_CLOSE_NONE; - kill_friend_connection(g_c->fr_c, g->close[i].number); + g->connections[i].type = GROUPCHAT_CONNECTION_NONE; + kill_friend_connection(g_c->fr_c, g->connections[i].number); } for (uint32_t i = 0; i < g->numpeers; ++i) { @@ -1187,6 +1170,19 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently return wipe_group_chat(g_c, groupnumber); } +static const Group_Peer *peer_in_list(const Group_c *g, uint32_t peernumber, bool frozen) +{ + const Group_Peer *list = frozen ? g->frozen : g->group; + const uint32_t num = frozen ? g->numfrozen : g->numpeers; + + if (peernumber >= num) { + return nullptr; + } + + return &list[peernumber]; +} + + /* Copy the public key of (frozen, if frozen is true) peernumber who is in * groupnumber to pk. pk must be CRYPTO_PUBLIC_KEY_SIZE long. * @@ -1194,7 +1190,7 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, uint8_t *pk, bool frozen) +int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint8_t *pk, bool frozen) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -1202,14 +1198,13 @@ int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, int peernumb return -1; } - const Group_Peer *list = frozen ? g->frozen : g->group; - const uint32_t num = frozen ? g->numfrozen : g->numpeers; + const Group_Peer *peer = peer_in_list(g, peernumber, frozen); - if ((uint32_t)peernumber >= num) { + if (peer == nullptr) { return -2; } - memcpy(pk, list[peernumber].real_pk, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(pk, peer->real_pk, CRYPTO_PUBLIC_KEY_SIZE); return 0; } @@ -1219,7 +1214,7 @@ int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, int peernumb * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, bool frozen) +int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, bool frozen) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -1227,18 +1222,13 @@ int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, int peernu return -1; } - const Group_Peer *list = frozen ? g->frozen : g->group; - const uint32_t num = frozen ? g->numfrozen : g->numpeers; + const Group_Peer *peer = peer_in_list(g, peernumber, frozen); - if ((uint32_t)peernumber >= num) { + if (peer == nullptr) { return -2; } - if (list[peernumber].nick_len == 0) { - return 0; - } - - return list[peernumber].nick_len; + return peer->nick_len; } /* Copy the name of (frozen, if frozen is true) peernumber who is in @@ -1248,7 +1238,7 @@ int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, int peernu * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, uint8_t *name, bool frozen) +int group_peername(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint8_t *name, bool frozen) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -1256,19 +1246,17 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, return -1; } - const Group_Peer *list = frozen ? g->frozen : g->group; - const uint32_t num = frozen ? g->numfrozen : g->numpeers; + const Group_Peer *peer = peer_in_list(g, peernumber, frozen); - if ((uint32_t)peernumber >= num) { + if (peer == nullptr) { return -2; } - if (list[peernumber].nick_len == 0) { - return 0; + if (peer->nick_len > 0) { + memcpy(name, peer->nick, peer->nick_len); } - memcpy(name, list[peernumber].nick, list[peernumber].nick_len); - return list[peernumber].nick_len; + return peer->nick_len; } /* Copy last active timestamp of frozennumber who is in groupnumber to @@ -1278,7 +1266,7 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, * return -1 if groupnumber is invalid. * return -2 if frozennumber is invalid. */ -int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, +int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint64_t *last_active) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -1287,7 +1275,7 @@ int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, int p return -1; } - if ((uint32_t)peernumber >= g->numfrozen) { + if (peernumber >= g->numfrozen) { return -2; } @@ -1315,9 +1303,9 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t /* List all the (frozen, if frozen is true) peers in the group chat. * - * Copies the names of the peers to the name[length][MAX_NAME_LENGTH] array. + * Copies the names of the peers to the `name[length][MAX_NAME_LENGTH]` array. * - * Copies the lengths of the names to lengths[length] + * Copies the lengths of the names to `lengths[length]` * * returns the number of peers on success. * @@ -1364,7 +1352,7 @@ int group_number_peers(const Group_Chats *g_c, uint32_t groupnumber, bool frozen * return -2 if peernumber is invalid. * return -3 if we are not connected to the group chat. */ -int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, int peernumber) +int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -1372,7 +1360,7 @@ int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, int p return -1; } - if ((uint32_t)peernumber >= g->numpeers) { + if (peernumber >= g->numpeers) { return -2; } @@ -1399,11 +1387,11 @@ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber) return g->type; } -/* Copies the unique id of group_chat[groupnumber] into id. -* -* return false on failure. -* return true on success. -*/ +/* Copies the unique id of `group_chat[groupnumber]` into `id`. + * + * return false on failure. + * return true on success. + */ bool conference_get_id(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *id) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -1498,14 +1486,8 @@ int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber) * return true if a packet was sent. * return false otherwise. */ -static bool try_send_rejoin(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk) +static bool try_send_rejoin(Group_Chats *g_c, Group_c *g, const uint8_t *real_pk) { - Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return false; - } - const int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, real_pk); if (friendcon_id == -1) { @@ -1522,16 +1504,20 @@ static bool try_send_rejoin(Group_Chats *g_c, uint32_t groupnumber, const uint8_ return false; } - add_conn_to_groupchat(g_c, friendcon_id, groupnumber, GROUPCHAT_CLOSE_REASON_INTRODUCER, 1); + add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCER, 1); return true; } static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t group_num); -/* Join a group (you need to have been invited first.) +static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t friendnumber, const uint8_t *data, + uint16_t length); + +/* Join a group (we need to have been invited first.) * - * expected_type is the groupchat type we expect the chat we are joining is. + * expected_type is the groupchat type we expect the chat we are joining to + * have. * * return group number on success. * return -1 if data length is invalid. @@ -1569,34 +1555,65 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ Group_c *g = &g_c->chats[groupnumber]; - const uint16_t group_num = net_htons(groupnumber); g->status = GROUPCHAT_STATUS_VALID; memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); - uint8_t response[INVITE_RESPONSE_PACKET_SIZE]; - response[0] = INVITE_RESPONSE_ID; - memcpy(response + 1, &group_num, sizeof(uint16_t)); - memcpy(response + 1 + sizeof(uint16_t), data, sizeof(uint16_t) + 1 + GROUP_ID_LENGTH); + if (!send_invite_response(g_c, groupnumber, friendnumber, data, length)) { + g->status = GROUPCHAT_STATUS_NONE; + return -6; + } + + return groupnumber; +} + +static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t friendnumber, const uint8_t *data, + uint16_t length) +{ + Group_c *g = get_group_c(g_c, groupnumber); + + const bool member = (g->status == GROUPCHAT_STATUS_CONNECTED); - if (send_conference_invite_packet(g_c->m, friendnumber, response, sizeof(response))) { - uint16_t other_groupnum; - memcpy(&other_groupnum, data, sizeof(other_groupnum)); - other_groupnum = net_ntohs(other_groupnum); + VLA(uint8_t, response, member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE); + response[0] = member ? INVITE_MEMBER_ID : INVITE_ACCEPT_ID; + net_pack_u16(response + 1, groupnumber); + memcpy(response + 1 + sizeof(uint16_t), data, length); + + if (member) { + net_pack_u16(response + 1 + sizeof(uint16_t) + length, g->peer_number); + } + + if (!send_conference_invite_packet(g_c->m, friendnumber, response, SIZEOF_VLA(response))) { + return false; + } + + if (!member) { g->type = data[sizeof(uint16_t)]; memcpy(g->id, data + sizeof(uint16_t) + 1, GROUP_ID_LENGTH); - const int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnumber, GROUPCHAT_CLOSE_REASON_INTRODUCER, 1); + } - if (close_index != -1) { - g->close[close_index].group_number = other_groupnum; - g->close[close_index].type = GROUPCHAT_CLOSE_ONLINE; - } + uint16_t other_groupnum; + net_unpack_u16(data, &other_groupnum); - send_peer_query(g_c, friendcon_id, other_groupnum); - return groupnumber; + const int friendcon_id = getfriendcon_id(g_c->m, friendnumber); + + if (friendcon_id == -1) { + return false; } - g->status = GROUPCHAT_STATUS_NONE; - return -6; + const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCER, 1); + + if (member) { + add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCING, 0); + } + + if (connection_index != -1) { + g->connections[connection_index].group_number = other_groupnum; + g->connections[connection_index].type = GROUPCHAT_CONNECTION_ONLINE; + } + + send_peer_query(g_c, friendcon_id, other_groupnum); + + return true; } /* Set handlers for custom lossy packets. */ @@ -1701,21 +1718,23 @@ int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_d static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint8_t message_id, const uint8_t *data, uint16_t len); -static int group_ping_send(const Group_Chats *g_c, uint32_t groupnumber) +/* send a ping message + * return true on success + */ +static bool group_ping_send(const Group_Chats *g_c, uint32_t groupnumber) { if (send_message_group(g_c, groupnumber, GROUP_MESSAGE_PING_ID, nullptr, 0) > 0) { - return 0; + return true; } - return -1; + return false; } /* send a new_peer message - * return 0 on success - * return -1 on failure + * return true on success */ -static int group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num, const uint8_t *real_pk, - uint8_t *temp_pk) +static bool group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num, const uint8_t *real_pk, + uint8_t *temp_pk) { uint8_t packet[GROUP_MESSAGE_NEW_PEER_LENGTH]; @@ -1725,10 +1744,10 @@ static int group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uin memcpy(packet + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE, temp_pk, CRYPTO_PUBLIC_KEY_SIZE); if (send_message_group(g_c, groupnumber, GROUP_MESSAGE_NEW_PEER_ID, packet, sizeof(packet)) > 0) { - return 0; + return true; } - return -1; + return false; } /* send a kill_peer message @@ -1766,20 +1785,19 @@ static bool group_freeze_peer_send(const Group_Chats *g_c, uint32_t groupnumber, } /* send a name message - * return 0 on success - * return -1 on failure + * return true on success */ -static int group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *nick, uint16_t nick_len) +static bool group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *nick, uint16_t nick_len) { if (nick_len > MAX_NAME_LENGTH) { - return -1; + return false; } if (send_message_group(g_c, groupnumber, GROUP_MESSAGE_NAME_ID, nick, nick_len) > 0) { - return 0; + return true; } - return -1; + return false; } /* send message to announce leaving group @@ -1850,7 +1868,7 @@ int group_title_get_size(const Group_Chats *g_c, uint32_t groupnumber) return -1; } - if (g->title_len == 0 || g->title_len > MAX_NAME_LENGTH) { + if (g->title_len > MAX_NAME_LENGTH || g->title_len == 0) { return -2; } @@ -1872,7 +1890,7 @@ int group_title_get(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *title return -1; } - if (g->title_len == 0 || g->title_len > MAX_NAME_LENGTH) { + if (g->title_len > MAX_NAME_LENGTH || g->title_len == 0) { return -2; } @@ -1882,14 +1900,14 @@ int group_title_get(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *title static bool get_peer_number(const Group_c *g, const uint8_t *real_pk, uint16_t *peer_number) { - const int peer_index = peer_in_chat(g, real_pk); + const int peer_index = peer_in_group(g, real_pk); if (peer_index >= 0) { *peer_number = g->group[peer_index].peer_number; return true; } - const int frozen_index = frozen_in_chat(g, real_pk); + const int frozen_index = frozen_in_group(g, real_pk); if (frozen_index >= 0) { *peer_number = g->frozen[frozen_index].peer_number; @@ -1925,19 +1943,28 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con } return; + } else { + Group_c *g = get_group_c(g_c, groupnumber); + + if (g && g->status == GROUPCHAT_STATUS_CONNECTED) { + send_invite_response(g_c, groupnumber, friendnumber, invite_data, invite_length); + } } break; } - case INVITE_RESPONSE_ID: { - if (length != INVITE_RESPONSE_PACKET_SIZE) { + case INVITE_ACCEPT_ID: + case INVITE_MEMBER_ID: { + const bool member = (data[0] == INVITE_MEMBER_ID); + + if (length != (member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE)) { return; } uint16_t other_groupnum, groupnum; - memcpy(&groupnum, data + 1 + sizeof(uint16_t), sizeof(uint16_t)); - groupnum = net_ntohs(groupnum); + net_unpack_u16(data + 1, &other_groupnum); + net_unpack_u16(data + 1 + sizeof(uint16_t), &groupnum); Group_c *g = get_group_c(g_c, groupnum); @@ -1953,24 +1980,28 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con return; } - /* TODO(irungentoo): what if two people enter the group at the same time and - are given the same peer_number by different nodes? */ - uint16_t peer_number = random_u16(); - - unsigned int tries = 0; + uint16_t peer_number; - while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) { + if (member) { + net_unpack_u16(data + 1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH, &peer_number); + } else { + /* TODO(irungentoo): what if two people enter the group at the + * same time and are given the same peer_number by different + * nodes? */ peer_number = random_u16(); - ++tries; - if (tries > 32) { - return; + unsigned int tries = 0; + + while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) { + peer_number = random_u16(); + ++tries; + + if (tries > 32) { + return; + } } } - memcpy(&other_groupnum, data + 1, sizeof(uint16_t)); - other_groupnum = net_ntohs(other_groupnum); - const int friendcon_id = getfriendcon_id(m, friendnumber); if (friendcon_id == -1) { @@ -1982,55 +2013,57 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id); addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, userdata, true, true); - const int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnum, GROUPCHAT_CLOSE_REASON_INTRODUCING, 1); + const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, + GROUPCHAT_CONNECTION_REASON_INTRODUCING, 1); - if (close_index != -1) { - g->close[close_index].group_number = other_groupnum; - g->close[close_index].type = GROUPCHAT_CLOSE_ONLINE; + if (member) { + add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCER, 0); + send_peer_query(g_c, friendcon_id, other_groupnum); + } + + if (connection_index != -1) { + g->connections[connection_index].group_number = other_groupnum; + g->connections[connection_index].type = GROUPCHAT_CONNECTION_ONLINE; } group_new_peer_send(g_c, groupnum, peer_number, real_pk, temp_pk); + break; } - default: return; } } -/* Find index of friend in the close list; +/* Find index of friend in the connections list. * - * returns index on success - * returns -1 on failure. + * return index on success + * return -1 on failure. */ -static int friend_in_close(const Group_c *g, int friendcon_id) +static int friend_in_connections(const Group_c *g, int friendcon_id) { - unsigned int i; - - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { + for (unsigned int i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { continue; } - if (g->close[i].number != (uint32_t)friendcon_id) { - continue; + if (g->connections[i].number == (uint32_t)friendcon_id) { + return i; } - - return i; } return -1; } -/* return number of connected close connections. +/* return number of connections. */ -static unsigned int count_close_connected(const Group_c *g) +static unsigned int count_connected(const Group_c *g) { - unsigned int i, count = 0; + unsigned int count = 0; - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_ONLINE) { + for (unsigned int i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_ONLINE) { ++count; } } @@ -2051,7 +2084,7 @@ static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16 sizeof(packet), 0) != -1; } -static int ping_groupchat(Group_Chats *g_c, uint32_t groupnumber); +static bool ping_groupchat(Group_Chats *g_c, uint32_t groupnumber); static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_t *data, uint16_t length) { @@ -2075,29 +2108,29 @@ static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_ return -1; } - const int index = friend_in_close(g, friendcon_id); + const int index = friend_in_connections(g, friendcon_id); if (index == -1) { return -1; } - if (g->close[index].type == GROUPCHAT_CLOSE_ONLINE) { + if (g->connections[index].type == GROUPCHAT_CONNECTION_ONLINE) { return -1; } - if (count_close_connected(g) == 0 || (g->close[index].reasons & GROUPCHAT_CLOSE_REASON_INTRODUCER)) { + if (count_connected(g) == 0 || (g->connections[index].reasons & GROUPCHAT_CONNECTION_REASON_INTRODUCER)) { send_peer_query(g_c, friendcon_id, other_groupnum); } - g->close[index].group_number = other_groupnum; - g->close[index].type = GROUPCHAT_CLOSE_ONLINE; + g->connections[index].group_number = other_groupnum; + g->connections[index].type = GROUPCHAT_CONNECTION_ONLINE; send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->type, g->id); - if (g->close[index].reasons & GROUPCHAT_CLOSE_REASON_INTRODUCING) { + if (g->connections[index].reasons & GROUPCHAT_CONNECTION_REASON_INTRODUCING) { uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE], temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id); - const int peer_index = peer_in_chat(g, real_pk); + const int peer_index = peer_in_group(g, real_pk); if (peer_index != -1) { group_new_peer_send(g_c, groupnumber, g->group[peer_index].peer_number, real_pk, temp_pk); @@ -2120,7 +2153,7 @@ static int handle_packet_rejoin(Group_Chats *g_c, int friendcon_id, const uint8_ const int32_t groupnum = get_group_num(g_c, *data, data + 1); - const Group_c *g = get_group_c(g_c, groupnum); + Group_c *g = get_group_c(g_c, groupnum); if (!g) { return -1; @@ -2136,9 +2169,10 @@ static int handle_packet_rejoin(Group_Chats *g_c, int friendcon_id, const uint8_ } addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, userdata, true, true); - const int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnum, GROUPCHAT_CLOSE_REASON_INTRODUCING, 1); + const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, + GROUPCHAT_CONNECTION_REASON_INTRODUCING, 1); - if (close_index != -1) { + if (connection_index != -1) { send_packet_online(g_c->fr_c, friendcon_id, groupnum, g->type, g->id); } @@ -2172,24 +2206,18 @@ static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t /* return number of peers sent on success. * return 0 on failure. */ -static unsigned int send_peers(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id, uint16_t group_num) +static unsigned int send_peers(Group_Chats *g_c, const Group_c *g, int friendcon_id, uint16_t group_num) { - const Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return 0; - } - uint8_t response_packet[MAX_CRYPTO_DATA_SIZE - (1 + sizeof(uint16_t))]; response_packet[0] = PEER_RESPONSE_ID; uint8_t *p = response_packet + 1; uint16_t sent = 0; - uint32_t i; - for (i = 0; i < g->numpeers; ++i) { - if ((p - response_packet) + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE * 2 + 1 + g->group[i].nick_len > sizeof( - response_packet)) { + for (uint32_t i = 0;; ++i) { + if (i == g->numpeers + || (p - response_packet) + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE * 2 + 1 + g->group[i].nick_len > + sizeof(response_packet)) { if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, response_packet, (p - response_packet))) { sent = i; @@ -2197,6 +2225,10 @@ static unsigned int send_peers(Group_Chats *g_c, uint32_t groupnumber, int frien return sent; } + if (i == g->numpeers) { + break; + } + p = response_packet + 1; } @@ -2213,13 +2245,6 @@ static unsigned int send_peers(Group_Chats *g_c, uint32_t groupnumber, int frien p += g->group[i].nick_len; } - if (sent != i) { - if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, response_packet, - (p - response_packet))) { - sent = i; - } - } - if (g->title_len) { VLA(uint8_t, title_packet, 1 + g->title_len); title_packet[0] = PEER_TITLE_ID; @@ -2289,37 +2314,31 @@ static int handle_send_peers(Group_Chats *g_c, uint32_t groupnumber, const uint8 } static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length, - int close_index, void *userdata) + int connection_index, void *userdata) { if (length == 0) { return; } - switch (data[0]) { - case PEER_INTRODUCED_ID: { - const Group_c *g = get_group_c(g_c, groupnumber); + Group_c *g = get_group_c(g_c, groupnumber); - if (!g) { - return; - } + if (!g) { + return; + } - remove_conn_reason(g_c, groupnumber, close_index, GROUPCHAT_CLOSE_REASON_INTRODUCING); + switch (data[0]) { + case PEER_INTRODUCED_ID: { + remove_connection_reason(g_c, g, connection_index, GROUPCHAT_CONNECTION_REASON_INTRODUCING); } break; case PEER_QUERY_ID: { - const Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return; - } - - if (g->close[close_index].type != GROUPCHAT_CLOSE_ONLINE) { + if (g->connections[connection_index].type != GROUPCHAT_CONNECTION_ONLINE) { return; } - send_peers(g_c, groupnumber, g->close[close_index].number, g->close[close_index].group_number); + send_peers(g_c, g, g->connections[connection_index].number, g->connections[connection_index].group_number); } break; @@ -2331,12 +2350,6 @@ static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const u break; case PEER_TITLE_ID: { - const Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - break; - } - if (!g->title_fresh) { settitle(g_c, groupnumber, -1, data + 1, length - 1, userdata); } @@ -2346,24 +2359,18 @@ static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const u } } -/* Send message to all close except receiver (if receiver isn't -1) +/* Send message to all connections except receiver (if receiver isn't -1) * NOTE: this function appends the group chat number to the data passed to it. * * return number of messages sent. */ -static unsigned int send_message_all_close(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, +static unsigned int send_message_all_connections(const Group_Chats *g_c, const Group_c *g, const uint8_t *data, uint16_t length, int receiver) { - const Group_c *g = get_group_c(g_c, groupnumber); - - if (!g) { - return 0; - } - - uint16_t i, sent = 0; + uint16_t sent = 0; - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type != GROUPCHAT_CLOSE_ONLINE) { + for (uint16_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type != GROUPCHAT_CONNECTION_ONLINE) { continue; } @@ -2371,8 +2378,8 @@ static unsigned int send_message_all_close(const Group_Chats *g_c, uint32_t grou continue; } - if (send_packet_group_peer(g_c->fr_c, g->close[i].number, PACKET_ID_MESSAGE_CONFERENCE, g->close[i].group_number, data, - length)) { + if (send_packet_group_peer(g_c->fr_c, g->connections[i].number, PACKET_ID_MESSAGE_CONFERENCE, + g->connections[i].group_number, data, length)) { ++sent; } } @@ -2380,25 +2387,19 @@ static unsigned int send_message_all_close(const Group_Chats *g_c, uint32_t grou return sent; } -/* Send lossy message to all close except receiver (if receiver isn't -1) +/* Send lossy message to all connections except receiver (if receiver isn't -1) * NOTE: this function appends the group chat number to the data passed to it. * * return number of messages sent. */ -static unsigned int send_lossy_all_close(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, +static unsigned int send_lossy_all_connections(const Group_Chats *g_c, const Group_c *g, const uint8_t *data, uint16_t length, int receiver) { - const Group_c *g = get_group_c(g_c, groupnumber); + unsigned int sent = 0, num_connected_closest = 0, connected_closest[DESIRED_CLOSEST]; - if (!g) { - return 0; - } - - unsigned int i, sent = 0, num_connected_closest = 0, connected_closest[DESIRED_CLOSE_CONNECTIONS]; - - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type != GROUPCHAT_CLOSE_ONLINE) { + for (unsigned int i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type != GROUPCHAT_CONNECTION_ONLINE) { continue; } @@ -2406,14 +2407,14 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, uint32_t groupn continue; } - if (g->close[i].reasons & GROUPCHAT_CLOSE_REASON_CLOSEST) { + if (g->connections[i].reasons & GROUPCHAT_CONNECTION_REASON_CLOSEST) { connected_closest[num_connected_closest] = i; ++num_connected_closest; continue; } - if (send_lossy_group_peer(g_c->fr_c, g->close[i].number, PACKET_ID_LOSSY_CONFERENCE, g->close[i].group_number, data, - length)) { + if (send_lossy_group_peer(g_c->fr_c, g->connections[i].number, PACKET_ID_LOSSY_CONFERENCE, + g->connections[i].group_number, data, length)) { ++sent; } } @@ -2422,48 +2423,31 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, uint32_t groupn return sent; } - unsigned int to_send = 0; - uint64_t comp_val_old = ~0; + unsigned int to_send[2] = {0, 0}; + uint64_t comp_val_old[2] = {(uint64_t) -1, (uint64_t) -1}; - for (i = 0; i < num_connected_closest; ++i) { + for (unsigned int i = 0; i < num_connected_closest; ++i) { uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[connected_closest[i]].number); + get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->connections[connected_closest[i]].number); const uint64_t comp_val = calculate_comp_value(g->real_pk, real_pk); - if (comp_val < comp_val_old) { - to_send = connected_closest[i]; - comp_val_old = comp_val; + for (uint8_t j = 0; j < 2; ++j) { + if (j ? (comp_val > comp_val_old[j]) : (comp_val < comp_val_old[j])) { + to_send[j] = connected_closest[i]; + comp_val_old[j] = comp_val; + } } } - if (send_lossy_group_peer(g_c->fr_c, g->close[to_send].number, PACKET_ID_LOSSY_CONFERENCE, - g->close[to_send].group_number, data, length)) { - ++sent; - } - - unsigned int to_send_other = 0; - comp_val_old = ~0; - - for (i = 0; i < num_connected_closest; ++i) { - uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[connected_closest[i]].number); - const uint64_t comp_val = calculate_comp_value(real_pk, g->real_pk); - - if (comp_val < comp_val_old) { - to_send_other = connected_closest[i]; - comp_val_old = comp_val; + for (uint8_t j = 0; j < 2; ++j) { + if (j && to_send[1] == to_send[0]) { + break; } - } - if (to_send_other == to_send) { - return sent; - } - - if (send_lossy_group_peer(g_c->fr_c, g->close[to_send_other].number, PACKET_ID_LOSSY_CONFERENCE, - g->close[to_send_other].group_number, data, length)) { - ++sent; + if (send_lossy_group_peer(g_c->fr_c, g->connections[to_send[j]].number, PACKET_ID_LOSSY_CONFERENCE, + g->connections[to_send[j]].group_number, data, length)) { + ++sent; + } } return sent; @@ -2490,7 +2474,7 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint return -2; } - if (g->status != GROUPCHAT_STATUS_CONNECTED || count_close_connected(g) == 0) { + if (g->status != GROUPCHAT_STATUS_CONNECTED || count_connected(g) == 0) { return -3; } @@ -2513,9 +2497,13 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint memcpy(packet + sizeof(uint16_t) + sizeof(uint32_t) + 1, data, len); } - unsigned int ret = send_message_all_close(g_c, groupnumber, packet, SIZEOF_VLA(packet), -1); + unsigned int ret = send_message_all_connections(g_c, g, packet, SIZEOF_VLA(packet), -1); + + if (ret == 0) { + return -4; + } - return (ret == 0) ? -4 : ret; + return ret; } /* send a group message @@ -2569,7 +2557,7 @@ int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const memcpy(packet + sizeof(uint16_t), &message_num, sizeof(uint16_t)); memcpy(packet + sizeof(uint16_t) * 2, data, length); - if (send_lossy_all_close(g_c, groupnumber, packet, SIZEOF_VLA(packet), -1) == 0) { + if (send_lossy_all_connections(g_c, g, packet, SIZEOF_VLA(packet), -1) == 0) { return -1; } @@ -2584,7 +2572,7 @@ static Message_Info *find_message_slot_or_reject(uint32_t message_number, uint8_ Message_Info *i; for (i = peer->last_message_infos; i < peer->last_message_infos + peer->num_last_message_infos; ++i) { - if (message_number > i->message_number) { + if (message_number - (i->message_number + 1) <= ((uint32_t)1 << 31)) { break; } @@ -2602,7 +2590,7 @@ static Message_Info *find_message_slot_or_reject(uint32_t message_number, uint8_ /* Stores message info in peer->last_message_infos. * - * return true if message should be processed; + * return true if message should be processed. * return false otherwise. */ static bool check_message_info(uint32_t message_number, uint8_t message_id, Group_Peer *peer) @@ -2630,13 +2618,13 @@ static bool check_message_info(uint32_t message_number, uint8_t message_id, Grou } static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length, - int close_index, void *userdata) + int connection_index, void *userdata) { if (length < sizeof(uint16_t) + sizeof(uint32_t) + 1) { return; } - const Group_c *g = get_group_c(g_c, groupnumber); + Group_c *g = get_group_c(g_c, groupnumber); if (!g) { return; @@ -2664,32 +2652,32 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, return; } - if (g->close[close_index].type != GROUPCHAT_CLOSE_ONLINE) { + if (g->connections[connection_index].type != GROUPCHAT_CONNECTION_ONLINE) { return; } /* If we don't know the peer this packet came from, then we query the * list of peers from the relaying peer. - * (They would not have relayed it if they didn't know the peer.) */ - send_peer_query(g_c, g->close[close_index].number, g->close[close_index].group_number); + * (They wouldn't have relayed it if they didn't know the peer.) */ + send_peer_query(g_c, g->connections[connection_index].number, g->connections[connection_index].group_number); return; } - if (g->num_introducer_connections > 0 && count_close_connected(g) > DESIRED_CLOSE_CONNECTIONS) { + if (g->num_introducer_connections > 0 && count_connected(g) > DESIRED_CLOSEST) { for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { - if (g->close[i].type == GROUPCHAT_CLOSE_NONE - || !(g->close[i].reasons & GROUPCHAT_CLOSE_REASON_INTRODUCER) - || i == close_index) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE + || !(g->connections[i].reasons & GROUPCHAT_CONNECTION_REASON_INTRODUCER) + || i == connection_index) { continue; } uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->close[i].number); + get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->connections[i].number); if (id_equal(g->group[index].real_pk, real_pk)) { /* Received message from peer relayed via another peer, so * the introduction was successful */ - remove_conn_reason(g_c, groupnumber, i, GROUPCHAT_CLOSE_REASON_INTRODUCER); + remove_connection_reason(g_c, g, i, GROUPCHAT_CONNECTION_REASON_INTRODUCER); } } } @@ -2727,7 +2715,7 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, if (peer_number == kill_peer_number) { if (message_id == GROUP_MESSAGE_KILL_PEER_ID) { - delpeer(g_c, groupnumber, index, userdata, false); + delpeer(g_c, groupnumber, index, userdata); } else { freeze_peer(g_c, groupnumber, index, userdata); } @@ -2739,14 +2727,14 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, break; case GROUP_MESSAGE_NAME_ID: { - if (setnick(g_c, groupnumber, index, msg_data, msg_data_len, userdata, true) == -1) { + if (!setnick(g_c, groupnumber, index, msg_data, msg_data_len, userdata, true)) { return; } } break; case GROUP_MESSAGE_TITLE_ID: { - if (settitle(g_c, groupnumber, index, msg_data, msg_data_len, userdata) == -1) { + if (!settitle(g_c, groupnumber, index, msg_data, msg_data_len, userdata)) { return; } } @@ -2790,7 +2778,15 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, return; } - send_message_all_close(g_c, groupnumber, data, length, -1/* TODO(irungentoo) close_index */); + /* If the packet was received from the peer who sent the message, relay it + * back. When the sender only has one group connection (e.g. because there + * are only two peers in the group), this is the only way for them to + * receive their own message. */ + uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; + get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->connections[connection_index].number); + bool relay_back = id_equal(g->group[index].real_pk, real_pk); + + send_message_all_connections(g_c, g, data, length, relay_back ? -1 : connection_index); } static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata) @@ -2809,10 +2805,6 @@ static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data, return handle_packet_rejoin(g_c, friendcon_id, data + 1, length - 1, userdata); } - if (data[0] != PACKET_ID_DIRECT_CONFERENCE && data[0] != PACKET_ID_MESSAGE_CONFERENCE) { - return -1; - } - uint16_t groupnumber; memcpy(&groupnumber, data + 1, sizeof(uint16_t)); groupnumber = net_ntohs(groupnumber); @@ -2822,30 +2814,25 @@ static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data, return -1; } - const int index = friend_in_close(g, friendcon_id); + const int index = friend_in_connections(g, friendcon_id); if (index == -1) { return -1; } - switch (data[0]) { - case PACKET_ID_DIRECT_CONFERENCE: { - handle_direct_packet(g_c, groupnumber, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), index, userdata); - break; - } - - case PACKET_ID_MESSAGE_CONFERENCE: { - handle_message_packet_group(g_c, groupnumber, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), index, - userdata); - break; - } + if (data[0] == PACKET_ID_DIRECT_CONFERENCE) { + handle_direct_packet(g_c, groupnumber, data + 1 + sizeof(uint16_t), + length - (1 + sizeof(uint16_t)), index, userdata); + return 0; + } - default: { - return 0; - } + if (data[0] == PACKET_ID_MESSAGE_CONFERENCE) { + handle_message_packet_group(g_c, groupnumber, data + 1 + sizeof(uint16_t), + length - (1 + sizeof(uint16_t)), index, userdata); + return 0; } - return 0; + return -1; } /* Did we already receive the lossy packet or not. @@ -2856,10 +2843,9 @@ static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data, * * TODO(irungentoo): test this */ -static unsigned int lossy_packet_not_received(const Group_c *g, int peer_index, uint16_t message_number) +static int lossy_packet_not_received(const Group_c *g, int peer_index, uint16_t message_number) { if (peer_index == -1) { - // TODO(sudden6): invalid return value return -1; } @@ -2880,7 +2866,6 @@ static unsigned int lossy_packet_not_received(const Group_c *g, int peer_index, } if ((uint16_t)(message_number - g->group[peer_index].bottom_lossy_number) > (1 << 15)) { - // TODO(sudden6): invalid return value return -1; } @@ -2888,21 +2873,18 @@ static unsigned int lossy_packet_not_received(const Group_c *g, int peer_index, if (top_distance >= MAX_LOSSY_COUNT) { crypto_memzero(g->group[peer_index].recv_lossy, sizeof(g->group[peer_index].recv_lossy)); - g->group[peer_index].top_lossy_number = message_number; - g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1; - g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1; } else { // top_distance < MAX_LOSSY_COUNT for (unsigned int i = g->group[peer_index].bottom_lossy_number; i != g->group[peer_index].bottom_lossy_number + top_distance; ++i) { g->group[peer_index].recv_lossy[i % MAX_LOSSY_COUNT] = 0; } - - g->group[peer_index].top_lossy_number = message_number; - g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1; - g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1; } + g->group[peer_index].top_lossy_number = message_number; + g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1; + g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1; + return 0; } @@ -2917,11 +2899,11 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin { Group_Chats *g_c = (Group_Chats *)object; - if (length < 1 + sizeof(uint16_t) * 3 + 1) { + if (data[0] != PACKET_ID_LOSSY_CONFERENCE) { return -1; } - if (data[0] != PACKET_ID_LOSSY_CONFERENCE) { + if (length < 1 + sizeof(uint16_t) * 3 + 1) { return -1; } @@ -2943,7 +2925,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin return -1; } - const int index = friend_in_close(g, friendcon_id); + const int index = friend_in_connections(g, friendcon_id); if (index == -1) { return -1; @@ -2959,7 +2941,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin return -1; } - if (lossy_packet_not_received(g, peer_index, message_number)) { + if (lossy_packet_not_received(g, peer_index, message_number) != 0) { return -1; } @@ -2969,14 +2951,14 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin ++lossy_data; --lossy_length; - send_lossy_all_close(g_c, groupnumber, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), index); + send_lossy_all_connections(g_c, g, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), index); - if (g_c->lossy_packethandlers[message_id].function) { - if (g_c->lossy_packethandlers[message_id].function(g->object, groupnumber, peer_index, g->group[peer_index].object, - lossy_data, lossy_length) == -1) { - return -1; - } - } else { + if (!g_c->lossy_packethandlers[message_id].function) { + return -1; + } + + if (g_c->lossy_packethandlers[message_id].function(g->object, groupnumber, peer_index, g->group[peer_index].object, + lossy_data, lossy_length) == -1) { return -1; } @@ -3005,7 +2987,7 @@ int group_set_object(const Group_Chats *g_c, uint32_t groupnumber, void *object) * return 0 on success. * return -1 on failure */ -int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, void *object) +int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, void *object) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -3013,7 +2995,7 @@ int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, int peer return -1; } - if ((uint32_t)peernumber >= g->numpeers) { + if (peernumber >= g->numpeers) { return -1; } @@ -3042,7 +3024,7 @@ void *group_get_object(const Group_Chats *g_c, uint32_t groupnumber) * return NULL on failure. * return object on success. */ -void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, int peernumber) +void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber) { const Group_c *g = get_group_c(g_c, groupnumber); @@ -3050,7 +3032,7 @@ void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, int pe return nullptr; } - if ((uint32_t)peernumber >= g->numpeers) { + if (peernumber >= g->numpeers) { return nullptr; } @@ -3060,29 +3042,32 @@ void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, int pe /* Interval in seconds to send ping messages */ #define GROUP_PING_INTERVAL 20 -static int ping_groupchat(Group_Chats *g_c, uint32_t groupnumber) +static bool ping_groupchat(Group_Chats *g_c, uint32_t groupnumber) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; + return false; } if (mono_time_is_timeout(g_c->mono_time, g->last_sent_ping, GROUP_PING_INTERVAL)) { - if (group_ping_send(g_c, groupnumber) != -1) { /* Ping */ + if (group_ping_send(g_c, groupnumber)) { g->last_sent_ping = mono_time_get(g_c->mono_time); } } - return 0; + return true; } -static int groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, void *userdata) +/* Seconds of inactivity after which to freeze a peer */ +#define FREEZE_TIMEOUT (GROUP_PING_INTERVAL * 3) + +static bool groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, void *userdata) { Group_c *g = get_group_c(g_c, groupnumber); if (!g) { - return -1; + return false; } for (uint32_t i = 0; i < g->numpeers; ++i) { @@ -3090,7 +3075,7 @@ static int groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, voi continue; } - if (mono_time_is_timeout(g_c->mono_time, g->group[i].last_active, GROUP_PING_INTERVAL * 3)) { + if (mono_time_is_timeout(g_c->mono_time, g->group[i].last_active, FREEZE_TIMEOUT)) { freeze_peer(g_c, groupnumber, i, userdata); } } @@ -3099,7 +3084,74 @@ static int groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, voi g->title_fresh = false; } - return 0; + return true; +} + +/* Push non-empty slots to start. */ +static void squash_connections(Group_c *g) +{ + uint16_t i = 0; + + for (uint16_t j = 0; j < MAX_GROUP_CONNECTIONS; ++j) { + if (g->connections[j].type != GROUPCHAT_CONNECTION_NONE) { + g->connections[i] = g->connections[j]; + ++i; + } + } + + for (; i < MAX_GROUP_CONNECTIONS; ++i) { + g->connections[i].type = GROUPCHAT_CONNECTION_NONE; + } +} + +#define MIN_EMPTY_CONNECTIONS (1 + MAX_GROUP_CONNECTIONS / 10) + +/* Remove old connections as necessary to ensure we have space for new + * connections. This invalidates connections array indices (which is + * why we do this periodically rather than on adding a connection). + */ +static void clean_connections(Group_Chats *g_c, Group_c *g) +{ + uint16_t to_clear = MIN_EMPTY_CONNECTIONS; + + for (uint16_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + if (g->connections[i].type == GROUPCHAT_CONNECTION_NONE) { + --to_clear; + + if (to_clear == 0) { + break; + } + } + } + + for (; to_clear > 0; --to_clear) { + // Remove a connection. Prefer non-closest connections, and given + // that prefer non-online connections, and given that prefer earlier + // slots. + uint16_t i = 0; + + while (i < MAX_GROUP_CONNECTIONS + && (g->connections[i].type != GROUPCHAT_CONNECTION_CONNECTING + || (g->connections[i].reasons & GROUPCHAT_CONNECTION_REASON_CLOSEST))) { + ++i; + } + + if (i == MAX_GROUP_CONNECTIONS) { + i = 0; + + while (i < MAX_GROUP_CONNECTIONS - to_clear + && (g->connections[i].type != GROUPCHAT_CONNECTION_ONLINE + || (g->connections[i].reasons & GROUPCHAT_CONNECTION_REASON_CLOSEST))) { + ++i; + } + } + + if (g->connections[i].type != GROUPCHAT_CONNECTION_NONE) { + remove_connection(g_c, g, i); + } + } + + squash_connections(g); } /* Send current name (set in messenger) to all online groups. @@ -3170,6 +3222,11 @@ static uint32_t saved_conf_size(const Group_c *g) return len; } +/* Save a future message number. The save will remain valid until we have sent + * this many more messages. */ +#define SAVE_OFFSET_MESSAGE_NUMBER (1 << 16) +#define SAVE_OFFSET_LOSSY_MESSAGE_NUMBER (1 << 13) + static uint8_t *save_conf(const Group_c *g, uint8_t *data) { *data = g->type; @@ -3178,10 +3235,10 @@ static uint8_t *save_conf(const Group_c *g, uint8_t *data) memcpy(data, g->id, GROUP_ID_LENGTH); data += GROUP_ID_LENGTH; - host_to_lendian_bytes32(data, g->message_number); + host_to_lendian_bytes32(data, g->message_number + SAVE_OFFSET_MESSAGE_NUMBER); data += sizeof(uint32_t); - host_to_lendian_bytes16(data, g->lossy_message_number); + host_to_lendian_bytes16(data, g->lossy_message_number + SAVE_OFFSET_LOSSY_MESSAGE_NUMBER); data += sizeof(uint16_t); host_to_lendian_bytes16(data, g->peer_number); @@ -3294,6 +3351,11 @@ static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data, } g->title_len = *data; + + if (g->title_len > MAX_NAME_LENGTH) { + return STATE_LOAD_STATUS_ERROR; + } + ++data; if (length < (uint32_t)(data - init_data) + g->title_len) { @@ -3323,6 +3385,11 @@ static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data, data += sizeof(uint64_t); peer->nick_len = *data; + + if (peer->nick_len > MAX_NAME_LENGTH) { + return STATE_LOAD_STATUS_ERROR; + } + ++data; if (length < (uint32_t)(data - init_data) + peer->nick_len) { @@ -3405,6 +3472,7 @@ void do_groupchats(Group_Chats *g_c, void *userdata) connect_to_closest(g_c, i, userdata); ping_groupchat(g_c, i); groupchat_freeze_timedout(g_c, i, userdata); + clean_connections(g_c, g); if (g->need_send_name) { group_name_send(g_c, i, g_c->m->name, g_c->m->name_length); @@ -3424,6 +3492,7 @@ void kill_groupchats(Group_Chats *g_c) } m_callback_conference_invite(g_c->m, nullptr); + set_global_status_callback(g_c->m->fr_c, nullptr, nullptr); g_c->m->conferences_object = nullptr; free(g_c); } diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h index 884ac8f5d4..1e054de3c6 100644 --- a/protocols/Tox/libtox/src/toxcore/group.h +++ b/protocols/Tox/libtox/src/toxcore/group.h @@ -1,25 +1,10 @@ -/* - * Slightly better groupchats implementation. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Slightly better groupchats implementation. */ #ifndef C_TOXCORE_TOXCORE_GROUP_H #define C_TOXCORE_TOXCORE_GROUP_H @@ -29,12 +14,12 @@ typedef enum Groupchat_Status { GROUPCHAT_STATUS_NONE, GROUPCHAT_STATUS_VALID, - GROUPCHAT_STATUS_CONNECTED + GROUPCHAT_STATUS_CONNECTED, } Groupchat_Status; typedef enum Groupchat_Type { GROUPCHAT_TYPE_TEXT, - GROUPCHAT_TYPE_AV + GROUPCHAT_TYPE_AV, } Groupchat_Type; #define MAX_LOSSY_COUNT 256 @@ -71,37 +56,37 @@ typedef struct Group_Peer { void *object; } Group_Peer; -#define DESIRED_CLOSE_CONNECTIONS 4 +#define DESIRED_CLOSEST 4 #define MAX_GROUP_CONNECTIONS 16 #define GROUP_ID_LENGTH CRYPTO_SYMMETRIC_KEY_SIZE -typedef enum Groupchat_Close_Type { - GROUPCHAT_CLOSE_NONE, - GROUPCHAT_CLOSE_CONNECTION, - GROUPCHAT_CLOSE_ONLINE -} Groupchat_Close_Type; +typedef enum Groupchat_Connection_Type { + GROUPCHAT_CONNECTION_NONE, + GROUPCHAT_CONNECTION_CONNECTING, + GROUPCHAT_CONNECTION_ONLINE, +} Groupchat_Connection_Type; -/* Connection is to one of the closest DESIRED_CLOSE_CONNECTIONS peers */ -#define GROUPCHAT_CLOSE_REASON_CLOSEST (1 << 0) +/* Connection is to one of the closest DESIRED_CLOSEST peers */ +#define GROUPCHAT_CONNECTION_REASON_CLOSEST (1 << 0) /* Connection is to a peer we are introducing to the conference */ -#define GROUPCHAT_CLOSE_REASON_INTRODUCING (1 << 1) +#define GROUPCHAT_CONNECTION_REASON_INTRODUCING (1 << 1) /* Connection is to a peer who is introducing us to the conference */ -#define GROUPCHAT_CLOSE_REASON_INTRODUCER (1 << 2) +#define GROUPCHAT_CONNECTION_REASON_INTRODUCER (1 << 2) -typedef struct Groupchat_Close { - uint8_t type; /* GROUPCHAT_CLOSE_* */ - uint8_t reasons; /* bit field with flags GROUPCHAT_CLOSE_REASON_* */ +typedef struct Groupchat_Connection { + uint8_t type; /* `GROUPCHAT_CONNECTION_*` */ + uint8_t reasons; /* bit field with flags `GROUPCHAT_CONNECTION_REASON_*` */ uint32_t number; uint16_t group_number; -} Groupchat_Close; +} Groupchat_Connection; -typedef struct Groupchat_Close_Connection { +typedef struct Groupchat_Closest { uint8_t entry; uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; -} Groupchat_Close_Connection; +} Groupchat_Closest; typedef void peer_on_join_cb(void *object, uint32_t conference_number, uint32_t peer_number); typedef void peer_on_leave_cb(void *object, uint32_t conference_number, void *peer_object); @@ -124,11 +109,10 @@ typedef struct Group_c { uint32_t maxfrozen; - /* TODO(zugz) rename close to something more accurate - "connected"? */ - Groupchat_Close close[MAX_GROUP_CONNECTIONS]; + Groupchat_Connection connections[MAX_GROUP_CONNECTIONS]; uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - Groupchat_Close_Connection closest_peers[DESIRED_CLOSE_CONNECTIONS]; + Groupchat_Closest closest_peers[DESIRED_CLOSEST]; uint8_t changed; uint8_t type; @@ -237,7 +221,7 @@ void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *functi /* Creates a new groupchat and puts it in the chats array. * - * type is one of GROUPCHAT_TYPE_* + * type is one of `GROUPCHAT_TYPE_*` * * return group number on success. * return -1 on failure. @@ -260,7 +244,7 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, uint8_t *pk, bool frozen); +int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint8_t *pk, bool frozen); /* * Return the size of (frozen, if frozen is true) peernumber's name. @@ -268,7 +252,7 @@ int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, int peernumb * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, int32_t peernumber, bool frozen); +int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, bool frozen); /* Copy the name of (frozen, if frozen is true) peernumber who is in * groupnumber to name. @@ -278,7 +262,7 @@ int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, int32_t pe * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, uint8_t *name, bool frozen); +int group_peername(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint8_t *name, bool frozen); /* Copy last active timestamp of frozen peernumber who is in groupnumber to * last_active. @@ -287,7 +271,7 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, * return -1 if groupnumber is invalid. * return -2 if peernumber is invalid. */ -int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, +int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint64_t *last_active); /* Set maximum number of frozen peers. @@ -307,7 +291,8 @@ int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber) /* Join a group (you need to have been invited first.) * - * expected_type is the groupchat type we expect the chat we are joining is. + * expected_type is the groupchat type we expect the chat we are joining to + * have. * * return group number on success. * return -1 if data length is invalid. @@ -368,13 +353,13 @@ int group_number_peers(const Group_Chats *g_c, uint32_t groupnumber, bool frozen * return -2 if peernumber is invalid. * return -3 if we are not connected to the group chat. */ -int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, int peernumber); +int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber); /* List all the (frozen, if frozen is true) peers in the group chat. * - * Copies the names of the peers to the name[length][MAX_NAME_LENGTH] array. + * Copies the names of the peers to the `name[length][MAX_NAME_LENGTH]` array. * - * Copies the lengths of the names to lengths[length] + * Copies the lengths of the names to `lengths[length]` * * returns the number of peers on success. * @@ -413,11 +398,11 @@ uint32_t copy_chatlist(const Group_Chats *g_c, uint32_t *out_list, uint32_t list */ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber); -/* Copies the unique id of group_chat[groupnumber] into id. -* -* return false on failure. -* return true on success. -*/ +/* Copies the unique id of `group_chat[groupnumber]` into id. + * + * return false on failure. + * return true on success. + */ bool conference_get_id(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *id); int32_t conference_by_id(const Group_Chats *g_c, const uint8_t *id); @@ -438,7 +423,7 @@ int group_set_object(const Group_Chats *g_c, uint32_t groupnumber, void *object) * return 0 on success. * return -1 on failure */ -int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, int peernumber, void *object); +int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, void *object); /* Return the object tied to the group chat previously set by group_set_object. * @@ -452,7 +437,7 @@ void *group_get_object(const Group_Chats *g_c, uint32_t groupnumber); * return NULL on failure. * return object on success. */ -void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, int peernumber); +void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber); /* Set a function to be called when a new peer joins a group chat. * @@ -486,7 +471,7 @@ uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data); * * @param data Data to load * @param length Length of data - * @param type Type of section (STATE_TYPE_*) + * @param type Type of section (`STATE_TYPE_*`) * @param status Result of loading section is stored here if the section is handled. * @return true iff section handled. */ diff --git a/protocols/Tox/libtox/src/toxcore/list.c b/protocols/Tox/libtox/src/toxcore/list.c index 1cc143e24f..cb3c71cc2a 100644 --- a/protocols/Tox/libtox/src/toxcore/list.c +++ b/protocols/Tox/libtox/src/toxcore/list.c @@ -1,28 +1,13 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. + */ + /* * Simple struct with functions to create a list which associates ids with data * -Allows for finding ids associated with data such as IPs or public keys in a short time * -Should only be used if there are relatively few add/remove calls to the list */ - -/* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. - */ #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/protocols/Tox/libtox/src/toxcore/list.h b/protocols/Tox/libtox/src/toxcore/list.h index c9c72c2a80..9d65b53fc6 100644 --- a/protocols/Tox/libtox/src/toxcore/list.h +++ b/protocols/Tox/libtox/src/toxcore/list.h @@ -1,28 +1,13 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. + */ + /* * Simple struct with functions to create a list which associates ids with data * -Allows for finding ids associated with data such as IPs or public keys in a short time * -Should only be used if there are relatively few add/remove calls to the list */ - -/* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. - */ #ifndef C_TOXCORE_TOXCORE_LIST_H #define C_TOXCORE_TOXCORE_LIST_H diff --git a/protocols/Tox/libtox/src/toxcore/logger.c b/protocols/Tox/libtox/src/toxcore/logger.c index 808332198c..00e85c36ff 100644 --- a/protocols/Tox/libtox/src/toxcore/logger.c +++ b/protocols/Tox/libtox/src/toxcore/logger.c @@ -1,25 +1,10 @@ -/* - * Text logging abstraction. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013,2015 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013,2015 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Text logging abstraction. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/logger.h b/protocols/Tox/libtox/src/toxcore/logger.h index 3abed896c2..cbd8752b9b 100644 --- a/protocols/Tox/libtox/src/toxcore/logger.h +++ b/protocols/Tox/libtox/src/toxcore/logger.h @@ -1,25 +1,10 @@ -/* - * Logger abstraction backed by callbacks for writing. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Logger abstraction backed by callbacks for writing. */ #ifndef C_TOXCORE_TOXCORE_LOGGER_H #define C_TOXCORE_TOXCORE_LOGGER_H @@ -38,7 +23,7 @@ typedef enum Logger_Level { LOGGER_LEVEL_DEBUG, LOGGER_LEVEL_INFO, LOGGER_LEVEL_WARNING, - LOGGER_LEVEL_ERROR + LOGGER_LEVEL_ERROR, } Logger_Level; typedef struct Logger Logger; diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.c b/protocols/Tox/libtox/src/toxcore/mono_time.c index 6e4bc067d3..876902f52f 100644 --- a/protocols/Tox/libtox/src/toxcore/mono_time.c +++ b/protocols/Tox/libtox/src/toxcore/mono_time.c @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2020 The TokTok team. + * Copyright © 2014 Tox project. + */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif @@ -19,6 +23,7 @@ #include "mono_time.h" +#include <pthread.h> #include <stdlib.h> #include <time.h> @@ -29,32 +34,47 @@ struct Mono_Time { uint64_t time; uint64_t base_time; #ifdef OS_WIN32 - uint64_t last_clock_mono; - uint64_t add_clock_mono; + /* protect `last_clock_update` and `last_clock_mono` from concurrent access */ + pthread_mutex_t last_clock_lock; + uint32_t last_clock_mono; + bool last_clock_update; #endif + /* protect `time` from concurrent access */ + pthread_rwlock_t *time_update_lock; + mono_time_current_time_cb *current_time_callback; void *user_data; }; static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_data) { - uint64_t time; + uint64_t time = 0; #ifdef OS_WIN32 - uint64_t old_add_clock_mono = mono_time->add_clock_mono; - time = (uint64_t)GetTickCount() + mono_time->add_clock_mono; - - /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race - * conditions when multiple threads call this function at once */ - if (time + 0x10000 < mono_time->last_clock_mono) { - uint32_t add = ~0; - /* use old_add_clock_mono rather than simply incrementing add_clock_mono, to handle the case that many threads - * simultaneously detect an overflow */ - mono_time->add_clock_mono = old_add_clock_mono + add; - time += add; + /* Must hold mono_time->last_clock_lock here */ + + /* GetTickCount provides only a 32 bit counter, but we can't use + * GetTickCount64 for backwards compatibility, so we handle wraparound + * ourselves. + */ + uint32_t ticks = GetTickCount(); + + /* the higher 32 bits count the number of wrap arounds */ + uint64_t old_ovf = mono_time->time & ~((uint64_t)UINT32_MAX); + + /* Check if time has decreased because of 32 bit wrap from GetTickCount() */ + if (ticks < mono_time->last_clock_mono) { + /* account for overflow */ + old_ovf += UINT32_MAX + UINT64_C(1); + } + + if (mono_time->last_clock_update) { + mono_time->last_clock_mono = ticks; + mono_time->last_clock_update = false; } - mono_time->last_clock_mono = time; + /* splice the low and high bits back together */ + time = old_ovf + ticks; #else struct timespec clock_mono; #if defined(__APPLE__) @@ -83,12 +103,33 @@ Mono_Time *mono_time_new(void) return nullptr; } + mono_time->time_update_lock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); + + if (mono_time->time_update_lock == nullptr) { + free(mono_time); + return nullptr; + } + + if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) < 0) { + free(mono_time->time_update_lock); + free(mono_time); + return nullptr; + } + mono_time->current_time_callback = current_time_monotonic_default; mono_time->user_data = nullptr; #ifdef OS_WIN32 + mono_time->last_clock_mono = 0; - mono_time->add_clock_mono = 0; + mono_time->last_clock_update = false; + + if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) { + free(mono_time->time_update_lock); + free(mono_time); + return nullptr; + } + #endif mono_time->time = 0; @@ -101,17 +142,40 @@ Mono_Time *mono_time_new(void) void mono_time_free(Mono_Time *mono_time) { +#ifdef OS_WIN32 + pthread_mutex_destroy(&mono_time->last_clock_lock); +#endif + pthread_rwlock_destroy(mono_time->time_update_lock); + free(mono_time->time_update_lock); free(mono_time); } void mono_time_update(Mono_Time *mono_time) { - mono_time->time = (current_time_monotonic(mono_time) / 1000ULL) + mono_time->base_time; + uint64_t time = 0; +#ifdef OS_WIN32 + /* we actually want to update the overflow state of mono_time here */ + pthread_mutex_lock(&mono_time->last_clock_lock); + mono_time->last_clock_update = true; +#endif + time = mono_time->current_time_callback(mono_time, mono_time->user_data) / 1000ULL; + time += mono_time->base_time; +#ifdef OS_WIN32 + pthread_mutex_unlock(&mono_time->last_clock_lock); +#endif + + pthread_rwlock_wrlock(mono_time->time_update_lock); + mono_time->time = time; + pthread_rwlock_unlock(mono_time->time_update_lock); } uint64_t mono_time_get(const Mono_Time *mono_time) { - return mono_time->time; + uint64_t time = 0; + pthread_rwlock_rdlock(mono_time->time_update_lock); + time = mono_time->time; + pthread_rwlock_unlock(mono_time->time_update_lock); + return time; } bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout) @@ -134,5 +198,15 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time, /* return current monotonic time in milliseconds (ms). */ uint64_t current_time_monotonic(Mono_Time *mono_time) { - return mono_time->current_time_callback(mono_time, mono_time->user_data); + /* For WIN32 we don't want to change overflow state of mono_time here */ +#ifdef OS_WIN32 + /* We don't want to update the overflow state of mono_time here, + * but must protect against other threads */ + pthread_mutex_lock(&mono_time->last_clock_lock); +#endif + uint64_t time = mono_time->current_time_callback(mono_time, mono_time->user_data); +#ifdef OS_WIN32 + pthread_mutex_unlock(&mono_time->last_clock_lock); +#endif + return time; } diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.h b/protocols/Tox/libtox/src/toxcore/mono_time.h index aa244baeb0..0951fc7499 100644 --- a/protocols/Tox/libtox/src/toxcore/mono_time.h +++ b/protocols/Tox/libtox/src/toxcore/mono_time.h @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2020 The TokTok team. + * Copyright © 2014 Tox project. + */ #ifndef C_TOXCORE_TOXCORE_MONO_TIME_H #define C_TOXCORE_TOXCORE_MONO_TIME_H diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c index b53146137c..fb69b7685f 100644 --- a/protocols/Tox/libtox/src/toxcore/net_crypto.c +++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c @@ -1,27 +1,12 @@ -/* - * Functions for the core network crypto. - * - * NOTE: This code has to be perfect. We don't mess around with encryption. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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. + * Functions for the core network crypto. * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see <http://www.gnu.org/licenses/>. + * NOTE: This code has to be perfect. We don't mess around with encryption. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -45,9 +30,21 @@ typedef struct Packet_Data { typedef struct Packets_Array { Packet_Data *buffer[CRYPTO_PACKET_BUFFER_SIZE]; uint32_t buffer_start; - uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */ + uint32_t buffer_end; /* packet numbers in array: `{buffer_start, buffer_end)` */ } Packets_Array; +typedef enum Crypto_Conn_State { + CRYPTO_CONN_FREE = 0, /* the connection slot is free. This value is 0 so it is valid after + * `crypto_memzero(...)` of the parent struct + */ + CRYPTO_CONN_NO_CONNECTION, /* the connection is allocated, but not yet used */ + CRYPTO_CONN_COOKIE_REQUESTING, /* we are sending cookie request packets */ + CRYPTO_CONN_HANDSHAKE_SENT, /* we are sending handshake packets */ + CRYPTO_CONN_NOT_CONFIRMED, /* we are sending handshake packets. + * we have received one from the other, but no data */ + CRYPTO_CONN_ESTABLISHED, /* the connection is established */ +} Crypto_Conn_State; + typedef struct Crypto_Connection { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ @@ -56,14 +53,7 @@ typedef struct Crypto_Connection { uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. */ - /** - * 0 if no connection, - * 1 we are sending cookie request packets, - * 2 if we are sending handshake packets, - * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), - * 4 if the connection is established. - */ - Crypto_Conn_State status; + Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ @@ -125,7 +115,8 @@ typedef struct Crypto_Connection { uint8_t maximum_speed_reached; - pthread_mutex_t mutex; + /* Must be a pointer, because the struct is moved in memory */ + pthread_mutex_t *mutex; dht_pk_cb *dht_pk_callback; void *dht_pk_callback_object; @@ -193,7 +184,9 @@ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_conn return 1; } - if (c->crypto_connections[crypt_connection_id].status == CRYPTO_CONN_NO_CONNECTION) { + const Crypto_Conn_State status = c->crypto_connections[crypt_connection_id].status; + + if (status == CRYPTO_CONN_NO_CONNECTION || status == CRYPTO_CONN_FREE) { return 1; } @@ -680,28 +673,30 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t int direct_send_attempt = 0; - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. if (!net_family_is_unspec(ip_port.ip.family)) { bool direct_connected = 0; + + // FIXME(sudden6): handle return value crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr); if (direct_connected) { if ((uint32_t)sendpacket(dht_get_net(c->dht), ip_port, data, length) == length) { - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); return 0; } - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); return -1; } // TODO(irungentoo): a better way of sending packets directly to confirm the others ip. const uint64_t current_time = mono_time_get(c->mono_time); - if ((((UDP_DIRECT_TIMEOUT / 2) + conn->direct_send_attempt_time) > current_time && length < 96) + if ((((UDP_DIRECT_TIMEOUT / 2) + conn->direct_send_attempt_time) < current_time && length < 96) || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) { if ((uint32_t)sendpacket(dht_get_net(c->dht), ip_port, data, length) == length) { direct_send_attempt = 1; @@ -710,18 +705,18 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t } } - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); pthread_mutex_lock(&c->tcp_mutex); int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length); pthread_mutex_unlock(&c->tcp_mutex); - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); if (ret == 0) { conn->last_tcp_sent = current_time_monotonic(c->mono_time); } - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); if (ret == 0 || direct_send_attempt) { return 0; @@ -730,7 +725,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } -/** START: Array Related functions **/ +/** START: Array Related functions */ /* Return number of packets in array @@ -994,7 +989,7 @@ static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packet uint32_t requested = 0; const uint64_t temp_time = current_time_monotonic(mono_time); - uint64_t l_sent_time = ~0; + uint64_t l_sent_time = -1; for (uint32_t i = send_array->buffer_start; i != send_array->buffer_end; ++i) { if (length == 0) { @@ -1050,7 +1045,7 @@ static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packet return requested; } -/** END: Array Related functions **/ +/** END: Array Related functions */ #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)) @@ -1073,19 +1068,19 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ return -1; } - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); if (len + 1 + sizeof(uint16_t) != SIZEOF_VLA(packet)) { - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); return -1; } increment_nonce(conn->sent_nonce); - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); return send_packet_to(c, crypt_connection_id, packet, SIZEOF_VLA(packet)); } @@ -1172,9 +1167,9 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons dt.sent_time = 0; dt.length = length; memcpy(dt.data, data, length); - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt); - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); if (packet_num == -1) { return -1; @@ -1476,7 +1471,18 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda userdata); } + while (1) { /* TODO(irungentoo): is this really the best way to do this? */ + pthread_mutex_lock(&c->connections_mutex); + + if (!c->connection_use_counter) { + break; + } + + pthread_mutex_unlock(&c->connections_mutex); + } + crypto_kill(c, crypt_connection_id); + pthread_mutex_unlock(&c->connections_mutex); } /* Handle a received data packet. @@ -1578,9 +1584,9 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } while (1) { - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); int ret = read_data_beg_buffer(c->log, &conn->recv_array, &dt); - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); if (ret == -1) { break; @@ -1748,12 +1754,6 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) */ static int create_crypto_connection(Net_Crypto *c) { - for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { - if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { - return i; - } - } - while (1) { /* TODO(irungentoo): is this really the best way to do this? */ pthread_mutex_lock(&c->connections_mutex); @@ -1766,21 +1766,42 @@ static int create_crypto_connection(Net_Crypto *c) int id = -1; - if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) { - id = c->crypto_connections_length; - ++c->crypto_connections_length; - memset(&c->crypto_connections[id], 0, sizeof(Crypto_Connection)); + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { + if (c->crypto_connections[i].status == CRYPTO_CONN_FREE) { + id = i; + break; + } + } + + if (id == -1) { + if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) { + id = c->crypto_connections_length; + ++c->crypto_connections_length; + memset(&c->crypto_connections[id], 0, sizeof(Crypto_Connection)); + } + } + + if (id != -1) { // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 c->crypto_connections[id].packet_recv_rate = 0; c->crypto_connections[id].packet_send_rate = 0; c->crypto_connections[id].last_packets_left_rem = 0; c->crypto_connections[id].packet_send_rate_requested = 0; c->crypto_connections[id].last_packets_left_requested_rem = 0; + c->crypto_connections[id].mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); - if (pthread_mutex_init(&c->crypto_connections[id].mutex, nullptr) != 0) { + if (c->crypto_connections[id].mutex == nullptr) { pthread_mutex_unlock(&c->connections_mutex); return -1; } + + if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { + free(c->crypto_connections[id].mutex); + pthread_mutex_unlock(&c->connections_mutex); + return -1; + } + + c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } pthread_mutex_unlock(&c->connections_mutex); @@ -1794,21 +1815,29 @@ static int create_crypto_connection(Net_Crypto *c) */ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) { - if (crypt_connection_id_not_valid(c, crypt_connection_id)) { + if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) { + return -1; + } + + if (c->crypto_connections == nullptr) { + return -1; + } + + const Crypto_Conn_State status = c->crypto_connections[crypt_connection_id].status; + + if (status == CRYPTO_CONN_FREE) { return -1; } uint32_t i; - /* Keep mutex, only destroy it when connection is realloced out. */ - pthread_mutex_t mutex = c->crypto_connections[crypt_connection_id].mutex; + pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); + free(c->crypto_connections[crypt_connection_id].mutex); crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); - c->crypto_connections[crypt_connection_id].mutex = mutex; + /* check if we can resize the connections array */ for (i = c->crypto_connections_length; i != 0; --i) { - if (c->crypto_connections[i - 1].status == CRYPTO_CONN_NO_CONNECTION) { - pthread_mutex_destroy(&c->crypto_connections[i - 1].mutex); - } else { + if (c->crypto_connections[i - 1].status != CRYPTO_CONN_FREE) { break; } } @@ -1829,10 +1858,12 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) { for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { - if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) { - if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) { - return i; - } + if (crypt_connection_id_not_valid(c, i)) { + continue; + } + + if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) { + return i; } } @@ -1975,6 +2006,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; if (n_c->cookie_length != COOKIE_LENGTH) { + wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -1983,6 +2015,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) pthread_mutex_unlock(&c->tcp_mutex); if (connection_number_tcp == -1) { + wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -1999,7 +2032,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); pthread_mutex_unlock(&c->tcp_mutex); - conn->status = CRYPTO_CONN_NO_CONNECTION; + wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -2039,6 +2072,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u pthread_mutex_unlock(&c->tcp_mutex); if (connection_number_tcp == -1) { + wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -2062,7 +2096,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); pthread_mutex_unlock(&c->tcp_mutex); - conn->status = CRYPTO_CONN_NO_CONNECTION; + wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -2259,19 +2293,24 @@ static void do_tcp(Net_Crypto *c, void *userdata) continue; } - if (conn->status == CRYPTO_CONN_ESTABLISHED) { - bool direct_connected = 0; - crypto_connection_status(c, i, &direct_connected, nullptr); + if (conn->status != CRYPTO_CONN_ESTABLISHED) { + continue; + } - if (direct_connected) { - pthread_mutex_lock(&c->tcp_mutex); - set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0); - pthread_mutex_unlock(&c->tcp_mutex); - } else { - pthread_mutex_lock(&c->tcp_mutex); - set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1); - pthread_mutex_unlock(&c->tcp_mutex); - } + bool direct_connected = 0; + + if (!crypto_connection_status(c, i, &direct_connected, nullptr)) { + continue; + } + + if (direct_connected) { + pthread_mutex_lock(&c->tcp_mutex); + set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0); + pthread_mutex_unlock(&c->tcp_mutex); + } else { + pthread_mutex_lock(&c->tcp_mutex); + set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1); + pthread_mutex_unlock(&c->tcp_mutex); } } } @@ -2425,7 +2464,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet return -1; } - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); if (net_family_is_ipv4(source.ip.family)) { conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time); @@ -2433,7 +2472,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time); } - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); return 0; } @@ -2459,7 +2498,7 @@ static void send_crypto_packets(Net_Crypto *c) { const uint64_t temp_time = current_time_monotonic(c->mono_time); double total_send_rate = 0; - uint32_t peak_request_packet_interval = ~0; + uint32_t peak_request_packet_interval = -1; for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { Crypto_Connection *conn = get_crypto_connection(c, i); @@ -2542,6 +2581,7 @@ static void send_crypto_packets(Net_Crypto *c) (CONGESTION_QUEUE_ARRAY_SIZE * CONGESTION_LAST_SENT_ARRAY_SIZE); bool direct_connected = 0; + /* return value can be ignored since the `if` above ensures the connection is established */ crypto_connection_status(c, i, &direct_connected, nullptr); /* When switching from TCP to UDP, don't change the packet send rate for CONGESTION_EVENT_TIMEOUT ms. */ @@ -2667,7 +2707,7 @@ static void send_crypto_packets(Net_Crypto *c) } } - c->current_sleep_time = ~0; + c->current_sleep_time = -1; uint32_t sleep_time = peak_request_packet_interval; if (c->current_sleep_time > sleep_time) { @@ -2824,10 +2864,10 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t int ret = -1; if (conn) { - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(conn->mutex); uint32_t buffer_start = conn->recv_array.buffer_start; uint32_t buffer_end = conn->send_array.buffer_end; - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(conn->mutex); ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length); } @@ -2845,16 +2885,6 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t */ int crypto_kill(Net_Crypto *c, int crypt_connection_id) { - while (1) { /* TODO(irungentoo): is this really the best way to do this? */ - pthread_mutex_lock(&c->connections_mutex); - - if (!c->connection_use_counter) { - break; - } - - pthread_mutex_unlock(&c->connections_mutex); - } - Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); int ret = -1; @@ -2876,23 +2906,16 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) ret = wipe_crypto_connection(c, crypt_connection_id); } - pthread_mutex_unlock(&c->connections_mutex); - return ret; } -/* return one of CRYPTO_CONN_* values indicating the state of the connection. - * - * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. - * sets online_tcp_relays to the number of connected tcp relays this connection has. - */ -Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, - unsigned int *online_tcp_relays) +bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, + unsigned int *online_tcp_relays) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { - return CRYPTO_CONN_NO_CONNECTION; + return false; } if (direct_connected) { @@ -2913,7 +2936,7 @@ Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connec *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp); } - return conn->status; + return true; } void new_keys(Net_Crypto *c) @@ -3002,10 +3025,6 @@ static void kill_timedout(Net_Crypto *c, void *userdata) continue; } - if (conn->status == CRYPTO_CONN_NO_CONNECTION) { - continue; - } - if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT || conn->status == CRYPTO_CONN_NOT_CONFIRMED) { if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) { @@ -3036,9 +3055,6 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /* Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { - if (c == nullptr) // !!!!!!!!!!!!!!!!! - return; - kill_timedout(c, userdata); do_tcp(c, userdata); send_crypto_packets(c); diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.h b/protocols/Tox/libtox/src/toxcore/net_crypto.h index 45e1a05ea2..3885a1ba5f 100644 --- a/protocols/Tox/libtox/src/toxcore/net_crypto.h +++ b/protocols/Tox/libtox/src/toxcore/net_crypto.h @@ -1,25 +1,10 @@ -/* - * Functions for the core network crypto. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Functions for the core network crypto. */ #ifndef C_TOXCORE_TOXCORE_NET_CRYPTO_H #define C_TOXCORE_TOXCORE_NET_CRYPTO_H @@ -31,9 +16,9 @@ #include <pthread.h> -/*** Crypto payloads. ***/ +/** Crypto payloads. */ -/** Ranges. **/ +/** Ranges. */ /* Packets in this range are reserved for net_crypto internal use. */ #define PACKET_ID_RANGE_RESERVED_START 0 @@ -56,7 +41,7 @@ #define PACKET_ID_RANGE_LOSSY_CUSTOM_END 254 #define PACKET_ID_RANGE_LOSSY_END 254 -/** Messages. **/ +/** Messages. */ #define PACKET_ID_PADDING 0 // Denotes padding #define PACKET_ID_REQUEST 1 // Used to request unreceived packets @@ -81,16 +66,6 @@ #define PACKET_ID_REJOIN_CONFERENCE 100 #define PACKET_ID_LOSSY_CONFERENCE 199 -/*** Crypto connections. ***/ - -typedef enum Crypto_Conn_State { - CRYPTO_CONN_NO_CONNECTION = 0, - CRYPTO_CONN_COOKIE_REQUESTING = 1, // send cookie request packets - CRYPTO_CONN_HANDSHAKE_SENT = 2, // send handshake packets - CRYPTO_CONN_NOT_CONFIRMED = 3, // send handshake packets, we have received one from the other - CRYPTO_CONN_ESTABLISHED = 4, -} Crypto_Conn_State; - /* Maximum size of receiving and sending packet buffers. */ #define CRYPTO_PACKET_BUFFER_SIZE 32768 // Must be a power of 2 @@ -319,13 +294,13 @@ unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, u */ int crypto_kill(Net_Crypto *c, int crypt_connection_id); -/* return one of CRYPTO_CONN_* values indicating the state of the connection. +/* return true if connection is valid, false otherwise * * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. * sets online_tcp_relays to the number of connected tcp relays this connection has. */ -Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, - unsigned int *online_tcp_relays); +bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, + unsigned int *online_tcp_relays); /* Generate our public and private keys. * Only call this function the first time the program starts. diff --git a/protocols/Tox/libtox/src/toxcore/network.c b/protocols/Tox/libtox/src/toxcore/network.c index 5e5160d893..d3284c4d26 100644 --- a/protocols/Tox/libtox/src/toxcore/network.c +++ b/protocols/Tox/libtox/src/toxcore/network.c @@ -1,25 +1,10 @@ -/* - * Functions for the core networking. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Functions for the core networking. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -98,6 +83,26 @@ #define TOX_EWOULDBLOCK EWOULDBLOCK +static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufsize) +{ + return inet_ntop(AF_INET, addr, buf, bufsize); +} + +static const char *inet_ntop6(const struct in6_addr *addr, char *buf, size_t bufsize) +{ + return inet_ntop(AF_INET6, addr, buf, bufsize); +} + +static int inet_pton4(const char *addrString, struct in_addr *addrbuf) +{ + return inet_pton(AF_INET, addrString, addrbuf); +} + +static int inet_pton6(const char *addrString, struct in6_addr *addrbuf) +{ + return inet_pton(AF_INET6, addrString, addrbuf); +} + #else #ifndef IPV6_V6ONLY #define IPV6_V6ONLY 27 @@ -105,72 +110,66 @@ #define TOX_EWOULDBLOCK WSAEWOULDBLOCK -static const char *inet_ntop(int family, const void *addr, char *buf, size_t bufsize) +static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufsize) { - if (family == AF_INET) { - struct sockaddr_in saddr; - memset(&saddr, 0, sizeof(saddr)); + struct sockaddr_in saddr = {0}; - saddr.sin_family = AF_INET; - saddr.sin_addr = *(const struct in_addr *)addr; + saddr.sin_family = AF_INET; + saddr.sin_addr = *addr; - DWORD len = bufsize; + DWORD len = bufsize; - if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), nullptr, buf, &len)) { - return nullptr; - } + if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), nullptr, buf, &len)) { + return nullptr; + } - return buf; - } else if (family == AF_INET6) { - struct sockaddr_in6 saddr; - memset(&saddr, 0, sizeof(saddr)); + return buf; +} - saddr.sin6_family = AF_INET6; - saddr.sin6_addr = *(const struct in6_addr *)addr; +static const char *inet_ntop6(const struct in6_addr *addr, char *buf, size_t bufsize) +{ + struct sockaddr_in6 saddr = {0}; - DWORD len = bufsize; + saddr.sin6_family = AF_INET6; + saddr.sin6_addr = *addr; - if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), nullptr, buf, &len)) { - return nullptr; - } + DWORD len = bufsize; - return buf; + if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), nullptr, buf, &len)) { + return nullptr; } - return nullptr; + return buf; } -static int inet_pton(int family, const char *addrString, void *addrbuf) +static int inet_pton4(const char *addrString, struct in_addr *addrbuf) { - if (family == AF_INET) { - struct sockaddr_in saddr; - memset(&saddr, 0, sizeof(saddr)); + struct sockaddr_in saddr = {0}; - INT len = sizeof(saddr); + INT len = sizeof(saddr); - if (WSAStringToAddress((LPTSTR)addrString, AF_INET, nullptr, (LPSOCKADDR)&saddr, &len)) { - return 0; - } - - *(struct in_addr *)addrbuf = saddr.sin_addr; + if (WSAStringToAddress((LPTSTR)addrString, AF_INET, nullptr, (LPSOCKADDR)&saddr, &len)) { + return 0; + } - return 1; - } else if (family == AF_INET6) { - struct sockaddr_in6 saddr; - memset(&saddr, 0, sizeof(saddr)); + *addrbuf = saddr.sin_addr; - INT len = sizeof(saddr); + return 1; +} - if (WSAStringToAddress((LPTSTR)addrString, AF_INET6, nullptr, (LPSOCKADDR)&saddr, &len)) { - return 0; - } +static int inet_pton6(const char *addrString, struct in6_addr *addrbuf) +{ + struct sockaddr_in6 saddr = {0}; - *(struct in6_addr *)addrbuf = saddr.sin6_addr; + INT len = sizeof(saddr); - return 1; + if (WSAStringToAddress((LPTSTR)addrString, AF_INET6, nullptr, (LPSOCKADDR)&saddr, &len)) { + return 0; } - return 0; + *addrbuf = saddr.sin6_addr; + + return 1; } #endif @@ -203,8 +202,33 @@ static int inet_pton(int family, const char *addrString, void *addrbuf) #error "TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN)" #endif -static int make_proto(int proto); -static int make_socktype(int type); +static int make_proto(int proto) +{ + switch (proto) { + case TOX_PROTO_TCP: + return IPPROTO_TCP; + + case TOX_PROTO_UDP: + return IPPROTO_UDP; + + default: + return proto; + } +} + +static int make_socktype(int type) +{ + switch (type) { + case TOX_SOCK_STREAM: + return SOCK_STREAM; + + case TOX_SOCK_DGRAM: + return SOCK_DGRAM; + + default: + return type; + } +} static int make_family(Family tox_family) { @@ -429,7 +453,7 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu { char ip_str[IP_NTOA_LEN]; - if (res < 0) { /* Windows doesn't necessarily know %zu */ + if (res < 0) { /* Windows doesn't necessarily know `%zu` */ int error = net_error(); const char *strerror = net_new_strerror(error); LOGGER_TRACE(log, "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x", @@ -852,19 +876,24 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from, int neterror = net_error(); const char *strerror = net_new_strerror(neterror); - LOGGER_DEBUG(log, res < 0 ? "Failed to activate local multicast membership. (%d, %s)" : - "Local multicast group FF02::1 joined successfully. (%d, %s)", neterror, strerror); + + if (res < 0) { + LOGGER_DEBUG(log, "Failed to activate local multicast membership. (%d, %s)", neterror, strerror); + } else { + LOGGER_DEBUG(log, "Local multicast group FF02::1 joined successfully. (%d, %s)", neterror, strerror); + } + net_kill_strerror(strerror); } - /* a hanging program or a different user might block the standard port; - * as long as it isn't a parameter coming from the commandline, - * try a few ports after it, to see if we can find a "free" one + /* A hanging program or a different user might block the standard port. + * As long as it isn't a parameter coming from the commandline, + * try a few ports after it, to see if we can find a "free" one. * - * if we go on without binding, the first sendto() automatically binds to - * a free port chosen by the system (i.e. anything from 1024 to 65535) + * If we go on without binding, the first sendto() automatically binds to + * a free port chosen by the system (i.e. anything from 1024 to 65535). * - * returning NULL after bind fails has both advantages and disadvantages: + * Returning NULL after bind fails has both advantages and disadvantages: * advantage: * we can rely on getting the port in the range 33445..33450, which * enables us to tell joe user to open their firewall to a small range @@ -1062,7 +1091,7 @@ void ip_copy(IP *target, const IP *source) return; } - memcpy(target, source, sizeof(IP)); + *target = *source; } /* copies an ip_port structure (careful about direction!) */ @@ -1072,7 +1101,7 @@ void ipport_copy(IP_Port *target, const IP_Port *source) return; } - memcpy(target, source, sizeof(IP_Port)); + *target = *source; } /* ip_ntoa @@ -1092,23 +1121,23 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length) } if (ip) { - const int family = make_family(ip->family); - if (net_family_is_ipv4(ip->family)) { /* returns standard quad-dotted notation */ struct in_addr addr; fill_addr4(ip->ip.v4, &addr); ip_str[0] = 0; - inet_ntop(family, &addr, ip_str, length); + assert(make_family(ip->family) == AF_INET); + inet_ntop4(&addr, ip_str, length); } else if (net_family_is_ipv6(ip->family)) { /* returns hex-groups enclosed into square brackets */ struct in6_addr addr; fill_addr6(ip->ip.v6, &addr); ip_str[0] = '['; - inet_ntop(family, &addr, &ip_str[1], length - 3); - size_t len = strlen(ip_str); + assert(make_family(ip->family) == AF_INET6); + inet_ntop6(&addr, &ip_str[1], length - 3); + const size_t len = strlen(ip_str); ip_str[len] = ']'; ip_str[len + 1] = 0; } else { @@ -1131,12 +1160,14 @@ bool ip_parse_addr(const IP *ip, char *address, size_t length) if (net_family_is_ipv4(ip->family)) { const struct in_addr *addr = (const struct in_addr *)&ip->ip.v4; - return inet_ntop(make_family(ip->family), addr, address, length) != nullptr; + assert(make_family(ip->family) == AF_INET); + return inet_ntop4(addr, address, length) != nullptr; } if (net_family_is_ipv6(ip->family)) { const struct in6_addr *addr = (const struct in6_addr *)&ip->ip.v6; - return inet_ntop(make_family(ip->family), addr, address, length) != nullptr; + assert(make_family(ip->family) == AF_INET6); + return inet_ntop6(addr, address, length) != nullptr; } return false; @@ -1150,7 +1181,7 @@ bool addr_parse_ip(const char *address, IP *to) struct in_addr addr4; - if (inet_pton(AF_INET, address, &addr4) == 1) { + if (inet_pton4(address, &addr4) == 1) { to->family = net_family_ipv4; get_ip4(&to->ip.v4, &addr4); return true; @@ -1158,7 +1189,7 @@ bool addr_parse_ip(const char *address, IP *to) struct in6_addr addr6; - if (inet_pton(AF_INET6, address, &addr6) == 1) { + if (inet_pton6(address, &addr6) == 1) { to->family = net_family_ipv6; get_ip6(&to->ip.v6, &addr6); return true; @@ -1207,12 +1238,12 @@ int addr_resolve(const char *address, IP *to, IP *extra) switch (walker->ai_family) { case AF_INET: if (walker->ai_family == family) { /* AF_INET requested, done */ - struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + struct sockaddr_in *addr = (struct sockaddr_in *)(void *)walker->ai_addr; get_ip4(&to->ip.v4, &addr->sin_addr); result = TOX_ADDR_RESOLVE_INET; done = 1; } else if (!(result & TOX_ADDR_RESOLVE_INET)) { /* AF_UNSPEC requested, store away */ - struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; + struct sockaddr_in *addr = (struct sockaddr_in *)(void *)walker->ai_addr; get_ip4(&ip4.ip.v4, &addr->sin_addr); result |= TOX_ADDR_RESOLVE_INET; } @@ -1222,14 +1253,14 @@ int addr_resolve(const char *address, IP *to, IP *extra) case AF_INET6: if (walker->ai_family == family) { /* AF_INET6 requested, done */ if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)walker->ai_addr; get_ip6(&to->ip.v6, &addr->sin6_addr); result = TOX_ADDR_RESOLVE_INET6; done = 1; } } else if (!(result & TOX_ADDR_RESOLVE_INET6)) { /* AF_UNSPEC requested, store away */ if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)walker->ai_addr; get_ip6(&ip6.ip.v6, &addr->sin6_addr); result |= TOX_ADDR_RESOLVE_INET6; } @@ -1344,10 +1375,10 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) } if (cur->ai_family == AF_INET) { - struct sockaddr_in *addr = (struct sockaddr_in *)cur->ai_addr; + struct sockaddr_in *addr = (struct sockaddr_in *)(void *)cur->ai_addr; memcpy(&ip_port->ip.ip.v4, &addr->sin_addr, sizeof(IP4)); } else if (cur->ai_family == AF_INET6) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)cur->ai_addr; + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)cur->ai_addr; memcpy(&ip_port->ip.ip.v6, &addr->sin6_addr, sizeof(IP6)); } else { continue; @@ -1400,34 +1431,6 @@ bool bind_to_port(Socket sock, Family family, uint16_t port) return bind(sock.socket, (struct sockaddr *)&addr, addrsize) == 0; } -static int make_socktype(int type) -{ - switch (type) { - case TOX_SOCK_STREAM: - return SOCK_STREAM; - - case TOX_SOCK_DGRAM: - return SOCK_DGRAM; - - default: - return type; - } -} - -static int make_proto(int proto) -{ - switch (proto) { - case TOX_PROTO_TCP: - return IPPROTO_TCP; - - case TOX_PROTO_UDP: - return IPPROTO_UDP; - - default: - return proto; - } -} - Socket net_socket(Family domain, int type, int protocol) { const int platform_domain = make_family(domain); diff --git a/protocols/Tox/libtox/src/toxcore/network.h b/protocols/Tox/libtox/src/toxcore/network.h index a1d838422c..b7e8ede2b9 100644 --- a/protocols/Tox/libtox/src/toxcore/network.h +++ b/protocols/Tox/libtox/src/toxcore/network.h @@ -1,25 +1,10 @@ -/* - * Datatypes, functions and includes for the core networking. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Datatypes, functions and includes for the core networking. */ #ifndef C_TOXCORE_TOXCORE_NETWORK_H #define C_TOXCORE_TOXCORE_NETWORK_H @@ -110,7 +95,7 @@ typedef enum Net_Packet_Type { NET_PACKET_CRYPTO = 0x20, /* Encrypted data packet ID. */ NET_PACKET_LAN_DISCOVERY = 0x21, /* LAN discovery packet ID. */ - /* See: docs/Prevent_Tracking.txt and onion.{c,h} */ + /* See: `docs/Prevent_Tracking.txt` and `onion.{c,h}` */ NET_PACKET_ONION_SEND_INITIAL = 0x80, NET_PACKET_ONION_SEND_1 = 0x81, NET_PACKET_ONION_SEND_2 = 0x82, @@ -303,11 +288,11 @@ void ipport_copy(IP_Port *target, const IP_Port *source); * IP versions are acceptable * @param extra can be NULL and is only set in special circumstances, see returns * - * returns in *to a valid IPAny (v4/v6), - * prefers v6 if ip.family was TOX_AF_UNSPEC and both available - * returns in *extra an IPv4 address, if family was TOX_AF_UNSPEC and *to is TOX_AF_INET6 + * returns in `*to` a valid IPAny (v4/v6), + * prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available + * returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6 * - * @return 0 on failure, TOX_ADDR_RESOLVE_* on success. + * @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success. */ int addr_resolve(const char *address, IP *to, IP *extra); @@ -320,8 +305,8 @@ int addr_resolve(const char *address, IP *to, IP *extra); * IP versions are acceptable * @param extra can be NULL and is only set in special circumstances, see returns * - * returns in *tro a matching address (IPv6 or IPv4) - * returns in *extra, if not NULL, an IPv4 address, if to->family was TOX_AF_UNSPEC + * returns in `*to` a matching address (IPv6 or IPv4) + * returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was TOX_AF_UNSPEC * * @return true on success, false on failure */ diff --git a/protocols/Tox/libtox/src/toxcore/onion.c b/protocols/Tox/libtox/src/toxcore/onion.c index f1873992d5..32a3e88d6e 100644 --- a/protocols/Tox/libtox/src/toxcore/onion.c +++ b/protocols/Tox/libtox/src/toxcore/onion.c @@ -1,25 +1,10 @@ -/* - * Implementation of the onion part of docs/Prevent_Tracking.txt +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the onion part of docs/Prevent_Tracking.txt */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -150,7 +135,7 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n return 0; } -/* Dump nodes in onion path to nodes of length num_nodes; +/* Dump nodes in onion path to nodes of length num_nodes. * * return -1 on failure. * return 0 on success. diff --git a/protocols/Tox/libtox/src/toxcore/onion.h b/protocols/Tox/libtox/src/toxcore/onion.h index 20cd1e5c2f..da1450818f 100644 --- a/protocols/Tox/libtox/src/toxcore/onion.h +++ b/protocols/Tox/libtox/src/toxcore/onion.h @@ -1,25 +1,10 @@ -/* - * Implementation of the onion part of docs/Prevent_Tracking.txt +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the onion part of docs/Prevent_Tracking.txt */ #ifndef C_TOXCORE_TOXCORE_ONION_H #define C_TOXCORE_TOXCORE_ONION_H @@ -155,8 +140,6 @@ int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data, int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port source, const uint8_t *nonce); /* Set the callback to be called when the dest ip_port doesn't have TOX_AF_INET6 or TOX_AF_INET as the family. - * - * Format: function(void *object, IP_Port dest, uint8_t *data, uint16_t length) */ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object); diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.c b/protocols/Tox/libtox/src/toxcore/onion_announce.c index f38772ddf1..6d38012aa7 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_announce.c +++ b/protocols/Tox/libtox/src/toxcore/onion_announce.c @@ -1,25 +1,10 @@ -/* - * Implementation of the announce part of docs/Prevent_Tracking.txt +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the announce part of docs/Prevent_Tracking.txt */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.h b/protocols/Tox/libtox/src/toxcore/onion_announce.h index 2eb5051b1f..3145803c15 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_announce.h +++ b/protocols/Tox/libtox/src/toxcore/onion_announce.h @@ -1,25 +1,10 @@ -/* - * Implementation of the announce part of docs/Prevent_Tracking.txt +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the announce part of docs/Prevent_Tracking.txt */ #ifndef C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H #define C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.c b/protocols/Tox/libtox/src/toxcore/onion_client.c index d11a91e81d..e161928bae 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_client.c +++ b/protocols/Tox/libtox/src/toxcore/onion_client.c @@ -1,26 +1,11 @@ -/* - * Implementation of the client part of docs/Prevent_Tracking.txt (The part that - * uses the onion stuff to connect to the friend) +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the client part of docs/Prevent_Tracking.txt (The part that + * uses the onion stuff to connect to the friend) */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -465,7 +450,7 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t return path_num; } - return ~0; + return -1; } /* Function to send onion packet via TCP and UDP. @@ -544,7 +529,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ * ret_pubkey must be at least CRYPTO_PUBLIC_KEY_SIZE big * ret_ip_port must be at least 1 big * - * return ~0 on failure + * return -1 on failure * return num (see new_sendback(...)) on success */ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, uint8_t *ret_pubkey, @@ -555,7 +540,7 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)]; if (ping_array_check(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data), sback) != sizeof(data)) { - return ~0; + return -1; } memcpy(ret_pubkey, data + sizeof(uint32_t), CRYPTO_PUBLIC_KEY_SIZE); @@ -834,7 +819,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for } if (j == list_length && good_to_ping(onion_c->mono_time, last_pinged, last_pinged_index, nodes[i].public_key)) { - client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, nullptr, ~0); + client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, nullptr, -1); } } } @@ -971,8 +956,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con } uint64_t no_replay; - memcpy(&no_replay, data + 1, sizeof(uint64_t)); - net_to_host((uint8_t *) &no_replay, sizeof(no_replay)); + net_unpack_u64(data + 1, &no_replay); if (no_replay <= onion_c->friends_list[friend_num].last_noreplay) { return 1; @@ -1099,7 +1083,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, for (i = 0; i < num_good; ++i) { Onion_Path path; - if (random_path(onion_c, &onion_c->onion_paths_friends, ~0, &path) == -1) { + if (random_path(onion_c, &onion_c->onion_paths_friends, -1, &path) == -1) { continue; } @@ -1207,9 +1191,8 @@ static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8 uint8_t data[DHTPK_DATA_MAX_LENGTH]; data[0] = ONION_DATA_DHTPK; - uint64_t no_replay = mono_time_get(onion_c->mono_time); - host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); - memcpy(data + 1, &no_replay, sizeof(no_replay)); + const uint64_t no_replay = mono_time_get(onion_c->mono_time); + net_pack_u64(data + 1, no_replay); memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE); Node_format nodes[MAX_SENT_NODES]; uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2)); @@ -1305,7 +1288,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key) return num; } - unsigned int i, index = ~0; + unsigned int i, index = -1; for (i = 0; i < onion_c->num_friends; ++i) { if (onion_c->friends_list[i].status == 0) { @@ -1314,7 +1297,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key) } } - if (index == (uint32_t)~0) { + if (index == (uint32_t) -1) { if (realloc_onion_friends(onion_c, onion_c->num_friends + 1) == -1) { return -1; } @@ -1609,7 +1592,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval) || (ping_random && random_u32() % (MAX_ONION_CLIENTS - i) == 0)) { if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, - list_nodes[i].public_key, nullptr, ~0) == 0) { + list_nodes[i].public_key, nullptr, -1) == 0) { list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time); ++list_nodes[i].unsuccessful_pings; ping_random = false; @@ -1632,7 +1615,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) for (j = 0; j < n; ++j) { const uint32_t num = random_u32() % num_nodes; client_send_announce_request(onion_c, friendnum + 1, onion_c->path_nodes[num].ip_port, - onion_c->path_nodes[num].public_key, nullptr, ~0); + onion_c->path_nodes[num].public_key, nullptr, -1); } ++onion_c->friends_list[friendnum].run_count; @@ -1703,7 +1686,7 @@ static void do_announce(Onion_Client *onion_c) uint32_t pathnum = list_nodes[i].path_used % NUMBER_ONION_PATHS; - /* A node/path is considered 'stable', and can be pinged less + /* A node/path is considered "stable", and can be pinged less * aggressively, if it has survived for at least TIME_TO_STABLE * and the latest packets sent to it are not timing out. */ @@ -1725,7 +1708,7 @@ static void do_announce(Onion_Client *onion_c) if (list_nodes[i].unsuccessful_pings == ONION_NODE_MAX_PINGS - 1 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)) { /* Last chance for a long-lived node - try a random path */ - path_to_use = ~0; + path_to_use = -1; } if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].public_key, @@ -1753,7 +1736,7 @@ static void do_announce(Onion_Client *onion_c) if (num_nodes != 0) { for (i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) { const uint32_t num = random_u32() % num_nodes; - client_send_announce_request(onion_c, 0, path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, ~0); + client_send_announce_request(onion_c, 0, path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1); } } } diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.h b/protocols/Tox/libtox/src/toxcore/onion_client.h index 66e417d76c..5b6bea659a 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_client.h +++ b/protocols/Tox/libtox/src/toxcore/onion_client.h @@ -1,26 +1,11 @@ -/* - * Implementation of the client part of docs/Prevent_Tracking.txt (The part that - * uses the onion stuff to connect to the friend) +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of the client part of docs/Prevent_Tracking.txt (The part that + * uses the onion stuff to connect to the friend) */ #ifndef C_TOXCORE_TOXCORE_ONION_CLIENT_H #define C_TOXCORE_TOXCORE_ONION_CLIENT_H @@ -151,8 +136,6 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, onion_dht_pk_cb uint32_t number); /* Set a friends DHT public key. - * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to - * the other peer. * * return -1 on failure. * return 0 on success. diff --git a/protocols/Tox/libtox/src/toxcore/ping.api.h b/protocols/Tox/libtox/src/toxcore/ping.api.h index 2ae5b3650b..d4d071b11d 100644 --- a/protocols/Tox/libtox/src/toxcore/ping.api.h +++ b/protocols/Tox/libtox/src/toxcore/ping.api.h @@ -1,28 +1,12 @@ %{ -/* - * Buffered pinging using cyclic arrays. - */ - -/* +/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * Copyright © 2013 plutooo - * - * This file is part of Tox, the free peer to peer instant messenger. - * This file is donated to the Tox Project. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Buffered pinging using cyclic arrays. */ #ifndef C_TOXCORE_TOXCORE_PING_H #define C_TOXCORE_TOXCORE_PING_H diff --git a/protocols/Tox/libtox/src/toxcore/ping.c b/protocols/Tox/libtox/src/toxcore/ping.c index df0adf046d..d2677ee786 100644 --- a/protocols/Tox/libtox/src/toxcore/ping.c +++ b/protocols/Tox/libtox/src/toxcore/ping.c @@ -1,27 +1,11 @@ -/* - * Buffered pinging using cyclic arrays. - */ - -/* +/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * Copyright © 2013 plutooo - * - * This file is part of Tox, the free peer to peer instant messenger. - * This file is donated to the Tox Project. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Buffered pinging using cyclic arrays. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/ping.h b/protocols/Tox/libtox/src/toxcore/ping.h index 0413e2856e..9badd5aa1b 100644 --- a/protocols/Tox/libtox/src/toxcore/ping.h +++ b/protocols/Tox/libtox/src/toxcore/ping.h @@ -1,27 +1,11 @@ -/* - * Buffered pinging using cyclic arrays. - */ - -/* +/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * Copyright © 2013 plutooo - * - * This file is part of Tox, the free peer to peer instant messenger. - * This file is donated to the Tox Project. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Buffered pinging using cyclic arrays. */ #ifndef C_TOXCORE_TOXCORE_PING_H #define C_TOXCORE_TOXCORE_PING_H diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.api.h b/protocols/Tox/libtox/src/toxcore/ping_array.api.h index e0ac333b48..81ede8fa8f 100644 --- a/protocols/Tox/libtox/src/toxcore/ping_array.api.h +++ b/protocols/Tox/libtox/src/toxcore/ping_array.api.h @@ -1,26 +1,11 @@ %{ -/* - * Implementation of an efficient array to store that we pinged something. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of an efficient array to store that we pinged something. */ #ifndef C_TOXCORE_TOXCORE_PING_ARRAY_H #define C_TOXCORE_TOXCORE_PING_ARRAY_H diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.c b/protocols/Tox/libtox/src/toxcore/ping_array.c index c39dc881d9..a93d48dd5c 100644 --- a/protocols/Tox/libtox/src/toxcore/ping_array.c +++ b/protocols/Tox/libtox/src/toxcore/ping_array.c @@ -1,25 +1,10 @@ -/* - * Implementation of an efficient array to store that we pinged something. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2014 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2014 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of an efficient array to store that we pinged something. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.h b/protocols/Tox/libtox/src/toxcore/ping_array.h index a2e57856bd..589573c80f 100644 --- a/protocols/Tox/libtox/src/toxcore/ping_array.h +++ b/protocols/Tox/libtox/src/toxcore/ping_array.h @@ -1,25 +1,10 @@ -/* - * Implementation of an efficient array to store that we pinged something. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Implementation of an efficient array to store that we pinged something. */ #ifndef C_TOXCORE_TOXCORE_PING_ARRAY_H #define C_TOXCORE_TOXCORE_PING_ARRAY_H diff --git a/protocols/Tox/libtox/src/toxcore/state.c b/protocols/Tox/libtox/src/toxcore/state.c index bca7a1512d..67cc68ada4 100644 --- a/protocols/Tox/libtox/src/toxcore/state.c +++ b/protocols/Tox/libtox/src/toxcore/state.c @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2020 The TokTok team. + * Copyright © 2014 Tox project. + */ #include "state.h" #include <string.h> diff --git a/protocols/Tox/libtox/src/toxcore/state.h b/protocols/Tox/libtox/src/toxcore/state.h index 829036d8dd..cbe97b49da 100644 --- a/protocols/Tox/libtox/src/toxcore/state.h +++ b/protocols/Tox/libtox/src/toxcore/state.h @@ -1,3 +1,8 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2020 The TokTok team. + * Copyright © 2014 Tox project. + */ + /** * The state module is responsible for parsing the Tox save data format and for * saving state in that format. diff --git a/protocols/Tox/libtox/src/toxcore/tox.api.h b/protocols/Tox/libtox/src/toxcore/tox.api.h index e73402de9c..c0901d0afe 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.api.h +++ b/protocols/Tox/libtox/src/toxcore/tox.api.h @@ -1,26 +1,11 @@ %{ -/* - * The Tox public API. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * The Tox public API. */ #ifndef C_TOXCORE_TOXCORE_TOX_H #define C_TOXCORE_TOXCORE_TOX_H @@ -182,7 +167,7 @@ const VERSION_MINOR = 2; * The patch or revision number. Incremented when bugfixes are applied without * changing any functionality or API or ABI. */ -const VERSION_PATCH = 10; +const VERSION_PATCH = 11; /** * A macro to check at preprocessing time whether the client code is compatible @@ -623,6 +608,21 @@ static class options { */ any user_data; } + + /** + * These options are experimental, so avoid writing code that depends on + * them. Options marked "experimental" may change their behaviour or go away + * entirely in the future, or may be renamed to something non-experimental + * if they become part of the supported API. + */ + namespace experimental { + /** + * Make public API functions thread-safe using a per-instance lock. + * + * Default: false. + */ + bool thread_safety; + } } @@ -2232,7 +2232,7 @@ namespace conference { /** * Creates a new conference. * - * This function creates a new text conference. + * This function creates and connects to a new text conference. * * @return conference number on success, or an unspecified value on failure. */ @@ -2279,7 +2279,10 @@ namespace conference { namespace peer { /** - * Return the number of peers in the conference. Return value is unspecified on failure. + * Return the number of online peers in the conference. The unsigned + * integers less than this number are the valid values of peer_number for + * the functions querying these peers. Return value is unspecified on + * failure. */ const uint32_t count(uint32_t conference_number) with error for peer_query; @@ -2327,7 +2330,9 @@ namespace conference { namespace offline_peer { /** - * Return the number of offline peers in the conference. Return value is unspecified on failure. + * Return the number of offline peers in the conference. The unsigned + * integers less than this number are the valid values of offline_peer_number for + * the functions querying these peers. Return value is unspecified on failure. */ const uint32_t count(uint32_t conference_number) with error for peer_query; @@ -2388,10 +2393,6 @@ namespace conference { /** * Invites a friend to a conference. * - * We must be connected to the conference, meaning that the conference has not - * been deleted, and either we created the conference with the $new function, - * or a `${event connected}` event has occurred for the conference. - * * @param friend_number The friend number of the friend we want to invite. * @param conference_number The conference number of the conference we want to invite the friend to. * @@ -2416,6 +2417,14 @@ namespace conference { /** * Joins a conference that the client has been invited to. * + * After successfully joining the conference, the client will not be "connected" + * to it until a handshaking procedure has been completed. A + * `${event connected}` event will then occur for the conference. The client + * will then remain connected to the conference until the conference is deleted, + * even across core restarts. Many operations on a conference will fail with a + * corresponding error if attempted on a conference to which the client is not + * yet connected. + * * @param friend_number The friend number of the friend who sent the invite. * @param cookie Received via the `${event invite}` event. * @param length The size of cookie. @@ -2552,8 +2561,16 @@ namespace conference { size(); /** - * Copy a list of valid conference IDs into the array chatlist. Determine how much space - * to allocate for the array with the `$size` function. + * Copy a list of valid conference numbers into the array chatlist. Determine + * how much space to allocate for the array with the `$size` function. + * + * Note that `${savedata.get}` saves all connected conferences; + * when toxcore is created from savedata in which conferences were saved, those + * conferences will be connected at startup, and will be listed by + * `$get`. + * + * The conference number of a loaded conference may differ from the conference + * number it had when it was saved. */ get(); } diff --git a/protocols/Tox/libtox/src/toxcore/tox.c b/protocols/Tox/libtox/src/toxcore/tox.c index 0a575dbf1b..b70be7a3e0 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.c +++ b/protocols/Tox/libtox/src/toxcore/tox.c @@ -1,33 +1,20 @@ -/* - * The Tox public API. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * The Tox public API. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifndef __cplusplus #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif +#endif #include "tox.h" @@ -77,8 +64,11 @@ #endif struct Tox { + // XXX: Messenger *must* be the first member, because toxav casts its + // `Tox *` to `Messenger **`. Messenger *m; Mono_Time *mono_time; + pthread_mutex_t *mutex; tox_self_connection_status_cb *self_connection_status_callback; tox_friend_name_cb *friend_name_callback; @@ -103,6 +93,20 @@ struct Tox { tox_friend_lossless_packet_cb *friend_lossless_packet_callback; }; +static void lock(const Tox *tox) +{ + if (tox->mutex != nullptr) { + pthread_mutex_lock(tox->mutex); + } +} + +static void unlock(const Tox *tox) +{ + if (tox->mutex != nullptr) { + pthread_mutex_unlock(tox->mutex); + } +} + struct Tox_Userdata { Tox *tox; void *user_data; @@ -302,8 +306,8 @@ static void tox_conference_peer_list_changed_handler(Messenger *m, uint32_t conf } } -static void tox_friend_lossy_packet_handler(Messenger *m, uint32_t friend_number, const uint8_t *data, size_t length, - void *user_data) +static void tox_friend_lossy_packet_handler(Messenger *m, uint32_t friend_number, uint8_t packet_id, + const uint8_t *data, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; @@ -312,8 +316,8 @@ static void tox_friend_lossy_packet_handler(Messenger *m, uint32_t friend_number } } -static void tox_friend_lossless_packet_handler(Messenger *m, uint32_t friend_number, const uint8_t *data, size_t length, - void *user_data) +static void tox_friend_lossless_packet_handler(Messenger *m, uint32_t friend_number, uint8_t packet_id, + const uint8_t *data, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; @@ -509,14 +513,35 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) return nullptr; } + if (tox_options_get_experimental_thread_safety(opts)) { + tox->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + + if (tox->mutex == nullptr) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); + tox_options_free(default_options); + free(tox); + return nullptr; + } + + + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(tox->mutex, &attr); + } else { + tox->mutex = nullptr; + } + + lock(tox); + unsigned int m_error; - Messenger *const m = new_messenger(tox->mono_time, &m_options, &m_error); - tox->m = m; + tox->m = new_messenger(tox->mono_time, &m_options, &m_error); // TODO(iphydf): Clarify this code, check for NULL before new_groupchats, so // new_groupchats can assume m is non-NULL. - if (!new_groupchats(tox->mono_time, m)) { - kill_messenger(m); + if (!new_groupchats(tox->mono_time, tox->m)) { + kill_messenger(tox->m); if (m_error == MESSENGER_ERROR_PORT) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC); @@ -528,6 +553,13 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) mono_time_free(tox->mono_time); tox_options_free(default_options); + unlock(tox); + + if (tox->mutex != nullptr) { + pthread_mutex_destroy(tox->mutex); + } + + free(tox->mutex); free(tox); return nullptr; } @@ -536,35 +568,37 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) && tox_load(tox, tox_options_get_savedata_data(opts), tox_options_get_savedata_length(opts)) == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); } else if (load_savedata_sk) { - load_secret_key(m->net_crypto, tox_options_get_savedata_data(opts)); + load_secret_key(tox->m->net_crypto, tox_options_get_savedata_data(opts)); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); } else { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); } - m_callback_namechange(m, tox_friend_name_handler); - m_callback_core_connection(m, tox_self_connection_status_handler); - m_callback_statusmessage(m, tox_friend_status_message_handler); - m_callback_userstatus(m, tox_friend_status_handler); - m_callback_connectionstatus(m, tox_friend_connection_status_handler); - m_callback_typingchange(m, tox_friend_typing_handler); - m_callback_read_receipt(m, tox_friend_read_receipt_handler); - m_callback_friendrequest(m, tox_friend_request_handler); - m_callback_friendmessage(m, tox_friend_message_handler); - callback_file_control(m, tox_file_recv_control_handler); - callback_file_reqchunk(m, tox_file_chunk_request_handler); - callback_file_sendrequest(m, tox_file_recv_handler); - callback_file_data(m, tox_file_recv_chunk_handler); - g_callback_group_invite(m->conferences_object, tox_conference_invite_handler); - g_callback_group_connected(m->conferences_object, tox_conference_connected_handler); - g_callback_group_message(m->conferences_object, tox_conference_message_handler); - g_callback_group_title(m->conferences_object, tox_conference_title_handler); - g_callback_peer_name(m->conferences_object, tox_conference_peer_name_handler); - g_callback_peer_list_changed(m->conferences_object, tox_conference_peer_list_changed_handler); - custom_lossy_packet_registerhandler(m, tox_friend_lossy_packet_handler); - custom_lossless_packet_registerhandler(m, tox_friend_lossless_packet_handler); + m_callback_namechange(tox->m, tox_friend_name_handler); + m_callback_core_connection(tox->m, tox_self_connection_status_handler); + m_callback_statusmessage(tox->m, tox_friend_status_message_handler); + m_callback_userstatus(tox->m, tox_friend_status_handler); + m_callback_connectionstatus(tox->m, tox_friend_connection_status_handler); + m_callback_typingchange(tox->m, tox_friend_typing_handler); + m_callback_read_receipt(tox->m, tox_friend_read_receipt_handler); + m_callback_friendrequest(tox->m, tox_friend_request_handler); + m_callback_friendmessage(tox->m, tox_friend_message_handler); + callback_file_control(tox->m, tox_file_recv_control_handler); + callback_file_reqchunk(tox->m, tox_file_chunk_request_handler); + callback_file_sendrequest(tox->m, tox_file_recv_handler); + callback_file_data(tox->m, tox_file_recv_chunk_handler); + g_callback_group_invite(tox->m->conferences_object, tox_conference_invite_handler); + g_callback_group_connected(tox->m->conferences_object, tox_conference_connected_handler); + g_callback_group_message(tox->m->conferences_object, tox_conference_message_handler); + g_callback_group_title(tox->m->conferences_object, tox_conference_title_handler); + g_callback_peer_name(tox->m->conferences_object, tox_conference_peer_name_handler); + g_callback_peer_list_changed(tox->m->conferences_object, tox_conference_peer_list_changed_handler); + custom_lossy_packet_registerhandler(tox->m, tox_friend_lossy_packet_handler); + custom_lossless_packet_registerhandler(tox->m, tox_friend_lossless_packet_handler); tox_options_free(default_options); + + unlock(tox); return tox; } @@ -574,11 +608,18 @@ void tox_kill(Tox *tox) return; } - Messenger *m = tox->m; - LOGGER_ASSERT(m->log, m->msi_packet == nullptr, "Attempted to kill tox while toxav is still alive"); - kill_groupchats(m->conferences_object); - kill_messenger(m); + lock(tox); + LOGGER_ASSERT(tox->m->log, tox->m->msi_packet == nullptr, "Attempted to kill tox while toxav is still alive"); + kill_groupchats(tox->m->conferences_object); + kill_messenger(tox->m); mono_time_free(tox->mono_time); + unlock(tox); + + if (tox->mutex != nullptr) { + pthread_mutex_destroy(tox->mutex); + free(tox->mutex); + } + free(tox); } @@ -594,11 +635,13 @@ static void end_save(uint8_t *data) size_t tox_get_savedata_size(const Tox *tox) { - const Messenger *m = tox->m; - return 2 * sizeof(uint32_t) - + messenger_size(m) - + conferences_size(m->conferences_object) - + end_size(); + lock(tox); + size_t ret = 2 * sizeof(uint32_t) + + messenger_size(tox->m) + + conferences_size(tox->m->conferences_object) + + end_size(); + unlock(tox); + return ret; } void tox_get_savedata(const Tox *tox, uint8_t *savedata) @@ -609,6 +652,8 @@ void tox_get_savedata(const Tox *tox, uint8_t *savedata) memset(savedata, 0, tox_get_savedata_size(tox)); + lock(tox); + const uint32_t size32 = sizeof(uint32_t); // write cookie @@ -617,10 +662,11 @@ void tox_get_savedata(const Tox *tox, uint8_t *savedata) host_to_lendian_bytes32(savedata, STATE_COOKIE_GLOBAL); savedata += size32; - const Messenger *m = tox->m; - savedata = messenger_save(m, savedata); - savedata = conferences_save(m->conferences_object, savedata); + savedata = messenger_save(tox->m, savedata); + savedata = conferences_save(tox->m->conferences_object, savedata); end_save(savedata); + + unlock(tox); } bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error) @@ -647,14 +693,17 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub unsigned int i; + lock(tox); + for (i = 0; i < count; ++i) { root[i].port = net_htons(port); - Messenger *m = tox->m; - onion_add_bs_path_node(m->onion_c, root[i], public_key); - dht_bootstrap(m->dht, root[i], public_key); + onion_add_bs_path_node(tox->m->onion_c, root[i], public_key); + dht_bootstrap(tox->m->dht, root[i], public_key); } + unlock(tox); + net_freeipport(root); if (count) { @@ -691,13 +740,16 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t unsigned int i; + lock(tox); + for (i = 0; i < count; ++i) { root[i].port = net_htons(port); - Messenger *m = tox->m; - add_tcp_relay(m->net_crypto, root[i], public_key); + add_tcp_relay(tox->m->net_crypto, root[i], public_key); } + unlock(tox); + net_freeipport(root); if (count) { @@ -711,9 +763,9 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t Tox_Connection tox_self_get_connection_status(const Tox *tox) { - const Messenger *m = tox->m; - - const unsigned int ret = onion_connection_status(m->onion_c); + lock(tox); + const unsigned int ret = onion_connection_status(tox->m->onion_c); + unlock(tox); if (ret == 2) { return TOX_CONNECTION_UDP; @@ -734,55 +786,64 @@ void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb uint32_t tox_iteration_interval(const Tox *tox) { - const Messenger *m = tox->m; - return messenger_run_interval(m); + lock(tox); + uint32_t ret = messenger_run_interval(tox->m); + unlock(tox); + return ret; } void tox_iterate(Tox *tox, void *user_data) { + lock(tox); + mono_time_update(tox->mono_time); - Messenger *m = tox->m; struct Tox_Userdata tox_data = { tox, user_data }; - do_messenger(m, &tox_data); - do_groupchats(m->conferences_object, &tox_data); + do_messenger(tox->m, &tox_data); + do_groupchats(tox->m->conferences_object, &tox_data); + + unlock(tox); } void tox_self_get_address(const Tox *tox, uint8_t *address) { if (address) { - const Messenger *m = tox->m; - getaddress(m, address); + lock(tox); + getaddress(tox->m, address); + unlock(tox); } } void tox_self_set_nospam(Tox *tox, uint32_t nospam) { - Messenger *m = tox->m; - set_nospam(m->fr, net_htonl(nospam)); + lock(tox); + set_nospam(tox->m->fr, net_htonl(nospam)); + unlock(tox); } uint32_t tox_self_get_nospam(const Tox *tox) { - const Messenger *m = tox->m; - return net_ntohl(get_nospam(m->fr)); + lock(tox); + uint32_t ret = net_ntohl(get_nospam(tox->m->fr)); + unlock(tox); + return ret; } void tox_self_get_public_key(const Tox *tox, uint8_t *public_key) { - const Messenger *m = tox->m; - if (public_key) { - memcpy(public_key, nc_get_self_public_key(m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); + lock(tox); + memcpy(public_key, nc_get_self_public_key(tox->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); + unlock(tox); } } void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key) { - const Messenger *m = tox->m; - if (secret_key) { - memcpy(secret_key, nc_get_self_secret_key(m->net_crypto), CRYPTO_SECRET_KEY_SIZE); + lock(tox); + memcpy(secret_key, nc_get_self_secret_key(tox->m->net_crypto), CRYPTO_SECRET_KEY_SIZE); + unlock(tox); } } @@ -793,30 +854,35 @@ bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, Tox_Err_Set return 0; } - Messenger *m = tox->m; + lock(tox); - if (setname(m, name, length) == 0) { + if (setname(tox->m, name, length) == 0) { // TODO(irungentoo): function to set different per group names? - send_name_all_groups(m->conferences_object); + send_name_all_groups(tox->m->conferences_object); SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_OK); + unlock(tox); return 1; } SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_TOO_LONG); + unlock(tox); return 0; } size_t tox_self_get_name_size(const Tox *tox) { - const Messenger *m = tox->m; - return m_get_self_name_size(m); + lock(tox); + size_t ret = m_get_self_name_size(tox->m); + unlock(tox); + return ret; } void tox_self_get_name(const Tox *tox, uint8_t *name) { if (name) { - const Messenger *m = tox->m; - getself_name(m, name); + lock(tox); + getself_name(tox->m, name); + unlock(tox); } } @@ -827,41 +893,48 @@ bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t return 0; } - Messenger *m = tox->m; + lock(tox); - if (m_set_statusmessage(m, status_message, length) == 0) { + if (m_set_statusmessage(tox->m, status_message, length) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_OK); + unlock(tox); return 1; } SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_TOO_LONG); + unlock(tox); return 0; } size_t tox_self_get_status_message_size(const Tox *tox) { - const Messenger *m = tox->m; - return m_get_self_statusmessage_size(m); + lock(tox); + size_t ret = m_get_self_statusmessage_size(tox->m); + unlock(tox); + return ret; } void tox_self_get_status_message(const Tox *tox, uint8_t *status_message) { if (status_message) { - const Messenger *m = tox->m; - m_copy_self_statusmessage(m, status_message); + lock(tox); + m_copy_self_statusmessage(tox->m, status_message); + unlock(tox); } } void tox_self_set_status(Tox *tox, Tox_User_Status status) { - Messenger *m = tox->m; - m_set_userstatus(m, status); + lock(tox); + m_set_userstatus(tox->m, status); + unlock(tox); } Tox_User_Status tox_self_get_status(const Tox *tox) { - const Messenger *m = tox->m; - const uint8_t status = m_get_self_userstatus(m); + lock(tox); + const uint8_t status = m_get_self_userstatus(tox->m); + unlock(tox); return (Tox_User_Status)status; } @@ -911,15 +984,17 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message return UINT32_MAX; } - Messenger *m = tox->m; - const int32_t ret = m_addfriend(m, address, message, length); + lock(tox); + const int32_t ret = m_addfriend(tox->m, address, message, length); if (ret >= 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK); + unlock(tox); return ret; } - set_friend_error(m->log, ret, error); + set_friend_error(tox->m->log, ret, error); + unlock(tox); return UINT32_MAX; } @@ -930,22 +1005,25 @@ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_F return UINT32_MAX; } - Messenger *m = tox->m; - const int32_t ret = m_addfriend_norequest(m, public_key); + lock(tox); + const int32_t ret = m_addfriend_norequest(tox->m, public_key); if (ret >= 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK); + unlock(tox); return ret; } - set_friend_error(m->log, ret, error); + set_friend_error(tox->m->log, ret, error); + unlock(tox); return UINT32_MAX; } bool tox_friend_delete(Tox *tox, uint32_t friend_number, Tox_Err_Friend_Delete *error) { - Messenger *m = tox->m; - const int ret = m_delfriend(m, friend_number); + lock(tox); + const int ret = m_delfriend(tox->m, friend_number); + unlock(tox); // TODO(irungentoo): handle if realloc fails? if (ret == -1) { @@ -964,8 +1042,9 @@ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox return UINT32_MAX; } - const Messenger *m = tox->m; - const int32_t ret = getfriend_id(m, public_key); + lock(tox); + const int32_t ret = getfriend_id(tox->m, public_key); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND); @@ -983,27 +1062,32 @@ bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t * return 0; } - const Messenger *m = tox->m; + lock(tox); - if (get_real_pk(m, friend_number, public_key) == -1) { + if (get_real_pk(tox->m, friend_number, public_key) == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND); + unlock(tox); return 0; } SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK); + unlock(tox); return 1; } bool tox_friend_exists(const Tox *tox, uint32_t friend_number) { - const Messenger *m = tox->m; - return m_friend_exists(m, friend_number); + lock(tox); + bool ret = m_friend_exists(tox->m, friend_number); + unlock(tox); + return ret; } uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Get_Last_Online *error) { - const Messenger *m = tox->m; - const uint64_t timestamp = m_get_last_online(m, friend_number); + lock(tox); + const uint64_t timestamp = m_get_last_online(tox->m, friend_number); + unlock(tox); if (timestamp == UINT64_MAX) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND); @@ -1016,23 +1100,27 @@ uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, Tox_ size_t tox_self_get_friend_list_size(const Tox *tox) { - const Messenger *m = tox->m; - return count_friendlist(m); + lock(tox); + size_t ret = count_friendlist(tox->m); + unlock(tox); + return ret; } void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list) { if (friend_list) { - const Messenger *m = tox->m; + lock(tox); // TODO(irungentoo): size parameter? - copy_friendlist(m, friend_list, tox_self_get_friend_list_size(tox)); + copy_friendlist(tox->m, friend_list, count_friendlist(tox->m)); + unlock(tox); } } size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { - const Messenger *m = tox->m; - const int ret = m_get_name_size(m, friend_number); + lock(tox); + const int ret = m_get_name_size(tox->m, friend_number); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); @@ -1050,8 +1138,9 @@ bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, return 0; } - const Messenger *m = tox->m; - const int ret = getname(m, friend_number, name); + lock(tox); + const int ret = getname(tox->m, friend_number, name); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); @@ -1069,8 +1158,9 @@ void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback) size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { - const Messenger *m = tox->m; - const int ret = m_get_statusmessage_size(m, friend_number); + lock(tox); + const int ret = m_get_statusmessage_size(tox->m, friend_number); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); @@ -1089,18 +1179,20 @@ bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8 return false; } - const Messenger *const m = tox->m; - const int size = m_get_statusmessage_size(m, friend_number); + lock(tox); + const int size = m_get_statusmessage_size(tox->m, friend_number); if (size == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); + unlock(tox); return false; } - const int ret = m_copy_statusmessage(m, friend_number, status_message, size); - LOGGER_ASSERT(m->log, ret == size, "concurrency problem: friend status message changed"); + const int ret = m_copy_statusmessage(tox->m, friend_number, status_message, size); + LOGGER_ASSERT(tox->m->log, ret == size, "concurrency problem: friend status message changed"); SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK); + unlock(tox); return ret == size; } @@ -1111,9 +1203,9 @@ void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb * Tox_User_Status tox_friend_get_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { - const Messenger *m = tox->m; - - const int ret = m_get_userstatus(m, friend_number); + lock(tox); + const int ret = m_get_userstatus(tox->m, friend_number); + unlock(tox); if (ret == USERSTATUS_INVALID) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); @@ -1131,9 +1223,9 @@ void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback) Tox_Connection tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { - const Messenger *m = tox->m; - - const int ret = m_get_friend_connectionstatus(m, friend_number); + lock(tox); + const int ret = m_get_friend_connectionstatus(tox->m, friend_number); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); @@ -1151,8 +1243,9 @@ void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_statu bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { - const Messenger *m = tox->m; - const int ret = m_get_istyping(m, friend_number); + lock(tox); + const int ret = m_get_istyping(tox->m, friend_number); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); @@ -1170,14 +1263,16 @@ void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback) bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, Tox_Err_Set_Typing *error) { - Messenger *m = tox->m; + lock(tox); - if (m_set_usertyping(m, friend_number, typing) == -1) { + if (m_set_usertyping(tox->m, friend_number, typing) == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND); + unlock(tox); return 0; } SET_ERROR_PARAMETER(error, TOX_ERR_SET_TYPING_OK); + unlock(tox); return 1; } @@ -1228,9 +1323,11 @@ uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, Tox_Message_T return 0; } - Messenger *m = tox->m; uint32_t message_id = 0; - set_message_error(m->log, m_send_message_generic(m, friend_number, type, message, length, &message_id), error); + lock(tox); + set_message_error(tox->m->log, m_send_message_generic(tox->m, friend_number, type, message, length, &message_id), + error); + unlock(tox); return message_id; } @@ -1262,8 +1359,9 @@ bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length) bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control, Tox_Err_File_Control *error) { - Messenger *m = tox->m; - const int ret = file_control(m, friend_number, file_number, control); + lock(tox); + const int ret = file_control(tox->m, friend_number, file_number, control); + unlock(tox); if (ret == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_OK); @@ -1311,8 +1409,9 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, To bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, Tox_Err_File_Seek *error) { - Messenger *m = tox->m; - const int ret = file_seek(m, friend_number, file_number, position); + lock(tox); + const int ret = file_seek(tox->m, friend_number, file_number, position); + unlock(tox); if (ret == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_OK); @@ -1363,8 +1462,9 @@ bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_ return 0; } - const Messenger *m = tox->m; - const int ret = file_get_id(m, friend_number, file_number, file_id); + lock(tox); + const int ret = file_get_id(tox->m, friend_number, file_number, file_id); + unlock(tox); if (ret == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_OK); @@ -1396,8 +1496,9 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_id = f_id; } - Messenger *m = tox->m; - const long int file_num = new_filesender(m, friend_number, kind, file_size, file_id, filename, filename_length); + lock(tox); + const long int file_num = new_filesender(tox->m, friend_number, kind, file_size, file_id, filename, filename_length); + unlock(tox); if (file_num >= 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_OK); @@ -1429,8 +1530,9 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, size_t length, Tox_Err_File_Send_Chunk *error) { - Messenger *m = tox->m; - const int ret = file_data(m, friend_number, file_number, position, data, length); + lock(tox); + const int ret = file_data(tox->m, friend_number, file_number, position, data, length); + unlock(tox); if (ret == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_OK); @@ -1518,8 +1620,9 @@ void tox_callback_conference_peer_list_changed(Tox *tox, tox_conference_peer_lis uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) { - Messenger *m = tox->m; - const int ret = add_groupchat(m->conferences_object, GROUPCHAT_TYPE_TEXT); + lock(tox); + const int ret = add_groupchat(tox->m->conferences_object, GROUPCHAT_TYPE_TEXT); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_NEW_INIT); @@ -1532,8 +1635,9 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error) { - Messenger *m = tox->m; - const int ret = del_groupchat(m->conferences_object, conference_number, true); + lock(tox); + const int ret = del_groupchat(tox->m->conferences_object, conference_number, true); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND); @@ -1546,8 +1650,9 @@ bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Confere uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_number_peers(m->conferences_object, conference_number, false); + lock(tox); + const int ret = group_number_peers(tox->m->conferences_object, conference_number, false); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND); @@ -1561,8 +1666,9 @@ uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, T size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_number, uint32_t peer_number, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peername_size(m->conferences_object, conference_number, peer_number, false); + lock(tox); + const int ret = group_peername_size(tox->m->conferences_object, conference_number, peer_number, false); + unlock(tox); switch (ret) { case -1: @@ -1581,8 +1687,9 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, uint32_t peer_number, uint8_t *name, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peername(m->conferences_object, conference_number, peer_number, name, false); + lock(tox); + const int ret = group_peername(tox->m->conferences_object, conference_number, peer_number, name, false); + unlock(tox); switch (ret) { case -1: @@ -1601,8 +1708,9 @@ bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, ui bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_number, uint32_t peer_number, uint8_t *public_key, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peer_pubkey(m->conferences_object, conference_number, peer_number, public_key, false); + lock(tox); + const int ret = group_peer_pubkey(tox->m->conferences_object, conference_number, peer_number, public_key, false); + unlock(tox); switch (ret) { case -1: @@ -1621,8 +1729,9 @@ bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_numb bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_number, uint32_t peer_number, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peernumber_is_ours(m->conferences_object, conference_number, peer_number); + lock(tox); + const int ret = group_peernumber_is_ours(tox->m->conferences_object, conference_number, peer_number); + unlock(tox); switch (ret) { case -1: @@ -1645,8 +1754,9 @@ bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_numb uint32_t tox_conference_offline_peer_count(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_number_peers(m->conferences_object, conference_number, true); + lock(tox); + const int ret = group_number_peers(tox->m->conferences_object, conference_number, true); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND); @@ -1661,8 +1771,9 @@ size_t tox_conference_offline_peer_get_name_size(const Tox *tox, uint32_t confer uint32_t offline_peer_number, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peername_size(m->conferences_object, conference_number, offline_peer_number, true); + lock(tox); + const int ret = group_peername_size(tox->m->conferences_object, conference_number, offline_peer_number, true); + unlock(tox); switch (ret) { case -1: @@ -1682,8 +1793,9 @@ bool tox_conference_offline_peer_get_name(const Tox *tox, uint32_t conference_nu uint8_t *name, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peername(m->conferences_object, conference_number, offline_peer_number, name, true); + lock(tox); + const int ret = group_peername(tox->m->conferences_object, conference_number, offline_peer_number, name, true); + unlock(tox); switch (ret) { case -1: @@ -1703,8 +1815,9 @@ bool tox_conference_offline_peer_get_public_key(const Tox *tox, uint32_t confere uint32_t offline_peer_number, uint8_t *public_key, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; - const int ret = group_peer_pubkey(m->conferences_object, conference_number, offline_peer_number, public_key, true); + lock(tox); + const int ret = group_peer_pubkey(tox->m->conferences_object, conference_number, offline_peer_number, public_key, true); + unlock(tox); switch (ret) { case -1: @@ -1724,9 +1837,11 @@ uint64_t tox_conference_offline_peer_get_last_active(const Tox *tox, uint32_t co uint32_t offline_peer_number, Tox_Err_Conference_Peer_Query *error) { - const Messenger *m = tox->m; uint64_t last_active = UINT64_MAX; - const int ret = group_frozen_last_active(m->conferences_object, conference_number, offline_peer_number, &last_active); + lock(tox); + const int ret = group_frozen_last_active(tox->m->conferences_object, conference_number, offline_peer_number, + &last_active); + unlock(tox); switch (ret) { case -1: @@ -1746,8 +1861,9 @@ bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number, uint32_t max_offline_peers, Tox_Err_Conference_Set_Max_Offline *error) { - const Messenger *m = tox->m; - const int ret = group_set_max_frozen(m->conferences_object, conference_number, max_offline_peers); + lock(tox); + const int ret = group_set_max_frozen(tox->m->conferences_object, conference_number, max_offline_peers); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND); @@ -1761,8 +1877,9 @@ bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number, bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference_number, Tox_Err_Conference_Invite *error) { - Messenger *m = tox->m; - const int ret = invite_friend(m->conferences_object, friend_number, conference_number); + lock(tox); + const int ret = invite_friend(tox->m->conferences_object, friend_number, conference_number); + unlock(tox); switch (ret) { case -1: @@ -1785,8 +1902,9 @@ bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *cookie, size_t length, Tox_Err_Conference_Join *error) { - Messenger *m = tox->m; - const int ret = join_groupchat(m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length); + lock(tox); + const int ret = join_groupchat(tox->m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length); + unlock(tox); switch (ret) { case -1: @@ -1821,15 +1939,17 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Message_Type type, const uint8_t *message, size_t length, Tox_Err_Conference_Send_Message *error) { - Messenger *m = tox->m; + lock(tox); int ret = 0; if (type == TOX_MESSAGE_TYPE_NORMAL) { - ret = group_message_send(m->conferences_object, conference_number, message, length); + ret = group_message_send(tox->m->conferences_object, conference_number, message, length); } else { - ret = group_action_send(m->conferences_object, conference_number, message, length); + ret = group_action_send(tox->m->conferences_object, conference_number, message, length); } + unlock(tox); + switch (ret) { case -1: SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SEND_MESSAGE_CONFERENCE_NOT_FOUND); @@ -1854,8 +1974,9 @@ bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Messa size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Title *error) { - const Messenger *m = tox->m; - const int ret = group_title_get_size(m->conferences_object, conference_number); + lock(tox); + const int ret = group_title_get_size(tox->m->conferences_object, conference_number); + unlock(tox); switch (ret) { case -1: @@ -1874,8 +1995,9 @@ size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_t *title, Tox_Err_Conference_Title *error) { - const Messenger *m = tox->m; - const int ret = group_title_get(m->conferences_object, conference_number, title); + lock(tox); + const int ret = group_title_get(tox->m->conferences_object, conference_number, title); + unlock(tox); switch (ret) { case -1: @@ -1894,8 +2016,9 @@ bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_t *title, size_t length, Tox_Err_Conference_Title *error) { - Messenger *m = tox->m; - const int ret = group_title_send(m->conferences_object, conference_number, title, length); + lock(tox); + const int ret = group_title_send(tox->m->conferences_object, conference_number, title, length); + unlock(tox); switch (ret) { case -1: @@ -1917,22 +2040,26 @@ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_ size_t tox_conference_get_chatlist_size(const Tox *tox) { - const Messenger *m = tox->m; - return count_chatlist(m->conferences_object); + lock(tox); + size_t ret = count_chatlist(tox->m->conferences_object); + unlock(tox); + return ret; } void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist) { - const Messenger *m = tox->m; - const size_t list_size = tox_conference_get_chatlist_size(tox); - copy_chatlist(m->conferences_object, chatlist, list_size); + lock(tox); + const size_t list_size = count_chatlist(tox->m->conferences_object); + copy_chatlist(tox->m->conferences_object, chatlist, list_size); + unlock(tox); } Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Get_Type *error) { - const Messenger *m = tox->m; - const int ret = group_get_type(m->conferences_object, conference_number); + lock(tox); + const int ret = group_get_type(tox->m->conferences_object, conference_number); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND); @@ -1943,13 +2070,18 @@ Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_ return (Tox_Conference_Type)ret; } -bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *id /* TOX_CONFERENCE_ID_SIZE bytes */) +/* id is TOX_CONFERENCE_ID_SIZE bytes */ +bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *id) { - return conference_get_id(tox->m->conferences_object, conference_number, id); + lock(tox); + bool ret = conference_get_id(tox->m->conferences_object, conference_number, id); + unlock(tox); + return ret; } // TODO(iphydf): Delete in 0.3.0. -bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid /* TOX_CONFERENCE_ID_SIZE bytes */) +/* uid is TOX_CONFERENCE_ID_SIZE bytes */ +bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid) { return tox_conference_get_id(tox, conference_number, uid); } @@ -1961,7 +2093,9 @@ uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Confere return UINT32_MAX; } + lock(tox); const int32_t ret = conference_by_id(tox->m->conferences_object, id); + unlock(tox); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND); @@ -2032,8 +2166,6 @@ bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_ return 0; } - Messenger *m = tox->m; - if (length == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY); return 0; @@ -2046,7 +2178,9 @@ bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_ return 0; } - const int ret = m_send_custom_lossy_packet(m, friend_number, data, length); + lock(tox); + const int ret = m_send_custom_lossy_packet(tox->m, friend_number, data, length); + unlock(tox); set_custom_packet_error(ret, error); @@ -2070,14 +2204,14 @@ bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uin return 0; } - Messenger *m = tox->m; - if (length == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY); return 0; } - const int ret = send_custom_lossless_packet(m, friend_number, data, length); + lock(tox); + const int ret = send_custom_lossless_packet(tox->m, friend_number, data, length); + unlock(tox); set_custom_packet_error(ret, error); @@ -2096,15 +2230,17 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id) { if (dht_id) { - const Messenger *m = tox->m; - memcpy(dht_id, dht_get_self_public_key(m->dht), CRYPTO_PUBLIC_KEY_SIZE); + lock(tox); + memcpy(dht_id, dht_get_self_public_key(tox->m->dht), CRYPTO_PUBLIC_KEY_SIZE); + unlock(tox); } } uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error) { - const Messenger *m = tox->m; - const uint16_t port = net_htons(net_port(m->net)); + lock(tox); + const uint16_t port = net_htons(net_port(tox->m->net)); + unlock(tox); if (port) { SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK); @@ -2117,13 +2253,16 @@ uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error) uint16_t tox_self_get_tcp_port(const Tox *tox, Tox_Err_Get_Port *error) { - const Messenger *m = tox->m; + lock(tox); - if (m->tcp_server) { + if (tox->m->tcp_server) { SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK); - return m->options.tcp_server_port; + uint16_t ret = tox->m->options.tcp_server_port; + unlock(tox); + return ret; } SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND); + unlock(tox); return 0; } diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h index af6f33608b..fd57e20d42 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.h +++ b/protocols/Tox/libtox/src/toxcore/tox.h @@ -1,25 +1,10 @@ -/* - * The Tox public API. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * The Tox public API. */ #ifndef C_TOXCORE_TOXCORE_TOX_H #define C_TOXCORE_TOXCORE_TOX_H @@ -183,7 +168,7 @@ uint32_t tox_version_minor(void); * The patch or revision number. Incremented when bugfixes are applied without * changing any functionality or API or ABI. */ -#define TOX_VERSION_PATCH 10 +#define TOX_VERSION_PATCH 11 uint32_t tox_version_patch(void); @@ -690,6 +675,20 @@ struct Tox_Options { */ void *log_user_data; + + /** + * These options are experimental, so avoid writing code that depends on + * them. Options marked "experimental" may change their behaviour or go away + * entirely in the future, or may be renamed to something non-experimental + * if they become part of the supported API. + */ + /** + * Make public API functions thread-safe using a per-instance lock. + * + * Default: false. + */ + bool experimental_thread_safety; + }; @@ -753,6 +752,10 @@ void *tox_options_get_log_user_data(const struct Tox_Options *options); void tox_options_set_log_user_data(struct Tox_Options *options, void *user_data); +bool tox_options_get_experimental_thread_safety(const struct Tox_Options *options); + +void tox_options_set_experimental_thread_safety(struct Tox_Options *options, bool thread_safety); + /** * Initialises a Tox_Options object with the default options. * @@ -2538,7 +2541,7 @@ typedef enum TOX_ERR_CONFERENCE_NEW { /** * Creates a new conference. * - * This function creates a new text conference. + * This function creates and connects to a new text conference. * * @return conference number on success, or an unspecified value on failure. */ @@ -2597,7 +2600,10 @@ typedef enum TOX_ERR_CONFERENCE_PEER_QUERY { /** - * Return the number of peers in the conference. Return value is unspecified on failure. + * Return the number of online peers in the conference. The unsigned + * integers less than this number are the valid values of peer_number for + * the functions querying these peers. Return value is unspecified on + * failure. */ uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_PEER_QUERY *error); @@ -2635,7 +2641,9 @@ bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_numb TOX_ERR_CONFERENCE_PEER_QUERY *error); /** - * Return the number of offline peers in the conference. Return value is unspecified on failure. + * Return the number of offline peers in the conference. The unsigned + * integers less than this number are the valid values of offline_peer_number for + * the functions querying these peers. Return value is unspecified on failure. */ uint32_t tox_conference_offline_peer_count(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_PEER_QUERY *error); @@ -2722,10 +2730,6 @@ typedef enum TOX_ERR_CONFERENCE_INVITE { /** * Invites a friend to a conference. * - * We must be connected to the conference, meaning that the conference has not - * been deleted, and either we created the conference with the tox_conference_new function, - * or a `conference_connected` event has occurred for the conference. - * * @param friend_number The friend number of the friend we want to invite. * @param conference_number The conference number of the conference we want to invite the friend to. * @@ -2777,6 +2781,14 @@ typedef enum TOX_ERR_CONFERENCE_JOIN { /** * Joins a conference that the client has been invited to. * + * After successfully joining the conference, the client will not be "connected" + * to it until a handshaking procedure has been completed. A + * `conference_connected` event will then occur for the conference. The client + * will then remain connected to the conference until the conference is deleted, + * even across core restarts. Many operations on a conference will fail with a + * corresponding error if attempted on a conference to which the client is not + * yet connected. + * * @param friend_number The friend number of the friend who sent the invite. * @param cookie Received via the `conference_invite` event. * @param length The size of cookie. @@ -2903,8 +2915,16 @@ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_ size_t tox_conference_get_chatlist_size(const Tox *tox); /** - * Copy a list of valid conference IDs into the array chatlist. Determine how much space - * to allocate for the array with the `tox_conference_get_chatlist_size` function. + * Copy a list of valid conference numbers into the array chatlist. Determine + * how much space to allocate for the array with the `tox_conference_get_chatlist_size` function. + * + * Note that `tox_get_savedata` saves all connected conferences; + * when toxcore is created from savedata in which conferences were saved, those + * conferences will be connected at startup, and will be listed by + * `tox_conference_get_chatlist`. + * + * The conference number of a loaded conference may differ from the conference + * number it had when it was saved. */ void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist); diff --git a/protocols/Tox/libtox/src/toxcore/tox_api.c b/protocols/Tox/libtox/src/toxcore/tox_api.c index 025c745623..8503f237c9 100644 --- a/protocols/Tox/libtox/src/toxcore/tox_api.c +++ b/protocols/Tox/libtox/src/toxcore/tox_api.c @@ -58,6 +58,7 @@ ACCESSORS(size_t, savedata_, length) ACCESSORS(tox_log_cb *, log_, callback) ACCESSORS(void *, log_, user_data) ACCESSORS(bool,, local_discovery_enabled) +ACCESSORS(bool,, experimental_thread_safety) const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options) { @@ -80,6 +81,7 @@ void tox_options_default(struct Tox_Options *options) tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE); tox_options_set_hole_punching_enabled(options, true); tox_options_set_local_discovery_enabled(options, true); + tox_options_set_experimental_thread_safety(options, false); } } diff --git a/protocols/Tox/libtox/src/toxcore/util.c b/protocols/Tox/libtox/src/toxcore/util.c index 73e16c4585..58b75763e5 100644 --- a/protocols/Tox/libtox/src/toxcore/util.c +++ b/protocols/Tox/libtox/src/toxcore/util.c @@ -1,27 +1,11 @@ -/* - * Utilities. - */ - -/* +/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * Copyright © 2013 plutooo - * - * This file is part of Tox, the free peer to peer instant messenger. - * This file is donated to the Tox Project. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Utilities. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -52,25 +36,6 @@ uint32_t id_copy(uint8_t *dest, const uint8_t *src) return CRYPTO_PUBLIC_KEY_SIZE; } -void host_to_net(uint8_t *num, uint16_t numbytes) -{ -#ifndef WORDS_BIGENDIAN - uint32_t i; - VLA(uint8_t, buff, numbytes); - - for (i = 0; i < numbytes; ++i) { - buff[i] = num[numbytes - i - 1]; - } - - memcpy(num, buff, numbytes); -#endif -} - -void net_to_host(uint8_t *num, uint16_t numbytes) -{ - host_to_net(num, numbytes); -} - int create_recursive_mutex(pthread_mutex_t *mutex) { pthread_mutexattr_t attr; diff --git a/protocols/Tox/libtox/src/toxcore/util.h b/protocols/Tox/libtox/src/toxcore/util.h index 79f5deb528..5483ff049e 100644 --- a/protocols/Tox/libtox/src/toxcore/util.h +++ b/protocols/Tox/libtox/src/toxcore/util.h @@ -1,27 +1,11 @@ -/* - * Utilities. - */ - -/* +/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * Copyright © 2013 plutooo - * - * This file is part of Tox, the free peer to peer instant messenger. - * This file is donated to the Tox Project. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Utilities. */ #ifndef C_TOXCORE_TOXCORE_UTIL_H #define C_TOXCORE_TOXCORE_UTIL_H @@ -40,9 +24,6 @@ extern "C" { bool id_equal(const uint8_t *dest, const uint8_t *src); uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ -void host_to_net(uint8_t *num, uint16_t numbytes); -void net_to_host(uint8_t *num, uint16_t numbytes); - /* Returns -1 if failed or 0 if success */ int create_recursive_mutex(pthread_mutex_t *mutex); diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h index c6a395f3eb..b1068c5079 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h @@ -1,26 +1,11 @@ %{ -/* - * Batch encryption functions. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013-2016 Tox Developers. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013-2016 Tox Developers. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Batch encryption functions. */ #ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H #define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c index a3e70b2f1e..70aa3746e4 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c @@ -1,25 +1,10 @@ -/* - * Batch encryption functions. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013 Tox project. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Batch encryption functions. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h index 0d608b1ced..34287a1ac9 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h @@ -1,25 +1,10 @@ -/* - * Batch encryption functions. +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013-2016 Tox Developers. */ /* - * Copyright © 2016-2018 The TokTok team. - * Copyright © 2013-2016 Tox Developers. - * - * This file is part of Tox, the free peer to peer instant messenger. - * - * Tox 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 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that 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 Tox. If not, see <http://www.gnu.org/licenses/>. + * Batch encryption functions. */ #ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H #define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H |