/* vim: set expandtab ts=4 sw=4: */
/*
* You may redistribute this program and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef SwitchPinger_H
#define SwitchPinger_H
#include "benc/String.h"
#include "dht/Address.h"
#include "crypto/random/Random.h"
#include "interface/Iface.h"
#include "util/events/EventBase.h"
#include "util/log/Log.h"
#include "util/Linker.h"
Linker_require("net/SwitchPinger.c");
#include
#define SwitchPinger_DEFAULT_MAX_CONCURRENT_PINGS 50
enum SwitchPinger_Result
{
/** Ping responded to ok. */
SwitchPinger_Result_OK,
/** Response label differs from sent label. */
SwitchPinger_Result_LABEL_MISMATCH,
/** Response contains different data than what was sent. */
SwitchPinger_Result_WRONG_DATA,
/** Instead of a normal response, got an error control packet. */
SwitchPinger_Result_ERROR_RESPONSE,
/** A sub-set of ERROR_RESPONSE where the route contains a loop. */
SwitchPinger_Result_LOOP_ROUTE,
/** Ping timeout. */
SwitchPinger_Result_TIMEOUT
};
struct SwitchPinger_Ping;
struct SwitchPinger_Response
{
/** SwitchPinger_Result_OK if all went well, otherwise SwitchPinger_Result_* */
enum SwitchPinger_Result res;
/** the label as of the responding node in host order. */
uint64_t label;
/** the content of the ping response. */
String* data;
/** the number of milliseconds since the original ping was sent. */
uint64_t milliseconds;
/** the version of the node which was pinged. */
uint32_t version;
/** The key for the node which was pinged, if not a keyPing then this is set to 0. */
uint8_t key[32];
// relevant to messages of type GETSNODE
uint32_t kbpsLimit;
struct Address snode;
struct SwitchPinger_Ping* ping;
};
/** Callback which will be called when the ping response comes back. */
typedef void (* SwitchPinger_ResponseCallback)(struct SwitchPinger_Response* resp, void* userData);
enum SwitchPinger_Type
{
SwitchPinger_Type_PING,
SwitchPinger_Type_KEYPING,
SwitchPinger_Type_GETSNODE
};
struct SwitchPinger_Ping
{
/**
* The allocator which is set by SwitchPinger_ping() and can be used to
* allocate space which will be freed when the ping completes.
*/
struct Allocator* pingAlloc;
enum SwitchPinger_Type type;
// relevant only for pings of type GETSNODE
uint32_t kbpsLimit;
struct Address snode;
/**
* This is NULL by default and is set by the caller of Pinger_ping(),
* when onResponse() is called, whatever this is, will be given to it.
*/
void* onResponseContext;
};
struct SwitchPinger
{
struct Iface controlHandlerIf;
};
String* SwitchPinger_resultString(enum SwitchPinger_Result result);
/**
* Allocate a ping message.
*
* @param label the HOST ORDER label of the node to send the ping message to.
* @param data the content of the ping to send, if NULL, an empty string will be
* returned in the response.
* @param timeoutMilliseconds how long to wait before failing the ping.
* @param onResponse the callback after the on pong or timeout.
* @param alloc free this to cancel the ping.
* @param ctx the pinger
*/
struct SwitchPinger_Ping* SwitchPinger_newPing(uint64_t label,
String* data,
uint32_t timeoutMilliseconds,
SwitchPinger_ResponseCallback onResponse,
struct Allocator* alloc,
struct SwitchPinger* ctx);
struct SwitchPinger* SwitchPinger_new(struct EventBase* eventBase,
struct Random* rand,
struct Log* logger,
struct Address* myAddr,
struct Allocator* alloc);
#endif