├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── dns2tcp.c └── libev ├── config.h ├── ev.c ├── ev.h ├── ev_epoll.c ├── ev_vars.h └── ev_wrap.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.gch 3 | dns2tcp 4 | .vscode/ 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -std=c99 -Wall -Wextra -Wvla -O3 -flto -fno-strict-aliasing -ffunction-sections -fdata-sections -DNDEBUG 3 | LDFLAGS = -O3 -flto -fno-strict-aliasing -Wl,--gc-sections -s 4 | LIBS = -lm 5 | SRCS = dns2tcp.c libev/ev.c 6 | OBJS = $(SRCS:.c=.o) 7 | MAIN = dns2tcp 8 | DESTDIR = /usr/local/bin 9 | 10 | .PHONY: all install clean 11 | 12 | all: $(MAIN) 13 | 14 | install: $(MAIN) 15 | mkdir -p $(DESTDIR) 16 | install -m 0755 $(MAIN) $(DESTDIR) 17 | 18 | clean: 19 | $(RM) $(MAIN) *.o libev/*.o 20 | 21 | $(MAIN): $(OBJS) 22 | $(CC) $(LDFLAGS) -o $(MAIN) $(OBJS) $(LIBS) 23 | 24 | .c.o: 25 | $(CC) $(CFLAGS) -c $< -o $@ 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dns2tcp 2 | 3 | 一个 DNS 实用工具,用于将 DNS 查询从 UDP 转为 TCP。 4 | 5 | 当然有很多 DNS 工具都可以实现这个功能,比如 pdnsd、dnsforwarder;但如果你只是想使用其 UDP 转 TCP 功能(比如配合 dnsmasq,将 dnsmasq 向上游发出的 DNS 查询从 UDP 转为 TCP),那么 dns2tcp 可能是更好的选择。 6 | 7 | `dns2tcp` 设计的非常简洁以及易用,它不需要任何配置文件,在命令行参数中指定一个 **本地 UDP 监听地址** 以及一个 **远程 DNS 服务器地址**(该 DNS 服务器支持 TCP 查询)即可,没有任何多余功能。 8 | 9 | ## 如何编译 10 | 11 | > 为了方便使用,[releases](https://github.com/zfl9/dns2tcp/releases) 页面发布了 linux 下常见架构的 musl 静态链接二进制。 12 | 13 | ```bash 14 | git clone https://github.com/zfl9/dns2tcp 15 | cd dns2tcp 16 | make && sudo make install 17 | ``` 18 | 19 | dns2tcp 默认安装到 `/usr/local/bin/dns2tcp`,可安装到其它目录,如 `make install DESTDIR=/opt/local/bin`。 20 | 21 | 交叉编译时只需指定 CC 变量,如 `make CC=aarch64-linux-gnu-gcc`(若报错,请先执行 `make clean`,然后再试)。 22 | 23 | ## 如何运行 24 | 25 | ```bash 26 | # sh/bash 可以不加引号,zsh 必须加引号,防止#被转义 27 | # UPDATE: 从 v1.1.1 版本开始可以省略端口号,默认是 53 28 | dns2tcp -L "127.0.0.1#5353" -R "8.8.8.8#53" 29 | 30 | # 如果想在后台运行,可以这样做: 31 | (dns2tcp -L "127.0.0.1#5353" -R "8.8.8.8#53" >/var/log/dns2tcp.log &) 32 | ``` 33 | 34 | - `-L` 选项指定本地监听地址,该监听地址接受 UDP 协议的 DNS 查询。 35 | - `-R` 选项指定远程 DNS 服务器地址,该 DNS 服务器应支持 TCP 查询。 36 | 37 | ## 小技巧 38 | 39 | 借助 iptables,将本机发往 8.8.8.8:53 的 UDP 查询请求,强行重定向至本机 dns2tcp 监听端口,这样就可以不用修改原有 dns 组件的配置,无感转换为 TCP 查询。还是上面那个例子,在启动 dns2tcp 之后,再执行如下 iptables 命令: 40 | 41 | ```bash 42 | # 将目标地址为 8.8.8.8:53/udp 的包重定向至 dns2tcp 监听端口,实现透明 udp2tcp 转换 43 | iptables -t nat -A OUTPUT -p udp -d 8.8.8.8 --dport 53 -j REDIRECT --to-ports 5353 44 | ``` 45 | 46 | 你可以在本机使用 `dig @8.8.8.8 baidu.com` 测试,观察 dns2tcp 日志(带上 -v),就会发现走 TCP 出去了。 47 | 48 | ## 全部参数 49 | 50 | ```console 51 | usage: dns2tcp <-L listen> <-R remote> [options...] 52 | -L udp listen address, port default to 53 53 | -R tcp remote address, port default to 53 54 | -l tcp local address, port default to 0 55 | -s set TCP_SYNCNT option for tcp socket 56 | -6 set IPV6_V6ONLY option for udp socket 57 | -r set SO_REUSEPORT option for udp socket 58 | -v print verbose log, used for debugging 59 | -V print version number of dns2tcp and exit 60 | -h print help information of dns2tcp and exit 61 | bug report: https://github.com/zfl9/dns2tcp. email: zfl9.com@gmail.com 62 | ``` 63 | 64 | `-l`:设置`TCP`连接的本地地址(源地址),`0地址`或`0端口`表示由系统选择。 65 | 66 | `-s`:对`TCP`套接字设置`TCP_SYNCNT`,该选项值将影响`TCP`的连接超时时间。 67 | 68 | `-6`:对`UDP`套接字设置`IPV6_V6ONLY`,建议始终启用,把 v4 和 v6 监听严格区分开。 69 | 70 | `-r`:对`UDP`套接字设置`SO_REUSEPORT`,用于多进程负载均衡,Linux 3.9+ 开始可用。 71 | -------------------------------------------------------------------------------- /dns2tcp.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "libev/ev.h" 18 | 19 | #define DNS2TCP_VER "dns2tcp v1.1.2" 20 | 21 | #ifndef IPV6_V6ONLY 22 | #define IPV6_V6ONLY 26 23 | #endif 24 | 25 | #ifndef SO_REUSEPORT 26 | #define SO_REUSEPORT 15 27 | #endif 28 | 29 | #ifndef TCP_SYNCNT 30 | #define TCP_SYNCNT 7 31 | #endif 32 | 33 | #define IP4STRLEN INET_ADDRSTRLEN /* include \0 */ 34 | #define IP6STRLEN INET6_ADDRSTRLEN /* include \0 */ 35 | #define PORTSTRLEN 6 /* "65535" (include \0) */ 36 | 37 | #define DNS_MSGSZ 1472 /* mtu:1500 - iphdr:20 - udphdr:8 */ 38 | 39 | /* ======================== helper ======================== */ 40 | 41 | #define __unused __attribute__((unused)) 42 | 43 | #define alignto(alignment) __attribute__((aligned(alignment))) 44 | 45 | // get the struct pointer by the field(member) pointer 46 | #define container_of(p_field, struct_type, field_name) ( \ 47 | (struct_type *) ((void *)(p_field) - offsetof(struct_type, field_name)) \ 48 | ) 49 | 50 | /* ======================== log-func ======================== */ 51 | 52 | #define log_write(color, level, fmt, args...) ({ \ 53 | time_t t_ = time(NULL); \ 54 | const struct tm *tm_ = localtime(&t_); \ 55 | printf("\e[" color ";1m%d-%02d-%02d %02d:%02d:%02d " level "\e[0m " \ 56 | "\e[1m[%s]\e[0m " fmt "\n", \ 57 | tm_->tm_year + 1900, tm_->tm_mon + 1, tm_->tm_mday, \ 58 | tm_->tm_hour, tm_->tm_min, tm_->tm_sec, \ 59 | __func__, ##args); \ 60 | }) 61 | 62 | #define log_verbose(fmt, args...) ({ \ 63 | if (verbose) log_info(fmt, ##args); \ 64 | }) 65 | 66 | #define log_info(fmt, args...) \ 67 | log_write("32", "I", fmt, ##args) 68 | 69 | #define log_warning(fmt, args...) \ 70 | log_write("33", "W", fmt, ##args) 71 | 72 | #define log_error(fmt, args...) \ 73 | log_write("35", "E", fmt, ##args) 74 | 75 | /* ======================== socket-addr ======================== */ 76 | 77 | union skaddr { 78 | struct sockaddr sa; 79 | struct sockaddr_in sin; 80 | struct sockaddr_in6 sin6; 81 | }; 82 | 83 | #define skaddr_family(addr) ((addr)->sa.sa_family) 84 | #define skaddr_is_sin(addr) (skaddr_family(addr) == AF_INET) 85 | #define skaddr_is_sin6(addr) (skaddr_family(addr) == AF_INET6) 86 | #define skaddr_len(addr) (skaddr_is_sin(addr) ? sizeof((addr)->sin) : sizeof((addr)->sin6)) 87 | 88 | static void skaddr_from_text(union skaddr *addr, int family, const char *ipstr, uint16_t port) { 89 | if (family == AF_INET) { 90 | addr->sin.sin_family = AF_INET; 91 | inet_pton(AF_INET, ipstr, &addr->sin.sin_addr); 92 | addr->sin.sin_port = htons(port); 93 | } else { 94 | addr->sin6.sin6_family = AF_INET6; 95 | inet_pton(AF_INET6, ipstr, &addr->sin6.sin6_addr); 96 | addr->sin6.sin6_port = htons(port); 97 | } 98 | } 99 | 100 | static void skaddr_to_text(const union skaddr *addr, char *ipstr, uint16_t *port) { 101 | if (skaddr_is_sin(addr)) { 102 | inet_ntop(AF_INET, &addr->sin.sin_addr, ipstr, IP4STRLEN); 103 | *port = ntohs(addr->sin.sin_port); 104 | } else { 105 | inet_ntop(AF_INET6, &addr->sin6.sin6_addr, ipstr, IP6STRLEN); 106 | *port = ntohs(addr->sin6.sin6_port); 107 | } 108 | } 109 | 110 | /* AF_INET, AF_INET6, -1(invalid) */ 111 | static int get_ipstr_family(const char *ipstr) { 112 | char tmp[16]; 113 | if (!ipstr) 114 | return -1; 115 | if (inet_pton(AF_INET, ipstr, &tmp) == 1) 116 | return AF_INET; 117 | if (inet_pton(AF_INET6, ipstr, &tmp) == 1) 118 | return AF_INET6; 119 | return -1; 120 | } 121 | 122 | /* ======================== context ======================== */ 123 | 124 | typedef struct { 125 | evio_t watcher; /* tcp watcher */ 126 | char buffer[2 + DNS_MSGSZ] alignto(__alignof__(uint16_t)); /* msglen(be16) + msg */ 127 | uint16_t nbytes; /* nrecv or nsend */ 128 | union skaddr srcaddr; 129 | } ctx_t; 130 | 131 | /* ======================== global-vars ======================== */ 132 | 133 | enum { 134 | FLAG_IPV6_V6ONLY = 1 << 0, /* udp listen */ 135 | FLAG_REUSE_PORT = 1 << 1, /* udp listen */ 136 | FLAG_VERBOSE = 1 << 2, /* logging */ 137 | FLAG_LOCAL_ADDR = 1 << 3, /* tcp local addr */ 138 | }; 139 | 140 | #define has_flag(flag) (g_flags & (flag)) 141 | #define add_flag(flag) (g_flags |= (flag)) 142 | 143 | #define verbose has_flag(FLAG_VERBOSE) 144 | 145 | static uint8_t g_flags = 0; 146 | static uint8_t g_syn_cnt = 0; 147 | 148 | /* udp listen */ 149 | static int g_listen_fd = -1; 150 | static char g_listen_ipstr[IP6STRLEN] = {0}; 151 | static uint16_t g_listen_port = 0; 152 | static union skaddr g_listen_skaddr = {0}; 153 | 154 | /* tcp server address */ 155 | static char g_remote_ipstr[IP6STRLEN] = {0}; 156 | static uint16_t g_remote_port = 0; 157 | static union skaddr g_remote_skaddr = {0}; 158 | 159 | /* tcp local address [optional] */ 160 | static char g_local_ipstr[IP6STRLEN] = {0}; 161 | static uint16_t g_local_port = 0; 162 | static union skaddr g_local_skaddr = {0}; 163 | 164 | static void udp_recvmsg_cb(evloop_t *evloop, evio_t *watcher, int events); 165 | static void tcp_connect_cb(evloop_t *evloop, evio_t *watcher, int events); 166 | static void tcp_sendmsg_cb(evloop_t *evloop, evio_t *watcher, int events); 167 | static void tcp_recvmsg_cb(evloop_t *evloop, evio_t *watcher, int events); 168 | 169 | static void print_help(void) { 170 | printf("usage: dns2tcp <-L listen> <-R remote> [options...]\n" 171 | " -L udp listen address, port default to 53\n" 172 | " -R tcp remote address, port default to 53\n" 173 | " -l tcp local address, port default to 0\n" 174 | " -s set TCP_SYNCNT option for tcp socket\n" 175 | " -6 set IPV6_V6ONLY option for udp socket\n" 176 | " -r set SO_REUSEPORT option for udp socket\n" 177 | " -v print verbose log, used for debugging\n" 178 | " -V print version number of dns2tcp and exit\n" 179 | " -h print help information of dns2tcp and exit\n" 180 | "bug report: https://github.com/zfl9/dns2tcp. email: zfl9.com@gmail.com\n" 181 | ); 182 | } 183 | 184 | enum addr_type { 185 | ADDR_UDP_LISTEN, 186 | ADDR_TCP_REMOTE, 187 | ADDR_TCP_LOCAL, 188 | }; 189 | 190 | static void parse_addr(const char *addr, enum addr_type addr_type) { 191 | const char *end = addr + strlen(addr); 192 | const char *sep = strchr(addr, '#') ?: end; 193 | 194 | const char *ipstart = addr; 195 | int iplen = sep - ipstart; 196 | 197 | const char *portstart = sep + 1; 198 | int portlen = (sep < end) ? end - portstart : -1; 199 | 200 | char ipstr[IP6STRLEN]; 201 | if (iplen >= IP6STRLEN) goto err; 202 | 203 | memcpy(ipstr, ipstart, iplen); 204 | ipstr[iplen] = 0; 205 | 206 | int family = get_ipstr_family(ipstr); 207 | if (family == -1) goto err; 208 | 209 | uint16_t port = addr_type != ADDR_TCP_LOCAL ? 53 : 0; 210 | if (portlen >= 0 && (port = strtoul(portstart, NULL, 10)) == 0 && addr_type != ADDR_TCP_LOCAL) goto err; 211 | 212 | #define set_addr(tag) ({ \ 213 | strcpy(g_##tag##_ipstr, ipstr); \ 214 | g_##tag##_port = port; \ 215 | skaddr_from_text(&g_##tag##_skaddr, family, ipstr, port); \ 216 | }) 217 | 218 | switch (addr_type) { 219 | case ADDR_UDP_LISTEN: 220 | set_addr(listen); 221 | break; 222 | case ADDR_TCP_REMOTE: 223 | set_addr(remote); 224 | break; 225 | case ADDR_TCP_LOCAL: 226 | set_addr(local); 227 | break; 228 | } 229 | 230 | #undef set_addr 231 | 232 | return; 233 | 234 | err:; 235 | const char *type; 236 | switch (addr_type) { 237 | case ADDR_UDP_LISTEN: 238 | type = "udp_listen"; 239 | break; 240 | case ADDR_TCP_REMOTE: 241 | type = "tcp_remote"; 242 | break; 243 | case ADDR_TCP_LOCAL: 244 | type = "tcp_local"; 245 | break; 246 | } 247 | 248 | printf("invalid %s address: '%s'\n", type, addr); 249 | print_help(); 250 | exit(1); 251 | } 252 | 253 | static void parse_opt(int argc, char *argv[]) { 254 | char opt_listen_addr[IP6STRLEN + PORTSTRLEN] = {0}; 255 | char opt_remote_addr[IP6STRLEN + PORTSTRLEN] = {0}; 256 | char opt_local_addr[IP6STRLEN + PORTSTRLEN] = {0}; 257 | 258 | opterr = 0; 259 | int shortopt; 260 | const char *optstr = "L:R:l:s:6rafvVh"; 261 | while ((shortopt = getopt(argc, argv, optstr)) != -1) { 262 | switch (shortopt) { 263 | case 'L': 264 | if (strlen(optarg) + 1 > IP6STRLEN + PORTSTRLEN) { 265 | printf("invalid udp listen addr: %s\n", optarg); 266 | goto err; 267 | } 268 | strcpy(opt_listen_addr, optarg); 269 | break; 270 | case 'R': 271 | if (strlen(optarg) + 1 > IP6STRLEN + PORTSTRLEN) { 272 | printf("invalid tcp remote addr: %s\n", optarg); 273 | goto err; 274 | } 275 | strcpy(opt_remote_addr, optarg); 276 | break; 277 | case 'l': 278 | if (strlen(optarg) + 1 > IP6STRLEN + PORTSTRLEN) { 279 | printf("invalid tcp local addr: %s\n", optarg); 280 | goto err; 281 | } 282 | strcpy(opt_local_addr, optarg); 283 | add_flag(FLAG_LOCAL_ADDR); 284 | break; 285 | case 's': 286 | g_syn_cnt = strtoul(optarg, NULL, 10); 287 | if (g_syn_cnt == 0) { 288 | printf("invalid tcp syn cnt: %s\n", optarg); 289 | goto err; 290 | } 291 | break; 292 | case '6': 293 | add_flag(FLAG_IPV6_V6ONLY); 294 | break; 295 | case 'r': 296 | add_flag(FLAG_REUSE_PORT); 297 | break; 298 | case 'a': 299 | /* nop */ 300 | break; 301 | case 'f': 302 | /* nop */ 303 | break; 304 | case 'v': 305 | add_flag(FLAG_VERBOSE); 306 | break; 307 | case 'V': 308 | printf(DNS2TCP_VER"\n"); 309 | exit(0); 310 | case 'h': 311 | print_help(); 312 | exit(0); 313 | case '?': 314 | if (!strchr(optstr, optopt)) { 315 | printf("unknown option '-%c'\n", optopt); 316 | } else { 317 | printf("missing optval '-%c'\n", optopt); 318 | } 319 | goto err; 320 | } 321 | } 322 | 323 | /* check the required opt */ 324 | if (strlen(opt_listen_addr) == 0) { 325 | printf("missing option: '-L'\n"); 326 | goto err; 327 | } 328 | if (strlen(opt_remote_addr) == 0) { 329 | printf("missing option: '-R'\n"); 330 | goto err; 331 | } 332 | 333 | parse_addr(opt_listen_addr, ADDR_UDP_LISTEN); 334 | parse_addr(opt_remote_addr, ADDR_TCP_REMOTE); 335 | 336 | if (has_flag(FLAG_LOCAL_ADDR)) 337 | parse_addr(opt_local_addr, ADDR_TCP_LOCAL); 338 | 339 | return; 340 | 341 | err: 342 | print_help(); 343 | exit(1); 344 | } 345 | 346 | /* udp listen or tcp connect */ 347 | static int create_socket(int family, int type) { 348 | const char *err_op = NULL; 349 | 350 | int fd = socket(family, type | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); 351 | if (fd < 0) { 352 | err_op = "create_socket"; 353 | goto out; 354 | } 355 | 356 | const int opt = 1; 357 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 358 | err_op = "set_reuseaddr"; 359 | goto out; 360 | } 361 | 362 | if (type == SOCK_DGRAM) { 363 | // udp listen socket 364 | if (has_flag(FLAG_REUSE_PORT) && setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { 365 | err_op = "set_reuseport"; 366 | goto out; 367 | } 368 | if (family == AF_INET6 && has_flag(FLAG_IPV6_V6ONLY) && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) < 0) { 369 | err_op = "set_ipv6only"; 370 | goto out; 371 | } 372 | } else { 373 | // tcp connect socket 374 | if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) { 375 | err_op = "set_tcp_nodelay"; 376 | goto out; 377 | } 378 | const int syn_cnt = g_syn_cnt; 379 | if (syn_cnt && setsockopt(fd, IPPROTO_TCP, TCP_SYNCNT, &syn_cnt, sizeof(syn_cnt)) < 0) { 380 | err_op = "set_tcp_syncnt"; 381 | goto out; 382 | } 383 | } 384 | 385 | out: 386 | if (err_op) 387 | log_error("%s(fd:%d, family:%d, type:%d) failed: %m", err_op, fd, family, type); 388 | return fd; 389 | } 390 | 391 | int main(int argc, char *argv[]) { 392 | signal(SIGPIPE, SIG_IGN); 393 | setvbuf(stdout, NULL, _IOLBF, 256); 394 | parse_opt(argc, argv); 395 | 396 | log_info("udp listen addr: %s#%hu", g_listen_ipstr, g_listen_port); 397 | log_info("tcp remote addr: %s#%hu", g_remote_ipstr, g_remote_port); 398 | if (has_flag(FLAG_LOCAL_ADDR)) log_info("tcp local addr: %s#%hu", g_local_ipstr, g_local_port); 399 | if (g_syn_cnt) log_info("enable TCP_SYNCNT:%hhu sockopt", g_syn_cnt); 400 | if (has_flag(FLAG_IPV6_V6ONLY)) log_info("enable IPV6_V6ONLY sockopt"); 401 | if (has_flag(FLAG_REUSE_PORT)) log_info("enable SO_REUSEPORT sockopt"); 402 | log_verbose("print the verbose log"); 403 | 404 | g_listen_fd = create_socket(skaddr_family(&g_listen_skaddr), SOCK_DGRAM); 405 | if (g_listen_fd < 0) 406 | return 1; 407 | 408 | if (bind(g_listen_fd, &g_listen_skaddr.sa, skaddr_len(&g_listen_skaddr)) < 0) { 409 | log_error("bind udp address: %m"); 410 | return 1; 411 | } 412 | 413 | evloop_t *evloop = ev_default_loop(0); 414 | 415 | evio_t watcher; 416 | ev_io_init(&watcher, udp_recvmsg_cb, g_listen_fd, EV_READ); 417 | ev_io_start(evloop, &watcher); 418 | 419 | return ev_run(evloop, 0); 420 | } 421 | 422 | static void udp_recvmsg_cb(evloop_t *evloop, evio_t *watcher __unused, int events __unused) { 423 | ctx_t *ctx = malloc(sizeof(*ctx)); 424 | 425 | ssize_t nrecv = recvfrom(g_listen_fd, (void *)ctx->buffer + 2, DNS_MSGSZ, 0, &ctx->srcaddr.sa, &(socklen_t){sizeof(ctx->srcaddr)}); 426 | if (nrecv < 0) { 427 | if (errno != EAGAIN && errno != EWOULDBLOCK) 428 | log_warning("recv from udp socket: %m"); 429 | goto free_ctx; 430 | } 431 | 432 | if (verbose) { 433 | char ip[IP6STRLEN]; 434 | uint16_t port; 435 | skaddr_to_text(&ctx->srcaddr, ip, &port); 436 | log_info("recv from %s#%hu, nrecv:%zd", ip, port, nrecv); 437 | } 438 | 439 | uint16_t *p_msglen = (void *)ctx->buffer; 440 | *p_msglen = htons(nrecv); /* msg length */ 441 | 442 | int fd = create_socket(skaddr_family(&g_remote_skaddr), SOCK_STREAM); 443 | if (fd < 0) 444 | goto free_ctx; 445 | 446 | if (has_flag(FLAG_LOCAL_ADDR) && bind(fd, &g_local_skaddr.sa, skaddr_len(&g_local_skaddr)) < 0) { 447 | log_warning("bind tcp address: %m"); 448 | goto close_fd; 449 | } 450 | 451 | if (connect(fd, &g_remote_skaddr.sa, skaddr_len(&g_remote_skaddr)) < 0 && errno != EINPROGRESS) { 452 | log_warning("connect to %s#%hu: %m", g_remote_ipstr, g_remote_port); 453 | goto close_fd; 454 | } 455 | log_verbose("try to connect to %s#%hu", g_remote_ipstr, g_remote_port); 456 | 457 | ev_io_init(&ctx->watcher, tcp_connect_cb, fd, EV_WRITE); 458 | ev_io_start(evloop, &ctx->watcher); 459 | 460 | return; 461 | 462 | close_fd: 463 | close(fd); 464 | free_ctx: 465 | free(ctx); 466 | } 467 | 468 | static void free_ctx(ctx_t *ctx, evloop_t *evloop) { 469 | ev_io_stop(evloop, &ctx->watcher); 470 | close(ctx->watcher.fd); 471 | free(ctx); 472 | } 473 | 474 | static void tcp_connect_cb(evloop_t *evloop, evio_t *watcher, int events __unused) { 475 | ctx_t *ctx = container_of(watcher, ctx_t, watcher); 476 | 477 | if (getsockopt(watcher->fd, SOL_SOCKET, SO_ERROR, &errno, &(socklen_t){sizeof(errno)}) < 0 || errno) { 478 | log_warning("connect to %s#%hu: %m", g_remote_ipstr, g_remote_port); 479 | free_ctx(ctx, evloop); 480 | return; 481 | } 482 | log_verbose("connect to %s#%hu succeed", g_remote_ipstr, g_remote_port); 483 | 484 | ctx->nbytes = 0; 485 | ev_set_cb(watcher, tcp_sendmsg_cb); 486 | ev_invoke(evloop, watcher, EV_WRITE); 487 | } 488 | 489 | static void tcp_sendmsg_cb(evloop_t *evloop, evio_t *watcher, int events __unused) { 490 | ctx_t *ctx = container_of(watcher, ctx_t, watcher); 491 | 492 | uint16_t *p_msglen = (void *)ctx->buffer; 493 | uint16_t datalen = 2 + ntohs(*p_msglen); 494 | 495 | ssize_t nsend = send(watcher->fd, (void *)ctx->buffer + ctx->nbytes, datalen - ctx->nbytes, 0); 496 | if (nsend < 0) { 497 | if (errno == EAGAIN || errno == EWOULDBLOCK) return; 498 | log_warning("send to %s#%hu: %m", g_remote_ipstr, g_remote_port); 499 | free_ctx(ctx, evloop); 500 | return; 501 | } 502 | log_verbose("send to %s#%hu, nsend:%zd", g_remote_ipstr, g_remote_port, nsend); 503 | 504 | ctx->nbytes += nsend; 505 | if (ctx->nbytes >= datalen) { 506 | ctx->nbytes = 0; 507 | ev_io_stop(evloop, watcher); 508 | ev_io_init(watcher, tcp_recvmsg_cb, watcher->fd, EV_READ); 509 | ev_io_start(evloop, watcher); 510 | } 511 | } 512 | 513 | static void tcp_recvmsg_cb(evloop_t *evloop, evio_t *watcher, int events __unused) { 514 | ctx_t *ctx = container_of(watcher, ctx_t, watcher); 515 | 516 | void *buffer = ctx->buffer; 517 | 518 | ssize_t nrecv = recv(watcher->fd, buffer + ctx->nbytes, 2 + DNS_MSGSZ - ctx->nbytes, 0); 519 | if (nrecv < 0) { 520 | if (errno == EAGAIN || errno == EWOULDBLOCK) return; 521 | log_warning("recv from %s#%hu: %m", g_remote_ipstr, g_remote_port); 522 | goto free_ctx; 523 | } 524 | if (nrecv == 0) { 525 | log_warning("recv from %s#%hu: connection is closed", g_remote_ipstr, g_remote_port); 526 | goto free_ctx; 527 | } 528 | log_verbose("recv from %s#%hu, nrecv:%zd", g_remote_ipstr, g_remote_port, nrecv); 529 | 530 | ctx->nbytes += nrecv; 531 | 532 | uint16_t msglen; 533 | if (ctx->nbytes < 2 || ctx->nbytes < 2 + (msglen = ntohs(*(uint16_t *)buffer))) return; 534 | 535 | ssize_t nsend = sendto(g_listen_fd, buffer + 2, msglen, 0, &ctx->srcaddr.sa, skaddr_len(&ctx->srcaddr)); 536 | if (nsend < 0 || verbose) { 537 | char ip[IP6STRLEN]; 538 | uint16_t port; 539 | skaddr_to_text(&ctx->srcaddr, ip, &port); 540 | if (nsend < 0) 541 | log_warning("send to %s#%hu: %m", ip, port); 542 | else 543 | log_info("send to %s#%hu, nsend:%zd", ip, port, nsend); 544 | } 545 | 546 | free_ctx: 547 | free_ctx(ctx, evloop); 548 | } 549 | -------------------------------------------------------------------------------- /libev/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma GCC diagnostic ignored "-Wcomment" 4 | #pragma GCC diagnostic ignored "-Wunused-function" 5 | #pragma GCC diagnostic ignored "-Wunused-parameter" 6 | #pragma GCC diagnostic ignored "-Wunused-variable" 7 | #pragma GCC diagnostic ignored "-Wunused-value" 8 | #ifdef __clang__ 9 | #pragma GCC diagnostic ignored "-Wextern-initializer" 10 | #endif 11 | 12 | /* libev-4.33 */ 13 | #define EV_STANDALONE 1 /* manual configuration */ 14 | #define EV_COMPAT3 0 /* remove compatible code */ 15 | #define EV_VERIFY 0 /* remove verification code */ 16 | #define EV_USE_FLOOR 1 /* use libm.floor() function */ 17 | // #define EV_NO_SMP 1 /* disable multi-threads support */ 18 | // #define EV_NO_THREADS 1 /* disable multi-threads support */ 19 | #define EV_PERIODIC_ENABLE 0 /* disable ev_periodic watcher */ 20 | #define EV_SIGNAL_ENABLE 0 /* disable ev_signal watcher */ 21 | #define EV_CHILD_ENABLE 0 /* disable ev_child watcher */ 22 | #define EV_STAT_ENABLE 0 /* disable ev_stat watcher */ 23 | #define EV_IDLE_ENABLE 0 /* disable ev_idle watcher */ 24 | #define EV_PREPARE_ENABLE 0 /* disable ev_prepare watcher */ 25 | #define EV_CHECK_ENABLE 0 /* disable ev_check watcher */ 26 | #define EV_EMBED_ENABLE 0 /* disable ev_embed watcher */ 27 | #define EV_FORK_ENABLE 0 /* disable ev_fork watcher */ 28 | #define EV_CLEANUP_ENABLE 0 /* disable ev_cleanup watcher */ 29 | #define EV_ASYNC_ENABLE 0 /* disbale ev_async watcher */ 30 | 31 | #define EV_USE_SELECT 0 32 | #define EV_USE_POLL 0 33 | #define EV_USE_EPOLL 1 34 | #define EV_USE_LINUXAIO 0 35 | #define EV_USE_IOURING 0 36 | #define EV_USE_KQUEUE 0 37 | #define EV_USE_PORT 0 38 | #define EV_USE_INOTIFY 0 39 | 40 | #define EV_USE_MONOTONIC 0 41 | #define EV_USE_REALTIME 0 42 | #define EV_USE_CLOCK_SYSCALL 0 43 | 44 | #define EV_USE_TIMERFD 0 45 | #define EV_USE_EVENTFD 0 46 | #define EV_USE_SIGNALFD 0 47 | 48 | #define EV_MINPRI 0 49 | #define EV_MAXPRI 0 50 | 51 | /* typedef struct */ 52 | typedef struct ev_loop evloop_t; 53 | typedef struct ev_io evio_t; 54 | typedef struct ev_timer evtimer_t; 55 | 56 | /* typedef callback */ 57 | typedef void (*evio_cb_t)(evloop_t *evloop, evio_t *watcher, int revents); 58 | typedef void (*evtimer_cb_t)(evloop_t *evloop, evtimer_t *watcher, int revents); 59 | -------------------------------------------------------------------------------- /libev/ev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libev native API header 3 | * 4 | * Copyright (c) 2007-2020 Marc Alexander Lehmann 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modifica- 8 | * tion, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | * OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Alternatively, the contents of this file may be used under the terms of 29 | * the GNU General Public License ("GPL") version 2 or any later version, 30 | * in which case the provisions of the GPL are applicable instead of 31 | * the above. If you wish to allow the use of your version of this file 32 | * only under the terms of the GPL and not to allow others to use your 33 | * version of this file under the BSD license, indicate your decision 34 | * by deleting the provisions above and replace them with the notice 35 | * and other provisions required by the GPL. If you do not delete the 36 | * provisions above, a recipient may use your version of this file under 37 | * either the BSD or the GPL. 38 | */ 39 | 40 | #ifndef EV_H_ 41 | #define EV_H_ 42 | 43 | #include "config.h" 44 | 45 | #ifdef __cplusplus 46 | # define EV_CPP(x) x 47 | # if __cplusplus >= 201103L 48 | # define EV_NOEXCEPT noexcept 49 | # else 50 | # define EV_NOEXCEPT 51 | # endif 52 | #else 53 | # define EV_CPP(x) 54 | # define EV_NOEXCEPT 55 | #endif 56 | #define EV_THROW EV_NOEXCEPT /* pre-4.25, do not use in new code */ 57 | 58 | EV_CPP(extern "C" {) 59 | 60 | /*****************************************************************************/ 61 | 62 | /* pre-4.0 compatibility */ 63 | #ifndef EV_COMPAT3 64 | # define EV_COMPAT3 1 65 | #endif 66 | 67 | #ifndef EV_FEATURES 68 | # if defined __OPTIMIZE_SIZE__ 69 | # define EV_FEATURES 0x7c 70 | # else 71 | # define EV_FEATURES 0x7f 72 | # endif 73 | #endif 74 | 75 | #define EV_FEATURE_CODE ((EV_FEATURES) & 1) 76 | #define EV_FEATURE_DATA ((EV_FEATURES) & 2) 77 | #define EV_FEATURE_CONFIG ((EV_FEATURES) & 4) 78 | #define EV_FEATURE_API ((EV_FEATURES) & 8) 79 | #define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16) 80 | #define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32) 81 | #define EV_FEATURE_OS ((EV_FEATURES) & 64) 82 | 83 | /* these priorities are inclusive, higher priorities will be invoked earlier */ 84 | #ifndef EV_MINPRI 85 | # define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0) 86 | #endif 87 | #ifndef EV_MAXPRI 88 | # define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0) 89 | #endif 90 | 91 | #ifndef EV_MULTIPLICITY 92 | # define EV_MULTIPLICITY EV_FEATURE_CONFIG 93 | #endif 94 | 95 | #ifndef EV_PERIODIC_ENABLE 96 | # define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS 97 | #endif 98 | 99 | #ifndef EV_STAT_ENABLE 100 | # define EV_STAT_ENABLE EV_FEATURE_WATCHERS 101 | #endif 102 | 103 | #ifndef EV_PREPARE_ENABLE 104 | # define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS 105 | #endif 106 | 107 | #ifndef EV_CHECK_ENABLE 108 | # define EV_CHECK_ENABLE EV_FEATURE_WATCHERS 109 | #endif 110 | 111 | #ifndef EV_IDLE_ENABLE 112 | # define EV_IDLE_ENABLE EV_FEATURE_WATCHERS 113 | #endif 114 | 115 | #ifndef EV_FORK_ENABLE 116 | # define EV_FORK_ENABLE EV_FEATURE_WATCHERS 117 | #endif 118 | 119 | #ifndef EV_CLEANUP_ENABLE 120 | # define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS 121 | #endif 122 | 123 | #ifndef EV_SIGNAL_ENABLE 124 | # define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS 125 | #endif 126 | 127 | #ifndef EV_CHILD_ENABLE 128 | # ifdef _WIN32 129 | # define EV_CHILD_ENABLE 0 130 | # else 131 | # define EV_CHILD_ENABLE EV_FEATURE_WATCHERS 132 | #endif 133 | #endif 134 | 135 | #ifndef EV_ASYNC_ENABLE 136 | # define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS 137 | #endif 138 | 139 | #ifndef EV_EMBED_ENABLE 140 | # define EV_EMBED_ENABLE EV_FEATURE_WATCHERS 141 | #endif 142 | 143 | #ifndef EV_WALK_ENABLE 144 | # define EV_WALK_ENABLE 0 /* not yet */ 145 | #endif 146 | 147 | /*****************************************************************************/ 148 | 149 | #if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE 150 | # undef EV_SIGNAL_ENABLE 151 | # define EV_SIGNAL_ENABLE 1 152 | #endif 153 | 154 | /*****************************************************************************/ 155 | 156 | #ifndef EV_TSTAMP_T 157 | # define EV_TSTAMP_T double 158 | #endif 159 | typedef EV_TSTAMP_T ev_tstamp; 160 | 161 | #include /* for memmove */ 162 | 163 | #ifndef EV_ATOMIC_T 164 | # include 165 | # define EV_ATOMIC_T sig_atomic_t volatile 166 | #endif 167 | 168 | #if EV_STAT_ENABLE 169 | # ifdef _WIN32 170 | # include 171 | # include 172 | # endif 173 | # include 174 | #endif 175 | 176 | /* support multiple event loops? */ 177 | #if EV_MULTIPLICITY 178 | struct ev_loop; 179 | # define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */ 180 | # define EV_P_ EV_P, /* a loop as first of multiple parameters */ 181 | # define EV_A loop /* a loop as sole argument to a function call */ 182 | # define EV_A_ EV_A, /* a loop as first of multiple arguments */ 183 | # define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */ 184 | # define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */ 185 | # define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */ 186 | # define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */ 187 | #else 188 | # define EV_P void 189 | # define EV_P_ 190 | # define EV_A 191 | # define EV_A_ 192 | # define EV_DEFAULT 193 | # define EV_DEFAULT_ 194 | # define EV_DEFAULT_UC 195 | # define EV_DEFAULT_UC_ 196 | # undef EV_EMBED_ENABLE 197 | #endif 198 | 199 | /* EV_INLINE is used for functions in header files */ 200 | #if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3 201 | # define EV_INLINE static inline 202 | #else 203 | # define EV_INLINE static 204 | #endif 205 | 206 | #ifdef EV_API_STATIC 207 | # define EV_API_DECL static 208 | #else 209 | # define EV_API_DECL extern 210 | #endif 211 | 212 | /* EV_PROTOTYPES can be used to switch of prototype declarations */ 213 | #ifndef EV_PROTOTYPES 214 | # define EV_PROTOTYPES 1 215 | #endif 216 | 217 | /*****************************************************************************/ 218 | 219 | #define EV_VERSION_MAJOR 4 220 | #define EV_VERSION_MINOR 33 221 | 222 | /* eventmask, revents, events... */ 223 | enum { 224 | EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */ 225 | EV_NONE = 0x00, /* no events */ 226 | EV_READ = 0x01, /* ev_io detected read will not block */ 227 | EV_WRITE = 0x02, /* ev_io detected write will not block */ 228 | EV__IOFDSET = 0x80, /* internal use only */ 229 | EV_IO = EV_READ, /* alias for type-detection */ 230 | EV_TIMER = 0x00000100, /* timer timed out */ 231 | #if EV_COMPAT3 232 | EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */ 233 | #endif 234 | EV_PERIODIC = 0x00000200, /* periodic timer timed out */ 235 | EV_SIGNAL = 0x00000400, /* signal was received */ 236 | EV_CHILD = 0x00000800, /* child/pid had status change */ 237 | EV_STAT = 0x00001000, /* stat data changed */ 238 | EV_IDLE = 0x00002000, /* event loop is idling */ 239 | EV_PREPARE = 0x00004000, /* event loop about to poll */ 240 | EV_CHECK = 0x00008000, /* event loop finished poll */ 241 | EV_EMBED = 0x00010000, /* embedded event loop needs sweep */ 242 | EV_FORK = 0x00020000, /* event loop resumed in child */ 243 | EV_CLEANUP = 0x00040000, /* event loop resumed in child */ 244 | EV_ASYNC = 0x00080000, /* async intra-loop signal */ 245 | EV_CUSTOM = 0x01000000, /* for use by user code */ 246 | EV_ERROR = (int)0x80000000 /* sent when an error occurs */ 247 | }; 248 | 249 | /* can be used to add custom fields to all watchers, while losing binary compatibility */ 250 | #ifndef EV_COMMON 251 | # define EV_COMMON void *data; 252 | #endif 253 | 254 | #ifndef EV_CB_DECLARE 255 | # define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents); 256 | #endif 257 | #ifndef EV_CB_INVOKE 258 | # define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents)) 259 | #endif 260 | 261 | /* not official, do not use */ 262 | #define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents) 263 | 264 | /* 265 | * struct member types: 266 | * private: you may look at them, but not change them, 267 | * and they might not mean anything to you. 268 | * ro: can be read anytime, but only changed when the watcher isn't active. 269 | * rw: can be read and modified anytime, even when the watcher is active. 270 | * 271 | * some internal details that might be helpful for debugging: 272 | * 273 | * active is either 0, which means the watcher is not active, 274 | * or the array index of the watcher (periodics, timers) 275 | * or the array index + 1 (most other watchers) 276 | * or simply 1 for watchers that aren't in some array. 277 | * pending is either 0, in which case the watcher isn't, 278 | * or the array index + 1 in the pendings array. 279 | */ 280 | 281 | #if EV_MINPRI == EV_MAXPRI 282 | # define EV_DECL_PRIORITY 283 | #elif !defined (EV_DECL_PRIORITY) 284 | # define EV_DECL_PRIORITY int priority; 285 | #endif 286 | 287 | /* shared by all watchers */ 288 | #define EV_WATCHER(type) \ 289 | int active; /* private */ \ 290 | int pending; /* private */ \ 291 | EV_DECL_PRIORITY /* private */ \ 292 | EV_COMMON /* rw */ \ 293 | EV_CB_DECLARE (type) /* private */ 294 | 295 | #define EV_WATCHER_LIST(type) \ 296 | EV_WATCHER (type) \ 297 | struct ev_watcher_list *next; /* private */ 298 | 299 | #define EV_WATCHER_TIME(type) \ 300 | EV_WATCHER (type) \ 301 | ev_tstamp at; /* private */ 302 | 303 | /* base class, nothing to see here unless you subclass */ 304 | typedef struct ev_watcher 305 | { 306 | EV_WATCHER (ev_watcher) 307 | } ev_watcher; 308 | 309 | /* base class, nothing to see here unless you subclass */ 310 | typedef struct ev_watcher_list 311 | { 312 | EV_WATCHER_LIST (ev_watcher_list) 313 | } ev_watcher_list; 314 | 315 | /* base class, nothing to see here unless you subclass */ 316 | typedef struct ev_watcher_time 317 | { 318 | EV_WATCHER_TIME (ev_watcher_time) 319 | } ev_watcher_time; 320 | 321 | /* invoked when fd is either EV_READable or EV_WRITEable */ 322 | /* revent EV_READ, EV_WRITE */ 323 | typedef struct ev_io 324 | { 325 | EV_WATCHER_LIST (ev_io) 326 | 327 | int fd; /* ro */ 328 | int events; /* ro */ 329 | } ev_io; 330 | 331 | /* invoked after a specific time, repeatable (based on monotonic clock) */ 332 | /* revent EV_TIMEOUT */ 333 | typedef struct ev_timer 334 | { 335 | EV_WATCHER_TIME (ev_timer) 336 | 337 | ev_tstamp repeat; /* rw */ 338 | } ev_timer; 339 | 340 | /* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */ 341 | /* revent EV_PERIODIC */ 342 | typedef struct ev_periodic 343 | { 344 | EV_WATCHER_TIME (ev_periodic) 345 | 346 | ev_tstamp offset; /* rw */ 347 | ev_tstamp interval; /* rw */ 348 | ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_NOEXCEPT; /* rw */ 349 | } ev_periodic; 350 | 351 | /* invoked when the given signal has been received */ 352 | /* revent EV_SIGNAL */ 353 | typedef struct ev_signal 354 | { 355 | EV_WATCHER_LIST (ev_signal) 356 | 357 | int signum; /* ro */ 358 | } ev_signal; 359 | 360 | /* invoked when sigchld is received and waitpid indicates the given pid */ 361 | /* revent EV_CHILD */ 362 | /* does not support priorities */ 363 | typedef struct ev_child 364 | { 365 | EV_WATCHER_LIST (ev_child) 366 | 367 | int flags; /* private */ 368 | int pid; /* ro */ 369 | int rpid; /* rw, holds the received pid */ 370 | int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */ 371 | } ev_child; 372 | 373 | #if EV_STAT_ENABLE 374 | /* st_nlink = 0 means missing file or other error */ 375 | # ifdef _WIN32 376 | typedef struct _stati64 ev_statdata; 377 | # else 378 | typedef struct stat ev_statdata; 379 | # endif 380 | 381 | /* invoked each time the stat data changes for a given path */ 382 | /* revent EV_STAT */ 383 | typedef struct ev_stat 384 | { 385 | EV_WATCHER_LIST (ev_stat) 386 | 387 | ev_timer timer; /* private */ 388 | ev_tstamp interval; /* ro */ 389 | const char *path; /* ro */ 390 | ev_statdata prev; /* ro */ 391 | ev_statdata attr; /* ro */ 392 | 393 | int wd; /* wd for inotify, fd for kqueue */ 394 | } ev_stat; 395 | #endif 396 | 397 | /* invoked when the nothing else needs to be done, keeps the process from blocking */ 398 | /* revent EV_IDLE */ 399 | typedef struct ev_idle 400 | { 401 | EV_WATCHER (ev_idle) 402 | } ev_idle; 403 | 404 | /* invoked for each run of the mainloop, just before the blocking call */ 405 | /* you can still change events in any way you like */ 406 | /* revent EV_PREPARE */ 407 | typedef struct ev_prepare 408 | { 409 | EV_WATCHER (ev_prepare) 410 | } ev_prepare; 411 | 412 | /* invoked for each run of the mainloop, just after the blocking call */ 413 | /* revent EV_CHECK */ 414 | typedef struct ev_check 415 | { 416 | EV_WATCHER (ev_check) 417 | } ev_check; 418 | 419 | /* the callback gets invoked before check in the child process when a fork was detected */ 420 | /* revent EV_FORK */ 421 | typedef struct ev_fork 422 | { 423 | EV_WATCHER (ev_fork) 424 | } ev_fork; 425 | 426 | /* is invoked just before the loop gets destroyed */ 427 | /* revent EV_CLEANUP */ 428 | typedef struct ev_cleanup 429 | { 430 | EV_WATCHER (ev_cleanup) 431 | } ev_cleanup; 432 | 433 | #if EV_EMBED_ENABLE 434 | /* used to embed an event loop inside another */ 435 | /* the callback gets invoked when the event loop has handled events, and can be 0 */ 436 | typedef struct ev_embed 437 | { 438 | EV_WATCHER (ev_embed) 439 | 440 | struct ev_loop *other; /* ro */ 441 | #undef EV_IO_ENABLE 442 | #define EV_IO_ENABLE 1 443 | ev_io io; /* private */ 444 | #undef EV_PREPARE_ENABLE 445 | #define EV_PREPARE_ENABLE 1 446 | ev_prepare prepare; /* private */ 447 | ev_check check; /* unused */ 448 | ev_timer timer; /* unused */ 449 | ev_periodic periodic; /* unused */ 450 | ev_idle idle; /* unused */ 451 | ev_fork fork; /* private */ 452 | ev_cleanup cleanup; /* unused */ 453 | } ev_embed; 454 | #endif 455 | 456 | #if EV_ASYNC_ENABLE 457 | /* invoked when somebody calls ev_async_send on the watcher */ 458 | /* revent EV_ASYNC */ 459 | typedef struct ev_async 460 | { 461 | EV_WATCHER (ev_async) 462 | 463 | EV_ATOMIC_T sent; /* private */ 464 | } ev_async; 465 | 466 | # define ev_async_pending(w) (+(w)->sent) 467 | #endif 468 | 469 | /* the presence of this union forces similar struct layout */ 470 | union ev_any_watcher 471 | { 472 | struct ev_watcher w; 473 | struct ev_watcher_list wl; 474 | 475 | struct ev_io io; 476 | struct ev_timer timer; 477 | struct ev_periodic periodic; 478 | struct ev_signal signal; 479 | struct ev_child child; 480 | #if EV_STAT_ENABLE 481 | struct ev_stat stat; 482 | #endif 483 | #if EV_IDLE_ENABLE 484 | struct ev_idle idle; 485 | #endif 486 | struct ev_prepare prepare; 487 | struct ev_check check; 488 | #if EV_FORK_ENABLE 489 | struct ev_fork fork; 490 | #endif 491 | #if EV_CLEANUP_ENABLE 492 | struct ev_cleanup cleanup; 493 | #endif 494 | #if EV_EMBED_ENABLE 495 | struct ev_embed embed; 496 | #endif 497 | #if EV_ASYNC_ENABLE 498 | struct ev_async async; 499 | #endif 500 | }; 501 | 502 | /* flag bits for ev_default_loop and ev_loop_new */ 503 | enum { 504 | /* the default */ 505 | EVFLAG_AUTO = 0x00000000U, /* not quite a mask */ 506 | /* flag bits */ 507 | EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */ 508 | EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */ 509 | /* debugging/feature disable */ 510 | EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */ 511 | #if EV_COMPAT3 512 | EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */ 513 | #endif 514 | EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */ 515 | EVFLAG_NOSIGMASK = 0x00400000U, /* avoid modifying the signal mask */ 516 | EVFLAG_NOTIMERFD = 0x00800000U /* avoid creating a timerfd */ 517 | }; 518 | 519 | /* method bits to be ored together */ 520 | enum { 521 | EVBACKEND_SELECT = 0x00000001U, /* available just about anywhere */ 522 | EVBACKEND_POLL = 0x00000002U, /* !win, !aix, broken on osx */ 523 | EVBACKEND_EPOLL = 0x00000004U, /* linux */ 524 | EVBACKEND_KQUEUE = 0x00000008U, /* bsd, broken on osx */ 525 | EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */ 526 | EVBACKEND_PORT = 0x00000020U, /* solaris 10 */ 527 | EVBACKEND_LINUXAIO = 0x00000040U, /* linux AIO, 4.19+ */ 528 | EVBACKEND_IOURING = 0x00000080U, /* linux io_uring, 5.1+ */ 529 | EVBACKEND_ALL = 0x000000FFU, /* all known backends */ 530 | EVBACKEND_MASK = 0x0000FFFFU /* all future backends */ 531 | }; 532 | 533 | #if EV_PROTOTYPES 534 | EV_API_DECL int ev_version_major (void) EV_NOEXCEPT; 535 | EV_API_DECL int ev_version_minor (void) EV_NOEXCEPT; 536 | 537 | EV_API_DECL unsigned int ev_supported_backends (void) EV_NOEXCEPT; 538 | EV_API_DECL unsigned int ev_recommended_backends (void) EV_NOEXCEPT; 539 | EV_API_DECL unsigned int ev_embeddable_backends (void) EV_NOEXCEPT; 540 | 541 | EV_API_DECL ev_tstamp ev_time (void) EV_NOEXCEPT; 542 | EV_API_DECL void ev_sleep (ev_tstamp delay) EV_NOEXCEPT; /* sleep for a while */ 543 | 544 | /* Sets the allocation function to use, works like realloc. 545 | * It is used to allocate and free memory. 546 | * If it returns zero when memory needs to be allocated, the library might abort 547 | * or take some potentially destructive action. 548 | * The default is your system realloc function. 549 | */ 550 | EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_NOEXCEPT) EV_NOEXCEPT; 551 | 552 | /* set the callback function to call on a 553 | * retryable syscall error 554 | * (such as failed select, poll, epoll_wait) 555 | */ 556 | EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT; 557 | 558 | #if EV_MULTIPLICITY 559 | 560 | /* the default loop is the only one that handles signals and child watchers */ 561 | /* you can call this as often as you like */ 562 | EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; 563 | 564 | #ifdef EV_API_STATIC 565 | EV_API_DECL struct ev_loop *ev_default_loop_ptr; 566 | #endif 567 | 568 | EV_INLINE struct ev_loop * 569 | ev_default_loop_uc_ (void) EV_NOEXCEPT 570 | { 571 | extern struct ev_loop *ev_default_loop_ptr; 572 | 573 | return ev_default_loop_ptr; 574 | } 575 | 576 | EV_INLINE int 577 | ev_is_default_loop (EV_P) EV_NOEXCEPT 578 | { 579 | return EV_A == EV_DEFAULT_UC; 580 | } 581 | 582 | /* create and destroy alternative loops that don't handle signals */ 583 | EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; 584 | 585 | EV_API_DECL ev_tstamp ev_now (EV_P) EV_NOEXCEPT; /* time w.r.t. timers and the eventloop, updated after each poll */ 586 | 587 | #else 588 | 589 | EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; /* returns true when successful */ 590 | 591 | EV_API_DECL ev_tstamp ev_rt_now; 592 | 593 | EV_INLINE ev_tstamp 594 | ev_now (void) EV_NOEXCEPT 595 | { 596 | return ev_rt_now; 597 | } 598 | 599 | /* looks weird, but ev_is_default_loop (EV_A) still works if this exists */ 600 | EV_INLINE int 601 | ev_is_default_loop (void) EV_NOEXCEPT 602 | { 603 | return 1; 604 | } 605 | 606 | #endif /* multiplicity */ 607 | 608 | /* destroy event loops, also works for the default loop */ 609 | EV_API_DECL void ev_loop_destroy (EV_P); 610 | 611 | /* this needs to be called after fork, to duplicate the loop */ 612 | /* when you want to re-use it in the child */ 613 | /* you can call it in either the parent or the child */ 614 | /* you can actually call it at any time, anywhere :) */ 615 | EV_API_DECL void ev_loop_fork (EV_P) EV_NOEXCEPT; 616 | 617 | EV_API_DECL unsigned int ev_backend (EV_P) EV_NOEXCEPT; /* backend in use by loop */ 618 | 619 | EV_API_DECL void ev_now_update (EV_P) EV_NOEXCEPT; /* update event loop time */ 620 | 621 | #if EV_WALK_ENABLE 622 | /* walk (almost) all watchers in the loop of a given type, invoking the */ 623 | /* callback on every such watcher. The callback might stop the watcher, */ 624 | /* but do nothing else with the loop */ 625 | EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT; 626 | #endif 627 | 628 | #endif /* prototypes */ 629 | 630 | /* ev_run flags values */ 631 | enum { 632 | EVRUN_NOWAIT = 1, /* do not block/wait */ 633 | EVRUN_ONCE = 2 /* block *once* only */ 634 | }; 635 | 636 | /* ev_break how values */ 637 | enum { 638 | EVBREAK_CANCEL = 0, /* undo unloop */ 639 | EVBREAK_ONE = 1, /* unloop once */ 640 | EVBREAK_ALL = 2 /* unloop all loops */ 641 | }; 642 | 643 | #if EV_PROTOTYPES 644 | EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0)); 645 | EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_NOEXCEPT; /* break out of the loop */ 646 | 647 | /* 648 | * ref/unref can be used to add or remove a refcount on the mainloop. every watcher 649 | * keeps one reference. if you have a long-running watcher you never unregister that 650 | * should not keep ev_loop from running, unref() after starting, and ref() before stopping. 651 | */ 652 | EV_API_DECL void ev_ref (EV_P) EV_NOEXCEPT; 653 | EV_API_DECL void ev_unref (EV_P) EV_NOEXCEPT; 654 | 655 | /* 656 | * convenience function, wait for a single event, without registering an event watcher 657 | * if timeout is < 0, do wait indefinitely 658 | */ 659 | EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_NOEXCEPT; 660 | 661 | EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */ 662 | 663 | # if EV_FEATURE_API 664 | EV_API_DECL unsigned int ev_iteration (EV_P) EV_NOEXCEPT; /* number of loop iterations */ 665 | EV_API_DECL unsigned int ev_depth (EV_P) EV_NOEXCEPT; /* #ev_loop enters - #ev_loop leaves */ 666 | EV_API_DECL void ev_verify (EV_P) EV_NOEXCEPT; /* abort if loop data corrupted */ 667 | 668 | EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */ 669 | EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */ 670 | 671 | /* advanced stuff for threading etc. support, see docs */ 672 | EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT; 673 | EV_API_DECL void *ev_userdata (EV_P) EV_NOEXCEPT; 674 | typedef void (*ev_loop_callback)(EV_P); 675 | EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT; 676 | /* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */ 677 | EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_NOEXCEPT, void (*acquire)(EV_P) EV_NOEXCEPT) EV_NOEXCEPT; 678 | 679 | EV_API_DECL unsigned int ev_pending_count (EV_P) EV_NOEXCEPT; /* number of pending events, if any */ 680 | 681 | /* 682 | * stop/start the timer handling. 683 | */ 684 | EV_API_DECL void ev_suspend (EV_P) EV_NOEXCEPT; 685 | EV_API_DECL void ev_resume (EV_P) EV_NOEXCEPT; 686 | #endif 687 | 688 | #endif 689 | 690 | /* these may evaluate ev multiple times, and the other arguments at most once */ 691 | /* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */ 692 | #define ev_init(ev,cb_) do { \ 693 | ((ev_watcher *)(void *)(ev))->active = \ 694 | ((ev_watcher *)(void *)(ev))->pending = 0; \ 695 | ev_set_priority ((ev), 0); \ 696 | ev_set_cb ((ev), cb_); \ 697 | } while (0) 698 | 699 | #define ev_io_modify(ev,events_) do { (ev)->events = ((ev)->events & EV__IOFDSET) | (events_); } while (0) 700 | #define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0) 701 | #define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0) 702 | #define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0) 703 | #define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0) 704 | #define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0) 705 | #define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0) 706 | #define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */ 707 | #define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */ 708 | #define ev_check_set(ev) /* nop, yes, this is a serious in-joke */ 709 | #define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0) 710 | #define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */ 711 | #define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */ 712 | #define ev_async_set(ev) /* nop, yes, this is a serious in-joke */ 713 | 714 | #define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0) 715 | #define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0) 716 | #define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0) 717 | #define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0) 718 | #define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0) 719 | #define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0) 720 | #define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0) 721 | #define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0) 722 | #define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0) 723 | #define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0) 724 | #define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0) 725 | #define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0) 726 | #define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0) 727 | 728 | #define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */ 729 | #define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */ 730 | 731 | #define ev_cb_(ev) (ev)->cb /* rw */ 732 | #define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb) 733 | 734 | #if EV_MINPRI == EV_MAXPRI 735 | # define ev_priority(ev) ((ev), EV_MINPRI) 736 | # define ev_set_priority(ev,pri) ((ev), (pri)) 737 | #else 738 | # define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority)) 739 | # define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri) 740 | #endif 741 | 742 | #define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at) 743 | 744 | #ifndef ev_set_cb 745 | /* memmove is used here to avoid strict aliasing violations, and hopefully is optimized out by any reasonable compiler */ 746 | # define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev)))) 747 | #endif 748 | 749 | /* stopping (enabling, adding) a watcher does nothing if it is already running */ 750 | /* stopping (disabling, deleting) a watcher does nothing unless it's already running */ 751 | #if EV_PROTOTYPES 752 | 753 | /* feeds an event into a watcher as if the event actually occurred */ 754 | /* accepts any ev_watcher type */ 755 | EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT; 756 | EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_NOEXCEPT; 757 | #if EV_SIGNAL_ENABLE 758 | EV_API_DECL void ev_feed_signal (int signum) EV_NOEXCEPT; 759 | EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_NOEXCEPT; 760 | #endif 761 | EV_API_DECL void ev_invoke (EV_P_ void *w, int revents); 762 | EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_NOEXCEPT; 763 | 764 | EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT; 765 | EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT; 766 | 767 | EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT; 768 | EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_NOEXCEPT; 769 | /* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */ 770 | EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_NOEXCEPT; 771 | /* return remaining time */ 772 | EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT; 773 | 774 | #if EV_PERIODIC_ENABLE 775 | EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT; 776 | EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_NOEXCEPT; 777 | EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_NOEXCEPT; 778 | #endif 779 | 780 | /* only supported in the default loop */ 781 | #if EV_SIGNAL_ENABLE 782 | EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_NOEXCEPT; 783 | EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_NOEXCEPT; 784 | #endif 785 | 786 | /* only supported in the default loop */ 787 | # if EV_CHILD_ENABLE 788 | EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_NOEXCEPT; 789 | EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_NOEXCEPT; 790 | # endif 791 | 792 | # if EV_STAT_ENABLE 793 | EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_NOEXCEPT; 794 | EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_NOEXCEPT; 795 | EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_NOEXCEPT; 796 | # endif 797 | 798 | # if EV_IDLE_ENABLE 799 | EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT; 800 | EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_NOEXCEPT; 801 | # endif 802 | 803 | #if EV_PREPARE_ENABLE 804 | EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT; 805 | EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_NOEXCEPT; 806 | #endif 807 | 808 | #if EV_CHECK_ENABLE 809 | EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT; 810 | EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_NOEXCEPT; 811 | #endif 812 | 813 | # if EV_FORK_ENABLE 814 | EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT; 815 | EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT; 816 | # endif 817 | 818 | # if EV_CLEANUP_ENABLE 819 | EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT; 820 | EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT; 821 | # endif 822 | 823 | # if EV_EMBED_ENABLE 824 | /* only supported when loop to be embedded is in fact embeddable */ 825 | EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT; 826 | EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT; 827 | EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT; 828 | # endif 829 | 830 | # if EV_ASYNC_ENABLE 831 | EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT; 832 | EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT; 833 | EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT; 834 | # endif 835 | 836 | #if EV_COMPAT3 837 | #define EVLOOP_NONBLOCK EVRUN_NOWAIT 838 | #define EVLOOP_ONESHOT EVRUN_ONCE 839 | #define EVUNLOOP_CANCEL EVBREAK_CANCEL 840 | #define EVUNLOOP_ONE EVBREAK_ONE 841 | #define EVUNLOOP_ALL EVBREAK_ALL 842 | #if EV_PROTOTYPES 843 | EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); } 844 | EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); } 845 | EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); } 846 | EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); } 847 | #if EV_FEATURE_API 848 | EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); } 849 | EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); } 850 | EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); } 851 | #endif 852 | #endif 853 | #else 854 | typedef struct ev_loop ev_loop; 855 | #endif 856 | 857 | #endif 858 | 859 | EV_CPP(}) 860 | 861 | #endif 862 | 863 | -------------------------------------------------------------------------------- /libev/ev_epoll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libev epoll fd activity backend 3 | * 4 | * Copyright (c) 2007,2008,2009,2010,2011,2016,2017,2019 Marc Alexander Lehmann 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modifica- 8 | * tion, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | * OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Alternatively, the contents of this file may be used under the terms of 29 | * the GNU General Public License ("GPL") version 2 or any later version, 30 | * in which case the provisions of the GPL are applicable instead of 31 | * the above. If you wish to allow the use of your version of this file 32 | * only under the terms of the GPL and not to allow others to use your 33 | * version of this file under the BSD license, indicate your decision 34 | * by deleting the provisions above and replace them with the notice 35 | * and other provisions required by the GPL. If you do not delete the 36 | * provisions above, a recipient may use your version of this file under 37 | * either the BSD or the GPL. 38 | */ 39 | 40 | /* 41 | * general notes about epoll: 42 | * 43 | * a) epoll silently removes fds from the fd set. as nothing tells us 44 | * that an fd has been removed otherwise, we have to continually 45 | * "rearm" fds that we suspect *might* have changed (same 46 | * problem with kqueue, but much less costly there). 47 | * b) the fact that ADD != MOD creates a lot of extra syscalls due to a) 48 | * and seems not to have any advantage. 49 | * c) the inability to handle fork or file descriptors (think dup) 50 | * limits the applicability over poll, so this is not a generic 51 | * poll replacement. 52 | * d) epoll doesn't work the same as select with many file descriptors 53 | * (such as files). while not critical, no other advanced interface 54 | * seems to share this (rather non-unixy) limitation. 55 | * e) epoll claims to be embeddable, but in practise you never get 56 | * a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32). 57 | * f) epoll_ctl returning EPERM means the fd is always ready. 58 | * 59 | * lots of "weird code" and complication handling in this file is due 60 | * to these design problems with epoll, as we try very hard to avoid 61 | * epoll_ctl syscalls for common usage patterns and handle the breakage 62 | * ensuing from receiving events for closed and otherwise long gone 63 | * file descriptors. 64 | */ 65 | 66 | #include 67 | 68 | #define EV_EMASK_EPERM 0x80 69 | 70 | static void 71 | epoll_modify (EV_P_ int fd, int oev, int nev) 72 | { 73 | struct epoll_event ev; 74 | unsigned char oldmask; 75 | 76 | /* 77 | * we handle EPOLL_CTL_DEL by ignoring it here 78 | * on the assumption that the fd is gone anyways 79 | * if that is wrong, we have to handle the spurious 80 | * event in epoll_poll. 81 | * if the fd is added again, we try to ADD it, and, if that 82 | * fails, we assume it still has the same eventmask. 83 | */ 84 | if (!nev) 85 | return; 86 | 87 | oldmask = anfds [fd].emask; 88 | anfds [fd].emask = nev; 89 | 90 | /* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */ 91 | ev.data.u64 = (uint64_t)(uint32_t)fd 92 | | ((uint64_t)(uint32_t)++anfds [fd].egen << 32); 93 | ev.events = (nev & EV_READ ? EPOLLIN : 0) 94 | | (nev & EV_WRITE ? EPOLLOUT : 0); 95 | 96 | if (ecb_expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) 97 | return; 98 | 99 | if (ecb_expect_true (errno == ENOENT)) 100 | { 101 | /* if ENOENT then the fd went away, so try to do the right thing */ 102 | if (!nev) 103 | goto dec_egen; 104 | 105 | if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev)) 106 | return; 107 | } 108 | else if (ecb_expect_true (errno == EEXIST)) 109 | { 110 | /* EEXIST means we ignored a previous DEL, but the fd is still active */ 111 | /* if the kernel mask is the same as the new mask, we assume it hasn't changed */ 112 | if (oldmask == nev) 113 | goto dec_egen; 114 | 115 | if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev)) 116 | return; 117 | } 118 | else if (ecb_expect_true (errno == EPERM)) 119 | { 120 | /* EPERM means the fd is always ready, but epoll is too snobbish */ 121 | /* to handle it, unlike select or poll. */ 122 | anfds [fd].emask = EV_EMASK_EPERM; 123 | 124 | /* add fd to epoll_eperms, if not already inside */ 125 | if (!(oldmask & EV_EMASK_EPERM)) 126 | { 127 | array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, array_needsize_noinit); 128 | epoll_eperms [epoll_epermcnt++] = fd; 129 | } 130 | 131 | return; 132 | } 133 | else 134 | assert (("libev: I/O watcher with invalid fd found in epoll_ctl", errno != EBADF && errno != ELOOP && errno != EINVAL)); 135 | 136 | fd_kill (EV_A_ fd); 137 | 138 | dec_egen: 139 | /* we didn't successfully call epoll_ctl, so decrement the generation counter again */ 140 | --anfds [fd].egen; 141 | } 142 | 143 | static void 144 | epoll_poll (EV_P_ ev_tstamp timeout) 145 | { 146 | int i; 147 | int eventcnt; 148 | 149 | if (ecb_expect_false (epoll_epermcnt)) 150 | timeout = EV_TS_CONST (0.); 151 | 152 | /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */ 153 | /* the default libev max wait time, however. */ 154 | EV_RELEASE_CB; 155 | eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, EV_TS_TO_MSEC (timeout)); 156 | EV_ACQUIRE_CB; 157 | 158 | if (ecb_expect_false (eventcnt < 0)) 159 | { 160 | if (errno != EINTR) 161 | ev_syserr ("(libev) epoll_wait"); 162 | 163 | return; 164 | } 165 | 166 | for (i = 0; i < eventcnt; ++i) 167 | { 168 | struct epoll_event *ev = epoll_events + i; 169 | 170 | int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */ 171 | int want = anfds [fd].events; 172 | int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) 173 | | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); 174 | 175 | /* 176 | * check for spurious notification. 177 | * this only finds spurious notifications on egen updates 178 | * other spurious notifications will be found by epoll_ctl, below 179 | * we assume that fd is always in range, as we never shrink the anfds array 180 | */ 181 | if (ecb_expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) 182 | { 183 | /* recreate kernel state */ 184 | postfork |= 2; 185 | continue; 186 | } 187 | 188 | if (ecb_expect_false (got & ~want)) 189 | { 190 | anfds [fd].emask = want; 191 | 192 | /* 193 | * we received an event but are not interested in it, try mod or del 194 | * this often happens because we optimistically do not unregister fds 195 | * when we are no longer interested in them, but also when we get spurious 196 | * notifications for fds from another process. this is partially handled 197 | * above with the gencounter check (== our fd is not the event fd), and 198 | * partially here, when epoll_ctl returns an error (== a child has the fd 199 | * but we closed it). 200 | * note: for events such as POLLHUP, where we can't know whether it refers 201 | * to EV_READ or EV_WRITE, we might issue redundant EPOLL_CTL_MOD calls. 202 | */ 203 | ev->events = (want & EV_READ ? EPOLLIN : 0) 204 | | (want & EV_WRITE ? EPOLLOUT : 0); 205 | 206 | /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ 207 | /* which is fortunately easy to do for us. */ 208 | if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) 209 | { 210 | postfork |= 2; /* an error occurred, recreate kernel state */ 211 | continue; 212 | } 213 | } 214 | 215 | fd_event (EV_A_ fd, got); 216 | } 217 | 218 | /* if the receive array was full, increase its size */ 219 | if (ecb_expect_false (eventcnt == epoll_eventmax)) 220 | { 221 | ev_free (epoll_events); 222 | epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1); 223 | epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); 224 | } 225 | 226 | /* now synthesize events for all fds where epoll fails, while select works... */ 227 | for (i = epoll_epermcnt; i--; ) 228 | { 229 | int fd = epoll_eperms [i]; 230 | unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE); 231 | 232 | if (anfds [fd].emask & EV_EMASK_EPERM && events) 233 | fd_event (EV_A_ fd, events); 234 | else 235 | { 236 | epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; 237 | anfds [fd].emask = 0; 238 | } 239 | } 240 | } 241 | 242 | static int 243 | epoll_epoll_create (void) 244 | { 245 | int fd; 246 | 247 | #if defined EPOLL_CLOEXEC && !defined __ANDROID__ 248 | fd = epoll_create1 (EPOLL_CLOEXEC); 249 | 250 | if (fd < 0 && (errno == EINVAL || errno == ENOSYS)) 251 | #endif 252 | { 253 | fd = epoll_create (256); 254 | 255 | if (fd >= 0) 256 | fcntl (fd, F_SETFD, FD_CLOEXEC); 257 | } 258 | 259 | return fd; 260 | } 261 | 262 | inline_size 263 | int 264 | epoll_init (EV_P_ int flags) 265 | { 266 | if ((backend_fd = epoll_epoll_create ()) < 0) 267 | return 0; 268 | 269 | backend_mintime = EV_TS_CONST (1e-3); /* epoll does sometimes return early, this is just to avoid the worst */ 270 | backend_modify = epoll_modify; 271 | backend_poll = epoll_poll; 272 | 273 | epoll_eventmax = 64; /* initial number of events receivable per poll */ 274 | epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); 275 | 276 | return EVBACKEND_EPOLL; 277 | } 278 | 279 | inline_size 280 | void 281 | epoll_destroy (EV_P) 282 | { 283 | ev_free (epoll_events); 284 | array_free (epoll_eperm, EMPTY); 285 | } 286 | 287 | ecb_cold 288 | static void 289 | epoll_fork (EV_P) 290 | { 291 | close (backend_fd); 292 | 293 | while ((backend_fd = epoll_epoll_create ()) < 0) 294 | ev_syserr ("(libev) epoll_create"); 295 | 296 | fd_rearm_all (EV_A); 297 | } 298 | 299 | -------------------------------------------------------------------------------- /libev/ev_vars.h: -------------------------------------------------------------------------------- 1 | /* 2 | * loop member variable declarations 3 | * 4 | * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2019 Marc Alexander Lehmann 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modifica- 8 | * tion, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | * OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Alternatively, the contents of this file may be used under the terms of 29 | * the GNU General Public License ("GPL") version 2 or any later version, 30 | * in which case the provisions of the GPL are applicable instead of 31 | * the above. If you wish to allow the use of your version of this file 32 | * only under the terms of the GPL and not to allow others to use your 33 | * version of this file under the BSD license, indicate your decision 34 | * by deleting the provisions above and replace them with the notice 35 | * and other provisions required by the GPL. If you do not delete the 36 | * provisions above, a recipient may use your version of this file under 37 | * either the BSD or the GPL. 38 | */ 39 | 40 | #define VARx(type,name) VAR(name, type name) 41 | 42 | VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */ 43 | VARx(ev_tstamp, mn_now) /* monotonic clock "now" */ 44 | VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */ 45 | 46 | /* for reverse feeding of events */ 47 | VARx(W *, rfeeds) 48 | VARx(int, rfeedmax) 49 | VARx(int, rfeedcnt) 50 | 51 | VAR (pendings, ANPENDING *pendings [NUMPRI]) 52 | VAR (pendingmax, int pendingmax [NUMPRI]) 53 | VAR (pendingcnt, int pendingcnt [NUMPRI]) 54 | VARx(int, pendingpri) /* highest priority currently pending */ 55 | VARx(ev_prepare, pending_w) /* dummy pending watcher */ 56 | 57 | VARx(ev_tstamp, io_blocktime) 58 | VARx(ev_tstamp, timeout_blocktime) 59 | 60 | VARx(int, backend) 61 | VARx(int, activecnt) /* total number of active events ("refcount") */ 62 | VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */ 63 | 64 | VARx(int, backend_fd) 65 | VARx(ev_tstamp, backend_mintime) /* assumed typical timer resolution */ 66 | VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev)) 67 | VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout)) 68 | 69 | VARx(ANFD *, anfds) 70 | VARx(int, anfdmax) 71 | 72 | VAR (evpipe, int evpipe [2]) 73 | VARx(ev_io, pipe_w) 74 | VARx(EV_ATOMIC_T, pipe_write_wanted) 75 | VARx(EV_ATOMIC_T, pipe_write_skipped) 76 | 77 | #if !defined(_WIN32) || EV_GENWRAP 78 | VARx(pid_t, curpid) 79 | #endif 80 | 81 | VARx(char, postfork) /* true if we need to recreate kernel state after fork */ 82 | 83 | #if EV_USE_SELECT || EV_GENWRAP 84 | VARx(void *, vec_ri) 85 | VARx(void *, vec_ro) 86 | VARx(void *, vec_wi) 87 | VARx(void *, vec_wo) 88 | #if defined(_WIN32) || EV_GENWRAP 89 | VARx(void *, vec_eo) 90 | #endif 91 | VARx(int, vec_max) 92 | #endif 93 | 94 | #if EV_USE_POLL || EV_GENWRAP 95 | VARx(struct pollfd *, polls) 96 | VARx(int, pollmax) 97 | VARx(int, pollcnt) 98 | VARx(int *, pollidxs) /* maps fds into structure indices */ 99 | VARx(int, pollidxmax) 100 | #endif 101 | 102 | #if EV_USE_EPOLL || EV_GENWRAP 103 | VARx(struct epoll_event *, epoll_events) 104 | VARx(int, epoll_eventmax) 105 | VARx(int *, epoll_eperms) 106 | VARx(int, epoll_epermcnt) 107 | VARx(int, epoll_epermmax) 108 | #endif 109 | 110 | #if EV_USE_LINUXAIO || EV_GENWRAP 111 | VARx(aio_context_t, linuxaio_ctx) 112 | VARx(int, linuxaio_iteration) 113 | VARx(struct aniocb **, linuxaio_iocbps) 114 | VARx(int, linuxaio_iocbpmax) 115 | VARx(struct iocb **, linuxaio_submits) 116 | VARx(int, linuxaio_submitcnt) 117 | VARx(int, linuxaio_submitmax) 118 | VARx(ev_io, linuxaio_epoll_w) 119 | #endif 120 | 121 | #if EV_USE_IOURING || EV_GENWRAP 122 | VARx(int, iouring_fd) 123 | VARx(unsigned, iouring_to_submit); 124 | VARx(int, iouring_entries) 125 | VARx(int, iouring_max_entries) 126 | VARx(void *, iouring_sq_ring) 127 | VARx(void *, iouring_cq_ring) 128 | VARx(void *, iouring_sqes) 129 | VARx(uint32_t, iouring_sq_ring_size) 130 | VARx(uint32_t, iouring_cq_ring_size) 131 | VARx(uint32_t, iouring_sqes_size) 132 | VARx(uint32_t, iouring_sq_head) 133 | VARx(uint32_t, iouring_sq_tail) 134 | VARx(uint32_t, iouring_sq_ring_mask) 135 | VARx(uint32_t, iouring_sq_ring_entries) 136 | VARx(uint32_t, iouring_sq_flags) 137 | VARx(uint32_t, iouring_sq_dropped) 138 | VARx(uint32_t, iouring_sq_array) 139 | VARx(uint32_t, iouring_cq_head) 140 | VARx(uint32_t, iouring_cq_tail) 141 | VARx(uint32_t, iouring_cq_ring_mask) 142 | VARx(uint32_t, iouring_cq_ring_entries) 143 | VARx(uint32_t, iouring_cq_overflow) 144 | VARx(uint32_t, iouring_cq_cqes) 145 | VARx(ev_tstamp, iouring_tfd_to) 146 | VARx(int, iouring_tfd) 147 | VARx(ev_io, iouring_tfd_w) 148 | #endif 149 | 150 | #if EV_USE_KQUEUE || EV_GENWRAP 151 | VARx(pid_t, kqueue_fd_pid) 152 | VARx(struct kevent *, kqueue_changes) 153 | VARx(int, kqueue_changemax) 154 | VARx(int, kqueue_changecnt) 155 | VARx(struct kevent *, kqueue_events) 156 | VARx(int, kqueue_eventmax) 157 | #endif 158 | 159 | #if EV_USE_PORT || EV_GENWRAP 160 | VARx(struct port_event *, port_events) 161 | VARx(int, port_eventmax) 162 | #endif 163 | 164 | #if EV_USE_IOCP || EV_GENWRAP 165 | VARx(HANDLE, iocp) 166 | #endif 167 | 168 | VARx(int *, fdchanges) 169 | VARx(int, fdchangemax) 170 | VARx(int, fdchangecnt) 171 | 172 | VARx(ANHE *, timers) 173 | VARx(int, timermax) 174 | VARx(int, timercnt) 175 | 176 | #if EV_PERIODIC_ENABLE || EV_GENWRAP 177 | VARx(ANHE *, periodics) 178 | VARx(int, periodicmax) 179 | VARx(int, periodiccnt) 180 | #endif 181 | 182 | #if EV_IDLE_ENABLE || EV_GENWRAP 183 | VAR (idles, ev_idle **idles [NUMPRI]) 184 | VAR (idlemax, int idlemax [NUMPRI]) 185 | VAR (idlecnt, int idlecnt [NUMPRI]) 186 | #endif 187 | VARx(int, idleall) /* total number */ 188 | 189 | VARx(struct ev_prepare **, prepares) 190 | VARx(int, preparemax) 191 | VARx(int, preparecnt) 192 | 193 | VARx(struct ev_check **, checks) 194 | VARx(int, checkmax) 195 | VARx(int, checkcnt) 196 | 197 | #if EV_FORK_ENABLE || EV_GENWRAP 198 | VARx(struct ev_fork **, forks) 199 | VARx(int, forkmax) 200 | VARx(int, forkcnt) 201 | #endif 202 | 203 | #if EV_CLEANUP_ENABLE || EV_GENWRAP 204 | VARx(struct ev_cleanup **, cleanups) 205 | VARx(int, cleanupmax) 206 | VARx(int, cleanupcnt) 207 | #endif 208 | 209 | #if EV_ASYNC_ENABLE || EV_GENWRAP 210 | VARx(EV_ATOMIC_T, async_pending) 211 | VARx(struct ev_async **, asyncs) 212 | VARx(int, asyncmax) 213 | VARx(int, asynccnt) 214 | #endif 215 | 216 | #if EV_USE_INOTIFY || EV_GENWRAP 217 | VARx(int, fs_fd) 218 | VARx(ev_io, fs_w) 219 | VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */ 220 | VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE]) 221 | #endif 222 | 223 | VARx(EV_ATOMIC_T, sig_pending) 224 | #if EV_USE_SIGNALFD || EV_GENWRAP 225 | VARx(int, sigfd) 226 | VARx(ev_io, sigfd_w) 227 | VARx(sigset_t, sigfd_set) 228 | #endif 229 | 230 | #if EV_USE_TIMERFD || EV_GENWRAP 231 | VARx(int, timerfd) /* timerfd for time jump detection */ 232 | VARx(ev_io, timerfd_w) 233 | #endif 234 | 235 | VARx(unsigned int, origflags) /* original loop flags */ 236 | 237 | #if EV_FEATURE_API || EV_GENWRAP 238 | VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */ 239 | VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */ 240 | 241 | VARx(void *, userdata) 242 | /* C++ doesn't support the ev_loop_callback typedef here. stinks. */ 243 | VAR (release_cb, void (*release_cb)(EV_P) EV_NOEXCEPT) 244 | VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_NOEXCEPT) 245 | VAR (invoke_cb , ev_loop_callback invoke_cb) 246 | #endif 247 | 248 | #undef VARx 249 | 250 | -------------------------------------------------------------------------------- /libev/ev_wrap.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT, automatically generated by update_ev_wrap */ 2 | #ifndef EV_WRAP_H 3 | #define EV_WRAP_H 4 | #define acquire_cb ((loop)->acquire_cb) 5 | #define activecnt ((loop)->activecnt) 6 | #define anfdmax ((loop)->anfdmax) 7 | #define anfds ((loop)->anfds) 8 | #define async_pending ((loop)->async_pending) 9 | #define asynccnt ((loop)->asynccnt) 10 | #define asyncmax ((loop)->asyncmax) 11 | #define asyncs ((loop)->asyncs) 12 | #define backend ((loop)->backend) 13 | #define backend_fd ((loop)->backend_fd) 14 | #define backend_mintime ((loop)->backend_mintime) 15 | #define backend_modify ((loop)->backend_modify) 16 | #define backend_poll ((loop)->backend_poll) 17 | #define checkcnt ((loop)->checkcnt) 18 | #define checkmax ((loop)->checkmax) 19 | #define checks ((loop)->checks) 20 | #define cleanupcnt ((loop)->cleanupcnt) 21 | #define cleanupmax ((loop)->cleanupmax) 22 | #define cleanups ((loop)->cleanups) 23 | #define curpid ((loop)->curpid) 24 | #define epoll_epermcnt ((loop)->epoll_epermcnt) 25 | #define epoll_epermmax ((loop)->epoll_epermmax) 26 | #define epoll_eperms ((loop)->epoll_eperms) 27 | #define epoll_eventmax ((loop)->epoll_eventmax) 28 | #define epoll_events ((loop)->epoll_events) 29 | #define evpipe ((loop)->evpipe) 30 | #define fdchangecnt ((loop)->fdchangecnt) 31 | #define fdchangemax ((loop)->fdchangemax) 32 | #define fdchanges ((loop)->fdchanges) 33 | #define forkcnt ((loop)->forkcnt) 34 | #define forkmax ((loop)->forkmax) 35 | #define forks ((loop)->forks) 36 | #define fs_2625 ((loop)->fs_2625) 37 | #define fs_fd ((loop)->fs_fd) 38 | #define fs_hash ((loop)->fs_hash) 39 | #define fs_w ((loop)->fs_w) 40 | #define idleall ((loop)->idleall) 41 | #define idlecnt ((loop)->idlecnt) 42 | #define idlemax ((loop)->idlemax) 43 | #define idles ((loop)->idles) 44 | #define invoke_cb ((loop)->invoke_cb) 45 | #define io_blocktime ((loop)->io_blocktime) 46 | #define iocp ((loop)->iocp) 47 | #define iouring_cq_cqes ((loop)->iouring_cq_cqes) 48 | #define iouring_cq_head ((loop)->iouring_cq_head) 49 | #define iouring_cq_overflow ((loop)->iouring_cq_overflow) 50 | #define iouring_cq_ring ((loop)->iouring_cq_ring) 51 | #define iouring_cq_ring_entries ((loop)->iouring_cq_ring_entries) 52 | #define iouring_cq_ring_mask ((loop)->iouring_cq_ring_mask) 53 | #define iouring_cq_ring_size ((loop)->iouring_cq_ring_size) 54 | #define iouring_cq_tail ((loop)->iouring_cq_tail) 55 | #define iouring_entries ((loop)->iouring_entries) 56 | #define iouring_fd ((loop)->iouring_fd) 57 | #define iouring_max_entries ((loop)->iouring_max_entries) 58 | #define iouring_sq_array ((loop)->iouring_sq_array) 59 | #define iouring_sq_dropped ((loop)->iouring_sq_dropped) 60 | #define iouring_sq_flags ((loop)->iouring_sq_flags) 61 | #define iouring_sq_head ((loop)->iouring_sq_head) 62 | #define iouring_sq_ring ((loop)->iouring_sq_ring) 63 | #define iouring_sq_ring_entries ((loop)->iouring_sq_ring_entries) 64 | #define iouring_sq_ring_mask ((loop)->iouring_sq_ring_mask) 65 | #define iouring_sq_ring_size ((loop)->iouring_sq_ring_size) 66 | #define iouring_sq_tail ((loop)->iouring_sq_tail) 67 | #define iouring_sqes ((loop)->iouring_sqes) 68 | #define iouring_sqes_size ((loop)->iouring_sqes_size) 69 | #define iouring_tfd ((loop)->iouring_tfd) 70 | #define iouring_tfd_to ((loop)->iouring_tfd_to) 71 | #define iouring_tfd_w ((loop)->iouring_tfd_w) 72 | #define iouring_to_submit ((loop)->iouring_to_submit) 73 | #define kqueue_changecnt ((loop)->kqueue_changecnt) 74 | #define kqueue_changemax ((loop)->kqueue_changemax) 75 | #define kqueue_changes ((loop)->kqueue_changes) 76 | #define kqueue_eventmax ((loop)->kqueue_eventmax) 77 | #define kqueue_events ((loop)->kqueue_events) 78 | #define kqueue_fd_pid ((loop)->kqueue_fd_pid) 79 | #define linuxaio_ctx ((loop)->linuxaio_ctx) 80 | #define linuxaio_epoll_w ((loop)->linuxaio_epoll_w) 81 | #define linuxaio_iocbpmax ((loop)->linuxaio_iocbpmax) 82 | #define linuxaio_iocbps ((loop)->linuxaio_iocbps) 83 | #define linuxaio_iteration ((loop)->linuxaio_iteration) 84 | #define linuxaio_submitcnt ((loop)->linuxaio_submitcnt) 85 | #define linuxaio_submitmax ((loop)->linuxaio_submitmax) 86 | #define linuxaio_submits ((loop)->linuxaio_submits) 87 | #define loop_count ((loop)->loop_count) 88 | #define loop_depth ((loop)->loop_depth) 89 | #define loop_done ((loop)->loop_done) 90 | #define mn_now ((loop)->mn_now) 91 | #define now_floor ((loop)->now_floor) 92 | #define origflags ((loop)->origflags) 93 | #define pending_w ((loop)->pending_w) 94 | #define pendingcnt ((loop)->pendingcnt) 95 | #define pendingmax ((loop)->pendingmax) 96 | #define pendingpri ((loop)->pendingpri) 97 | #define pendings ((loop)->pendings) 98 | #define periodiccnt ((loop)->periodiccnt) 99 | #define periodicmax ((loop)->periodicmax) 100 | #define periodics ((loop)->periodics) 101 | #define pipe_w ((loop)->pipe_w) 102 | #define pipe_write_skipped ((loop)->pipe_write_skipped) 103 | #define pipe_write_wanted ((loop)->pipe_write_wanted) 104 | #define pollcnt ((loop)->pollcnt) 105 | #define pollidxmax ((loop)->pollidxmax) 106 | #define pollidxs ((loop)->pollidxs) 107 | #define pollmax ((loop)->pollmax) 108 | #define polls ((loop)->polls) 109 | #define port_eventmax ((loop)->port_eventmax) 110 | #define port_events ((loop)->port_events) 111 | #define postfork ((loop)->postfork) 112 | #define preparecnt ((loop)->preparecnt) 113 | #define preparemax ((loop)->preparemax) 114 | #define prepares ((loop)->prepares) 115 | #define release_cb ((loop)->release_cb) 116 | #define rfeedcnt ((loop)->rfeedcnt) 117 | #define rfeedmax ((loop)->rfeedmax) 118 | #define rfeeds ((loop)->rfeeds) 119 | #define rtmn_diff ((loop)->rtmn_diff) 120 | #define sig_pending ((loop)->sig_pending) 121 | #define sigfd ((loop)->sigfd) 122 | #define sigfd_set ((loop)->sigfd_set) 123 | #define sigfd_w ((loop)->sigfd_w) 124 | #define timeout_blocktime ((loop)->timeout_blocktime) 125 | #define timercnt ((loop)->timercnt) 126 | #define timerfd ((loop)->timerfd) 127 | #define timerfd_w ((loop)->timerfd_w) 128 | #define timermax ((loop)->timermax) 129 | #define timers ((loop)->timers) 130 | #define userdata ((loop)->userdata) 131 | #define vec_eo ((loop)->vec_eo) 132 | #define vec_max ((loop)->vec_max) 133 | #define vec_ri ((loop)->vec_ri) 134 | #define vec_ro ((loop)->vec_ro) 135 | #define vec_wi ((loop)->vec_wi) 136 | #define vec_wo ((loop)->vec_wo) 137 | #else 138 | #undef EV_WRAP_H 139 | #undef acquire_cb 140 | #undef activecnt 141 | #undef anfdmax 142 | #undef anfds 143 | #undef async_pending 144 | #undef asynccnt 145 | #undef asyncmax 146 | #undef asyncs 147 | #undef backend 148 | #undef backend_fd 149 | #undef backend_mintime 150 | #undef backend_modify 151 | #undef backend_poll 152 | #undef checkcnt 153 | #undef checkmax 154 | #undef checks 155 | #undef cleanupcnt 156 | #undef cleanupmax 157 | #undef cleanups 158 | #undef curpid 159 | #undef epoll_epermcnt 160 | #undef epoll_epermmax 161 | #undef epoll_eperms 162 | #undef epoll_eventmax 163 | #undef epoll_events 164 | #undef evpipe 165 | #undef fdchangecnt 166 | #undef fdchangemax 167 | #undef fdchanges 168 | #undef forkcnt 169 | #undef forkmax 170 | #undef forks 171 | #undef fs_2625 172 | #undef fs_fd 173 | #undef fs_hash 174 | #undef fs_w 175 | #undef idleall 176 | #undef idlecnt 177 | #undef idlemax 178 | #undef idles 179 | #undef invoke_cb 180 | #undef io_blocktime 181 | #undef iocp 182 | #undef iouring_cq_cqes 183 | #undef iouring_cq_head 184 | #undef iouring_cq_overflow 185 | #undef iouring_cq_ring 186 | #undef iouring_cq_ring_entries 187 | #undef iouring_cq_ring_mask 188 | #undef iouring_cq_ring_size 189 | #undef iouring_cq_tail 190 | #undef iouring_entries 191 | #undef iouring_fd 192 | #undef iouring_max_entries 193 | #undef iouring_sq_array 194 | #undef iouring_sq_dropped 195 | #undef iouring_sq_flags 196 | #undef iouring_sq_head 197 | #undef iouring_sq_ring 198 | #undef iouring_sq_ring_entries 199 | #undef iouring_sq_ring_mask 200 | #undef iouring_sq_ring_size 201 | #undef iouring_sq_tail 202 | #undef iouring_sqes 203 | #undef iouring_sqes_size 204 | #undef iouring_tfd 205 | #undef iouring_tfd_to 206 | #undef iouring_tfd_w 207 | #undef iouring_to_submit 208 | #undef kqueue_changecnt 209 | #undef kqueue_changemax 210 | #undef kqueue_changes 211 | #undef kqueue_eventmax 212 | #undef kqueue_events 213 | #undef kqueue_fd_pid 214 | #undef linuxaio_ctx 215 | #undef linuxaio_epoll_w 216 | #undef linuxaio_iocbpmax 217 | #undef linuxaio_iocbps 218 | #undef linuxaio_iteration 219 | #undef linuxaio_submitcnt 220 | #undef linuxaio_submitmax 221 | #undef linuxaio_submits 222 | #undef loop_count 223 | #undef loop_depth 224 | #undef loop_done 225 | #undef mn_now 226 | #undef now_floor 227 | #undef origflags 228 | #undef pending_w 229 | #undef pendingcnt 230 | #undef pendingmax 231 | #undef pendingpri 232 | #undef pendings 233 | #undef periodiccnt 234 | #undef periodicmax 235 | #undef periodics 236 | #undef pipe_w 237 | #undef pipe_write_skipped 238 | #undef pipe_write_wanted 239 | #undef pollcnt 240 | #undef pollidxmax 241 | #undef pollidxs 242 | #undef pollmax 243 | #undef polls 244 | #undef port_eventmax 245 | #undef port_events 246 | #undef postfork 247 | #undef preparecnt 248 | #undef preparemax 249 | #undef prepares 250 | #undef release_cb 251 | #undef rfeedcnt 252 | #undef rfeedmax 253 | #undef rfeeds 254 | #undef rtmn_diff 255 | #undef sig_pending 256 | #undef sigfd 257 | #undef sigfd_set 258 | #undef sigfd_w 259 | #undef timeout_blocktime 260 | #undef timercnt 261 | #undef timerfd 262 | #undef timerfd_w 263 | #undef timermax 264 | #undef timers 265 | #undef userdata 266 | #undef vec_eo 267 | #undef vec_max 268 | #undef vec_ri 269 | #undef vec_ro 270 | #undef vec_wi 271 | #undef vec_wo 272 | #endif 273 | --------------------------------------------------------------------------------