From 249b3c0ac62b83dcb5bb17c998eae7fd675ebfe8 Mon Sep 17 00:00:00 2001 From: zcy <290198252@qq.com> Date: Sat, 9 Oct 2021 00:14:49 +0800 Subject: [PATCH] no message --- examples/proto_debuger/new_monitor_form.cpp | 13 +- examples/proto_debuger/proto_debuger.vcxproj | 10 +- examples/proto_debuger/tcp_client.cpp | 176 ++ examples/proto_debuger/tcp_client.h | 72 + examples/proto_debuger/tcpclient_process.cpp | 14 + examples/proto_debuger/tcpclient_process.h | 15 + .../third/include/libevent/include/evdns.h | 45 + .../third/include/libevent/include/event.h | 83 + .../include/libevent/include/event2/buffer.h | 1098 +++++++++++ .../libevent/include/event2/buffer_compat.h | 116 ++ .../libevent/include/event2/bufferevent.h | 1061 +++++++++++ .../include/event2/bufferevent_compat.h | 112 ++ .../libevent/include/event2/bufferevent_ssl.h | 262 +++ .../include/event2/bufferevent_struct.h | 116 ++ .../include/libevent/include/event2/dns.h | 807 ++++++++ .../libevent/include/event2/dns_compat.h | 358 ++++ .../libevent/include/event2/dns_struct.h | 80 + .../libevent/include/event2/event-config.h | 360 ++++ .../include/libevent/include/event2/event.h | 1685 +++++++++++++++++ .../libevent/include/event2/event_compat.h | 230 +++ .../libevent/include/event2/event_struct.h | 182 ++ .../include/libevent/include/event2/http.h | 1429 ++++++++++++++ .../libevent/include/event2/http_compat.h | 94 + .../libevent/include/event2/http_struct.h | 152 ++ .../libevent/include/event2/keyvalq_struct.h | 80 + .../libevent/include/event2/listener.h | 193 ++ .../include/libevent/include/event2/rpc.h | 626 ++++++ .../libevent/include/event2/rpc_compat.h | 61 + .../libevent/include/event2/rpc_struct.h | 114 ++ .../include/libevent/include/event2/tag.h | 146 ++ .../libevent/include/event2/tag_compat.h | 49 + .../include/libevent/include/event2/thread.h | 268 +++ .../include/libevent/include/event2/util.h | 888 +++++++++ .../libevent/include/event2/visibility.h | 68 + .../include/libevent/include/event2/watch.h | 136 ++ .../third/include/libevent/include/evhttp.h | 45 + .../third/include/libevent/include/evrpc.h | 45 + .../third/include/libevent/include/evutil.h | 39 + examples/proto_debuger/third/lib/event.exp | Bin 0 -> 85617 bytes examples/proto_debuger/third/lib/event.lib | Bin 0 -> 140020 bytes .../proto_debuger/third/lib/event_core.exp | Bin 0 -> 52006 bytes .../proto_debuger/third/lib/event_core.lib | Bin 0 -> 86914 bytes .../proto_debuger/third/lib/event_extra.exp | Bin 0 -> 34387 bytes .../proto_debuger/third/lib/event_extra.lib | Bin 0 -> 57892 bytes .../proto_debuger/third/lib/event_openssl.exp | Bin 0 -> 2463 bytes .../proto_debuger/third/lib/event_openssl.lib | Bin 0 -> 4534 bytes examples/proto_debuger/uart_process.cpp | 1 - 47 files changed, 11323 insertions(+), 6 deletions(-) create mode 100644 examples/proto_debuger/tcp_client.cpp create mode 100644 examples/proto_debuger/tcp_client.h create mode 100644 examples/proto_debuger/third/include/libevent/include/evdns.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/buffer.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/buffer_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/bufferevent.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/bufferevent_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/bufferevent_ssl.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/bufferevent_struct.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/dns.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/dns_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/dns_struct.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/event-config.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/event.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/event_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/event_struct.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/http.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/http_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/http_struct.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/keyvalq_struct.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/listener.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/rpc.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/rpc_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/rpc_struct.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/tag.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/tag_compat.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/thread.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/util.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/visibility.h create mode 100644 examples/proto_debuger/third/include/libevent/include/event2/watch.h create mode 100644 examples/proto_debuger/third/include/libevent/include/evhttp.h create mode 100644 examples/proto_debuger/third/include/libevent/include/evrpc.h create mode 100644 examples/proto_debuger/third/include/libevent/include/evutil.h create mode 100644 examples/proto_debuger/third/lib/event.exp create mode 100644 examples/proto_debuger/third/lib/event.lib create mode 100644 examples/proto_debuger/third/lib/event_core.exp create mode 100644 examples/proto_debuger/third/lib/event_core.lib create mode 100644 examples/proto_debuger/third/lib/event_extra.exp create mode 100644 examples/proto_debuger/third/lib/event_extra.lib create mode 100644 examples/proto_debuger/third/lib/event_openssl.exp create mode 100644 examples/proto_debuger/third/lib/event_openssl.lib diff --git a/examples/proto_debuger/new_monitor_form.cpp b/examples/proto_debuger/new_monitor_form.cpp index 01ce3cfb..5d263e0c 100644 --- a/examples/proto_debuger/new_monitor_form.cpp +++ b/examples/proto_debuger/new_monitor_form.cpp @@ -13,7 +13,6 @@ using namespace std; const std::wstring NewMonitorForm::kClassName = L"Basic"; - vector EnumPortsWdm() { std::vector ret; @@ -128,10 +127,18 @@ void NewMonitorForm::InitWindow() } } - if (m_combo_type->GetText() == L"tcp_client") { + if (m_combo_type->GetText() == L"tcp client") { } - + if (m_combo_type->GetText() == L"tcp server") { + + } + if (m_combo_type->GetText() == L"udp client") { + + } + if (m_combo_type->GetText() == L"udp server") { + + } return true; }); } diff --git a/examples/proto_debuger/proto_debuger.vcxproj b/examples/proto_debuger/proto_debuger.vcxproj index cbd79baf..05d967fe 100644 --- a/examples/proto_debuger/proto_debuger.vcxproj +++ b/examples/proto_debuger/proto_debuger.vcxproj @@ -81,6 +81,9 @@ true + $(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\;$(ProjectDir)third\include\libevent\include + $(ReferencePath) + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(ProjectDir)third\lib false @@ -121,12 +124,14 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _WINSOCK_DEPRECATED_NO_WARNINGS ;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreadedDebug - Console + Windows true + ws2_32.lib;event_extra.lib;event_core.lib;event.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) @@ -161,6 +166,7 @@ + diff --git a/examples/proto_debuger/tcp_client.cpp b/examples/proto_debuger/tcp_client.cpp new file mode 100644 index 00000000..2dbe2bb5 --- /dev/null +++ b/examples/proto_debuger/tcp_client.cpp @@ -0,0 +1,176 @@ +// +// Created by 29019 on 2020/4/18. +// +#define _WSPIAPI_H_ +#define _WINSOCKAPI_ +#include "tcp_client.h" +#include +#include +#include + +static void conn_writecb(struct bufferevent *, void *); +static void conn_readcb(struct bufferevent *, void *); +static void conn_eventcb(struct bufferevent *, short, void *); + +void delay(int ms); +int ThreadRun(TcpClientLibevent *p); + + + +void conn_writecb(struct bufferevent *bev, void *user_data) +{ + +} + +// 运行线程 +int ThreadRun(TcpClientLibevent *p) { + if (nullptr != p) { + p->mStatus = TcpClientLibevent::UNCONNECTED; + int ret = p->Dispatch(); + if (0 > ret){ + } + while ((p->mStatus != TcpClientLibevent::UNCONNECTED )) + { + if (p->mStatus == TcpClientLibevent::FAIL) { //连接失败,如果有设置自动重连就一直重连 + p->ConnectServer(); +#ifdef _WIN32 + Sleep(100); +#else + //todo linux版本sleep +#endif + } + ret = p->Dispatch(); + } + } + p->mStatus = TcpClientLibevent::UNCONNECTED; + return 0; +} + +void conn_readcb(struct bufferevent *bev, void *user_data) +{ + TcpClientLibevent *server = (TcpClientLibevent*)user_data; + struct evbuffer *input = bufferevent_get_input(bev); + size_t sz = evbuffer_get_length(input); + if (sz > 0) + { + uint8_t *msg = new uint8_t[sz]; + int ret = bufferevent_read(bev, msg, sz); + printf("%s\n", msg); + if(server->mObserver != nullptr){ + } + server->mObserver->OnData(msg,ret); + delete[] msg; + } +} + +void conn_eventcb(struct bufferevent *bev, short events, void *user_data) +{ + TcpClientLibevent *p; + p = (TcpClientLibevent *)user_data; + if (events & BEV_EVENT_EOF) { + if (nullptr != p->mObserver) + p->mObserver->OnDisConnected(); + if (p != nullptr) + p->mStatus = TcpClientLibevent::UNCONNECTED; + printf("Connection closed\n"); + } + else if (events & BEV_EVENT_ERROR) { + printf("Got an error on the connection: %s\n", strerror(errno)); + if (nullptr != p->mObserver) + p->mObserver->OnDisConnected(); + p->mStatus = TcpClientLibevent::FAIL; + } + else if (events & BEV_EVENT_CONNECTED) { + printf("Connect succeed\n"); + //客户端链接成功后,给服务器发送第一条消息 + if (nullptr != p->mObserver) + p->mObserver->OnConnected(); + if (p != nullptr) + p->mStatus = TcpClientLibevent::UNCONNECTED; + return; + } + bufferevent_free(bev); +} + +void delay(int ms) +{ + clock_t start = clock(); + while (clock() - start < ms); +} + +bool TcpClientLibevent::Connected() { + return (((mStatus != UNCONNECTED)&& (mStatus != FAIL) )?true : false); +} + +TcpClientLibevent::TcpClientLibevent(std::string addrinfo, int port, TcpClientLibevent::TcpClientObserver *p) : + mStatus(UNCONNECTED), + mObserver(nullptr) +{ + memset(&mSrv, 0, sizeof(mSrv)); +#ifdef linux + mSrv.sin_addr.s_addr = inet_addr(addrinfo.c_str()); + mSrv.sin_family = AF_INET; +#endif +#ifdef _WIN32 + mSrv.sin_addr.S_un.S_addr = inet_addr(addrinfo.c_str()); + mSrv.sin_family = AF_INET; +#endif + mSrv.sin_port = htons(port); + + mBase = event_base_new(); + if (!mBase) + { + printf("Could not initialize libevent\n"); + } + +#ifdef WIN32 + evthread_use_windows_threads(); +#else + evthread_use_pthreads(); +#endif + ConnectServer(); + this->mThread = new thread(ThreadRun,this); + this->mObserver = p; +} + +int TcpClientLibevent::ConnectServer() { + printf("connect server\r\n"); + evthread_make_base_notifiable(mBase); + bev = bufferevent_socket_new(mBase, -1, + BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE); + if (nullptr == bev) { + this->mStatus = TcpClientLibevent::FAIL; + return - 1; + } + bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, this); + int flag = bufferevent_socket_connect(bev, (struct sockaddr *)&mSrv, sizeof(mSrv)); + bufferevent_enable(bev, EV_READ | EV_WRITE); + if (-1 == flag) { + this->mStatus = TcpClientLibevent::FAIL; + bufferevent_free(bev); + bev = nullptr; + printf("Connect failed\n"); + return -1; + } + this->mStatus = TcpClientLibevent::CONNECTED; + return 0; +} + +int TcpClientLibevent::SetReconnect(bool reconn) { + this->mReConnect = reconn; + return 0; +} + +int TcpClientLibevent::SetObserver(TcpClientLibevent::TcpClientObserver *ob) { + this->mObserver = ob; + return 0; +} + +int TcpClientLibevent::Dispatch() { + return event_base_dispatch(mBase);; +} + +int TcpClientLibevent::Close() { + event_base_free(mBase); + return 0; +} diff --git a/examples/proto_debuger/tcp_client.h b/examples/proto_debuger/tcp_client.h new file mode 100644 index 00000000..e5397e6d --- /dev/null +++ b/examples/proto_debuger/tcp_client.h @@ -0,0 +1,72 @@ +// +// Created by 29019 on 2020/4/18. +// + +#ifndef GENERAL_TCPCLIENT_H +#define GENERAL_TCPCLIENT_H + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 +#endif +#ifdef linux +#include +#include +#include +#define EVENT__HAVE_PTHREADS +#endif + +extern "C"{ + #include "event2/bufferevent.h" + #include "event2/buffer.h" + #include "event2/listener.h" + #include "event2/util.h" + #include "event2/event.h" + #include "event2/thread.h" +}; +#include +#include +// #include "PackageReceiver.h" +#include +#include +using namespace std; + +class TcpClientLibevent { +public: + typedef enum { + UNCONNECTED, // 未连接 + CONNECTED, //已经连接 + FAIL, // 连接失败 + }Status; + class TcpClientObserver{ + public: + virtual ~TcpClientObserver(){return;} + mutex mMux; + virtual void OnConnected() { return; }; + virtual void OnDisConnected() { return; }; + virtual void OnData(uint8_t *dat,uint64_t len){return;}; + virtual void OnClose(){return;}; + }; + TcpClientLibevent(std::string addrinfo,int port, TcpClientObserver *p); + ~TcpClientLibevent(){ + event_base_free(mBase); + }; + int ConnectServer(); + bool Connected(); + int Dispatch(); + int OnTCPPackage(uint8_t *, uint16_t); + int SetReconnect(bool); + int SetObserver(TcpClientObserver*); + int Close(); + Status mStatus; + TcpClientObserver *mObserver; +private: + bool mReConnect = false; + int sendData(void*,size_t); + struct event_base *mBase; + struct bufferevent* bev; + struct sockaddr_in mSrv; + std::thread *mThread; + mutex mLock; +}; + +#endif //GENERAL_TCPCLIENT_H diff --git a/examples/proto_debuger/tcpclient_process.cpp b/examples/proto_debuger/tcpclient_process.cpp index e69de29b..91ce764a 100644 --- a/examples/proto_debuger/tcpclient_process.cpp +++ b/examples/proto_debuger/tcpclient_process.cpp @@ -0,0 +1,14 @@ +#include "tcpclient_process.h" + +void TcpclientForm::Init() +{ + ui::Label* m_label_1 = dynamic_cast(FindSubControl(L"uart_info_label")); + ui::RichEdit* m_rich_edit_1 = dynamic_cast(FindSubControl(L"uart_recv_eidt")); + ui::RichEdit* m_rich_edit_2 = dynamic_cast(FindSubControl(L"lua_script")); + ui::RichEdit* m_rich_edit_3 = dynamic_cast(FindSubControl(L"uart_send_edit")); + ui::Button* m_button_1 = dynamic_cast(FindSubControl(L"btn_send_data")); + ui::CheckBox* m_check_box_1 = dynamic_cast(FindSubControl(L"check_new_line")); + ui::CheckBox* m_check_box_2 = dynamic_cast(FindSubControl(L"check_time_send")); + ui::CheckBox* m_check_box_3 = dynamic_cast(FindSubControl(L"check_hex_send")); + ui::CheckBox* m_check_box_4 = dynamic_cast(FindSubControl(L"check_hex_recv")); +} diff --git a/examples/proto_debuger/tcpclient_process.h b/examples/proto_debuger/tcpclient_process.h index b8961eb6..55c22fb6 100644 --- a/examples/proto_debuger/tcpclient_process.h +++ b/examples/proto_debuger/tcpclient_process.h @@ -20,5 +20,20 @@ class TcpclientForm : public ui::ChildBox { public: + + virtual void Init() override; + + +private: + ui::Label* m_label_1; + ui::RichEdit* m_rich_edit_1; + ui::RichEdit* m_rich_edit_2; + ui::RichEdit* m_rich_edit_3; + ui::Button* m_button_1; + ui::CheckBox* m_check_box_1; + ui::CheckBox* m_check_box_2; + ui::CheckBox* m_check_box_3; + ui::CheckBox* m_check_box_4; + }; diff --git a/examples/proto_debuger/third/include/libevent/include/evdns.h b/examples/proto_debuger/third/include/libevent/include/evdns.h new file mode 100644 index 00000000..8672db03 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/evdns.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT1_EVDNS_H_INCLUDED_ +#define EVENT1_EVDNS_H_INCLUDED_ + +/** @file evdns.h + + A dns subsystem for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other + headers. + */ + +#include +#include +#include +#include + +#endif /* EVENT1_EVDNS_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event.h b/examples/proto_debuger/third/include/libevent/include/event.h new file mode 100644 index 00000000..ba518671 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT1_EVENT_H_INCLUDED_ +#define EVENT1_EVENT_H_INCLUDED_ + +/** @file event.h + + A library for writing event-driven network servers. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other event2/ + headers. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif +#ifdef EVENT__HAVE_STDINT_H +#include +#endif +#include + +/* For int types. */ +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#undef WIN32_LEAN_AND_MEAN +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT1_EVENT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/buffer.h b/examples/proto_debuger/third/include/libevent/include/event2/buffer.h new file mode 100644 index 00000000..5a76cf20 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/buffer.h @@ -0,0 +1,1098 @@ +/* + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_BUFFER_H_INCLUDED_ +#define EVENT2_BUFFER_H_INCLUDED_ + +/** @file event2/buffer.h + + @brief Functions for buffering data for network sending or receiving. + + An evbuffer can be used for preparing data before sending it to + the network or conversely for reading data from the network. + Evbuffers try to avoid memory copies as much as possible. As a + result, evbuffers can be used to pass data around without actually + incurring the overhead of copying the data. + + A new evbuffer can be allocated with evbuffer_new(), and can be + freed with evbuffer_free(). Most users will be using evbuffers via + the bufferevent interface. To access a bufferevent's evbuffers, use + bufferevent_get_input() and bufferevent_get_output(). + + There are several guidelines for using evbuffers. + + - if you already know how much data you are going to add as a result + of calling evbuffer_add() multiple times, it makes sense to use + evbuffer_expand() first to make sure that enough memory is allocated + before hand. + + - evbuffer_add_buffer() adds the contents of one buffer to the other + without incurring any unnecessary memory copies. + + - evbuffer_add() and evbuffer_add_buffer() do not mix very well: + if you use them, you will wind up with fragmented memory in your + buffer. + + - For high-performance code, you may want to avoid copying data into and out + of buffers. You can skip the copy step by using + evbuffer_reserve_space()/evbuffer_commit_space() when writing into a + buffer, and evbuffer_peek() when reading. + + In Libevent 2.0 and later, evbuffers are represented using a linked + list of memory chunks, with pointers to the first and last chunk in + the chain. + + As the contents of an evbuffer can be stored in multiple different + memory blocks, it cannot be accessed directly. Instead, evbuffer_pullup() + can be used to force a specified number of bytes to be contiguous. This + will cause memory reallocation and memory copies if the data is split + across multiple blocks. It is more efficient, however, to use + evbuffer_peek() if you don't require that the memory to be contiguous. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_UIO_H +#include +#endif +#include + +/** + An evbuffer is an opaque data type for efficiently buffering data to be + sent or received on the network. + + @see event2/event.h for more information +*/ +struct evbuffer +#ifdef EVENT_IN_DOXYGEN_ +{} +#endif +; + +/** + Pointer to a position within an evbuffer. + + Used when repeatedly searching through a buffer. Calling any function + that modifies or re-packs the buffer contents may invalidate all + evbuffer_ptrs for that buffer. Do not modify or contruct these values + except with evbuffer_ptr_set. + + An evbuffer_ptr can represent any position from the start of a buffer up + to a position immediately after the end of a buffer. + + @see evbuffer_ptr_set() + */ +struct evbuffer_ptr { + ev_ssize_t pos; + + /* Do not alter or rely on the values of fields: they are for internal + * use */ + struct { + void *chain; + size_t pos_in_chain; + } internal_; +}; + +/** Describes a single extent of memory inside an evbuffer. Used for + direct-access functions. + + @see evbuffer_reserve_space, evbuffer_commit_space, evbuffer_peek + */ +#ifdef EVENT__HAVE_SYS_UIO_H +#define evbuffer_iovec iovec +/* Internal use -- defined only if we are using the native struct iovec */ +#define EVBUFFER_IOVEC_IS_NATIVE_ +#else +struct evbuffer_iovec { + /** The start of the extent of memory. */ + void *iov_base; + /** The length of the extent of memory. */ + size_t iov_len; +}; +#endif + +/** + Allocate storage for a new evbuffer. + + @return a pointer to a newly allocated evbuffer struct, or NULL if an error + occurred + */ +EVENT2_EXPORT_SYMBOL +struct evbuffer *evbuffer_new(void); +/** + Deallocate storage for an evbuffer. + + @param buf pointer to the evbuffer to be freed + */ +EVENT2_EXPORT_SYMBOL +void evbuffer_free(struct evbuffer *buf); + + +/** + Set maximum read buffer size + + Default is 4096 and it works fine most of time, so before increasing the + default check carefully, since this has some negative effects (like memory + fragmentation and unfair resource distribution, i.e. some events will make + less progress than others). + + @param buf pointer to the evbuffer + @param max buffer size + @return 0 on success, -1 on failure (if max > INT_MAX). + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_set_max_read(struct evbuffer *buf, size_t max); +/** + Get maximum read buffer size + + @param buf pointer to the evbuffer + @return current maximum buffer read + */ +EVENT2_EXPORT_SYMBOL +size_t evbuffer_get_max_read(struct evbuffer *buf); + +/** + Enable locking on an evbuffer so that it can safely be used by multiple + threads at the same time. + + NOTE: when locking is enabled, the lock will be held when callbacks are + invoked. This could result in deadlock if you aren't careful. Plan + accordingly! + + @param buf An evbuffer to make lockable. + @param lock A lock object, or NULL if we should allocate our own. + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_enable_locking(struct evbuffer *buf, void *lock); + +/** + Acquire the lock on an evbuffer. Has no effect if locking was not enabled + with evbuffer_enable_locking. +*/ +EVENT2_EXPORT_SYMBOL +void evbuffer_lock(struct evbuffer *buf); + +/** + Release the lock on an evbuffer. Has no effect if locking was not enabled + with evbuffer_enable_locking. +*/ +EVENT2_EXPORT_SYMBOL +void evbuffer_unlock(struct evbuffer *buf); + + +/** If this flag is set, then we will not use evbuffer_peek(), + * evbuffer_remove(), evbuffer_remove_buffer(), and so on to read bytes + * from this buffer: we'll only take bytes out of this buffer by + * writing them to the network (as with evbuffer_write_atmost), by + * removing them without observing them (as with evbuffer_drain), + * or by copying them all out at once (as with evbuffer_add_buffer). + * + * Using this option allows the implementation to use sendfile-based + * operations for evbuffer_add_file(); see that function for more + * information. + * + * This flag is on by default for bufferevents that can take advantage + * of it; you should never actually need to set it on a bufferevent's + * output buffer. + */ +#define EVBUFFER_FLAG_DRAINS_TO_FD 1 + +/** Change the flags that are set for an evbuffer by adding more. + * + * @param buf the evbuffer that the callback is watching. + * @param flags One or more EVBUFFER_FLAG_* options + * @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_set_flags(struct evbuffer *buf, ev_uint64_t flags); +/** Change the flags that are set for an evbuffer by removing some. + * + * @param buf the evbuffer that the callback is watching. + * @param flags One or more EVBUFFER_FLAG_* options + * @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_clear_flags(struct evbuffer *buf, ev_uint64_t flags); + +/** + Returns the total number of bytes stored in the evbuffer + + @param buf pointer to the evbuffer + @return the number of bytes stored in the evbuffer +*/ +EVENT2_EXPORT_SYMBOL +size_t evbuffer_get_length(const struct evbuffer *buf); + +/** + Returns the number of contiguous available bytes in the first buffer chain. + + This is useful when processing data that might be split into multiple + chains, or that might all be in the first chain. Calls to + evbuffer_pullup() that cause reallocation and copying of data can thus be + avoided. + + @param buf pointer to the evbuffer + @return 0 if no data is available, otherwise the number of available bytes + in the first buffer chain. +*/ +EVENT2_EXPORT_SYMBOL +size_t evbuffer_get_contiguous_space(const struct evbuffer *buf); + +/** + Expands the available space in an evbuffer. + + Expands the available space in the evbuffer to at least datlen, so that + appending datlen additional bytes will not require any new allocations. + + @param buf the evbuffer to be expanded + @param datlen the new minimum length requirement + @return 0 if successful, or -1 if an error occurred +*/ +EVENT2_EXPORT_SYMBOL +int evbuffer_expand(struct evbuffer *buf, size_t datlen); + +/** + Reserves space in the last chain or chains of an evbuffer. + + Makes space available in the last chain or chains of an evbuffer that can + be arbitrarily written to by a user. The space does not become + available for reading until it has been committed with + evbuffer_commit_space(). + + The space is made available as one or more extents, represented by + an initial pointer and a length. You can force the memory to be + available as only one extent. Allowing more extents, however, makes the + function more efficient. + + Multiple subsequent calls to this function will make the same space + available until evbuffer_commit_space() has been called. + + It is an error to do anything that moves around the buffer's internal + memory structures before committing the space. + + NOTE: The code currently does not ever use more than two extents. + This may change in future versions. + + @param buf the evbuffer in which to reserve space. + @param size how much space to make available, at minimum. The + total length of the extents may be greater than the requested + length. + @param vec an array of one or more evbuffer_iovec structures to + hold pointers to the reserved extents of memory. + @param n_vec The length of the vec array. Must be at least 1; + 2 is more efficient. + @return the number of provided extents, or -1 on error. + @see evbuffer_commit_space() +*/ +EVENT2_EXPORT_SYMBOL +int +evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size, + struct evbuffer_iovec *vec, int n_vec); + +/** + Commits previously reserved space. + + Commits some of the space previously reserved with + evbuffer_reserve_space(). It then becomes available for reading. + + This function may return an error if the pointer in the extents do + not match those returned from evbuffer_reserve_space, or if data + has been added to the buffer since the space was reserved. + + If you want to commit less data than you got reserved space for, + modify the iov_len pointer of the appropriate extent to a smaller + value. Note that you may have received more space than you + requested if it was available! + + @param buf the evbuffer in which to reserve space. + @param vec one or two extents returned by evbuffer_reserve_space. + @param n_vecs the number of extents. + @return 0 on success, -1 on error + @see evbuffer_reserve_space() +*/ +EVENT2_EXPORT_SYMBOL +int evbuffer_commit_space(struct evbuffer *buf, + struct evbuffer_iovec *vec, int n_vecs); + +/** + Append data to the end of an evbuffer. + + @param buf the evbuffer to be appended to + @param data pointer to the beginning of the data buffer + @param datlen the number of bytes to be copied from the data buffer + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen); + + +/** + Read data from an evbuffer and drain the bytes read. + + If more bytes are requested than are available in the evbuffer, we + only extract as many bytes as were available. + + @param buf the evbuffer to be read from + @param data the destination buffer to store the result + @param datlen the maximum size of the destination buffer + @return the number of bytes read, or -1 if we can't drain the buffer. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen); + +/** + Read data from an evbuffer, and leave the buffer unchanged. + + If more bytes are requested than are available in the evbuffer, we + only extract as many bytes as were available. + + @param buf the evbuffer to be read from + @param data_out the destination buffer to store the result + @param datlen the maximum size of the destination buffer + @return the number of bytes read, or -1 if we can't drain the buffer. + */ +EVENT2_EXPORT_SYMBOL +ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen); + +/** + Read data from the middle of an evbuffer, and leave the buffer unchanged. + + If more bytes are requested than are available in the evbuffer, we + only extract as many bytes as were available. + + @param buf the evbuffer to be read from + @param pos the position to start reading from + @param data_out the destination buffer to store the result + @param datlen the maximum size of the destination buffer + @return the number of bytes read, or -1 if we can't drain the buffer. + */ +EVENT2_EXPORT_SYMBOL +ev_ssize_t evbuffer_copyout_from(struct evbuffer *buf, const struct evbuffer_ptr *pos, void *data_out, size_t datlen); + +/** + Read data from an evbuffer into another evbuffer, draining + the bytes from the source buffer. This function avoids copy + operations to the extent possible. + + If more bytes are requested than are available in src, the src + buffer is drained completely. + + @param src the evbuffer to be read from + @param dst the destination evbuffer to store the result into + @param datlen the maximum numbers of bytes to transfer + @return the number of bytes read + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, + size_t datlen); + +/** Used to tell evbuffer_readln what kind of line-ending to look for. + */ +enum evbuffer_eol_style { + /** Any sequence of CR and LF characters is acceptable as an + * EOL. + * + * Note that this style can produce ambiguous results: the + * sequence "CRLF" will be treated as a single EOL if it is + * all in the buffer at once, but if you first read a CR from + * the network and later read an LF from the network, it will + * be treated as two EOLs. + */ + EVBUFFER_EOL_ANY, + /** An EOL is an LF, optionally preceded by a CR. This style is + * most useful for implementing text-based internet protocols. */ + EVBUFFER_EOL_CRLF, + /** An EOL is a CR followed by an LF. */ + EVBUFFER_EOL_CRLF_STRICT, + /** An EOL is a LF. */ + EVBUFFER_EOL_LF, + /** An EOL is a NUL character (that is, a single byte with value 0) */ + EVBUFFER_EOL_NUL +}; + +/** + * Read a single line from an evbuffer. + * + * Reads a line terminated by an EOL as determined by the evbuffer_eol_style + * argument. Returns a newly allocated nul-terminated string; the caller must + * free the returned value. The EOL is not included in the returned string. + * + * @param buffer the evbuffer to read from + * @param n_read_out if non-NULL, points to a size_t that is set to the + * number of characters in the returned string. This is useful for + * strings that can contain NUL characters. + * @param eol_style the style of line-ending to use. + * @return pointer to a single line, or NULL if an error occurred + */ +EVENT2_EXPORT_SYMBOL +char *evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, + enum evbuffer_eol_style eol_style); + +/** + Move all data from one evbuffer into another evbuffer. + + This is a destructive add. The data from one buffer moves into + the other buffer. However, no unnecessary memory copies occur. + + @param outbuf the output buffer + @param inbuf the input buffer + @return 0 if successful, or -1 if an error occurred + + @see evbuffer_remove_buffer() + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf); + +/** + Copy data from one evbuffer into another evbuffer. + + This is a non-destructive add. The data from one buffer is copied + into the other buffer. However, no unnecessary memory copies occur. + + Note that buffers already containing buffer references can't be added + to other buffers. + + @param outbuf the output buffer + @param inbuf the input buffer + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add_buffer_reference(struct evbuffer *outbuf, + struct evbuffer *inbuf); + +/** + A cleanup function for a piece of memory added to an evbuffer by + reference. + + @see evbuffer_add_reference() + */ +typedef void (*evbuffer_ref_cleanup_cb)(const void *data, + size_t datalen, void *extra); + +/** + Reference memory into an evbuffer without copying. + + The memory needs to remain valid until all the added data has been + read. This function keeps just a reference to the memory without + actually incurring the overhead of a copy. + + @param outbuf the output buffer + @param data the memory to reference + @param datlen how memory to reference + @param cleanupfn callback to be invoked when the memory is no longer + referenced by this evbuffer. + @param cleanupfn_arg optional argument to the cleanup callback + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add_reference(struct evbuffer *outbuf, + const void *data, size_t datlen, + evbuffer_ref_cleanup_cb cleanupfn, void *cleanupfn_arg); + +/** + Copy data from a file into the evbuffer for writing to a socket. + + This function avoids unnecessary data copies between userland and + kernel. If sendfile is available and the EVBUFFER_FLAG_DRAINS_TO_FD + flag is set, it uses those functions. Otherwise, it tries to use + mmap (or CreateFileMapping on Windows). + + The function owns the resulting file descriptor and will close it + when finished transferring data. + + The results of using evbuffer_remove() or evbuffer_pullup() on + evbuffers whose data was added using this function are undefined. + + For more fine-grained control, use evbuffer_add_file_segment. + + @param outbuf the output buffer + @param fd the file descriptor + @param offset the offset from which to read data + @param length how much data to read, or -1 to read as much as possible. + (-1 requires that 'fd' support fstat.) + @return 0 if successful, or -1 if an error occurred +*/ + +EVENT2_EXPORT_SYMBOL +int evbuffer_add_file(struct evbuffer *outbuf, int fd, ev_off_t offset, + ev_off_t length); + +/** + An evbuffer_file_segment holds a reference to a range of a file -- + possibly the whole file! -- for use in writing from an evbuffer to a + socket. It could be implemented with mmap or sendfile, or (if all else + fails) by just pulling all the data into RAM. A single evbuffer_file_segment + can be added more than once, and to more than one evbuffer. + */ +struct evbuffer_file_segment; + +/** + Flag for creating evbuffer_file_segment: If this flag is set, then when + the evbuffer_file_segment is freed and no longer in use by any + evbuffer, the underlying fd is closed. + */ +#define EVBUF_FS_CLOSE_ON_FREE 0x01 +/** + Flag for creating evbuffer_file_segment: Disable memory-map based + implementations. + */ +#define EVBUF_FS_DISABLE_MMAP 0x02 +/** + Flag for creating evbuffer_file_segment: Disable direct fd-to-fd + implementations (sendfile). + + You might want to use this option if data needs to be taken from the + evbuffer by any means other than writing it to the network: the sendfile + backend is fast, but it only works for sending files directly to the + network. + */ +#define EVBUF_FS_DISABLE_SENDFILE 0x04 +/** + Flag for creating evbuffer_file_segment: Do not allocate a lock for this + segment. If this option is set, then neither the segment nor any + evbuffer it is added to may ever be accessed from more than one thread + at a time. + */ +#define EVBUF_FS_DISABLE_LOCKING 0x08 + +/** + A cleanup function for a evbuffer_file_segment added to an evbuffer + for reference. + */ +typedef void (*evbuffer_file_segment_cleanup_cb)( + struct evbuffer_file_segment const* seg, int flags, void* arg); + +/** + Create and return a new evbuffer_file_segment for reading data from a + file and sending it out via an evbuffer. + + This function avoids unnecessary data copies between userland and + kernel. Where available, it uses sendfile. + + The file descriptor must not be closed so long as any evbuffer is using + this segment. + + The results of using evbuffer_remove() or evbuffer_pullup() or any other + function that reads bytes from an evbuffer on any evbuffer containing + the newly returned segment are undefined, unless you pass the + EVBUF_FS_DISABLE_SENDFILE flag to this function. + + @param fd an open file to read from. + @param offset an index within the file at which to start reading + @param length how much data to read, or -1 to read as much as possible. + (-1 requires that 'fd' support fstat.) + @param flags any number of the EVBUF_FS_* flags + @return a new evbuffer_file_segment, or NULL on failure. + **/ +EVENT2_EXPORT_SYMBOL +struct evbuffer_file_segment *evbuffer_file_segment_new( + int fd, ev_off_t offset, ev_off_t length, unsigned flags); + +/** + Free an evbuffer_file_segment + + It is safe to call this function even if the segment has been added to + one or more evbuffers. The evbuffer_file_segment will not be freed + until no more references to it exist. + */ +EVENT2_EXPORT_SYMBOL +void evbuffer_file_segment_free(struct evbuffer_file_segment *seg); + +/** + Add cleanup callback and argument for the callback to an + evbuffer_file_segment. + + The cleanup callback will be invoked when no more references to the + evbuffer_file_segment exist. + **/ +EVENT2_EXPORT_SYMBOL +void evbuffer_file_segment_add_cleanup_cb(struct evbuffer_file_segment *seg, + evbuffer_file_segment_cleanup_cb cb, void* arg); + +/** + Insert some or all of an evbuffer_file_segment at the end of an evbuffer + + Note that the offset and length parameters of this function have a + different meaning from those provided to evbuffer_file_segment_new: When + you create the segment, the offset is the offset _within the file_, and + the length is the length _of the segment_, whereas when you add a + segment to an evbuffer, the offset is _within the segment_ and the + length is the length of the _part of the segment you want to use. + + In other words, if you have a 10 KiB file, and you create an + evbuffer_file_segment for it with offset 20 and length 1000, it will + refer to bytes 20..1019 inclusive. If you then pass this segment to + evbuffer_add_file_segment and specify an offset of 20 and a length of + 50, you will be adding bytes 40..99 inclusive. + + @param buf the evbuffer to append to + @param seg the segment to add + @param offset the offset within the segment to start from + @param length the amount of data to add, or -1 to add it all. + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add_file_segment(struct evbuffer *buf, + struct evbuffer_file_segment *seg, ev_off_t offset, ev_off_t length); + +/** + Append a formatted string to the end of an evbuffer. + + The string is formated as printf. + + @param buf the evbuffer that will be appended to + @param fmt a format string + @param ... arguments that will be passed to printf(3) + @return The number of bytes added if successful, or -1 if an error occurred. + + @see evutil_printf(), evbuffer_add_vprintf() + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) +#endif +; + +/** + Append a va_list formatted string to the end of an evbuffer. + + @param buf the evbuffer that will be appended to + @param fmt a format string + @param ap a varargs va_list argument array that will be passed to vprintf(3) + @return The number of bytes added if successful, or -1 if an error occurred. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) +#ifdef __GNUC__ + __attribute__((format(printf, 2, 0))) +#endif +; + + +/** + Remove a specified number of bytes data from the beginning of an evbuffer. + + @param buf the evbuffer to be drained + @param len the number of bytes to drain from the beginning of the buffer + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_drain(struct evbuffer *buf, size_t len); + + +/** + Write the contents of an evbuffer to a file descriptor. + + The evbuffer will be drained after the bytes have been successfully written. + + @param buffer the evbuffer to be written and drained + @param fd the file descriptor to be written to + @return the number of bytes written, or -1 if an error occurred + @see evbuffer_read() + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd); + +/** + Write some of the contents of an evbuffer to a file descriptor. + + The evbuffer will be drained after the bytes have been successfully written. + + @param buffer the evbuffer to be written and drained + @param fd the file descriptor to be written to + @param howmuch the largest allowable number of bytes to write, or -1 + to write as many bytes as we can. + @return the number of bytes written, or -1 if an error occurred + @see evbuffer_read() + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd, + ev_ssize_t howmuch); + +/** + Read from a file descriptor and store the result in an evbuffer. + + @param buffer the evbuffer to store the result + @param fd the file descriptor to read from + @param howmuch the number of bytes to be read. If the given number is negative + or out of maximum bytes per one read, as many bytes as we can will be read. + @return the number of bytes read, or -1 if an error occurred + @see evbuffer_write() + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_read(struct evbuffer *buffer, evutil_socket_t fd, int howmuch); + +/** + Search for a string within an evbuffer. + + @param buffer the evbuffer to be searched + @param what the string to be searched for + @param len the length of the search string + @param start NULL or a pointer to a valid struct evbuffer_ptr. + @return a struct evbuffer_ptr whose 'pos' field has the offset of the + first occurrence of the string in the buffer after 'start'. The 'pos' + field of the result is -1 if the string was not found. + */ +EVENT2_EXPORT_SYMBOL +struct evbuffer_ptr evbuffer_search(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start); + +/** + Search for a string within part of an evbuffer. + + @param buffer the evbuffer to be searched + @param what the string to be searched for + @param len the length of the search string + @param start NULL or a pointer to a valid struct evbuffer_ptr that + indicates where we should start searching. + @param end NULL or a pointer to a valid struct evbuffer_ptr that + indicates where we should stop searching. + @return a struct evbuffer_ptr whose 'pos' field has the offset of the + first occurrence of the string in the buffer after 'start'. The 'pos' + field of the result is -1 if the string was not found. + */ +EVENT2_EXPORT_SYMBOL +struct evbuffer_ptr evbuffer_search_range(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start, const struct evbuffer_ptr *end); + +/** + Defines how to adjust an evbuffer_ptr by evbuffer_ptr_set() + + @see evbuffer_ptr_set() */ +enum evbuffer_ptr_how { + /** Sets the pointer to the position; can be called on with an + uninitialized evbuffer_ptr. */ + EVBUFFER_PTR_SET, + /** Advances the pointer by adding to the current position. */ + EVBUFFER_PTR_ADD +}; + +/** + Sets the search pointer in the buffer to position. + + There are two ways to use this function: you can call + evbuffer_ptr_set(buf, &pos, N, EVBUFFER_PTR_SET) + to move 'pos' to a position 'N' bytes after the start of the buffer, or + evbuffer_ptr_set(buf, &pos, N, EVBUFFER_PTR_ADD) + to move 'pos' forward by 'N' bytes. + + If evbuffer_ptr is not initialized, this function can only be called + with EVBUFFER_PTR_SET. + + An evbuffer_ptr can represent any position from the start of the buffer to + a position immediately after the end of the buffer. + + @param buffer the evbuffer to be search + @param ptr a pointer to a struct evbuffer_ptr + @param position the position at which to start the next search + @param how determines how the pointer should be manipulated. + @returns 0 on success or -1 otherwise +*/ +EVENT2_EXPORT_SYMBOL +int +evbuffer_ptr_set(struct evbuffer *buffer, struct evbuffer_ptr *ptr, + size_t position, enum evbuffer_ptr_how how); + +/** + Search for an end-of-line string within an evbuffer. + + @param buffer the evbuffer to be searched + @param start NULL or a pointer to a valid struct evbuffer_ptr to start + searching at. + @param eol_len_out If non-NULL, the pointed-to value will be set to + the length of the end-of-line string. + @param eol_style The kind of EOL to look for; see evbuffer_readln() for + more information + @return a struct evbuffer_ptr whose 'pos' field has the offset of the + first occurrence EOL in the buffer after 'start'. The 'pos' + field of the result is -1 if the string was not found. + */ +EVENT2_EXPORT_SYMBOL +struct evbuffer_ptr evbuffer_search_eol(struct evbuffer *buffer, + struct evbuffer_ptr *start, size_t *eol_len_out, + enum evbuffer_eol_style eol_style); + +/** Function to peek at data inside an evbuffer without removing it or + copying it out. + + Pointers to the data are returned by filling the 'vec_out' array + with pointers to one or more extents of data inside the buffer. + + The total data in the extents that you get back may be more than + you requested (if there is more data last extent than you asked + for), or less (if you do not provide enough evbuffer_iovecs, or if + the buffer does not have as much data as you asked to see). + + @param buffer the evbuffer to peek into, + @param len the number of bytes to try to peek. If len is negative, we + will try to fill as much of vec_out as we can. If len is negative + and vec_out is not provided, we return the number of evbuffer_iovecs + that would be needed to get all the data in the buffer. + @param start_at an evbuffer_ptr indicating the point at which we + should start looking for data. NULL means, "At the start of the + buffer." + @param vec_out an array of evbuffer_iovec + @param n_vec the length of vec_out. If 0, we only count how many + extents would be necessary to point to the requested amount of + data. + @return The number of extents needed. This may be less than n_vec + if we didn't need all the evbuffer_iovecs we were given, or more + than n_vec if we would need more to return all the data that was + requested. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len, + struct evbuffer_ptr *start_at, + struct evbuffer_iovec *vec_out, int n_vec); + + +/** Structure passed to an evbuffer_cb_func evbuffer callback + + @see evbuffer_cb_func, evbuffer_add_cb() + */ +struct evbuffer_cb_info { + /** The number of bytes in this evbuffer when callbacks were last + * invoked. */ + size_t orig_size; + /** The number of bytes added since callbacks were last invoked. */ + size_t n_added; + /** The number of bytes removed since callbacks were last invoked. */ + size_t n_deleted; +}; + +/** Type definition for a callback that is invoked whenever data is added or + removed from an evbuffer. + + An evbuffer may have one or more callbacks set at a time. The order + in which they are executed is undefined. + + A callback function may add more callbacks, or remove itself from the + list of callbacks, or add or remove data from the buffer. It may not + remove another callback from the list. + + If a callback adds or removes data from the buffer or from another + buffer, this can cause a recursive invocation of your callback or + other callbacks. If you ask for an infinite loop, you might just get + one: watch out! + + @param buffer the buffer whose size has changed + @param info a structure describing how the buffer changed. + @param arg a pointer to user data +*/ +typedef void (*evbuffer_cb_func)(struct evbuffer *buffer, const struct evbuffer_cb_info *info, void *arg); + +struct evbuffer_cb_entry; +/** Add a new callback to an evbuffer. + + Subsequent calls to evbuffer_add_cb() add new callbacks. To remove this + callback, call evbuffer_remove_cb or evbuffer_remove_cb_entry. + + @param buffer the evbuffer to be monitored + @param cb the callback function to invoke when the evbuffer is modified, + or NULL to remove all callbacks. + @param cbarg an argument to be provided to the callback function + @return a handle to the callback on success, or NULL on failure. + */ +EVENT2_EXPORT_SYMBOL +struct evbuffer_cb_entry *evbuffer_add_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg); + +/** Remove a callback from an evbuffer, given a handle returned from + evbuffer_add_cb. + + Calling this function invalidates the handle. + + @return 0 if a callback was removed, or -1 if no matching callback was + found. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_remove_cb_entry(struct evbuffer *buffer, + struct evbuffer_cb_entry *ent); + +/** Remove a callback from an evbuffer, given the function and argument + used to add it. + + @return 0 if a callback was removed, or -1 if no matching callback was + found. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg); + +/** If this flag is not set, then a callback is temporarily disabled, and + * should not be invoked. + * + * @see evbuffer_cb_set_flags(), evbuffer_cb_clear_flags() + */ +#define EVBUFFER_CB_ENABLED 1 + +/** Change the flags that are set for a callback on a buffer by adding more. + + @param buffer the evbuffer that the callback is watching. + @param cb the callback whose status we want to change. + @param flags EVBUFFER_CB_ENABLED to re-enable the callback. + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_cb_set_flags(struct evbuffer *buffer, + struct evbuffer_cb_entry *cb, ev_uint32_t flags); + +/** Change the flags that are set for a callback on a buffer by removing some + + @param buffer the evbuffer that the callback is watching. + @param cb the callback whose status we want to change. + @param flags EVBUFFER_CB_ENABLED to disable the callback. + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_cb_clear_flags(struct evbuffer *buffer, + struct evbuffer_cb_entry *cb, ev_uint32_t flags); + +#if 0 +/** Postpone calling a given callback until unsuspend is called later. + + This is different from disabling the callback, since the callback will get + invoked later if the buffer size changes between now and when we unsuspend + it. + + @param the buffer that the callback is watching. + @param cb the callback we want to suspend. + */ +EVENT2_EXPORT_SYMBOL +void evbuffer_cb_suspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb); +/** Stop postponing a callback that we postponed with evbuffer_cb_suspend. + + If data was added to or removed from the buffer while the callback was + suspended, the callback will get called once now. + + @param the buffer that the callback is watching. + @param cb the callback we want to stop suspending. + */ +EVENT2_EXPORT_SYMBOL +void evbuffer_cb_unsuspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb); +#endif + +/** + Makes the data at the beginning of an evbuffer contiguous. + + @param buf the evbuffer to make contiguous + @param size the number of bytes to make contiguous, or -1 to make the + entire buffer contiguous. + @return a pointer to the contiguous memory array, or NULL if param size + requested more data than is present in the buffer. +*/ + +EVENT2_EXPORT_SYMBOL +unsigned char *evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size); + +/** + Prepends data to the beginning of the evbuffer + + @param buf the evbuffer to which to prepend data + @param data a pointer to the memory to prepend + @param size the number of bytes to prepend + @return 0 if successful, or -1 otherwise +*/ + +EVENT2_EXPORT_SYMBOL +int evbuffer_prepend(struct evbuffer *buf, const void *data, size_t size); + +/** + Prepends all data from the src evbuffer to the beginning of the dst + evbuffer. + + @param dst the evbuffer to which to prepend data + @param src the evbuffer to prepend; it will be emptied as a result + @return 0 if successful, or -1 otherwise +*/ +EVENT2_EXPORT_SYMBOL +int evbuffer_prepend_buffer(struct evbuffer *dst, struct evbuffer* src); + +/** + Prevent calls that modify an evbuffer from succeeding. A buffer may + frozen at the front, at the back, or at both the front and the back. + + If the front of a buffer is frozen, operations that drain data from + the front of the buffer, or that prepend data to the buffer, will + fail until it is unfrozen. If the back a buffer is frozen, operations + that append data from the buffer will fail until it is unfrozen. + + @param buf The buffer to freeze + @param at_front If true, we freeze the front of the buffer. If false, + we freeze the back. + @return 0 on success, -1 on failure. +*/ +EVENT2_EXPORT_SYMBOL +int evbuffer_freeze(struct evbuffer *buf, int at_front); +/** + Re-enable calls that modify an evbuffer. + + @param buf The buffer to un-freeze + @param at_front If true, we unfreeze the front of the buffer. If false, + we unfreeze the back. + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_unfreeze(struct evbuffer *buf, int at_front); + +struct event_base; +/** + Force all the callbacks on an evbuffer to be run, not immediately after + the evbuffer is altered, but instead from inside the event loop. + + This can be used to serialize all the callbacks to a single thread + of execution. + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base); + +/** + Append data from 1 or more iovec's to an evbuffer + + Calculates the number of bytes needed for an iovec structure and guarantees + all data will fit into a single chain. Can be used in lieu of functionality + which calls evbuffer_add() constantly before being used to increase + performance. + + @param buffer the destination buffer + @param vec the source iovec + @param n_vec the number of iovec structures. + @return the number of bytes successfully written to the output buffer. +*/ +EVENT2_EXPORT_SYMBOL +size_t evbuffer_add_iovec(struct evbuffer * buffer, struct evbuffer_iovec * vec, int n_vec); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_BUFFER_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/buffer_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/buffer_compat.h new file mode 100644 index 00000000..c4092bf4 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/buffer_compat.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EVENT2_BUFFER_COMPAT_H_INCLUDED_ +#define EVENT2_BUFFER_COMPAT_H_INCLUDED_ + +#include + +/** @file event2/buffer_compat.h + + @brief Obsolete and deprecated versions of the functions in buffer.h: provided + only for backward compatibility. + */ + + +/** + Obsolete alias for evbuffer_readln(buffer, NULL, EVBUFFER_EOL_ANY). + + @deprecated This function is deprecated because its behavior is not correct + for almost any protocol, and also because it's wholly subsumed by + evbuffer_readln(). + + @param buffer the evbuffer to read from + @return pointer to a single line, or NULL if an error occurred + +*/ +EVENT2_EXPORT_SYMBOL +char *evbuffer_readline(struct evbuffer *buffer); + +/** Type definition for a callback that is invoked whenever data is added or + removed from an evbuffer. + + An evbuffer may have one or more callbacks set at a time. The order + in which they are executed is undefined. + + A callback function may add more callbacks, or remove itself from the + list of callbacks, or add or remove data from the buffer. It may not + remove another callback from the list. + + If a callback adds or removes data from the buffer or from another + buffer, this can cause a recursive invocation of your callback or + other callbacks. If you ask for an infinite loop, you might just get + one: watch out! + + @param buffer the buffer whose size has changed + @param old_len the previous length of the buffer + @param new_len the current length of the buffer + @param arg a pointer to user data +*/ +typedef void (*evbuffer_cb)(struct evbuffer *buffer, size_t old_len, size_t new_len, void *arg); + +/** + Replace all callbacks on an evbuffer with a single new callback, or + remove them. + + Subsequent calls to evbuffer_setcb() replace callbacks set by previous + calls. Setting the callback to NULL removes any previously set callback. + + @deprecated This function is deprecated because it clears all previous + callbacks set on the evbuffer, which can cause confusing behavior if + multiple parts of the code all want to add their own callbacks on a + buffer. Instead, use evbuffer_add(), evbuffer_del(), and + evbuffer_setflags() to manage your own evbuffer callbacks without + interfering with callbacks set by others. + + @param buffer the evbuffer to be monitored + @param cb the callback function to invoke when the evbuffer is modified, + or NULL to remove all callbacks. + @param cbarg an argument to be provided to the callback function + @return 0 if successful, or -1 on error + */ +EVENT2_EXPORT_SYMBOL +int evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg); + + +/** + Find a string within an evbuffer. + + @param buffer the evbuffer to be searched + @param what the string to be searched for + @param len the length of the search string + @return a pointer to the beginning of the search string, or NULL if the search failed. + */ +EVENT2_EXPORT_SYMBOL +unsigned char *evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len); + +/** deprecated in favor of calling the functions directly */ +#define EVBUFFER_LENGTH(x) evbuffer_get_length(x) +/** deprecated in favor of calling the functions directly */ +#define EVBUFFER_DATA(x) evbuffer_pullup((x), -1) + +#endif + diff --git a/examples/proto_debuger/third/include/libevent/include/event2/bufferevent.h b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent.h new file mode 100644 index 00000000..a50944f7 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent.h @@ -0,0 +1,1061 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_BUFFEREVENT_H_INCLUDED_ +#define EVENT2_BUFFEREVENT_H_INCLUDED_ + +/** + @file event2/bufferevent.h + + @brief Functions for buffering data for network sending or receiving. + + Bufferevents are higher level than evbuffers: each has an underlying evbuffer for reading + and one for writing, and callbacks that are invoked under certain + circumstances. + + A bufferevent provides input and output buffers that get filled and + drained automatically. The user of a bufferevent no longer deals + directly with the I/O, but instead is reading from input and writing + to output buffers. + + Once initialized, the bufferevent structure can be used repeatedly + with bufferevent_enable() and bufferevent_disable(). + + When reading is enabled, the bufferevent will try to read from the + file descriptor onto its input buffer, and call the read callback. + When writing is enabled, the bufferevent will try to write data onto its + file descriptor when the output buffer has enough data, and call the write + callback when the output buffer is sufficiently drained. + + Bufferevents come in several flavors, including: + +
+
Socket-based bufferevents
+
A bufferevent that reads and writes data onto a network + socket. Created with bufferevent_socket_new().
+ +
Paired bufferevents
+
A pair of bufferevents that send and receive data to one + another without touching the network. Created with + bufferevent_pair_new().
+ +
Filtering bufferevents
+
A bufferevent that transforms data, and sends or receives it + over another underlying bufferevent. Created with + bufferevent_filter_new().
+ +
SSL-backed bufferevents
+
A bufferevent that uses the openssl library to send and + receive data over an encrypted connection. Created with + bufferevent_openssl_socket_new() or + bufferevent_openssl_filter_new().
+
+ */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +/** @name Bufferevent event codes + + These flags are passed as arguments to a bufferevent's event callback. + + @{ +*/ +#define BEV_EVENT_READING 0x01 /**< error encountered while reading */ +#define BEV_EVENT_WRITING 0x02 /**< error encountered while writing */ +#define BEV_EVENT_EOF 0x10 /**< eof file reached */ +#define BEV_EVENT_ERROR 0x20 /**< unrecoverable error encountered */ +#define BEV_EVENT_TIMEOUT 0x40 /**< user-specified timeout reached */ +#define BEV_EVENT_CONNECTED 0x80 /**< connect operation finished. */ +/**@}*/ + +/** + An opaque type for handling buffered IO + + @see event2/bufferevent.h + */ +struct bufferevent +#ifdef EVENT_IN_DOXYGEN_ +{} +#endif +; +struct event_base; +struct evbuffer; +struct sockaddr; + +/** + A read or write callback for a bufferevent. + + The read callback is triggered when new data arrives in the input + buffer and the amount of readable data exceed the low watermark + which is 0 by default. + + The write callback is triggered if the write buffer has been + exhausted or fell below its low watermark. + + @param bev the bufferevent that triggered the callback + @param ctx the user-specified context for this bufferevent + */ +typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx); + +/** + An event/error callback for a bufferevent. + + The event callback is triggered if either an EOF condition or another + unrecoverable error was encountered. + + For bufferevents with deferred callbacks, this is a bitwise OR of all errors + that have happened on the bufferevent since the last callback invocation. + + @param bev the bufferevent for which the error condition was reached + @param what a conjunction of flags: BEV_EVENT_READING or BEV_EVENT_WRITING + to indicate if the error was encountered on the read or write path, + and one of the following flags: BEV_EVENT_EOF, BEV_EVENT_ERROR, + BEV_EVENT_TIMEOUT, BEV_EVENT_CONNECTED. + + @param ctx the user-specified context for this bufferevent +*/ +typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx); + +/** Options that can be specified when creating a bufferevent */ +enum bufferevent_options { + /** If set, we close the underlying file + * descriptor/bufferevent/whatever when this bufferevent is freed. */ + BEV_OPT_CLOSE_ON_FREE = (1<<0), + + /** If set, and threading is enabled, operations on this bufferevent + * are protected by a lock */ + BEV_OPT_THREADSAFE = (1<<1), + + /** If set, callbacks are run deferred in the event loop. */ + BEV_OPT_DEFER_CALLBACKS = (1<<2), + + /** If set, callbacks are executed without locks being held on the + * bufferevent. This option currently requires that + * BEV_OPT_DEFER_CALLBACKS also be set; a future version of Libevent + * might remove the requirement.*/ + BEV_OPT_UNLOCK_CALLBACKS = (1<<3) +}; + +/** + Create a new socket bufferevent over an existing socket. + + @param base the event base to associate with the new bufferevent. + @param fd the file descriptor from which data is read and written to. + This file descriptor is not allowed to be a pipe(2). + It is safe to set the fd to -1, so long as you later + set it with bufferevent_setfd or bufferevent_socket_connect(). + @param options Zero or more BEV_OPT_* flags + @return a pointer to a newly allocated bufferevent struct, or NULL if an + error occurred + @see bufferevent_free() + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent *bufferevent_socket_new(struct event_base *base, evutil_socket_t fd, int options); + +/** + Launch a connect() attempt with a socket-based bufferevent. + + When the connect succeeds, the eventcb will be invoked with + BEV_EVENT_CONNECTED set. + + If the bufferevent does not already have a socket set, we allocate a new + socket here and make it nonblocking before we begin. + + If no address is provided, we assume that the socket is already connecting, + and configure the bufferevent so that a BEV_EVENT_CONNECTED event will be + yielded when it is done connecting. + + @param bufev an existing bufferevent allocated with + bufferevent_socket_new(). + @param addr the address we should connect to + @param socklen The length of the address + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_socket_connect(struct bufferevent *bufev, const struct sockaddr *addr, int socklen); + +struct evdns_base; +/** + Resolve the hostname 'hostname' and connect to it as with + bufferevent_socket_connect(). + + @param bufev An existing bufferevent allocated with bufferevent_socket_new() + @param evdns_base Optionally, an evdns_base to use for resolving hostnames + asynchronously. May be set to NULL for a blocking resolve. + @param family A preferred address family to resolve addresses to, or + AF_UNSPEC for no preference. Only AF_INET, AF_INET6, and AF_UNSPEC are + supported. + @param hostname The hostname to resolve; see below for notes on recognized + formats + @param port The port to connect to on the resolved address. + @return 0 if successful, -1 on failure. + + @see bufferevent_socket_connect_hostname_hints() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_socket_connect_hostname(struct bufferevent *bufev, + struct evdns_base *evdns_base, int family, const char *hostname, int port); + +/** + Resolve the hostname 'hostname' and connect to it as with + bufferevent_socket_connect(). + + @param bufev An existing bufferevent allocated with bufferevent_socket_new() + @param evdns_base Optionally, an evdns_base to use for resolving hostnames + asynchronously. May be set to NULL for a blocking resolve. + @param hints_in points to an addrinfo structure that specifies criteria for + selecting the socket address structures to be used + @param hostname The hostname to resolve; see below for notes on recognized + formats + @param port The port to connect to on the resolved address. + @return 0 if successful, -1 on failure. + + Recognized hostname formats are: + + www.example.com (hostname) + 1.2.3.4 (ipv4address) + ::1 (ipv6address) + [::1] ([ipv6address]) + + Performance note: If you do not provide an evdns_base, this function + may block while it waits for a DNS response. This is probably not + what you want. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_socket_connect_hostname_hints(struct bufferevent *bufev, + struct evdns_base *evdns_base, const struct evutil_addrinfo *hints_in, const char *hostname, int port); + + +/** + Return the error code for the last failed DNS lookup attempt made by + bufferevent_socket_connect_hostname(). + + @param bev The bufferevent object. + @return DNS error code. + @see evutil_gai_strerror() +*/ +EVENT2_EXPORT_SYMBOL +int bufferevent_socket_get_dns_error(struct bufferevent *bev); + +/** + Assign a bufferevent to a specific event_base. + + NOTE that only socket bufferevents support this function. + + @param base an event_base returned by event_init() + @param bufev a bufferevent struct returned by bufferevent_new() + or bufferevent_socket_new() + @return 0 if successful, or -1 if an error occurred + @see bufferevent_new() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_base_set(struct event_base *base, struct bufferevent *bufev); + +/** + Return the event_base used by a bufferevent +*/ +EVENT2_EXPORT_SYMBOL +struct event_base *bufferevent_get_base(struct bufferevent *bev); + +/** + Assign a priority to a bufferevent. + + Only supported for socket bufferevents. + + @param bufev a bufferevent struct + @param pri the priority to be assigned + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_priority_set(struct bufferevent *bufev, int pri); + +/** + Return the priority of a bufferevent. + + Only supported for socket bufferevents + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_get_priority(const struct bufferevent *bufev); + +/** + Deallocate the storage associated with a bufferevent structure. + + If there is pending data to write on the bufferevent, it probably won't be + flushed before the bufferevent is freed. + + @param bufev the bufferevent structure to be freed. + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_free(struct bufferevent *bufev); + + +/** + Changes the callbacks for a bufferevent. + + @param bufev the bufferevent object for which to change callbacks + @param readcb callback to invoke when there is data to be read, or NULL if + no callback is desired + @param writecb callback to invoke when the file descriptor is ready for + writing, or NULL if no callback is desired + @param eventcb callback to invoke when there is an event on the file + descriptor + @param cbarg an argument that will be supplied to each of the callbacks + (readcb, writecb, and errorcb) + @see bufferevent_new() + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_setcb(struct bufferevent *bufev, + bufferevent_data_cb readcb, bufferevent_data_cb writecb, + bufferevent_event_cb eventcb, void *cbarg); + +/** + Retrieves the callbacks for a bufferevent. + + @param bufev the bufferevent to examine. + @param readcb_ptr if readcb_ptr is nonnull, *readcb_ptr is set to the current + read callback for the bufferevent. + @param writecb_ptr if writecb_ptr is nonnull, *writecb_ptr is set to the + current write callback for the bufferevent. + @param eventcb_ptr if eventcb_ptr is nonnull, *eventcb_ptr is set to the + current event callback for the bufferevent. + @param cbarg_ptr if cbarg_ptr is nonnull, *cbarg_ptr is set to the current + callback argument for the bufferevent. + @see buffervent_setcb() +*/ +EVENT2_EXPORT_SYMBOL +void bufferevent_getcb(struct bufferevent *bufev, + bufferevent_data_cb *readcb_ptr, + bufferevent_data_cb *writecb_ptr, + bufferevent_event_cb *eventcb_ptr, + void **cbarg_ptr); + +/** + Changes the file descriptor on which the bufferevent operates. + Not supported for all bufferevent types. + + @param bufev the bufferevent object for which to change the file descriptor + @param fd the file descriptor to operate on +*/ +EVENT2_EXPORT_SYMBOL +int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd); + +/** + Replaces the file descriptor on which the bufferevent operates. + Not supported for all bufferevent types. + + Unlike bufferevent_setfd() it will close previous file descriptor (if any). + + @param bufev the bufferevent object for which to change the file descriptor + @param fd the file descriptor to operate on +*/ +EVENT2_EXPORT_SYMBOL +int bufferevent_replacefd(struct bufferevent *bufev, evutil_socket_t fd); + +/** + Returns the file descriptor associated with a bufferevent, or -1 if + no file descriptor is associated with the bufferevent. + */ +EVENT2_EXPORT_SYMBOL +evutil_socket_t bufferevent_getfd(struct bufferevent *bufev); + +/** + Returns the underlying bufferevent associated with a bufferevent (if + the bufferevent is a wrapper), or NULL if there is no underlying bufferevent. + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent *bufferevent_get_underlying(struct bufferevent *bufev); + +/** + Write data to a bufferevent buffer. + + The bufferevent_write() function can be used to write data to the file + descriptor. The data is appended to the output buffer and written to the + descriptor automatically as it becomes available for writing. + + @param bufev the bufferevent to be written to + @param data a pointer to the data to be written + @param size the length of the data, in bytes + @return 0 if successful, or -1 if an error occurred + @see bufferevent_write_buffer() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_write(struct bufferevent *bufev, + const void *data, size_t size); + + +/** + Write data from an evbuffer to a bufferevent buffer. The evbuffer is + being drained as a result. + + @param bufev the bufferevent to be written to + @param buf the evbuffer to be written + @return 0 if successful, or -1 if an error occurred + @see bufferevent_write() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); + + +/** + Read data from a bufferevent buffer. + + The bufferevent_read() function is used to read data from the input buffer. + + @param bufev the bufferevent to be read from + @param data pointer to a buffer that will store the data + @param size the size of the data buffer, in bytes + @return the amount of data read, in bytes. If 0 is returned, it is possible + that there is no data in the buffer or that the read failed. + */ +EVENT2_EXPORT_SYMBOL +size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); + +/** + Read data from a bufferevent buffer into an evbuffer. This avoids + memory copies. + + @param bufev the bufferevent to be read from + @param buf the evbuffer to which to add data + @return 0 if successful, or -1 if an error occurred. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_read_buffer(struct bufferevent *bufev, struct evbuffer *buf); + +/** + Returns the input buffer. + + The user MUST NOT set the callback on this buffer. + + @param bufev the bufferevent from which to get the evbuffer + @return the evbuffer object for the input buffer + */ + +EVENT2_EXPORT_SYMBOL +struct evbuffer *bufferevent_get_input(struct bufferevent *bufev); + +/** + Returns the output buffer. + + The user MUST NOT set the callback on this buffer. + + When filters are being used, the filters need to be manually + triggered if the output buffer was manipulated. + + @param bufev the bufferevent from which to get the evbuffer + @return the evbuffer object for the output buffer + */ + +EVENT2_EXPORT_SYMBOL +struct evbuffer *bufferevent_get_output(struct bufferevent *bufev); + +/** + Enable a bufferevent. + + @param bufev the bufferevent to be enabled + @param event any combination of EV_READ | EV_WRITE. + @return 0 if successful, or -1 if an error occurred + @see bufferevent_disable() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_enable(struct bufferevent *bufev, short event); + +/** + Disable a bufferevent. + + @param bufev the bufferevent to be disabled + @param event any combination of EV_READ | EV_WRITE. + @return 0 if successful, or -1 if an error occurred + @see bufferevent_enable() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_disable(struct bufferevent *bufev, short event); + +/** + Return the events that are enabled on a given bufferevent. + + @param bufev the bufferevent to inspect + @return A combination of EV_READ | EV_WRITE + */ +EVENT2_EXPORT_SYMBOL +short bufferevent_get_enabled(struct bufferevent *bufev); + +/** + Set the read and write timeout for a bufferevent. + + A bufferevent's timeout will fire the first time that the indicated + amount of time has elapsed since a successful read or write operation, + during which the bufferevent was trying to read or write. + + (In other words, if reading or writing is disabled, or if the + bufferevent's read or write operation has been suspended because + there's no data to write, or not enough bandwidth, or so on, the + timeout isn't active. The timeout only becomes active when we we're + willing to actually read or write.) + + Calling bufferevent_enable or setting a timeout for a bufferevent + whose timeout is already pending resets its timeout. + + If the timeout elapses, the corresponding operation (EV_READ or + EV_WRITE) becomes disabled until you re-enable it again. The + bufferevent's event callback is called with the + BEV_EVENT_TIMEOUT|BEV_EVENT_READING or + BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING. + + @param bufev the bufferevent to be modified + @param timeout_read the read timeout, or NULL + @param timeout_write the write timeout, or NULL + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_set_timeouts(struct bufferevent *bufev, + const struct timeval *timeout_read, const struct timeval *timeout_write); + +/** + Sets the watermarks for read and write events. + + On input, a bufferevent does not invoke the user read callback unless + there is at least low watermark data in the buffer. If the read buffer + is beyond the high watermark, the bufferevent stops reading from the network. + But be aware that bufferevent input/read buffer can overrun high watermark + limit (typical example is openssl bufferevent), so you should not relay in + this. + + On output, the user write callback is invoked whenever the buffered data + falls below the low watermark. Filters that write to this bufev will try + not to write more bytes to this buffer than the high watermark would allow, + except when flushing. + + @param bufev the bufferevent to be modified + @param events EV_READ, EV_WRITE or both + @param lowmark the lower watermark to set + @param highmark the high watermark to set +*/ + +EVENT2_EXPORT_SYMBOL +void bufferevent_setwatermark(struct bufferevent *bufev, short events, + size_t lowmark, size_t highmark); + +/** + Retrieves the watermarks for read or write events. + Returns non-zero if events contains not only EV_READ or EV_WRITE. + Returns zero if events equal EV_READ or EV_WRITE + + @param bufev the bufferevent to be examined + @param events EV_READ or EV_WRITE + @param lowmark receives the lower watermark if not NULL + @param highmark receives the high watermark if not NULL +*/ +EVENT2_EXPORT_SYMBOL +int bufferevent_getwatermark(struct bufferevent *bufev, short events, + size_t *lowmark, size_t *highmark); + +/** + Acquire the lock on a bufferevent. Has no effect if locking was not + enabled with BEV_OPT_THREADSAFE. + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_lock(struct bufferevent *bufev); + +/** + Release the lock on a bufferevent. Has no effect if locking was not + enabled with BEV_OPT_THREADSAFE. + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_unlock(struct bufferevent *bufev); + + +/** + * Public interface to manually increase the reference count of a bufferevent + * this is useful in situations where a user may reference the bufferevent + * somewhere else (unknown to libevent) + * + * @param bufev the bufferevent to increase the refcount on + * + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_incref(struct bufferevent *bufev); + +/** + * Public interface to manually decrement the reference count of a bufferevent + * + * Warning: make sure you know what you're doing. This is mainly used in + * conjunction with bufferevent_incref(). This will free up all data associated + * with a bufferevent if the reference count hits 0. + * + * @param bufev the bufferevent to decrement the refcount on + * + * @return 1 if the bufferevent was freed, otherwise 0 (still referenced) + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_decref(struct bufferevent *bufev); + +/** + Flags that can be passed into filters to let them know how to + deal with the incoming data. +*/ +enum bufferevent_flush_mode { + /** usually set when processing data */ + BEV_NORMAL = 0, + + /** want to checkpoint all data sent. */ + BEV_FLUSH = 1, + + /** encountered EOF on read or done sending data */ + BEV_FINISHED = 2 +}; + +/** + Triggers the bufferevent to produce more data if possible. + + @param bufev the bufferevent object + @param iotype either EV_READ or EV_WRITE or both. + @param mode either BEV_NORMAL or BEV_FLUSH or BEV_FINISHED + @return -1 on failure, 0 if no data was produces, 1 if data was produced + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_flush(struct bufferevent *bufev, + short iotype, + enum bufferevent_flush_mode mode); + +/** + Flags for bufferevent_trigger(_event) that modify when and how to trigger + the callback. +*/ +enum bufferevent_trigger_options { + /** trigger the callback regardless of the watermarks */ + BEV_TRIG_IGNORE_WATERMARKS = (1<<16), + + /** defer even if the callbacks are not */ + BEV_TRIG_DEFER_CALLBACKS = BEV_OPT_DEFER_CALLBACKS + + /* (Note: for internal reasons, these need to be disjoint from + * bufferevent_options, except when they mean the same thing. */ +}; + +/** + Triggers bufferevent data callbacks. + + The function will honor watermarks unless options contain + BEV_TRIG_IGNORE_WATERMARKS. If the options contain BEV_OPT_DEFER_CALLBACKS, + the callbacks are deferred. + + @param bufev the bufferevent object + @param iotype either EV_READ or EV_WRITE or both. + @param options + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_trigger(struct bufferevent *bufev, short iotype, + int options); + +/** + Triggers the bufferevent event callback. + + If the options contain BEV_OPT_DEFER_CALLBACKS, the callbacks are deferred. + + @param bufev the bufferevent object + @param what the flags to pass onto the event callback + @param options + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_trigger_event(struct bufferevent *bufev, short what, + int options); + +/** + @name Filtering support + + @{ +*/ +/** + Values that filters can return. + */ +enum bufferevent_filter_result { + /** everything is okay */ + BEV_OK = 0, + + /** the filter needs to read more data before output */ + BEV_NEED_MORE = 1, + + /** the filter encountered a critical error, no further data + can be processed. */ + BEV_ERROR = 2 +}; + +/** A callback function to implement a filter for a bufferevent. + + @param src An evbuffer to drain data from. + @param dst An evbuffer to add data to. + @param limit A suggested upper bound of bytes to write to dst. + The filter may ignore this value, but doing so means that + it will overflow the high-water mark associated with dst. + -1 means "no limit". + @param mode Whether we should write data as may be convenient + (BEV_NORMAL), or flush as much data as we can (BEV_FLUSH), + or flush as much as we can, possibly including an end-of-stream + marker (BEV_FINISH). + @param ctx A user-supplied pointer. + + @return BEV_OK if we wrote some data; BEV_NEED_MORE if we can't + produce any more output until we get some input; and BEV_ERROR + on an error. + */ +typedef enum bufferevent_filter_result (*bufferevent_filter_cb)( + struct evbuffer *src, struct evbuffer *dst, ev_ssize_t dst_limit, + enum bufferevent_flush_mode mode, void *ctx); + +/** + Allocate a new filtering bufferevent on top of an existing bufferevent. + + @param underlying the underlying bufferevent. + @param input_filter The filter to apply to data we read from the underlying + bufferevent + @param output_filter The filer to apply to data we write to the underlying + bufferevent + @param options A bitfield of bufferevent options. + @param free_context A function to use to free the filter context when + this bufferevent is freed. + @param ctx A context pointer to pass to the filter functions. + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent * +bufferevent_filter_new(struct bufferevent *underlying, + bufferevent_filter_cb input_filter, + bufferevent_filter_cb output_filter, + int options, + void (*free_context)(void *), + void *ctx); +/**@}*/ + +/** + Allocate a pair of linked bufferevents. The bufferevents behave as would + two bufferevent_sock instances connected to opposite ends of a + socketpair(), except that no internal socketpair is allocated. + + @param base The event base to associate with the socketpair. + @param options A set of options for this bufferevent + @param pair A pointer to an array to hold the two new bufferevent objects. + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_pair_new(struct event_base *base, int options, + struct bufferevent *pair[2]); + +/** + Given one bufferevent returned by bufferevent_pair_new(), returns the + other one if it still exists. Otherwise returns NULL. + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent *bufferevent_pair_get_partner(struct bufferevent *bev); + +/** + Abstract type used to configure rate-limiting on a bufferevent or a group + of bufferevents. + */ +struct ev_token_bucket_cfg; + +/** + A group of bufferevents which are configured to respect the same rate + limit. +*/ +struct bufferevent_rate_limit_group; + +/** Maximum configurable rate- or burst-limit. */ +#define EV_RATE_LIMIT_MAX EV_SSIZE_MAX + +/** + Initialize and return a new object to configure the rate-limiting behavior + of bufferevents. + + @param read_rate The maximum number of bytes to read per tick on + average. + @param read_burst The maximum number of bytes to read in any single tick. + @param write_rate The maximum number of bytes to write per tick on + average. + @param write_burst The maximum number of bytes to write in any single tick. + @param tick_len The length of a single tick. Defaults to one second. + Any fractions of a millisecond are ignored. + + Note that all rate-limits hare are currently best-effort: future versions + of Libevent may implement them more tightly. + */ +EVENT2_EXPORT_SYMBOL +struct ev_token_bucket_cfg *ev_token_bucket_cfg_new( + size_t read_rate, size_t read_burst, + size_t write_rate, size_t write_burst, + const struct timeval *tick_len); + +/** Free all storage held in 'cfg'. + + Note: 'cfg' is not currently reference-counted; it is not safe to free it + until no bufferevent is using it. + */ +EVENT2_EXPORT_SYMBOL +void ev_token_bucket_cfg_free(struct ev_token_bucket_cfg *cfg); + +/** + Set the rate-limit of a the bufferevent 'bev' to the one specified in + 'cfg'. If 'cfg' is NULL, disable any per-bufferevent rate-limiting on + 'bev'. + + Note that only some bufferevent types currently respect rate-limiting. + They are: socket-based bufferevents (normal and IOCP-based), and SSL-based + bufferevents. + + Return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_set_rate_limit(struct bufferevent *bev, + struct ev_token_bucket_cfg *cfg); + +/** + Create a new rate-limit group for bufferevents. A rate-limit group + constrains the maximum number of bytes sent and received, in toto, + by all of its bufferevents. + + @param base An event_base to run any necessary timeouts for the group. + Note that all bufferevents in the group do not necessarily need to share + this event_base. + @param cfg The rate-limit for this group. + + Note that all rate-limits hare are currently best-effort: future versions + of Libevent may implement them more tightly. + + Note also that only some bufferevent types currently respect rate-limiting. + They are: socket-based bufferevents (normal and IOCP-based), and SSL-based + bufferevents. + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent_rate_limit_group *bufferevent_rate_limit_group_new( + struct event_base *base, + const struct ev_token_bucket_cfg *cfg); +/** + Change the rate-limiting settings for a given rate-limiting group. + + Return 0 on success, -1 on failure. +*/ +EVENT2_EXPORT_SYMBOL +int bufferevent_rate_limit_group_set_cfg( + struct bufferevent_rate_limit_group *, + const struct ev_token_bucket_cfg *); + +/** + Change the smallest quantum we're willing to allocate to any single + bufferevent in a group for reading or writing at a time. + + The rationale is that, because of TCP/IP protocol overheads and kernel + behavior, if a rate-limiting group is so tight on bandwidth that you're + only willing to send 1 byte per tick per bufferevent, you might instead + want to batch up the reads and writes so that you send N bytes per + 1/N of the bufferevents (chosen at random) each tick, so you still wind + up send 1 byte per tick per bufferevent on average, but you don't send + so many tiny packets. + + The default min-share is currently 64 bytes. + + Returns 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_rate_limit_group_set_min_share( + struct bufferevent_rate_limit_group *, size_t); + +/** + Free a rate-limiting group. The group must have no members when + this function is called. +*/ +EVENT2_EXPORT_SYMBOL +void bufferevent_rate_limit_group_free(struct bufferevent_rate_limit_group *); + +/** + Add 'bev' to the list of bufferevents whose aggregate reading and writing + is restricted by 'g'. If 'g' is NULL, remove 'bev' from its current group. + + A bufferevent may belong to no more than one rate-limit group at a time. + If 'bev' is already a member of a group, it will be removed from its old + group before being added to 'g'. + + Return 0 on success and -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_add_to_rate_limit_group(struct bufferevent *bev, + struct bufferevent_rate_limit_group *g); + +/** Remove 'bev' from its current rate-limit group (if any). */ +EVENT2_EXPORT_SYMBOL +int bufferevent_remove_from_rate_limit_group(struct bufferevent *bev); + +/** + Set the size limit for single read operation. + + Set to 0 for a reasonable default. + + Return 0 on success and -1 on failure. + + @see evbuffer_set_max_read() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_set_max_single_read(struct bufferevent *bev, size_t size); + +/** + Set the size limit for single write operation. + + Set to 0 for a reasonable default. + + Return 0 on success and -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_set_max_single_write(struct bufferevent *bev, size_t size); + +/** Get the current size limit for single read operation. */ +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_get_max_single_read(struct bufferevent *bev); + +/** Get the current size limit for single write operation. */ +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_get_max_single_write(struct bufferevent *bev); + +/** + @name Rate limit inspection + + Return the current read or write bucket size for a bufferevent. + If it is not configured with a per-bufferevent ratelimit, return + EV_SSIZE_MAX. This function does not inspect the group limit, if any. + Note that it can return a negative value if the bufferevent has been + made to read or write more than its limit. + + @{ + */ +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_get_read_limit(struct bufferevent *bev); +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_get_write_limit(struct bufferevent *bev); +/*@}*/ + +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_get_max_to_read(struct bufferevent *bev); +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_get_max_to_write(struct bufferevent *bev); + +EVENT2_EXPORT_SYMBOL +const struct ev_token_bucket_cfg *bufferevent_get_token_bucket_cfg(const struct bufferevent * bev); + +/** + @name Group Rate limit inspection + + Return the read or write bucket size for a bufferevent rate limit + group. Note that it can return a negative value if bufferevents in + the group have been made to read or write more than their limits. + + @{ + */ +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_rate_limit_group_get_read_limit( + struct bufferevent_rate_limit_group *); +EVENT2_EXPORT_SYMBOL +ev_ssize_t bufferevent_rate_limit_group_get_write_limit( + struct bufferevent_rate_limit_group *); +/*@}*/ + +/** + @name Rate limit manipulation + + Subtract a number of bytes from a bufferevent's read or write bucket. + The decrement value can be negative, if you want to manually refill + the bucket. If the change puts the bucket above or below zero, the + bufferevent will resume or suspend reading writing as appropriate. + These functions make no change in the buckets for the bufferevent's + group, if any. + + Returns 0 on success, -1 on internal error. + + @{ + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_decrement_read_limit(struct bufferevent *bev, ev_ssize_t decr); +EVENT2_EXPORT_SYMBOL +int bufferevent_decrement_write_limit(struct bufferevent *bev, ev_ssize_t decr); +/*@}*/ + +/** + @name Group rate limit manipulation + + Subtract a number of bytes from a bufferevent rate-limiting group's + read or write bucket. The decrement value can be negative, if you + want to manually refill the bucket. If the change puts the bucket + above or below zero, the bufferevents in the group will resume or + suspend reading writing as appropriate. + + Returns 0 on success, -1 on internal error. + + @{ + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_rate_limit_group_decrement_read( + struct bufferevent_rate_limit_group *, ev_ssize_t); +EVENT2_EXPORT_SYMBOL +int bufferevent_rate_limit_group_decrement_write( + struct bufferevent_rate_limit_group *, ev_ssize_t); +/*@}*/ + + +/** + * Inspect the total bytes read/written on a group. + * + * Set the variable pointed to by total_read_out to the total number of bytes + * ever read on grp, and the variable pointed to by total_written_out to the + * total number of bytes ever written on grp. */ +EVENT2_EXPORT_SYMBOL +void bufferevent_rate_limit_group_get_totals( + struct bufferevent_rate_limit_group *grp, + ev_uint64_t *total_read_out, ev_uint64_t *total_written_out); + +/** + * Reset the total bytes read/written on a group. + * + * Reset the number of bytes read or written on grp as given by + * bufferevent_rate_limit_group_reset_totals(). */ +EVENT2_EXPORT_SYMBOL +void +bufferevent_rate_limit_group_reset_totals( + struct bufferevent_rate_limit_group *grp); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_BUFFEREVENT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_compat.h new file mode 100644 index 00000000..e0713220 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_compat.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2007-2012 Niels Provos, Nick Mathewson + * Copyright (c) 2000-2007 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_ +#define EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_ + +/** @file event2/bufferevent_compat.h + * + * @brief Deprecated versions of the functions in bufferevent.h: provided + * only for backwards compatibility. + */ + +#include + +#define evbuffercb bufferevent_data_cb +#define everrorcb bufferevent_event_cb + +/** + Create a new bufferevent for an fd. + + This function is deprecated. Use bufferevent_socket_new and + bufferevent_set_callbacks instead. + + Libevent provides an abstraction on top of the regular event callbacks. + This abstraction is called a buffered event. A buffered event provides + input and output buffers that get filled and drained automatically. The + user of a buffered event no longer deals directly with the I/O, but + instead is reading from input and writing to output buffers. + + Once initialized, the bufferevent structure can be used repeatedly with + bufferevent_enable() and bufferevent_disable(). + + When read enabled the bufferevent will try to read from the file descriptor + and call the read callback. The write callback is executed whenever the + output buffer is drained below the write low watermark, which is 0 by + default. + + If multiple bases are in use, bufferevent_base_set() must be called before + enabling the bufferevent for the first time. + + @deprecated This function is deprecated because it uses the current + event base, and as such can be error prone for multithreaded programs. + Use bufferevent_socket_new() instead. + + @param fd the file descriptor from which data is read and written to. + This file descriptor is not allowed to be a pipe(2). + @param readcb callback to invoke when there is data to be read, or NULL if + no callback is desired + @param writecb callback to invoke when the file descriptor is ready for + writing, or NULL if no callback is desired + @param errorcb callback to invoke when there is an error on the file + descriptor + @param cbarg an argument that will be supplied to each of the callbacks + (readcb, writecb, and errorcb) + @return a pointer to a newly allocated bufferevent struct, or NULL if an + error occurred + @see bufferevent_base_set(), bufferevent_free() + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent *bufferevent_new(evutil_socket_t fd, + evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); + + +/** + Set the read and write timeout for a buffered event. + + @deprecated Use bufferevent_set_timeouts instead. + + @param bufev the bufferevent to be modified + @param timeout_read the read timeout + @param timeout_write the write timeout + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_settimeout(struct bufferevent *bufev, + int timeout_read, int timeout_write); + +#define EVBUFFER_READ BEV_EVENT_READING +#define EVBUFFER_WRITE BEV_EVENT_WRITING +#define EVBUFFER_EOF BEV_EVENT_EOF +#define EVBUFFER_ERROR BEV_EVENT_ERROR +#define EVBUFFER_TIMEOUT BEV_EVENT_TIMEOUT + +/** macro for getting access to the input buffer of a bufferevent */ +#define EVBUFFER_INPUT(x) bufferevent_get_input(x) +/** macro for getting access to the output buffer of a bufferevent */ +#define EVBUFFER_OUTPUT(x) bufferevent_get_output(x) + +#endif diff --git a/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_ssl.h b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_ssl.h new file mode 100644 index 00000000..8cc35732 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_ssl.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_BUFFEREVENT_SSL_H_INCLUDED_ +#define EVENT2_BUFFEREVENT_SSL_H_INCLUDED_ + +/** @file event2/bufferevent_ssl.h + + @brief OpenSSL support for bufferevents. + */ +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + The state of an SSL object to be used when creating a new + SSL bufferevent. + */ +enum bufferevent_ssl_state { + BUFFEREVENT_SSL_OPEN = 0, + BUFFEREVENT_SSL_CONNECTING = 1, + BUFFEREVENT_SSL_ACCEPTING = 2 +}; + +/** Control how to report dirty SSL shutdowns. + + If the peer (or the network, or an attacker) closes the TCP + connection before closing the SSL channel, and the protocol is SSL >= v3, + this is a "dirty" shutdown. If BUFFEREVENT_SSL_DIRTY_SHUTDOWN is not set + (default), this is reported as BEV_EVENT_ERROR. + + If instead BUFFEREVENT_SSL_DIRTY_SHUTDOWN is set, a dirty shutdown is + reported as BEV_EVENT_EOF. + + (Note that if the protocol is < SSLv3, you will always receive + BEV_EVENT_EOF, since SSL 2 and earlier cannot distinguish a secure + connection close from a dirty one. This is one reason (among many) + not to use SSL 2.) +*/ +#define BUFFEREVENT_SSL_DIRTY_SHUTDOWN 1 +/** Control writes in the SSL bufferevents. + + By default SSL bufferevent will peek bytes from the buffer as the arrived. + with respect to the segment boundaries in the buffer. + However, by ignoring these segment boundaries number of packets to send + can be decreased. + + This flags will ignore the segment boundaries. + + Useful in conjunction with http layer. +*/ +#define BUFFEREVENT_SSL_BATCH_WRITE 2 + +#if defined(EVENT__HAVE_OPENSSL) || defined(EVENT__HAVE_MBEDTLS) +/** + * Get flags of the SSL bufferevent. + * + * @see BUFFEREVENT_SSL_* + * @return flags or SIZE_MAX in case of error (if bufferevent is not SSL). + */ +EVENT2_EXPORT_SYMBOL +ev_uint64_t bufferevent_ssl_get_flags(struct bufferevent *bev); +/** Change the flags that are set for an ssl bufferevent by adding more. + * + * @param bev the ssl bufferevent. + * @param flags One or more BUFFEREVENT_SSL_* options + * @return old flags success, EV_UINT64_MAX on failure. + */ +EVENT2_EXPORT_SYMBOL +ev_uint64_t bufferevent_ssl_set_flags(struct bufferevent *bev, ev_uint64_t flags); +/** Change the flags that are set for an ssl bufferevent by removing some. + * + * @param bev the bufferevent. + * @param flags One or more BUFFEREVENT_SSL_* options + * @return old flags success, EV_UINT64_MAX on failure. + */ +EVENT2_EXPORT_SYMBOL +ev_uint64_t bufferevent_ssl_clear_flags(struct bufferevent *bev, ev_uint64_t flags); + +#endif /* defined(EVENT__HAVE_OPENSSL) || defined(EVENT__HAVE_MBEDTLS) */ + +#if defined(EVENT__HAVE_OPENSSL) || defined(EVENT_IN_DOXYGEN_) +/* This is what openssl's SSL objects are underneath. */ +struct ssl_st; + +/** + Create a new SSL bufferevent to send its data over another bufferevent. + + @param base An event_base to use to detect reading and writing. It + must also be the base for the underlying bufferevent. + @param underlying A socket to use for this SSL + @param ssl A SSL* object from openssl. + @param state The current state of the SSL connection + @param options One or more bufferevent_options + @return A new bufferevent on success, or NULL on failure +*/ +EVENT2_EXPORT_SYMBOL +struct bufferevent * +bufferevent_openssl_filter_new(struct event_base *base, + struct bufferevent *underlying, + struct ssl_st *ssl, + enum bufferevent_ssl_state state, + int options); + +/** + Create a new SSL bufferevent to send its data over an SSL * on a socket. + + @param base An event_base to use to detect reading and writing + @param fd A socket to use for this SSL + @param ssl A SSL* object from openssl. + @param state The current state of the SSL connection + @param options One or more bufferevent_options + @return A new bufferevent on success, or NULL on failure. +*/ +EVENT2_EXPORT_SYMBOL +struct bufferevent * +bufferevent_openssl_socket_new(struct event_base *base, + evutil_socket_t fd, + struct ssl_st *ssl, + enum bufferevent_ssl_state state, + int options); + +/** + * Get value of the BUFFEREVENT_SSL_DIRTY_SHUTDOWN flag. + * + * @see BUFFEREVENT_SSL_DIRTY_SHUTDOWN + * @deprecated This function is deprecated, use bufferevent_ssl_get_flags() instead. + * @see bufferevent_ssl_get_flags() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev); +/** + * Set value of the BUFFEREVENT_SSL_DIRTY_SHUTDOWN flag. + * + * @see BUFFEREVENT_SSL_DIRTY_SHUTDOWN + * @deprecated This function is deprecated, use bufferevent_ssl_set_flags() instead. + * @see bufferevent_ssl_set_flags() + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev, + int allow_dirty_shutdown); + +/** Return the underlying openssl SSL * object for an SSL bufferevent. */ +EVENT2_EXPORT_SYMBOL +struct ssl_st * +bufferevent_openssl_get_ssl(struct bufferevent *bufev); + +/** Tells a bufferevent to begin SSL renegotiation. */ +EVENT2_EXPORT_SYMBOL +int bufferevent_ssl_renegotiate(struct bufferevent *bev); + +/** Return the most recent OpenSSL error reported on an SSL bufferevent. */ +EVENT2_EXPORT_SYMBOL +unsigned long bufferevent_get_openssl_error(struct bufferevent *bev); + +#endif +#if defined(EVENT__HAVE_MBEDTLS) || defined(EVENT_IN_DOXYGEN_) +struct mbedtls_ssl_context; +/** + Create a new SSL bufferevent to send its data over another bufferevent. + + @param base An event_base to use to detect reading and writing. It + must also be the base for the underlying bufferevent. + @param underlying A socket to use for this SSL + @param ssl A SSL* object from openssl. + @param state The current state of the SSL connection + @param options One or more bufferevent_options + @return A new bufferevent on success, or NULL on failure +*/ +EVENT2_EXPORT_SYMBOL +struct bufferevent * +bufferevent_mbedtls_filter_new(struct event_base *base, + struct bufferevent *underlying, + struct mbedtls_ssl_context *ssl, + enum bufferevent_ssl_state state, + int options); + +/** + Create a new SSL bufferevent to send its data over an SSL * on a socket. + + @param base An event_base to use to detect reading and writing + @param fd A socket to use for this SSL + @param ssl A SSL* object from mbedtls. + @param state The current state of the SSL connection + @param options One or more bufferevent_options + @return A new bufferevent on success, or NULL on failure. +*/ +EVENT2_EXPORT_SYMBOL +struct bufferevent * +bufferevent_mbedtls_socket_new(struct event_base *base, + evutil_socket_t fd, + struct mbedtls_ssl_context *ssl, + enum bufferevent_ssl_state state, + int options); + +/** + * Get value of the BUFFEREVENT_SSL_DIRTY_SHUTDOWN flag. + * + * @see BUFFEREVENT_SSL_DIRTY_SHUTDOWN + * @deprecated This function is deprecated, use bufferevent_ssl_get_flags() instead. + * @see bufferevent_ssl_get_flags() + */ +EVENT2_EXPORT_SYMBOL +int bufferevent_mbedtls_get_allow_dirty_shutdown(struct bufferevent *bev); +/** + * Set value of the BUFFEREVENT_SSL_DIRTY_SHUTDOWN flag. + * + * @see BUFFEREVENT_SSL_DIRTY_SHUTDOWN + * @deprecated This function is deprecated, use bufferevent_ssl_set_flags() instead. + * @see bufferevent_ssl_set_flags() + */ +EVENT2_EXPORT_SYMBOL +void bufferevent_mbedtls_set_allow_dirty_shutdown(struct bufferevent *bev, + int allow_dirty_shutdown); + +/** Return the underlying mbedtls SSL * object for an SSL bufferevent. */ +EVENT2_EXPORT_SYMBOL +struct mbedtls_ssl_context * +bufferevent_mbedtls_get_ssl(struct bufferevent *bufev); + +/** Tells a bufferevent to begin SSL renegotiation. */ +EVENT2_EXPORT_SYMBOL +int bufferevent_mbedtls_renegotiate(struct bufferevent *bev); + +/** Return the most recent OpenSSL error reported on an SSL bufferevent. */ +EVENT2_EXPORT_SYMBOL +unsigned long bufferevent_get_mbedtls_error(struct bufferevent *bev); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_BUFFEREVENT_SSL_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_struct.h b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_struct.h new file mode 100644 index 00000000..546773ab --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/bufferevent_struct.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_BUFFEREVENT_STRUCT_H_INCLUDED_ +#define EVENT2_BUFFEREVENT_STRUCT_H_INCLUDED_ + +/** @file event2/bufferevent_struct.h + + Data structures for bufferevents. Using these structures may hurt forward + compatibility with later versions of Libevent: be careful! + + @deprecated Use of bufferevent_struct.h is completely deprecated; these + structures are only exposed for backward compatibility with programs + written before Libevent 2.0 that used them. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include +/* For struct event */ +#include + +struct event_watermark { + size_t low; + size_t high; +}; + +/** + Shared implementation of a bufferevent. + + This type is exposed only because it was exposed in previous versions, + and some people's code may rely on manipulating it. Otherwise, you + should really not rely on the layout, size, or contents of this structure: + it is fairly volatile, and WILL change in future versions of the code. +**/ +struct bufferevent { + /** Event base for which this bufferevent was created. */ + struct event_base *ev_base; + /** Pointer to a table of function pointers to set up how this + bufferevent behaves. */ + const struct bufferevent_ops *be_ops; + + /** A read event that triggers when a timeout has happened or a socket + is ready to read data. Only used by some subtypes of + bufferevent. */ + struct event ev_read; + /** A write event that triggers when a timeout has happened or a socket + is ready to write data. Only used by some subtypes of + bufferevent. */ + struct event ev_write; + + /** An input buffer. Only the bufferevent is allowed to add data to + this buffer, though the user is allowed to drain it. */ + struct evbuffer *input; + + /** An output buffer. Only the bufferevent is allowed to drain data + from this buffer, though the user is allowed to add it. */ + struct evbuffer *output; + + struct event_watermark wm_read; + struct event_watermark wm_write; + + bufferevent_data_cb readcb; + bufferevent_data_cb writecb; + /* This should be called 'eventcb', but renaming it would break + * backward compatibility */ + bufferevent_event_cb errorcb; + void *cbarg; + + struct timeval timeout_read; + struct timeval timeout_write; + + /** Events that are currently enabled: currently EV_READ and EV_WRITE + are supported. */ + short enabled; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_BUFFEREVENT_STRUCT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/dns.h b/examples/proto_debuger/third/include/libevent/include/event2/dns.h new file mode 100644 index 00000000..51264652 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/dns.h @@ -0,0 +1,807 @@ +/* + * Copyright (c) 2006-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * The original DNS code is due to Adam Langley with heavy + * modifications by Nick Mathewson. Adam put his DNS software in the + * public domain. You can find his original copyright below. Please, + * aware that the code as part of Libevent is governed by the 3-clause + * BSD license above. + * + * This software is Public Domain. To view a copy of the public domain dedication, + * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to + * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + * + * I ask and expect, but do not require, that all derivative works contain an + * attribution similar to: + * Parts developed by Adam Langley + * + * You may wish to replace the word "Parts" with something else depending on + * the amount of original code. + * + * (Derivative works does not include programs which link against, run or include + * the source verbatim in their source distributions) + */ + +/** @file event2/dns.h + * + * @brief Provides a few APIs to use for resolving DNS names, and a facility + * for implementing simple DNS servers. + * + * Welcome, gentle reader + * + * Async DNS lookups are really a whole lot harder than they should be, + * mostly stemming from the fact that the libc resolver has never been + * very good at them. Before you use this library you should see if libc + * can do the job for you with the modern async call getaddrinfo_a + * (see http://www.imperialviolet.org/page25.html#e498). Otherwise, + * please continue. + * + * The library keeps track of the state of nameservers and will avoid + * them when they go down. Otherwise it will round robin between them. + * + * Quick start guide: + * @code + * #include "evdns.h" + * void callback(int result, char type, int count, int ttl, + * void *addresses, void *arg); + * evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf"); + * evdns_resolve("www.hostname.com", 0, callback, NULL); + *@endcode + * When the lookup is complete the callback function is called. The + * first argument will be one of the DNS_ERR_* defines in evdns.h. + * Hopefully it will be DNS_ERR_NONE, in which case type will be + * DNS_IPv4_A, count will be the number of IP addresses, ttl is the time + * which the data can be cached for (in seconds), addresses will point + * to an array of uint32_t's and arg will be whatever you passed to + * evdns_resolve. + * + * Searching: + * + * In order for this library to be a good replacement for glibc's resolver it + * supports searching. This involves setting a list of default domains, in + * which names will be queried for. The number of dots in the query name + * determines the order in which this list is used. + * + * Searching appears to be a single lookup from the point of view of the API, + * although many DNS queries may be generated from a single call to + * evdns_resolve. Searching can also drastically slow down the resolution + * of names. + * + * To disable searching: + * 1. Never set it up. If you never call evdns_resolv_conf_parse or + * evdns_search_add then no searching will occur. + * + * 2. If you do call evdns_resolv_conf_parse then don't pass + * DNS_OPTION_SEARCH (or DNS_OPTIONS_ALL, which implies it). + * + * 3. When calling evdns_resolve, pass the DNS_QUERY_NO_SEARCH flag. + * + * The order of searches depends on the number of dots in the name. If the + * number is greater than the ndots setting then the names is first tried + * globally. Otherwise each search domain is appended in turn. + * + * The ndots setting can either be set from a resolv.conf, or by calling + * evdns_search_ndots_set. + * + * For example, with ndots set to 1 (the default) and a search domain list of + * ["myhome.net"]: + * + *
+ *  Query: www
+ *  Order: www.myhome.net, www.
+ *
+ *  Query: www.abc
+ *  Order: www.abc., www.abc.myhome.net
+ * 
+ * Internals: + * + * Requests are kept in two queues. The first is the inflight queue. In + * this queue requests have an allocated transaction id and nameserver. + * They will soon be transmitted if they haven't already been. + * + * The second is the waiting queue. The size of the inflight ring is + * limited and all other requests wait in waiting queue for space. This + * bounds the number of concurrent requests so that we don't flood the + * nameserver. Several algorithms require a full walk of the inflight + * queue and so bounding its size keeps thing going nicely under huge + * (many thousands of requests) loads. + * + * If a nameserver loses too many requests it is considered down and we + * try not to use it. After a while we send a probe to that nameserver + * (a lookup for google.com) and, if it replies, we consider it working + * again. If the nameserver fails a probe we wait longer to try again + * with the next probe. + */ + +#ifndef EVENT2_DNS_H_INCLUDED_ +#define EVENT2_DNS_H_INCLUDED_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* For integer types. */ +#include + +/** Error codes 0-5 are as described in RFC 1035. */ +#define DNS_ERR_NONE 0 +/** The name server was unable to interpret the query */ +#define DNS_ERR_FORMAT 1 +/** The name server was unable to process this query due to a problem with the + * name server */ +#define DNS_ERR_SERVERFAILED 2 +/** The domain name does not exist */ +#define DNS_ERR_NOTEXIST 3 +/** The name server does not support the requested kind of query */ +#define DNS_ERR_NOTIMPL 4 +/** The name server refuses to reform the specified operation for policy + * reasons */ +#define DNS_ERR_REFUSED 5 +/** The reply was truncated or ill-formatted */ +#define DNS_ERR_TRUNCATED 65 +/** An unknown error occurred */ +#define DNS_ERR_UNKNOWN 66 +/** Communication with the server timed out */ +#define DNS_ERR_TIMEOUT 67 +/** The request was canceled because the DNS subsystem was shut down. */ +#define DNS_ERR_SHUTDOWN 68 +/** The request was canceled via a call to evdns_cancel_request */ +#define DNS_ERR_CANCEL 69 +/** There were no answers and no error condition in the DNS packet. + * This can happen when you ask for an address that exists, but a record + * type that doesn't. */ +#define DNS_ERR_NODATA 70 + +#define DNS_IPv4_A 1 +#define DNS_PTR 2 +#define DNS_IPv6_AAAA 3 +#define DNS_CNAME 4 + +/** Disable searching for the query. */ +#define DNS_QUERY_NO_SEARCH 0x01 +/** Use TCP connections ("virtual circuits") for queries rather than UDP datagrams. */ +#define DNS_QUERY_USEVC 0x02 +/** Ignore trancation flag in responses (don't fallback to TCP connections). */ +#define DNS_QUERY_IGNTC 0x04 +/** Make a separate callback for CNAME in answer */ +#define DNS_CNAME_CALLBACK 0x80 + +/* Allow searching */ +#define DNS_OPTION_SEARCH 1 +/* Parse "nameserver" and add default if no such section */ +#define DNS_OPTION_NAMESERVERS 2 +/* Parse additional options like: + * - timeout: + * - getaddrinfo-allow-skew: + * - max-timeouts: + * - max-inflight: + * - attempts: + * - randomize-case: + * - initial-probe-timeout: + * - max-probe-timeout: + * - probe-backoff-factor: + * - tcp-idle-timeout: + * - edns-udp-size: + * - use-vc + * - ignore-tc + */ +#define DNS_OPTION_MISC 4 +/* Load hosts file (i.e. "/etc/hosts") */ +#define DNS_OPTION_HOSTSFILE 8 +/** + * All above: + * - DNS_OPTION_SEARCH + * - DNS_OPTION_NAMESERVERS + * - DNS_OPTION_MISC + * - DNS_OPTION_HOSTSFILE + */ +#define DNS_OPTIONS_ALL ( \ + DNS_OPTION_SEARCH | \ + DNS_OPTION_NAMESERVERS | \ + DNS_OPTION_MISC | \ + DNS_OPTION_HOSTSFILE | \ + 0 \ +) +/* Do not "default" nameserver (i.e. "127.0.0.1:53") if there is no nameservers + * in resolv.conf, (iff DNS_OPTION_NAMESERVERS is set) */ +#define DNS_OPTION_NAMESERVERS_NO_DEFAULT 16 + +/* Obsolete name for DNS_QUERY_NO_SEARCH */ +#define DNS_NO_SEARCH DNS_QUERY_NO_SEARCH + +/** + * The callback that contains the results from a lookup. + * - result is one of the DNS_ERR_* values (DNS_ERR_NONE for success) + * - type is either DNS_IPv4_A or DNS_PTR or DNS_IPv6_AAAA + * - count contains the number of addresses of form type + * - ttl is the number of seconds the resolution may be cached for. + * - addresses needs to be cast according to type. It will be an array of + * 4-byte sequences for ipv4, or an array of 16-byte sequences for ipv6, + * or a nul-terminated string for PTR. + */ +typedef void (*evdns_callback_type) (int result, char type, int count, int ttl, void *addresses, void *arg); + +struct evdns_base; +struct event_base; + +/** Flag for evdns_base_new: process resolv.conf. */ +#define EVDNS_BASE_INITIALIZE_NAMESERVERS 1 +/** Flag for evdns_base_new: Do not prevent the libevent event loop from + * exiting when we have no active dns requests. */ +#define EVDNS_BASE_DISABLE_WHEN_INACTIVE 0x8000 +/** Flag for evdns_base_new: If EVDNS_BASE_INITIALIZE_NAMESERVERS isset, do not + * add default nameserver if there are no nameservers in resolv.conf + * @see DNS_OPTION_NAMESERVERS_NO_DEFAULT */ +#define EVDNS_BASE_NAMESERVERS_NO_DEFAULT 0x10000 + +/** + Initialize the asynchronous DNS library. + + This function initializes support for non-blocking name resolution by + calling evdns_resolv_conf_parse() on UNIX and + evdns_config_windows_nameservers() on Windows. + + @param event_base the event base to associate the dns client with + @param initialize_nameservers any of EVDNS_BASE_INITIALIZE_NAMESERVERS| + EVDNS_BASE_DISABLE_WHEN_INACTIVE|EVDNS_BASE_NAMESERVERS_NO_DEFAULT + @return evdns_base object if successful, or NULL if an error occurred. + @see evdns_base_free() + */ +EVENT2_EXPORT_SYMBOL +struct evdns_base * evdns_base_new(struct event_base *event_base, int initialize_nameservers); + + +/** + Shut down the asynchronous DNS resolver and terminate all active requests. + + If the 'fail_requests' option is enabled, all active requests will return + an empty result with the error flag set to DNS_ERR_SHUTDOWN. Otherwise, + the requests will be silently discarded. + + @param base the evdns base to free + @param fail_requests if zero, active requests will be aborted; if non-zero, + active requests will return DNS_ERR_SHUTDOWN. + @see evdns_base_new() + */ +EVENT2_EXPORT_SYMBOL +void evdns_base_free(struct evdns_base *base, int fail_requests); + +/** + Remove all hosts entries that have been loaded into the event_base via + evdns_base_load_hosts or via event_base_resolv_conf_parse. + + @param base the evdns base to remove outdated host addresses from + */ +EVENT2_EXPORT_SYMBOL +void evdns_base_clear_host_addresses(struct evdns_base *base); + +/** + Convert a DNS error code to a string. + + @param err the DNS error code + @return a string containing an explanation of the error code +*/ +EVENT2_EXPORT_SYMBOL +const char *evdns_err_to_string(int err); + + +/** + Add a nameserver. + + The address should be an IPv4 address in network byte order. + The type of address is chosen so that it matches in_addr.s_addr. + + @param base the evdns_base to which to add the name server + @param address an IP address in network byte order + @return 0 if successful, or -1 if an error occurred + @see evdns_base_nameserver_ip_add() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_nameserver_add(struct evdns_base *base, + unsigned long int address); + +/** + Get the number of configured nameservers. + + This returns the number of configured nameservers (not necessarily the + number of running nameservers). This is useful for double-checking + whether our calls to the various nameserver configuration functions + have been successful. + + @param base the evdns_base to which to apply this operation + @return the number of configured nameservers + @see evdns_base_nameserver_add() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_count_nameservers(struct evdns_base *base); + +/** + Remove all configured nameservers, and suspend all pending resolves. + + Resolves will not necessarily be re-attempted until evdns_base_resume() is called. + + @param base the evdns_base to which to apply this operation + @return 0 if successful, or -1 if an error occurred + @see evdns_base_resume() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_clear_nameservers_and_suspend(struct evdns_base *base); + + +/** + Resume normal operation and continue any suspended resolve requests. + + Re-attempt resolves left in limbo after an earlier call to + evdns_base_clear_nameservers_and_suspend(). + + @param base the evdns_base to which to apply this operation + @return 0 if successful, or -1 if an error occurred + @see evdns_base_clear_nameservers_and_suspend() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_resume(struct evdns_base *base); + +/** + Add a nameserver by string address. + + This function parses a n IPv4 or IPv6 address from a string and adds it as a + nameserver. It supports the following formats: + - [IPv6Address]:port + - [IPv6Address] + - IPv6Address + - IPv4Address:port + - IPv4Address + + If no port is specified, it defaults to 53. + + @param base the evdns_base to which to apply this operation + @return 0 if successful, or -1 if an error occurred + @see evdns_base_nameserver_add() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_nameserver_ip_add(struct evdns_base *base, + const char *ip_as_string); + +/** + Add a nameserver by sockaddr. + **/ +EVENT2_EXPORT_SYMBOL +int +evdns_base_nameserver_sockaddr_add(struct evdns_base *base, + const struct sockaddr *sa, ev_socklen_t len, unsigned flags); + +struct evdns_request; + +/** + Lookup an A record for a given name. + + @param base the evdns_base to which to apply this operation + @param name a DNS hostname + @param flags either 0, or combination of DNS_QUERY_* flags. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return an evdns_request object if successful, or NULL if an error occurred. + @see evdns_resolve_ipv6(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6(), evdns_cancel_request() + */ +EVENT2_EXPORT_SYMBOL +struct evdns_request *evdns_base_resolve_ipv4(struct evdns_base *base, const char *name, int flags, evdns_callback_type callback, void *ptr); + +/** + Lookup an AAAA record for a given name. + + @param base the evdns_base to which to apply this operation + @param name a DNS hostname + @param flags either 0, or combination of DNS_QUERY_* flags. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return an evdns_request object if successful, or NULL if an error occurred. + @see evdns_resolve_ipv4(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6(), evdns_cancel_request() + */ +EVENT2_EXPORT_SYMBOL +struct evdns_request *evdns_base_resolve_ipv6(struct evdns_base *base, const char *name, int flags, evdns_callback_type callback, void *ptr); + +struct in_addr; +struct in6_addr; + +/** + Lookup a PTR record for a given IP address. + + @param base the evdns_base to which to apply this operation + @param in an IPv4 address + @param flags either 0, or combination of DNS_QUERY_* flags. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return an evdns_request object if successful, or NULL if an error occurred. + @see evdns_resolve_reverse_ipv6(), evdns_cancel_request() + */ +EVENT2_EXPORT_SYMBOL +struct evdns_request *evdns_base_resolve_reverse(struct evdns_base *base, const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr); + + +/** + Lookup a PTR record for a given IPv6 address. + + @param base the evdns_base to which to apply this operation + @param in an IPv6 address + @param flags either 0, or combination of DNS_QUERY_* flags. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return an evdns_request object if successful, or NULL if an error occurred. + @see evdns_resolve_reverse_ipv6(), evdns_cancel_request() + */ +EVENT2_EXPORT_SYMBOL +struct evdns_request *evdns_base_resolve_reverse_ipv6(struct evdns_base *base, const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr); + +/** + Cancels a pending DNS resolution request. + + @param base the evdns_base that was used to make the request + @param req the evdns_request that was returned by calling a resolve function + @see evdns_base_resolve_ipv4(), evdns_base_resolve_ipv6, evdns_base_resolve_reverse +*/ +EVENT2_EXPORT_SYMBOL +void evdns_cancel_request(struct evdns_base *base, struct evdns_request *req); + +/** + Set the value of a configuration option. + + The currently available configuration options are: + + ndots, timeout, max-timeouts, max-inflight, attempts, randomize-case, + bind-to, initial-probe-timeout, max-probe-timeout, probe-backoff-factor, + getaddrinfo-allow-skew, so-rcvbuf, so-sndbuf, tcp-idle-timeout, use-vc, + ignore-tc, edns-udp-size. + + - probe-backoff-factor + Backoff factor of probe timeout + + - max-probe-timeout + Maximum timeout between two probe packets will change initial-probe-timeout + when this value is smaller + + In versions before Libevent 2.0.3-alpha, the option name needed to end with + a colon. + + In case of options without values (use-vc, ingore-tc) val should be an empty + string or NULL. + + @param base the evdns_base to which to apply this operation + @param option the name of the configuration option to be modified + @param val the value to be set + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_set_option(struct evdns_base *base, const char *option, const char *val); + + +/** + Parse a resolv.conf file. + + The 'flags' parameter determines what information is parsed from the + resolv.conf file. See the man page for resolv.conf for the format of this + file. + + The following directives are not parsed from the file: sortlist, rotate, + no-check-names, inet6, debug. + + If this function encounters an error, the possible return values are: 1 = + failed to open file, 2 = failed to stat file, 3 = file too large, 4 = out of + memory, 5 = short read from file, 6 = no nameservers listed in the file + + @param base the evdns_base to which to apply this operation + @param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC| + DNS_OPTION_HOSTSFILE|DNS_OPTIONS_ALL|DNS_OPTION_NAMESERVERS_NO_DEFAULT + @param filename the path to the resolv.conf file + @return 0 if successful, or various positive error codes if an error + occurred (see above) + @see resolv.conf(3), evdns_config_windows_nameservers() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_resolv_conf_parse(struct evdns_base *base, int flags, const char *const filename); + +/** + Load an /etc/hosts-style file from 'hosts_fname' into 'base'. + + If hosts_fname is NULL, add minimal entries for localhost, and nothing + else. + + Note that only evdns_getaddrinfo uses the /etc/hosts entries. + + This function does not replace previously loaded hosts entries; to do that, + call evdns_base_clear_host_addresses first. + + Return 0 on success, negative on failure. +*/ +EVENT2_EXPORT_SYMBOL +int evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname); + +#if defined(EVENT_IN_DOXYGEN_) || defined(_WIN32) +/** + Obtain nameserver information using the Windows API. + + Attempt to configure a set of nameservers based on platform settings on + a win32 host. Preferentially tries to use GetNetworkParams; if that fails, + looks in the registry. + + @return 0 if successful, or -1 if an error occurred + @see evdns_resolv_conf_parse() + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_config_windows_nameservers(struct evdns_base *); +#define EVDNS_BASE_CONFIG_WINDOWS_NAMESERVERS_IMPLEMENTED +#endif + + +/** + Clear the list of search domains. + */ +EVENT2_EXPORT_SYMBOL +void evdns_base_search_clear(struct evdns_base *base); + + +/** + Add a domain to the list of search domains + + @param domain the domain to be added to the search list + */ +EVENT2_EXPORT_SYMBOL +void evdns_base_search_add(struct evdns_base *base, const char *domain); + + +/** + Set the 'ndots' parameter for searches. + + Sets the number of dots which, when found in a name, causes + the first query to be without any search domain. + + @param ndots the new ndots parameter + */ +EVENT2_EXPORT_SYMBOL +void evdns_base_search_ndots_set(struct evdns_base *base, const int ndots); + +/** + A callback that is invoked when a log message is generated + + @param is_warning indicates if the log message is a 'warning' + @param msg the content of the log message + */ +typedef void (*evdns_debug_log_fn_type)(int is_warning, const char *msg); + + +/** + Set the callback function to handle DNS log messages. If this + callback is not set, evdns log messages are handled with the regular + Libevent logging system. + + @param fn the callback to be invoked when a log message is generated + */ +EVENT2_EXPORT_SYMBOL +void evdns_set_log_fn(evdns_debug_log_fn_type fn); + +/* + * Functions used to implement a DNS server. + */ + +struct evdns_server_request; +struct evdns_server_question; + +/** + A callback to implement a DNS server. The callback function receives a DNS + request. It should then optionally add a number of answers to the reply + using the evdns_server_request_add_*_reply functions, before calling either + evdns_server_request_respond to send the reply back, or + evdns_server_request_drop to decline to answer the request. + + @param req A newly received request + @param user_data A pointer that was passed to + evdns_add_server_port_with_base(). + */ +typedef void (*evdns_request_callback_fn_type)(struct evdns_server_request *, void *); +#define EVDNS_ANSWER_SECTION 0 +#define EVDNS_AUTHORITY_SECTION 1 +#define EVDNS_ADDITIONAL_SECTION 2 + +#define EVDNS_TYPE_A 1 +#define EVDNS_TYPE_NS 2 +#define EVDNS_TYPE_CNAME 5 +#define EVDNS_TYPE_SOA 6 +#define EVDNS_TYPE_PTR 12 +#define EVDNS_TYPE_MX 15 +#define EVDNS_TYPE_TXT 16 +#define EVDNS_TYPE_AAAA 28 + +#define EVDNS_QTYPE_AXFR 252 +#define EVDNS_QTYPE_ALL 255 + +#define EVDNS_CLASS_INET 1 + +/* flags that can be set in answers; as part of the err parameter */ +#define EVDNS_FLAGS_AA 0x400 +#define EVDNS_FLAGS_RD 0x080 + +/** Create a new UDP DNS server port. + + @param base The event base to handle events for the server port. + @param socket A UDP socket to accept DNS requests. + @param flags Always 0 for now. + @param callback A function to invoke whenever we get a DNS request + on the socket. + @param user_data Data to pass to the callback. + @return an evdns_server_port structure for this server port or NULL if + an error occurred. + */ +EVENT2_EXPORT_SYMBOL +struct evdns_server_port *evdns_add_server_port_with_base(struct event_base *base, evutil_socket_t socket, int flags, evdns_request_callback_fn_type callback, void *user_data); + +struct evconnlistener; + +/** Create a new TCP DNS server port. + + @param base The event base to handle events for the server port. + @param listener A TCP listener to accept DNS requests. + @param flags Always 0 for now. + @param callback A function to invoke whenever we get a DNS request + on the socket. + @param user_data Data to pass to the callback. + @return an evdns_server_port structure for this server port or NULL if + an error occurred. + */ +EVENT2_EXPORT_SYMBOL +struct evdns_server_port *evdns_add_server_port_with_listener( + struct event_base *base, struct evconnlistener *listener, int flags, + evdns_request_callback_fn_type callback, void *user_data); + +/** Close down a DNS server port, and free associated structures. */ +EVENT2_EXPORT_SYMBOL +void evdns_close_server_port(struct evdns_server_port *port); + +/** + * List of configurable evdns_server_port options. + * + * @see evdns_server_port_set_option() + */ +enum evdns_server_option { + /** + * Maximum number of simultaneous tcp connections (clients) + * that server can hold. Can be set only for TCP DNS servers. + */ + EVDNS_SOPT_TCP_MAX_CLIENTS, + /** + * Idle timeout (in seconds) of incoming TCP connections. + * If client doesn't send any requests via the connection + * during this period connection is closed by the server. + * Can be set only for TCP DNS servers. + */ + EVDNS_SOPT_TCP_IDLE_TIMEOUT, +}; + +/** + Configure DNS server. + + @param port the evdns_server_port to which to apply this operation + @param option @see evdns_server_option for the list of possible options + @param val value of the option + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int evdns_server_port_set_option(struct evdns_server_port *port, enum evdns_server_option option, size_t value); + +/** Sets some flags in a reply we're building. + Allows setting of the AA or RD flags + */ +EVENT2_EXPORT_SYMBOL +void evdns_server_request_set_flags(struct evdns_server_request *req, int flags); + +/* Functions to add an answer to an in-progress DNS reply. + */ +EVENT2_EXPORT_SYMBOL +int evdns_server_request_add_reply(struct evdns_server_request *req, int section, const char *name, int type, int dns_class, int ttl, int datalen, int is_name, const char *data); +EVENT2_EXPORT_SYMBOL +int evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, const void *addrs, int ttl); +EVENT2_EXPORT_SYMBOL +int evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, const void *addrs, int ttl); +EVENT2_EXPORT_SYMBOL +int evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl); +EVENT2_EXPORT_SYMBOL +int evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl); + +/** + Send back a response to a DNS request, and free the request structure. +*/ +EVENT2_EXPORT_SYMBOL +int evdns_server_request_respond(struct evdns_server_request *req, int err); +/** + Free a DNS request without sending back a reply. +*/ +EVENT2_EXPORT_SYMBOL +int evdns_server_request_drop(struct evdns_server_request *req); +struct sockaddr; +/** + Get the address that made a DNS request. + */ +EVENT2_EXPORT_SYMBOL +int evdns_server_request_get_requesting_addr(struct evdns_server_request *req, struct sockaddr *sa, int addr_len); + +/** Callback for evdns_getaddrinfo. */ +typedef void (*evdns_getaddrinfo_cb)(int result, struct evutil_addrinfo *res, void *arg); + +struct evdns_base; +struct evdns_getaddrinfo_request; +/** Make a non-blocking getaddrinfo request using the dns_base in 'dns_base'. + * + * If we can answer the request immediately (with an error or not!), then we + * invoke cb immediately and return NULL. Otherwise we return + * an evdns_getaddrinfo_request and invoke cb later. + * + * When the callback is invoked, we pass as its first argument the error code + * that getaddrinfo would return (or 0 for no error). As its second argument, + * we pass the evutil_addrinfo structures we found (or NULL on error). We + * pass 'arg' as the third argument. + * + * Limitations: + * + * - The AI_V4MAPPED and AI_ALL flags are not currently implemented. + * - For ai_socktype, we only handle SOCKTYPE_STREAM, SOCKTYPE_UDP, and 0. + * - For ai_protocol, we only handle IPPROTO_TCP, IPPROTO_UDP, and 0. + */ +EVENT2_EXPORT_SYMBOL +struct evdns_getaddrinfo_request *evdns_getaddrinfo( + struct evdns_base *dns_base, + const char *nodename, const char *servname, + const struct evutil_addrinfo *hints_in, + evdns_getaddrinfo_cb cb, void *arg); + +/* Cancel an in-progress evdns_getaddrinfo. This MUST NOT be called after the + * getaddrinfo's callback has been invoked. The resolves will be canceled, + * and the callback will be invoked with the error EVUTIL_EAI_CANCEL. */ +EVENT2_EXPORT_SYMBOL +void evdns_getaddrinfo_cancel(struct evdns_getaddrinfo_request *req); + +/** + Retrieve the address of the 'idx'th configured nameserver. + + @param base The evdns_base to examine. + @param idx The index of the nameserver to get the address of. + @param sa A location to receive the server's address. + @param len The number of bytes available at sa. + + @return the number of bytes written into sa on success. On failure, returns + -1 if idx is greater than the number of configured nameservers, or a + value greater than 'len' if len was not high enough. + */ +EVENT2_EXPORT_SYMBOL +int evdns_base_get_nameserver_addr(struct evdns_base *base, int idx, + struct sockaddr *sa, ev_socklen_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* !EVENT2_DNS_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/dns_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/dns_compat.h new file mode 100644 index 00000000..ea002663 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/dns_compat.h @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2006-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_DNS_COMPAT_H_INCLUDED_ +#define EVENT2_DNS_COMPAT_H_INCLUDED_ + +/** @file event2/dns_compat.h + + @brief Potentially non-threadsafe versions of the functions in dns.h: provided + only for backwards compatibility. + + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include +#include + +/** + Initialize the asynchronous DNS library. + + This function initializes support for non-blocking name resolution by + calling evdns_resolv_conf_parse() on UNIX and + evdns_config_windows_nameservers() on Windows. + + @deprecated This function is deprecated because it always uses the current + event base, and is easily confused by multiple calls to event_init(), and + so is not safe for multithreaded use. Additionally, it allocates a global + structure that only one thread can use. The replacement is + evdns_base_new(). + + @return 0 if successful, or -1 if an error occurred + @see evdns_shutdown() + */ +EVENT2_EXPORT_SYMBOL +int evdns_init(void); + +struct evdns_base; +/** + Return the global evdns_base created by event_init() and used by the other + deprecated functions. + + @deprecated This function is deprecated because use of the global + evdns_base is error-prone. + */ +EVENT2_EXPORT_SYMBOL +struct evdns_base *evdns_get_global_base(void); + +/** + Shut down the asynchronous DNS resolver and terminate all active requests. + + If the 'fail_requests' option is enabled, all active requests will return + an empty result with the error flag set to DNS_ERR_SHUTDOWN. Otherwise, + the requests will be silently discarded. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_shutdown(). + + @param fail_requests if zero, active requests will be aborted; if non-zero, + active requests will return DNS_ERR_SHUTDOWN. + @see evdns_init() + */ +EVENT2_EXPORT_SYMBOL +void evdns_shutdown(int fail_requests); + +/** + Add a nameserver. + + The address should be an IPv4 address in network byte order. + The type of address is chosen so that it matches in_addr.s_addr. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_nameserver_add(). + + @param address an IP address in network byte order + @return 0 if successful, or -1 if an error occurred + @see evdns_nameserver_ip_add() + */ +EVENT2_EXPORT_SYMBOL +int evdns_nameserver_add(unsigned long int address); + +/** + Get the number of configured nameservers. + + This returns the number of configured nameservers (not necessarily the + number of running nameservers). This is useful for double-checking + whether our calls to the various nameserver configuration functions + have been successful. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_count_nameservers(). + + @return the number of configured nameservers + @see evdns_nameserver_add() + */ +EVENT2_EXPORT_SYMBOL +int evdns_count_nameservers(void); + +/** + Remove all configured nameservers, and suspend all pending resolves. + + Resolves will not necessarily be re-attempted until evdns_resume() is called. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_clear_nameservers_and_suspend(). + + @return 0 if successful, or -1 if an error occurred + @see evdns_resume() + */ +EVENT2_EXPORT_SYMBOL +int evdns_clear_nameservers_and_suspend(void); + +/** + Resume normal operation and continue any suspended resolve requests. + + Re-attempt resolves left in limbo after an earlier call to + evdns_clear_nameservers_and_suspend(). + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_resume(). + + @return 0 if successful, or -1 if an error occurred + @see evdns_clear_nameservers_and_suspend() + */ +EVENT2_EXPORT_SYMBOL +int evdns_resume(void); + +/** + Add a nameserver. + + This wraps the evdns_nameserver_add() function by parsing a string as an IP + address and adds it as a nameserver. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_nameserver_ip_add(). + + @return 0 if successful, or -1 if an error occurred + @see evdns_nameserver_add() + */ +EVENT2_EXPORT_SYMBOL +int evdns_nameserver_ip_add(const char *ip_as_string); + +/** + Lookup an A record for a given name. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_resolve_ipv4(). + + @param name a DNS hostname + @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return 0 if successful, or -1 if an error occurred + @see evdns_resolve_ipv6(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6() + */ +EVENT2_EXPORT_SYMBOL +int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr); + +/** + Lookup an AAAA record for a given name. + + @param name a DNS hostname + @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return 0 if successful, or -1 if an error occurred + @see evdns_resolve_ipv4(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6() + */ +EVENT2_EXPORT_SYMBOL +int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr); + +struct in_addr; +struct in6_addr; + +/** + Lookup a PTR record for a given IP address. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_resolve_reverse(). + + @param in an IPv4 address + @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return 0 if successful, or -1 if an error occurred + @see evdns_resolve_reverse_ipv6() + */ +EVENT2_EXPORT_SYMBOL +int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr); + +/** + Lookup a PTR record for a given IPv6 address. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_resolve_reverse_ipv6(). + + @param in an IPv6 address + @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query. + @param callback a callback function to invoke when the request is completed + @param ptr an argument to pass to the callback function + @return 0 if successful, or -1 if an error occurred + @see evdns_resolve_reverse_ipv6() + */ +EVENT2_EXPORT_SYMBOL +int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr); + +/** + Set the value of a configuration option. + + The currently available configuration options are: + + ndots, timeout, max-timeouts, max-inflight, and attempts + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_set_option(). + + @param option the name of the configuration option to be modified + @param val the value to be set + @param flags Ignored. + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int evdns_set_option(const char *option, const char *val, int flags); + +/** + Parse a resolv.conf file. + + The 'flags' parameter determines what information is parsed from the + resolv.conf file. See the man page for resolv.conf for the format of this + file. + + The following directives are not parsed from the file: sortlist, rotate, + no-check-names, inet6, debug. + + If this function encounters an error, the possible return values are: 1 = + failed to open file, 2 = failed to stat file, 3 = file too large, 4 = out of + memory, 5 = short read from file, 6 = no nameservers listed in the file + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_resolv_conf_parse(). + + @param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC| + DNS_OPTIONS_ALL + @param filename the path to the resolv.conf file + @return 0 if successful, or various positive error codes if an error + occurred (see above) + @see resolv.conf(3), evdns_config_windows_nameservers() + */ +EVENT2_EXPORT_SYMBOL +int evdns_resolv_conf_parse(int flags, const char *const filename); + +/** + Clear the list of search domains. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_search_clear(). + */ +EVENT2_EXPORT_SYMBOL +void evdns_search_clear(void); + +/** + Add a domain to the list of search domains + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_search_add(). + + @param domain the domain to be added to the search list + */ +EVENT2_EXPORT_SYMBOL +void evdns_search_add(const char *domain); + +/** + Set the 'ndots' parameter for searches. + + Sets the number of dots which, when found in a name, causes + the first query to be without any search domain. + + @deprecated This function is deprecated because it does not allow the + caller to specify which evdns_base it applies to. The recommended + function is evdns_base_search_ndots_set(). + + @param ndots the new ndots parameter + */ +EVENT2_EXPORT_SYMBOL +void evdns_search_ndots_set(const int ndots); + +/** + As evdns_server_new_with_base. + + @deprecated This function is deprecated because it does not allow the + caller to specify which even_base it uses. The recommended + function is evdns_add_server_port_with_base(). + +*/ +EVENT2_EXPORT_SYMBOL +struct evdns_server_port * +evdns_add_server_port(evutil_socket_t socket, int flags, + evdns_request_callback_fn_type callback, void *user_data); + +#ifdef _WIN32 +EVENT2_EXPORT_SYMBOL +int evdns_config_windows_nameservers(void); +#define EVDNS_CONFIG_WINDOWS_NAMESERVERS_IMPLEMENTED +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_EVENT_COMPAT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/dns_struct.h b/examples/proto_debuger/third/include/libevent/include/event2/dns_struct.h new file mode 100644 index 00000000..593a8a70 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/dns_struct.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_DNS_STRUCT_H_INCLUDED_ +#define EVENT2_DNS_STRUCT_H_INCLUDED_ + +/** @file event2/dns_struct.h + + Data structures for dns. Using these structures may hurt forward + compatibility with later versions of Libevent: be careful! + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +/* + * Structures used to implement a DNS server. + */ + +struct evdns_server_request { + int flags; + int nquestions; + struct evdns_server_question **questions; +}; +struct evdns_server_question { + int type; +#ifdef __cplusplus + int dns_question_class; +#else + /* You should refer to this field as "dns_question_class". The + * name "class" works in C for backward compatibility, and will be + * removed in a future version. (1.5 or later). */ + int class; +#define dns_question_class class +#endif + char name[1]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_DNS_STRUCT_H_INCLUDED_ */ + diff --git a/examples/proto_debuger/third/include/libevent/include/event2/event-config.h b/examples/proto_debuger/third/include/libevent/include/event2/event-config.h new file mode 100644 index 00000000..e6ed3aa4 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/event-config.h @@ -0,0 +1,360 @@ +/* event2/event-config.h + * + * This file was generated by autoconf when libevent was built, and post- + * processed by Libevent so that its macros would have a uniform prefix. + * + * DO NOT EDIT THIS FILE. + * + * Do not rely on macros in this file existing in later versions. + */ +#ifndef EVENT_CONFIG_H__ +#define EVENT_CONFIG_H__ +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define if libevent should not allow replacing the mm functions */ +/* #undef EVENT__DISABLE_MM_REPLACEMENT */ + +/* Define if libevent should not be compiled with thread support */ +/* #undef EVENT__DISABLE_THREAD_SUPPORT */ + +/* Define if clock_gettime is available in libc */ +/* #undef _EVENT_DNS_USE_CPU_CLOCK_FOR_ID */ + +/* Define is no secure id variant is available */ +/* #define _EVENT_DNS_USE_GETTIMEOFDAY_FOR_ID 1 */ +#define EVENT_DNS_USE_FTIME_FOR_ID_ 1 + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_ARPA_INET_H */ + +/* Define to 1 if you have the `clock_gettime' function. */ +/* #undef EVENT__HAVE_CLOCK_GETTIME */ + +/* Define if /dev/poll is available */ +/* #undef EVENT__HAVE_DEVPOLL */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_DLFCN_H */ + +/* Define if your system supports the epoll system calls */ +/* #undef EVENT__HAVE_EPOLL */ + +/* Define to 1 if you have the `epoll_ctl' function. */ +/* #undef EVENT__HAVE_EPOLL_CTL */ + +/* Define to 1 if you have the `eventfd' function. */ +/* #undef EVENT__HAVE_EVENTFD */ + +/* Define if your system supports event ports */ +/* #undef EVENT__HAVE_EVENT_PORTS */ + +/* Define to 1 if you have the `fcntl' function. */ +/* #undef EVENT__HAVE_FCNTL */ + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +#define EVENT__HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `getnameinfo' function. */ +#define EVENT__HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getprotobynumber' function. */ +#define EVENT__HAVE_GETPROTOBYNUMBER 1 + +/* Define to 1 if you have the `getservbyname' function. */ +#define EVENT__HAVE_GETSERVBYNAME 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +/* #define EVENT__HAVE_GETTIMEOFDAY 1 */ + +/* Define to 1 if you have the `inet_ntop' function. */ +/* #undef EVENT__HAVE_INET_NTOP */ + +/* Define to 1 if you have the `inet_pton' function. */ +/* #undef EVENT__HAVE_INET_PTON */ + +/* Define to 1 if you have the header file. */ +/* #define EVENT__HAVE_INTTYPES_H 1 */ + +/* Define to 1 if you have the `kqueue' function. */ +/* #undef EVENT__HAVE_KQUEUE */ + +/* Define if the system has zlib */ +/* #undef EVENT__HAVE_LIBZ */ + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mmap' function. */ +/* #undef EVENT__HAVE_MMAP */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_NETINET_IN6_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_NETINET_IN_H */ + +/* Define to 1 if you have the `pipe' function. */ +/* #undef EVENT__HAVE_PIPE */ + +/* Define to 1 if you have the `poll' function. */ +/* #undef EVENT__HAVE_POLL */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_POLL_H */ + +/* Define to 1 if you have the `port_create' function. */ +/* #undef EVENT__HAVE_PORT_CREATE */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_PORT_H */ + +/* Define if you have POSIX threads libraries and header files. */ +/* #undef EVENT__HAVE_PTHREAD */ + +/* Define if we have pthreads on this system */ +/* #undef EVENT__HAVE_PTHREADS */ + +/* Define to 1 if the system has the type `sa_family_t'. */ +/* #undef EVENT__HAVE_SA_FAMILY_T */ + +/* Define to 1 if you have the `select' function. */ +/* #undef EVENT__HAVE_SELECT */ + +/* Define to 1 if you have the `sendfile' function. */ +/* #undef EVENT__HAVE_SENDFILE */ + +/* Define if F_SETFD is defined in */ +/* #undef EVENT__HAVE_SETFD */ + +/* Define to 1 if you have the `sigaction' function. */ +/* #undef EVENT__HAVE_SIGACTION */ + +/* Define to 1 if you have the `signal' function. */ +#define EVENT__HAVE_SIGNAL 1 + +/* Define to 1 if you have the `splice' function. */ +/* #undef EVENT__HAVE_SPLICE */ + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDARG_H 1 + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +/* #define EVENT__HAVE_STDINT_H 1 */ + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef EVENT__HAVE_STRLCPY */ + +/* Define to 1 if you have the `strsep' function. */ +/* #undef EVENT__HAVE_STRSEP */ + +/* Define to 1 if you have the `strtok_r' function. */ +/* #undef EVENT__HAVE_STRTOK_R */ + +/* Define to 1 if you have the `strtoll' function. */ +/* #define EVENT__HAVE_STRTOLL 1 */ + +#define EVENT__HAVE_STRUCT_ADDRINFO 1 + +/* Define to 1 if the system has the type `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR 1 + +/* Define to 1 if `s6_addr16' is member of `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1 + +/* Define to 1 if `s6_addr32' is member of `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1 + +/* Define to 1 if the system has the type `struct sockaddr_in6'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1 + +/* Define to 1 if `sin6_len' is member of `struct sockaddr_in6'. */ +/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */ + +/* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */ +/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_DEVPOLL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_EPOLL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_EVENTFD_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_EVENT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_IOCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_MMAN_H */ + +/* Define to 1 if you have the header file. */ +/* #define EVENT__HAVE_SYS_PARAM_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_QUEUE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_SENDFILE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_SOCKET_H */ + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #define EVENT__HAVE_SYS_TIME_H 1 */ + +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_UIO_H */ + +/* Define if TAILQ_FOREACH is defined in */ +/* #undef EVENT__HAVE_TAILQFOREACH */ + +/* Define if timeradd is defined in */ +/* #undef EVENT__HAVE_TIMERADD */ + +/* Define if timerclear is defined in */ +#define EVENT__HAVE_TIMERCLEAR 1 + +/* Define if timercmp is defined in */ +#define EVENT__HAVE_TIMERCMP 1 + +/* Define if timerisset is defined in */ +#define EVENT__HAVE_TIMERISSET 1 + +/* Define to 1 if the system has the type `uint16_t'. */ +/* #define EVENT__HAVE_UINT16_T 1 */ + +/* Define to 1 if the system has the type `uint32_t'. */ +/* #define EVENT__HAVE_UINT32_T 1 */ + +/* Define to 1 if the system has the type `uint64_t'. */ +/* #define EVENT__HAVE_UINT64_T 1 */ + +/* Define to 1 if the system has the type `uint8_t'. */ +/* #define EVENT__HAVE_UINT8_T 1 */ + +/* Define to 1 if you have the header file. */ +/* #define EVENT__HAVE_UNISTD_H 1 */ + +/* Define to 1 if you have the `vasprintf' function. */ +/* #undef EVENT__HAVE_VASPRINTF */ + +/* Define if kqueue works correctly with pipes */ +/* #undef EVENT__HAVE_WORKING_KQUEUE */ + +/* Numeric representation of the version */ +#define EVENT__NUMERIC_VERSION 0x02010800 + +/* Name of package */ +#define EVENT__PACKAGE "libevent" + +/* Define to the address where bug reports for this package should be sent. */ +#define EVENT__PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define EVENT__PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define EVENT__PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define EVENT__PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define EVENT__PACKAGE_VERSION "" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef EVENT__PTHREAD_CREATE_JOINABLE */ + +/* The size of a `int', as computed by sizeof. */ +#define EVENT__SIZEOF_INT 4 + +/* The size of a `long', as computed by sizeof. */ +#define EVENT__SIZEOF_LONG 4 + +/* The size of a `long long', as computed by sizeof. */ +#define EVENT__SIZEOF_LONG_LONG 8 + +/* The size of a `short', as computed by sizeof. */ +#define EVENT__SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#ifdef _WIN64 +#define EVENT__SIZEOF_SIZE_T 8 +#else +#define EVENT__SIZEOF_SIZE_T 4 +#endif + +/* The size of `void *', as computed by sizeof. */ +#ifdef _WIN64 +#define EVENT__SIZEOF_VOID_P 8 +#else +#define EVENT__SIZEOF_VOID_P 4 +#endif + +/* Define to 1 if you have the ANSI C header files. */ +#define EVENT__STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define EVENT__TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define EVENT__VERSION "2.1.8-stable" + +/* Define to appropriate substitue if compiler doesnt have __func__ */ +#define EVENT____func__ __FUNCTION__ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef EVENT__const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef _EVENT___cplusplus +#define EVENT__inline __inline +#endif + +/* Define to `int' if does not define. */ +/* #undef EVENT__pid_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef EVENT__size_t */ + +/* Define to unsigned int if you dont have it */ +#define EVENT__socklen_t unsigned int + +/* Define to `int' if does not define. */ +#define EVENT__ssize_t SSIZE_T + +#endif diff --git a/examples/proto_debuger/third/include/libevent/include/event2/event.h b/examples/proto_debuger/third/include/libevent/include/event2/event.h new file mode 100644 index 00000000..e7513e54 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/event.h @@ -0,0 +1,1685 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_EVENT_H_INCLUDED_ +#define EVENT2_EVENT_H_INCLUDED_ + +/** + @mainpage + + @section intro Introduction + + Libevent is an event notification library for developing scalable network + servers. The Libevent API provides a mechanism to execute a callback + function when a specific event occurs on a file descriptor or after a + timeout has been reached. Furthermore, Libevent also support callbacks due + to signals or regular timeouts. + + Libevent is meant to replace the event loop found in event driven network + servers. An application just needs to call event_base_dispatch() and then add or + remove events dynamically without having to change the event loop. + + + Currently, Libevent supports /dev/poll, kqueue(2), select(2), poll(2), + epoll(4), and evports. The internal event mechanism is completely + independent of the exposed event API, and a simple update of Libevent can + provide new functionality without having to redesign the applications. As a + result, Libevent allows for portable application development and provides + the most scalable event notification mechanism available on an operating + system. Libevent can also be used for multithreaded programs. Libevent + should compile on Linux, *BSD, Mac OS X, Solaris and, Windows. + + @section usage Standard usage + + Every program that uses Libevent must include the + header, and pass the -levent flag to the linker. (You can instead link + -levent_core if you only want the main event and buffered IO-based code, + and don't want to link any protocol code.) + + @section setup Library setup + + Before you call any other Libevent functions, you need to set up the + library. If you're going to use Libevent from multiple threads in a + multithreaded application, you need to initialize thread support -- + typically by using evthread_use_pthreads() or + evthread_use_windows_threads(). See for more + information. + + This is also the point where you can replace Libevent's memory + management functions with event_set_mem_functions, and enable debug mode + with event_enable_debug_mode(). + + @section base Creating an event base + + Next, you need to create an event_base structure, using event_base_new() + or event_base_new_with_config(). The event_base is responsible for + keeping track of which events are "pending" (that is to say, being + watched to see if they become active) and which events are "active". + Every event is associated with a single event_base. + + @section event Event notification + + For each file descriptor that you wish to monitor, you must create an + event structure with event_new(). (You may also declare an event + structure and call event_assign() to initialize the members of the + structure.) To enable notification, you add the structure to the list + of monitored events by calling event_add(). The event structure must + remain allocated as long as it is active, so it should generally be + allocated on the heap. + + @section loop Dispatching events. + + Finally, you call event_base_dispatch() to loop and dispatch events. + You can also use event_base_loop() for more fine-grained control. + + Currently, only one thread can be dispatching a given event_base at a + time. If you want to run events in multiple threads at once, you can + either have a single event_base whose events add work to a work queue, + or you can create multiple event_base objects. + + @section bufferevent I/O Buffers + + Libevent provides a buffered I/O abstraction on top of the regular event + callbacks. This abstraction is called a bufferevent. A bufferevent + provides input and output buffers that get filled and drained + automatically. The user of a buffered event no longer deals directly + with the I/O, but instead is reading from input and writing to output + buffers. + + Once initialized via bufferevent_socket_new(), the bufferevent structure + can be used repeatedly with bufferevent_enable() and + bufferevent_disable(). Instead of reading and writing directly to a + socket, you would call bufferevent_read() and bufferevent_write(). + + When read enabled the bufferevent will try to read from the file descriptor + and call the read callback. The write callback is executed whenever the + output buffer is drained below the write low watermark, which is 0 by + default. + + See for more information. + + @section timers Timers + + Libevent can also be used to create timers that invoke a callback after a + certain amount of time has expired. The evtimer_new() macro returns + an event struct to use as a timer. To activate the timer, call + evtimer_add(). Timers can be deactivated by calling evtimer_del(). + (These macros are thin wrappers around event_new(), event_add(), + and event_del(); you can also use those instead.) + + @section evdns Asynchronous DNS resolution + + Libevent provides an asynchronous DNS resolver that should be used instead + of the standard DNS resolver functions. See the + functions for more detail. + + @section evhttp Event-driven HTTP servers + + Libevent provides a very simple event-driven HTTP server that can be + embedded in your program and used to service HTTP requests. + + To use this capability, you need to include the header in your + program. See that header for more information. + + @section evrpc A framework for RPC servers and clients + + Libevent provides a framework for creating RPC servers and clients. It + takes care of marshaling and unmarshaling all data structures. + + @section api API Reference + + To browse the complete documentation of the libevent API, click on any of + the following links. + + event2/event.h + The primary libevent header + + event2/thread.h + Functions for use by multithreaded programs + + event2/buffer.h and event2/bufferevent.h + Buffer management for network reading and writing + + event2/util.h + Utility functions for portable nonblocking network code + + event2/dns.h + Asynchronous DNS resolution + + event2/http.h + An embedded libevent-based HTTP server + + event2/rpc.h + A framework for creating RPC servers and clients + + event2/watch.h + "Prepare" and "check" watchers. + */ + +/** @file event2/event.h + + @brief Core functions for waiting for and receiving events, and using event bases. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +#include + +/* For int types. */ +#include + +/** + * Structure to hold information and state for a Libevent dispatch loop. + * + * The event_base lies at the center of Libevent; every application will + * have one. It keeps track of all pending and active events, and + * notifies your application of the active ones. + * + * This is an opaque structure; you can allocate one using + * event_base_new() or event_base_new_with_config(). + * + * @see event_base_new(), event_base_free(), event_base_loop(), + * event_base_new_with_config() + */ +struct event_base +#ifdef EVENT_IN_DOXYGEN_ +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +/** + * Structure to represent a single event. + * + * An event can have some underlying condition it represents: a socket + * becoming readable or writeable (or both), or a signal becoming raised. + * (An event that represents no underlying condition is still useful: you + * can use one to implement a timer, or to communicate between threads.) + * + * Generally, you can create events with event_new(), then make them + * pending with event_add(). As your event_base runs, it will run the + * callbacks of an events whose conditions are triggered. When you no + * longer want the event, free it with event_free(). + * + * In more depth: + * + * An event may be "pending" (one whose condition we are watching), + * "active" (one whose condition has triggered and whose callback is about + * to run), neither, or both. Events come into existence via + * event_assign() or event_new(), and are then neither active nor pending. + * + * To make an event pending, pass it to event_add(). When doing so, you + * can also set a timeout for the event. + * + * Events become active during an event_base_loop() call when either their + * condition has triggered, or when their timeout has elapsed. You can + * also activate an event manually using event_active(). The even_base + * loop will run the callbacks of active events; after it has done so, it + * marks them as no longer active. + * + * You can make an event non-pending by passing it to event_del(). This + * also makes the event non-active. + * + * Events can be "persistent" or "non-persistent". A non-persistent event + * becomes non-pending as soon as it is triggered: thus, it only runs at + * most once per call to event_add(). A persistent event remains pending + * even when it becomes active: you'll need to event_del() it manually in + * order to make it non-pending. When a persistent event with a timeout + * becomes active, its timeout is reset: this means you can use persistent + * events to implement periodic timeouts. + * + * This should be treated as an opaque structure; you should never read or + * write any of its fields directly. For backward compatibility with old + * code, it is defined in the event2/event_struct.h header; including this + * header may make your code incompatible with other versions of Libevent. + * + * @see event_new(), event_free(), event_assign(), event_get_assignment(), + * event_add(), event_del(), event_active(), event_pending(), + * event_get_fd(), event_get_base(), event_get_events(), + * event_get_callback(), event_get_callback_arg(), + * event_priority_set() + */ +struct event +#ifdef EVENT_IN_DOXYGEN_ +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +/** + * Configuration for an event_base. + * + * There are many options that can be used to alter the behavior and + * implementation of an event_base. To avoid having to pass them all in a + * complex many-argument constructor, we provide an abstract data type + * where you set up configuration information before passing it to + * event_base_new_with_config(). + * + * @see event_config_new(), event_config_free(), event_base_new_with_config(), + * event_config_avoid_method(), event_config_require_features(), + * event_config_set_flag(), event_config_set_num_cpus_hint() + */ +struct event_config +#ifdef EVENT_IN_DOXYGEN_ +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +/** + * Enable some relatively expensive debugging checks in Libevent that + * would normally be turned off. Generally, these checks cause code that + * would otherwise crash mysteriously to fail earlier with an assertion + * failure. Note that this method MUST be called before any events or + * event_bases have been created. + * + * Debug mode can currently catch the following errors: + * An event is re-assigned while it is added + * Any function is called on a non-assigned event + * + * Note that debugging mode uses memory to track every event that has been + * initialized (via event_assign, event_set, or event_new) but not yet + * released (via event_free or event_debug_unassign). If you want to use + * debug mode, and you find yourself running out of memory, you will need + * to use event_debug_unassign to explicitly stop tracking events that + * are no longer considered set-up. + * + * @see event_debug_unassign() + */ +EVENT2_EXPORT_SYMBOL +void event_enable_debug_mode(void); + +/** + * When debugging mode is enabled, informs Libevent that an event should no + * longer be considered as assigned. When debugging mode is not enabled, does + * nothing. + * + * This function must only be called on a non-added event. + * + * @see event_enable_debug_mode() + */ +EVENT2_EXPORT_SYMBOL +void event_debug_unassign(struct event *); + +/** + * Create and return a new event_base to use with the rest of Libevent. + * + * @return a new event_base on success, or NULL on failure. + * + * @see event_base_free(), event_base_new_with_config() + */ +EVENT2_EXPORT_SYMBOL +struct event_base *event_base_new(void); + +/** + Reinitialize the event base after a fork + + Some event mechanisms do not survive across fork. The event base needs + to be reinitialized with the event_reinit() function. + + @param base the event base that needs to be re-initialized + @return 0 if successful, or -1 if some events could not be re-added. + @see event_base_new() +*/ +EVENT2_EXPORT_SYMBOL +int event_reinit(struct event_base *base); + +/** + Event dispatching loop + + This loop will run the event base until either there are no more pending or + active, or until something calls event_base_loopbreak() or + event_base_loopexit(). + + @param base the event_base structure returned by event_base_new() or + event_base_new_with_config() + @return 0 if successful, -1 if an error occurred, or 1 if we exited because + no events were pending or active. + @see event_base_loop() + */ +EVENT2_EXPORT_SYMBOL +int event_base_dispatch(struct event_base *base); + +/** + Get the kernel event notification mechanism used by Libevent. + + @param eb the event_base structure returned by event_base_new() + @return a string identifying the kernel event mechanism (kqueue, epoll, etc.) + */ +EVENT2_EXPORT_SYMBOL +const char *event_base_get_method(const struct event_base *eb); + +/** + Gets all event notification mechanisms supported by Libevent. + + This functions returns the event mechanism in order preferred by + Libevent. Note that this list will include all backends that + Libevent has compiled-in support for, and will not necessarily check + your OS to see whether it has the required resources. + + @return an array with pointers to the names of support methods. + The end of the array is indicated by a NULL pointer. If an + error is encountered NULL is returned. +*/ +EVENT2_EXPORT_SYMBOL +const char **event_get_supported_methods(void); + +/** Query the current monotonic time from a the timer for a struct + * event_base. + */ +EVENT2_EXPORT_SYMBOL +int event_gettime_monotonic(struct event_base *base, struct timeval *tp); + +/** + @name event type flag + + Flags to pass to event_base_get_num_events() to specify the kinds of events + we want to aggregate counts for +*/ +/**@{*/ +/** count the number of active events, which have been triggered.*/ +#define EVENT_BASE_COUNT_ACTIVE 1U +/** count the number of virtual events, which is used to represent an internal + * condition, other than a pending event, that keeps the loop from exiting. */ +#define EVENT_BASE_COUNT_VIRTUAL 2U +/** count the number of events which have been added to event base, including + * internal events. */ +#define EVENT_BASE_COUNT_ADDED 4U +/**@}*/ + +/** + Gets the number of events in event_base, as specified in the flags. + + Since event base has some internal events added to make some of its + functionalities work, EVENT_BASE_COUNT_ADDED may return more than the + number of events you added using event_add(). + + If you pass EVENT_BASE_COUNT_ACTIVE and EVENT_BASE_COUNT_ADDED together, an + active event will be counted twice. However, this might not be the case in + future libevent versions. The return value is an indication of the work + load, but the user shouldn't rely on the exact value as this may change in + the future. + + @param eb the event_base structure returned by event_base_new() + @param flags a bitwise combination of the kinds of events to aggregate + counts for + @return the number of events specified in the flags +*/ +EVENT2_EXPORT_SYMBOL +int event_base_get_num_events(struct event_base *eb, unsigned int flags); + +/** + Get the maximum number of events in a given event_base as specified in the + flags. + + @param eb the event_base structure returned by event_base_new() + @param flags a bitwise combination of the kinds of events to aggregate + counts for + @param clear option used to reset the maximum count. + @return the number of events specified in the flags + */ +EVENT2_EXPORT_SYMBOL +int event_base_get_max_events(struct event_base *eb, unsigned int flags, int clear); + +/** + Allocates a new event configuration object. + + The event configuration object can be used to change the behavior of + an event base. + + @return an event_config object that can be used to store configuration, or + NULL if an error is encountered. + @see event_base_new_with_config(), event_config_free(), event_config +*/ +EVENT2_EXPORT_SYMBOL +struct event_config *event_config_new(void); + +/** + Deallocates all memory associated with an event configuration object + + @param cfg the event configuration object to be freed. +*/ +EVENT2_EXPORT_SYMBOL +void event_config_free(struct event_config *cfg); + +/** + Enters an event method that should be avoided into the configuration. + + This can be used to avoid event mechanisms that do not support certain + file descriptor types, or for debugging to avoid certain event + mechanisms. An application can make use of multiple event bases to + accommodate incompatible file descriptor types. + + @param cfg the event configuration object + @param method the name of the event method to avoid + @return 0 on success, -1 on failure. +*/ +EVENT2_EXPORT_SYMBOL +int event_config_avoid_method(struct event_config *cfg, const char *method); + +/** + A flag used to describe which features an event_base (must) provide. + + Because of OS limitations, not every Libevent backend supports every + possible feature. You can use this type with + event_config_require_features() to tell Libevent to only proceed if your + event_base implements a given feature, and you can receive this type from + event_base_get_features() to see which features are available. +*/ +enum event_method_feature { + /** Require an event method that allows edge-triggered events with EV_ET. */ + EV_FEATURE_ET = 0x01, + /** Require an event method where having one event triggered among + * many is [approximately] an O(1) operation. This excludes (for + * example) select and poll, which are approximately O(N) for N + * equal to the total number of possible events. */ + EV_FEATURE_O1 = 0x02, + /** Require an event method that allows file descriptors as well as + * sockets. */ + EV_FEATURE_FDS = 0x04, + /** Require an event method that allows you to use EV_CLOSED to detect + * connection close without the necessity of reading all the pending data. + * + * Methods that do support EV_CLOSED may not be able to provide support on + * all kernel versions. + **/ + EV_FEATURE_EARLY_CLOSE = 0x08 +}; + +/** + A flag passed to event_config_set_flag(). + + These flags change the behavior of an allocated event_base. + + @see event_config_set_flag(), event_base_new_with_config(), + event_method_feature + */ +enum event_base_config_flag { + /** Do not allocate a lock for the event base, even if we have + locking set up. + + Setting this option will make it unsafe and nonfunctional to call + functions on the base concurrently from multiple threads. + */ + EVENT_BASE_FLAG_NOLOCK = 0x01, + /** Do not check the EVENT_* environment variables when configuring + an event_base */ + EVENT_BASE_FLAG_IGNORE_ENV = 0x02, + /** Windows only: enable the IOCP dispatcher at startup + + If this flag is set then bufferevent_socket_new() and + evconn_listener_new() will use IOCP-backed implementations + instead of the usual select-based one on Windows. + */ + EVENT_BASE_FLAG_STARTUP_IOCP = 0x04, + /** Instead of checking the current time every time the event loop is + ready to run timeout callbacks, check after each timeout callback. + */ + EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08, + + /** If we are using the epoll backend, this flag says that it is + safe to use Libevent's internal change-list code to batch up + adds and deletes in order to try to do as few syscalls as + possible. Setting this flag can make your code run faster, but + it may trigger a Linux bug: it is not safe to use this flag + if you have any fds cloned by dup() or its variants. Doing so + will produce strange and hard-to-diagnose bugs. + + This flag can also be activated by setting the + EVENT_EPOLL_USE_CHANGELIST environment variable. + + This flag has no effect if you wind up using a backend other than + epoll. + */ + EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10, + + /** Ordinarily, Libevent implements its time and timeout code using + the fastest monotonic timer that we have. If this flag is set, + however, we use less efficient more precise timer, assuming one is + present. + */ + EVENT_BASE_FLAG_PRECISE_TIMER = 0x20, + + /** With EVENT_BASE_FLAG_PRECISE_TIMER, + epoll backend will use timerfd for more accurate timers, this will + allows to disable this. + + That said that this is something in between lack of + (CLOCK_MONOTONIC_COARSE) and enabled EVENT_BASE_FLAG_PRECISE_TIMER + (CLOCK_MONOTONIC + timerfd). + + This flag has no effect if you wind up using a backend other than + epoll and if you do not have EVENT_BASE_FLAG_PRECISE_TIMER enabled. + */ + EVENT_BASE_FLAG_EPOLL_DISALLOW_TIMERFD = 0x40, +}; + +/** + Return a bitmask of the features implemented by an event base. This + will be a bitwise OR of one or more of the values of + event_method_feature + + @see event_method_feature + */ +EVENT2_EXPORT_SYMBOL +int event_base_get_features(const struct event_base *base); + +/** + Enters a required event method feature that the application demands. + + Note that not every feature or combination of features is supported + on every platform. Code that requests features should be prepared + to handle the case where event_base_new_with_config() returns NULL, as in: +
+     event_config_require_features(cfg, EV_FEATURE_ET);
+     base = event_base_new_with_config(cfg);
+     if (base == NULL) {
+       // We can't get edge-triggered behavior here.
+       event_config_require_features(cfg, 0);
+       base = event_base_new_with_config(cfg);
+     }
+   
+ + @param cfg the event configuration object + @param feature a bitfield of one or more event_method_feature values. + Replaces values from previous calls to this function. + @return 0 on success, -1 on failure. + @see event_method_feature, event_base_new_with_config() +*/ +EVENT2_EXPORT_SYMBOL +int event_config_require_features(struct event_config *cfg, int feature); + +/** + * Sets one or more flags to configure what parts of the eventual event_base + * will be initialized, and how they'll work. + * + * @see event_base_config_flags, event_base_new_with_config() + **/ +EVENT2_EXPORT_SYMBOL +int event_config_set_flag(struct event_config *cfg, int flag); + +/** + * Records a hint for the number of CPUs in the system. This is used for + * tuning thread pools, etc, for optimal performance. In Libevent 2.0, + * it is only on Windows, and only when IOCP is in use. + * + * @param cfg the event configuration object + * @param cpus the number of cpus + * @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus); + +/** + * Record an interval and/or a number of callbacks after which the event base + * should check for new events. By default, the event base will run as many + * events are as activated at the highest activated priority before checking + * for new events. If you configure it by setting max_interval, it will check + * the time after each callback, and not allow more than max_interval to + * elapse before checking for new events. If you configure it by setting + * max_callbacks to a value >= 0, it will run no more than max_callbacks + * callbacks before checking for new events. + * + * This option can decrease the latency of high-priority events, and + * avoid priority inversions where multiple low-priority events keep us from + * polling for high-priority events, but at the expense of slightly decreasing + * the throughput. Use it with caution! + * + * @param cfg The event_base configuration object. + * @param max_interval An interval after which Libevent should stop running + * callbacks and check for more events, or NULL if there should be + * no such interval. + * @param max_callbacks A number of callbacks after which Libevent should + * stop running callbacks and check for more events, or -1 if there + * should be no such limit. + * @param min_priority A priority below which max_interval and max_callbacks + * should not be enforced. If this is set to 0, they are enforced + * for events of every priority; if it's set to 1, they're enforced + * for events of priority 1 and above, and so on. + * @return 0 on success, -1 on failure. + **/ +EVENT2_EXPORT_SYMBOL +int event_config_set_max_dispatch_interval(struct event_config *cfg, + const struct timeval *max_interval, int max_callbacks, + int min_priority); + +/** + Initialize the event API. + + Use event_base_new_with_config() to initialize a new event base, taking + the specified configuration under consideration. The configuration object + can currently be used to avoid certain event notification mechanisms. + + @param cfg the event configuration object + @return an initialized event_base that can be used to registering events, + or NULL if no event base can be created with the requested event_config. + @see event_base_new(), event_base_free(), event_init(), event_assign() +*/ +EVENT2_EXPORT_SYMBOL +struct event_base *event_base_new_with_config(const struct event_config *cfg); + +/** + Deallocate all memory associated with an event_base, and free the base. + + Note that this function will not close any fds or free any memory passed + to event_new as the argument to callback. + + If there are any pending finalizer callbacks, this function will invoke + them. + + @param eb an event_base to be freed + */ +EVENT2_EXPORT_SYMBOL +void event_base_free(struct event_base *eb); + +/** + As event_base_free, but do not run finalizers. + */ +EVENT2_EXPORT_SYMBOL +void event_base_free_nofinalize(struct event_base *); + +/** @name Log severities + */ +/**@{*/ +#define EVENT_LOG_DEBUG 0 +#define EVENT_LOG_MSG 1 +#define EVENT_LOG_WARN 2 +#define EVENT_LOG_ERR 3 +/**@}*/ + +/* Obsolete names: these are deprecated, but older programs might use them. + * They violate the reserved-identifier namespace. */ +#define _EVENT_LOG_DEBUG EVENT_LOG_DEBUG +#define _EVENT_LOG_MSG EVENT_LOG_MSG +#define _EVENT_LOG_WARN EVENT_LOG_WARN +#define _EVENT_LOG_ERR EVENT_LOG_ERR + +/** + A callback function used to intercept Libevent's log messages. + + @see event_set_log_callback + */ +typedef void (*event_log_cb)(int severity, const char *msg); +/** + Redirect Libevent's log messages. + + @param cb a function taking two arguments: an integer severity between + EVENT_LOG_DEBUG and EVENT_LOG_ERR, and a string. If cb is NULL, + then the default log is used. + + NOTE: The function you provide *must not* call any other libevent + functionality. Doing so can produce undefined behavior. + */ +EVENT2_EXPORT_SYMBOL +void event_set_log_callback(event_log_cb cb); + +/** + A function to be called if Libevent encounters a fatal internal error. + + @see event_set_fatal_callback + */ +typedef void (*event_fatal_cb)(int err); + +/** + Override Libevent's behavior in the event of a fatal internal error. + + By default, Libevent will call exit(1) if a programming error makes it + impossible to continue correct operation. This function allows you to supply + another callback instead. Note that if the function is ever invoked, + something is wrong with your program, or with Libevent: any subsequent calls + to Libevent may result in undefined behavior. + + Libevent will (almost) always log an EVENT_LOG_ERR message before calling + this function; look at the last log message to see why Libevent has died. + */ +EVENT2_EXPORT_SYMBOL +void event_set_fatal_callback(event_fatal_cb cb); + +#define EVENT_DBG_ALL 0xffffffffu +#define EVENT_DBG_NONE 0 + +/** + Turn on debugging logs and have them sent to the default log handler. + + This is a global setting; if you are going to call it, you must call this + before any calls that create an event-base. You must call it before any + multithreaded use of Libevent. + + Debug logs are verbose. + + @param which Controls which debug messages are turned on. This option is + unused for now; for forward compatibility, you must pass in the constant + "EVENT_DBG_ALL" to turn debugging logs on, or "EVENT_DBG_NONE" to turn + debugging logs off. + */ +EVENT2_EXPORT_SYMBOL +void event_enable_debug_logging(ev_uint32_t which); + +/** + Associate a different event base with an event. + + The event to be associated must not be currently active or pending. + + @param eb the event base + @param ev the event + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int event_base_set(struct event_base *eb, struct event *ev); + +/** @name Loop flags + + These flags control the behavior of event_base_loop(). + */ +/**@{*/ +/** Block until we have an active event, then exit once all active events + * have had their callbacks run. */ +#define EVLOOP_ONCE 0x01 +/** Do not block: see which events are ready now, run the callbacks + * of the highest-priority ones, then exit. */ +#define EVLOOP_NONBLOCK 0x02 +/** Do not exit the loop because we have no pending events. Instead, keep + * running until event_base_loopexit() or event_base_loopbreak() makes us + * stop. + */ +#define EVLOOP_NO_EXIT_ON_EMPTY 0x04 +/**@}*/ + +/** + Wait for events to become active, and run their callbacks. + + This is a more flexible version of event_base_dispatch(). + + By default, this loop will run the event base until either there are no more + pending or active events, or until something calls event_base_loopbreak() or + event_base_loopexit(). You can override this behavior with the 'flags' + argument. + + @param eb the event_base structure returned by event_base_new() or + event_base_new_with_config() + @param flags any combination of EVLOOP_ONCE | EVLOOP_NONBLOCK + @return 0 if successful, -1 if an error occurred, or 1 if we exited because + no events were pending or active. + @see event_base_loopexit(), event_base_dispatch(), EVLOOP_ONCE, + EVLOOP_NONBLOCK + */ +EVENT2_EXPORT_SYMBOL +int event_base_loop(struct event_base *eb, int flags); + +/** + Exit the event loop after the specified time + + The next event_base_loop() iteration after the given timer expires will + complete normally (handling all queued events) then exit without + blocking for events again. + + Subsequent invocations of event_base_loop() will proceed normally. + + @param eb the event_base structure returned by event_init() + @param tv the amount of time after which the loop should terminate, + or NULL to exit after running all currently active events. + @return 0 if successful, or -1 if an error occurred + @see event_base_loopbreak() + */ +EVENT2_EXPORT_SYMBOL +int event_base_loopexit(struct event_base *eb, const struct timeval *tv); + +/** + Abort the active event_base_loop() immediately. + + event_base_loop() will abort the loop after the next event is completed; + event_base_loopbreak() is typically invoked from this event's callback. + This behavior is analogous to the "break;" statement. + + Subsequent invocations of event_base_loop() will proceed normally. + + @param eb the event_base structure returned by event_init() + @return 0 if successful, or -1 if an error occurred + @see event_base_loopexit() + */ +EVENT2_EXPORT_SYMBOL +int event_base_loopbreak(struct event_base *eb); + +/** + Tell the active event_base_loop() to scan for new events immediately. + + Calling this function makes the currently active event_base_loop() + start the loop over again (scanning for new events) after the current + event callback finishes. If the event loop is not running, this + function has no effect. + + event_base_loopbreak() is typically invoked from this event's callback. + This behavior is analogous to the "continue;" statement. + + Subsequent invocations of event loop will proceed normally. + + @param eb the event_base structure returned by event_init() + @return 0 if successful, or -1 if an error occurred + @see event_base_loopbreak() + */ +EVENT2_EXPORT_SYMBOL +int event_base_loopcontinue(struct event_base *eb); + +/** + Checks if the event loop was told to exit by event_base_loopexit(). + + This function will return true for an event_base at every point after + event_loopexit() is called, until the event loop is next entered. + + @param eb the event_base structure returned by event_init() + @return true if event_base_loopexit() was called on this event base, + or 0 otherwise + @see event_base_loopexit() + @see event_base_got_break() + */ +EVENT2_EXPORT_SYMBOL +int event_base_got_exit(struct event_base *eb); + +/** + Checks if the event loop was told to abort immediately by event_base_loopbreak(). + + This function will return true for an event_base at every point after + event_base_loopbreak() is called, until the event loop is next entered. + + @param eb the event_base structure returned by event_init() + @return true if event_base_loopbreak() was called on this event base, + or 0 otherwise + @see event_base_loopbreak() + @see event_base_got_exit() + */ +EVENT2_EXPORT_SYMBOL +int event_base_got_break(struct event_base *eb); + +/** + * @name event flags + * + * Flags to pass to event_new(), event_assign(), event_pending(), and + * anything else with an argument of the form "short events" + */ +/**@{*/ +/** Indicates that a timeout has occurred. It's not necessary to pass + * this flag to event_for new()/event_assign() to get a timeout. */ +#define EV_TIMEOUT 0x01 +/** Wait for a socket or FD to become readable */ +#define EV_READ 0x02 +/** Wait for a socket or FD to become writeable */ +#define EV_WRITE 0x04 +/** Wait for a POSIX signal to be raised*/ +#define EV_SIGNAL 0x08 +/** + * Persistent event: won't get removed automatically when activated. + * + * When a persistent event with a timeout becomes activated, its timeout + * is reset to 0. + */ +#define EV_PERSIST 0x10 +/** Select edge-triggered behavior, if supported by the backend. */ +#define EV_ET 0x20 +/** + * If this option is provided, then event_del() will not block in one thread + * while waiting for the event callback to complete in another thread. + * + * To use this option safely, you may need to use event_finalize() or + * event_free_finalize() in order to safely tear down an event in a + * multithreaded application. See those functions for more information. + **/ +#define EV_FINALIZE 0x40 +/** + * Detects connection close events. You can use this to detect when a + * connection has been closed, without having to read all the pending data + * from a connection. + * + * Not all backends support EV_CLOSED. To detect or require it, use the + * feature flag EV_FEATURE_EARLY_CLOSE. + **/ +#define EV_CLOSED 0x80 +/**@}*/ + +/** + @name evtimer_* macros + + Aliases for working with one-shot timer events + If you need EV_PERSIST timer use event_*() functions. + */ +/**@{*/ +#define evtimer_assign(ev, b, cb, arg) \ + event_assign((ev), (b), -1, 0, (cb), (arg)) +#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) +#define evtimer_add(ev, tv) event_add((ev), (tv)) +#define evtimer_del(ev) event_del(ev) +#define evtimer_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv)) +#define evtimer_initialized(ev) event_initialized(ev) +/**@}*/ + +/** + @name evsignal_* macros + + Aliases for working with signal events + */ +/**@{*/ +#define evsignal_add(ev, tv) event_add((ev), (tv)) +#define evsignal_assign(ev, b, x, cb, arg) \ + event_assign((ev), (b), (x), EV_SIGNAL|EV_PERSIST, cb, (arg)) +#define evsignal_new(b, x, cb, arg) \ + event_new((b), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg)) +#define evsignal_del(ev) event_del(ev) +#define evsignal_pending(ev, tv) event_pending((ev), EV_SIGNAL, (tv)) +#define evsignal_initialized(ev) event_initialized(ev) +/**@}*/ + +/** + @name evuser_* macros + + Aliases for working with user-triggered events + If you need EV_PERSIST event use event_*() functions. + */ +/**@{*/ +#define evuser_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) +#define evuser_del(ev) event_del(ev) +#define evuser_pending(ev, tv) event_pending((ev), 0, (tv)) +#define evuser_initialized(ev) event_initialized(ev) +#define evuser_trigger(ev) event_active((ev), 0, 0) +/**@}*/ + +/** + A callback function for an event. + + It receives three arguments: + + @param fd An fd or signal + @param events One or more EV_* flags + @param arg A user-supplied argument. + + @see event_new() + */ +typedef void (*event_callback_fn)(evutil_socket_t, short, void *); + +/** + Return a value used to specify that the event itself must be used as the callback argument. + + The function event_new() takes a callback argument which is passed + to the event's callback function. To specify that the argument to be + passed to the callback function is the event that event_new() returns, + pass in the return value of event_self_cbarg() as the callback argument + for event_new(). + + For example: +
+      struct event *ev = event_new(base, sock, events, callback, %event_self_cbarg());
+  
+ + For consistency with event_new(), it is possible to pass the return value + of this function as the callback argument for event_assign() – this + achieves the same result as passing the event in directly. + + @return a value to be passed as the callback argument to event_new() or + event_assign(). + @see event_new(), event_assign() + */ +EVENT2_EXPORT_SYMBOL +void *event_self_cbarg(void); + +/** + Allocate and assign a new event structure, ready to be added. + + The function event_new() returns a new event that can be used in + future calls to event_add() and event_del(). The fd and events + arguments determine which conditions will trigger the event; the + callback and callback_arg arguments tell Libevent what to do when the + event becomes active. + + If events contains one of EV_READ, EV_WRITE, or EV_READ|EV_WRITE, then + fd is a file descriptor or socket that should get monitored for + readiness to read, readiness to write, or readiness for either operation + (respectively). If events contains EV_SIGNAL, then fd is a signal + number to wait for. If events contains none of those flags, then the + event can be triggered only by a timeout or by manual activation with + event_active(): In this case, fd must be -1. + + The EV_PERSIST flag can also be passed in the events argument: it makes + event_add() persistent until event_del() is called. + + The EV_ET flag is compatible with EV_READ and EV_WRITE, and supported + only by certain backends. It tells Libevent to use edge-triggered + events. + + The EV_TIMEOUT flag has no effect here. + + It is okay to have multiple events all listening on the same fds; but + they must either all be edge-triggered, or not be edge-triggered at all. + + When the event becomes active, the event loop will run the provided + callback function, with three arguments. The first will be the provided + fd value. The second will be a bitfield of the events that triggered: + EV_READ, EV_WRITE, or EV_SIGNAL. Here the EV_TIMEOUT flag indicates + that a timeout occurred, and EV_ET indicates that an edge-triggered + event occurred. The third event will be the callback_arg pointer that + you provide. + + @param base the event base to which the event should be attached. + @param fd the file descriptor or signal to be monitored, or -1. + @param events desired events to monitor: bitfield of EV_READ, EV_WRITE, + EV_SIGNAL, EV_PERSIST, EV_ET. + @param callback callback function to be invoked when the event occurs + @param callback_arg an argument to be passed to the callback function + + @return a newly allocated struct event that must later be freed with + event_free() or NULL if an error occurred. + @see event_free(), event_add(), event_del(), event_assign() + */ +EVENT2_EXPORT_SYMBOL +struct event *event_new(struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg); + + +/** + Prepare a new, already-allocated event structure to be added. + + The function event_assign() prepares the event structure ev to be used + in future calls to event_add() and event_del(). Unlike event_new(), it + doesn't allocate memory itself: it requires that you have already + allocated a struct event, probably on the heap. Doing this will + typically make your code depend on the size of the event structure, and + thereby create incompatibility with future versions of Libevent. + + The easiest way to avoid this problem is just to use event_new() and + event_free() instead. + + A slightly harder way to future-proof your code is to use + event_get_struct_event_size() to determine the required size of an event + at runtime. + + Note that it is NOT safe to call this function on an event that is + active or pending. Doing so WILL corrupt internal data structures in + Libevent, and lead to strange, hard-to-diagnose bugs. You _can_ use + event_assign to change an existing event, but only if it is not active + or pending! + + The arguments for this function, and the behavior of the events that it + makes, are as for event_new(). + + @param ev an event struct to be modified + @param base the event base to which ev should be attached. + @param fd the file descriptor to be monitored + @param events desired events to monitor; can be EV_READ and/or EV_WRITE + @param callback callback function to be invoked when the event occurs + @param callback_arg an argument to be passed to the callback function + + @return 0 if success, or -1 on invalid arguments. + + @see event_new(), event_add(), event_del(), event_base_once(), + event_get_struct_event_size() + */ +EVENT2_EXPORT_SYMBOL +int event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg); + +/** + Deallocate a struct event * returned by event_new(). + + If the event is pending or active, this function makes it non-pending + and non-active first. + */ +EVENT2_EXPORT_SYMBOL +void event_free(struct event *); + +/** + * Callback type for event_finalize and event_free_finalize(). + **/ +typedef void (*event_finalize_callback_fn)(struct event *, void *); +/** + @name Finalization functions + + These functions are used to safely tear down an event in a multithreaded + application. If you construct your events with EV_FINALIZE to avoid + deadlocks, you will need a way to remove an event in the certainty that + it will definitely not be running its callback when you deallocate it + and its callback argument. + + To do this, call one of event_finalize() or event_free_finalize with + 0 for its first argument, the event to tear down as its second argument, + and a callback function as its third argument. The callback will be + invoked as part of the event loop, with the event's priority. + + After you call a finalizer function, event_add() and event_active() will + no longer work on the event, and event_del() will produce a no-op. You + must not try to change the event's fields with event_assign() or + event_set() while the finalize callback is in progress. Once the + callback has been invoked, you should treat the event structure as + containing uninitialized memory. + + The event_free_finalize() function frees the event after it's finalized; + event_finalize() does not. + + A finalizer callback must not make events pending or active. It must not + add events, activate events, or attempt to "resuscitate" the event being + finalized in any way. + + @return 0 on success, -1 on failure. + */ +/**@{*/ +EVENT2_EXPORT_SYMBOL +int event_finalize(unsigned, struct event *, event_finalize_callback_fn); +EVENT2_EXPORT_SYMBOL +int event_free_finalize(unsigned, struct event *, event_finalize_callback_fn); +/**@}*/ + +/** + Schedule a one-time event + + The function event_base_once() is similar to event_new(). However, it + schedules a callback to be called exactly once, and does not require the + caller to prepare an event structure. + + Note that in Libevent 2.0 and earlier, if the event is never triggered, the + internal memory used to hold it will never be freed. In Libevent 2.1, + the internal memory will get freed by event_base_free() if the event + is never triggered. The 'arg' value, however, will not get freed in either + case--you'll need to free that on your own if you want it to go away. + + @param base an event_base + @param fd a file descriptor to monitor, or -1 for no fd. + @param events event(s) to monitor; can be any of EV_READ | + EV_WRITE, or EV_TIMEOUT + @param callback callback function to be invoked when the event occurs + @param arg an argument to be passed to the callback function + @param timeout the maximum amount of time to wait for the event. NULL + makes an EV_READ/EV_WRITE event make forever; NULL makes an + EV_TIMEOUT event success immediately. + @return 0 if successful, or -1 if an error occurred + */ +EVENT2_EXPORT_SYMBOL +int event_base_once(struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *arg, const struct timeval *timeout); + +/** + Add an event to the set of pending events. + + The function event_add() schedules the execution of the event 'ev' when the + condition specified by event_assign() or event_new() occurs, or when the time + specified in timeout has elapsed. If a timeout is NULL, no timeout + occurs and the function will only be + called if a matching event occurs. The event in the + ev argument must be already initialized by event_assign() or event_new() + and may not be used + in calls to event_assign() until it is no longer pending. + + If the event in the ev argument already has a scheduled timeout, calling + event_add() replaces the old timeout with the new one if tv is non-NULL. + + @param ev an event struct initialized via event_assign() or event_new() + @param timeout the maximum amount of time to wait for the event, or NULL + to wait forever + @return 0 if successful, or -1 if an error occurred + @see event_del(), event_assign(), event_new() + */ +EVENT2_EXPORT_SYMBOL +int event_add(struct event *ev, const struct timeval *timeout); + +/** + Remove a timer from a pending event without removing the event itself. + + If the event has a scheduled timeout, this function unschedules it but + leaves the event otherwise pending. + + @param ev an event struct initialized via event_assign() or event_new() + @return 0 on success, or -1 if an error occurred. +*/ +EVENT2_EXPORT_SYMBOL +int event_remove_timer(struct event *ev); + +/** + Remove an event from the set of monitored events. + + The function event_del() will cancel the event in the argument ev. If the + event has already executed or has never been added the call will have no + effect. + + @param ev an event struct to be removed from the working set + @return 0 if successful, or -1 if an error occurred + @see event_add() + */ +EVENT2_EXPORT_SYMBOL +int event_del(struct event *ev); + +/** + As event_del(), but never blocks while the event's callback is running + in another thread, even if the event was constructed without the + EV_FINALIZE flag. + */ +EVENT2_EXPORT_SYMBOL +int event_del_noblock(struct event *ev); +/** + As event_del(), but always blocks while the event's callback is running + in another thread, even if the event was constructed with the + EV_FINALIZE flag. + */ +EVENT2_EXPORT_SYMBOL +int event_del_block(struct event *ev); + +/** + Make an event active. + + You can use this function on a pending or a non-pending event to make it + active, so that its callback will be run by event_base_dispatch() or + event_base_loop(). + + One common use in multithreaded programs is to wake the thread running + event_base_loop() from another thread. + + @param ev an event to make active. + @param res a set of flags to pass to the event's callback. + @param ncalls an obsolete argument: this is ignored. + **/ +EVENT2_EXPORT_SYMBOL +void event_active(struct event *ev, int res, short ncalls); + +/** + Checks if a specific event is pending or scheduled. + + @param ev an event struct previously passed to event_add() + @param events the requested event type; any of EV_TIMEOUT|EV_READ| + EV_WRITE|EV_SIGNAL + @param tv if this field is not NULL, and the event has a timeout, + this field is set to hold the time at which the timeout will + expire. + + @return true if the event is pending on any of the events in 'what', (that + is to say, it has been added), or 0 if the event is not added. + */ +EVENT2_EXPORT_SYMBOL +int event_pending(const struct event *ev, short events, struct timeval *tv); + +/** + If called from within the callback for an event, returns that event. + + The behavior of this function is not defined when called from outside the + callback function for an event. + */ +EVENT2_EXPORT_SYMBOL +struct event *event_base_get_running_event(struct event_base *base); + +/** + Test if an event structure might be initialized. + + The event_initialized() function can be used to check if an event has been + initialized. + + Warning: This function is only useful for distinguishing a zeroed-out + piece of memory from an initialized event, it can easily be confused by + uninitialized memory. Thus, it should ONLY be used to distinguish an + initialized event from zero. + + @param ev an event structure to be tested + @return 1 if the structure might be initialized, or 0 if it has not been + initialized + */ +EVENT2_EXPORT_SYMBOL +int event_initialized(const struct event *ev); + +/** + Get the signal number assigned to a signal event +*/ +#define event_get_signal(ev) ((int)event_get_fd(ev)) + +/** + Get the socket or signal assigned to an event, or -1 if the event has + no socket. +*/ +EVENT2_EXPORT_SYMBOL +evutil_socket_t event_get_fd(const struct event *ev); + +/** + Get the event_base associated with an event. +*/ +EVENT2_EXPORT_SYMBOL +struct event_base *event_get_base(const struct event *ev); + +/** + Return the events (EV_READ, EV_WRITE, etc) assigned to an event. +*/ +EVENT2_EXPORT_SYMBOL +short event_get_events(const struct event *ev); + +/** + Return the callback assigned to an event. +*/ +EVENT2_EXPORT_SYMBOL +event_callback_fn event_get_callback(const struct event *ev); + +/** + Return the callback argument assigned to an event. +*/ +EVENT2_EXPORT_SYMBOL +void *event_get_callback_arg(const struct event *ev); + +/** + Return the priority of an event. + @see event_priority_init(), event_get_priority() +*/ +EVENT2_EXPORT_SYMBOL +int event_get_priority(const struct event *ev); + +/** + Extract _all_ of arguments given to construct a given event. The + event_base is copied into *base_out, the fd is copied into *fd_out, and so + on. + + If any of the "_out" arguments is NULL, it will be ignored. + */ +EVENT2_EXPORT_SYMBOL +void event_get_assignment(const struct event *event, + struct event_base **base_out, evutil_socket_t *fd_out, short *events_out, + event_callback_fn *callback_out, void **arg_out); + +/** + Return the size of struct event that the Libevent library was compiled + with. + + This will be NO GREATER than sizeof(struct event) if you're running with + the same version of Libevent that your application was built with, but + otherwise might not. + + Note that it might be SMALLER than sizeof(struct event) if some future + version of Libevent adds extra padding to the end of struct event. + We might do this to help ensure ABI-compatibility between different + versions of Libevent. + */ +EVENT2_EXPORT_SYMBOL +size_t event_get_struct_event_size(void); + +/** + Get the Libevent version. + + Note that this will give you the version of the library that you're + currently linked against, not the version of the headers that you've + compiled against. + + @return a string containing the version number of Libevent +*/ +EVENT2_EXPORT_SYMBOL +const char *event_get_version(void); + +/** + Return a numeric representation of Libevent's version. + + Note that this will give you the version of the library that you're + currently linked against, not the version of the headers you've used to + compile. + + The format uses one byte each for the major, minor, and patchlevel parts of + the version number. The low-order byte is unused. For example, version + 2.0.1-alpha has a numeric representation of 0x02000100 +*/ +EVENT2_EXPORT_SYMBOL +ev_uint32_t event_get_version_number(void); + +/** As event_get_version, but gives the version of Libevent's headers. */ +#define LIBEVENT_VERSION EVENT__VERSION +/** As event_get_version_number, but gives the version number of Libevent's + * headers. */ +#define LIBEVENT_VERSION_NUMBER EVENT__NUMERIC_VERSION + +/** Largest number of priorities that Libevent can support. */ +#define EVENT_MAX_PRIORITIES 256 +/** + Set the number of different event priorities + + By default Libevent schedules all active events with the same priority. + However, some time it is desirable to process some events with a higher + priority than others. For that reason, Libevent supports strict priority + queues. Active events with a lower priority are always processed before + events with a higher priority. + + The number of different priorities can be set initially with the + event_base_priority_init() function. This function should be called + before the first call to event_base_dispatch(). The + event_priority_set() function can be used to assign a priority to an + event. By default, Libevent assigns the middle priority to all events + unless their priority is explicitly set. + + Note that urgent-priority events can starve less-urgent events: after + running all urgent-priority callbacks, Libevent checks for more urgent + events again, before running less-urgent events. Less-urgent events + will not have their callbacks run until there are no events more urgent + than them that want to be active. + + @param eb the event_base structure returned by event_base_new() + @param npriorities the maximum number of priorities + @return 0 if successful, or -1 if an error occurred + @see event_priority_set() + */ +EVENT2_EXPORT_SYMBOL +int event_base_priority_init(struct event_base *eb, int npriorities); + +/** + Get the number of different event priorities. + + @param eb the event_base structure returned by event_base_new() + @return Number of different event priorities + @see event_base_priority_init() +*/ +EVENT2_EXPORT_SYMBOL +int event_base_get_npriorities(struct event_base *eb); + +/** + Assign a priority to an event. + + @param ev an event struct + @param priority the new priority to be assigned + @return 0 if successful, or -1 if an error occurred + @see event_priority_init(), event_get_priority() + */ +EVENT2_EXPORT_SYMBOL +int event_priority_set(struct event *ev, int priority); + +/** + Prepare an event_base to use a large number of timeouts with the same + duration. + + Libevent's default scheduling algorithm is optimized for having a large + number of timeouts with their durations more or less randomly + distributed. But if you have a large number of timeouts that all have + the same duration (for example, if you have a large number of + connections that all have a 10-second timeout), then you can improve + Libevent's performance by telling Libevent about it. + + To do this, call this function with the common duration. It will return a + pointer to a different, opaque timeout value. (Don't depend on its actual + contents!) When you use this timeout value in event_add(), Libevent will + schedule the event more efficiently. + + (This optimization probably will not be worthwhile until you have thousands + or tens of thousands of events with the same timeout.) + */ +EVENT2_EXPORT_SYMBOL +const struct timeval *event_base_init_common_timeout(struct event_base *base, + const struct timeval *duration); + +#if !defined(EVENT__DISABLE_MM_REPLACEMENT) || defined(EVENT_IN_DOXYGEN_) +/** + Override the functions that Libevent uses for memory management. + + Usually, Libevent uses the standard libc functions malloc, realloc, and + free to allocate memory. Passing replacements for those functions to + event_set_mem_functions() overrides this behavior. + + Note that all memory returned from Libevent will be allocated by the + replacement functions rather than by malloc() and realloc(). Thus, if you + have replaced those functions, it will not be appropriate to free() memory + that you get from Libevent. Instead, you must use the free_fn replacement + that you provided. + + Note also that if you are going to call this function, you should do so + before any call to any Libevent function that does allocation. + Otherwise, those functions will allocate their memory using malloc(), but + then later free it using your provided free_fn. + + @param malloc_fn A replacement for malloc. + @param realloc_fn A replacement for realloc + @param free_fn A replacement for free. + **/ +EVENT2_EXPORT_SYMBOL +void event_set_mem_functions( + void *(*malloc_fn)(size_t sz), + void *(*realloc_fn)(void *ptr, size_t sz), + void (*free_fn)(void *ptr)); +/** This definition is present if Libevent was built with support for + event_set_mem_functions() */ +#define EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED +#endif + +/** + Writes a human-readable description of all inserted and/or active + events to a provided stdio stream. + + This is intended for debugging; its format is not guaranteed to be the same + between libevent versions. + + @param base An event_base on which to scan the events. + @param output A stdio file to write on. + */ +EVENT2_EXPORT_SYMBOL +void event_base_dump_events(struct event_base *base, FILE *output); + + +/** + Activates all pending events for the given fd and event mask. + + This function activates pending events only. Events which have not been + added will not become active. + + @param base the event_base on which to activate the events. + @param fd An fd to active events on. + @param events One or more of EV_{READ,WRITE,TIMEOUT}. + */ +EVENT2_EXPORT_SYMBOL +void event_base_active_by_fd(struct event_base *base, evutil_socket_t fd, short events); + +/** + Activates all pending signals with a given signal number + + This function activates pending events only. Events which have not been + added will not become active. + + @param base the event_base on which to activate the events. + @param sig The signal to active events on. + */ +EVENT2_EXPORT_SYMBOL +void event_base_active_by_signal(struct event_base *base, int sig); + +/** + * Callback for iterating events in an event base via event_base_foreach_event + */ +typedef int (*event_base_foreach_event_cb)(const struct event_base *, const struct event *, void *); + +/** + Iterate over all added or active events events in an event loop, and invoke + a given callback on each one. + + The callback must not call any function that modifies the event base, that + modifies any event in the event base, or that adds or removes any event to + the event base. Doing so is unsupported and will lead to undefined + behavior -- likely, to crashes. + + event_base_foreach_event() holds a lock on the event_base() for the whole + time it's running: slow callbacks are not advisable. + + Note that Libevent adds some events of its own to make pieces of its + functionality work. You must not assume that the only events you'll + encounter will be the ones you added yourself. + + The callback function must return 0 to continue iteration, or some other + integer to stop iterating. + + @param base An event_base on which to scan the events. + @param fn A callback function to receive the events. + @param arg An argument passed to the callback function. + @return 0 if we iterated over every event, or the value returned by the + callback function if the loop exited early. +*/ +EVENT2_EXPORT_SYMBOL +int event_base_foreach_event(struct event_base *base, event_base_foreach_event_cb fn, void *arg); + + +/** Sets 'tv' to the current time (as returned by gettimeofday()), + looking at the cached value in 'base' if possible, and calling + gettimeofday() or clock_gettime() as appropriate if there is no + cached time. + + Generally, this value will only be cached while actually + processing event callbacks, and may be very inaccurate if your + callbacks take a long time to execute. + + Returns 0 on success, negative on failure. + */ +EVENT2_EXPORT_SYMBOL +int event_base_gettimeofday_cached(struct event_base *base, + struct timeval *tv); + +/** Update cached_tv in the 'base' to the current time + * + * You can use this function is useful for selectively increasing + * the accuracy of the cached time value in 'base' during callbacks + * that take a long time to execute. + * + * This function has no effect if the base is currently not in its + * event loop, or if timeval caching is disabled via + * EVENT_BASE_FLAG_NO_CACHE_TIME. + * + * @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int event_base_update_cache_time(struct event_base *base); + +/** Release up all globally-allocated resources allocated by Libevent. + + This function does not free developer-controlled resources like + event_bases, events, bufferevents, listeners, and so on. It only releases + resources like global locks that there is no other way to free. + + It is not actually necessary to call this function before exit: every + resource that it frees would be released anyway on exit. It mainly exists + so that resource-leak debugging tools don't see Libevent as holding + resources at exit. + + You should only call this function when no other Libevent functions will + be invoked -- e.g., when cleanly exiting a program. + */ +EVENT2_EXPORT_SYMBOL +void libevent_global_shutdown(void); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_EVENT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/event_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/event_compat.h new file mode 100644 index 00000000..fecdb3b1 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/event_compat.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_EVENT_COMPAT_H_INCLUDED_ +#define EVENT2_EVENT_COMPAT_H_INCLUDED_ + +/** @file event2/event_compat.h + + @brief Potentially non-threadsafe versions of the functions in event.h: provided + only for backwards compatibility. + + In the oldest versions of Libevent, event_base was not a first-class + structure. Instead, there was a single event base that every function + manipulated. Later, when separate event bases were added, the old functions + that didn't take an event_base argument needed to work by manipulating the + "current" event base. This could lead to thread-safety issues, and obscure, + hard-to-diagnose bugs. + + @deprecated All functions in this file are by definition deprecated. + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +/** + Initialize the event API. + + The event API needs to be initialized with event_init() before it can be + used. Sets the global current base that gets used for events that have no + base associated with them. + + @deprecated This function is deprecated because it replaces the "current" + event_base, and is totally unsafe for multithreaded use. The replacement + is event_base_new(). + + @see event_base_set(), event_base_new() + */ +EVENT2_EXPORT_SYMBOL +struct event_base *event_init(void); + +/** + Loop to process events. + + Like event_base_dispatch(), but uses the "current" base. + + @deprecated This function is deprecated because it is easily confused by + multiple calls to event_init(), and because it is not safe for + multithreaded use. The replacement is event_base_dispatch(). + + @see event_base_dispatch(), event_init() + */ +EVENT2_EXPORT_SYMBOL +int event_dispatch(void); + +/** + Handle events. + + This function behaves like event_base_loop(), but uses the "current" base + + @deprecated This function is deprecated because it uses the event base from + the last call to event_init, and is therefore not safe for multithreaded + use. The replacement is event_base_loop(). + + @see event_base_loop(), event_init() +*/ +EVENT2_EXPORT_SYMBOL +int event_loop(int); + + +/** + Exit the event loop after the specified time. + + This function behaves like event_base_loopexit(), except that it uses the + "current" base. + + @deprecated This function is deprecated because it uses the event base from + the last call to event_init, and is therefore not safe for multithreaded + use. The replacement is event_base_loopexit(). + + @see event_init, event_base_loopexit() + */ +EVENT2_EXPORT_SYMBOL +int event_loopexit(const struct timeval *); + + +/** + Abort the active event_loop() immediately. + + This function behaves like event_base_loopbreakt(), except that it uses the + "current" base. + + @deprecated This function is deprecated because it uses the event base from + the last call to event_init, and is therefore not safe for multithreaded + use. The replacement is event_base_loopbreak(). + + @see event_base_loopbreak(), event_init() + */ +EVENT2_EXPORT_SYMBOL +int event_loopbreak(void); + +/** + Schedule a one-time event to occur. + + @deprecated This function is obsolete, and has been replaced by + event_base_once(). Its use is deprecated because it relies on the + "current" base configured by event_init(). + + @see event_base_once() + */ +EVENT2_EXPORT_SYMBOL +int event_once(evutil_socket_t , short, + void (*)(evutil_socket_t, short, void *), void *, const struct timeval *); + + +/** + Get the kernel event notification mechanism used by Libevent. + + @deprecated This function is obsolete, and has been replaced by + event_base_get_method(). Its use is deprecated because it relies on the + "current" base configured by event_init(). + + @see event_base_get_method() + */ +EVENT2_EXPORT_SYMBOL +const char *event_get_method(void); + + +/** + Set the number of different event priorities. + + @deprecated This function is deprecated because it is easily confused by + multiple calls to event_init(), and because it is not safe for + multithreaded use. The replacement is event_base_priority_init(). + + @see event_base_priority_init() + */ +EVENT2_EXPORT_SYMBOL +int event_priority_init(int); + +/** + Prepare an event structure to be added. + + @deprecated event_set() is not recommended for new code, because it requires + a subsequent call to event_base_set() to be safe under most circumstances. + Use event_assign() or event_new() instead. + */ +EVENT2_EXPORT_SYMBOL +void event_set(struct event *, evutil_socket_t, short, void (*)(evutil_socket_t, short, void *), void *); + +#define evtimer_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg)) +#define evsignal_set(ev, x, cb, arg) \ + event_set((ev), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg)) + + +/** + @name timeout_* macros + + @deprecated These macros are deprecated because their naming is inconsistent + with the rest of Libevent. Use the evtimer_* macros instead. + @{ + */ +#define timeout_add(ev, tv) event_add((ev), (tv)) +#define timeout_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg)) +#define timeout_del(ev) event_del(ev) +#define timeout_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv)) +#define timeout_initialized(ev) event_initialized(ev) +/**@}*/ + +/** + @name signal_* macros + + @deprecated These macros are deprecated because their naming is inconsistent + with the rest of Libevent. Use the evsignal_* macros instead. + @{ + */ +#define signal_add(ev, tv) event_add((ev), (tv)) +#define signal_set(ev, x, cb, arg) \ + event_set((ev), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg)) +#define signal_del(ev) event_del(ev) +#define signal_pending(ev, tv) event_pending((ev), EV_SIGNAL, (tv)) +#define signal_initialized(ev) event_initialized(ev) +/**@}*/ + +#ifndef EVENT_FD +/* These macros are obsolete; use event_get_fd and event_get_signal instead. */ +#define EVENT_FD(ev) ((int)event_get_fd(ev)) +#define EVENT_SIGNAL(ev) event_get_signal(ev) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_EVENT_COMPAT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/event_struct.h b/examples/proto_debuger/third/include/libevent/include/event2/event_struct.h new file mode 100644 index 00000000..34672e84 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/event_struct.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_EVENT_STRUCT_H_INCLUDED_ +#define EVENT2_EVENT_STRUCT_H_INCLUDED_ + +/** @file event2/event_struct.h + + Structures used by event.h. Using these structures directly WILL harm + forward compatibility: be careful. + + No field declared in this file should be used directly in user code. Except + for historical reasons, these fields would not be exposed at all. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +/* For evkeyvalq */ +#include + +#define EVLIST_TIMEOUT 0x01 +#define EVLIST_INSERTED 0x02 +#define EVLIST_SIGNAL 0x04 +#define EVLIST_ACTIVE 0x08 +#define EVLIST_INTERNAL 0x10 +#define EVLIST_ACTIVE_LATER 0x20 +#define EVLIST_FINALIZING 0x40 +#define EVLIST_INIT 0x80 + +#define EVLIST_ALL 0xff + +/* Fix so that people don't have to run with */ +#ifndef TAILQ_ENTRY +#define EVENT_DEFINED_TQENTRY_ +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} +#endif /* !TAILQ_ENTRY */ + +#ifndef TAILQ_HEAD +#define EVENT_DEFINED_TQHEAD_ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; \ + struct type **tqh_last; \ +} +#endif + +/* Fix so that people don't have to run with */ +#ifndef LIST_ENTRY +#define EVENT_DEFINED_LISTENTRY_ +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} +#endif /* !LIST_ENTRY */ + +#ifndef LIST_HEAD +#define EVENT_DEFINED_LISTHEAD_ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ + } +#endif /* !LIST_HEAD */ + +struct event; + +struct event_callback { + TAILQ_ENTRY(event_callback) evcb_active_next; + short evcb_flags; + ev_uint8_t evcb_pri; /* smaller numbers are higher priority */ + ev_uint8_t evcb_closure; + /* allows us to adopt for different types of events */ + union { + void (*evcb_callback)(evutil_socket_t, short, void *); + void (*evcb_selfcb)(struct event_callback *, void *); + void (*evcb_evfinalize)(struct event *, void *); + void (*evcb_cbfinalize)(struct event_callback *, void *); + } evcb_cb_union; + void *evcb_arg; +}; + +struct event_base; +struct event { + struct event_callback ev_evcallback; + + /* for managing timeouts */ + union { + TAILQ_ENTRY(event) ev_next_with_common_timeout; + size_t min_heap_idx; + } ev_timeout_pos; + evutil_socket_t ev_fd; + + short ev_events; + short ev_res; /* result passed to event callback */ + + struct event_base *ev_base; + + union { + /* used for io events */ + struct { + LIST_ENTRY (event) ev_io_next; + struct timeval ev_timeout; + } ev_io; + + /* used by signal events */ + struct { + LIST_ENTRY (event) ev_signal_next; + short ev_ncalls; + /* Allows deletes in callback */ + short *ev_pncalls; + } ev_signal; + } ev_; + + + struct timeval ev_timeout; +}; + +TAILQ_HEAD (event_list, event); + +#ifdef EVENT_DEFINED_TQENTRY_ +#undef TAILQ_ENTRY +#endif + +#ifdef EVENT_DEFINED_TQHEAD_ +#undef TAILQ_HEAD +#endif + +LIST_HEAD (event_dlist, event); + +#ifdef EVENT_DEFINED_LISTENTRY_ +#undef LIST_ENTRY +#endif + +#ifdef EVENT_DEFINED_LISTHEAD_ +#undef LIST_HEAD +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_EVENT_STRUCT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/http.h b/examples/proto_debuger/third/include/libevent/include/event2/http.h new file mode 100644 index 00000000..22e6122e --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/http.h @@ -0,0 +1,1429 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_HTTP_H_INCLUDED_ +#define EVENT2_HTTP_H_INCLUDED_ + +/* For int types. */ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* In case we haven't included the right headers yet. */ +struct evbuffer; +struct event_base; +struct bufferevent; +struct evhttp_connection; + +/** @file event2/http.h + * + * @brief Basic support for HTTP serving. + * + * As Libevent is a library for dealing with event notification and most + * interesting applications are networked today, I have often found the + * need to write HTTP code. The following prototypes and definitions provide + * an application with a minimal interface for making HTTP requests and for + * creating a very simple HTTP server. + */ + +/* Response codes */ +#define HTTP_OK 200 /**< request completed ok */ +#define HTTP_NOCONTENT 204 /**< request does not have content */ +#define HTTP_MOVEPERM 301 /**< the uri moved permanently */ +#define HTTP_MOVETEMP 302 /**< the uri moved temporarily */ +#define HTTP_NOTMODIFIED 304 /**< page was not modified from last */ +#define HTTP_BADREQUEST 400 /**< invalid http request was made */ +#define HTTP_NOTFOUND 404 /**< could not find content for uri */ +#define HTTP_BADMETHOD 405 /**< method not allowed for this uri */ +#define HTTP_ENTITYTOOLARGE 413 /**< */ +#define HTTP_EXPECTATIONFAILED 417 /**< we can't handle this expectation */ +#define HTTP_INTERNAL 500 /**< internal error */ +#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */ +#define HTTP_SERVUNAVAIL 503 /**< the server is not available */ + +struct evhttp; +struct evhttp_request; +struct evkeyvalq; +struct evhttp_bound_socket; +struct evconnlistener; +struct evdns_base; +struct evhttp_ext_method; + +/** + * Create a new HTTP server. + * + * @param base (optional) the event base to receive the HTTP events + * @return a pointer to a newly initialized evhttp server structure or NULL + * on error + * @see evhttp_free() + */ +EVENT2_EXPORT_SYMBOL +struct evhttp *evhttp_new(struct event_base *base); + +/** + * Binds an HTTP server on the specified address and port. + * + * Can be called multiple times to bind the same http server + * to multiple different ports. + * + * @param http a pointer to an evhttp object + * @param address a string containing the IP address to listen(2) on + * @param port the port number to listen on + * @return 0 on success, -1 on failure. + * @see evhttp_accept_socket() + */ +EVENT2_EXPORT_SYMBOL +int evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port); + +/** + * Like evhttp_bind_socket(), but returns a handle for referencing the socket. + * + * The returned pointer is not valid after \a http is freed. + * + * @param http a pointer to an evhttp object + * @param address a string containing the IP address to listen(2) on + * @param port the port number to listen on + * @return Handle for the socket on success, NULL on failure. + * @see evhttp_bind_socket(), evhttp_del_accept_socket() + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_bound_socket *evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port); + +/** + * Makes an HTTP server accept connections on the specified socket. + * + * This may be useful to create a socket and then fork multiple instances + * of an http server, or when a socket has been communicated via file + * descriptor passing in situations where an http servers does not have + * permissions to bind to a low-numbered port. + * + * Can be called multiple times to have the http server listen to + * multiple different sockets. + * + * @param http a pointer to an evhttp object + * @param fd a socket fd that is ready for accepting connections + * @return 0 on success, -1 on failure. + * @see evhttp_bind_socket() + */ +EVENT2_EXPORT_SYMBOL +int evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd); + +/** + * Like evhttp_accept_socket(), but returns a handle for referencing the socket. + * + * The returned pointer is not valid after \a http is freed. + * + * @param http a pointer to an evhttp object + * @param fd a socket fd that is ready for accepting connections + * @return Handle for the socket on success, NULL on failure. + * @see evhttp_accept_socket(), evhttp_del_accept_socket() + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_bound_socket *evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd); + +/** + * The most low-level evhttp_bind/accept method: takes an evconnlistener, and + * returns an evhttp_bound_socket. The listener will be freed when the bound + * socket is freed. + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_bound_socket *evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener); + +/** + * Return the listener used to implement a bound socket. + */ +EVENT2_EXPORT_SYMBOL +struct evconnlistener *evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound); + +typedef void evhttp_bound_socket_foreach_fn(struct evhttp_bound_socket *, void *); +/** + * Applies the function specified in the first argument to all + * evhttp_bound_sockets associated with "http". The user must not + * attempt to free or remove any connections, sockets or listeners + * in the callback "function". + * + * @param http pointer to an evhttp object + * @param function function to apply to every bound socket + * @param argument pointer value passed to function for every socket iterated + */ +EVENT2_EXPORT_SYMBOL +void evhttp_foreach_bound_socket(struct evhttp *http, evhttp_bound_socket_foreach_fn *function, void *argument); + +/** + * Makes an HTTP server stop accepting connections on the specified socket + * + * This may be useful when a socket has been sent via file descriptor passing + * and is no longer needed by the current process. + * + * If you created this bound socket with evhttp_bind_socket_with_handle or + * evhttp_accept_socket_with_handle, this function closes the fd you provided. + * If you created this bound socket with evhttp_bind_listener, this function + * frees the listener you provided. + * + * \a bound_socket is an invalid pointer after this call returns. + * + * @param http a pointer to an evhttp object + * @param bound_socket a handle returned by evhttp_{bind,accept}_socket_with_handle + * @see evhttp_bind_socket_with_handle(), evhttp_accept_socket_with_handle() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound_socket); + +/** + * Get the raw file descriptor referenced by an evhttp_bound_socket. + * + * @param bound_socket a handle returned by evhttp_{bind,accept}_socket_with_handle + * @return the file descriptor used by the bound socket + * @see evhttp_bind_socket_with_handle(), evhttp_accept_socket_with_handle() + */ +EVENT2_EXPORT_SYMBOL +evutil_socket_t evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound_socket); + +/** + * Free the previously created HTTP server. + * + * Works only if no requests are currently being served. + * + * @param http the evhttp server object to be freed + * @see evhttp_start() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_free(struct evhttp* http); + +/** XXX Document. */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size); +/** XXX Document. */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size); + +/** + * Set the maximum number of simultaneous connections for this server. + * A value of zero or less disables the limit. + * + * @param http the http server on which to set the max connection limit + * @param max_connections the maximum number of simultaneous connections or 0 + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_max_connections(struct evhttp* http, int max_connections); + +/** + * Get the current number of connections. + * + * @return The current number of connections for this server. + */ +EVENT2_EXPORT_SYMBOL +int evhttp_get_connection_count(struct evhttp* http); + +/** + Set the value to use for the Content-Type header when none was provided. If + the content type string is NULL, the Content-Type header will not be + automatically added. + + @param http the http server on which to set the default content type + @param content_type the value for the Content-Type header +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_set_default_content_type(struct evhttp *http, + const char *content_type); + +/** + Sets the what HTTP methods are supported in requests accepted by this + server, and passed to user callbacks. + + If not supported they will generate a "405 Method not allowed" response. + + By default this includes the following methods: GET, POST, HEAD, PUT, DELETE + + @param http the http server on which to set the methods + @param methods bit mask constructed from evhttp_cmd_type values +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods); + +typedef int (*evhttp_ext_method_cb)(struct evhttp_ext_method *); +/** + Sets the callback function which allows HTTP extended methods + to be supported by this server. + + The callback should : + - if method field is NULL : set method field according to type field + - else : set type and flags fields according to method string + - return 0 for success (known method / type) + - return -1 for error (unknown method / type) + + evhttp_set_allowed_methods still needs to be called. + + @param http the http server on which to add support to the methods + @param cmp the extended method callback + @see evhttp_ext_method +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp); + +/** + Set a callback for a specified URI + + @param http the http sever on which to set the callback + @param path the path for which to invoke the callback + @param cb the callback function that gets invoked on requesting path + @param cb_arg an additional context argument for the callback + @return 0 on success, -1 if the callback existed already, -2 on failure +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_set_cb(struct evhttp *http, const char *path, + void (*cb)(struct evhttp_request *, void *), void *cb_arg); + +/** Removes the callback for a specified URI */ +EVENT2_EXPORT_SYMBOL +int evhttp_del_cb(struct evhttp *, const char *); + +/** + Set a callback for all requests that are not caught by specific callbacks + + Invokes the specified callback for all requests that do not match any of + the previously specified request paths. This is catchall for requests not + specifically configured with evhttp_set_cb(). + + @param http the evhttp server object for which to set the callback + @param cb the callback to invoke for any unmatched requests + @param arg an context argument for the callback +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_set_gencb(struct evhttp *http, + void (*cb)(struct evhttp_request *, void *), void *arg); + +/** + Set a callback used to create new bufferevents for connections + to a given evhttp object. + + You can use this to override the default bufferevent type -- for example, + to make this evhttp object use SSL bufferevents rather than unencrypted + ones. + + New bufferevents must be allocated with no fd set on them. + + @param http the evhttp server object for which to set the callback + @param cb the callback to invoke for incoming connections + @param arg an context argument for the callback + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_bevcb(struct evhttp *http, + struct bufferevent *(*cb)(struct event_base *, void *), void *arg); + + +/** + Set a callback which allows the user to note or throttle incoming requests. + + The requests are not populated with HTTP level information. They + are just associated to a connection. + + If the callback returns -1, the associated connection is terminated + and the request is closed. + + @param http the evhttp server object for which to set the callback + @param cb the callback to invoke for incoming connections + @param arg an context argument for the callback + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_newreqcb(struct evhttp *http, + int (*cb)(struct evhttp_request*, void *), void *arg); + +/** + Set a callback to output for any error pages sent for requests of a given + evhttp object. + + You can use this to override the default error pages sent, allowing such + things as multi-lingual support or customization to match other pages. + + The callback should use the supplied buffer to output the text for an + error page. If the callback returns a negative value or doesn't output + anything to the buffer, the default error page will be sent instead. The + buffer will be automatically be sent when the callback returns, so the + callback shouldn't do so itself. + + Microsoft Internet Explorer may display its own error pages if ones sent by + an HTTP server are smaller than certain sizes, depending on the status code. + To reliably suppress this feature an error page should be at least 512 + bytes in size. + + @param http the evhttp server object for which to set the callback + @param cb the callback to invoke to format error pages + @param arg an context argument for the callback + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_errorcb(struct evhttp *http, + int (*cb)(struct evhttp_request *req, struct evbuffer *buffer, int error, const char *reason, void *cbarg), + void *cbarg); + +/** + Adds a virtual host to the http server. + + A virtual host is a newly initialized evhttp object that has request + callbacks set on it via evhttp_set_cb() or evhttp_set_gencb(). It + most not have any listing sockets associated with it. + + If the virtual host has not been removed by the time that evhttp_free() + is called on the main http server, it will be automatically freed, too. + + It is possible to have hierarchical vhosts. For example: A vhost + with the pattern *.example.com may have other vhosts with patterns + foo.example.com and bar.example.com associated with it. + + @param http the evhttp object to which to add a virtual host + @param pattern the glob pattern against which the hostname is matched. + The match is case insensitive and follows otherwise regular shell + matching. + @param vhost the virtual host to add the regular http server. + @return 0 on success, -1 on failure + @see evhttp_remove_virtual_host() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_add_virtual_host(struct evhttp* http, const char *pattern, + struct evhttp* vhost); + +/** + Removes a virtual host from the http server. + + @param http the evhttp object from which to remove the virtual host + @param vhost the virtual host to remove from the regular http server. + @return 0 on success, -1 on failure + @see evhttp_add_virtual_host() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost); + +/** + Add a server alias to an http object. The http object can be a virtual + host or the main server. + + @param http the evhttp object + @param alias the alias to add + @see evhttp_add_remove_alias() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_add_server_alias(struct evhttp *http, const char *alias); + +/** + Remove a server alias from an http object. + + @param http the evhttp object + @param alias the alias to remove + @see evhttp_add_server_alias() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_remove_server_alias(struct evhttp *http, const char *alias); + +/** + * Set the timeout for an HTTP request. + * + * @param http an evhttp object + * @param timeout the timeout, in seconds + * @see evhttp_set_timeout_tv() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_timeout(struct evhttp *http, int timeout); + +/** + * Set read and write timeout for an HTTP request. + * + * @param http an evhttp object + * @param tv the timeout, or NULL + * + * For more precise control: + * @see evhttp_set_read_timeout_tv() + * @see evhttp_set_write_timeout_tv() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_timeout_tv(struct evhttp *http, const struct timeval* tv); + +/** + * Set read timeout for an HTTP request. + * + * @param http an evhttp object + * @param tv the timeout, or NULL + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_read_timeout_tv(struct evhttp *http, const struct timeval* tv); + +/** + * Set write timeout for an HTTP request. + * + * @param http an evhttp object + * @param tv the timeout, or NULL + */ +EVENT2_EXPORT_SYMBOL +void evhttp_set_write_timeout_tv(struct evhttp *http, const struct timeval* tv); + +/* Read all the clients body, and only after this respond with an error if the + * clients body exceed max_body_size */ +#define EVHTTP_SERVER_LINGERING_CLOSE 0x0001 +/** + * Set connection flags for HTTP server. + * + * @see EVHTTP_SERVER_* + * @return 0 on success, otherwise non zero (for example if flag doesn't + * supported). + */ +EVENT2_EXPORT_SYMBOL +int evhttp_set_flags(struct evhttp *http, int flags); + +/* Request/Response functionality */ + +/** + * Send an HTML error message to the client. + * + * @param req a request object + * @param error the HTTP error code + * @param reason a brief explanation of the error. If this is NULL, we'll + * just use the standard meaning of the error code. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_send_error(struct evhttp_request *req, int error, + const char *reason); + +/** + * Send an HTML reply to the client. + * + * The body of the reply consists of the data in databuf. After calling + * evhttp_send_reply() databuf will be empty, but the buffer is still + * owned by the caller and needs to be deallocated by the caller if + * necessary. + * + * @param req a request object + * @param code the HTTP response code to send + * @param reason a brief message to send with the response code + * @param databuf the body of the response + */ +EVENT2_EXPORT_SYMBOL +void evhttp_send_reply(struct evhttp_request *req, int code, + const char *reason, struct evbuffer *databuf); + +/* Low-level response interface, for streaming/chunked replies */ + +/** + Initiate a reply that uses Transfer-Encoding chunked. + + This allows the caller to stream the reply back to the client and is + useful when either not all of the reply data is immediately available + or when sending very large replies. + + The caller needs to supply data chunks with evhttp_send_reply_chunk() + and complete the reply by calling evhttp_send_reply_end(). + + @param req a request object + @param code the HTTP response code to send + @param reason a brief message to send with the response code +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_send_reply_start(struct evhttp_request *req, int code, + const char *reason); + +/** + Send another data chunk as part of an ongoing chunked reply. + + The reply chunk consists of the data in databuf. After calling + evhttp_send_reply_chunk() databuf will be empty, but the buffer is + still owned by the caller and needs to be deallocated by the caller + if necessary. + + @param req a request object + @param databuf the data chunk to send as part of the reply. +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_send_reply_chunk(struct evhttp_request *req, + struct evbuffer *databuf); + +/** + Send another data chunk as part of an ongoing chunked reply. + + The reply chunk consists of the data in databuf. After calling + evhttp_send_reply_chunk() databuf will be empty, but the buffer is + still owned by the caller and needs to be deallocated by the caller + if necessary. + + @param req a request object + @param databuf the data chunk to send as part of the reply. + @param cb callback funcion + @param arg call back's argument. +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf, + void (*cb)(struct evhttp_connection *, void *), void *arg); + +/** + Complete a chunked reply, freeing the request as appropriate. + + @param req a request object +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_send_reply_end(struct evhttp_request *req); + +/* + * Interfaces for making requests + */ + +/** The different request types supported by evhttp. These are as specified + * in RFC2616, except for: + * - PATCH which is specified by RFC5789 + * - PROPFIND, PROPPATCH, MKCOL, LOCK, UNLOCK, COPY, MOVE + * which are specified by RFC4918 + * + * By default, only some of these methods are accepted and passed to user + * callbacks; use evhttp_set_allowed_methods() to change which methods + * are allowed. + */ +enum evhttp_cmd_type { + EVHTTP_REQ_GET = 1 << 0, + EVHTTP_REQ_POST = 1 << 1, + EVHTTP_REQ_HEAD = 1 << 2, + EVHTTP_REQ_PUT = 1 << 3, + EVHTTP_REQ_DELETE = 1 << 4, + EVHTTP_REQ_OPTIONS = 1 << 5, + EVHTTP_REQ_TRACE = 1 << 6, + EVHTTP_REQ_CONNECT = 1 << 7, + EVHTTP_REQ_PATCH = 1 << 8, + EVHTTP_REQ_PROPFIND= 1 << 9, + EVHTTP_REQ_PROPPATCH=1 << 10, + EVHTTP_REQ_MKCOL = 1 << 11, + EVHTTP_REQ_LOCK = 1 << 12, + EVHTTP_REQ_UNLOCK = 1 << 13, + EVHTTP_REQ_COPY = 1 << 14, + EVHTTP_REQ_MOVE = 1 << 15, +}; + +#define EVHTTP_REQ_MAX EVHTTP_REQ_MOVE + +/** + * @brief stucture that is passed to (and modified by) the + * extended method callback function + * + * @see evhttp_set_ext_method_cmp + * @see evhttp_connection_set_ext_method_cmp + */ +struct evhttp_ext_method { + const char *method; + ev_uint32_t type; /* @see enum evhttp_cmd_type */ + ev_uint16_t flags; /* Available flag : EVHTTP_METHOD_HAS_BODY */ +}; + +#define EVHTTP_METHOD_HAS_BODY 0x0001 + +/** a request object can represent either a request or a reply */ +enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE }; + +/** + * Create and return a connection object that can be used to for making HTTP + * requests. The connection object tries to resolve address and establish the + * connection when it is given an http request object. + * + * Connection also has default timeouts for the following events: + * - connect HTTP_CONNECT_TIMEOUT, which is 45 seconds + * - read HTTP_READ_TIMEOUT which is 50 seconds + * - write HTTP_WRITE_TIMEOUT, which is 50 seconds + * + * @param base the event_base to use for handling the connection + * @param dnsbase the dns_base to use for resolving host names; if not + * specified host name resolution will block. + * @param bev a bufferevent to use for connecting to the server; if NULL, a + * socket-based bufferevent will be created. This buffrevent will be freed + * when the connection closes. It must have no fd set on it. + * @param address the address to which to connect + * @param port the port to connect to + * @return an evhttp_connection object that can be used for making requests or + * NULL on error + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_connection *evhttp_connection_base_bufferevent_new( + struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev, const char *address, ev_uint16_t port); + +/** + * Return the bufferevent that an evhttp_connection is using. + */ +EVENT2_EXPORT_SYMBOL +struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon); + +/** + * Return the HTTP server associated with this connection, or NULL. + */ +EVENT2_EXPORT_SYMBOL +struct evhttp *evhttp_connection_get_server(struct evhttp_connection *evcon); + +/** + * Creates a new request object that needs to be filled in with the request + * parameters. The callback is executed when the request completed or an + * error occurred. + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_request *evhttp_request_new( + void (*cb)(struct evhttp_request *, void *), void *arg); + +/** + * Enable delivery of chunks to requestor. + * @param cb will be called after every read of data with the same argument + * as the completion callback. Will never be called on an empty + * response. May drain the input buffer; it will be drained + * automatically on return. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_request_set_chunked_cb(struct evhttp_request *, + void (*cb)(struct evhttp_request *, void *)); + +/** + * Register callback for additional parsing of request headers. + * @param cb will be called after receiving and parsing the full header. + * It allows analyzing the header and possibly closing the connection + * by returning a value < 0. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_request_set_header_cb(struct evhttp_request *, + int (*cb)(struct evhttp_request *, void *)); + +/** + * The different error types supported by evhttp + * + * @see evhttp_request_set_error_cb() + */ +enum evhttp_request_error { + /** + * Timeout reached, also @see evhttp_connection_set_timeout() + */ + EVREQ_HTTP_TIMEOUT, + /** + * EOF reached + */ + EVREQ_HTTP_EOF, + /** + * Error while reading header, or invalid header + */ + EVREQ_HTTP_INVALID_HEADER, + /** + * Error encountered while reading or writing + */ + EVREQ_HTTP_BUFFER_ERROR, + /** + * The evhttp_cancel_request() called on this request. + */ + EVREQ_HTTP_REQUEST_CANCEL, + /** + * Body is greater then evhttp_connection_set_max_body_size() + */ + EVREQ_HTTP_DATA_TOO_LONG +}; +/** + * Set a callback for errors + * @see evhttp_request_error for error types. + * + * On error, both the error callback and the regular callback will be called, + * error callback is called before the regular callback. + **/ +EVENT2_EXPORT_SYMBOL +void evhttp_request_set_error_cb(struct evhttp_request *, + void (*)(enum evhttp_request_error, void *)); + +/** + * Set a callback to be called on request completion of evhttp_send_* function. + * + * The callback function will be called on the completion of the request after + * the output data has been written and before the evhttp_request object + * is destroyed. This can be useful for tracking resources associated with a + * request (ex: timing metrics). + * + * @param req a request object + * @param cb callback function that will be called on request completion + * @param cb_arg an additional context argument for the callback + */ +EVENT2_EXPORT_SYMBOL +void evhttp_request_set_on_complete_cb(struct evhttp_request *req, + void (*cb)(struct evhttp_request *, void *), void *cb_arg); + +/** Frees the request object and removes associated events. */ +EVENT2_EXPORT_SYMBOL +void evhttp_request_free(struct evhttp_request *req); + +/** + * Create and return a connection object that can be used to for making HTTP + * requests. The connection object tries to resolve address and establish the + * connection when it is given an http request object. + * + * @param base the event_base to use for handling the connection + * @param dnsbase the dns_base to use for resolving host names; if not + * specified host name resolution will block. + * @param address the address to which to connect + * @param port the port to connect to + * @return an evhttp_connection object that can be used for making requests or + * NULL on error + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_connection *evhttp_connection_base_new( + struct event_base *base, struct evdns_base *dnsbase, + const char *address, ev_uint16_t port); + +/** + * Set family hint for DNS requests. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_family(struct evhttp_connection *evcon, + int family); + +/* reuse connection address on retry */ +#define EVHTTP_CON_REUSE_CONNECTED_ADDR 0x0008 +/* Try to read error, since server may already send and close + * connection, but if at that time we have some data to send then we + * can send get EPIPE and fail, while we can read that HTTP error. */ +#define EVHTTP_CON_READ_ON_WRITE_ERROR 0x0010 +/* @see EVHTTP_SERVER_LINGERING_CLOSE */ +#define EVHTTP_CON_LINGERING_CLOSE 0x0020 +/* Padding for public flags, @see EVHTTP_CON_* in http-internal.h */ +#define EVHTTP_CON_PUBLIC_FLAGS_END 0x100000 +/** + * Set connection flags. + * + * @see EVHTTP_CON_* + * @return 0 on success, otherwise non zero (for example if flag doesn't + * supported). + */ +EVENT2_EXPORT_SYMBOL +int evhttp_connection_set_flags(struct evhttp_connection *evcon, + int flags); + +/** Takes ownership of the request object + * + * Can be used in a request callback to keep onto the request until + * evhttp_request_free() is explicitly called by the user. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_request_own(struct evhttp_request *req); + +/** Returns 1 if the request is owned by the user */ +EVENT2_EXPORT_SYMBOL +int evhttp_request_is_owned(struct evhttp_request *req); + +/** + * Sets extended method cmp callback for this http connection. + * + * @see evhttp_set_ext_method_cmp + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon, + evhttp_ext_method_cb cmp); + +/** + * Returns the connection object associated with the request or NULL + * + * The user needs to either free the request explicitly or call + * evhttp_send_reply_end(). + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_connection *evhttp_request_get_connection(struct evhttp_request *req); + +/** + * Returns the underlying event_base for this connection + */ +EVENT2_EXPORT_SYMBOL +struct event_base *evhttp_connection_get_base(struct evhttp_connection *req); + +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon, + ev_ssize_t new_max_headers_size); + +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_max_body_size(struct evhttp_connection* evcon, + ev_ssize_t new_max_body_size); + +/** Frees an http connection */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_free(struct evhttp_connection *evcon); + +/** Disowns a given connection object + * + * Can be used to tell libevent to free the connection object after + * the last request has completed or failed. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_free_on_completion(struct evhttp_connection *evcon); + +/** Sets the IP address from which http connections are made + * + * Note this resets internal bufferevent fd, so any options that had been + * installed will be flushed. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_local_address(struct evhttp_connection *evcon, + const char *address); + +/** sets the local port from which http connections are made */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_local_port(struct evhttp_connection *evcon, + ev_uint16_t port); + +/** + * Sets the timeout for this connection. + * + * @see evhttp_connection_set_timeout_tv() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_timeout(struct evhttp_connection *evcon, + int timeout); + +/** + * Sets the timeout for this connection for the following events: + * - read, if tv==NULL then it uses default timeout (HTTP_READ_TIMEOUT) + * - write, if tv==NULL then it uses default timeout (HTTP_WRITE_TIMEOUT) + * + * But it does not adjust timeout for the "connect" (for historical reasons). + * + * @param tv the timeout, or NULL + * + * For more precise control: + * @see evhttp_connection_set_connect_timeout_tv() + * @see evhttp_connection_set_read_timeout_tv() + * @see evhttp_connection_set_write_timeout_tv() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon, + const struct timeval *tv); + +/** + * Sets the connect timeout for this connection + * + * @param tv the timeout, or NULL + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon, + const struct timeval *tv); + +/** + * Sets the read timeout for this connection + * + * @param tv the timeout, or NULL + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon, + const struct timeval *tv); + +/** + * Sets the write timeout for this connection + * + * @param tv the timeout, or NULL + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon, + const struct timeval *tv); + +/** + * Sets the delay before retrying requests on this connection. + * + * This is only used if evhttp_connection_set_retries is used to make the + * number of retries at least one. Each retry after the first is twice as long + * as the one before it. + * + * Default delay is HTTP_INITIAL_RETRY_TIMEOUT, which is 2 seconds. + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon, + const struct timeval *tv); + +/** Sets the retry limit for this connection - -1 repeats indefinitely */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_retries(struct evhttp_connection *evcon, + int retry_max); + +/** Set a callback for connection close. */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_closecb(struct evhttp_connection *evcon, + void (*)(struct evhttp_connection *, void *), void *); + +/** Get the remote address and port associated with this connection. */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_get_peer(struct evhttp_connection *evcon, + const char **address, ev_uint16_t *port); + +/** Get the remote address associated with this connection. + * extracted from getpeername() OR from nameserver. + * + * @return NULL if getpeername() return non success, + * or connection is not connected, + * otherwise it return pointer to struct sockaddr_storage */ +EVENT2_EXPORT_SYMBOL +const struct sockaddr* +evhttp_connection_get_addr(struct evhttp_connection *evcon); + +/** + Make an HTTP request over the specified connection. + + The connection gets ownership of the request. On failure, the + request object is no longer valid as it has been freed. + + @param evcon the evhttp_connection object over which to send the request + @param req the previously created and configured request object + @param type the request type EVHTTP_REQ_GET, EVHTTP_REQ_POST, etc. + @param uri the URI associated with the request + @return 0 on success, -1 on failure + @see evhttp_cancel_request() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_make_request(struct evhttp_connection *evcon, + struct evhttp_request *req, + enum evhttp_cmd_type type, const char *uri); + +/** + Cancels a pending HTTP request. + + Cancels an ongoing HTTP request. The callback associated with this request + is not executed and the request object is freed. If the request is + currently being processed, e.g. it is ongoing, the corresponding + evhttp_connection object is going to get reset. + + A request cannot be canceled if its callback has executed already. A request + may be canceled reentrantly from its chunked callback. + + @param req the evhttp_request to cancel; req becomes invalid after this call. +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_cancel_request(struct evhttp_request *req); + +/** + * A structure to hold a parsed URI or Relative-Ref conforming to RFC3986. + */ +struct evhttp_uri; + +/** Returns the request URI */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_request_get_uri(const struct evhttp_request *req); +/** Returns the request URI (parsed) */ +EVENT2_EXPORT_SYMBOL +const struct evhttp_uri *evhttp_request_get_evhttp_uri(const struct evhttp_request *req); +/** Returns the request command */ +EVENT2_EXPORT_SYMBOL +enum evhttp_cmd_type evhttp_request_get_command(const struct evhttp_request *req); + +EVENT2_EXPORT_SYMBOL +int evhttp_request_get_response_code(const struct evhttp_request *req); +EVENT2_EXPORT_SYMBOL +const char * evhttp_request_get_response_code_line(const struct evhttp_request *req); + +/** Returns the input headers */ +EVENT2_EXPORT_SYMBOL +struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req); +/** Returns the output headers */ +EVENT2_EXPORT_SYMBOL +struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req); +/** Returns the input buffer */ +EVENT2_EXPORT_SYMBOL +struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req); +/** Returns the output buffer */ +EVENT2_EXPORT_SYMBOL +struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req); +/** Returns the host associated with the request. If a client sends an absolute + URI, the host part of that is preferred. Otherwise, the input headers are + searched for a Host: header. NULL is returned if no absolute URI or Host: + header is provided. */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_request_get_host(struct evhttp_request *req); + +/* Interfaces for dealing with HTTP headers */ + +/** + Finds the value belonging to a header. + + @param headers the evkeyvalq object in which to find the header + @param key the name of the header to find + @returns a pointer to the value for the header or NULL if the header + could not be found. + @see evhttp_add_header(), evhttp_remove_header() +*/ +EVENT2_EXPORT_SYMBOL +const char *evhttp_find_header(const struct evkeyvalq *headers, + const char *key); + +/** + Removes a header from a list of existing headers. + + @param headers the evkeyvalq object from which to remove a header + @param key the name of the header to remove + @returns 0 if the header was removed, -1 otherwise. + @see evhttp_find_header(), evhttp_add_header() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_remove_header(struct evkeyvalq *headers, const char *key); + +/** + Adds a header to a list of existing headers. + + @param headers the evkeyvalq object to which to add a header + @param key the name of the header + @param value the value belonging to the header + @returns 0 on success, -1 otherwise. + @see evhttp_find_header(), evhttp_clear_headers() +*/ +EVENT2_EXPORT_SYMBOL +int evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *value); + +/** + Removes all headers from the header list. + + @param headers the evkeyvalq object from which to remove all headers +*/ +EVENT2_EXPORT_SYMBOL +void evhttp_clear_headers(struct evkeyvalq *headers); + +/* Miscellaneous utility functions */ + + +/** + Helper function to encode a string for inclusion in a URI. All + characters are replaced by their hex-escaped (%22) equivalents, + except for characters explicitly unreserved by RFC3986 -- that is, + ASCII alphanumeric characters, hyphen, dot, underscore, and tilde. + + The returned string must be freed by the caller. + + @param str an unencoded string + @return a newly allocated URI-encoded string or NULL on failure + */ +EVENT2_EXPORT_SYMBOL +char *evhttp_encode_uri(const char *str); + +/** + As evhttp_encode_uri, but if 'size' is nonnegative, treat the string + as being 'size' bytes long. This allows you to encode strings that + may contain 0-valued bytes. + + The returned string must be freed by the caller. + + @param str an unencoded string + @param size the length of the string to encode, or -1 if the string + is NUL-terminated + @param space_to_plus if true, space characters in 'str' are encoded + as +, not %20. + @return a newly allocate URI-encoded string, or NULL on failure. + */ +EVENT2_EXPORT_SYMBOL +char *evhttp_uriencode(const char *str, ev_ssize_t size, int space_to_plus); + +/** + Helper function to sort of decode a URI-encoded string. Unlike + evhttp_uridecode, it decodes all plus characters that appear + _after_ the first question mark character, but no plusses that occur + before. This is not a good way to decode URIs in whole or in part. + + The returned string must be freed by the caller + + @deprecated This function is deprecated; you probably want to use + evhttp_uridecode instead. + + @param uri an encoded URI + @return a newly allocated unencoded URI or NULL on failure + */ +EVENT2_EXPORT_SYMBOL +char *evhttp_decode_uri(const char *uri); + +/** + Helper function to decode a URI-escaped string or HTTP parameter. + + If 'decode_plus' is 1, then we decode the string as an HTTP parameter + value, and convert all plus ('+') characters to spaces. If + 'decode_plus' is 0, we leave all plus characters unchanged. + + The returned string must be freed by the caller. + + @param uri a URI-encode encoded URI + @param decode_plus determines whether we convert '+' to space. + @param size_out if size_out is not NULL, *size_out is set to the size of the + returned string + @return a newly allocated unencoded URI or NULL on failure + */ +EVENT2_EXPORT_SYMBOL +char *evhttp_uridecode(const char *uri, int decode_plus, + size_t *size_out); + +/** + Helper function to parse out arguments in a query. + + Parsing a URI like + + http://foo.com/?q=test&s=some+thing + + will result in two entries in the key value queue. + + The first entry is: key="q", value="test" + The second entry is: key="s", value="some thing" + + @deprecated This function is deprecated as of Libevent 2.0.9. Use + evhttp_uri_parse and evhttp_parse_query_str instead. + + @param uri the request URI + @param headers the head of the evkeyval queue + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evhttp_parse_query(const char *uri, struct evkeyvalq *headers); + +/** @see evhttp_parse_query_str_flags() */ +EVENT2_EXPORT_SYMBOL +int evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers); + +/** Tolerate queries that are not standard conformant. + * + * Here are some examples: + * + * - test=123&test2 + * with with this flag test2 will be present in the output headers + * + * - test=123&&test2=1 + * will parse the query with this flag + * + * - test=123&=456&test2=1 + * will parse the queyr with this flag, however there won't be empty key + * present + */ +#define EVHTTP_URI_QUERY_NONCONFORMANT 0x01 +/** Prefer last value over the first from query args + * + * Example: test=123&test=456 + * Without: test=123 + * With : test=456 + */ +#define EVHTTP_URI_QUERY_LAST_VAL 0x02 + +/** + Helper function to parse out arguments from the query portion of an + HTTP URI. + + Parsing a query string like + + q=test&s=some+thing + + will result in two entries in the key value queue. + + The first entry is: key="q", value="test" + The second entry is: key="s", value="some thing" + + @param uri the query portion of the URI + @param headers the head of the evkeyval queue + @param flags one or more of EVHTTP_URI_QUERY_* + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags); + +/** + * Escape HTML character entities in a string. + * + * Replaces <, >, ", ' and & with <, >, ", + * ' and & correspondingly. + * + * The returned string needs to be freed by the caller. + * + * @param html an unescaped HTML string + * @return an escaped HTML string or NULL on error + */ +EVENT2_EXPORT_SYMBOL +char *evhttp_htmlescape(const char *html); + +/** + * Return a new empty evhttp_uri with no fields set. + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_uri *evhttp_uri_new(void); + +/** + * Changes the flags set on a given URI. See EVHTTP_URI_* for + * a list of flags. + **/ +EVENT2_EXPORT_SYMBOL +void evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags); + +/** Return the scheme of an evhttp_uri, or NULL if there is no scheme has + * been set and the evhttp_uri contains a Relative-Ref. */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_uri_get_scheme(const struct evhttp_uri *uri); +/** + * Return the userinfo part of an evhttp_uri, or NULL if it has no userinfo + * set. + */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_uri_get_userinfo(const struct evhttp_uri *uri); +/** + * Return the host part of an evhttp_uri, or NULL if it has no host set. + * The host may either be a regular hostname (conforming to the RFC 3986 + * "regname" production), or an IPv4 address, or the empty string, or a + * bracketed IPv6 address, or a bracketed 'IP-Future' address. + * + * Note that having a NULL host means that the URI has no authority + * section, but having an empty-string host means that the URI has an + * authority section with no host part. For example, + * "mailto:user@example.com" has a host of NULL, but "file:///etc/motd" + * has a host of "". + */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_uri_get_host(const struct evhttp_uri *uri); +/** Return the port part of an evhttp_uri, or -1 if there is no port set. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_get_port(const struct evhttp_uri *uri); +/** Return the path part of an evhttp_uri, or NULL if it has no path set */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_uri_get_path(const struct evhttp_uri *uri); +/** Return the query part of an evhttp_uri (excluding the leading "?"), or + * NULL if it has no query set */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_uri_get_query(const struct evhttp_uri *uri); +/** Return the fragment part of an evhttp_uri (excluding the leading "#"), + * or NULL if it has no fragment set */ +EVENT2_EXPORT_SYMBOL +const char *evhttp_uri_get_fragment(const struct evhttp_uri *uri); + +/** Set the scheme of an evhttp_uri, or clear the scheme if scheme==NULL. + * Returns 0 on success, -1 if scheme is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme); +/** Set the userinfo of an evhttp_uri, or clear the userinfo if userinfo==NULL. + * Returns 0 on success, -1 if userinfo is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo); +/** Set the host of an evhttp_uri, or clear the host if host==NULL. + * Returns 0 on success, -1 if host is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_host(struct evhttp_uri *uri, const char *host); +/** Set the port of an evhttp_uri, or clear the port if port==-1. + * Returns 0 on success, -1 if port is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_port(struct evhttp_uri *uri, int port); +/** Set the path of an evhttp_uri, or clear the path if path==NULL. + * Returns 0 on success, -1 if path is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_path(struct evhttp_uri *uri, const char *path); +/** Set the query of an evhttp_uri, or clear the query if query==NULL. + * The query should not include a leading "?". + * Returns 0 on success, -1 if query is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_query(struct evhttp_uri *uri, const char *query); +/** Set the fragment of an evhttp_uri, or clear the fragment if fragment==NULL. + * The fragment should not include a leading "#". + * Returns 0 on success, -1 if fragment is not well-formed. */ +EVENT2_EXPORT_SYMBOL +int evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment); + +/** + * Helper function to parse a URI-Reference as specified by RFC3986. + * + * This function matches the URI-Reference production from RFC3986, + * which includes both URIs like + * + * scheme://[[userinfo]@]foo.com[:port]]/[path][?query][#fragment] + * + * and relative-refs like + * + * [path][?query][#fragment] + * + * Any optional elements portions not present in the original URI are + * left set to NULL in the resulting evhttp_uri. If no port is + * specified, the port is set to -1. + * + * Note that no decoding is performed on percent-escaped characters in + * the string; if you want to parse them, use evhttp_uridecode or + * evhttp_parse_query_str as appropriate. + * + * Note also that most URI schemes will have additional constraints that + * this function does not know about, and cannot check. For example, + * mailto://www.example.com/cgi-bin/fortune.pl is not a reasonable + * mailto url, http://www.example.com:99999/ is not a reasonable HTTP + * URL, and ftp:username@example.com is not a reasonable FTP URL. + * Nevertheless, all of these URLs conform to RFC3986, and this function + * accepts all of them as valid. + * + * @param source_uri the request URI + * @param flags Zero or more EVHTTP_URI_* flags to affect the behavior + * of the parser. + * @return uri container to hold parsed data, or NULL if there is error + * @see evhttp_uri_free() + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_uri *evhttp_uri_parse_with_flags(const char *source_uri, + unsigned flags); + +/** Tolerate URIs that do not conform to RFC3986. + * + * Unfortunately, some HTTP clients generate URIs that, according to RFC3986, + * are not conformant URIs. If you need to support these URIs, you can + * do so by passing this flag to evhttp_uri_parse_with_flags. + * + * Currently, these changes are: + *
    + *
  • Nonconformant URIs are allowed to contain otherwise unreasonable + * characters in their path, query, and fragment components. + *
+ */ +#define EVHTTP_URI_NONCONFORMANT 0x01 +/** + * Strip brackets from the IPv6 address and only for evhttp_uri_get_host(), + * evhttp_uri_join() returns the host with brackets. + * + * Thus you can use host part of the evhttp_uri for getaddrinfo(). + * + * @see also _EVHTTP_URI_HOST_HAS_BRACKETS + */ +#define EVHTTP_URI_HOST_STRIP_BRACKETS 0x04 + +/** Alias for evhttp_uri_parse_with_flags(source_uri, 0) */ +EVENT2_EXPORT_SYMBOL +struct evhttp_uri *evhttp_uri_parse(const char *source_uri); + +/** + * Free all memory allocated for a parsed uri. Only use this for URIs + * generated by evhttp_uri_parse. + * + * @param uri container with parsed data + * @see evhttp_uri_parse() + */ +EVENT2_EXPORT_SYMBOL +void evhttp_uri_free(struct evhttp_uri *uri); + +/** + * Join together the uri parts from parsed data to form a URI-Reference. + * + * Note that no escaping of reserved characters is done on the members + * of the evhttp_uri, so the generated string might not be a valid URI + * unless the members of evhttp_uri are themselves valid. + * + * @param uri container with parsed data + * @param buf destination buffer + * @param limit destination buffer size + * @return an joined uri as string or NULL on error + * @see evhttp_uri_parse() + */ +EVENT2_EXPORT_SYMBOL +char *evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_HTTP_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/http_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/http_compat.h new file mode 100644 index 00000000..979a3a46 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/http_compat.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_HTTP_COMPAT_H_INCLUDED_ +#define EVENT2_HTTP_COMPAT_H_INCLUDED_ + +/** @file event2/http_compat.h + + @brief Potentially non-threadsafe versions of the functions in http.h: provided + only for backwards compatibility. + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +/** + * Start an HTTP server on the specified address and port + * + * @deprecated It does not allow an event base to be specified + * + * @param address the address to which the HTTP server should be bound + * @param port the port number on which the HTTP server should listen + * @return a pointer to a newly initialized evhttp server structure + * or NULL on error + */ +EVENT2_EXPORT_SYMBOL +struct evhttp *evhttp_start(const char *address, ev_uint16_t port); + +/** + * A connection object that can be used to for making HTTP requests. The + * connection object tries to establish the connection when it is given an + * http request object. + * + * @deprecated It does not allow an event base to be specified + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_connection *evhttp_connection_new( + const char *address, ev_uint16_t port); + +/** + * Associates an event base with the connection - can only be called + * on a freshly created connection object that has not been used yet. + * + * @deprecated XXXX Why? + */ +EVENT2_EXPORT_SYMBOL +void evhttp_connection_set_base(struct evhttp_connection *evcon, + struct event_base *base); + + +/** Returns the request URI */ +#define evhttp_request_uri evhttp_request_get_uri + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_EVENT_COMPAT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/http_struct.h b/examples/proto_debuger/third/include/libevent/include/event2/http_struct.h new file mode 100644 index 00000000..4bf5b1ff --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/http_struct.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_HTTP_STRUCT_H_INCLUDED_ +#define EVENT2_HTTP_STRUCT_H_INCLUDED_ + +/** @file event2/http_struct.h + + Data structures for http. Using these structures may hurt forward + compatibility with later versions of Libevent: be careful! + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +/** + * the request structure that a server receives. + * WARNING: expect this structure to change. I will try to provide + * reasonable accessors. + */ +struct evhttp_request { +#if defined(TAILQ_ENTRY) + TAILQ_ENTRY(evhttp_request) next; +#else +struct { + struct evhttp_request *tqe_next; + struct evhttp_request **tqe_prev; +} next; +#endif + + /* the connection object that this request belongs to */ + struct evhttp_connection *evcon; + int flags; +/** The request obj owns the evhttp connection and needs to free it */ +#define EVHTTP_REQ_OWN_CONNECTION 0x0001 +/** Request was made via a proxy */ +#define EVHTTP_PROXY_REQUEST 0x0002 +/** The request object is owned by the user; the user must free it */ +#define EVHTTP_USER_OWNED 0x0004 +/** The request will be used again upstack; freeing must be deferred */ +#define EVHTTP_REQ_DEFER_FREE 0x0008 +/** The request should be freed upstack */ +#define EVHTTP_REQ_NEEDS_FREE 0x0010 + + struct evkeyvalq *input_headers; + struct evkeyvalq *output_headers; + + /* address of the remote host and the port connection came from */ + char *remote_host; + ev_uint16_t remote_port; + + /* cache of the hostname for evhttp_request_get_host */ + char *host_cache; + + enum evhttp_request_kind kind; + enum evhttp_cmd_type type; + + size_t headers_size; + size_t body_size; + + char *uri; /* uri after HTTP request was parsed */ + struct evhttp_uri *uri_elems; /* uri elements */ + + char major; /* HTTP Major number */ + char minor; /* HTTP Minor number */ + + int response_code; /* HTTP Response code */ + char *response_code_line; /* Readable response */ + + struct evbuffer *input_buffer; /* read data */ + ev_int64_t ntoread; + unsigned chunked:1, /* a chunked request */ + userdone:1; /* the user has sent all data */ + + struct evbuffer *output_buffer; /* outgoing post or data */ + + /* Callback */ + void (*cb)(struct evhttp_request *, void *); + void *cb_arg; + + /* + * Chunked data callback - call for each completed chunk if + * specified. If not specified, all the data is delivered via + * the regular callback. + */ + void (*chunk_cb)(struct evhttp_request *, void *); + + /* + * Callback added for forked-daapd so they can collect ICY + * (shoutcast) metadata from the http header. If return + * int is negative the connection will be closed. + */ + int (*header_cb)(struct evhttp_request *, void *); + + /* + * Error callback - called when error is occured. + * @see evhttp_request_error for error types. + * + * @see evhttp_request_set_error_cb() + */ + void (*error_cb)(enum evhttp_request_error, void *); + + /* + * Send complete callback - called when the request is actually + * sent and completed. + */ + void (*on_complete_cb)(struct evhttp_request *, void *); + void *on_complete_cb_arg; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_HTTP_STRUCT_H_INCLUDED_ */ + diff --git a/examples/proto_debuger/third/include/libevent/include/event2/keyvalq_struct.h b/examples/proto_debuger/third/include/libevent/include/event2/keyvalq_struct.h new file mode 100644 index 00000000..bffa54b3 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/keyvalq_struct.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_KEYVALQ_STRUCT_H_INCLUDED_ +#define EVENT2_KEYVALQ_STRUCT_H_INCLUDED_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Fix so that people don't have to run with */ +/* XXXX This code is duplicated with event_struct.h */ +#ifndef TAILQ_ENTRY +#define EVENT_DEFINED_TQENTRY_ +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} +#endif /* !TAILQ_ENTRY */ + +#ifndef TAILQ_HEAD +#define EVENT_DEFINED_TQHEAD_ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; \ + struct type **tqh_last; \ +} +#endif + +/* + * Key-Value pairs. Can be used for HTTP headers but also for + * query argument parsing. + */ +struct evkeyval { + TAILQ_ENTRY(evkeyval) next; + + char *key; + char *value; +}; + +TAILQ_HEAD (evkeyvalq, evkeyval); + +/* XXXX This code is duplicated with event_struct.h */ +#ifdef EVENT_DEFINED_TQENTRY_ +#undef TAILQ_ENTRY +#endif + +#ifdef EVENT_DEFINED_TQHEAD_ +#undef TAILQ_HEAD +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/proto_debuger/third/include/libevent/include/event2/listener.h b/examples/proto_debuger/third/include/libevent/include/event2/listener.h new file mode 100644 index 00000000..53b734e7 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/listener.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_LISTENER_H_INCLUDED_ +#define EVENT2_LISTENER_H_INCLUDED_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct sockaddr; +struct evconnlistener; + +/**@file event2/listener.h + + @brief A callback that we invoke when a listener has a new connection. + + @param listener The evconnlistener + @param fd The new file descriptor + @param addr The source address of the connection + @param socklen The length of addr + @param user_arg the pointer passed to evconnlistener_new() + */ +typedef void (*evconnlistener_cb)(struct evconnlistener *, evutil_socket_t, struct sockaddr *, int socklen, void *); + +/** + A callback that we invoke when a listener encounters a non-retriable error. + + @param listener The evconnlistener + @param user_arg the pointer passed to evconnlistener_new() + */ +typedef void (*evconnlistener_errorcb)(struct evconnlistener *, void *); + +/** Flag: Indicates that we should not make incoming sockets nonblocking + * before passing them to the callback. */ +#define LEV_OPT_LEAVE_SOCKETS_BLOCKING (1u<<0) +/** Flag: Indicates that freeing the listener should close the underlying + * socket. */ +#define LEV_OPT_CLOSE_ON_FREE (1u<<1) +/** Flag: Indicates that we should set the close-on-exec flag, if possible */ +#define LEV_OPT_CLOSE_ON_EXEC (1u<<2) +/** Flag: Indicates that we should disable the timeout (if any) between when + * this socket is closed and when we can listen again on the same port. */ +#define LEV_OPT_REUSEABLE (1u<<3) +/** Flag: Indicates that the listener should be locked so it's safe to use + * from multiple threadcs at once. */ +#define LEV_OPT_THREADSAFE (1u<<4) +/** Flag: Indicates that the listener should be created in disabled + * state. Use evconnlistener_enable() to enable it later. */ +#define LEV_OPT_DISABLED (1u<<5) +/** Flag: Indicates that the listener should defer accept() until data is + * available, if possible. Ignored on platforms that do not support this. + * + * This option can help performance for protocols where the client transmits + * immediately after connecting. Do not use this option if your protocol + * _doesn't_ start out with the client transmitting data, since in that case + * this option will sometimes cause the kernel to never tell you about the + * connection. + * + * This option is only supported by evconnlistener_new_bind(): it can't + * work with evconnlistener_new_fd(), since the listener needs to be told + * to use the option before it is actually bound. + */ +#define LEV_OPT_DEFERRED_ACCEPT (1u<<6) +/** Flag: Indicates that we ask to allow multiple servers (processes or + * threads) to bind to the same port if they each set the option. + * + * SO_REUSEPORT is what most people would expect SO_REUSEADDR to be, however + * SO_REUSEPORT does not imply SO_REUSEADDR. + * + * This is only available on Linux and kernel 3.9+ + */ +#define LEV_OPT_REUSEABLE_PORT (1u<<7) +/** Flag: Indicates that the listener wants to work only in IPv6 socket. + * + * According to RFC3493 and most Linux distributions, default value is to + * work in IPv4-mapped mode. If there is a requirement to bind same port + * on same ip addresses but different handlers for both IPv4 and IPv6, + * it is required to set IPV6_V6ONLY socket option to be sure that the + * code works as expected without affected by bindv6only sysctl setting in + * system. + * + * This socket option also supported by Windows. + */ +#define LEV_OPT_BIND_IPV6ONLY (1u<<8) + +/** + Allocate a new evconnlistener object to listen for incoming TCP connections + on a given file descriptor. + + @param base The event base to associate the listener with. + @param cb A callback to be invoked when a new connection arrives. If the + callback is NULL, the listener will be treated as disabled until the + callback is set. + @param ptr A user-supplied pointer to give to the callback. + @param flags Any number of LEV_OPT_* flags + @param backlog Passed to the listen() call to determine the length of the + acceptable connection backlog. Set to -1 for a reasonable default. + Set to 0 if the socket is already listening. + @param fd The file descriptor to listen on. It must be a nonblocking + file descriptor, and it should already be bound to an appropriate + port and address. +*/ +EVENT2_EXPORT_SYMBOL +struct evconnlistener *evconnlistener_new(struct event_base *base, + evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, + evutil_socket_t fd); +/** + Allocate a new evconnlistener object to listen for incoming TCP connections + on a given address. + + @param base The event base to associate the listener with. + @param cb A callback to be invoked when a new connection arrives. If the + callback is NULL, the listener will be treated as disabled until the + callback is set. + @param ptr A user-supplied pointer to give to the callback. + @param flags Any number of LEV_OPT_* flags + @param backlog Passed to the listen() call to determine the length of the + acceptable connection backlog. Set to -1 for a reasonable default. + @param sa The address to listen for connections on. + @param socklen The length of the address. + */ +EVENT2_EXPORT_SYMBOL +struct evconnlistener *evconnlistener_new_bind(struct event_base *base, + evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, + const struct sockaddr *sa, int socklen); +/** + Disable and deallocate an evconnlistener. + */ +EVENT2_EXPORT_SYMBOL +void evconnlistener_free(struct evconnlistener *lev); +/** + Re-enable an evconnlistener that has been disabled. + */ +EVENT2_EXPORT_SYMBOL +int evconnlistener_enable(struct evconnlistener *lev); +/** + Stop listening for connections on an evconnlistener. + */ +EVENT2_EXPORT_SYMBOL +int evconnlistener_disable(struct evconnlistener *lev); + +/** Return an evconnlistener's associated event_base. */ +EVENT2_EXPORT_SYMBOL +struct event_base *evconnlistener_get_base(struct evconnlistener *lev); + +/** Return the socket that an evconnlistner is listening on. */ +EVENT2_EXPORT_SYMBOL +evutil_socket_t evconnlistener_get_fd(struct evconnlistener *lev); + +/** Change the callback on the listener to cb and its user_data to arg. + */ +EVENT2_EXPORT_SYMBOL +void evconnlistener_set_cb(struct evconnlistener *lev, + evconnlistener_cb cb, void *arg); + +/** Set an evconnlistener's error callback. */ +EVENT2_EXPORT_SYMBOL +void evconnlistener_set_error_cb(struct evconnlistener *lev, + evconnlistener_errorcb errorcb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/proto_debuger/third/include/libevent/include/event2/rpc.h b/examples/proto_debuger/third/include/libevent/include/event2/rpc.h new file mode 100644 index 00000000..9e8830c6 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/rpc.h @@ -0,0 +1,626 @@ +/* + * Copyright (c) 2006-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_RPC_H_INCLUDED_ +#define EVENT2_RPC_H_INCLUDED_ + +/* For int types. */ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file event2/rpc.h + * + * @brief This header files provides basic support for an RPC server and client. + * + * To support RPCs in a server, every supported RPC command needs to be + * defined and registered. + * + * EVRPC_HEADER(SendCommand, Request, Reply); + * + * SendCommand is the name of the RPC command. + * Request is the name of a structure generated by event_rpcgen.py. + * It contains all parameters relating to the SendCommand RPC. The + * server needs to fill in the Reply structure. + * Reply is the name of a structure generated by event_rpcgen.py. It + * contains the answer to the RPC. + * + * To register an RPC with an HTTP server, you need to first create an RPC + * base with: + * + * struct evrpc_base *base = evrpc_init(http); + * + * A specific RPC can then be registered with + * + * EVRPC_REGISTER(base, SendCommand, Request, Reply, FunctionCB, arg); + * + * when the server receives an appropriately formatted RPC, the user callback + * is invoked. The callback needs to fill in the reply structure. + * + * void FunctionCB(EVRPC_STRUCT(SendCommand)* rpc, void *arg); + * + * To send the reply, call EVRPC_REQUEST_DONE(rpc); + * + * See the regression test for an example. + */ + +/** + Determines if the member has been set in the message + + @param msg the message to inspect + @param member the member variable to test for presences + @return 1 if it's present or 0 otherwise. +*/ +#define EVTAG_HAS(msg, member) \ + ((msg)->member##_set == 1) + +#ifndef EVENT2_RPC_COMPAT_H_INCLUDED_ + +/** + Assigns a value to the member in the message. + + @param msg the message to which to assign a value + @param member the name of the member variable + @param value the value to assign +*/ +#define EVTAG_ASSIGN(msg, member, value) \ + (*(msg)->base->member##_assign)((msg), (value)) +/** + Assigns a value to the member in the message. + + @param msg the message to which to assign a value + @param member the name of the member variable + @param value the value to assign + @param len the length of the value +*/ +#define EVTAG_ASSIGN_WITH_LEN(msg, member, value, len) \ + (*(msg)->base->member##_assign)((msg), (value), (len)) +/** + Returns the value for a member. + + @param msg the message from which to get the value + @param member the name of the member variable + @param pvalue a pointer to the variable to hold the value + @return 0 on success, -1 otherwise. +*/ +#define EVTAG_GET(msg, member, pvalue) \ + (*(msg)->base->member##_get)((msg), (pvalue)) +/** + Returns the value for a member. + + @param msg the message from which to get the value + @param member the name of the member variable + @param pvalue a pointer to the variable to hold the value + @param plen a pointer to the length of the value + @return 0 on success, -1 otherwise. +*/ +#define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen) \ + (*(msg)->base->member##_get)((msg), (pvalue), (plen)) + +#endif /* EVENT2_RPC_COMPAT_H_INCLUDED_ */ + +/** + Adds a value to an array. +*/ +#define EVTAG_ARRAY_ADD_VALUE(msg, member, value) \ + (*(msg)->base->member##_add)((msg), (value)) +/** + Allocates a new entry in the array and returns it. +*/ +#define EVTAG_ARRAY_ADD(msg, member) \ + (*(msg)->base->member##_add)(msg) +/** + Gets a variable at the specified offset from the array. +*/ +#define EVTAG_ARRAY_GET(msg, member, offset, pvalue) \ + (*(msg)->base->member##_get)((msg), (offset), (pvalue)) +/** + Returns the number of entries in the array. +*/ +#define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length) + + +struct evbuffer; +struct event_base; +struct evrpc_req_generic; +struct evrpc_request_wrapper; +struct evrpc; + +/** The type of a specific RPC Message + * + * @param rpcname the name of the RPC message + */ +#define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname + +struct evhttp_request; +struct evrpc_status; +struct evrpc_hook_meta; + +/** Creates the definitions and prototypes for an RPC + * + * You need to use EVRPC_HEADER to create structures and function prototypes + * needed by the server and client implementation. The structures have to be + * defined in an .rpc file and converted to source code via event_rpcgen.py + * + * @param rpcname the name of the RPC + * @param reqstruct the name of the RPC request structure + * @param rplystruct the name of the RPC reply structure + * @see EVRPC_GENERATE() + */ +#define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \ +EVRPC_STRUCT(rpcname) { \ + struct evrpc_hook_meta *hook_meta; \ + struct reqstruct* request; \ + struct rplystruct* reply; \ + struct evrpc* rpc; \ + struct evhttp_request* http_req; \ + struct evbuffer* rpc_data; \ +}; \ +EVENT2_EXPORT_SYMBOL \ +int evrpc_send_request_##rpcname(struct evrpc_pool *, \ + struct reqstruct *, struct rplystruct *, \ + void (*)(struct evrpc_status *, \ + struct reqstruct *, struct rplystruct *, void *cbarg), \ + void *); + +struct evrpc_pool; + +/** use EVRPC_GENERATE instead */ +EVENT2_EXPORT_SYMBOL +struct evrpc_request_wrapper *evrpc_make_request_ctx( + struct evrpc_pool *pool, void *request, void *reply, + const char *rpcname, + void (*req_marshal)(struct evbuffer*, void *), + void (*rpl_clear)(void *), + int (*rpl_unmarshal)(void *, struct evbuffer *), + void (*cb)(struct evrpc_status *, void *, void *, void *), + void *cbarg); + +/** Creates a context structure that contains rpc specific information. + * + * EVRPC_MAKE_CTX is used to populate a RPC specific context that + * contains information about marshaling the RPC data types. + * + * @param rpcname the name of the RPC + * @param reqstruct the name of the RPC request structure + * @param rplystruct the name of the RPC reply structure + * @param pool the evrpc_pool over which to make the request + * @param request a pointer to the RPC request structure object + * @param reply a pointer to the RPC reply structure object + * @param cb the callback function to call when the RPC has completed + * @param cbarg the argument to supply to the callback + */ +#define EVRPC_MAKE_CTX(rpcname, reqstruct, rplystruct, \ + pool, request, reply, cb, cbarg) \ + evrpc_make_request_ctx(pool, request, reply, \ + #rpcname, \ + (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ + (void (*)(void *))rplystruct##_clear, \ + (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \ + (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ + cbarg) + +/** Generates the code for receiving and sending an RPC message + * + * EVRPC_GENERATE is used to create the code corresponding to sending + * and receiving a particular RPC message + * + * @param rpcname the name of the RPC + * @param reqstruct the name of the RPC request structure + * @param rplystruct the name of the RPC reply structure + * @see EVRPC_HEADER() + */ +#define EVRPC_GENERATE(rpcname, reqstruct, rplystruct) \ + int evrpc_send_request_##rpcname(struct evrpc_pool *pool, \ + struct reqstruct *request, struct rplystruct *reply, \ + void (*cb)(struct evrpc_status *, \ + struct reqstruct *, struct rplystruct *, void *cbarg), \ + void *cbarg) { \ + return evrpc_send_request_generic(pool, request, reply, \ + (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ + cbarg, \ + #rpcname, \ + (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ + (void (*)(void *))rplystruct##_clear, \ + (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \ +} + +/** Provides access to the HTTP request object underlying an RPC + * + * Access to the underlying http object; can be used to look at headers or + * for getting the remote ip address + * + * @param rpc_req the rpc request structure provided to the server callback + * @return an struct evhttp_request object that can be inspected for + * HTTP headers or sender information. + */ +#define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req + +/** completes the server response to an rpc request */ +EVENT2_EXPORT_SYMBOL +void evrpc_request_done(struct evrpc_req_generic *req); + +/** accessors for request and reply */ +EVENT2_EXPORT_SYMBOL +void *evrpc_get_request(struct evrpc_req_generic *req); +EVENT2_EXPORT_SYMBOL +void *evrpc_get_reply(struct evrpc_req_generic *req); + +/** Creates the reply to an RPC request + * + * EVRPC_REQUEST_DONE is used to answer a request; the reply is expected + * to have been filled in. The request and reply pointers become invalid + * after this call has finished. + * + * @param rpc_req the rpc request structure provided to the server callback + */ +#define EVRPC_REQUEST_DONE(rpc_req) do { \ + struct evrpc_req_generic *req_ = (struct evrpc_req_generic *)(rpc_req); \ + evrpc_request_done(req_); \ +} while (0) + + +struct evrpc_base; +struct evhttp; + +/* functions to start up the rpc system */ + +/** Creates a new rpc base from which RPC requests can be received + * + * @param server a pointer to an existing HTTP server + * @return a newly allocated evrpc_base struct or NULL if an error occurred + * @see evrpc_free() + */ +EVENT2_EXPORT_SYMBOL +struct evrpc_base *evrpc_init(struct evhttp *server); + +/** + * Frees the evrpc base + * + * For now, you are responsible for making sure that no rpcs are ongoing. + * + * @param base the evrpc_base object to be freed + * @see evrpc_init + */ +EVENT2_EXPORT_SYMBOL +void evrpc_free(struct evrpc_base *base); + +/** register RPCs with the HTTP Server + * + * registers a new RPC with the HTTP server, each RPC needs to have + * a unique name under which it can be identified. + * + * @param base the evrpc_base structure in which the RPC should be + * registered. + * @param name the name of the RPC + * @param request the name of the RPC request structure + * @param reply the name of the RPC reply structure + * @param callback the callback that should be invoked when the RPC + * is received. The callback has the following prototype + * void (*callback)(EVRPC_STRUCT(Message)* rpc, void *arg) + * @param cbarg an additional parameter that can be passed to the callback. + * The parameter can be used to carry around state. + */ +#define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \ + evrpc_register_generic(base, #name, \ + (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \ + (void *(*)(void *))request##_new_with_arg, NULL, \ + (void (*)(void *))request##_free, \ + (int (*)(void *, struct evbuffer *))request##_unmarshal, \ + (void *(*)(void *))reply##_new_with_arg, NULL, \ + (void (*)(void *))reply##_free, \ + (int (*)(void *))reply##_complete, \ + (void (*)(struct evbuffer *, void *))reply##_marshal) + +/** + Low level function for registering an RPC with a server. + + Use EVRPC_REGISTER() instead. + + @see EVRPC_REGISTER() +*/ +EVENT2_EXPORT_SYMBOL +int evrpc_register_rpc(struct evrpc_base *, struct evrpc *, + void (*)(struct evrpc_req_generic*, void *), void *); + +/** + * Unregisters an already registered RPC + * + * @param base the evrpc_base object from which to unregister an RPC + * @param name the name of the rpc to unregister + * @return -1 on error or 0 when successful. + * @see EVRPC_REGISTER() + */ +#define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name) + +EVENT2_EXPORT_SYMBOL +int evrpc_unregister_rpc(struct evrpc_base *base, const char *name); + +/* + * Client-side RPC support + */ + +struct evhttp_connection; +struct evrpc_status; + +/** launches an RPC and sends it to the server + * + * EVRPC_MAKE_REQUEST() is used by the client to send an RPC to the server. + * + * @param name the name of the RPC + * @param pool the evrpc_pool that contains the connection objects over which + * the request should be sent. + * @param request a pointer to the RPC request structure - it contains the + * data to be sent to the server. + * @param reply a pointer to the RPC reply structure. It is going to be filled + * if the request was answered successfully + * @param cb the callback to invoke when the RPC request has been answered + * @param cbarg an additional argument to be passed to the client + * @return 0 on success, -1 on failure + */ +#define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg) \ + evrpc_send_request_##name((pool), (request), (reply), (cb), (cbarg)) + +/** + Makes an RPC request based on the provided context. + + This is a low-level function and should not be used directly + unless a custom context object is provided. Use EVRPC_MAKE_REQUEST() + instead. + + @param ctx a context from EVRPC_MAKE_CTX() + @returns 0 on success, -1 otherwise. + @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX() +*/ +EVENT2_EXPORT_SYMBOL +int evrpc_make_request(struct evrpc_request_wrapper *ctx); + +/** creates an rpc connection pool + * + * a pool has a number of connections associated with it. + * rpc requests are always made via a pool. + * + * @param base a pointer to an struct event_based object; can be left NULL + * in singled-threaded applications + * @return a newly allocated struct evrpc_pool object or NULL if an error + * occurred + * @see evrpc_pool_free() + */ +EVENT2_EXPORT_SYMBOL +struct evrpc_pool *evrpc_pool_new(struct event_base *base); +/** frees an rpc connection pool + * + * @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new() + * @see evrpc_pool_new() + */ +EVENT2_EXPORT_SYMBOL +void evrpc_pool_free(struct evrpc_pool *pool); + +/** + * Adds a connection over which rpc can be dispatched to the pool. + * + * The connection object must have been newly created. + * + * @param pool the pool to which to add the connection + * @param evcon the connection to add to the pool. + */ +EVENT2_EXPORT_SYMBOL +void evrpc_pool_add_connection(struct evrpc_pool *pool, + struct evhttp_connection *evcon); + +/** + * Removes a connection from the pool. + * + * The connection object must have been newly created. + * + * @param pool the pool from which to remove the connection + * @param evcon the connection to remove from the pool. + */ +EVENT2_EXPORT_SYMBOL +void evrpc_pool_remove_connection(struct evrpc_pool *pool, + struct evhttp_connection *evcon); + +/** + * Sets the timeout in secs after which a request has to complete. The + * RPC is completely aborted if it does not complete by then. Setting + * the timeout to 0 means that it never timeouts and can be used to + * implement callback type RPCs. + * + * Any connection already in the pool will be updated with the new + * timeout. Connections added to the pool after set_timeout has be + * called receive the pool timeout only if no timeout has been set + * for the connection itself. + * + * @param pool a pointer to a struct evrpc_pool object + * @param timeout_in_secs the number of seconds after which a request should + * timeout and a failure be returned to the callback. + */ +EVENT2_EXPORT_SYMBOL +void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs); + +/** + * Hooks for changing the input and output of RPCs; this can be used to + * implement compression, authentication, encryption, ... + */ + +enum EVRPC_HOOK_TYPE { + EVRPC_INPUT, /**< apply the function to an input hook */ + EVRPC_OUTPUT /**< apply the function to an output hook */ +}; + +#ifndef _WIN32 +/** Deprecated alias for EVRPC_INPUT. Not available on windows, where it + * conflicts with platform headers. */ +#define INPUT EVRPC_INPUT +/** Deprecated alias for EVRPC_OUTPUT. Not available on windows, where it + * conflicts with platform headers. */ +#define OUTPUT EVRPC_OUTPUT +#endif + +/** + * Return value from hook processing functions + */ + +enum EVRPC_HOOK_RESULT { + EVRPC_TERMINATE = -1, /**< indicates the rpc should be terminated */ + EVRPC_CONTINUE = 0, /**< continue processing the rpc */ + EVRPC_PAUSE = 1 /**< pause processing request until resumed */ +}; + +/** adds a processing hook to either an rpc base or rpc pool + * + * If a hook returns TERMINATE, the processing is aborted. On CONTINUE, + * the request is immediately processed after the hook returns. If the + * hook returns PAUSE, request processing stops until evrpc_resume_request() + * has been called. + * + * The add functions return handles that can be used for removing hooks. + * + * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool + * @param hook_type either INPUT or OUTPUT + * @param cb the callback to call when the hook is activated + * @param cb_arg an additional argument for the callback + * @return a handle to the hook so it can be removed later + * @see evrpc_remove_hook() + */ +EVENT2_EXPORT_SYMBOL +void *evrpc_add_hook(void *vbase, + enum EVRPC_HOOK_TYPE hook_type, + int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *), + void *cb_arg); + +/** removes a previously added hook + * + * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool + * @param hook_type either INPUT or OUTPUT + * @param handle a handle returned by evrpc_add_hook() + * @return 1 on success or 0 on failure + * @see evrpc_add_hook() + */ +EVENT2_EXPORT_SYMBOL +int evrpc_remove_hook(void *vbase, + enum EVRPC_HOOK_TYPE hook_type, + void *handle); + +/** resume a paused request + * + * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool + * @param ctx the context pointer provided to the original hook call + */ +EVENT2_EXPORT_SYMBOL +int evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); + +/** adds meta data to request + * + * evrpc_hook_add_meta() allows hooks to add meta data to a request. for + * a client request, the meta data can be inserted by an outgoing request hook + * and retrieved by the incoming request hook. + * + * @param ctx the context provided to the hook call + * @param key a NUL-terminated c-string + * @param data the data to be associated with the key + * @param data_size the size of the data + */ +EVENT2_EXPORT_SYMBOL +void evrpc_hook_add_meta(void *ctx, const char *key, + const void *data, size_t data_size); + +/** retrieves meta data previously associated + * + * evrpc_hook_find_meta() can be used to retrieve meta data associated to a + * request by a previous hook. + * @param ctx the context provided to the hook call + * @param key a NUL-terminated c-string + * @param data pointer to a data pointer that will contain the retrieved data + * @param data_size pointer to the size of the data + * @return 0 on success or -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evrpc_hook_find_meta(void *ctx, const char *key, + void **data, size_t *data_size); + +/** + * returns the connection object associated with the request + * + * @param ctx the context provided to the hook call + * @return a pointer to the evhttp_connection object or NULL if an error + * occurred + */ +EVENT2_EXPORT_SYMBOL +struct evhttp_connection *evrpc_hook_get_connection(void *ctx); + +/** + Function for sending a generic RPC request. + + Do not call this function directly, use EVRPC_MAKE_REQUEST() instead. + + @see EVRPC_MAKE_REQUEST() + */ +EVENT2_EXPORT_SYMBOL +int evrpc_send_request_generic(struct evrpc_pool *pool, + void *request, void *reply, + void (*cb)(struct evrpc_status *, void *, void *, void *), + void *cb_arg, + const char *rpcname, + void (*req_marshal)(struct evbuffer *, void *), + void (*rpl_clear)(void *), + int (*rpl_unmarshal)(void *, struct evbuffer *)); + +/** + Function for registering a generic RPC with the RPC base. + + Do not call this function directly, use EVRPC_REGISTER() instead. + + @see EVRPC_REGISTER() + */ +EVENT2_EXPORT_SYMBOL +int evrpc_register_generic(struct evrpc_base *base, const char *name, + void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, + void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), + int (*req_unmarshal)(void *, struct evbuffer *), + void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *), + int (*rpl_complete)(void *), + void (*rpl_marshal)(struct evbuffer *, void *)); + +/** accessors for obscure and undocumented functionality */ +EVENT2_EXPORT_SYMBOL +struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx); +EVENT2_EXPORT_SYMBOL +void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx, + struct evrpc_pool *pool); +EVENT2_EXPORT_SYMBOL +void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx, + void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg), + void *cb_arg); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_RPC_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/rpc_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/rpc_compat.h new file mode 100644 index 00000000..b3d3de33 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/rpc_compat.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_RPC_COMPAT_H_INCLUDED_ +#define EVENT2_RPC_COMPAT_H_INCLUDED_ + +/** @file event2/rpc_compat.h + + @brief Deprecated versions of the functions in rpc.h: provided only for + backwards compatibility. + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** backwards compatible accessors that work only with gcc */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +#undef EVTAG_ASSIGN +#undef EVTAG_GET +#undef EVTAG_ADD + +#define EVTAG_ASSIGN(msg, member, args...) \ + (*(msg)->base->member##_assign)(msg, ## args) +#define EVTAG_GET(msg, member, args...) \ + (*(msg)->base->member##_get)(msg, ## args) +#define EVTAG_ADD(msg, member, args...) \ + (*(msg)->base->member##_add)(msg, ## args) +#endif +#define EVTAG_LEN(msg, member) ((msg)->member##_length) + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_EVENT_COMPAT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/rpc_struct.h b/examples/proto_debuger/third/include/libevent/include/event2/rpc_struct.h new file mode 100644 index 00000000..f3cb460a --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/rpc_struct.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2006-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_RPC_STRUCT_H_INCLUDED_ +#define EVENT2_RPC_STRUCT_H_INCLUDED_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file event2/rpc_struct.h + + Structures used by rpc.h. Using these structures directly may harm + forward compatibility: be careful! + + */ + +/* Fix so that people don't have to run with */ +#ifndef TAILQ_ENTRY +#define EVENT_DEFINED_TQENTRY_ +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} +#endif /* !TAILQ_ENTRY */ + +/** + * provides information about the completed RPC request. + */ +struct evrpc_status { +#define EVRPC_STATUS_ERR_NONE 0 +#define EVRPC_STATUS_ERR_TIMEOUT 1 +#define EVRPC_STATUS_ERR_BADPAYLOAD 2 +#define EVRPC_STATUS_ERR_UNSTARTED 3 +#define EVRPC_STATUS_ERR_HOOKABORTED 4 + int error; + + /* for looking at headers or other information */ + struct evhttp_request *http_req; +}; + +/* the structure below needs to be synchronized with evrpc_req_generic */ + +/* Encapsulates a request */ +struct evrpc { + TAILQ_ENTRY(evrpc) next; + + /* the URI at which the request handler lives */ + const char* uri; + + /* creates a new request structure */ + void *(*request_new)(void *); + void *request_new_arg; + + /* frees the request structure */ + void (*request_free)(void *); + + /* unmarshals the buffer into the proper request structure */ + int (*request_unmarshal)(void *, struct evbuffer *); + + /* creates a new reply structure */ + void *(*reply_new)(void *); + void *reply_new_arg; + + /* frees the reply structure */ + void (*reply_free)(void *); + + /* verifies that the reply is valid */ + int (*reply_complete)(void *); + + /* marshals the reply into a buffer */ + void (*reply_marshal)(struct evbuffer*, void *); + + /* the callback invoked for each received rpc */ + void (*cb)(struct evrpc_req_generic *, void *); + void *cb_arg; + + /* reference for further configuration */ + struct evrpc_base *base; +}; + +#ifdef EVENT_DEFINED_TQENTRY_ +#undef TAILQ_ENTRY +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_RPC_STRUCT_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/tag.h b/examples/proto_debuger/third/include/libevent/include/event2/tag.h new file mode 100644 index 00000000..e765ea85 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/tag.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_TAG_H_INCLUDED_ +#define EVENT2_TAG_H_INCLUDED_ + +/** @file event2/tag.h + + @brief Helper functions for reading and writing tagged data onto buffers. + + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif + +/* For int types. */ +#include + +struct evbuffer; + +/* + * Marshaling tagged data - We assume that all tags are inserted in their + * numeric order - so that unknown tags will always be higher than the + * known ones - and we can just ignore the end of an event buffer. + */ + +EVENT2_EXPORT_SYMBOL +void evtag_init(void); + +/** + Unmarshals the header and returns the length of the payload + + @param evbuf the buffer from which to unmarshal data + @param ptag a pointer in which the tag id is being stored + @returns -1 on failure or the number of bytes in the remaining payload. +*/ +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal_header(struct evbuffer *evbuf, ev_uint32_t *ptag); + +EVENT2_EXPORT_SYMBOL +void evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag, const void *data, + ev_uint32_t len); +EVENT2_EXPORT_SYMBOL +void evtag_marshal_buffer(struct evbuffer *evbuf, ev_uint32_t tag, + struct evbuffer *data); + +/** + Encode an integer and store it in an evbuffer. + + We encode integers by nybbles; the first nibble contains the number + of significant nibbles - 1; this allows us to encode up to 64-bit + integers. This function is byte-order independent. + + @param evbuf evbuffer to store the encoded number + @param number a 32-bit integer + */ +EVENT2_EXPORT_SYMBOL +void evtag_encode_int(struct evbuffer *evbuf, ev_uint32_t number); +EVENT2_EXPORT_SYMBOL +void evtag_encode_int64(struct evbuffer *evbuf, ev_uint64_t number); + +EVENT2_EXPORT_SYMBOL +void evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, + ev_uint32_t integer); +EVENT2_EXPORT_SYMBOL +void evtag_marshal_int64(struct evbuffer *evbuf, ev_uint32_t tag, + ev_uint64_t integer); + +EVENT2_EXPORT_SYMBOL +void evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, + const char *string); + +EVENT2_EXPORT_SYMBOL +void evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, + struct timeval *tv); + +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, + struct evbuffer *dst); +EVENT2_EXPORT_SYMBOL +int evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag); +EVENT2_EXPORT_SYMBOL +int evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength); +EVENT2_EXPORT_SYMBOL +int evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength); +EVENT2_EXPORT_SYMBOL +int evtag_consume(struct evbuffer *evbuf); + +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag, + ev_uint32_t *pinteger); +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal_int64(struct evbuffer *evbuf, ev_uint32_t need_tag, + ev_uint64_t *pinteger); + +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, + void *data, size_t len); + +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag, + char **pstring); + +EVENT2_EXPORT_SYMBOL +int evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag, + struct timeval *ptv); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_TAG_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/tag_compat.h b/examples/proto_debuger/third/include/libevent/include/event2/tag_compat.h new file mode 100644 index 00000000..51a09e41 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/tag_compat.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_TAG_COMPAT_H_INCLUDED_ +#define EVENT2_TAG_COMPAT_H_INCLUDED_ + +/** @file event2/tag_compat.h + + @brief Obsolete/deprecated functions from tag.h; provided only for backwards + compatibility. + */ + +/** + @name Misnamed functions + + @deprecated These macros are deprecated because their names don't follow + Libevent's naming conventions. Use evtag_encode_int and + evtag_encode_int64 instead. + + @{ +*/ +#define encode_int(evbuf, number) evtag_encode_int((evbuf), (number)) +#define encode_int64(evbuf, number) evtag_encode_int64((evbuf), (number)) +/**@}*/ + +#endif /* EVENT2_TAG_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/thread.h b/examples/proto_debuger/third/include/libevent/include/event2/thread.h new file mode 100644 index 00000000..481a02fe --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/thread.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2008-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_THREAD_H_INCLUDED_ +#define EVENT2_THREAD_H_INCLUDED_ + +/** @file event2/thread.h + + @brief Functions for multi-threaded applications using Libevent. + + When using a multi-threaded application in which multiple threads + add and delete events from a single event base, Libevent needs to + lock its data structures. + + Like the memory-management function hooks, all of the threading functions + _must_ be set up before an event_base is created if you want the base to + use them. + + Most programs will either be using Windows threads or Posix threads. You + can configure Libevent to use one of these evthread_use_windows_threads() or + evthread_use_pthreads() respectively. If you're using another threading + library, you'll need to configure threading functions manually using + evthread_set_lock_callbacks() and evthread_set_condition_callbacks(). + + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + @name Flags passed to lock functions + + @{ +*/ +/** A flag passed to a locking callback when the lock was allocated as a + * read-write lock, and we want to acquire or release the lock for writing. */ +#define EVTHREAD_WRITE 0x04 +/** A flag passed to a locking callback when the lock was allocated as a + * read-write lock, and we want to acquire or release the lock for reading. */ +#define EVTHREAD_READ 0x08 +/** A flag passed to a locking callback when we don't want to block waiting + * for the lock; if we can't get the lock immediately, we will instead + * return nonzero from the locking callback. */ +#define EVTHREAD_TRY 0x10 +/**@}*/ + +#if !defined(EVENT__DISABLE_THREAD_SUPPORT) || defined(EVENT_IN_DOXYGEN_) + +#define EVTHREAD_LOCK_API_VERSION 1 + +/** + @name Types of locks + + @{*/ +/** A recursive lock is one that can be acquired multiple times at once by the + * same thread. No other process can allocate the lock until the thread that + * has been holding it has unlocked it as many times as it locked it. */ +#define EVTHREAD_LOCKTYPE_RECURSIVE 1 +/* A read-write lock is one that allows multiple simultaneous readers, but + * where any one writer excludes all other writers and readers. */ +#define EVTHREAD_LOCKTYPE_READWRITE 2 +/**@}*/ + +/** This structure describes the interface a threading library uses for + * locking. It's used to tell evthread_set_lock_callbacks() how to use + * locking on this platform. + */ +struct evthread_lock_callbacks { + /** The current version of the locking API. Set this to + * EVTHREAD_LOCK_API_VERSION */ + int lock_api_version; + /** Which kinds of locks does this version of the locking API + * support? A bitfield of EVTHREAD_LOCKTYPE_RECURSIVE and + * EVTHREAD_LOCKTYPE_READWRITE. + * + * (Note that RECURSIVE locks are currently mandatory, and + * READWRITE locks are not currently used.) + **/ + unsigned supported_locktypes; + /** Function to allocate and initialize new lock of type 'locktype'. + * Returns NULL on failure. */ + void *(*alloc)(unsigned locktype); + /** Funtion to release all storage held in 'lock', which was created + * with type 'locktype'. */ + void (*free)(void *lock, unsigned locktype); + /** Acquire an already-allocated lock at 'lock' with mode 'mode'. + * Returns 0 on success, and nonzero on failure. */ + int (*lock)(unsigned mode, void *lock); + /** Release a lock at 'lock' using mode 'mode'. Returns 0 on success, + * and nonzero on failure. */ + int (*unlock)(unsigned mode, void *lock); +}; + +/** Sets a group of functions that Libevent should use for locking. + * For full information on the required callback API, see the + * documentation for the individual members of evthread_lock_callbacks. + * + * Note that if you're using Windows or the Pthreads threading library, you + * probably shouldn't call this function; instead, use + * evthread_use_windows_threads() or evthread_use_posix_threads() if you can. + */ +EVENT2_EXPORT_SYMBOL +int evthread_set_lock_callbacks(const struct evthread_lock_callbacks *); + +#define EVTHREAD_CONDITION_API_VERSION 1 + +struct timeval; + +/** This structure describes the interface a threading library uses for + * condition variables. It's used to tell evthread_set_condition_callbacks + * how to use locking on this platform. + */ +struct evthread_condition_callbacks { + /** The current version of the conditions API. Set this to + * EVTHREAD_CONDITION_API_VERSION */ + int condition_api_version; + /** Function to allocate and initialize a new condition variable. + * Returns the condition variable on success, and NULL on failure. + * The 'condtype' argument will be 0 with this API version. + */ + void *(*alloc_condition)(unsigned condtype); + /** Function to free a condition variable. */ + void (*free_condition)(void *cond); + /** Function to signal a condition variable. If 'broadcast' is 1, all + * threads waiting on 'cond' should be woken; otherwise, only on one + * thread is worken. Should return 0 on success, -1 on failure. + * This function will only be called while holding the associated + * lock for the condition. + */ + int (*signal_condition)(void *cond, int broadcast); + /** Function to wait for a condition variable. The lock 'lock' + * will be held when this function is called; should be released + * while waiting for the condition to be come signalled, and + * should be held again when this function returns. + * If timeout is provided, it is interval of seconds to wait for + * the event to become signalled; if it is NULL, the function + * should wait indefinitely. + * + * The function should return -1 on error; 0 if the condition + * was signalled, or 1 on a timeout. */ + int (*wait_condition)(void *cond, void *lock, + const struct timeval *timeout); +}; + +/** Sets a group of functions that Libevent should use for condition variables. + * For full information on the required callback API, see the + * documentation for the individual members of evthread_condition_callbacks. + * + * Note that if you're using Windows or the Pthreads threading library, you + * probably shouldn't call this function; instead, use + * evthread_use_windows_threads() or evthread_use_pthreads() if you can. + */ +EVENT2_EXPORT_SYMBOL +int evthread_set_condition_callbacks( + const struct evthread_condition_callbacks *); + +/** + Sets the function for determining the thread id. + + @param id_fn the identify function Libevent should invoke to + determine the identity of a thread. +*/ +EVENT2_EXPORT_SYMBOL +void evthread_set_id_callback( + unsigned long (*id_fn)(void)); + +#if (defined(_WIN32) && !defined(EVENT__DISABLE_THREAD_SUPPORT)) || defined(EVENT_IN_DOXYGEN_) +/** Sets up Libevent for use with Windows builtin locking and thread ID + functions. Unavailable if Libevent is not built for Windows. + + @return 0 on success, -1 on failure. */ +EVENT2_EXPORT_SYMBOL +int evthread_use_windows_threads(void); +/** + Defined if Libevent was built with support for evthread_use_windows_threads() +*/ +#define EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED 1 +#endif + +#if defined(EVENT__HAVE_PTHREADS) || defined(EVENT_IN_DOXYGEN_) +/** Sets up Libevent for use with Pthreads locking and thread ID functions. + Unavailable if Libevent is not build for use with pthreads. Requires + libraries to link against Libevent_pthreads as well as Libevent. + + @return 0 on success, -1 on failure. */ +EVENT2_EXPORT_SYMBOL +int evthread_use_pthreads(void); + +/* Enables posix mutex priority inheritance + * (if pthread_mutexattr_setprotocol() is supported). */ +#define EVTHREAD_PTHREAD_PRIO_INHERIT 0x01 + +/** + * Sets up Libevent for use with Pthreads locking and thread ID functions. + * Use evthread_use_pthreads_with_flags() to use Pthreads locking, taking the + * specified flags under consideration. + * + * @param flags the flags to apply when setting up Pthreads locking. @see EVTHREAD_PTHREAD_* + * @return 0 on success, -1 on failure. + **/ +EVENT2_EXPORT_SYMBOL +int evthread_use_pthreads_with_flags(int flags); + +/** Defined if Libevent was built with support for evthread_use_pthreads() */ +#define EVTHREAD_USE_PTHREADS_IMPLEMENTED 1 + +#endif + +/** Enable debugging wrappers around the current lock callbacks. If Libevent + * makes one of several common locking errors, exit with an assertion failure. + * + * If you're going to call this function, you must do so before any locks are + * allocated. + **/ +EVENT2_EXPORT_SYMBOL +void evthread_enable_lock_debugging(void); + +/* Old (misspelled) version: This is deprecated; use + * evthread_enable_log_debugging instead. */ +EVENT2_EXPORT_SYMBOL +void evthread_enable_lock_debuging(void); + +#endif /* EVENT__DISABLE_THREAD_SUPPORT */ + +struct event_base; +/** Make sure it's safe to tell an event base to wake up from another thread + or a signal handler. + + You shouldn't need to call this by hand; configuring the base with thread + support should be necessary and sufficient. + + @return 0 on success, -1 on failure. + */ +EVENT2_EXPORT_SYMBOL +int evthread_make_base_notifiable(struct event_base *base); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_THREAD_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/util.h b/examples/proto_debuger/third/include/libevent/include/event2/util.h new file mode 100644 index 00000000..43955bf6 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/util.h @@ -0,0 +1,888 @@ +/* + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_UTIL_H_INCLUDED_ +#define EVENT2_UTIL_H_INCLUDED_ + +/** @file event2/util.h + + @brief Common convenience functions for cross-platform portability and + related socket manipulations. + + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifdef EVENT__HAVE_SYS_TIME_H +#include +#endif +#ifdef EVENT__HAVE_STDINT_H +#include +#elif defined(EVENT__HAVE_INTTYPES_H) +#include +#endif +#ifdef EVENT__HAVE_SYS_TYPES_H +#include +#endif +#ifdef EVENT__HAVE_STDDEF_H +#include +#endif +#ifdef _MSC_VER +#include +#endif +#include +#ifdef EVENT__HAVE_NETDB_H +#include +#endif + +#ifdef _WIN32 +#include +#ifdef EVENT__HAVE_GETADDRINFO +/* for EAI_* definitions. */ +#include +#endif +#else +#ifdef EVENT__HAVE_ERRNO_H +#include +#endif +#include +#endif + +#include + +/* Some openbsd autoconf versions get the name of this macro wrong. */ +#if defined(EVENT__SIZEOF_VOID__) && !defined(EVENT__SIZEOF_VOID_P) +#define EVENT__SIZEOF_VOID_P EVENT__SIZEOF_VOID__ +#endif + +/** + * @name Standard integer types. + * + * Integer type definitions for types that are supposed to be defined in the + * C99-specified stdint.h. Shamefully, some platforms do not include + * stdint.h, so we need to replace it. (If you are on a platform like this, + * your C headers are now over 10 years out of date. You should bug them to + * do something about this.) + * + * We define: + * + *
+ *
ev_uint64_t, ev_uint32_t, ev_uint16_t, ev_uint8_t
+ *
unsigned integer types of exactly 64, 32, 16, and 8 bits + * respectively.
+ *
ev_int64_t, ev_int32_t, ev_int16_t, ev_int8_t
+ *
signed integer types of exactly 64, 32, 16, and 8 bits + * respectively.
+ *
ev_uintptr_t, ev_intptr_t
+ *
unsigned/signed integers large enough + * to hold a pointer without loss of bits.
+ *
ev_ssize_t
+ *
A signed type of the same size as size_t
+ *
ev_off_t
+ *
A signed type typically used to represent offsets within a + * (potentially large) file
+ * + * @{ + */ +#ifdef EVENT__HAVE_UINT64_T +#define ev_uint64_t uint64_t +#define ev_int64_t int64_t +#elif defined(_WIN32) +#define ev_uint64_t unsigned __int64 +#define ev_int64_t signed __int64 +#elif EVENT__SIZEOF_LONG_LONG == 8 +#define ev_uint64_t unsigned long long +#define ev_int64_t long long +#elif EVENT__SIZEOF_LONG == 8 +#define ev_uint64_t unsigned long +#define ev_int64_t long +#elif defined(EVENT_IN_DOXYGEN_) +#define ev_uint64_t ... +#define ev_int64_t ... +#else +#error "No way to define ev_uint64_t" +#endif + +#ifdef EVENT__HAVE_UINT32_T +#define ev_uint32_t uint32_t +#define ev_int32_t int32_t +#elif defined(_WIN32) +#define ev_uint32_t unsigned int +#define ev_int32_t signed int +#elif EVENT__SIZEOF_LONG == 4 +#define ev_uint32_t unsigned long +#define ev_int32_t signed long +#elif EVENT__SIZEOF_INT == 4 +#define ev_uint32_t unsigned int +#define ev_int32_t signed int +#elif defined(EVENT_IN_DOXYGEN_) +#define ev_uint32_t ... +#define ev_int32_t ... +#else +#error "No way to define ev_uint32_t" +#endif + +#ifdef EVENT__HAVE_UINT16_T +#define ev_uint16_t uint16_t +#define ev_int16_t int16_t +#elif defined(_WIN32) +#define ev_uint16_t unsigned short +#define ev_int16_t signed short +#elif EVENT__SIZEOF_INT == 2 +#define ev_uint16_t unsigned int +#define ev_int16_t signed int +#elif EVENT__SIZEOF_SHORT == 2 +#define ev_uint16_t unsigned short +#define ev_int16_t signed short +#elif defined(EVENT_IN_DOXYGEN_) +#define ev_uint16_t ... +#define ev_int16_t ... +#else +#error "No way to define ev_uint16_t" +#endif + +#ifdef EVENT__HAVE_UINT8_T +#define ev_uint8_t uint8_t +#define ev_int8_t int8_t +#elif defined(EVENT_IN_DOXYGEN_) +#define ev_uint8_t ... +#define ev_int8_t ... +#else +#define ev_uint8_t unsigned char +#define ev_int8_t signed char +#endif + +#ifdef EVENT__HAVE_UINTPTR_T +#define ev_uintptr_t uintptr_t +#define ev_intptr_t intptr_t +#elif EVENT__SIZEOF_VOID_P <= 4 +#define ev_uintptr_t ev_uint32_t +#define ev_intptr_t ev_int32_t +#elif EVENT__SIZEOF_VOID_P <= 8 +#define ev_uintptr_t ev_uint64_t +#define ev_intptr_t ev_int64_t +#elif defined(EVENT_IN_DOXYGEN_) +#define ev_uintptr_t ... +#define ev_intptr_t ... +#else +#error "No way to define ev_uintptr_t" +#endif + +#ifdef EVENT__ssize_t +#define ev_ssize_t EVENT__ssize_t +#else +#define ev_ssize_t ssize_t +#endif + +/* Note that we define ev_off_t based on the compile-time size of off_t that + * we used to build Libevent, and not based on the current size of off_t. + * (For example, we don't define ev_off_t to off_t.). We do this because + * some systems let you build your software with different off_t sizes + * at runtime, and so putting in any dependency on off_t would risk API + * mismatch. + */ +#ifdef _WIN32 +#define ev_off_t ev_int64_t +#elif EVENT__SIZEOF_OFF_T == 8 +#define ev_off_t ev_int64_t +#elif EVENT__SIZEOF_OFF_T == 4 +#define ev_off_t ev_int32_t +#elif defined(EVENT_IN_DOXYGEN_) +#define ev_off_t ... +#else +#define ev_off_t off_t +#endif +/**@}*/ + +/* Limits for integer types. + + We're making two assumptions here: + - The compiler does constant folding properly. + - The platform does signed arithmetic in two's complement. +*/ + +/** + @name Limits for integer types + + These macros hold the largest or smallest values possible for the + ev_[u]int*_t types. + + @{ +*/ +#ifndef EVENT__HAVE_STDINT_H +#define EV_UINT64_MAX ((((ev_uint64_t)0xffffffffUL) << 32) | 0xffffffffUL) +#define EV_INT64_MAX ((((ev_int64_t) 0x7fffffffL) << 32) | 0xffffffffL) +#define EV_INT64_MIN ((-EV_INT64_MAX) - 1) +#define EV_UINT32_MAX ((ev_uint32_t)0xffffffffUL) +#define EV_INT32_MAX ((ev_int32_t) 0x7fffffffL) +#define EV_INT32_MIN ((-EV_INT32_MAX) - 1) +#define EV_UINT16_MAX ((ev_uint16_t)0xffffUL) +#define EV_INT16_MAX ((ev_int16_t) 0x7fffL) +#define EV_INT16_MIN ((-EV_INT16_MAX) - 1) +#define EV_UINT8_MAX 255 +#define EV_INT8_MAX 127 +#define EV_INT8_MIN ((-EV_INT8_MAX) - 1) +#else +#define EV_UINT64_MAX UINT64_MAX +#define EV_INT64_MAX INT64_MAX +#define EV_INT64_MIN INT64_MIN +#define EV_UINT32_MAX UINT32_MAX +#define EV_INT32_MAX INT32_MAX +#define EV_INT32_MIN INT32_MIN +#define EV_UINT16_MAX UINT16_MAX +#define EV_INT16_MIN INT16_MIN +#define EV_INT16_MAX INT16_MAX +#define EV_UINT8_MAX UINT8_MAX +#define EV_INT8_MAX INT8_MAX +#define EV_INT8_MIN INT8_MIN +/** @} */ +#endif + + +/** + @name Limits for SIZE_T and SSIZE_T + + @{ +*/ +#if EVENT__SIZEOF_SIZE_T == 8 +#define EV_SIZE_MAX EV_UINT64_MAX +#define EV_SSIZE_MAX EV_INT64_MAX +#elif EVENT__SIZEOF_SIZE_T == 4 +#define EV_SIZE_MAX EV_UINT32_MAX +#define EV_SSIZE_MAX EV_INT32_MAX +#elif defined(EVENT_IN_DOXYGEN_) +#define EV_SIZE_MAX ... +#define EV_SSIZE_MAX ... +#else +#error "No way to define SIZE_MAX" +#endif + +#define EV_SSIZE_MIN ((-EV_SSIZE_MAX) - 1) +/**@}*/ + +#ifdef _WIN32 +#define ev_socklen_t int +#elif defined(EVENT__socklen_t) +#define ev_socklen_t EVENT__socklen_t +#else +#define ev_socklen_t socklen_t +#endif + +#ifdef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY +#if !defined(EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY) \ + && !defined(ss_family) +#define ss_family __ss_family +#endif +#endif + +/** + * A type wide enough to hold the output of "socket()" or "accept()". On + * Windows, this is an intptr_t; elsewhere, it is an int. */ +#ifdef _WIN32 +#define evutil_socket_t intptr_t +#else +#define evutil_socket_t int +#endif + +/** + * Structure to hold information about a monotonic timer + * + * Use this with evutil_configure_monotonic_time() and + * evutil_gettime_monotonic(). + * + * This is an opaque structure; you can allocate one using + * evutil_monotonic_timer_new(). + * + * @see evutil_monotonic_timer_new(), evutil_monotonic_timer_free(), + * evutil_configure_monotonic_time(), evutil_gettime_monotonic() + */ +struct evutil_monotonic_timer +#ifdef EVENT_IN_DOXYGEN_ +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +#define EV_MONOT_PRECISE 1 +#define EV_MONOT_FALLBACK 2 + +/** Format a date string using RFC 1123 format (used in HTTP). + * If `tm` is NULL, current system's time will be used. + * The number of characters written will be returned. + * One should check if the return value is smaller than `datelen` to check if + * the result is truncated or not. + */ +EVENT2_EXPORT_SYMBOL int +evutil_date_rfc1123(char *date, const size_t datelen, const struct tm *tm); + +/** Allocate a new struct evutil_monotonic_timer for use with the + * evutil_configure_monotonic_time() and evutil_gettime_monotonic() + * functions. You must configure the timer with + * evutil_configure_monotonic_time() before using it. + */ +EVENT2_EXPORT_SYMBOL +struct evutil_monotonic_timer * evutil_monotonic_timer_new(void); + +/** Free a struct evutil_monotonic_timer that was allocated using + * evutil_monotonic_timer_new(). + */ +EVENT2_EXPORT_SYMBOL +void evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer); + +/** Set up a struct evutil_monotonic_timer; flags can include + * EV_MONOT_PRECISE and EV_MONOT_FALLBACK. + */ +EVENT2_EXPORT_SYMBOL +int evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer, + int flags); + +/** Query the current monotonic time from a struct evutil_monotonic_timer + * previously configured with evutil_configure_monotonic_time(). Monotonic + * time is guaranteed never to run in reverse, but is not necessarily epoch- + * based, or relative to any other definite point. Use it to make reliable + * measurements of elapsed time between events even when the system time + * may be changed. + * + * It is not safe to use this funtion on the same timer from multiple + * threads. + */ +EVENT2_EXPORT_SYMBOL +int evutil_gettime_monotonic(struct evutil_monotonic_timer *timer, + struct timeval *tp); + +/** Create two new sockets that are connected to each other. + + On Unix, this simply calls socketpair(). On Windows, it uses the + loopback network interface on 127.0.0.1, and only + AF_INET,SOCK_STREAM are supported. + + (This may fail on some Windows hosts where firewall software has cleverly + decided to keep 127.0.0.1 from talking to itself.) + + Parameters and return values are as for socketpair() +*/ +EVENT2_EXPORT_SYMBOL +int evutil_socketpair(int d, int type, int protocol, evutil_socket_t sv[2]); +/** Do platform-specific operations as needed to make a socket nonblocking. + + @param sock The socket to make nonblocking + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_make_socket_nonblocking(evutil_socket_t sock); + +/** Do platform-specific operations to make a listener socket reusable. + + Specifically, we want to make sure that another program will be able + to bind this address right after we've closed the listener. + + This differs from Windows's interpretation of "reusable", which + allows multiple listeners to bind the same address at the same time. + + @param sock The socket to make reusable + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_make_listen_socket_reuseable(evutil_socket_t sock); + +/** Do platform-specific operations to make a listener port reusable. + + Specifically, we want to make sure that multiple programs which also + set the same socket option will be able to bind, listen at the same time. + + This is a feature available only to Linux 3.9+ + + @param sock The socket to make reusable + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_make_listen_socket_reuseable_port(evutil_socket_t sock); + +/** Set ipv6 only bind socket option to make listener work only in ipv6 sockets. + + According to RFC3493 and most Linux distributions, default value for the + sockets is to work in IPv4-mapped mode. In IPv4-mapped mode, it is not possible + to bind same port from different IPv4 and IPv6 handlers. + + @param sock The socket to make in ipv6only working mode + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_make_listen_socket_ipv6only(evutil_socket_t sock); + +/** Do platform-specific operations as needed to close a socket upon a + successful execution of one of the exec*() functions. + + @param sock The socket to be closed + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_make_socket_closeonexec(evutil_socket_t sock); + +/** Do the platform-specific call needed to close a socket returned from + socket() or accept(). + + @param sock The socket to be closed + @return 0 on success (whether the operation is supported or not), + -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_closesocket(evutil_socket_t sock); +#define EVUTIL_CLOSESOCKET(s) evutil_closesocket(s) + +/** Do platform-specific operations, if possible, to make a tcp listener + * socket defer accept()s until there is data to read. + * + * Not all platforms support this. You don't want to do this for every + * listener socket: only the ones that implement a protocol where the + * client transmits before the server needs to respond. + * + * @param sock The listening socket to to make deferred + * @return 0 on success (whether the operation is supported or not), + * -1 on failure +*/ +EVENT2_EXPORT_SYMBOL +int evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock); + +#ifdef _WIN32 +/** Return the most recent socket error. Not idempotent on all platforms. */ +#define EVUTIL_SOCKET_ERROR() WSAGetLastError() +/** Replace the most recent socket error with errcode */ +#define EVUTIL_SET_SOCKET_ERROR(errcode) \ + do { WSASetLastError(errcode); } while (0) +/** Return the most recent socket error to occur on sock. */ +EVENT2_EXPORT_SYMBOL +int evutil_socket_geterror(evutil_socket_t sock); +/** Convert a socket error to a string. */ +EVENT2_EXPORT_SYMBOL +const char *evutil_socket_error_to_string(int errcode); +#define EVUTIL_INVALID_SOCKET INVALID_SOCKET +#elif defined(EVENT_IN_DOXYGEN_) +/** + @name Socket error functions + + These functions are needed for making programs compatible between + Windows and Unix-like platforms. + + You see, Winsock handles socket errors differently from the rest of + the world. Elsewhere, a socket error is like any other error and is + stored in errno. But winsock functions require you to retrieve the + error with a special function, and don't let you use strerror for + the error codes. And handling EWOULDBLOCK is ... different. + + @{ +*/ +/** Return the most recent socket error. Not idempotent on all platforms. */ +#define EVUTIL_SOCKET_ERROR() ... +/** Replace the most recent socket error with errcode */ +#define EVUTIL_SET_SOCKET_ERROR(errcode) ... +/** Return the most recent socket error to occur on sock. */ +#define evutil_socket_geterror(sock) ... +/** Convert a socket error to a string. */ +#define evutil_socket_error_to_string(errcode) ... +#define EVUTIL_INVALID_SOCKET -1 +/**@}*/ +#else /** !EVENT_IN_DOXYGEN_ && !_WIN32 */ +#define EVUTIL_SOCKET_ERROR() (errno) +#define EVUTIL_SET_SOCKET_ERROR(errcode) \ + do { errno = (errcode); } while (0) +#define evutil_socket_geterror(sock) (errno) +#define evutil_socket_error_to_string(errcode) (strerror(errcode)) +#define EVUTIL_INVALID_SOCKET -1 +#endif /** !_WIN32 */ + + +/** + * @name Manipulation macros for struct timeval. + * + * We define replacements + * for timeradd, timersub, timerclear, timercmp, and timerisset. + * + * @{ + */ +#ifdef EVENT__HAVE_TIMERADD +#define evutil_timeradd(tvp, uvp, vvp) timeradd((tvp), (uvp), (vvp)) +#define evutil_timersub(tvp, uvp, vvp) timersub((tvp), (uvp), (vvp)) +#else +#define evutil_timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define evutil_timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif /* !EVENT__HAVE_TIMERADD */ + +#ifdef EVENT__HAVE_TIMERCLEAR +#define evutil_timerclear(tvp) timerclear(tvp) +#else +#define evutil_timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif +/**@}*/ + +/** Return true iff the tvp is related to uvp according to the relational + * operator cmp. Recognized values for cmp are ==, <=, <, >=, and >. */ +#define evutil_timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) + +#ifdef EVENT__HAVE_TIMERISSET +#define evutil_timerisset(tvp) timerisset(tvp) +#else +#define evutil_timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#endif + +/** Replacement for offsetof on platforms that don't define it. */ +#ifdef offsetof +#define evutil_offsetof(type, field) offsetof(type, field) +#else +#define evutil_offsetof(type, field) ((off_t)(&((type *)0)->field)) +#endif + +/* big-int related functions */ +/** Parse a 64-bit value from a string. Arguments are as for strtol. */ +EVENT2_EXPORT_SYMBOL +ev_int64_t evutil_strtoll(const char *s, char **endptr, int base); + +/** Replacement for gettimeofday on platforms that lack it. */ +#ifdef EVENT__HAVE_GETTIMEOFDAY +#define evutil_gettimeofday(tv, tz) gettimeofday((tv), (tz)) +#else +struct timezone; +EVENT2_EXPORT_SYMBOL +int evutil_gettimeofday(struct timeval *tv, struct timezone *tz); +#endif + +/** Replacement for snprintf to get consistent behavior on platforms for + which the return value of snprintf does not conform to C99. + */ +EVENT2_EXPORT_SYMBOL +int evutil_snprintf(char *buf, size_t buflen, const char *format, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 3, 4))) +#endif +; +/** Replacement for vsnprintf to get consistent behavior on platforms for + which the return value of snprintf does not conform to C99. + */ +EVENT2_EXPORT_SYMBOL +int evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap) +#ifdef __GNUC__ + __attribute__((format(printf, 3, 0))) +#endif +; + +/** Replacement for inet_ntop for platforms which lack it. */ +EVENT2_EXPORT_SYMBOL +const char *evutil_inet_ntop(int af, const void *src, char *dst, size_t len); +/** Variation of inet_pton that also parses IPv6 scopes. Public for + unit tests. No reason to call this directly. + */ +EVENT2_EXPORT_SYMBOL +int evutil_inet_pton_scope(int af, const char *src, void *dst, + unsigned *indexp); +/** Replacement for inet_pton for platforms which lack it. */ +EVENT2_EXPORT_SYMBOL +int evutil_inet_pton(int af, const char *src, void *dst); +struct sockaddr; + +/** Parse an IPv4 or IPv6 address, with optional port, from a string. + + Recognized formats are: + - [IPv6Address]:port + - [IPv6Address] + - IPv6Address + - IPv4Address:port + - IPv4Address + + If no port is specified, the port in the output is set to 0. + + @param str The string to parse. + @param out A struct sockaddr to hold the result. This should probably be + a struct sockaddr_storage. + @param outlen A pointer to the number of bytes that that 'out' can safely + hold. Set to the number of bytes used in 'out' on success. + @return -1 if the address is not well-formed, if the port is out of range, + or if out is not large enough to hold the result. Otherwise returns + 0 on success. +*/ +EVENT2_EXPORT_SYMBOL +int evutil_parse_sockaddr_port(const char *str, struct sockaddr *out, int *outlen); + +/** Compare two sockaddrs; return 0 if they are equal, or less than 0 if sa1 + * preceeds sa2, or greater than 0 if sa1 follows sa2. If include_port is + * true, consider the port as well as the address. Only implemented for + * AF_INET and AF_INET6 addresses. The ordering is not guaranteed to remain + * the same between Libevent versions. */ +EVENT2_EXPORT_SYMBOL +int evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2, + int include_port); + +/** As strcasecmp, but always compares the characters in locale-independent + ASCII. That's useful if you're handling data in ASCII-based protocols. + */ +EVENT2_EXPORT_SYMBOL +int evutil_ascii_strcasecmp(const char *str1, const char *str2); +/** As strncasecmp, but always compares the characters in locale-independent + ASCII. That's useful if you're handling data in ASCII-based protocols. + */ +EVENT2_EXPORT_SYMBOL +int evutil_ascii_strncasecmp(const char *str1, const char *str2, size_t n); + +/* Here we define evutil_addrinfo to the native addrinfo type, or redefine it + * if this system has no getaddrinfo(). */ +#ifdef EVENT__HAVE_STRUCT_ADDRINFO +#define evutil_addrinfo addrinfo +#else +/** A definition of struct addrinfo for systems that lack it. + + (This is just an alias for struct addrinfo if the system defines + struct addrinfo.) +*/ +struct evutil_addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for nodename */ + struct sockaddr *ai_addr; /* binary address */ + struct evutil_addrinfo *ai_next; /* next structure in linked list */ +}; +#endif +/** @name evutil_getaddrinfo() error codes + + These values are possible error codes for evutil_getaddrinfo() and + related functions. + + @{ +*/ +#if defined(EAI_ADDRFAMILY) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_ADDRFAMILY EAI_ADDRFAMILY +#else +#define EVUTIL_EAI_ADDRFAMILY -901 +#endif +#if defined(EAI_AGAIN) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_AGAIN EAI_AGAIN +#else +#define EVUTIL_EAI_AGAIN -902 +#endif +#if defined(EAI_BADFLAGS) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_BADFLAGS EAI_BADFLAGS +#else +#define EVUTIL_EAI_BADFLAGS -903 +#endif +#if defined(EAI_FAIL) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_FAIL EAI_FAIL +#else +#define EVUTIL_EAI_FAIL -904 +#endif +#if defined(EAI_FAMILY) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_FAMILY EAI_FAMILY +#else +#define EVUTIL_EAI_FAMILY -905 +#endif +#if defined(EAI_MEMORY) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_MEMORY EAI_MEMORY +#else +#define EVUTIL_EAI_MEMORY -906 +#endif +/* This test is a bit complicated, since some MS SDKs decide to + * remove NODATA or redefine it to be the same as NONAME, in a + * fun interpretation of RFC 2553 and RFC 3493. */ +#if defined(EAI_NODATA) && defined(EVENT__HAVE_GETADDRINFO) && (!defined(EAI_NONAME) || EAI_NODATA != EAI_NONAME) +#define EVUTIL_EAI_NODATA EAI_NODATA +#else +#define EVUTIL_EAI_NODATA -907 +#endif +#if defined(EAI_NONAME) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_NONAME EAI_NONAME +#else +#define EVUTIL_EAI_NONAME -908 +#endif +#if defined(EAI_SERVICE) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_SERVICE EAI_SERVICE +#else +#define EVUTIL_EAI_SERVICE -909 +#endif +#if defined(EAI_SOCKTYPE) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_SOCKTYPE EAI_SOCKTYPE +#else +#define EVUTIL_EAI_SOCKTYPE -910 +#endif +#if defined(EAI_SYSTEM) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_EAI_SYSTEM EAI_SYSTEM +#else +#define EVUTIL_EAI_SYSTEM -911 +#endif + +#define EVUTIL_EAI_CANCEL -90001 + +#if defined(AI_PASSIVE) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_PASSIVE AI_PASSIVE +#else +#define EVUTIL_AI_PASSIVE 0x1000 +#endif +#if defined(AI_CANONNAME) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_CANONNAME AI_CANONNAME +#else +#define EVUTIL_AI_CANONNAME 0x2000 +#endif +#if defined(AI_NUMERICHOST) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_NUMERICHOST AI_NUMERICHOST +#else +#define EVUTIL_AI_NUMERICHOST 0x4000 +#endif +#if defined(AI_NUMERICSERV) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_NUMERICSERV AI_NUMERICSERV +#else +#define EVUTIL_AI_NUMERICSERV 0x8000 +#endif +#if defined(AI_V4MAPPED) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_V4MAPPED AI_V4MAPPED +#else +#define EVUTIL_AI_V4MAPPED 0x10000 +#endif +#if defined(AI_ALL) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_ALL AI_ALL +#else +#define EVUTIL_AI_ALL 0x20000 +#endif +#if defined(AI_ADDRCONFIG) && defined(EVENT__HAVE_GETADDRINFO) +#define EVUTIL_AI_ADDRCONFIG AI_ADDRCONFIG +#else +#define EVUTIL_AI_ADDRCONFIG 0x40000 +#endif +/**@}*/ + +struct evutil_addrinfo; +/** + * This function clones getaddrinfo for systems that don't have it. For full + * details, see RFC 3493, section 6.1. + * + * Limitations: + * - When the system has no getaddrinfo, we fall back to gethostbyname_r or + * gethostbyname, with their attendant issues. + * - The AI_V4MAPPED and AI_ALL flags are not currently implemented. + * + * For a nonblocking variant, see evdns_getaddrinfo. + */ +EVENT2_EXPORT_SYMBOL +int evutil_getaddrinfo(const char *nodename, const char *servname, + const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res); + +/** Release storage allocated by evutil_getaddrinfo or evdns_getaddrinfo. */ +EVENT2_EXPORT_SYMBOL +void evutil_freeaddrinfo(struct evutil_addrinfo *ai); + +EVENT2_EXPORT_SYMBOL +const char *evutil_gai_strerror(int err); + +/** Generate n bytes of secure pseudorandom data, and store them in buf. + * + * Current versions of Libevent use an ARC4-based random number generator, + * seeded using the platform's entropy source (/dev/urandom on Unix-like + * systems; BCryptGenRandom on Windows). This is not actually as secure as it + * should be: ARC4 is a pretty lousy cipher, and the current implementation + * provides only rudimentary prediction- and backtracking-resistance. Don't + * use this for serious cryptographic applications. + */ +EVENT2_EXPORT_SYMBOL +void evutil_secure_rng_get_bytes(void *buf, size_t n); + +/** + * Seed the secure random number generator if needed, and return 0 on + * success or -1 on failure. + * + * It is okay to call this function more than once; it will still return + * 0 if the RNG has been successfully seeded and -1 if it can't be + * seeded. + * + * Ordinarily you don't need to call this function from your own code; + * Libevent will seed the RNG itself the first time it needs good random + * numbers. You only need to call it if (a) you want to double-check + * that one of the seeding methods did succeed, or (b) you plan to drop + * the capability to seed (by chrooting, or dropping capabilities, or + * whatever), and you want to make sure that seeding happens before your + * program loses the ability to do it. + */ +EVENT2_EXPORT_SYMBOL +int evutil_secure_rng_init(void); + +/** + * Set a filename to use in place of /dev/urandom for seeding the secure + * PRNG. Return 0 on success, -1 on failure. + * + * Call this function BEFORE calling any other initialization or RNG + * functions. + * + * (This string will _NOT_ be copied internally. Do not free it while any + * user of the secure RNG might be running. Don't pass anything other than a + * real /dev/...random device file here, or you might lose security.) + * + * This API is unstable, and might change in a future libevent version. + */ +EVENT2_EXPORT_SYMBOL +int evutil_secure_rng_set_urandom_device_file(char *fname); + +#if !defined(EVENT__HAVE_ARC4RANDOM) || defined(EVENT__HAVE_ARC4RANDOM_ADDRANDOM) +/** Seed the random number generator with extra random bytes. + + You should almost never need to call this function; it should be + sufficient to invoke evutil_secure_rng_init(), or let Libevent take + care of calling evutil_secure_rng_init() on its own. + + If you call this function as a _replacement_ for the regular + entropy sources, then you need to be sure that your input + contains a fairly large amount of strong entropy. Doing so is + notoriously hard: most people who try get it wrong. Watch out! + + @param dat a buffer full of a strong source of random numbers + @param datlen the number of bytes to read from datlen + */ +EVENT2_EXPORT_SYMBOL +void evutil_secure_rng_add_bytes(const char *dat, size_t datlen); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT1_EVUTIL_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/visibility.h b/examples/proto_debuger/third/include/libevent/include/event2/visibility.h new file mode 100644 index 00000000..2b07994a --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/visibility.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_VISIBILITY_H_INCLUDED_ +#define EVENT2_VISIBILITY_H_INCLUDED_ + +#include + +#if defined(event_shared_EXPORTS) || \ + defined(event_extra_shared_EXPORTS) || \ + defined(event_core_shared_EXPORTS) || \ + defined(event_pthreads_shared_EXPORTS) || \ + defined(event_openssl_shared_EXPORTS) || \ + defined(event_mbedtls_shared_EXPORTS) + +# if defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) +# define EVENT2_EXPORT_SYMBOL __global +# elif defined __GNUC__ +# define EVENT2_EXPORT_SYMBOL __attribute__ ((visibility("default"))) +# elif defined(_MSC_VER) +# define EVENT2_EXPORT_SYMBOL __declspec(dllexport) +# else +# define EVENT2_EXPORT_SYMBOL /* unknown compiler */ +# endif + +#else /* event_*_EXPORTS */ + +# define EVENT2_EXPORT_SYMBOL + +#endif /* event_*_EXPORTS */ + +/** We need to dllimport event_debug_logging_mask_ into event_extra */ +#if defined(_MSC_VER) +# if defined(event_core_shared_EXPORTS) /** from core export */ +# define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllexport) +# elif defined(event_extra_shared_EXPORTS) || /** from extra import */ \ + defined(EVENT_VISIBILITY_WANT_DLLIMPORT) +# define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllimport) +# endif +#endif /* _MSC_VER */ +#if !defined(EVENT2_CORE_EXPORT_SYMBOL) +# define EVENT2_CORE_EXPORT_SYMBOL EVENT2_EXPORT_SYMBOL +#endif + +#endif /* EVENT2_VISIBILITY_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/event2/watch.h b/examples/proto_debuger/third/include/libevent/include/event2/watch.h new file mode 100644 index 00000000..90007aa3 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/event2/watch.h @@ -0,0 +1,136 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT2_WATCH_H_INCLUDED_ +#define EVENT2_WATCH_H_INCLUDED_ + +/** @file event2/watch.h + + @brief "Prepare" and "check" watchers. + + "Prepare" and "check" watchers. A "prepare" watcher is a callback that fires + immediately before polling for I/O. A "check" watcher is a callback that + fires immediately after polling and before processing any active events. This + may be useful for embedding other libraries' event loops (e.g. UI toolkits) + into libevent's. + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct event_base; +struct evwatch; +struct evwatch_prepare_cb_info; +struct evwatch_check_cb_info; +struct timeval; + +/** + Prepare callback, invoked by event_base_loop immediately before polling for + I/O. + + @param watcher the prepare watcher that invoked this callback. + @param info contextual information passed from event_base_loop. + @param arg additional user-defined argument, set in `evwatch_prepare_new`. + */ +typedef void (*evwatch_prepare_cb)(struct evwatch *, const struct evwatch_prepare_cb_info *, void *); + +/** + Check callback, invoked by event_base_loop immediately after polling for I/O + and before processing any active events. + + @param watcher the check watcher that invoked this callback. + @param info contextual information passed from event_base_loop. + @param arg additional user-defined argument, set in `evwatch_check_new`. + */ +typedef void (*evwatch_check_cb)(struct evwatch *, const struct evwatch_check_cb_info *, void *); + +/** + Register a new "prepare" watcher, to be called in the event loop prior to + polling for events. Watchers will be called in the order they were + registered. + + @param base the event_base to operate on. + @param callback the callback function to invoke. + @param arg additional user-defined argument provided to the callback. + @return a pointer to the newly allocated event watcher. + */ +EVENT2_EXPORT_SYMBOL +struct evwatch *evwatch_prepare_new(struct event_base *base, evwatch_prepare_cb callback, void *arg); + +/** + Register a new "check" watcher, to be called in the event loop after polling + for events and before handling them. Watchers will be called in the order + they were registered. + + @param base the event_base to operate on. + @param callback the callback function to invoke. + @param arg additional user-defined argument provided to the callback. + @return a pointer to the newly allocated event watcher. + */ +EVENT2_EXPORT_SYMBOL +struct evwatch *evwatch_check_new(struct event_base *base, evwatch_check_cb callback, void *arg); + +/** + Get the event_base that a given evwatch is registered with. + + @param watcher the watcher to get the event_base for. + @return the event_base for the given watcher. + */ +EVENT2_EXPORT_SYMBOL +struct event_base *evwatch_base(struct evwatch *watcher); + +/** + Deregister and deallocate a watcher. Any watchers not freed using + evwatch_free will eventually be deallocated in event_base_free + (calling evwatch_free on a watcher after event_base_free has been + called on its corresponding event_base is an error). + + @param watcher the watcher to deregister and deallocate. + */ +EVENT2_EXPORT_SYMBOL +void evwatch_free(struct evwatch *watcher); + +/** + Get the timeout (the expected polling duration) passed to the underlying + implementation's `dispatch`. This value will only be set if there are pending + EV_TIMEOUT events and if the event_base isn't in EVLOOP_NONBLOCK mode. It may + be a useful performance statistic to compare the expected polling duration + against the actual polling duration (that is, the time difference measured + between this prepare callback and the following check callback). + + @param info the "prepare" callback info. + @param timeout address of a timeval to write the polling duration to. + @return 1 if a value was written to *timeout, or 0 if not. + */ +EVENT2_EXPORT_SYMBOL +int evwatch_prepare_get_timeout(const struct evwatch_prepare_cb_info *info, struct timeval *timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT2_WATCH_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/evhttp.h b/examples/proto_debuger/third/include/libevent/include/evhttp.h new file mode 100644 index 00000000..549bc9b1 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/evhttp.h @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2007 Niels Provos + * Copyright 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT1_EVHTTP_H_INCLUDED_ +#define EVENT1_EVHTTP_H_INCLUDED_ + +/** @file evhttp.h + + An http implementation subsystem for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other + headers. + */ + +#include +#include +#include +#include + +#endif /* EVENT1_EVHTTP_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/evrpc.h b/examples/proto_debuger/third/include/libevent/include/evrpc.h new file mode 100644 index 00000000..7e986f7d --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/evrpc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000-2007 Niels Provos + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT1_EVRPC_H_INCLUDED_ +#define EVENT1_EVRPC_H_INCLUDED_ + +/** @file evrpc.h + + An RPC system for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other + headers. + */ + +#include +#include +#include +#include + +#endif /* EVENT1_EVRPC_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/include/libevent/include/evutil.h b/examples/proto_debuger/third/include/libevent/include/evutil.h new file mode 100644 index 00000000..12c137d7 --- /dev/null +++ b/examples/proto_debuger/third/include/libevent/include/evutil.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef EVENT1_EVUTIL_H_INCLUDED_ +#define EVENT1_EVUTIL_H_INCLUDED_ + +/** @file evutil.h + + Utility and compatibility functions for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. +*/ + +#include + +#endif /* EVENT1_EVUTIL_H_INCLUDED_ */ diff --git a/examples/proto_debuger/third/lib/event.exp b/examples/proto_debuger/third/lib/event.exp new file mode 100644 index 0000000000000000000000000000000000000000..e1d638b82367f2e02c6e810bda7487b03ef1d152 GIT binary patch literal 85617 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 literal 0 HcmV?d00001 diff --git a/examples/proto_debuger/third/lib/event.lib b/examples/proto_debuger/third/lib/event.lib new file mode 100644 index 0000000000000000000000000000000000000000..b84658ab49c4a88dd2c19fd3c2bb091402959382 GIT binary patch literal 140020 zcmeEvdA!`y`Tsd%k1e$?5utWLkVNb|K|~s%D8}U8xw#|v&fLzOi9~Cys;a7@t)i5o zwA!kwqN)*Fr1q`WSZWu<7O}G?*0b-=IUDR!sJ3

y;2q6iMK3csNG)zJo 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

-Yr3)Z+k<>7;$|BU*StypW$RadRpWm?<+ywdX? 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 IWRg+;2iRP-CIA2c literal 0 HcmV?d00001 diff --git a/examples/proto_debuger/third/lib/event_core.exp b/examples/proto_debuger/third/lib/event_core.exp new file mode 100644 index 0000000000000000000000000000000000000000..3063a3153b6afcf387e5ed3d451c00e1dac6696f GIT binary patch literal 52006 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 D$0k@* literal 0 HcmV?d00001 diff --git a/examples/proto_debuger/third/lib/event_core.lib b/examples/proto_debuger/third/lib/event_core.lib new file mode 100644 index 0000000000000000000000000000000000000000..f3b7c431748ea3dac8d93d5a88066683d8e002b3 GIT binary patch literal 86914 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�g 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≪}Bxy|FW|Q7k;voXTXA-dg&W?4EVZ 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 Ug5DEcPEq5DHW&YY`f;592Pb#f&Hw-a literal 0 HcmV?d00001 diff --git a/examples/proto_debuger/third/lib/event_extra.lib b/examples/proto_debuger/third/lib/event_extra.lib new file mode 100644 index 0000000000000000000000000000000000000000..579b7745c6b79aec18e98e15ea8301d75b757a93 GIT binary patch literal 57892 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 literal 0 HcmV?d00001 diff --git a/examples/proto_debuger/third/lib/event_openssl.exp b/examples/proto_debuger/third/lib/event_openssl.exp new file mode 100644 index 0000000000000000000000000000000000000000..84403f6c908770b831401c301f9c3f0523ddfd8d GIT binary patch literal 2463 zcmeHI%Wl&^6uqenv^*Q$uSJA{lnUfWUQH^HLO}=wltNL}#Yo1n$Ej7vj%=q1d;my@ zZ(zwUuwlg)utGwx;|t&i;NEf5I8K6K!H!Ah_{^C*cWyHGj;$9n@Dm%~4{#CUCUeV( zjNJh~zGeU{d^Toc?JRNp$`)^STlw`^1*k{>D)wY+z`_cRX^(-9?%?2VA87yPnSmLQ zU>5elemDSgFb{l(dy(#UxEF@5Y`HEpySB}PSa0#YIh_ZAAB@cIuF`GCjd-AYyf<;0 zoEWa__jJn%qGx)z)r~B_=S?-nNG8sOf8!|h&26+#2Zg?M)8$5>+pf_HNA{sP3U=~L zz&+mbBgcsN*eZ%FUUe7`ZWg;FvS*)QIYdk+)bfZ21S=pO7i?tBeA;C4oGlEgJ9ucg8Nck$k7UEICZXuo%%tbsV z*d4_4f^`rV1iO!TL9hrhD;WLO@7NbH&tF1@M7X=GZ24`j$foZZo!_fh%w=OX>ZQq7m&V9>-^l`hjBxe(2j#uJCv-Dydy2}NE)GrHC$nN2PBOSp)VW!fStdU8x9Gs$LZ@l()LT@x1#F9F)0 zN-t@az6^3`L#3Fu8D0wHg$grmk-Qwp3l(bGW_U?7OuyZc9SbuuL$3h|8a6i~SydNs z`&dc7bm-(HNWNa^lq3kBuNrMU-PbsZZGu*32M16{D6!RALg_sW@J8tGDfv|_K~;k{ zDWwSSQ%VWGq?9tu;nwl)v7ZX$Q%V&crIaP;q?8)GPAPSGJE~|ZeArVk3~|xYlN$Xa z0G9;D5Gyyv6mLvRpU+9n?^m+ zOF8vlsD!xo!mXD`Aa2}{xD-{rv}&u07KsYfL#5E~^X|m6o*6p}VWrRW_@48k{2E)*O2HT!LfAPX{-adQo(wXJ?i}?%7w)3S^^KEzCsnzRM*!I%p z#YL42HzITaRsPeTdCK$2ZE5 z&}JE{B%n~Ox|?>X;`v|M^|cMZ}s8DR_g$OtrW1`3(WNaS=z9MfZH_Q83ZN?wlcu2e%hyTZWy>vcq(xukVG2Y*oXZ{ zp$7x#LofQZdtFpruUxmPdv+5x5p=0|RY8J?1!^m+Jqsm3o3`-^71Fj1aJtEXS8dx( zLdvD2m(Wa1xlmP~%UIz^$=f=#(a$Dg_OK3T^sSay-+NpADYHgB*@}^U*otd62gZrO<$aqq6ABlpv2sanODxQs)hPSU0)KHRypOEoF1)|3Vz`@-QU4?kcLMDe}wBU8ZC_93+ZyS@%vc&6xrRdlbfliiQ~MB?R3nU5H#`7wy&TR_9~HL=q;XrL{mnPM7Z!Vb-J zbBFie=AZCm>A=U~iiaew((h}u(GKaDj+;S~(>W=FlKAiI?4!F4L)lzFmqDcfweu@w z&E`$sTYru>PTU>2 zSk&uHZ3waT&o(=@(0}#G#)ApcpP&XLUmcnYR5c)Wjn14)78cveg>%O?1crIcpM!3=5LP2z7`8wpG&IxxbetMsoDA0k3+w_Puf!&?VOpxf2lpttvUI2 i>d6Z}`F@RV`N_8j+BGN7=MMeOC-2p0Z$2tj-TwnK$;4Fv literal 0 HcmV?d00001 diff --git a/examples/proto_debuger/uart_process.cpp b/examples/proto_debuger/uart_process.cpp index c5e0a7d1..0dad0d74 100644 --- a/examples/proto_debuger/uart_process.cpp +++ b/examples/proto_debuger/uart_process.cpp @@ -124,7 +124,6 @@ void UartForm::Init() return true; }); } - } void UartForm::UpdateRecvEdit()