├── .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 |
--------------------------------------------------------------------------------