initial commit
This commit is contained in:
commit
636959b37b
2474 files changed
+1343178
No files matched your search
@@ -0,0 +1,76 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_H__
|
||||
#define __PJLIB_UTIL_H__
|
||||
|
||||
/**
|
||||
* @file pjlib-util.h
|
||||
* @brief pjlib-util.h
|
||||
*/
|
||||
|
||||
/* Base */
|
||||
#include <pjlib-util/errno.h>
|
||||
#include <pjlib-util/types.h>
|
||||
|
||||
/* Getopt */
|
||||
#include <pjlib-util/getopt.h>
|
||||
|
||||
/* Crypto */
|
||||
#include <pjlib-util/base64.h>
|
||||
#include <pjlib-util/crc32.h>
|
||||
#include <pjlib-util/hmac_md5.h>
|
||||
#include <pjlib-util/hmac_sha1.h>
|
||||
#include <pjlib-util/md5.h>
|
||||
#include <pjlib-util/sha1.h>
|
||||
|
||||
/* DNS and resolver */
|
||||
#include <pjlib-util/dns.h>
|
||||
#include <pjlib-util/resolver.h>
|
||||
#include <pjlib-util/srv_resolver.h>
|
||||
|
||||
/* Simple DNS server */
|
||||
#include <pjlib-util/dns_server.h>
|
||||
|
||||
/* Text scanner and utilities */
|
||||
#include <pjlib-util/scanner.h>
|
||||
#include <pjlib-util/string.h>
|
||||
|
||||
/* XML */
|
||||
#include <pjlib-util/xml.h>
|
||||
|
||||
/* JSON */
|
||||
#include <pjlib-util/json.h>
|
||||
|
||||
/* Old STUN */
|
||||
#include <pjlib-util/stun_simple.h>
|
||||
|
||||
/* PCAP */
|
||||
#include <pjlib-util/pcap.h>
|
||||
|
||||
/* HTTP */
|
||||
#include <pjlib-util/http_client.h>
|
||||
|
||||
/** CLI **/
|
||||
#include <pjlib-util/cli.h>
|
||||
#include <pjlib-util/cli_console.h>
|
||||
#include <pjlib-util/cli_telnet.h>
|
||||
|
||||
#endif /* __PJLIB_UTIL_H__ */
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_BASE64_H__
|
||||
#define __PJLIB_UTIL_BASE64_H__
|
||||
|
||||
/**
|
||||
* @file base64.h
|
||||
* @brief Base64 encoding and decoding
|
||||
*/
|
||||
|
||||
#include <pjlib-util/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_BASE64 Base64 Encoding/Decoding
|
||||
* @ingroup PJLIB_UTIL_ENCRYPTION
|
||||
* @{
|
||||
* This module implements base64 encoding and decoding.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper macro to calculate the approximate length required for base256 to
|
||||
* base64 conversion.
|
||||
*/
|
||||
#define PJ_BASE256_TO_BASE64_LEN(len) (len * 4 / 3 + 3)
|
||||
|
||||
/**
|
||||
* Helper macro to calculate the approximage length required for base64 to
|
||||
* base256 conversion.
|
||||
*/
|
||||
#define PJ_BASE64_TO_BASE256_LEN(len) (len * 3 / 4)
|
||||
|
||||
|
||||
/**
|
||||
* Encode a buffer into base64 encoding.
|
||||
*
|
||||
* @param input The input buffer.
|
||||
* @param in_len Size of the input buffer.
|
||||
* @param output Output buffer. Caller must allocate this buffer with
|
||||
* the appropriate size.
|
||||
* @param out_len On entry, it specifies the length of the output buffer.
|
||||
* Upon return, this will be filled with the actual
|
||||
* length of the output buffer.
|
||||
*
|
||||
* @return PJ_SUCCESS on success.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len);
|
||||
|
||||
|
||||
/**
|
||||
* Decode base64 string.
|
||||
*
|
||||
* @param input Input string.
|
||||
* @param out Buffer to store the output. Caller must allocate
|
||||
* this buffer with the appropriate size.
|
||||
* @param out_len On entry, it specifies the length of the output buffer.
|
||||
* Upon return, this will be filled with the actual
|
||||
* length of the output.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_base64_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_BASE64_H__ */
|
||||
|
||||
@@ -0,0 +1,531 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_CLI_H__
|
||||
#define __PJLIB_UTIL_CLI_H__
|
||||
|
||||
/**
|
||||
* @file cli.h
|
||||
* @brief Command Line Interface
|
||||
*/
|
||||
|
||||
#include <pjlib-util/types.h>
|
||||
#include <pj/list.h>
|
||||
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_CLI Command Line Interface Framework
|
||||
* @{
|
||||
* A CLI framework features an interface for defining command specification,
|
||||
* parsing, and executing a command.
|
||||
* It also features an interface to communicate with various front-ends,
|
||||
* such as console, telnet.
|
||||
* Application normally needs only one CLI instance to be created.
|
||||
* On special cases, application could also create multiple CLI
|
||||
* instances, with each instance has specific command structure.
|
||||
*
|
||||
\verbatim
|
||||
| vid help Show this help screen |
|
||||
| vid enable|disable Enable or disable video in next offer/answer |
|
||||
| vid call add Add video stream for current call |
|
||||
| vid call cap N ID Set capture dev ID for stream #N in current call |
|
||||
| disable_codec g711|g722 Show this help screen |
|
||||
<CMD name='vid' id='0' desc="">
|
||||
<CMD name='help' id='0' desc='' />
|
||||
<CMD name='enable' id='0' desc='' />
|
||||
<CMD name='disable' id='0' desc='' />
|
||||
<CMD name='call' id='0' desc='' >
|
||||
<CMD name='add' id='101' desc='...' />
|
||||
<CMD name='cap' id='102' desc='...' >
|
||||
<ARG name='streamno' type='int' desc='...' id='1'/>
|
||||
<ARG name='devid' type='int' optional='1' id='2'/>
|
||||
</CMD>
|
||||
</CMD>
|
||||
</CMD>
|
||||
<CMD name='disable_codec' id=0 desc="">
|
||||
<ARG name='codec_list' type='choice' id='3'>
|
||||
<CHOICE value='g711'/>
|
||||
<CHOICE value='g722'/>
|
||||
</ARG>
|
||||
</CMD>
|
||||
\endverbatim
|
||||
*/
|
||||
|
||||
/**
|
||||
* This opaque structure represents a CLI application. A CLI application is
|
||||
* the root placeholder of other CLI objects. In an application, one (and
|
||||
* normally only one) CLI application instance needs to be created.
|
||||
*/
|
||||
typedef struct pj_cli_t pj_cli_t;
|
||||
|
||||
/**
|
||||
* Type of command id.
|
||||
*/
|
||||
typedef int pj_cli_cmd_id;
|
||||
|
||||
/**
|
||||
* This describes the parameters to be specified when creating a CLI
|
||||
* application with pj_cli_create(). Application MUST initialize this
|
||||
* structure by calling pj_cli_cfg_default() before using it.
|
||||
*/
|
||||
typedef struct pj_cli_cfg
|
||||
{
|
||||
/**
|
||||
* The application name, which will be used in places such as logs.
|
||||
* This field is mandatory.
|
||||
*/
|
||||
pj_str_t name;
|
||||
|
||||
/**
|
||||
* Optional application title, which will be used in places such as
|
||||
* window title. If not specified, the application name will be used
|
||||
* as the title.
|
||||
*/
|
||||
pj_str_t title;
|
||||
|
||||
/**
|
||||
* The pool factory where all memory allocations will be taken from.
|
||||
* This field is mandatory.
|
||||
*/
|
||||
pj_pool_factory *pf;
|
||||
|
||||
} pj_cli_cfg;
|
||||
|
||||
/**
|
||||
* Type of argument id.
|
||||
*/
|
||||
typedef int pj_cli_arg_id;
|
||||
|
||||
/**
|
||||
* Forward declaration of pj_cli_cmd_spec structure.
|
||||
*/
|
||||
typedef struct pj_cli_cmd_spec pj_cli_cmd_spec;
|
||||
|
||||
/**
|
||||
* Forward declaration for pj_cli_sess, which will be declared in cli_imp.h.
|
||||
*/
|
||||
typedef struct pj_cli_sess pj_cli_sess;
|
||||
|
||||
/**
|
||||
* Forward declaration for CLI front-end.
|
||||
*/
|
||||
typedef struct pj_cli_front_end pj_cli_front_end;
|
||||
|
||||
/**
|
||||
* Forward declaration for CLI argument spec structure.
|
||||
*/
|
||||
typedef struct pj_cli_arg_spec pj_cli_arg_spec;
|
||||
|
||||
/**
|
||||
* This structure contains the command to be executed by command handler.
|
||||
*/
|
||||
typedef struct pj_cli_cmd_val
|
||||
{
|
||||
/** The session on which the command was executed on. */
|
||||
pj_cli_sess *sess;
|
||||
|
||||
/** The command specification being executed. */
|
||||
const pj_cli_cmd_spec *cmd;
|
||||
|
||||
/** Number of argvs. */
|
||||
int argc;
|
||||
|
||||
/** Array of args, with argv[0] specifies the name of the cmd. */
|
||||
pj_str_t argv[PJ_CLI_MAX_ARGS];
|
||||
|
||||
} pj_cli_cmd_val;
|
||||
|
||||
/**
|
||||
* This structure contains the hints information for the end user.
|
||||
* This structure could contain either command or argument information.
|
||||
* The front-end will format the information and present it to the user.
|
||||
*/
|
||||
typedef struct pj_cli_hint_info
|
||||
{
|
||||
/**
|
||||
* The hint value.
|
||||
*/
|
||||
pj_str_t name;
|
||||
|
||||
/**
|
||||
* The hint type.
|
||||
*/
|
||||
pj_str_t type;
|
||||
|
||||
/**
|
||||
* Helpful description of the hint value.
|
||||
*/
|
||||
pj_str_t desc;
|
||||
|
||||
} pj_cli_hint_info;
|
||||
|
||||
/**
|
||||
* This structure contains extra information returned by pj_cli_sess_exec()/
|
||||
* pj_cli_sess_parse().
|
||||
* Upon return from the function, various other fields in this structure will
|
||||
* be set by the function.
|
||||
*/
|
||||
typedef struct pj_cli_exec_info
|
||||
{
|
||||
/**
|
||||
* If command parsing failed, on return this will point to the location
|
||||
* where the failure occurs, otherwise the value will be set to -1.
|
||||
*/
|
||||
int err_pos;
|
||||
|
||||
/**
|
||||
* If a command matching the command in the cmdline was found, on return
|
||||
* this will be set to the command id of the command, otherwise it will be
|
||||
* set to PJ_CLI_INVALID_CMD_ID.
|
||||
*/
|
||||
pj_cli_cmd_id cmd_id;
|
||||
|
||||
/**
|
||||
* If a command was executed, on return this will be set to the return
|
||||
* value of the command, otherwise it will contain PJ_SUCCESS.
|
||||
*/
|
||||
pj_status_t cmd_ret;
|
||||
|
||||
/**
|
||||
* The number of hint elements
|
||||
**/
|
||||
unsigned hint_cnt;
|
||||
|
||||
/**
|
||||
* If pj_cli_sess_parse() fails because of a missing argument or ambigous
|
||||
* command/argument, the function returned PJ_CLI_EMISSINGARG or
|
||||
* PJ_CLI_EAMBIGUOUS error.
|
||||
* This field will contain the hint information. This is useful to give
|
||||
* helpful information to the end_user.
|
||||
*/
|
||||
pj_cli_hint_info hint[PJ_CLI_MAX_HINTS];
|
||||
|
||||
} pj_cli_exec_info;
|
||||
|
||||
/**
|
||||
* This structure contains the information returned from the dynamic
|
||||
* argument callback.
|
||||
*/
|
||||
typedef struct pj_cli_arg_choice_val
|
||||
{
|
||||
/**
|
||||
* The argument choice value
|
||||
*/
|
||||
pj_str_t value;
|
||||
|
||||
/**
|
||||
* Helpful description of the choice value. This text will be used when
|
||||
* displaying the help texts for the choice value
|
||||
*/
|
||||
pj_str_t desc;
|
||||
|
||||
} pj_cli_arg_choice_val;
|
||||
|
||||
/**
|
||||
* This structure contains the parameters for pj_cli_get_dyn_choice
|
||||
*/
|
||||
typedef struct pj_cli_dyn_choice_param
|
||||
{
|
||||
/**
|
||||
* The session on which the command was executed on.
|
||||
*/
|
||||
pj_cli_sess *sess;
|
||||
|
||||
/**
|
||||
* The command being processed.
|
||||
*/
|
||||
pj_cli_cmd_spec *cmd;
|
||||
|
||||
/**
|
||||
* The argument id.
|
||||
*/
|
||||
pj_cli_arg_id arg_id;
|
||||
|
||||
/**
|
||||
* The maximum number of values that the choice can hold.
|
||||
*/
|
||||
unsigned max_cnt;
|
||||
|
||||
/**
|
||||
* The pool to allocate memory from.
|
||||
*/
|
||||
pj_pool_t *pool;
|
||||
|
||||
/**
|
||||
* The choice values count.
|
||||
*/
|
||||
unsigned cnt;
|
||||
|
||||
/**
|
||||
* Array containing the valid choice values.
|
||||
*/
|
||||
pj_cli_arg_choice_val choice[PJ_CLI_MAX_CHOICE_VAL];
|
||||
} pj_cli_dyn_choice_param;
|
||||
|
||||
/**
|
||||
* This specifies the callback type for argument handlers, which will be
|
||||
* called to get the valid values of the choice type arguments.
|
||||
*/
|
||||
typedef void (*pj_cli_get_dyn_choice) (pj_cli_dyn_choice_param *param);
|
||||
|
||||
/**
|
||||
* This specifies the callback type for command handlers, which will be
|
||||
* executed when the specified command is invoked.
|
||||
*
|
||||
* @param cmd_val The command that is specified by the user.
|
||||
*
|
||||
* @return Return the status of the command execution.
|
||||
*/
|
||||
typedef pj_status_t (*pj_cli_cmd_handler)(pj_cli_cmd_val *cval);
|
||||
|
||||
/**
|
||||
* Write a log message to the CLI application. The CLI application
|
||||
* will send the log message to all the registered front-ends.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
* @param level Verbosity level of this message message.
|
||||
* @param buffer The message itself.
|
||||
* @param len Length of this message.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_write_log(pj_cli_t *cli,
|
||||
int level,
|
||||
const char *buffer,
|
||||
int len);
|
||||
|
||||
/**
|
||||
* Create a new CLI application instance.
|
||||
*
|
||||
* @param cfg CLI application creation parameters.
|
||||
* @param p_cli Pointer to receive the returned instance.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_create(pj_cli_cfg *cfg,
|
||||
pj_cli_t **p_cli);
|
||||
|
||||
/**
|
||||
* This specifies the function to get the id of the specified command
|
||||
*
|
||||
* @param cmd The specified command.
|
||||
*
|
||||
* @return The command id
|
||||
*/
|
||||
PJ_DECL(pj_cli_cmd_id) pj_cli_get_cmd_id(const pj_cli_cmd_spec *cmd);
|
||||
|
||||
/**
|
||||
* Get the internal parameter of the CLI instance.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
*
|
||||
* @return CLI parameter instance.
|
||||
*/
|
||||
PJ_DECL(pj_cli_cfg*) pj_cli_get_param(pj_cli_t *cli);
|
||||
|
||||
/**
|
||||
* Call this to signal application shutdown. Typically application would
|
||||
* call this from it's "Quit" menu or similar command to quit the
|
||||
* application.
|
||||
*
|
||||
* See also pj_cli_sess_end_session() to end a session instead of quitting the
|
||||
* whole application.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
* @param req The session on which the shutdown request is
|
||||
* received.
|
||||
* @param restart Indicate whether application restart is wanted.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_quit(pj_cli_t *cli, pj_cli_sess *req,
|
||||
pj_bool_t restart);
|
||||
/**
|
||||
* Check if application shutdown or restart has been requested.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
*
|
||||
* @return PJ_TRUE if pj_cli_quit() has been called.
|
||||
*/
|
||||
PJ_DECL(pj_bool_t) pj_cli_is_quitting(pj_cli_t *cli);
|
||||
|
||||
/**
|
||||
* Check if application restart has been requested.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
*
|
||||
* @return PJ_TRUE if pj_cli_quit() has been called with
|
||||
* restart parameter set.
|
||||
*/
|
||||
PJ_DECL(pj_bool_t) pj_cli_is_restarting(pj_cli_t *cli);
|
||||
|
||||
/**
|
||||
* Destroy a CLI application instance. This would also close all sessions
|
||||
* currently running for this CLI application.
|
||||
*
|
||||
* @param cli The CLI application.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_destroy(pj_cli_t *cli);
|
||||
|
||||
/**
|
||||
* Initialize a pj_cli_cfg with its default values.
|
||||
*
|
||||
* @param param The instance to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_cfg_default(pj_cli_cfg *param);
|
||||
|
||||
/**
|
||||
* Register a front end to the CLI application.
|
||||
*
|
||||
* @param CLI The CLI application.
|
||||
* @param fe The CLI front end to be registered.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_register_front_end(pj_cli_t *cli,
|
||||
pj_cli_front_end *fe);
|
||||
|
||||
/**
|
||||
* Create a new complete command specification from an XML node text and
|
||||
* register it to the CLI application.
|
||||
*
|
||||
* Note that the input string MUST be NULL terminated.
|
||||
*
|
||||
* @param cli The CLI application.
|
||||
* @param group Optional group to which this command will be added
|
||||
* to, or specify NULL if this command is a root
|
||||
* command.
|
||||
* @param xml Input string containing XML node text for the
|
||||
* command, MUST be NULL terminated.
|
||||
* @param handler Function handler for the command. This must be NULL
|
||||
* if the command specifies a command group.
|
||||
* @param p_cmd Optional pointer to store the newly created
|
||||
* specification.
|
||||
* @param get_choice Function handler for the argument. Specify this for
|
||||
* dynamic choice type arguments.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_add_cmd_from_xml(pj_cli_t *cli,
|
||||
pj_cli_cmd_spec *group,
|
||||
const pj_str_t *xml,
|
||||
pj_cli_cmd_handler handler,
|
||||
pj_cli_cmd_spec **p_cmd,
|
||||
pj_cli_get_dyn_choice get_choice);
|
||||
/**
|
||||
* Initialize pj_cli_exec_info with its default values.
|
||||
*
|
||||
* @param param The param to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_exec_info_default(pj_cli_exec_info *param);
|
||||
|
||||
/**
|
||||
* Write a log message to the specific CLI session.
|
||||
*
|
||||
* @param sess The CLI active session.
|
||||
* @param buffer The message itself.
|
||||
* @param len Length of this message.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_sess_write_msg(pj_cli_sess *sess,
|
||||
const char *buffer,
|
||||
pj_size_t len);
|
||||
|
||||
/**
|
||||
* Parse an input cmdline string. The first word of the command line is the
|
||||
* command itself, which will be matched against command specifications
|
||||
* registered in the CLI application.
|
||||
*
|
||||
* Zero or more arguments follow the command name. Arguments are separated by
|
||||
* one or more whitespaces. Argument may be placed inside a pair of quotes,
|
||||
* double quotes, '{' and '}', or '[' and ']' pairs. This is useful when the
|
||||
* argument itself contains whitespaces or other restricted characters. If
|
||||
* the quote character itself is to appear in the argument, the argument then
|
||||
* must be quoted with different quote characters. There is no character
|
||||
* escaping facility provided by this function (such as the use of backslash
|
||||
* '\' character).
|
||||
*
|
||||
* The cmdline may be followed by an extra newline (LF or CR-LF characters),
|
||||
* which will be removed by the function. However any more characters
|
||||
* following this newline will cause an error to be returned.
|
||||
*
|
||||
* @param sess The CLI session.
|
||||
* @param cmdline The command line string to be parsed.
|
||||
* @param val Structure to store the parsing result.
|
||||
* @param pool The pool to allocate memory from.
|
||||
* @param info Additional info to be returned regarding the parsing.
|
||||
*
|
||||
* @return This function returns the status of the parsing,
|
||||
* which can be one of the following :
|
||||
* - PJ_SUCCESS: a command was executed successfully.
|
||||
* - PJ_EINVAL: invalid parameter to this function.
|
||||
* - PJ_ENOTFOUND: command is not found.
|
||||
* - PJ_CLI_EAMBIGUOUS: command/argument is ambiguous.
|
||||
* - PJ_CLI_EMISSINGARG: missing argument.
|
||||
* - PJ_CLI_EINVARG: invalid command argument.
|
||||
* - PJ_CLI_EEXIT: "exit" has been called to end
|
||||
* the current session. This is a signal for the
|
||||
* application to end it's main loop.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_sess_parse(pj_cli_sess *sess,
|
||||
char *cmdline,
|
||||
pj_cli_cmd_val *val,
|
||||
pj_pool_t *pool,
|
||||
pj_cli_exec_info *info);
|
||||
|
||||
/**
|
||||
* End the specified session, and destroy it to release all resources used
|
||||
* by the session.
|
||||
*
|
||||
* See also pj_cli_sess and pj_cli_front_end for more info regarding the
|
||||
* creation process.
|
||||
* See also pj_cli_quit() to quit the whole application instead.
|
||||
*
|
||||
* @param sess The CLI session to be destroyed.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_sess_end_session(pj_cli_sess *sess);
|
||||
|
||||
/**
|
||||
* Execute a command line. This function will parse the input string to find
|
||||
* the appropriate command and verify whether the string matches the command
|
||||
* specifications. If matches, the command will be executed, and the return
|
||||
* value of the command will be set in the \a cmd_ret field of the \a info
|
||||
* argument, if specified.
|
||||
*
|
||||
* See also pj_cli_sess_parse() for more info regarding the cmdline format.
|
||||
*
|
||||
* @param sess The CLI session.
|
||||
* @param cmdline The command line string to be executed.
|
||||
* @param pool The pool to allocate memory from.
|
||||
* @param info Optional pointer to receive additional information
|
||||
* related to the execution of the command (such as
|
||||
* the command return value).
|
||||
*
|
||||
* @return This function returns the status of the command
|
||||
* parsing and execution (note that the return value
|
||||
* of the handler itself will be returned in \a info
|
||||
* argument, if specified). Please see the return value
|
||||
* of pj_cli_sess_parse() for possible return values.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_sess_exec(pj_cli_sess *sess,
|
||||
char *cmdline,
|
||||
pj_pool_t *pool,
|
||||
pj_cli_exec_info *info);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_CLI_H__ */
|
||||
@@ -0,0 +1,117 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_CLI_CONSOLE_H__
|
||||
#define __PJLIB_UTIL_CLI_CONSOLE_H__
|
||||
|
||||
/**
|
||||
* @file cli_console.h
|
||||
* @brief Command Line Interface Console Front End API
|
||||
*/
|
||||
|
||||
#include <pjlib-util/cli_imp.h>
|
||||
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @ingroup PJLIB_UTIL_CLI_IMP
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This structure contains various options for CLI console front-end.
|
||||
* Application must call pj_cli_console_cfg_default() to initialize
|
||||
* this structure with its default values.
|
||||
*/
|
||||
typedef struct pj_cli_console_cfg
|
||||
{
|
||||
/**
|
||||
* Default log verbosity level for the session.
|
||||
*
|
||||
* Default value: PJ_CLI_CONSOLE_LOG_LEVEL
|
||||
*/
|
||||
int log_level;
|
||||
|
||||
/**
|
||||
* Specify text message as a prompt string to user.
|
||||
*
|
||||
* Default: empty
|
||||
*/
|
||||
pj_str_t prompt_str;
|
||||
|
||||
/**
|
||||
* Specify the command to quit the application.
|
||||
*
|
||||
* Default: empty
|
||||
*/
|
||||
pj_str_t quit_command;
|
||||
|
||||
} pj_cli_console_cfg;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize pj_cli_console_cfg with its default values.
|
||||
*
|
||||
* @param param The structure to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_console_cfg_default(pj_cli_console_cfg *param);
|
||||
|
||||
|
||||
/**
|
||||
* Create a console front-end for the specified CLI application, and return
|
||||
* the only session instance for the console front end. On Windows operating
|
||||
* system, this may open a new console window.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
* @param param Optional console CLI parameters. If this value is
|
||||
* NULL, default parameters will be used.
|
||||
* @param p_sess Pointer to receive the session instance for the
|
||||
* console front end.
|
||||
* @param p_fe Optional pointer to receive the front-end instance
|
||||
* of the console front-end just created.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_console_create(pj_cli_t *cli,
|
||||
const pj_cli_console_cfg *param,
|
||||
pj_cli_sess **p_sess,
|
||||
pj_cli_front_end **p_fe);
|
||||
|
||||
/**
|
||||
* Retrieve a cmdline from console stdin and process the input accordingly.
|
||||
*
|
||||
* @param sess The CLI session.
|
||||
* @param buf Pointer to receive the buffer.
|
||||
* @param maxlen Maximum length to read.
|
||||
*
|
||||
* @return PJ_SUCCESS if an input was read
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_console_process(pj_cli_sess *sess,
|
||||
char *buf,
|
||||
unsigned maxlen);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_CLI_CONSOLE_H__ */
|
||||
@@ -0,0 +1,208 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_CLI_IMP_H__
|
||||
#define __PJLIB_UTIL_CLI_IMP_H__
|
||||
|
||||
/**
|
||||
* @file cli_imp.h
|
||||
* @brief Command Line Interface Implementor's API
|
||||
*/
|
||||
|
||||
#include <pjlib-util/cli.h>
|
||||
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_CLI_IMP Command Line Interface Implementor's API
|
||||
* @ingroup PJLIB_UTIL_CLI
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default log level for console sessions.
|
||||
*/
|
||||
#ifndef PJ_CLI_CONSOLE_LOG_LEVEL
|
||||
# define PJ_CLI_CONSOLE_LOG_LEVEL PJ_LOG_MAX_LEVEL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default log level for telnet sessions.
|
||||
*/
|
||||
#ifndef PJ_CLI_TELNET_LOG_LEVEL
|
||||
# define PJ_CLI_TELNET_LOG_LEVEL 4
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default port number for telnet daemon.
|
||||
*/
|
||||
#ifndef PJ_CLI_TELNET_PORT
|
||||
# define PJ_CLI_TELNET_PORT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This enumeration specifies front end types.
|
||||
*/
|
||||
typedef enum pj_cli_front_end_type
|
||||
{
|
||||
PJ_CLI_CONSOLE_FRONT_END, /**< Console front end. */
|
||||
PJ_CLI_TELNET_FRONT_END, /**< Telnet front end. */
|
||||
PJ_CLI_HTTP_FRONT_END, /**< HTTP front end. */
|
||||
PJ_CLI_GUI_FRONT_END /**< GUI front end. */
|
||||
} pj_cli_front_end_type;
|
||||
|
||||
|
||||
/**
|
||||
* Front end operations. Only the CLI should call these functions
|
||||
* directly.
|
||||
*/
|
||||
typedef struct pj_cli_front_end_op
|
||||
{
|
||||
/**
|
||||
* Callback to write a log message to the appropriate sessions belonging
|
||||
* to this front end. The front end would only send the log message to
|
||||
* the session if the session's log verbosity level is greater than the
|
||||
* level of this log message.
|
||||
*
|
||||
* @param fe The front end.
|
||||
* @param level Verbosity level of this message message.
|
||||
* @param data The message itself.
|
||||
* @param len Length of this message.
|
||||
*/
|
||||
void (*on_write_log)(pj_cli_front_end *fe, int level,
|
||||
const char *data, pj_size_t len);
|
||||
|
||||
/**
|
||||
* Callback to be called when the application is quitting, to signal the
|
||||
* front-end to end its main loop or any currently blocking functions,
|
||||
* if any.
|
||||
*
|
||||
* @param fe The front end.
|
||||
* @param req The session which requested the application quit.
|
||||
*/
|
||||
void (*on_quit)(pj_cli_front_end *fe, pj_cli_sess *req);
|
||||
|
||||
/**
|
||||
* Callback to be called to close and self destroy the front-end. This
|
||||
* must also close any active sessions created by this front-ends.
|
||||
*
|
||||
* @param fe The front end.
|
||||
*/
|
||||
void (*on_destroy)(pj_cli_front_end *fe);
|
||||
|
||||
} pj_cli_front_end_op;
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes common properties of CLI front-ends. A front-
|
||||
* end is a mean to interact with end user, for example the CLI application
|
||||
* may interact with console, telnet, web, or even a GUI.
|
||||
*
|
||||
* Each end user's interaction will create an instance of pj_cli_sess.
|
||||
*
|
||||
* Application instantiates the front end by calling the appropriate
|
||||
* function to instantiate them.
|
||||
*/
|
||||
struct pj_cli_front_end
|
||||
{
|
||||
/**
|
||||
* Linked list members
|
||||
*/
|
||||
PJ_DECL_LIST_MEMBER(struct pj_cli_front_end);
|
||||
|
||||
/**
|
||||
* Front end type.
|
||||
*/
|
||||
pj_cli_front_end_type type;
|
||||
|
||||
/**
|
||||
* The CLI application.
|
||||
*/
|
||||
pj_cli_t *cli;
|
||||
|
||||
/**
|
||||
* Front end operations.
|
||||
*/
|
||||
pj_cli_front_end_op *op;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Session operations.
|
||||
*/
|
||||
typedef struct pj_cli_sess_op
|
||||
{
|
||||
/**
|
||||
* Callback to be called to close and self destroy the session.
|
||||
*
|
||||
* @param sess The session to destroy.
|
||||
*/
|
||||
void (*destroy)(pj_cli_sess *sess);
|
||||
|
||||
} pj_cli_sess_op;
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes common properties of a CLI session. A CLI session
|
||||
* is the interaction of an end user to the CLI application via a specific
|
||||
* renderer, where the renderer can be console, telnet, web, or a GUI app for
|
||||
* mobile. A session is created by its renderer, and it's creation procedures
|
||||
* vary among renderer (for example, a telnet session is created when the
|
||||
* end user connects to the application, while a console session is always
|
||||
* instantiated once the program is run).
|
||||
*/
|
||||
struct pj_cli_sess
|
||||
{
|
||||
/**
|
||||
* Linked list members
|
||||
*/
|
||||
PJ_DECL_LIST_MEMBER(struct pj_cli_sess);
|
||||
|
||||
/**
|
||||
* Pointer to the front-end instance which created this session.
|
||||
*/
|
||||
pj_cli_front_end *fe;
|
||||
|
||||
/**
|
||||
* Session operations.
|
||||
*/
|
||||
pj_cli_sess_op *op;
|
||||
|
||||
/**
|
||||
* Text containing session info, which is filled by the renderer when
|
||||
* the session is created.
|
||||
*/
|
||||
pj_str_t info;
|
||||
|
||||
/**
|
||||
* Log verbosity of this session.
|
||||
*/
|
||||
int log_level;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_CLI_IMP_H__ */
|
||||
@@ -0,0 +1,167 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_CLI_TELNET_H__
|
||||
#define __PJLIB_UTIL_CLI_TELNET_H__
|
||||
|
||||
/**
|
||||
* @file cli_telnet.h
|
||||
* @brief Command Line Interface Telnet Front End API
|
||||
*/
|
||||
|
||||
#include <pjlib-util/cli_imp.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @ingroup PJLIB_UTIL_CLI_IMP
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This structure contains the information about the telnet.
|
||||
* Application will get updated information each time the telnet is started/
|
||||
* restarted.
|
||||
*/
|
||||
typedef struct pj_cli_telnet_info
|
||||
{
|
||||
/**
|
||||
* The telnet's ip address.
|
||||
*/
|
||||
pj_str_t ip_address;
|
||||
|
||||
/**
|
||||
* The telnet's port number.
|
||||
*/
|
||||
pj_uint16_t port;
|
||||
|
||||
/* Internal buffer for IP address */
|
||||
char buf_[32];
|
||||
|
||||
} pj_cli_telnet_info;
|
||||
|
||||
/**
|
||||
* This specifies the callback called when telnet is started
|
||||
*
|
||||
* @param status The status of telnet startup process.
|
||||
*
|
||||
*/
|
||||
typedef void (*pj_cli_telnet_on_started)(pj_status_t status);
|
||||
|
||||
/**
|
||||
* This structure contains various options to instantiate the telnet daemon.
|
||||
* Application must call pj_cli_telnet_cfg_default() to initialize
|
||||
* this structure with its default values.
|
||||
*/
|
||||
typedef struct pj_cli_telnet_cfg
|
||||
{
|
||||
/**
|
||||
* Listening port number. The value may be 0 to let the system choose
|
||||
* the first available port.
|
||||
*
|
||||
* Default value: PJ_CLI_TELNET_PORT
|
||||
*/
|
||||
pj_uint16_t port;
|
||||
|
||||
/**
|
||||
* Ioqueue instance to be used. If this field is NULL, an internal
|
||||
* ioqueue and worker thread will be created.
|
||||
*/
|
||||
pj_ioqueue_t *ioqueue;
|
||||
|
||||
/**
|
||||
* Default log verbosity level for the session.
|
||||
*
|
||||
* Default value: PJ_CLI_TELNET_LOG_LEVEL
|
||||
*/
|
||||
int log_level;
|
||||
|
||||
/**
|
||||
* Specify a password to be asked to the end user to access the
|
||||
* application. Currently this is not implemented yet.
|
||||
*
|
||||
* Default: empty (no password)
|
||||
*/
|
||||
pj_str_t passwd;
|
||||
|
||||
/**
|
||||
* Specify text message to be displayed to newly connected users.
|
||||
* Currently this is not implemented yet.
|
||||
*
|
||||
* Default: empty
|
||||
*/
|
||||
pj_str_t welcome_msg;
|
||||
|
||||
/**
|
||||
* Specify text message as a prompt string to user.
|
||||
*
|
||||
* Default: empty
|
||||
*/
|
||||
pj_str_t prompt_str;
|
||||
|
||||
/**
|
||||
* Specify the pj_cli_telnet_on_started callback.
|
||||
*
|
||||
* Default: empty
|
||||
*/
|
||||
pj_cli_telnet_on_started on_started;
|
||||
|
||||
} pj_cli_telnet_cfg;
|
||||
|
||||
/**
|
||||
* Initialize pj_cli_telnet_cfg with its default values.
|
||||
*
|
||||
* @param param The structure to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_cli_telnet_cfg_default(pj_cli_telnet_cfg *param);
|
||||
|
||||
|
||||
/**
|
||||
* Create, initialize, and start a telnet daemon for the application.
|
||||
*
|
||||
* @param cli The CLI application instance.
|
||||
* @param param Optional parameters for creating the telnet daemon.
|
||||
* If this value is NULL, default parameters will be used.
|
||||
* @param p_fe Optional pointer to receive the front-end instance
|
||||
* of the telnet front-end just created.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_telnet_create(pj_cli_t *cli,
|
||||
pj_cli_telnet_cfg *param,
|
||||
pj_cli_front_end **p_fe);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve cli telnet info.
|
||||
*
|
||||
* @param telnet_info The telnet runtime information.
|
||||
*
|
||||
* @return PJ_SUCCESS on success.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cli_telnet_get_info(pj_cli_front_end *fe,
|
||||
pj_cli_telnet_info *info);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_CLI_TELNET_H__ */
|
||||
@@ -0,0 +1,374 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_CONFIG_H__
|
||||
#define __PJLIB_UTIL_CONFIG_H__
|
||||
|
||||
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief Compile time settings
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_CONFIG Configuration
|
||||
* @ingroup PJLIB_UTIL_BASE
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* DNS CONFIGURATION
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum number of IP addresses in DNS A response.
|
||||
*/
|
||||
#ifndef PJ_DNS_MAX_IP_IN_A_REC
|
||||
# define PJ_DNS_MAX_IP_IN_A_REC 8
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Maximum server address entries per one SRV record
|
||||
*/
|
||||
#ifndef PJ_DNS_SRV_MAX_ADDR
|
||||
# define PJ_DNS_SRV_MAX_ADDR 8
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* This constant specifies the maximum names to keep in the temporary name
|
||||
* table when performing name compression scheme when duplicating DNS packet
|
||||
* (the #pj_dns_packet_dup() function).
|
||||
*
|
||||
* Generally name compression is desired, since it saves some memory (see
|
||||
* PJ_DNS_RESOLVER_RES_BUF_SIZE setting). However it comes at the expense of
|
||||
* a little processing overhead to perform name scanning and also a little
|
||||
* bit more stack usage (8 bytes per entry on 32bit platform).
|
||||
*
|
||||
* Default: 16
|
||||
*/
|
||||
#ifndef PJ_DNS_MAX_NAMES_IN_NAMETABLE
|
||||
# define PJ_DNS_MAX_NAMES_IN_NAMETABLE 16
|
||||
#endif
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* RESOLVER CONFIGURATION
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Maximum numbers of DNS nameservers that can be configured in resolver.
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_MAX_NS
|
||||
# define PJ_DNS_RESOLVER_MAX_NS 16
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Default retransmission delay, in miliseconds. The combination of
|
||||
* retransmission delay and count determines the query timeout.
|
||||
*
|
||||
* Default: 2000 (2 seconds, according to RFC 1035)
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY
|
||||
# define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY 2000
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Maximum number of transmissions before timeout is declared for
|
||||
* the query.
|
||||
*
|
||||
* Default: 5
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT
|
||||
# define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT 5
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Maximum life-time of DNS response in the resolver response cache,
|
||||
* in seconds. If the value is zero, then DNS response caching will be
|
||||
* disabled.
|
||||
*
|
||||
* Default is 300 seconds (5 minutes).
|
||||
*
|
||||
* @see PJ_DNS_RESOLVER_INVALID_TTL
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_MAX_TTL
|
||||
# define PJ_DNS_RESOLVER_MAX_TTL (5*60)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The life-time of invalid DNS response in the resolver response cache.
|
||||
* An invalid DNS response is a response which RCODE is non-zero and
|
||||
* response without any answer section. These responses can be put in
|
||||
* the cache too to minimize message round-trip.
|
||||
*
|
||||
* Default: 60 (one minute).
|
||||
*
|
||||
* @see PJ_DNS_RESOLVER_MAX_TTL
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_INVALID_TTL
|
||||
# define PJ_DNS_RESOLVER_INVALID_TTL 60
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The interval on which nameservers which are known to be good to be
|
||||
* probed again to determine whether they are still good. Note that
|
||||
* this applies to both active nameserver (the one currently being used)
|
||||
* and idle nameservers (good nameservers that are not currently selected).
|
||||
* The probing to query the "goodness" of nameservers involves sending
|
||||
* the same query to multiple servers, so it's probably not a good idea
|
||||
* to send this probing too often.
|
||||
*
|
||||
* Default: 600 (ten minutes)
|
||||
*
|
||||
* @see PJ_DNS_RESOLVER_BAD_NS_TTL
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_GOOD_NS_TTL
|
||||
# define PJ_DNS_RESOLVER_GOOD_NS_TTL (10*60)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The interval on which nameservers which known to be bad to be probed
|
||||
* again to determine whether it is still bad.
|
||||
*
|
||||
* Default: 60 (one minute)
|
||||
*
|
||||
* @see PJ_DNS_RESOLVER_GOOD_NS_TTL
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_BAD_NS_TTL
|
||||
# define PJ_DNS_RESOLVER_BAD_NS_TTL (1*60)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Maximum size of UDP packet. RFC 1035 states that maximum size of
|
||||
* DNS packet carried over UDP is 512 bytes.
|
||||
*
|
||||
* Default: 512 byes
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_MAX_UDP_SIZE
|
||||
# define PJ_DNS_RESOLVER_MAX_UDP_SIZE 512
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Size of memory pool allocated for each individual DNS response cache.
|
||||
* This value here should be more or less the same as maximum UDP packet
|
||||
* size (PJ_DNS_RESOLVER_MAX_UDP_SIZE), since the DNS replicator function
|
||||
* (#pj_dns_packet_dup()) is also capable of performing name compressions.
|
||||
*
|
||||
* Default: 512
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_RES_BUF_SIZE
|
||||
# define PJ_DNS_RESOLVER_RES_BUF_SIZE 512
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Size of temporary pool buffer for parsing DNS packets in resolver.
|
||||
*
|
||||
* default: 4000
|
||||
*/
|
||||
#ifndef PJ_DNS_RESOLVER_TMP_BUF_SIZE
|
||||
# define PJ_DNS_RESOLVER_TMP_BUF_SIZE 4000
|
||||
#endif
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* SCANNER CONFIGURATION
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Macro PJ_SCANNER_USE_BITWISE is defined and non-zero (by default yes)
|
||||
* will enable the use of bitwise for character input specification (cis).
|
||||
* This would save several kilobytes of .bss memory in the SIP parser.
|
||||
*/
|
||||
#ifndef PJ_SCANNER_USE_BITWISE
|
||||
# define PJ_SCANNER_USE_BITWISE 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* STUN CLIENT CONFIGURATION
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum number of attributes in the STUN packet (for the old STUN
|
||||
* library).
|
||||
*
|
||||
* Default: 16
|
||||
*/
|
||||
#ifndef PJSTUN_MAX_ATTR
|
||||
# define PJSTUN_MAX_ATTR 16
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Maximum number of attributes in the STUN packet (for the new STUN
|
||||
* library).
|
||||
*
|
||||
* Default: 16
|
||||
*/
|
||||
#ifndef PJ_STUN_MAX_ATTR
|
||||
# define PJ_STUN_MAX_ATTR 16
|
||||
#endif
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* ENCRYPTION
|
||||
*/
|
||||
|
||||
/**
|
||||
* Specifies whether CRC32 algorithm should use the table based lookup table
|
||||
* for faster calculation, at the expense of about 1KB table size on the
|
||||
* executable. If zero, the CRC32 will use non-table based which is more than
|
||||
* an order of magnitude slower.
|
||||
*
|
||||
* Default: 1
|
||||
*/
|
||||
#ifndef PJ_CRC32_HAS_TABLES
|
||||
# define PJ_CRC32_HAS_TABLES 1
|
||||
#endif
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* HTTP Client configuration
|
||||
*/
|
||||
/**
|
||||
* Timeout value for HTTP request operation. The value is in ms.
|
||||
* Default: 60000ms
|
||||
*/
|
||||
#ifndef PJ_HTTP_DEFAULT_TIMEOUT
|
||||
# define PJ_HTTP_DEFAULT_TIMEOUT (60000)
|
||||
#endif
|
||||
|
||||
/* **************************************************************************
|
||||
* CLI configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initial pool size for CLI.
|
||||
* Default: 1024 bytes
|
||||
*/
|
||||
#ifndef PJ_CLI_POOL_SIZE
|
||||
# define PJ_CLI_POOL_SIZE 1024
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pool increment size for CLI.
|
||||
* Default: 512 bytes
|
||||
*/
|
||||
#ifndef PJ_CLI_POOL_INC
|
||||
# define PJ_CLI_POOL_INC 512
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Maximum length of command buffer.
|
||||
* Default: 512
|
||||
*/
|
||||
#ifndef PJ_CLI_MAX_CMDBUF
|
||||
# define PJ_CLI_MAX_CMDBUF 512
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Maximum command arguments.
|
||||
* Default: 8
|
||||
*/
|
||||
#ifndef PJ_CLI_MAX_ARGS
|
||||
# define PJ_CLI_MAX_ARGS 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Maximum number of hints.
|
||||
* Default: 32
|
||||
*/
|
||||
#ifndef PJ_CLI_MAX_HINTS
|
||||
# define PJ_CLI_MAX_HINTS 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Maximum short name version (shortcuts) for a command.
|
||||
* Default: 4
|
||||
*/
|
||||
#ifndef PJ_CLI_MAX_SHORTCUTS
|
||||
# define PJ_CLI_MAX_SHORTCUTS 4
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initial pool size for console CLI.
|
||||
* Default: 256 bytes
|
||||
*/
|
||||
#ifndef PJ_CLI_CONSOLE_POOL_SIZE
|
||||
# define PJ_CLI_CONSOLE_POOL_SIZE 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pool increment size for console CLI.
|
||||
* Default: 256 bytes
|
||||
*/
|
||||
#ifndef PJ_CLI_CONSOLE_POOL_INC
|
||||
# define PJ_CLI_CONSOLE_POOL_INC 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initial pool size for telnet CLI.
|
||||
* Default: 1024 bytes
|
||||
*/
|
||||
#ifndef PJ_CLI_TELNET_POOL_SIZE
|
||||
# define PJ_CLI_TELNET_POOL_SIZE 1024
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pool increment size for telnet CLI.
|
||||
* Default: 512 bytes
|
||||
*/
|
||||
#ifndef PJ_CLI_TELNET_POOL_INC
|
||||
# define PJ_CLI_TELNET_POOL_INC 512
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Maximum number of argument values of choice type.
|
||||
* Default: 64
|
||||
*/
|
||||
#ifndef PJ_CLI_MAX_CHOICE_VAL
|
||||
# define PJ_CLI_MAX_CHOICE_VAL 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Maximum number of command history.
|
||||
* Default: 16
|
||||
*/
|
||||
#ifndef PJ_CLI_MAX_CMD_HISTORY
|
||||
# define PJ_CLI_MAX_CMD_HISTORY 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __PJLIB_UTIL_CONFIG_H__ */
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_CRC32_H__
|
||||
#define __PJLIB_UTIL_CRC32_H__
|
||||
|
||||
/**
|
||||
* @file crc32.h
|
||||
* @brief CRC32 implementation
|
||||
*/
|
||||
|
||||
#include <pjlib-util/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_CRC32 CRC32 (Cyclic Redundancy Check)
|
||||
* @ingroup PJLIB_UTIL_ENCRYPTION
|
||||
* @{
|
||||
* This implements CRC32 algorithm. See ITU-T V.42 for the formal
|
||||
* specification.
|
||||
*/
|
||||
|
||||
/** CRC32 context. */
|
||||
typedef struct pj_crc32_context
|
||||
{
|
||||
pj_uint32_t crc_state; /**< Current state. */
|
||||
} pj_crc32_context;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize CRC32 context.
|
||||
*
|
||||
* @param ctx CRC32 context.
|
||||
*/
|
||||
PJ_DECL(void) pj_crc32_init(pj_crc32_context *ctx);
|
||||
|
||||
/**
|
||||
* Feed data incrementally to the CRC32 algorithm.
|
||||
*
|
||||
* @param ctx CRC32 context.
|
||||
* @param data Input data.
|
||||
* @param nbytes Length of the input data.
|
||||
*
|
||||
* @return The current CRC32 value.
|
||||
*/
|
||||
PJ_DECL(pj_uint32_t) pj_crc32_update(pj_crc32_context *ctx,
|
||||
const pj_uint8_t *data,
|
||||
pj_size_t nbytes);
|
||||
|
||||
/**
|
||||
* Finalize CRC32 calculation and retrieve the CRC32 value.
|
||||
*
|
||||
* @param ctx CRC32 context.
|
||||
*
|
||||
* @return The current CRC value.
|
||||
*/
|
||||
PJ_DECL(pj_uint32_t) pj_crc32_final(pj_crc32_context *ctx);
|
||||
|
||||
/**
|
||||
* Perform one-off CRC32 calculation to the specified data.
|
||||
*
|
||||
* @param data Input data.
|
||||
* @param nbytes Length of input data.
|
||||
*
|
||||
* @return CRC value of the data.
|
||||
*/
|
||||
PJ_DECL(pj_uint32_t) pj_crc32_calc(const pj_uint8_t *data,
|
||||
pj_size_t nbytes);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_CRC32_H__ */
|
||||
|
||||
@@ -0,0 +1,461 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_DNS_H__
|
||||
#define __PJLIB_UTIL_DNS_H__
|
||||
|
||||
|
||||
/**
|
||||
* @file dns.h
|
||||
* @brief Low level DNS message parsing and packetization.
|
||||
*/
|
||||
#include <pjlib-util/types.h>
|
||||
#include <pj/sock.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_DNS DNS and Asynchronous DNS Resolver
|
||||
* @ingroup PJ_PROTOCOLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJ_DNS_PARSING Low-level DNS Message Parsing and Packetization
|
||||
* @ingroup PJ_DNS
|
||||
* @{
|
||||
*
|
||||
* This module provides low-level services to parse and packetize DNS queries
|
||||
* and responses. The functions support building a DNS query packet and parse
|
||||
* the data in the DNS response. This implementation conforms to the
|
||||
* following specifications:
|
||||
* - RFC 1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION
|
||||
* - RFC 1886: DNS Extensions to support IP version 6
|
||||
*
|
||||
* To create a DNS query packet, application should call #pj_dns_make_query()
|
||||
* function, specifying the desired DNS query type, the name to be resolved,
|
||||
* and the buffer where the DNS packet will be built into.
|
||||
*
|
||||
* When incoming DNS query or response packet arrives, application can use
|
||||
* #pj_dns_parse_packet() to parse the TCP/UDP payload into parsed DNS packet
|
||||
* structure.
|
||||
*
|
||||
* This module does not provide any networking functionalities to send or
|
||||
* receive DNS packets. This functionality should be provided by higher layer
|
||||
* modules such as @ref PJ_DNS_RESOLVER.
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
PJ_DNS_CLASS_IN = 1 /**< DNS class IN. */
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration describes standard DNS record types as described by
|
||||
* RFC 1035, RFC 2782, and others.
|
||||
*/
|
||||
typedef enum pj_dns_type
|
||||
{
|
||||
PJ_DNS_TYPE_A = 1, /**< Host address (A) record. */
|
||||
PJ_DNS_TYPE_NS = 2, /**< Authoritative name server (NS) */
|
||||
PJ_DNS_TYPE_MD = 3, /**< Mail destination (MD) record. */
|
||||
PJ_DNS_TYPE_MF = 4, /**< Mail forwarder (MF) record. */
|
||||
PJ_DNS_TYPE_CNAME = 5, /**< Canonical name (CNAME) record. */
|
||||
PJ_DNS_TYPE_SOA = 6, /**< Marks start of zone authority. */
|
||||
PJ_DNS_TYPE_MB = 7, /**< Mailbox domain name (MB). */
|
||||
PJ_DNS_TYPE_MG = 8, /**< Mail group member (MG). */
|
||||
PJ_DNS_TYPE_MR = 9, /**< Mail rename domain name. */
|
||||
PJ_DNS_TYPE_NULL = 10, /**< NULL RR. */
|
||||
PJ_DNS_TYPE_WKS = 11, /**< Well known service description */
|
||||
PJ_DNS_TYPE_PTR = 12, /**< Domain name pointer. */
|
||||
PJ_DNS_TYPE_HINFO = 13, /**< Host information. */
|
||||
PJ_DNS_TYPE_MINFO = 14, /**< Mailbox or mail list information. */
|
||||
PJ_DNS_TYPE_MX = 15, /**< Mail exchange record. */
|
||||
PJ_DNS_TYPE_TXT = 16, /**< Text string. */
|
||||
PJ_DNS_TYPE_RP = 17, /**< Responsible person. */
|
||||
PJ_DNS_TYPE_AFSB = 18, /**< AFS cell database. */
|
||||
PJ_DNS_TYPE_X25 = 19, /**< X.25 calling address. */
|
||||
PJ_DNS_TYPE_ISDN = 20, /**< ISDN calling address. */
|
||||
PJ_DNS_TYPE_RT = 21, /**< Router. */
|
||||
PJ_DNS_TYPE_NSAP = 22, /**< NSAP address. */
|
||||
PJ_DNS_TYPE_NSAP_PTR= 23, /**< NSAP reverse address. */
|
||||
PJ_DNS_TYPE_SIG = 24, /**< Signature. */
|
||||
PJ_DNS_TYPE_KEY = 25, /**< Key. */
|
||||
PJ_DNS_TYPE_PX = 26, /**< X.400 mail mapping. */
|
||||
PJ_DNS_TYPE_GPOS = 27, /**< Geographical position (withdrawn) */
|
||||
PJ_DNS_TYPE_AAAA = 28, /**< IPv6 address. */
|
||||
PJ_DNS_TYPE_LOC = 29, /**< Location. */
|
||||
PJ_DNS_TYPE_NXT = 30, /**< Next valid name in the zone. */
|
||||
PJ_DNS_TYPE_EID = 31, /**< Endpoint idenfitier. */
|
||||
PJ_DNS_TYPE_NIMLOC = 32, /**< Nimrod locator. */
|
||||
PJ_DNS_TYPE_SRV = 33, /**< Server selection (SRV) record. */
|
||||
PJ_DNS_TYPE_ATMA = 34, /**< DNS ATM address record. */
|
||||
PJ_DNS_TYPE_NAPTR = 35, /**< DNS Naming authority pointer record. */
|
||||
PJ_DNS_TYPE_KX = 36, /**< DNS key exchange record. */
|
||||
PJ_DNS_TYPE_CERT = 37, /**< DNS certificate record. */
|
||||
PJ_DNS_TYPE_A6 = 38, /**< DNS IPv6 address (experimental) */
|
||||
PJ_DNS_TYPE_DNAME = 39, /**< DNS non-terminal name redirection rec. */
|
||||
|
||||
PJ_DNS_TYPE_OPT = 41, /**< DNS options - contains EDNS metadata. */
|
||||
PJ_DNS_TYPE_APL = 42, /**< DNS Address Prefix List (APL) record. */
|
||||
PJ_DNS_TYPE_DS = 43, /**< DNS Delegation Signer (DS) */
|
||||
PJ_DNS_TYPE_SSHFP = 44, /**< DNS SSH Key Fingerprint */
|
||||
PJ_DNS_TYPE_IPSECKEY= 45, /**< DNS IPSEC Key. */
|
||||
PJ_DNS_TYPE_RRSIG = 46, /**< DNS Resource Record signature. */
|
||||
PJ_DNS_TYPE_NSEC = 47, /**< DNS Next Secure Name. */
|
||||
PJ_DNS_TYPE_DNSKEY = 48 /**< DNSSEC Key. */
|
||||
} pj_dns_type;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Standard DNS header, according to RFC 1035, which will be present in
|
||||
* both DNS query and DNS response.
|
||||
*
|
||||
* Note that all values seen by application would be in
|
||||
* host by order. The library would convert them to network
|
||||
* byte order as necessary.
|
||||
*/
|
||||
typedef struct pj_dns_hdr
|
||||
{
|
||||
pj_uint16_t id; /**< Transaction ID. */
|
||||
pj_uint16_t flags; /**< Flags. */
|
||||
pj_uint16_t qdcount; /**< Nb. of queries. */
|
||||
pj_uint16_t anscount; /**< Nb. of res records */
|
||||
pj_uint16_t nscount; /**< Nb. of NS records. */
|
||||
pj_uint16_t arcount; /**< Nb. of additional records */
|
||||
} pj_dns_hdr;
|
||||
|
||||
/** Create RCODE flag */
|
||||
#define PJ_DNS_SET_RCODE(c) ((pj_uint16_t)((c) & 0x0F))
|
||||
|
||||
/** Create RA (Recursion Available) bit */
|
||||
#define PJ_DNS_SET_RA(on) ((pj_uint16_t)((on) << 7))
|
||||
|
||||
/** Create RD (Recursion Desired) bit */
|
||||
#define PJ_DNS_SET_RD(on) ((pj_uint16_t)((on) << 8))
|
||||
|
||||
/** Create TC (Truncated) bit */
|
||||
#define PJ_DNS_SET_TC(on) ((pj_uint16_t)((on) << 9))
|
||||
|
||||
/** Create AA (Authoritative Answer) bit */
|
||||
#define PJ_DNS_SET_AA(on) ((pj_uint16_t)((on) << 10))
|
||||
|
||||
/** Create four bits opcode */
|
||||
#define PJ_DNS_SET_OPCODE(o) ((pj_uint16_t)((o) << 11))
|
||||
|
||||
/** Create query/response bit */
|
||||
#define PJ_DNS_SET_QR(on) ((pj_uint16_t)((on) << 15))
|
||||
|
||||
|
||||
/** Get RCODE value */
|
||||
#define PJ_DNS_GET_RCODE(val) (((val) & PJ_DNS_SET_RCODE(0x0F)) >> 0)
|
||||
|
||||
/** Get RA bit */
|
||||
#define PJ_DNS_GET_RA(val) (((val) & PJ_DNS_SET_RA(1)) >> 7)
|
||||
|
||||
/** Get RD bit */
|
||||
#define PJ_DNS_GET_RD(val) (((val) & PJ_DNS_SET_RD(1)) >> 8)
|
||||
|
||||
/** Get TC bit */
|
||||
#define PJ_DNS_GET_TC(val) (((val) & PJ_DNS_SET_TC(1)) >> 9)
|
||||
|
||||
/** Get AA bit */
|
||||
#define PJ_DNS_GET_AA(val) (((val) & PJ_DNS_SET_AA(1)) >> 10)
|
||||
|
||||
/** Get OPCODE value */
|
||||
#define PJ_DNS_GET_OPCODE(val) (((val) & PJ_DNS_SET_OPCODE(0x0F)) >> 11)
|
||||
|
||||
/** Get QR bit */
|
||||
#define PJ_DNS_GET_QR(val) (((val) & PJ_DNS_SET_QR(1)) >> 15)
|
||||
|
||||
|
||||
/**
|
||||
* These constants describe DNS RCODEs. Application can fold these constants
|
||||
* into PJLIB pj_status_t namespace by calling #PJ_STATUS_FROM_DNS_RCODE()
|
||||
* macro.
|
||||
*/
|
||||
typedef enum pj_dns_rcode
|
||||
{
|
||||
PJ_DNS_RCODE_FORMERR = 1, /**< Format error. */
|
||||
PJ_DNS_RCODE_SERVFAIL = 2, /**< Server failure. */
|
||||
PJ_DNS_RCODE_NXDOMAIN = 3, /**< Name Error. */
|
||||
PJ_DNS_RCODE_NOTIMPL = 4, /**< Not Implemented. */
|
||||
PJ_DNS_RCODE_REFUSED = 5, /**< Refused. */
|
||||
PJ_DNS_RCODE_YXDOMAIN = 6, /**< The name exists. */
|
||||
PJ_DNS_RCODE_YXRRSET = 7, /**< The RRset (name, type) exists. */
|
||||
PJ_DNS_RCODE_NXRRSET = 8, /**< The RRset (name, type) doesn't exist*/
|
||||
PJ_DNS_RCODE_NOTAUTH = 9, /**< Not authorized. */
|
||||
PJ_DNS_RCODE_NOTZONE = 10 /**< The zone specified is not a zone. */
|
||||
|
||||
} pj_dns_rcode;
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes a DNS query record.
|
||||
*/
|
||||
typedef struct pj_dns_parsed_query
|
||||
{
|
||||
pj_str_t name; /**< The domain in the query. */
|
||||
pj_uint16_t type; /**< Type of the query (pj_dns_type) */
|
||||
pj_uint16_t dnsclass; /**< Network class (PJ_DNS_CLASS_IN=1) */
|
||||
} pj_dns_parsed_query;
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes a Resource Record parsed from the DNS packet.
|
||||
* All integral values are in host byte order.
|
||||
*/
|
||||
typedef struct pj_dns_parsed_rr
|
||||
{
|
||||
pj_str_t name; /**< The domain name which this rec pertains. */
|
||||
pj_uint16_t type; /**< RR type code. */
|
||||
pj_uint16_t dnsclass; /**< Class of data (PJ_DNS_CLASS_IN=1). */
|
||||
pj_uint32_t ttl; /**< Time to live. */
|
||||
pj_uint16_t rdlength; /**< Resource data length. */
|
||||
void *data; /**< Pointer to the raw resource data, only
|
||||
when the type is not known. If it is known,
|
||||
the data will be put in rdata below. */
|
||||
|
||||
/** For resource types that are recognized/supported by this library,
|
||||
* the parsed resource data will be placed in this rdata union.
|
||||
*/
|
||||
union rdata
|
||||
{
|
||||
/** SRV Resource Data (PJ_DNS_TYPE_SRV, 33) */
|
||||
struct srv {
|
||||
pj_uint16_t prio; /**< Target priority (lower is higher). */
|
||||
pj_uint16_t weight; /**< Weight/proportion */
|
||||
pj_uint16_t port; /**< Port number of the service */
|
||||
pj_str_t target; /**< Target name. */
|
||||
} srv;
|
||||
|
||||
/** CNAME Resource Data (PJ_DNS_TYPE_CNAME, 5) */
|
||||
struct cname {
|
||||
pj_str_t name; /**< Primary canonical name for an alias. */
|
||||
} cname;
|
||||
|
||||
/** NS Resource Data (PJ_DNS_TYPE_NS, 2) */
|
||||
struct ns {
|
||||
pj_str_t name; /**< Primary name server. */
|
||||
} ns;
|
||||
|
||||
/** PTR Resource Data (PJ_DNS_TYPE_PTR, 12) */
|
||||
struct ptr {
|
||||
pj_str_t name; /**< PTR name. */
|
||||
} ptr;
|
||||
|
||||
/** A Resource Data (PJ_DNS_TYPE_A, 1) */
|
||||
struct a {
|
||||
pj_in_addr ip_addr;/**< IPv4 address in network byte order. */
|
||||
} a;
|
||||
|
||||
/** AAAA Resource Data (PJ_DNS_TYPE_AAAA, 28) */
|
||||
struct aaaa {
|
||||
pj_in6_addr ip_addr;/**< IPv6 address in network byte order. */
|
||||
} aaaa;
|
||||
|
||||
} rdata;
|
||||
|
||||
} pj_dns_parsed_rr;
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes the parsed repersentation of the raw DNS packet.
|
||||
* Note that all integral values in the parsed packet are represented in
|
||||
* host byte order.
|
||||
*/
|
||||
typedef struct pj_dns_parsed_packet
|
||||
{
|
||||
pj_dns_hdr hdr; /**< Pointer to DNS hdr, in host byte order */
|
||||
pj_dns_parsed_query *q; /**< Array of DNS queries. */
|
||||
pj_dns_parsed_rr *ans; /**< Array of DNS RR answer. */
|
||||
pj_dns_parsed_rr *ns; /**< Array of NS record in the answer. */
|
||||
pj_dns_parsed_rr *arr; /**< Array of additional RR answer. */
|
||||
} pj_dns_parsed_packet;
|
||||
|
||||
|
||||
/**
|
||||
* Option flags to be specified when calling #pj_dns_packet_dup() function.
|
||||
* These flags can be combined with bitwise OR operation.
|
||||
*/
|
||||
enum pj_dns_dup_options
|
||||
{
|
||||
PJ_DNS_NO_QD = 1, /**< Do not duplicate the query section. */
|
||||
PJ_DNS_NO_ANS = 2, /**< Do not duplicate the answer section. */
|
||||
PJ_DNS_NO_NS = 4, /**< Do not duplicate the NS section. */
|
||||
PJ_DNS_NO_AR = 8 /**< Do not duplicate the additional rec section */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create DNS query packet to resolve the specified names. This function
|
||||
* can be used to build any types of DNS query, such as A record or DNS SRV
|
||||
* record.
|
||||
*
|
||||
* Application specifies the type of record and the name to be queried,
|
||||
* and the function will build the DNS query packet into the buffer
|
||||
* specified. Once the packet is successfully built, application can send
|
||||
* the packet via TCP or UDP connection.
|
||||
*
|
||||
* @param packet The buffer to put the DNS query packet.
|
||||
* @param size On input, it specifies the size of the buffer.
|
||||
* On output, it will be filled with the actual size of
|
||||
* the DNS query packet.
|
||||
* @param id DNS query ID to associate DNS response with the
|
||||
* query.
|
||||
* @param qtype DNS type of record to be queried (see #pj_dns_type).
|
||||
* @param name Name to be queried from the DNS server.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_make_query(void *packet,
|
||||
unsigned *size,
|
||||
pj_uint16_t id,
|
||||
int qtype,
|
||||
const pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Parse raw DNS packet into parsed DNS packet structure. This function is
|
||||
* able to parse few DNS resource records such as A record, PTR record,
|
||||
* CNAME record, NS record, and SRV record.
|
||||
*
|
||||
* @param pool Pool to allocate memory for the parsed packet.
|
||||
* @param packet Pointer to the DNS packet (the TCP/UDP payload of
|
||||
* the raw packet).
|
||||
* @param size The size of the DNS packet.
|
||||
* @param p_res Pointer to store the resulting parsed packet.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_parse_packet(pj_pool_t *pool,
|
||||
const void *packet,
|
||||
unsigned size,
|
||||
pj_dns_parsed_packet **p_res);
|
||||
|
||||
/**
|
||||
* Duplicate DNS packet.
|
||||
*
|
||||
* @param pool The pool to allocate memory for the duplicated packet.
|
||||
* @param p The DNS packet to be cloned.
|
||||
* @param options Option flags, from pj_dns_dup_options.
|
||||
* @param p_dst Pointer to store the cloned DNS packet.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_packet_dup(pj_pool_t *pool,
|
||||
const pj_dns_parsed_packet*p,
|
||||
unsigned options,
|
||||
pj_dns_parsed_packet **p_dst);
|
||||
|
||||
|
||||
/**
|
||||
* Utility function to get the type name string of the specified DNS type.
|
||||
*
|
||||
* @param type DNS type (see #pj_dns_type).
|
||||
*
|
||||
* @return String name of the type (e.g. "A", "SRV", etc.).
|
||||
*/
|
||||
PJ_DECL(const char *) pj_dns_get_type_name(int type);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize DNS record as DNS SRV record.
|
||||
*
|
||||
* @param rec The DNS resource record to be initialized as DNS
|
||||
* SRV record.
|
||||
* @param res_name Resource name.
|
||||
* @param dnsclass DNS class.
|
||||
* @param ttl Resource TTL value.
|
||||
* @param prio DNS SRV priority.
|
||||
* @param weight DNS SRV weight.
|
||||
* @param port Target port.
|
||||
* @param target Target name.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_init_srv_rr(pj_dns_parsed_rr *rec,
|
||||
const pj_str_t *res_name,
|
||||
unsigned dnsclass,
|
||||
unsigned ttl,
|
||||
unsigned prio,
|
||||
unsigned weight,
|
||||
unsigned port,
|
||||
const pj_str_t *target);
|
||||
|
||||
/**
|
||||
* Initialize DNS record as DNS CNAME record.
|
||||
*
|
||||
* @param rec The DNS resource record to be initialized as DNS
|
||||
* CNAME record.
|
||||
* @param res_name Resource name.
|
||||
* @param dnsclass DNS class.
|
||||
* @param ttl Resource TTL value.
|
||||
* @param name Host name.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_init_cname_rr(pj_dns_parsed_rr *rec,
|
||||
const pj_str_t *res_name,
|
||||
unsigned dnsclass,
|
||||
unsigned ttl,
|
||||
const pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Initialize DNS record as DNS A record.
|
||||
*
|
||||
* @param rec The DNS resource record to be initialized as DNS
|
||||
* A record.
|
||||
* @param res_name Resource name.
|
||||
* @param dnsclass DNS class.
|
||||
* @param ttl Resource TTL value.
|
||||
* @param ip_addr Host address.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_init_a_rr(pj_dns_parsed_rr *rec,
|
||||
const pj_str_t *res_name,
|
||||
unsigned dnsclass,
|
||||
unsigned ttl,
|
||||
const pj_in_addr *ip_addr);
|
||||
|
||||
/**
|
||||
* Initialize DNS record as DNS AAAA record.
|
||||
*
|
||||
* @param rec The DNS resource record to be initialized as DNS
|
||||
* AAAA record.
|
||||
* @param res_name Resource name.
|
||||
* @param dnsclass DNS class.
|
||||
* @param ttl Resource TTL value.
|
||||
* @param ip_addr Host address.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_init_aaaa_rr(pj_dns_parsed_rr *rec,
|
||||
const pj_str_t *res_name,
|
||||
unsigned dnsclass,
|
||||
unsigned ttl,
|
||||
const pj_in6_addr *ip_addr);
|
||||
|
||||
/**
|
||||
* Dump DNS packet to standard log.
|
||||
*
|
||||
* @param res The DNS packet.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_dump_packet(const pj_dns_parsed_packet *res);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_DNS_H__ */
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_DNS_SERVER_H__
|
||||
#define __PJLIB_UTIL_DNS_SERVER_H__
|
||||
|
||||
/**
|
||||
* @file dns_server.h
|
||||
* @brief Simple DNS server
|
||||
*/
|
||||
#include <pjlib-util/types.h>
|
||||
#include <pjlib-util/dns.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_DNS_SERVER Simple DNS Server
|
||||
* @ingroup PJ_DNS
|
||||
* @{
|
||||
* This contains a simple but fully working DNS server implementation,
|
||||
* mostly for testing purposes. It supports serving various DNS resource
|
||||
* records such as SRV, CNAME, A, and AAAA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Opaque structure to hold DNS server instance.
|
||||
*/
|
||||
typedef struct pj_dns_server pj_dns_server;
|
||||
|
||||
/**
|
||||
* Create the DNS server instance. The instance will run immediately.
|
||||
*
|
||||
* @param pf The pool factory to create memory pools.
|
||||
* @param ioqueue Ioqueue instance where the server socket will be
|
||||
* registered to.
|
||||
* @param af Address family of the server socket (valid values
|
||||
* are pj_AF_INET() for IPv4 and pj_AF_INET6() for IPv6).
|
||||
* @param port The UDP port to listen.
|
||||
* @param flags Flags, currently must be zero.
|
||||
* @param p_srv Pointer to receive the DNS server instance.
|
||||
*
|
||||
* @return PJ_SUCCESS if server has been created successfully,
|
||||
* otherwise the function will return the appropriate
|
||||
* error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_server_create(pj_pool_factory *pf,
|
||||
pj_ioqueue_t *ioqueue,
|
||||
int af,
|
||||
unsigned port,
|
||||
unsigned flags,
|
||||
pj_dns_server **p_srv);
|
||||
|
||||
/**
|
||||
* Destroy DNS server instance.
|
||||
*
|
||||
* @param srv The DNS server instance.
|
||||
*
|
||||
* @return PJ_SUCCESS on success or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_server_destroy(pj_dns_server *srv);
|
||||
|
||||
|
||||
/**
|
||||
* Add generic resource record entries to the server.
|
||||
*
|
||||
* @param srv The DNS server instance.
|
||||
* @param count Number of records to be added.
|
||||
* @param rr Array of records to be added.
|
||||
*
|
||||
* @return PJ_SUCCESS on success or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_server_add_rec(pj_dns_server *srv,
|
||||
unsigned count,
|
||||
const pj_dns_parsed_rr rr[]);
|
||||
|
||||
/**
|
||||
* Remove the specified record from the server.
|
||||
*
|
||||
* @param srv The DNS server instance.
|
||||
* @param dns_class The resource's DNS class. Valid value is PJ_DNS_CLASS_IN.
|
||||
* @param type The resource type.
|
||||
* @param name The resource name to be removed.
|
||||
*
|
||||
* @return PJ_SUCCESS on success or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_server_del_rec(pj_dns_server *srv,
|
||||
int dns_class,
|
||||
pj_dns_type type,
|
||||
const pj_str_t *name);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_DNS_SERVER_H__ */
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_ERRNO_H__
|
||||
#define __PJLIB_UTIL_ERRNO_H__
|
||||
|
||||
|
||||
#include <pj/errno.h>
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_ERROR Error Codes
|
||||
* @ingroup PJLIB_UTIL_BASE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Start of error code relative to PJ_ERRNO_START_USER.
|
||||
* This value is 320000.
|
||||
*/
|
||||
#define PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)
|
||||
|
||||
|
||||
/************************************************************
|
||||
* STUN ERROR
|
||||
***********************************************************/
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Unable to resolve STUN server
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNRESOLVE (PJLIB_UTIL_ERRNO_START+1) /* 320001 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Unknown STUN message type.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNINMSGTYPE (PJLIB_UTIL_ERRNO_START+2) /* 320002 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN message length
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNINMSGLEN (PJLIB_UTIL_ERRNO_START+3) /* 320003 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN attribute length
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNINATTRLEN (PJLIB_UTIL_ERRNO_START+4) /* 320004 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN attribute type
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNINATTRTYPE (PJLIB_UTIL_ERRNO_START+5) /* 320005 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN server/socket index
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNININDEX (PJLIB_UTIL_ERRNO_START+6) /* 320006 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* No STUN binding response in the message
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOBINDRES (PJLIB_UTIL_ERRNO_START+7) /* 320007 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Received STUN error attribute
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNRECVERRATTR (PJLIB_UTIL_ERRNO_START+8) /* 320008 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* No STUN mapped address attribute
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOMAP (PJLIB_UTIL_ERRNO_START+9) /* 320009 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Received no response from STUN server
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOTRESPOND (PJLIB_UTIL_ERRNO_START+10) /* 320010 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Symetric NAT detected by STUN
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNSYMMETRIC (PJLIB_UTIL_ERRNO_START+11) /* 320011 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN magic value
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOTMAGIC (PJLIB_UTIL_ERRNO_START+12) /* 320012 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN fingerprint value
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNFINGERPRINT (PJLIB_UTIL_ERRNO_START+13) /* 320013 */
|
||||
|
||||
|
||||
|
||||
/************************************************************
|
||||
* XML ERROR
|
||||
***********************************************************/
|
||||
/**
|
||||
* @hideinitializer
|
||||
* General invalid XML message.
|
||||
*/
|
||||
#define PJLIB_UTIL_EINXML (PJLIB_UTIL_ERRNO_START+20) /* 320020 */
|
||||
|
||||
|
||||
/************************************************************
|
||||
* JSON ERROR
|
||||
***********************************************************/
|
||||
/**
|
||||
* @hideinitializer
|
||||
* General invalid JSON message.
|
||||
*/
|
||||
#define PJLIB_UTIL_EINJSON (PJLIB_UTIL_ERRNO_START+30) /* 320030 */
|
||||
|
||||
|
||||
/************************************************************
|
||||
* DNS ERROR
|
||||
***********************************************************/
|
||||
/**
|
||||
* @hideinitializer
|
||||
* DNS query packet buffer is too small.
|
||||
* This error occurs when the user supplied buffer for creating DNS
|
||||
* query (#pj_dns_make_query() function) is too small.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSQRYTOOSMALL (PJLIB_UTIL_ERRNO_START+40) /* 320040 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid DNS packet length.
|
||||
* This error occurs when the received DNS response packet does not
|
||||
* match all the fields length.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSINSIZE (PJLIB_UTIL_ERRNO_START+41) /* 320041 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid DNS class.
|
||||
* This error occurs when the received DNS response contains network
|
||||
* class other than IN (Internet).
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSINCLASS (PJLIB_UTIL_ERRNO_START+42) /* 320042 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid DNS name pointer.
|
||||
* This error occurs when parsing the compressed names inside DNS
|
||||
* response packet, when the name pointer points to an invalid address
|
||||
* or the parsing has triggerred too much recursion.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSINNAMEPTR (PJLIB_UTIL_ERRNO_START+43) /* 320043 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid DNS nameserver address. If hostname was specified for nameserver
|
||||
* address, this error means that the function was unable to resolve
|
||||
* the nameserver hostname.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSINNSADDR (PJLIB_UTIL_ERRNO_START+44) /* 320044 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* No nameserver is in DNS resolver. No nameserver is configured in the
|
||||
* resolver.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSNONS (PJLIB_UTIL_ERRNO_START+45) /* 320045 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* No working DNS nameserver. All nameservers have been queried,
|
||||
* but none was able to serve any DNS requests. These "bad" nameservers
|
||||
* will be re-tested again for "goodness" after some period.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSNOWORKINGNS (PJLIB_UTIL_ERRNO_START+46) /* 320046 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* No answer record in the DNS response.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSNOANSWERREC (PJLIB_UTIL_ERRNO_START+47) /* 320047 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid DNS answer. This error is raised for example when the DNS
|
||||
* answer does not have a query section, or the type of RR in the answer
|
||||
* doesn't match the query.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNSINANSWER (PJLIB_UTIL_ERRNO_START+48) /* 320048 */
|
||||
|
||||
|
||||
/* DNS ERRORS MAPPED FROM RCODE: */
|
||||
|
||||
/**
|
||||
* Start of error code mapped from DNS RCODE
|
||||
*/
|
||||
#define PJLIB_UTIL_DNS_RCODE_START (PJLIB_UTIL_ERRNO_START+50) /* 320050 */
|
||||
|
||||
/**
|
||||
* Map DNS RCODE status into pj_status_t.
|
||||
*/
|
||||
#define PJ_STATUS_FROM_DNS_RCODE(rcode) (rcode==0 ? PJ_SUCCESS : \
|
||||
PJLIB_UTIL_DNS_RCODE_START+rcode)
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Format error - The name server was unable to interpret the query.
|
||||
* This corresponds to DNS RCODE 1.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_FORMERR PJ_STATUS_FROM_DNS_RCODE(1) /* 320051 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Server failure - The name server was unable to process this query due to a
|
||||
* problem with the name server.
|
||||
* This corresponds to DNS RCODE 2.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_SERVFAIL PJ_STATUS_FROM_DNS_RCODE(2) /* 320052 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Name Error - Meaningful only for responses from an authoritative name
|
||||
* server, this code signifies that the domain name referenced in the query
|
||||
* does not exist.
|
||||
* This corresponds to DNS RCODE 3.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_NXDOMAIN PJ_STATUS_FROM_DNS_RCODE(3) /* 320053 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Not Implemented - The name server does not support the requested kind of
|
||||
* query.
|
||||
* This corresponds to DNS RCODE 4.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_NOTIMPL PJ_STATUS_FROM_DNS_RCODE(4) /* 320054 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Refused - The name server refuses to perform the specified operation for
|
||||
* policy reasons.
|
||||
* This corresponds to DNS RCODE 5.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_REFUSED PJ_STATUS_FROM_DNS_RCODE(5) /* 320055 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* The name exists.
|
||||
* This corresponds to DNS RCODE 6.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_YXDOMAIN PJ_STATUS_FROM_DNS_RCODE(6) /* 320056 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* The RRset (name, type) exists.
|
||||
* This corresponds to DNS RCODE 7.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_YXRRSET PJ_STATUS_FROM_DNS_RCODE(7) /* 320057 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* The RRset (name, type) does not exist.
|
||||
* This corresponds to DNS RCODE 8.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_NXRRSET PJ_STATUS_FROM_DNS_RCODE(8) /* 320058 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* The requestor is not authorized to perform this operation.
|
||||
* This corresponds to DNS RCODE 9.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_NOTAUTH PJ_STATUS_FROM_DNS_RCODE(9) /* 320059 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* The zone specified is not a zone.
|
||||
* This corresponds to DNS RCODE 10.
|
||||
*/
|
||||
#define PJLIB_UTIL_EDNS_NOTZONE PJ_STATUS_FROM_DNS_RCODE(10)/* 320060 */
|
||||
|
||||
|
||||
/************************************************************
|
||||
* NEW STUN ERROR
|
||||
***********************************************************/
|
||||
/* Messaging errors */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Too many STUN attributes.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNTOOMANYATTR (PJLIB_UTIL_ERRNO_START+110)/* 320110 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Unknown STUN attribute. This error happens when the decoder encounters
|
||||
* mandatory attribute type which it doesn't understand.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNUNKNOWNATTR (PJLIB_UTIL_ERRNO_START+111)/* 320111 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid STUN socket address length.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNINADDRLEN (PJLIB_UTIL_ERRNO_START+112)/* 320112 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* STUN IPv6 attribute not supported
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNIPV6NOTSUPP (PJLIB_UTIL_ERRNO_START+113)/* 320113 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Expecting STUN response message.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOTRESPONSE (PJLIB_UTIL_ERRNO_START+114)/* 320114 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* STUN transaction ID mismatch.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNINVALIDID (PJLIB_UTIL_ERRNO_START+115)/* 320115 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Unable to find handler for the request.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOHANDLER (PJLIB_UTIL_ERRNO_START+116)/* 320116 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Found non-FINGERPRINT attribute after MESSAGE-INTEGRITY. This is not
|
||||
* valid since MESSAGE-INTEGRITY MUST be the last attribute or the
|
||||
* attribute right before FINGERPRINT before the message.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNMSGINTPOS (PJLIB_UTIL_ERRNO_START+118)/* 320118 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Found attribute after FINGERPRINT. This is not valid since FINGERPRINT
|
||||
* MUST be the last attribute in the message.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNFINGERPOS (PJLIB_UTIL_ERRNO_START+119)/* 320119 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Missing STUN USERNAME attribute.
|
||||
* When credential is included in the STUN message (MESSAGE-INTEGRITY is
|
||||
* present), the USERNAME attribute must be present in the message.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOUSERNAME (PJLIB_UTIL_ERRNO_START+120)/* 320120 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Unknown STUN username/credential.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNUSERNAME (PJLIB_UTIL_ERRNO_START+121)/* 320121 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Missing/invalidSTUN MESSAGE-INTEGRITY attribute.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNMSGINT (PJLIB_UTIL_ERRNO_START+122)/* 320122 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Found duplicate STUN attribute.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNDUPATTR (PJLIB_UTIL_ERRNO_START+123)/* 320123 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Missing STUN REALM attribute.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNOREALM (PJLIB_UTIL_ERRNO_START+124)/* 320124 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Missing/stale STUN NONCE attribute value.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNNONCE (PJLIB_UTIL_ERRNO_START+125)/* 320125 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* STUN transaction terminates with failure.
|
||||
*/
|
||||
#define PJLIB_UTIL_ESTUNTSXFAILED (PJLIB_UTIL_ERRNO_START+126)/* 320126 */
|
||||
|
||||
|
||||
//#define PJ_STATUS_FROM_STUN_CODE(code) (PJLIB_UTIL_ERRNO_START+code)
|
||||
|
||||
/************************************************************
|
||||
* HTTP Client ERROR
|
||||
***********************************************************/
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid URL format
|
||||
*/
|
||||
#define PJLIB_UTIL_EHTTPINURL (PJLIB_UTIL_ERRNO_START+151)/* 320151 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid port number
|
||||
*/
|
||||
#define PJLIB_UTIL_EHTTPINPORT (PJLIB_UTIL_ERRNO_START+152)/* 320152 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Incomplete headers received
|
||||
*/
|
||||
#define PJLIB_UTIL_EHTTPINCHDR (PJLIB_UTIL_ERRNO_START+153)/* 320153 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Insufficient buffer
|
||||
*/
|
||||
#define PJLIB_UTIL_EHTTPINSBUF (PJLIB_UTIL_ERRNO_START+154)/* 320154 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Connection lost
|
||||
*/
|
||||
#define PJLIB_UTIL_EHTTPLOST (PJLIB_UTIL_ERRNO_START+155)/* 320155 */
|
||||
|
||||
/************************************************************
|
||||
* CLI ERROR
|
||||
***********************************************************/
|
||||
|
||||
/**
|
||||
* @hideinitializer
|
||||
* End the current session. This is a special error code returned by
|
||||
* pj_cli_sess_exec() to indicate that "exit" or equivalent command has been
|
||||
* called to end the current session.
|
||||
*/
|
||||
#define PJ_CLI_EEXIT (PJLIB_UTIL_ERRNO_START+201)/* 320201 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* A required CLI argument is not specified.
|
||||
*/
|
||||
#define PJ_CLI_EMISSINGARG (PJLIB_UTIL_ERRNO_START+202)/* 320202 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Too many CLI arguments.
|
||||
*/
|
||||
#define PJ_CLI_ETOOMANYARGS (PJLIB_UTIL_ERRNO_START+203)/* 320203 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid CLI argument. Typically this is caused by extra characters
|
||||
* specified in the command line which does not match any arguments.
|
||||
*/
|
||||
#define PJ_CLI_EINVARG (PJLIB_UTIL_ERRNO_START+204)/* 320204 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* CLI command with the specified name already exist.
|
||||
*/
|
||||
#define PJ_CLI_EBADNAME (PJLIB_UTIL_ERRNO_START+205)/* 320205 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* CLI command with the specified id already exist.
|
||||
*/
|
||||
#define PJ_CLI_EBADID (PJLIB_UTIL_ERRNO_START+206)/* 320206 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Invalid XML format for CLI command specification.
|
||||
*/
|
||||
#define PJ_CLI_EBADXML (PJLIB_UTIL_ERRNO_START+207)/* 320207 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* CLI command entered by user match with more than one command/argument
|
||||
* specification.
|
||||
*/
|
||||
#define PJ_CLI_EAMBIGUOUS (PJLIB_UTIL_ERRNO_START+208)/* 320208 */
|
||||
/**
|
||||
* @hideinitializer
|
||||
* Telnet connection lost.
|
||||
*/
|
||||
#define PJ_CLI_ETELNETLOST (PJLIB_UTIL_ERRNO_START+211)/* 320211 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __PJLIB_UTIL_ERRNO_H__ */
|
||||
@@ -0,0 +1,145 @@
|
||||
/* $Id$ */
|
||||
/* Declarations for pj_getopt.
|
||||
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef __PJ_GETOPT_H__
|
||||
#define __PJ_GETOPT_H__ 1
|
||||
|
||||
/**
|
||||
* @file getopt.h
|
||||
* @brief Compile time settings
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_GETOPT Getopt
|
||||
* @ingroup PJLIB_TEXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `pj_getopt' to the caller.
|
||||
When `pj_getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *pj_optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `pj_getopt'.
|
||||
|
||||
On entry to `pj_getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `pj_getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `pj_optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int pj_optind;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int pj_optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to pj_getopt_long or pj_getopt_long_only is a vector
|
||||
of `struct pj_getopt_option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `pj_optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `pj_getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct pj_getopt_option
|
||||
{
|
||||
const char *name;
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct pj_getopt_option'. */
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `pj_optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `pj_optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `pj_getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `pj_getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`pj_getopt'. */
|
||||
|
||||
int pj_getopt (int argc, char *const *argv, const char *shortopts);
|
||||
|
||||
int pj_getopt_long (int argc, char *const *argv, const char *options,
|
||||
const struct pj_getopt_option *longopts, int *longind);
|
||||
int pj_getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct pj_getopt_option *longopts, int *longind);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* pj_getopt.h */
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_HMAC_MD5_H__
|
||||
#define __PJLIB_UTIL_HMAC_MD5_H__
|
||||
|
||||
/**
|
||||
* @file hmac_md5.h
|
||||
* @brief HMAC MD5 Message Authentication
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_ENCRYPTION Encryption Algorithms
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
#include <pjlib-util/md5.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_HMAC_MD5 HMAC MD5 Message Authentication
|
||||
* @ingroup PJLIB_UTIL_ENCRYPTION
|
||||
* @{
|
||||
*
|
||||
* This module contains the implementation of HMAC: Keyed-Hashing
|
||||
* for Message Authentication, as described in RFC 2104
|
||||
*/
|
||||
|
||||
/**
|
||||
* The HMAC-MD5 context used in the incremental HMAC calculation.
|
||||
*/
|
||||
typedef struct pj_hmac_md5_context
|
||||
{
|
||||
pj_md5_context context; /**< MD5 context */
|
||||
pj_uint8_t k_opad[64]; /**< opad xor-ed with key */
|
||||
} pj_hmac_md5_context;
|
||||
|
||||
|
||||
/**
|
||||
* Calculate HMAC MD5 digest for the specified input and key.
|
||||
*
|
||||
* @param input Pointer to the input stream.
|
||||
* @param input_len Length of input stream in bytes.
|
||||
* @param key Pointer to the authentication key.
|
||||
* @param key_len Length of the authentication key.
|
||||
* @param digest Buffer to be filled with HMAC MD5 digest.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_md5(const pj_uint8_t *input, unsigned input_len,
|
||||
const pj_uint8_t *key, unsigned key_len,
|
||||
pj_uint8_t digest[16]);
|
||||
|
||||
|
||||
/**
|
||||
* Initiate HMAC-MD5 context for incremental hashing.
|
||||
*
|
||||
* @param hctx HMAC-MD5 context.
|
||||
* @param key Pointer to the authentication key.
|
||||
* @param key_len Length of the authentication key.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_md5_init(pj_hmac_md5_context *hctx,
|
||||
const pj_uint8_t *key, unsigned key_len);
|
||||
|
||||
/**
|
||||
* Append string to the message.
|
||||
*
|
||||
* @param hctx HMAC-MD5 context.
|
||||
* @param input Pointer to the input stream.
|
||||
* @param input_len Length of input stream in bytes.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_md5_update(pj_hmac_md5_context *hctx,
|
||||
const pj_uint8_t *input,
|
||||
unsigned input_len);
|
||||
|
||||
/**
|
||||
* Finish the message and return the digest.
|
||||
*
|
||||
* @param hctx HMAC-MD5 context.
|
||||
* @param digest Buffer to be filled with HMAC MD5 digest.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_md5_final(pj_hmac_md5_context *hctx,
|
||||
pj_uint8_t digest[16]);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_HMAC_MD5_H__ */
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_HMAC_SHA1_H__
|
||||
#define __PJLIB_UTIL_HMAC_SHA1_H__
|
||||
|
||||
/**
|
||||
* @file hmac_sha1.h
|
||||
* @brief HMAC SHA1 Message Authentication
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
#include <pjlib-util/sha1.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_HMAC_SHA1 HMAC SHA1 Message Authentication
|
||||
* @ingroup PJLIB_UTIL_ENCRYPTION
|
||||
* @{
|
||||
*
|
||||
* This module contains the implementation of HMAC: Keyed-Hashing
|
||||
* for Message Authentication, as described in RFC 2104.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The HMAC-SHA1 context used in the incremental HMAC calculation.
|
||||
*/
|
||||
typedef struct pj_hmac_sha1_context
|
||||
{
|
||||
pj_sha1_context context; /**< SHA1 context */
|
||||
pj_uint8_t k_opad[64]; /**< opad xor-ed with key */
|
||||
} pj_hmac_sha1_context;
|
||||
|
||||
|
||||
/**
|
||||
* Calculate HMAC-SHA1 digest for the specified input and key with this
|
||||
* single function call.
|
||||
*
|
||||
* @param input Pointer to the input stream.
|
||||
* @param input_len Length of input stream in bytes.
|
||||
* @param key Pointer to the authentication key.
|
||||
* @param key_len Length of the authentication key.
|
||||
* @param digest Buffer to be filled with HMAC SHA1 digest.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_sha1(const pj_uint8_t *input, unsigned input_len,
|
||||
const pj_uint8_t *key, unsigned key_len,
|
||||
pj_uint8_t digest[20]);
|
||||
|
||||
|
||||
/**
|
||||
* Initiate HMAC-SHA1 context for incremental hashing.
|
||||
*
|
||||
* @param hctx HMAC-SHA1 context.
|
||||
* @param key Pointer to the authentication key.
|
||||
* @param key_len Length of the authentication key.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_sha1_init(pj_hmac_sha1_context *hctx,
|
||||
const pj_uint8_t *key, unsigned key_len);
|
||||
|
||||
/**
|
||||
* Append string to the message.
|
||||
*
|
||||
* @param hctx HMAC-SHA1 context.
|
||||
* @param input Pointer to the input stream.
|
||||
* @param input_len Length of input stream in bytes.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_sha1_update(pj_hmac_sha1_context *hctx,
|
||||
const pj_uint8_t *input,
|
||||
unsigned input_len);
|
||||
|
||||
/**
|
||||
* Finish the message and return the digest.
|
||||
*
|
||||
* @param hctx HMAC-SHA1 context.
|
||||
* @param digest Buffer to be filled with HMAC SHA1 digest.
|
||||
*/
|
||||
PJ_DECL(void) pj_hmac_sha1_final(pj_hmac_sha1_context *hctx,
|
||||
pj_uint8_t digest[20]);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_HMAC_SHA1_H__ */
|
||||
|
||||
|
||||
@@ -0,0 +1,494 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_HTTP_CLIENT_H__
|
||||
#define __PJLIB_UTIL_HTTP_CLIENT_H__
|
||||
|
||||
/**
|
||||
* @file http_client.h
|
||||
* @brief Simple HTTP Client
|
||||
*/
|
||||
#include <pj/activesock.h>
|
||||
#include <pjlib-util/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_HTTP_CLIENT Simple HTTP Client
|
||||
* @ingroup PJ_PROTOCOLS
|
||||
* @{
|
||||
* This contains a simple HTTP client implementation.
|
||||
* Some known limitations:
|
||||
* - Does not support chunked Transfer-Encoding.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This opaque structure describes the http request.
|
||||
*/
|
||||
typedef struct pj_http_req pj_http_req;
|
||||
|
||||
/**
|
||||
* Defines the maximum number of elements in a pj_http_headers
|
||||
* structure.
|
||||
*/
|
||||
#define PJ_HTTP_HEADER_SIZE 32
|
||||
|
||||
/**
|
||||
* HTTP header representation.
|
||||
*/
|
||||
typedef struct pj_http_header_elmt
|
||||
{
|
||||
pj_str_t name; /**< Header name */
|
||||
pj_str_t value; /**< Header value */
|
||||
} pj_http_header_elmt;
|
||||
|
||||
/**
|
||||
* This structure describes http request/response headers.
|
||||
* Application should call #pj_http_headers_add_elmt() to
|
||||
* add a header field.
|
||||
*/
|
||||
typedef struct pj_http_headers
|
||||
{
|
||||
/**< Number of header fields */
|
||||
unsigned count;
|
||||
|
||||
/** Header elements/fields */
|
||||
pj_http_header_elmt header[PJ_HTTP_HEADER_SIZE];
|
||||
} pj_http_headers;
|
||||
|
||||
/**
|
||||
* Structure to save HTTP authentication credential.
|
||||
*/
|
||||
typedef struct pj_http_auth_cred
|
||||
{
|
||||
/**
|
||||
* Specify specific authentication schemes to be responded. Valid values
|
||||
* are "basic" and "digest". If this field is not set, any authentication
|
||||
* schemes will be responded.
|
||||
*
|
||||
* Default is empty.
|
||||
*/
|
||||
pj_str_t scheme;
|
||||
|
||||
/**
|
||||
* Specify specific authentication realm to be responded. If this field
|
||||
* is set, only 401/407 response with matching realm will be responded.
|
||||
* If this field is not set, any realms will be responded.
|
||||
*
|
||||
* Default is empty.
|
||||
*/
|
||||
pj_str_t realm;
|
||||
|
||||
/**
|
||||
* Specify authentication username.
|
||||
*
|
||||
* Default is empty.
|
||||
*/
|
||||
pj_str_t username;
|
||||
|
||||
/**
|
||||
* The type of password in \a data field. Currently only 0 is
|
||||
* supported, meaning the \a data contains plain-text password.
|
||||
*
|
||||
* Default is 0.
|
||||
*/
|
||||
unsigned data_type;
|
||||
|
||||
/**
|
||||
* Specify authentication password. The encoding of the password depends
|
||||
* on the value of \a data_type field above.
|
||||
*
|
||||
* Default is empty.
|
||||
*/
|
||||
pj_str_t data;
|
||||
|
||||
} pj_http_auth_cred;
|
||||
|
||||
|
||||
/**
|
||||
* Parameters that can be given during http request creation. Application
|
||||
* must initialize this structure with #pj_http_req_param_default().
|
||||
*/
|
||||
typedef struct pj_http_req_param
|
||||
{
|
||||
/**
|
||||
* The address family of the URL.
|
||||
* Default is pj_AF_INET().
|
||||
*/
|
||||
int addr_family;
|
||||
|
||||
/**
|
||||
* The HTTP request method.
|
||||
* Default is GET.
|
||||
*/
|
||||
pj_str_t method;
|
||||
|
||||
/**
|
||||
* The HTTP protocol version ("1.0" or "1.1").
|
||||
* Default is "1.0".
|
||||
*/
|
||||
pj_str_t version;
|
||||
|
||||
/**
|
||||
* HTTP request operation timeout.
|
||||
* Default is PJ_HTTP_DEFAULT_TIMEOUT.
|
||||
*/
|
||||
pj_time_val timeout;
|
||||
|
||||
/**
|
||||
* User-defined data.
|
||||
* Default is NULL.
|
||||
*/
|
||||
void *user_data;
|
||||
|
||||
/**
|
||||
* HTTP request headers.
|
||||
* Default is empty.
|
||||
*/
|
||||
pj_http_headers headers;
|
||||
|
||||
/**
|
||||
* This structure describes the http request body. If application
|
||||
* specifies the data to send, the data must remain valid until
|
||||
* the HTTP request is sent. Alternatively, application can choose
|
||||
* to specify total_size as the total data size to send instead
|
||||
* while leaving the data NULL (and its size 0). In this case,
|
||||
* HTTP request will then call on_send_data() callback once it is
|
||||
* ready to send the request body. This will be useful if
|
||||
* application does not wish to load the data into the buffer at
|
||||
* once.
|
||||
*
|
||||
* Default is empty.
|
||||
*/
|
||||
struct pj_http_reqdata
|
||||
{
|
||||
void *data; /**< Request body data */
|
||||
pj_size_t size; /**< Request body size */
|
||||
pj_size_t total_size; /**< If total_size > 0, data */
|
||||
/**< will be provided later */
|
||||
} reqdata;
|
||||
|
||||
/**
|
||||
* Authentication credential needed to respond to 401/407 response.
|
||||
*/
|
||||
pj_http_auth_cred auth_cred;
|
||||
|
||||
/**
|
||||
* Optional source port range to use when binding the socket.
|
||||
* This can be used if the source port needs to be within a certain range
|
||||
* for instance due to strict firewall settings. The port used will be
|
||||
* randomized within the range.
|
||||
*
|
||||
* Note that if authentication is configured, the authentication response
|
||||
* will be a new transaction
|
||||
*
|
||||
* Default is 0 (The OS will select the source port automatically)
|
||||
*/
|
||||
pj_uint16_t source_port_range_start;
|
||||
|
||||
/**
|
||||
* Optional source port range to use when binding.
|
||||
* The size of the port restriction range
|
||||
*
|
||||
* Default is 0 (The OS will select the source port automatically))
|
||||
*/
|
||||
pj_uint16_t source_port_range_size;
|
||||
|
||||
/**
|
||||
* Max number of retries if binding to a port fails.
|
||||
* Note that this does not adress the scenario where a request times out
|
||||
* or errors. This needs to be taken care of by the on_complete callback.
|
||||
*
|
||||
* Default is 3
|
||||
*/
|
||||
pj_uint16_t max_retries;
|
||||
|
||||
} pj_http_req_param;
|
||||
|
||||
/**
|
||||
* HTTP authentication challenge, parsed from WWW-Authenticate header.
|
||||
*/
|
||||
typedef struct pj_http_auth_chal
|
||||
{
|
||||
pj_str_t scheme; /**< Auth scheme. */
|
||||
pj_str_t realm; /**< Realm for the challenge. */
|
||||
pj_str_t domain; /**< Domain. */
|
||||
pj_str_t nonce; /**< Nonce challenge. */
|
||||
pj_str_t opaque; /**< Opaque value. */
|
||||
int stale; /**< Stale parameter. */
|
||||
pj_str_t algorithm; /**< Algorithm parameter. */
|
||||
pj_str_t qop; /**< Quality of protection. */
|
||||
} pj_http_auth_chal;
|
||||
|
||||
/**
|
||||
* This structure describes HTTP response.
|
||||
*/
|
||||
typedef struct pj_http_resp
|
||||
{
|
||||
pj_str_t version; /**< HTTP version of the server */
|
||||
pj_uint16_t status_code; /**< Status code of the request */
|
||||
pj_str_t reason; /**< Reason phrase */
|
||||
pj_http_headers headers; /**< Response headers */
|
||||
pj_http_auth_chal auth_chal; /**< Parsed WWW-Authenticate header, if
|
||||
any. */
|
||||
pj_int32_t content_length; /**< The value of content-length header
|
||||
field. -1 if not specified. */
|
||||
void *data; /**< Data received */
|
||||
pj_size_t size; /**< Data size */
|
||||
} pj_http_resp;
|
||||
|
||||
/**
|
||||
* This structure describes HTTP URL.
|
||||
*/
|
||||
typedef struct pj_http_url
|
||||
{
|
||||
pj_str_t username; /**< Username part */
|
||||
pj_str_t passwd; /**< Password part */
|
||||
pj_str_t protocol; /**< Protocol used */
|
||||
pj_str_t host; /**< Host name */
|
||||
pj_uint16_t port; /**< Port number */
|
||||
pj_str_t path; /**< Path */
|
||||
} pj_http_url;
|
||||
|
||||
/**
|
||||
* This structure describes the callbacks to be called by the HTTP request.
|
||||
*/
|
||||
typedef struct pj_http_req_callback
|
||||
{
|
||||
/**
|
||||
* This callback is called when a complete HTTP response header
|
||||
* is received.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
* @param resp The response of the request.
|
||||
*/
|
||||
void (*on_response)(pj_http_req *http_req, const pj_http_resp *resp);
|
||||
|
||||
/**
|
||||
* This callback is called when the HTTP request is ready to send
|
||||
* its request body. Application may wish to use this callback if
|
||||
* it wishes to load the data at a later time or if it does not
|
||||
* wish to load the whole data into memory. In order for this
|
||||
* callback to be called, application MUST set http_req_param.total_size
|
||||
* to a value greater than 0.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
* @param data Pointer to the data that will be sent. Application
|
||||
* must set the pointer to the current data chunk/segment
|
||||
* to be sent. Data must remain valid until the next
|
||||
* on_send_data() callback or for the last segment,
|
||||
* until it is sent.
|
||||
* @param size Pointer to the data size that will be sent.
|
||||
*/
|
||||
void (*on_send_data)(pj_http_req *http_req,
|
||||
void **data, pj_size_t *size);
|
||||
|
||||
/**
|
||||
* This callback is called when a segment of response body data
|
||||
* arrives. If this callback is specified (i.e. not NULL), the
|
||||
* on_complete() callback will be called with zero-length data
|
||||
* (within the response parameter), hence the application must
|
||||
* store and manage its own data buffer, otherwise the
|
||||
* on_complete() callback will be called with the response
|
||||
* parameter containing the complete data.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
* @param data The buffer containing the data.
|
||||
* @param size The length of data in the buffer.
|
||||
*/
|
||||
void (*on_data_read)(pj_http_req *http_req,
|
||||
void *data, pj_size_t size);
|
||||
|
||||
/**
|
||||
* This callback is called when the HTTP request is completed.
|
||||
* If the callback on_data_read() is specified, the variable
|
||||
* response->data will be set to NULL, otherwise it will
|
||||
* contain the complete data. Response data is allocated from
|
||||
* pj_http_req's internal memory pool so the data remain valid
|
||||
* as long as pj_http_req is not destroyed and application does
|
||||
* not start a new request.
|
||||
*
|
||||
* If no longer required, application may choose to destroy
|
||||
* pj_http_req immediately by calling #pj_http_req_destroy() inside
|
||||
* the callback.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
* @param status The status of the request operation. PJ_SUCCESS
|
||||
* if the operation completed successfully
|
||||
* (connection-wise). To check the server's
|
||||
* status-code response to the HTTP request,
|
||||
* application should check resp->status_code instead.
|
||||
* @param resp The response of the corresponding request. If
|
||||
* the status argument is non-PJ_SUCCESS, this
|
||||
* argument will be set to NULL.
|
||||
*/
|
||||
void (*on_complete)(pj_http_req *http_req,
|
||||
pj_status_t status,
|
||||
const pj_http_resp *resp);
|
||||
|
||||
} pj_http_req_callback;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the http request parameters with the default values.
|
||||
*
|
||||
* @param param The parameter to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_http_req_param_default(pj_http_req_param *param);
|
||||
|
||||
/**
|
||||
* Add a header element/field. Application MUST make sure that
|
||||
* name and val pointer remains valid until the HTTP request is sent.
|
||||
*
|
||||
* @param headers The headers.
|
||||
* @param name The header field name.
|
||||
* @param value The header field value.
|
||||
*
|
||||
* @return PJ_SUCCESS if the operation has been successful,
|
||||
* or the appropriate error code on failure.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_headers_add_elmt(pj_http_headers *headers,
|
||||
pj_str_t *name,
|
||||
pj_str_t *val);
|
||||
|
||||
/**
|
||||
* The same as #pj_http_headers_add_elmt() with char * as
|
||||
* its parameters. Application MUST make sure that name and val pointer
|
||||
* remains valid until the HTTP request is sent.
|
||||
*
|
||||
* @param headers The headers.
|
||||
* @param name The header field name.
|
||||
* @param value The header field value.
|
||||
*
|
||||
* @return PJ_SUCCESS if the operation has been successful,
|
||||
* or the appropriate error code on failure.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_headers_add_elmt2(pj_http_headers *headers,
|
||||
char *name, char *val);
|
||||
|
||||
/**
|
||||
* Parse a http URL into its components.
|
||||
*
|
||||
* @param url The URL to be parsed.
|
||||
* @param hurl Pointer to receive the parsed result.
|
||||
*
|
||||
* @return PJ_SUCCESS if the operation has been successful,
|
||||
* or the appropriate error code on failure.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_req_parse_url(const pj_str_t *url,
|
||||
pj_http_url *hurl);
|
||||
|
||||
/**
|
||||
* Create the HTTP request.
|
||||
*
|
||||
* @param pool Pool to use. HTTP request will use the pool's factory
|
||||
* to allocate its own memory pool.
|
||||
* @param url HTTP URL request.
|
||||
* @param timer The timer to use.
|
||||
* @param ioqueue The ioqueue to use.
|
||||
* @param param Optional parameters. When this parameter is not
|
||||
* specifed (NULL), the default values will be used.
|
||||
* @param hcb Pointer to structure containing application
|
||||
* callbacks.
|
||||
* @param http_req Pointer to receive the http request instance.
|
||||
*
|
||||
* @return PJ_SUCCESS if the operation has been successful,
|
||||
* or the appropriate error code on failure.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_req_create(pj_pool_t *pool,
|
||||
const pj_str_t *url,
|
||||
pj_timer_heap_t *timer,
|
||||
pj_ioqueue_t *ioqueue,
|
||||
const pj_http_req_param *param,
|
||||
const pj_http_req_callback *hcb,
|
||||
pj_http_req **http_req);
|
||||
|
||||
/**
|
||||
* Set the timeout of the HTTP request operation. Note that if the
|
||||
* HTTP request is currently running, the timeout will only affect
|
||||
* subsequent request operations.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
* @param timeout Timeout value for HTTP request operation.
|
||||
*/
|
||||
PJ_DECL(void) pj_http_req_set_timeout(pj_http_req *http_req,
|
||||
const pj_time_val* timeout);
|
||||
|
||||
/**
|
||||
* Starts an asynchronous HTTP request to the URL specified.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
*
|
||||
* @return
|
||||
* - PJ_SUCCESS if success
|
||||
* - non-zero which indicates the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_req_start(pj_http_req *http_req);
|
||||
|
||||
/**
|
||||
* Cancel the asynchronous HTTP request.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
* @param notify If non-zero, the on_complete() callback will be
|
||||
* called with status PJ_ECANCELLED to notify that
|
||||
* the query has been cancelled.
|
||||
*
|
||||
* @return
|
||||
* - PJ_SUCCESS if success
|
||||
* - non-zero which indicates the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_req_cancel(pj_http_req *http_req,
|
||||
pj_bool_t notify);
|
||||
|
||||
/**
|
||||
* Destroy the http request.
|
||||
*
|
||||
* @param http_req The http request to be destroyed.
|
||||
*
|
||||
* @return PJ_SUCCESS if success.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_http_req_destroy(pj_http_req *http_req);
|
||||
|
||||
/**
|
||||
* Find out whether the http request is running.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
*
|
||||
* @return PJ_TRUE if a request is pending, or
|
||||
* PJ_FALSE if idle
|
||||
*/
|
||||
PJ_DECL(pj_bool_t) pj_http_req_is_running(const pj_http_req *http_req);
|
||||
|
||||
/**
|
||||
* Retrieve the user data previously associated with this http
|
||||
* request.
|
||||
*
|
||||
* @param http_req The http request.
|
||||
*
|
||||
* @return The user data.
|
||||
*/
|
||||
PJ_DECL(void *) pj_http_req_get_user_data(pj_http_req *http_req);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_HTTP_CLIENT_H__ */
|
||||
@@ -0,0 +1,228 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_JSON_H__
|
||||
#define __PJLIB_UTIL_JSON_H__
|
||||
|
||||
|
||||
/**
|
||||
* @file json.h
|
||||
* @brief PJLIB JSON Implementation
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
#include <pj/list.h>
|
||||
#include <pj/pool.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_JSON JSON Writer and Loader
|
||||
* @ingroup PJ_FILE_FMT
|
||||
* @{
|
||||
* This API implements JSON file format according to RFC 4627. It can be used
|
||||
* to parse, write, and manipulate JSON documents.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type of JSON value.
|
||||
*/
|
||||
typedef enum pj_json_val_type
|
||||
{
|
||||
PJ_JSON_VAL_NULL, /**< Null value (null) */
|
||||
PJ_JSON_VAL_BOOL, /**< Boolean value (true, false) */
|
||||
PJ_JSON_VAL_NUMBER, /**< Numeric (float or fixed point) */
|
||||
PJ_JSON_VAL_STRING, /**< Literal string value. */
|
||||
PJ_JSON_VAL_ARRAY, /**< Array */
|
||||
PJ_JSON_VAL_OBJ /**< Object. */
|
||||
} pj_json_val_type;
|
||||
|
||||
/* Forward declaration for JSON element */
|
||||
typedef struct pj_json_elem pj_json_elem;
|
||||
|
||||
/**
|
||||
* JSON list to store child elements.
|
||||
*/
|
||||
typedef struct pj_json_list
|
||||
{
|
||||
PJ_DECL_LIST_MEMBER(pj_json_elem);
|
||||
} pj_json_list;
|
||||
|
||||
/**
|
||||
* This represents JSON element. A JSON element is basically a name/value
|
||||
* pair, where the name is a string and the value can be one of null, boolean
|
||||
* (true and false constants), number, string, array (containing zero or more
|
||||
* elements), or object. An object can be viewed as C struct, that is a
|
||||
* compound element containing other elements, each having name/value pair.
|
||||
*/
|
||||
struct pj_json_elem
|
||||
{
|
||||
PJ_DECL_LIST_MEMBER(pj_json_elem);
|
||||
pj_str_t name; /**< ELement name. */
|
||||
pj_json_val_type type; /**< Element type. */
|
||||
union
|
||||
{
|
||||
pj_bool_t is_true; /**< Boolean value. */
|
||||
float num; /**< Number value. */
|
||||
pj_str_t str; /**< String value. */
|
||||
pj_json_list children; /**< Object and array children */
|
||||
} value; /**< Element value. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure to be specified to pj_json_parse() to be filled with additional
|
||||
* info when parsing failed.
|
||||
*/
|
||||
typedef struct pj_json_err_info
|
||||
{
|
||||
unsigned line; /**< Line location of the error */
|
||||
unsigned col; /**< Column location of the error */
|
||||
int err_char; /**< The offending character. */
|
||||
} pj_json_err_info;
|
||||
|
||||
/**
|
||||
* Type of function callback to write JSON document in pj_json_writef().
|
||||
*
|
||||
* @param s The string to be written to the document.
|
||||
* @param size The length of the string
|
||||
* @param user_data User data that was specified to pj_json_writef()
|
||||
*
|
||||
* @return If the callback returns non-PJ_SUCCESS, it will
|
||||
* stop the pj_json_writef() function and this error
|
||||
* will be returned to caller.
|
||||
*/
|
||||
typedef pj_status_t (*pj_json_writer)(const char *s,
|
||||
unsigned size,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* Initialize null element.
|
||||
*
|
||||
* @param el The element.
|
||||
* @param name Name to be given to the element, or NULL.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_null(pj_json_elem *el, pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Initialize boolean element with the specified value.
|
||||
*
|
||||
* @param el The element.
|
||||
* @param name Name to be given to the element, or NULL.
|
||||
* @param val The value.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_bool(pj_json_elem *el, pj_str_t *name,
|
||||
pj_bool_t val);
|
||||
|
||||
/**
|
||||
* Initialize number element with the specified value.
|
||||
*
|
||||
* @param el The element.
|
||||
* @param name Name to be given to the element, or NULL.
|
||||
* @param val The value.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_number(pj_json_elem *el, pj_str_t *name,
|
||||
float val);
|
||||
|
||||
/**
|
||||
* Initialize string element with the specified value.
|
||||
*
|
||||
* @param el The element.
|
||||
* @param name Name to be given to the element, or NULL.
|
||||
* @param val The value.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_string(pj_json_elem *el, pj_str_t *name,
|
||||
pj_str_t *val);
|
||||
|
||||
/**
|
||||
* Initialize element as an empty array
|
||||
*
|
||||
* @param el The element.
|
||||
* @param name Name to be given to the element, or NULL.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_array(pj_json_elem *el, pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Initialize element as an empty object
|
||||
*
|
||||
* @param el The element.
|
||||
* @param name Name to be given to the element, or NULL.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_obj(pj_json_elem *el, pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Add an element to an object or array.
|
||||
*
|
||||
* @param el The object or array element.
|
||||
* @param child Element to be added to the object or array.
|
||||
*/
|
||||
PJ_DECL(void) pj_json_elem_add(pj_json_elem *el, pj_json_elem *child);
|
||||
|
||||
/**
|
||||
* Parse a JSON document in the buffer. The buffer MUST be NULL terminated,
|
||||
* or if not then it must have enough size to put the NULL character.
|
||||
*
|
||||
* @param pool The pool to allocate memory for creating elements.
|
||||
* @param buffer String buffer containing JSON document.
|
||||
* @param size Size of the document.
|
||||
* @param err_info Optional structure to be filled with info when
|
||||
* parsing failed.
|
||||
*
|
||||
* @return The root element from the document.
|
||||
*/
|
||||
PJ_DECL(pj_json_elem*) pj_json_parse(pj_pool_t *pool,
|
||||
char *buffer,
|
||||
unsigned *size,
|
||||
pj_json_err_info *err_info);
|
||||
|
||||
/**
|
||||
* Write the specified element to the string buffer.
|
||||
*
|
||||
* @param elem The element to be written.
|
||||
* @param buffer Output buffer.
|
||||
* @param size On input, it must be set to the size of the buffer.
|
||||
* Upon successful return, this will be set to
|
||||
* the length of the written string.
|
||||
*
|
||||
* @return PJ_SUCCESS on success or the appropriate error.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_json_write(const pj_json_elem *elem,
|
||||
char *buffer, unsigned *size);
|
||||
|
||||
/**
|
||||
* Incrementally write the element to arbitrary medium using the specified
|
||||
* callback to write the document chunks.
|
||||
*
|
||||
* @param elem The element to be written.
|
||||
* @param writer Callback function which will be called to write
|
||||
* text chunks.
|
||||
* @param user_data Arbitrary user data which will be given back when
|
||||
* calling the callback.
|
||||
*
|
||||
* @return PJ_SUCCESS on success or the appropriate error.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_json_writef(const pj_json_elem *elem,
|
||||
pj_json_writer writer,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_JSON_H__ */
|
||||
@@ -0,0 +1,74 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_MD5_H__
|
||||
#define __PJLIB_UTIL_MD5_H__
|
||||
|
||||
/**
|
||||
* @file md5.h
|
||||
* @brief MD5 Functions
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_MD5 MD5
|
||||
* @ingroup PJLIB_UTIL_ENCRYPTION
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** MD5 context. */
|
||||
typedef struct pj_md5_context
|
||||
{
|
||||
pj_uint32_t buf[4]; /**< buf */
|
||||
pj_uint32_t bits[2]; /**< bits */
|
||||
pj_uint8_t in[64]; /**< in */
|
||||
} pj_md5_context;
|
||||
|
||||
/** Initialize the algorithm.
|
||||
* @param pms MD5 context.
|
||||
*/
|
||||
PJ_DECL(void) pj_md5_init(pj_md5_context *pms);
|
||||
|
||||
/** Append a string to the message.
|
||||
* @param pms MD5 context.
|
||||
* @param data Data.
|
||||
* @param nbytes Length of data.
|
||||
*/
|
||||
PJ_DECL(void) pj_md5_update( pj_md5_context *pms,
|
||||
const pj_uint8_t *data, unsigned nbytes);
|
||||
|
||||
/** Finish the message and return the digest.
|
||||
* @param pms MD5 context.
|
||||
* @param digest 16 byte digest.
|
||||
*/
|
||||
PJ_DECL(void) pj_md5_final(pj_md5_context *pms, pj_uint8_t digest[16]);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_MD5_H__ */
|
||||
@@ -0,0 +1,196 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_PCAP_H__
|
||||
#define __PJLIB_UTIL_PCAP_H__
|
||||
|
||||
/**
|
||||
* @file pcap.h
|
||||
* @brief Simple PCAP file reader
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_PCAP Simple PCAP file reader
|
||||
* @ingroup PJ_FILE_FMT
|
||||
* @{
|
||||
* This module describes simple utility to read PCAP file. It is not intended
|
||||
* to support all PCAP features (that's what libpcap is for!), but it can
|
||||
* be useful for example to playback or stream PCAP contents.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enumeration to describe supported data link types.
|
||||
*/
|
||||
typedef enum pj_pcap_link_type
|
||||
{
|
||||
/** Ethernet data link */
|
||||
PJ_PCAP_LINK_TYPE_ETH = 1
|
||||
|
||||
} pj_pcap_link_type;
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration to describe supported protocol types.
|
||||
*/
|
||||
typedef enum pj_pcap_proto_type
|
||||
{
|
||||
/** UDP protocol */
|
||||
PJ_PCAP_PROTO_TYPE_UDP = 17
|
||||
|
||||
} pj_pcap_proto_type;
|
||||
|
||||
|
||||
/**
|
||||
* This describes UDP header, which may optionally be returned in
|
||||
* #pj_pcap_read_udp() function. All fields are in network byte order.
|
||||
*/
|
||||
typedef struct pj_pcap_udp_hdr
|
||||
{
|
||||
pj_uint16_t src_port; /**< Source port. */
|
||||
pj_uint16_t dst_port; /**< Destination port */
|
||||
pj_uint16_t len; /**< Length. */
|
||||
pj_uint16_t csum; /**< Checksum. */
|
||||
} pj_pcap_udp_hdr;
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes the filter to be used when reading packets from
|
||||
* a PCAP file. When a filter is configured, only packets matching all the
|
||||
* filter specifications will be read from PCAP file.
|
||||
*/
|
||||
typedef struct pj_pcap_filter
|
||||
{
|
||||
/**
|
||||
* Select data link type, or zero to include any supported data links.
|
||||
*/
|
||||
pj_pcap_link_type link;
|
||||
|
||||
/**
|
||||
* Select protocol, or zero to include all supported protocols.
|
||||
*/
|
||||
pj_pcap_proto_type proto;
|
||||
|
||||
/**
|
||||
* Specify source IP address of the packets, or zero to include packets
|
||||
* from any IP addresses. Note that IP address here must be in
|
||||
* network byte order.
|
||||
*/
|
||||
pj_uint32_t ip_src;
|
||||
|
||||
/**
|
||||
* Specify destination IP address of the packets, or zero to include packets
|
||||
* destined to any IP addresses. Note that IP address here must be in
|
||||
* network byte order.
|
||||
*/
|
||||
pj_uint32_t ip_dst;
|
||||
|
||||
/**
|
||||
* Specify source port of the packets, or zero to include packets with
|
||||
* any source port number. Note that the port number must be in network
|
||||
* byte order.
|
||||
*/
|
||||
pj_uint16_t src_port;
|
||||
|
||||
/**
|
||||
* Specify destination port of the packets, or zero to include packets with
|
||||
* any destination port number. Note that the port number must be in network
|
||||
* byte order.
|
||||
*/
|
||||
pj_uint16_t dst_port;
|
||||
|
||||
} pj_pcap_filter;
|
||||
|
||||
|
||||
/** Opaque declaration for PCAP file */
|
||||
typedef struct pj_pcap_file pj_pcap_file;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize filter with default values. The default value is to allow
|
||||
* any packets.
|
||||
*
|
||||
* @param filter Filter to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_pcap_filter_default(pj_pcap_filter *filter);
|
||||
|
||||
/**
|
||||
* Open PCAP file.
|
||||
*
|
||||
* @param pool Pool to allocate memory.
|
||||
* @param path File/path name.
|
||||
* @param p_file Pointer to receive PCAP file handle.
|
||||
*
|
||||
* @return PJ_SUCCESS if file can be opened successfully.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_pcap_open(pj_pool_t *pool,
|
||||
const char *path,
|
||||
pj_pcap_file **p_file);
|
||||
|
||||
/**
|
||||
* Close PCAP file.
|
||||
*
|
||||
* @param file PCAP file handle.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_pcap_close(pj_pcap_file *file);
|
||||
|
||||
/**
|
||||
* Configure filter for reading the file. When filter is configured,
|
||||
* only packets matching all the filter settings will be returned.
|
||||
*
|
||||
* @param file PCAP file handle.
|
||||
* @param filter The filter.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_pcap_set_filter(pj_pcap_file *file,
|
||||
const pj_pcap_filter *filter);
|
||||
|
||||
/**
|
||||
* Read UDP payload from the next packet in the PCAP file. Optionally it
|
||||
* can return the UDP header, if caller supplies it.
|
||||
*
|
||||
* @param file PCAP file handle.
|
||||
* @param udp_hdr Optional buffer to receive UDP header.
|
||||
* @param udp_payload Buffer to receive the UDP payload.
|
||||
* @param udp_payload_size On input, specify the size of the buffer.
|
||||
* On output, it will be filled with the actual size
|
||||
* of the payload as read from the packet.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_pcap_read_udp(pj_pcap_file *file,
|
||||
pj_pcap_udp_hdr *udp_hdr,
|
||||
pj_uint8_t *udp_payload,
|
||||
pj_size_t *udp_payload_size);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_PCAP_H__ */
|
||||
|
||||
@@ -0,0 +1,516 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_RESOLVER_H__
|
||||
#define __PJLIB_UTIL_RESOLVER_H__
|
||||
|
||||
/**
|
||||
* @file resolver.h
|
||||
* @brief Asynchronous DNS resolver
|
||||
*/
|
||||
#include <pjlib-util/dns.h>
|
||||
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup PJ_DNS_RESOLVER DNS Asynchronous/Caching Resolution Engine
|
||||
* @ingroup PJ_DNS
|
||||
* @{
|
||||
*
|
||||
* This module manages the host/server resolution by performing asynchronous
|
||||
* DNS queries and caching the results in the cache. It uses PJLIB-UTIL
|
||||
* low-level DNS parsing functions (see @ref PJ_DNS) and currently supports
|
||||
* several types of DNS resource records such as A record (typical query with
|
||||
* gethostbyname()) and SRV record.
|
||||
*
|
||||
* \section PJ_DNS_RESOLVER_FEATURES Features
|
||||
*
|
||||
* \subsection PJ_DNS_RESOLVER_FEATURES_ASYNC Asynchronous Query and Query Aggregation
|
||||
*
|
||||
* The DNS queries are performed asychronously, with timeout setting
|
||||
* configured on per resolver instance basis. Application can issue multiple
|
||||
* asynchronous queries simultaneously. Subsequent queries to the same resource
|
||||
* (name and DNS resource type) while existing query is still pending will be
|
||||
* merged into one query, so that only one DNS request packet is issued.
|
||||
*
|
||||
* \subsection PJ_DNS_RESOLVER_FEATURES_RETRANSMISSION Query Retransmission
|
||||
*
|
||||
* Asynchronous query will be retransmitted if no response is received
|
||||
* within the preconfigured time. Once maximum retransmission count is
|
||||
* exceeded and no response is received, the query will time out and the
|
||||
* callback will be called when error status.
|
||||
*
|
||||
* \subsection PJ_DNS_RESOLVER_FEATURES_CACHING Response Caching with TTL
|
||||
*
|
||||
* The resolver instance caches the results returned by nameservers, to
|
||||
* enhance the performance by minimizing the message round-trip to the server.
|
||||
* The TTL of the cached resposne is calculated from minimum TTL value found
|
||||
* across all resource record (RR) TTL in the response and further more it can
|
||||
* be limited to some preconfigured maximum TTL in the resolver.
|
||||
*
|
||||
* Response caching can be disabled by setting the maximum TTL value of the
|
||||
* resolver to zero.
|
||||
*
|
||||
* \subsection PJ_DNS_RESOLVER_FEATURES_PARALLEL Parallel and Backup Name Servers
|
||||
*
|
||||
* When the resolver is configured with multiple nameservers, initially the
|
||||
* queries will be issued to multiple name servers simultaneously to probe
|
||||
* which servers are not active. Once the probing stage is done, subsequent
|
||||
* queries will be directed to only one ACTIVE server which provides the best
|
||||
* response time.
|
||||
*
|
||||
* Name servers are probed periodically to see which nameservers are active
|
||||
* and which are down. This probing is done when a query is sent, thus no
|
||||
* timer is needed to maintain this. Also probing will be done in parallel
|
||||
* so that there would be no additional delay for the query.
|
||||
*
|
||||
*
|
||||
* \subsection PJ_DNS_RESOLVER_FEATURES_REC Supported Resource Records
|
||||
*
|
||||
* The low-level DNS parsing utility (see @ref PJ_DNS) supports parsing of
|
||||
* the following DNS resource records (RR):
|
||||
* - DNS A record
|
||||
* - DNS SRV record
|
||||
* - DNS PTR record
|
||||
* - DNS NS record
|
||||
* - DNS CNAME record
|
||||
*
|
||||
* For other types of record, application can parse the raw resource
|
||||
* record data (rdata) from the parsed DNS packet (#pj_dns_parsed_packet).
|
||||
*
|
||||
*
|
||||
* \section PJ_DNS_RESOLVER_USING Using the Resolver
|
||||
*
|
||||
* To use the resolver, application first creates the resolver instance by
|
||||
* calling #pj_dns_resolver_create(). If application already has its own
|
||||
* timer and ioqueue instances, it can instruct the resolver to use these
|
||||
* instances so that application does not need to poll the resolver
|
||||
* periodically to process events. If application does not specify the
|
||||
* timer and ioqueue instance for the resolver, an internal timer and
|
||||
* ioqueue will be created by the resolver. And since the resolver does not
|
||||
* create it's own thread, application MUST poll the resolver periodically
|
||||
* by calling #pj_dns_resolver_handle_events() to allow events (network and
|
||||
* timer) to be processed.
|
||||
*
|
||||
* Next, application MUST configure the nameservers to be used by the
|
||||
* resolver, by calling #pj_dns_resolver_set_ns().
|
||||
*
|
||||
* Application performs asynchronous query by submitting the query with
|
||||
* #pj_dns_resolver_start_query(). Once the query completes (either
|
||||
* successfully or times out), the callback will be called.
|
||||
*
|
||||
* Application can cancel a pending query by calling #pj_dns_resolver_cancel_query().
|
||||
*
|
||||
* Resolver must be destroyed by calling #pj_dns_resolver_destroy() to
|
||||
* release all resources back to the system.
|
||||
*
|
||||
*
|
||||
* \section PJ_DNS_RESOLVER_LIMITATIONS Resolver Limitations
|
||||
*
|
||||
* Current implementation mainly suffers from a growing memory problem,
|
||||
* which mainly is caused by the response caching. Although there is only
|
||||
* one cache entry per {query, name} combination, these cache entry will
|
||||
* never get deleted since there is no timer is created to invalidate these
|
||||
* entries. So the more unique names being queried by application, there more
|
||||
* enties will be created in the response cache.
|
||||
*
|
||||
* Note that a single response entry will occupy about 600-700 bytes of
|
||||
* pool memory (the PJ_DNS_RESOLVER_RES_BUF_SIZE value plus internal
|
||||
* structure).
|
||||
*
|
||||
* Application can work around this problem by doing one of these:
|
||||
* - disable caching by setting PJ_DNS_RESOLVER_MAX_TTL and
|
||||
* PJ_DNS_RESOLVER_INVALID_TTL to zero.
|
||||
* - periodically query #pj_dns_resolver_get_cached_count() and destroy-
|
||||
* recreate the resolver to recycle the memory used by the resolver.
|
||||
*
|
||||
* Note that future improvement may solve this problem by introducing
|
||||
* expiration timer to the cached entries.
|
||||
*
|
||||
*
|
||||
* \section PJ_DNS_RESOLVER_REFERENCE Reference
|
||||
*
|
||||
* The PJLIB-UTIL resolver was built from the information in the following
|
||||
* standards:
|
||||
* - <A HREF="http://www.faqs.org/rfcs/rfc1035.html">
|
||||
* RFC 1035: "Domain names - implementation and specification"</A>
|
||||
* - <A HREF="http://www.faqs.org/rfcs/rfc2782.html">
|
||||
* RFC 2782: "A DNS RR for specifying the location of services (DNS SRV)"
|
||||
* </A>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Opaque data type for DNS resolver object.
|
||||
*/
|
||||
typedef struct pj_dns_resolver pj_dns_resolver;
|
||||
|
||||
/**
|
||||
* Opaque data type for asynchronous DNS query object.
|
||||
*/
|
||||
typedef struct pj_dns_async_query pj_dns_async_query;
|
||||
|
||||
/**
|
||||
* Type of asynchronous callback which will be called when the asynchronous
|
||||
* query completes.
|
||||
*
|
||||
* @param user_data The user data set by application when creating the
|
||||
* asynchronous query.
|
||||
* @param status Status of the DNS resolution.
|
||||
* @param response The response packet received from the server. This
|
||||
* argument may be NULL when status is not PJ_SUCCESS.
|
||||
*/
|
||||
typedef void pj_dns_callback(void *user_data,
|
||||
pj_status_t status,
|
||||
pj_dns_parsed_packet *response);
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes resolver settings.
|
||||
*/
|
||||
typedef struct pj_dns_settings
|
||||
{
|
||||
unsigned options; /**< Options flags. */
|
||||
unsigned qretr_delay; /**< Query retransmit delay in msec. */
|
||||
unsigned qretr_count; /**< Query maximum retransmission count. */
|
||||
unsigned cache_max_ttl; /**< Maximum TTL for cached responses. If the
|
||||
value is zero, caching is disabled. */
|
||||
unsigned good_ns_ttl; /**< See #PJ_DNS_RESOLVER_GOOD_NS_TTL */
|
||||
unsigned bad_ns_ttl; /**< See #PJ_DNS_RESOLVER_BAD_NS_TTL */
|
||||
} pj_dns_settings;
|
||||
|
||||
|
||||
/**
|
||||
* This structure represents DNS A record, as the result of parsing
|
||||
* DNS response packet using #pj_dns_parse_a_response().
|
||||
*/
|
||||
typedef struct pj_dns_a_record
|
||||
{
|
||||
/** The target name being queried. */
|
||||
pj_str_t name;
|
||||
|
||||
/** If target name corresponds to a CNAME entry, the alias contains
|
||||
* the value of the CNAME entry, otherwise it will be empty.
|
||||
*/
|
||||
pj_str_t alias;
|
||||
|
||||
/** Number of IP addresses. */
|
||||
unsigned addr_count;
|
||||
|
||||
/** IP addresses of the host found in the response */
|
||||
pj_in_addr addr[PJ_DNS_MAX_IP_IN_A_REC];
|
||||
|
||||
/** Internal buffer for hostname and alias. */
|
||||
char buf_[128];
|
||||
|
||||
} pj_dns_a_record;
|
||||
|
||||
|
||||
/**
|
||||
* This structure represents DNS address record, i.e: DNS A and DNS AAAA
|
||||
* records, as the result of parsing DNS response packet using
|
||||
* #pj_dns_parse_addr_response().
|
||||
*/
|
||||
typedef struct pj_dns_addr_record
|
||||
{
|
||||
/** The target name being queried. */
|
||||
pj_str_t name;
|
||||
|
||||
/** If target name corresponds to a CNAME entry, the alias contains
|
||||
* the value of the CNAME entry, otherwise it will be empty.
|
||||
*/
|
||||
pj_str_t alias;
|
||||
|
||||
/** Number of IP addresses. */
|
||||
unsigned addr_count;
|
||||
|
||||
/** IP addresses of the host found in the response */
|
||||
struct {
|
||||
|
||||
/** IP address family */
|
||||
int af;
|
||||
|
||||
/** IP address */
|
||||
union {
|
||||
/** IPv4 address */
|
||||
pj_in_addr v4;
|
||||
|
||||
/** IPv6 address */
|
||||
pj_in6_addr v6;
|
||||
} ip;
|
||||
|
||||
} addr[PJ_DNS_MAX_IP_IN_A_REC];
|
||||
|
||||
/** Internal buffer for hostname and alias. */
|
||||
char buf_[128];
|
||||
|
||||
} pj_dns_addr_record;
|
||||
|
||||
|
||||
/**
|
||||
* Set default values to the DNS settings.
|
||||
*
|
||||
* @param s The DNS settings to be initialized.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_settings_default(pj_dns_settings *s);
|
||||
|
||||
|
||||
/**
|
||||
* Create DNS resolver instance. After the resolver is created, application
|
||||
* MUST configure the nameservers with #pj_dns_resolver_set_ns().
|
||||
*
|
||||
* When creating the resolver, application may specify both timer heap
|
||||
* and ioqueue instance, so that it doesn't need to poll the resolver
|
||||
* periodically.
|
||||
*
|
||||
* @param pf Pool factory where the memory pool will be created from.
|
||||
* @param name Optional resolver name to identify the instance in
|
||||
* the log.
|
||||
* @param options Optional options, must be zero for now.
|
||||
* @param timer Optional timer heap instance to be used by the resolver.
|
||||
* If timer heap is not specified, an internal timer will be
|
||||
* created, and application would need to poll the resolver
|
||||
* periodically.
|
||||
* @param ioqueue Optional I/O Queue instance to be used by the resolver.
|
||||
* If ioqueue is not specified, an internal one will be
|
||||
* created, and application would need to poll the resolver
|
||||
* periodically.
|
||||
* @param p_resolver Pointer to receive the resolver instance.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code,
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_create(pj_pool_factory *pf,
|
||||
const char *name,
|
||||
unsigned options,
|
||||
pj_timer_heap_t *timer,
|
||||
pj_ioqueue_t *ioqueue,
|
||||
pj_dns_resolver **p_resolver);
|
||||
|
||||
|
||||
/**
|
||||
* Update the name servers for the DNS resolver. The name servers MUST be
|
||||
* configured before any resolution can be done. The order of nameservers
|
||||
* specifies their priority; the first name server will be tried first
|
||||
* before the next in the list.
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
* @param count Number of name servers in the array.
|
||||
* @param servers Array of name server IP addresses or hostnames. If
|
||||
* hostname is specified, the hostname must be resolvable
|
||||
* with pj_gethostbyname().
|
||||
* @param ports Optional array of ports. If this argument is NULL,
|
||||
* the nameserver will use default port.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code,
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_set_ns(pj_dns_resolver *resolver,
|
||||
unsigned count,
|
||||
const pj_str_t servers[],
|
||||
const pj_uint16_t ports[]);
|
||||
|
||||
|
||||
/**
|
||||
* Get the resolver current settings.
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
* @param st Buffer to be filled up with resolver settings.
|
||||
*
|
||||
* @return The query timeout setting, in seconds.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_get_settings(pj_dns_resolver *resolver,
|
||||
pj_dns_settings *st);
|
||||
|
||||
|
||||
/**
|
||||
* Modify the resolver settings. Application should initialize the settings
|
||||
* by retrieving current settings first before applying new settings, to
|
||||
* ensure that all fields are initialized properly.
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
* @param st The resolver settings.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code,
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,
|
||||
const pj_dns_settings *st);
|
||||
|
||||
|
||||
/**
|
||||
* Poll for events from the resolver. This function MUST be called
|
||||
* periodically when the resolver is using it's own timer or ioqueue
|
||||
* (in other words, when NULL is specified as either \a timer or
|
||||
* \a ioqueue argument in #pj_dns_resolver_create()).
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
* @param timeout Maximum time to wait for event occurence. If this
|
||||
* argument is NULL, this function will wait forever
|
||||
* until events occur.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,
|
||||
const pj_time_val *timeout);
|
||||
|
||||
|
||||
/**
|
||||
* Destroy DNS resolver instance.
|
||||
*
|
||||
* @param resolver The resolver object to be destryed
|
||||
* @param notify If non-zero, all pending asynchronous queries will be
|
||||
* cancelled and its callback will be called. If FALSE,
|
||||
* then no callback will be called.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code,
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_destroy(pj_dns_resolver *resolver,
|
||||
pj_bool_t notify);
|
||||
|
||||
|
||||
/**
|
||||
* Create and start asynchronous DNS query for a single resource. Depending
|
||||
* on whether response cache is available, this function will either start
|
||||
* an asynchronous DNS query or call the callback immediately.
|
||||
*
|
||||
* If response is not available in the cache, an asynchronous query will be
|
||||
* started, and callback will be called at some time later when the query
|
||||
* completes. If \a p_query argument is not NULL, it will be filled with
|
||||
* the asynchronous query object.
|
||||
*
|
||||
* If response is available in the cache, the callback will be called
|
||||
* immediately before this function returns. In this case, if \a p_query
|
||||
* argument is not NULL, the value will be set to NULL since no new query
|
||||
* is started.
|
||||
*
|
||||
* @param resolver The resolver object.
|
||||
* @param name The name to be resolved.
|
||||
* @param type The type of resource (see #pj_dns_type constants).
|
||||
* @param options Optional options, must be zero for now.
|
||||
* @param cb Callback to be called when the query completes,
|
||||
* either successfully or with failure.
|
||||
* @param user_data Arbitrary user data to be associated with the query,
|
||||
* and which will be given back in the callback.
|
||||
* @param p_query Optional pointer to receive the query object, if one
|
||||
* was started. If this pointer is specified, a NULL may
|
||||
* be returned if response cache is available immediately.
|
||||
*
|
||||
* @return PJ_SUCCESS if either an asynchronous query has been
|
||||
* started successfully or response cache is available and
|
||||
* the user callback has been called.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_start_query(pj_dns_resolver *resolver,
|
||||
const pj_str_t *name,
|
||||
int type,
|
||||
unsigned options,
|
||||
pj_dns_callback *cb,
|
||||
void *user_data,
|
||||
pj_dns_async_query **p_query);
|
||||
|
||||
/**
|
||||
* Cancel a pending query.
|
||||
*
|
||||
* @param query The pending asynchronous query to be cancelled.
|
||||
* @param notify If non-zero, the callback will be called with failure
|
||||
* status to notify that the query has been cancelled.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code,
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,
|
||||
pj_bool_t notify);
|
||||
|
||||
/**
|
||||
* A utility function to parse a DNS response containing A records into
|
||||
* DNS A record.
|
||||
*
|
||||
* @param pkt The DNS response packet.
|
||||
* @param rec The structure to be initialized with the parsed
|
||||
* DNS A record from the packet.
|
||||
*
|
||||
* @return PJ_SUCCESS if response can be parsed successfully.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,
|
||||
pj_dns_a_record *rec);
|
||||
|
||||
|
||||
/**
|
||||
* A utility function to parse a DNS response containing AAAA records into
|
||||
* DNS AAAA record.
|
||||
*
|
||||
* @param pkt The DNS response packet.
|
||||
* @param rec The structure to be initialized with the parsed
|
||||
* DNS AAAA record from the packet.
|
||||
*
|
||||
* @return PJ_SUCCESS if response can be parsed successfully.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_parse_addr_response(
|
||||
const pj_dns_parsed_packet *pkt,
|
||||
pj_dns_addr_record *rec);
|
||||
|
||||
|
||||
/**
|
||||
* Put the specified DNS packet into DNS cache. This function is mainly used
|
||||
* for testing the resolver, however it can also be used to inject entries
|
||||
* into the resolver.
|
||||
*
|
||||
* The packet MUST contain either answer section or query section so that
|
||||
* it can be indexed.
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
* @param pkt DNS packet to be added to the DNS cache. If the packet
|
||||
* matches existing entry, it will update the entry.
|
||||
* @param set_ttl If the value is PJ_FALSE, the entry will not expire
|
||||
* (so use with care). Otherwise cache expiration will be
|
||||
* calculated based on the TTL of the answeres.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_resolver_add_entry(pj_dns_resolver *resolver,
|
||||
const pj_dns_parsed_packet *pkt,
|
||||
pj_bool_t set_ttl);
|
||||
|
||||
/**
|
||||
* Get the total number of response in the response cache.
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
*
|
||||
* @return Current number of entries being stored in the response
|
||||
* cache.
|
||||
*/
|
||||
PJ_DECL(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver);
|
||||
|
||||
|
||||
/**
|
||||
* Dump resolver state to the log.
|
||||
*
|
||||
* @param resolver The resolver instance.
|
||||
* @param detail Will print detailed entries.
|
||||
*/
|
||||
PJ_DECL(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
|
||||
pj_bool_t detail);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_RESOLVER_H__ */
|
||||
|
||||
@@ -0,0 +1,554 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJ_SCANNER_H__
|
||||
#define __PJ_SCANNER_H__
|
||||
|
||||
/**
|
||||
* @file scanner.h
|
||||
* @brief Text Scanning.
|
||||
*/
|
||||
|
||||
#include <pjlib-util/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_SCAN Fast Text Scanning
|
||||
* @ingroup PJLIB_TEXT
|
||||
* @brief Text scanning utility.
|
||||
*
|
||||
* This module describes a fast text scanning functions.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0
|
||||
# include <pjlib-util/scanner_cis_bitwise.h>
|
||||
#else
|
||||
# include <pjlib-util/scanner_cis_uint.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize scanner input specification buffer.
|
||||
*
|
||||
* @param cs_buf The scanner character specification.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_buf_init(pj_cis_buf_t *cs_buf);
|
||||
|
||||
/**
|
||||
* Create a new input specification.
|
||||
*
|
||||
* @param cs_buf Specification buffer.
|
||||
* @param cis Character input specification to be initialized.
|
||||
*
|
||||
* @return PJ_SUCCESS if new specification has been successfully
|
||||
* created, or PJ_ETOOMANY if there are already too many
|
||||
* specifications in the buffer.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cis_init(pj_cis_buf_t *cs_buf, pj_cis_t *cis);
|
||||
|
||||
/**
|
||||
* Create a new input specification based on an existing specification.
|
||||
*
|
||||
* @param new_cis The new specification to be initialized.
|
||||
* @param existing The existing specification, from which the input
|
||||
* bitmask will be copied to the new specification.
|
||||
*
|
||||
* @return PJ_SUCCESS if new specification has been successfully
|
||||
* created, or PJ_ETOOMANY if there are already too many
|
||||
* specifications in the buffer.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_cis_dup(pj_cis_t *new_cis, pj_cis_t *existing);
|
||||
|
||||
/**
|
||||
* Add the characters in the specified range '[cstart, cend)' to the
|
||||
* specification (the last character itself ('cend') is not added).
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
* @param cstart The first character in the range.
|
||||
* @param cend The next character after the last character in the range.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_add_range( pj_cis_t *cis, int cstart, int cend);
|
||||
|
||||
/**
|
||||
* Add alphabetic characters to the specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_add_alpha( pj_cis_t *cis);
|
||||
|
||||
/**
|
||||
* Add numeric characters to the specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_add_num( pj_cis_t *cis);
|
||||
|
||||
/**
|
||||
* Add the characters in the string to the specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
* @param str The string.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_add_str( pj_cis_t *cis, const char *str);
|
||||
|
||||
/**
|
||||
* Add specification from another specification.
|
||||
*
|
||||
* @param cis The specification is to be set.
|
||||
* @param rhs The specification to be copied.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_add_cis( pj_cis_t *cis, const pj_cis_t *rhs);
|
||||
|
||||
/**
|
||||
* Delete characters in the specified range from the specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
* @param cstart The first character in the range.
|
||||
* @param cend The next character after the last character in the range.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend);
|
||||
|
||||
/**
|
||||
* Delete characters in the specified string from the specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
* @param str The string.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_del_str( pj_cis_t *cis, const char *str);
|
||||
|
||||
/**
|
||||
* Invert specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
*/
|
||||
PJ_DECL(void) pj_cis_invert( pj_cis_t *cis );
|
||||
|
||||
/**
|
||||
* Check whether the specified character belongs to the specification.
|
||||
*
|
||||
* @param cis The scanner character specification.
|
||||
* @param c The character to check for matching.
|
||||
*
|
||||
* @return Non-zero if match (not necessarily one).
|
||||
*/
|
||||
PJ_INLINE(int) pj_cis_match( const pj_cis_t *cis, pj_uint8_t c )
|
||||
{
|
||||
return PJ_CIS_ISSET(cis, c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flags for scanner.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/** This flags specifies that the scanner should automatically skip
|
||||
whitespaces
|
||||
*/
|
||||
PJ_SCAN_AUTOSKIP_WS = 1,
|
||||
|
||||
/** This flags specifies that the scanner should automatically skip
|
||||
SIP header continuation. This flag implies PJ_SCAN_AUTOSKIP_WS.
|
||||
*/
|
||||
PJ_SCAN_AUTOSKIP_WS_HEADER = 3,
|
||||
|
||||
/** Auto-skip new lines.
|
||||
*/
|
||||
PJ_SCAN_AUTOSKIP_NEWLINE = 4
|
||||
};
|
||||
|
||||
|
||||
/* Forward decl. */
|
||||
struct pj_scanner;
|
||||
|
||||
|
||||
/**
|
||||
* The callback function type to be called by the scanner when it encounters
|
||||
* syntax error.
|
||||
*
|
||||
* @param scanner The scanner instance that calls the callback .
|
||||
*/
|
||||
typedef void (*pj_syn_err_func_ptr)(struct pj_scanner *scanner);
|
||||
|
||||
|
||||
/**
|
||||
* The text scanner structure.
|
||||
*/
|
||||
typedef struct pj_scanner
|
||||
{
|
||||
char *begin; /**< Start of input buffer. */
|
||||
char *end; /**< End of input buffer. */
|
||||
char *curptr; /**< Current pointer. */
|
||||
int line; /**< Current line. */
|
||||
char *start_line; /**< Where current line starts. */
|
||||
int skip_ws; /**< Skip whitespace flag. */
|
||||
pj_syn_err_func_ptr callback; /**< Syntax error callback. */
|
||||
} pj_scanner;
|
||||
|
||||
|
||||
/**
|
||||
* This structure can be used by application to store the state of the parser,
|
||||
* so that the scanner state can be rollback to this state when necessary.
|
||||
*/
|
||||
typedef struct pj_scan_state
|
||||
{
|
||||
char *curptr; /**< Current scanner's pointer. */
|
||||
int line; /**< Current line. */
|
||||
char *start_line; /**< Start of current line. */
|
||||
} pj_scan_state;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the scanner.
|
||||
* Note that the input string buffer MUST be NULL terminated and have
|
||||
* length at least buflen+1 (buflen MUST NOT include the NULL terminator).
|
||||
*
|
||||
* @param scanner The scanner to be initialized.
|
||||
* @param bufstart The input buffer to scan, which must be NULL terminated.
|
||||
* @param buflen The length of the input buffer, which normally is
|
||||
* strlen(bufstart), hence not counting the NULL terminator.
|
||||
* @param options Zero, or combination of PJ_SCAN_AUTOSKIP_WS or
|
||||
* PJ_SCAN_AUTOSKIP_WS_HEADER
|
||||
* @param callback Callback to be called when the scanner encounters syntax
|
||||
* error condition.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_init( pj_scanner *scanner, char *bufstart,
|
||||
pj_size_t buflen,
|
||||
unsigned options,
|
||||
pj_syn_err_func_ptr callback );
|
||||
|
||||
|
||||
/**
|
||||
* Call this function when application has finished using the scanner.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_fini( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the EOF condition for the scanner has been met.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*
|
||||
* @return Non-zero if scanner is EOF.
|
||||
*/
|
||||
PJ_INLINE(int) pj_scan_is_eof( const pj_scanner *scanner)
|
||||
{
|
||||
return scanner->curptr >= scanner->end;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Peek strings in current position according to parameter spec, and return
|
||||
* the strings in parameter out. The current scanner position will not be
|
||||
* moved. If the scanner is already in EOF state, syntax error callback will
|
||||
* be called thrown.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param spec The spec to match input string.
|
||||
* @param out String to store the result.
|
||||
*
|
||||
* @return the character right after the peek-ed position or zero if there's
|
||||
* no more characters.
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_peek( pj_scanner *scanner,
|
||||
const pj_cis_t *spec, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Peek len characters in current position, and return them in out parameter.
|
||||
* Note that whitespaces or newlines will be returned as it is, regardless
|
||||
* of PJ_SCAN_AUTOSKIP_WS settings. If the character left is less than len,
|
||||
* syntax error callback will be called.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param len Length to peek.
|
||||
* @param out String to store the result.
|
||||
*
|
||||
* @return the character right after the peek-ed position or zero if there's
|
||||
* no more characters.
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_peek_n( pj_scanner *scanner,
|
||||
pj_size_t len, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Peek strings in current position until spec is matched, and return
|
||||
* the strings in parameter out. The current scanner position will not be
|
||||
* moved. If the scanner is already in EOF state, syntax error callback will
|
||||
* be called.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param spec The peeking will stop when the input match this spec.
|
||||
* @param out String to store the result.
|
||||
*
|
||||
* @return the character right after the peek-ed position.
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_peek_until( pj_scanner *scanner,
|
||||
const pj_cis_t *spec,
|
||||
pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Get characters from the buffer according to the spec, and return them
|
||||
* in out parameter. The scanner will attempt to get as many characters as
|
||||
* possible as long as the spec matches. If the first character doesn't
|
||||
* match the spec, or scanner is already in EOF when this function is called,
|
||||
* an exception will be thrown.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param spec The spec to match input string.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get( pj_scanner *scanner,
|
||||
const pj_cis_t *spec, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Just like #pj_scan_get(), but additionally performs unescaping when
|
||||
* escaped ('%') character is found. The input spec MUST NOT contain the
|
||||
* specification for '%' characted.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param spec The spec to match input string.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_unescape( pj_scanner *scanner,
|
||||
const pj_cis_t *spec, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Get characters between quotes. If current input doesn't match begin_quote,
|
||||
* syntax error will be thrown. Note that the resulting string will contain
|
||||
* the enclosing quote.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param begin_quote The character to begin the quote.
|
||||
* @param end_quote The character to end the quote.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_quote( pj_scanner *scanner,
|
||||
int begin_quote, int end_quote,
|
||||
pj_str_t *out);
|
||||
|
||||
/**
|
||||
* Get characters between quotes. If current input doesn't match begin_quote,
|
||||
* syntax error will be thrown. Note that the resulting string will contain
|
||||
* the enclosing quote.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param begin_quotes The character array to begin the quotes. For example,
|
||||
* the two characters " and '.
|
||||
* @param end_quotes The character array to end the quotes. The position
|
||||
* found in the begin_quotes array will be used to match
|
||||
* the end quotes. So if the begin_quotes was the array
|
||||
* of "'< the end_quotes should be "'>. If begin_array
|
||||
* matched the ' then the end_quotes will look for ' to
|
||||
* match at the end.
|
||||
* @param qsize The size of the begin_quotes and end_quotes arrays.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_quotes(pj_scanner *scanner,
|
||||
const char *begin_quotes,
|
||||
const char *end_quotes, int qsize,
|
||||
pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Get N characters from the scanner.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param N Number of characters to get.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_n( pj_scanner *scanner,
|
||||
unsigned N, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Get one character from the scanner.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*
|
||||
* @return The character.
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_get_char( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Get characters from the scanner and move the scanner position until the
|
||||
* current character matches the spec.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param spec Get until the input match this spec.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_until( pj_scanner *scanner,
|
||||
const pj_cis_t *spec, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Get characters from the scanner and move the scanner position until the
|
||||
* current character matches until_char.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param until_char Get until the input match this character.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_until_ch( pj_scanner *scanner,
|
||||
int until_char, pj_str_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* Get characters from the scanner and move the scanner position until the
|
||||
* current character matches until_char.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param until_spec Get until the input match any of these characters.
|
||||
* @param out String to store the result.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_until_chr( pj_scanner *scanner,
|
||||
const char *until_spec, pj_str_t *out);
|
||||
|
||||
/**
|
||||
* Advance the scanner N characters, and skip whitespace
|
||||
* if necessary.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param N Number of characters to skip.
|
||||
* @param skip Flag to specify whether whitespace should be skipped
|
||||
* after skipping the characters.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_advance_n( pj_scanner *scanner,
|
||||
unsigned N, pj_bool_t skip);
|
||||
|
||||
|
||||
/**
|
||||
* Compare string in current position with the specified string.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param s The string to compare with.
|
||||
* @param len Length of the string to compare.
|
||||
*
|
||||
* @return zero, <0, or >0 (just like strcmp()).
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len);
|
||||
|
||||
|
||||
/**
|
||||
* Case-less string comparison of current position with the specified
|
||||
* string.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param s The string to compare with.
|
||||
* @param len Length of the string to compare with.
|
||||
*
|
||||
* @return zero, <0, or >0 (just like strcmp()).
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);
|
||||
|
||||
/**
|
||||
* Perform case insensitive string comparison of string in current position,
|
||||
* knowing that the string to compare only consists of alphanumeric
|
||||
* characters.
|
||||
*
|
||||
* Note that unlike #pj_scan_stricmp, this function can only return zero or
|
||||
* -1.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param s The string to compare with.
|
||||
* @param len Length of the string to compare with.
|
||||
*
|
||||
* @return zero if equal or -1.
|
||||
*
|
||||
* @see strnicmp_alnum, pj_stricmp_alnum
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s,
|
||||
int len);
|
||||
|
||||
|
||||
/**
|
||||
* Get a newline from the scanner. A newline is defined as '\\n', or '\\r', or
|
||||
* "\\r\\n". If current input is not newline, syntax error will be thrown.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Manually skip whitespaces according to flag that was specified when
|
||||
* the scanner was initialized.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_skip_whitespace( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Skip current line.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_skip_line( pj_scanner *scanner );
|
||||
|
||||
/**
|
||||
* Save the full scanner state.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param state Variable to store scanner's state.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_save_state( const pj_scanner *scanner,
|
||||
pj_scan_state *state);
|
||||
|
||||
|
||||
/**
|
||||
* Restore the full scanner state.
|
||||
* Note that this would not restore the string if application has modified
|
||||
* it. This will only restore the scanner scanning position.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param state State of the scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_restore_state( pj_scanner *scanner,
|
||||
pj_scan_state *state);
|
||||
|
||||
/**
|
||||
* Get current column position.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*
|
||||
* @return The column position.
|
||||
*/
|
||||
PJ_INLINE(int) pj_scan_get_col( const pj_scanner *scanner )
|
||||
{
|
||||
return (int)(scanner->curptr - scanner->start_line);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_SCANNER_CIS_BIT_H__
|
||||
#define __PJLIB_UTIL_SCANNER_CIS_BIT_H__
|
||||
|
||||
#include <pj/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* This describes the type of individual character specification in
|
||||
* #pj_cis_buf_t. Basicly the number of bits here
|
||||
*/
|
||||
#ifndef PJ_CIS_ELEM_TYPE
|
||||
# define PJ_CIS_ELEM_TYPE pj_uint32_t
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This describes the type of individual character specification in
|
||||
* #pj_cis_buf_t.
|
||||
*/
|
||||
typedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;
|
||||
|
||||
/**
|
||||
* Maximum number of input specification in a buffer.
|
||||
* Effectively this means the number of bits in pj_cis_elem_t.
|
||||
*/
|
||||
#define PJ_CIS_MAX_INDEX (sizeof(pj_cis_elem_t) << 3)
|
||||
|
||||
/**
|
||||
* The scanner input specification buffer.
|
||||
*/
|
||||
typedef struct pj_cis_buf_t
|
||||
{
|
||||
pj_cis_elem_t cis_buf[256]; /**< Must be 256 (not 128)! */
|
||||
pj_cis_elem_t use_mask; /**< To keep used indexes. */
|
||||
} pj_cis_buf_t;
|
||||
|
||||
/**
|
||||
* Character input specification.
|
||||
*/
|
||||
typedef struct pj_cis_t
|
||||
{
|
||||
pj_cis_elem_t *cis_buf; /**< Pointer to buffer. */
|
||||
int cis_id; /**< Id. */
|
||||
} pj_cis_t;
|
||||
|
||||
|
||||
/**
|
||||
* Set the membership of the specified character.
|
||||
* Note that this is a macro, and arguments may be evaluated more than once.
|
||||
*
|
||||
* @param cis Pointer to character input specification.
|
||||
* @param c The character.
|
||||
*/
|
||||
#define PJ_CIS_SET(cis,c) ((cis)->cis_buf[(int)(c)] |= (1 << (cis)->cis_id))
|
||||
|
||||
/**
|
||||
* Remove the membership of the specified character.
|
||||
* Note that this is a macro, and arguments may be evaluated more than once.
|
||||
*
|
||||
* @param cis Pointer to character input specification.
|
||||
* @param c The character to be removed from the membership.
|
||||
*/
|
||||
#define PJ_CIS_CLR(cis,c) ((cis)->cis_buf[(int)c] &= ~(1 << (cis)->cis_id))
|
||||
|
||||
/**
|
||||
* Check the membership of the specified character.
|
||||
* Note that this is a macro, and arguments may be evaluated more than once.
|
||||
*
|
||||
* @param cis Pointer to character input specification.
|
||||
* @param c The character.
|
||||
*/
|
||||
#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[(int)c] & (1 << (cis)->cis_id))
|
||||
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_SCANNER_CIS_BIT_H__ */
|
||||
@@ -0,0 +1,84 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_SCANNER_CIS_BIT_H__
|
||||
#define __PJLIB_UTIL_SCANNER_CIS_BIT_H__
|
||||
|
||||
#include <pj/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* This describes the type of individual character specification in
|
||||
* #pj_cis_buf_t. Basicly the number of bits here
|
||||
*/
|
||||
#ifndef PJ_CIS_ELEM_TYPE
|
||||
# define PJ_CIS_ELEM_TYPE int
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This describes the type of individual character specification in
|
||||
* #pj_cis_buf_t.
|
||||
*/
|
||||
typedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;
|
||||
|
||||
/** pj_cis_buf_t is not used when uint back-end is used. */
|
||||
typedef int pj_cis_buf_t;
|
||||
|
||||
/**
|
||||
* Character input specification.
|
||||
*/
|
||||
typedef struct pj_cis_t
|
||||
{
|
||||
PJ_CIS_ELEM_TYPE cis_buf[256]; /**< Internal buffer. */
|
||||
} pj_cis_t;
|
||||
|
||||
|
||||
/**
|
||||
* Set the membership of the specified character.
|
||||
* Note that this is a macro, and arguments may be evaluated more than once.
|
||||
*
|
||||
* @param cis Pointer to character input specification.
|
||||
* @param c The character.
|
||||
*/
|
||||
#define PJ_CIS_SET(cis,c) ((cis)->cis_buf[(int)(c)] = 1)
|
||||
|
||||
/**
|
||||
* Remove the membership of the specified character.
|
||||
* Note that this is a macro, and arguments may be evaluated more than once.
|
||||
*
|
||||
* @param cis Pointer to character input specification.
|
||||
* @param c The character to be removed from the membership.
|
||||
*/
|
||||
#define PJ_CIS_CLR(cis,c) ((cis)->cis_buf[(int)c] = 0)
|
||||
|
||||
/**
|
||||
* Check the membership of the specified character.
|
||||
* Note that this is a macro, and arguments may be evaluated more than once.
|
||||
*
|
||||
* @param cis Pointer to character input specification.
|
||||
* @param c The character.
|
||||
*/
|
||||
#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[(int)c])
|
||||
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJLIB_UTIL_SCANNER_CIS_BIT_H__ */
|
||||
@@ -0,0 +1,80 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_SHA1_H__
|
||||
#define __PJLIB_UTIL_SHA1_H__
|
||||
|
||||
/**
|
||||
* @file sha1.h
|
||||
* @brief SHA1 encryption implementation
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_SHA1 SHA1
|
||||
* @ingroup PJLIB_UTIL_ENCRYPTION
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** SHA1 context */
|
||||
typedef struct pj_sha1_context
|
||||
{
|
||||
pj_uint32_t state[5]; /**< State */
|
||||
pj_uint32_t count[2]; /**< Count */
|
||||
pj_uint8_t buffer[64]; /**< Buffer */
|
||||
} pj_sha1_context;
|
||||
|
||||
/** SHA1 digest size is 20 bytes */
|
||||
#define PJ_SHA1_DIGEST_SIZE 20
|
||||
|
||||
|
||||
/** Initialize the algorithm.
|
||||
* @param ctx SHA1 context.
|
||||
*/
|
||||
PJ_DECL(void) pj_sha1_init(pj_sha1_context *ctx);
|
||||
|
||||
/** Append a stream to the message.
|
||||
* @param ctx SHA1 context.
|
||||
* @param data Data.
|
||||
* @param nbytes Length of data.
|
||||
*/
|
||||
PJ_DECL(void) pj_sha1_update(pj_sha1_context *ctx,
|
||||
const pj_uint8_t *data,
|
||||
const pj_size_t nbytes);
|
||||
|
||||
/** Finish the message and return the digest.
|
||||
* @param ctx SHA1 context.
|
||||
* @param digest 16 byte digest.
|
||||
*/
|
||||
PJ_DECL(void) pj_sha1_final(pj_sha1_context *ctx,
|
||||
pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE]);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_SHA1_H__ */
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_SRV_RESOLVER_H__
|
||||
#define __PJLIB_UTIL_SRV_RESOLVER_H__
|
||||
|
||||
/**
|
||||
* @file srv_resolver.h
|
||||
* @brief DNS SRV resolver
|
||||
*/
|
||||
#include <pjlib-util/resolver.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_DNS_SRV_RESOLVER DNS SRV Resolution Helper
|
||||
* @ingroup PJ_DNS
|
||||
* @{
|
||||
*
|
||||
* \section PJ_DNS_SRV_RESOLVER_INTRO DNS SRV Resolution Helper
|
||||
*
|
||||
* This module provides an even higher layer of abstraction for the DNS
|
||||
* resolution framework, to resolve DNS SRV names.
|
||||
*
|
||||
* The #pj_dns_srv_resolve() function will asynchronously resolve the server
|
||||
* name into IP address(es) with a single function call. If the SRV name
|
||||
* contains multiple names, then each will be resolved with individual
|
||||
* DNS A resolution to get the IP addresses. Upon successful completion,
|
||||
* application callback will be called with each IP address of the
|
||||
* target selected based on the load-balancing and fail-over criteria
|
||||
* below.
|
||||
*
|
||||
* When the resolver fails to resolve the name using DNS SRV resolution
|
||||
* (for example when the DNS SRV record is not present in the DNS server),
|
||||
* the resolver will fallback to using DNS A record resolution to resolve
|
||||
* the name.
|
||||
*
|
||||
* \subsection PJ_DNS_SRV_RESOLVER_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over
|
||||
*
|
||||
* When multiple targets are returned in the DNS SRV response, server entries
|
||||
* are selected based on the following rule (which is described in RFC 2782):
|
||||
* - targets will be sorted based on the priority first.
|
||||
* - for targets with the same priority, #pj_dns_srv_resolve() will select
|
||||
* only one target according to its weight. To select this one target,
|
||||
* the function associates running-sum for all targets, and generates
|
||||
* a random number between zero and the total running-sum (inclusive).
|
||||
* The target selected is the first target with running-sum greater than
|
||||
* or equal to this random number.
|
||||
*
|
||||
* The above procedure will select one target for each priority, allowing
|
||||
* application to fail-over to the next target when the previous target fails.
|
||||
* These targets are returned in the #pj_dns_srv_record structure
|
||||
* argument of the callback.
|
||||
*
|
||||
* \section PJ_DNS_SRV_RESOLVER_REFERENCE Reference
|
||||
*
|
||||
* Reference:
|
||||
* - <A HREF="http://www.ietf.org/rfc/rfc2782.txt">RFC 2782</A>:
|
||||
* A DNS RR for specifying the location of services (DNS SRV)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Flags to be specified when starting the DNS SRV query.
|
||||
*/
|
||||
typedef enum pj_dns_srv_option
|
||||
{
|
||||
/**
|
||||
* Specify if the resolver should fallback with DNS A
|
||||
* resolution when the SRV resolution fails. This option may
|
||||
* be specified together with PJ_DNS_SRV_FALLBACK_AAAA to
|
||||
* make the resolver fallback to both DNS A and DNS AAAA
|
||||
* resolutions if SRV resolution fails.
|
||||
*/
|
||||
PJ_DNS_SRV_FALLBACK_A = 1,
|
||||
|
||||
/**
|
||||
* Specify if the resolver should fallback with DNS AAAA
|
||||
* resolution when the SRV resolution fails. This option may
|
||||
* be specified together with PJ_DNS_SRV_FALLBACK_AAAA to
|
||||
* make the resolver fallback to both DNS A and DNS AAAA
|
||||
* resolutions if SRV resolution fails.
|
||||
*/
|
||||
PJ_DNS_SRV_FALLBACK_AAAA = 2,
|
||||
|
||||
/**
|
||||
* Specify if the resolver should try to resolve with DNS AAAA
|
||||
* resolution of each targets in the DNS SRV record. If this
|
||||
* option is not specified, the SRV resolver will query the
|
||||
* DNS A record for the target instead.
|
||||
*/
|
||||
PJ_DNS_SRV_RESOLVE_AAAA = 4,
|
||||
|
||||
/**
|
||||
* Specify if the resolver should try to resolve with DNS AAAA
|
||||
* resolution only (i.e: without DNS A resolution) for each targets
|
||||
* in the DNS SRV record.
|
||||
*/
|
||||
PJ_DNS_SRV_RESOLVE_AAAA_ONLY = 8
|
||||
|
||||
} pj_dns_srv_option;
|
||||
|
||||
|
||||
/**
|
||||
* This structure represents DNS SRV records as the result of DNS SRV
|
||||
* resolution using #pj_dns_srv_resolve().
|
||||
*/
|
||||
typedef struct pj_dns_srv_record
|
||||
{
|
||||
/** Number of address records. */
|
||||
unsigned count;
|
||||
|
||||
/** Address records. */
|
||||
struct
|
||||
{
|
||||
/** Server priority (the lower the higher the priority). */
|
||||
unsigned priority;
|
||||
|
||||
/** Server weight (the higher the more load it can handle). */
|
||||
unsigned weight;
|
||||
|
||||
/** Port number. */
|
||||
pj_uint16_t port;
|
||||
|
||||
/** The host address. */
|
||||
pj_dns_addr_record server;
|
||||
|
||||
} entry[PJ_DNS_SRV_MAX_ADDR];
|
||||
|
||||
} pj_dns_srv_record;
|
||||
|
||||
|
||||
/** Opaque declaration for DNS SRV query */
|
||||
typedef struct pj_dns_srv_async_query pj_dns_srv_async_query;
|
||||
|
||||
/**
|
||||
* Type of callback function to receive notification from the resolver
|
||||
* when the resolution process completes.
|
||||
*/
|
||||
typedef void pj_dns_srv_resolver_cb(void *user_data,
|
||||
pj_status_t status,
|
||||
const pj_dns_srv_record *rec);
|
||||
|
||||
|
||||
/**
|
||||
* Start DNS SRV resolution for the specified name. The full name of the
|
||||
* entry will be concatenated from \a res_name and \a domain_name fragments.
|
||||
*
|
||||
* @param domain_name The domain name part of the name.
|
||||
* @param res_name The full service name, including the transport name
|
||||
* and with all the leading underscore characters and
|
||||
* ending dot (e.g. "_sip._udp.", "_stun._udp.").
|
||||
* @param def_port The port number to be assigned to the resolved address
|
||||
* when the DNS SRV resolution fails and the name is
|
||||
* resolved with DNS A resolution.
|
||||
* @param pool Memory pool used to allocate memory for the query.
|
||||
* @param resolver The resolver instance.
|
||||
* @param option Option flags, which can be constructed from
|
||||
* #pj_dns_srv_option bitmask. Note that this argument
|
||||
* was called "fallback_a" in pjsip version 0.8.0 and
|
||||
* older, but the new option should be backward
|
||||
* compatible with existing applications. If application
|
||||
* specifies PJ_TRUE as "fallback_a" value, it will
|
||||
* correspond to PJ_DNS_SRV_FALLBACK_A option.
|
||||
* @param token Arbitrary data to be associated with this query when
|
||||
* the calback is called.
|
||||
* @param cb Pointer to callback function to receive the
|
||||
* notification when the resolution process completes.
|
||||
* @param p_query Optional pointer to receive the query object, if one
|
||||
* was started. If this pointer is specified, a NULL may
|
||||
* be returned if response cache is available immediately.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_srv_resolve(const pj_str_t *domain_name,
|
||||
const pj_str_t *res_name,
|
||||
unsigned def_port,
|
||||
pj_pool_t *pool,
|
||||
pj_dns_resolver *resolver,
|
||||
unsigned option,
|
||||
void *token,
|
||||
pj_dns_srv_resolver_cb *cb,
|
||||
pj_dns_srv_async_query **p_query);
|
||||
|
||||
|
||||
/**
|
||||
* Cancel an outstanding DNS SRV query.
|
||||
*
|
||||
* @param query The pending asynchronous query to be cancelled.
|
||||
* @param notify If non-zero, the callback will be called with failure
|
||||
* status to notify that the query has been cancelled.
|
||||
*
|
||||
* @return PJ_SUCCESS on success, or the appropriate error code,
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,
|
||||
pj_bool_t notify);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
#endif /* __PJLIB_UTIL_SRV_RESOLVER_H__ */
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_STRING_H__
|
||||
#define __PJLIB_UTIL_STRING_H__
|
||||
|
||||
/**
|
||||
* @file string.h
|
||||
* @brief More string functions.
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
#include <pjlib-util/scanner.h>
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_STRING String Escaping Utilities
|
||||
* @ingroup PJLIB_TEXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Unescape string. If source string does not contain any escaped
|
||||
* characters, the function would simply return the original string.
|
||||
* Otherwise a new string will be allocated.
|
||||
*
|
||||
* @param pool Pool to allocate the string.
|
||||
* @param src Source string to unescape.
|
||||
*
|
||||
* @return String with no escaped characters.
|
||||
*/
|
||||
PJ_DECL(pj_str_t) pj_str_unescape( pj_pool_t *pool, const pj_str_t *src);
|
||||
|
||||
/**
|
||||
* Unescape string to destination.
|
||||
*
|
||||
* @param dst Target string.
|
||||
* @param src Source string.
|
||||
*
|
||||
* @return Target string.
|
||||
*/
|
||||
PJ_DECL(pj_str_t*) pj_strcpy_unescape(pj_str_t *dst, const pj_str_t *src);
|
||||
|
||||
/**
|
||||
* Copy string to destination while escaping reserved characters, up to
|
||||
* the specified maximum length.
|
||||
*
|
||||
* @param dst Target string.
|
||||
* @param src Source string.
|
||||
* @param max Maximum length to copy to target string.
|
||||
* @param unres Unreserved characters, which are allowed to appear
|
||||
* unescaped.
|
||||
*
|
||||
* @return The target string if all characters have been copied
|
||||
* successfully, or NULL if there's not enough buffer to
|
||||
* escape the strings.
|
||||
*/
|
||||
PJ_DECL(pj_str_t*) pj_strncpy_escape(pj_str_t *dst, const pj_str_t *src,
|
||||
pj_ssize_t max, const pj_cis_t *unres);
|
||||
|
||||
|
||||
/**
|
||||
* Copy string to destination while escaping reserved characters, up to
|
||||
* the specified maximum length.
|
||||
*
|
||||
* @param dst Target string.
|
||||
* @param src Source string.
|
||||
* @param max Maximum length to copy to target string.
|
||||
* @param unres Unreserved characters, which are allowed to appear
|
||||
* unescaped.
|
||||
*
|
||||
* @return The length of the destination, or -1 if there's not
|
||||
* enough buffer.
|
||||
*/
|
||||
PJ_DECL(pj_ssize_t) pj_strncpy2_escape(char *dst, const pj_str_t *src,
|
||||
pj_ssize_t max, const pj_cis_t *unres);
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __PJLIB_UTIL_STRING_H__ */
|
||||
@@ -0,0 +1,289 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJSTUN_H__
|
||||
#define __PJSTUN_H__
|
||||
|
||||
/**
|
||||
* @file stun.h
|
||||
* @brief STUN client.
|
||||
*/
|
||||
|
||||
#include <pjlib-util/types.h>
|
||||
#include <pj/sock.h>
|
||||
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/*
|
||||
* This enumeration describes STUN message types.
|
||||
*/
|
||||
typedef enum pjstun_msg_type
|
||||
{
|
||||
PJSTUN_BINDING_REQUEST = 0x0001,
|
||||
PJSTUN_BINDING_RESPONSE = 0x0101,
|
||||
PJSTUN_BINDING_ERROR_RESPONSE = 0x0111,
|
||||
PJSTUN_SHARED_SECRET_REQUEST = 0x0002,
|
||||
PJSTUN_SHARED_SECRET_RESPONSE = 0x0102,
|
||||
PJSTUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112
|
||||
} pjstun_msg_type;
|
||||
|
||||
|
||||
/*
|
||||
* This enumeration describes STUN attribute types.
|
||||
*/
|
||||
typedef enum pjstun_attr_type
|
||||
{
|
||||
PJSTUN_ATTR_MAPPED_ADDR = 1,
|
||||
PJSTUN_ATTR_RESPONSE_ADDR,
|
||||
PJSTUN_ATTR_CHANGE_REQUEST,
|
||||
PJSTUN_ATTR_SOURCE_ADDR,
|
||||
PJSTUN_ATTR_CHANGED_ADDR,
|
||||
PJSTUN_ATTR_USERNAME,
|
||||
PJSTUN_ATTR_PASSWORD,
|
||||
PJSTUN_ATTR_MESSAGE_INTEGRITY,
|
||||
PJSTUN_ATTR_ERROR_CODE,
|
||||
PJSTUN_ATTR_UNKNOWN_ATTRIBUTES,
|
||||
PJSTUN_ATTR_REFLECTED_FROM,
|
||||
PJSTUN_ATTR_XOR_MAPPED_ADDR = 0x0020
|
||||
} pjstun_attr_type;
|
||||
|
||||
|
||||
/*
|
||||
* This structre describes STUN message header.
|
||||
*/
|
||||
typedef struct pjstun_msg_hdr
|
||||
{
|
||||
pj_uint16_t type;
|
||||
pj_uint16_t length;
|
||||
pj_uint32_t tsx[4];
|
||||
} pjstun_msg_hdr;
|
||||
|
||||
|
||||
/*
|
||||
* This structre describes STUN attribute header.
|
||||
*/
|
||||
typedef struct pjstun_attr_hdr
|
||||
{
|
||||
pj_uint16_t type;
|
||||
pj_uint16_t length;
|
||||
} pjstun_attr_hdr;
|
||||
|
||||
|
||||
/*
|
||||
* This structre describes STUN MAPPED-ADDR attribute.
|
||||
*/
|
||||
typedef struct pjstun_mapped_addr_attr
|
||||
{
|
||||
pjstun_attr_hdr hdr;
|
||||
pj_uint8_t ignored;
|
||||
pj_uint8_t family;
|
||||
pj_uint16_t port;
|
||||
pj_uint32_t addr;
|
||||
} pjstun_mapped_addr_attr;
|
||||
|
||||
typedef pjstun_mapped_addr_attr pjstun_response_addr_attr;
|
||||
typedef pjstun_mapped_addr_attr pjstun_changed_addr_attr;
|
||||
typedef pjstun_mapped_addr_attr pjstun_src_addr_attr;
|
||||
typedef pjstun_mapped_addr_attr pjstun_reflected_form_attr;
|
||||
|
||||
typedef struct pjstun_change_request_attr
|
||||
{
|
||||
pjstun_attr_hdr hdr;
|
||||
pj_uint32_t value;
|
||||
} pjstun_change_request_attr;
|
||||
|
||||
typedef struct pjstun_username_attr
|
||||
{
|
||||
pjstun_attr_hdr hdr;
|
||||
pj_uint32_t value[1];
|
||||
} pjstun_username_attr;
|
||||
|
||||
typedef pjstun_username_attr pjstun_password_attr;
|
||||
|
||||
typedef struct pjstun_error_code_attr
|
||||
{
|
||||
pjstun_attr_hdr hdr;
|
||||
pj_uint16_t ignored;
|
||||
pj_uint8_t err_class;
|
||||
pj_uint8_t number;
|
||||
char reason[4];
|
||||
} pjstun_error_code_attr;
|
||||
|
||||
typedef struct pjstun_msg
|
||||
{
|
||||
pjstun_msg_hdr *hdr;
|
||||
int attr_count;
|
||||
pjstun_attr_hdr *attr[PJSTUN_MAX_ATTR];
|
||||
} pjstun_msg;
|
||||
|
||||
/* STUN message API (stun.c). */
|
||||
|
||||
PJ_DECL(pj_status_t) pjstun_create_bind_req( pj_pool_t *pool,
|
||||
void **msg, pj_size_t *len,
|
||||
pj_uint32_t id_hi,
|
||||
pj_uint32_t id_lo);
|
||||
PJ_DECL(pj_status_t) pjstun_parse_msg( void *buf, pj_size_t len,
|
||||
pjstun_msg *msg);
|
||||
PJ_DECL(void*) pjstun_msg_find_attr( pjstun_msg *msg, pjstun_attr_type t);
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_STUN_CLIENT Simple STUN Helper
|
||||
* @ingroup PJ_PROTOCOLS
|
||||
* @brief A simple and small footprint STUN resolution helper
|
||||
* @{
|
||||
*
|
||||
* This is the older implementation of STUN client, with only one function
|
||||
* provided (pjstun_get_mapped_addr()) to retrieve the public IP address
|
||||
* of multiple sockets.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the main function to request the mapped address of local sockets
|
||||
* to multiple STUN servers. This function is able to find the mapped
|
||||
* addresses of multiple sockets simultaneously, and for each socket, two
|
||||
* requests will be sent to two different STUN servers to see if both servers
|
||||
* get the same public address for the same socket. (Note that application can
|
||||
* specify the same address for the two servers, but still two requests will
|
||||
* be sent for each server).
|
||||
*
|
||||
* This function will perform necessary retransmissions of the requests if
|
||||
* response is not received within a predetermined period. When all responses
|
||||
* have been received, the function will compare the mapped addresses returned
|
||||
* by the servers, and when both are equal, the address will be returned in
|
||||
* \a mapped_addr argument.
|
||||
*
|
||||
* @param pf The pool factory where memory will be allocated from.
|
||||
* @param sock_cnt Number of sockets in the socket array.
|
||||
* @param sock Array of local UDP sockets which public addresses are
|
||||
* to be queried from the STUN servers.
|
||||
* @param srv1 Host name or IP address string of the first STUN
|
||||
* server.
|
||||
* @param port1 The port number of the first STUN server.
|
||||
* @param srv2 Host name or IP address string of the second STUN
|
||||
* server.
|
||||
* @param port2 The port number of the second STUN server.
|
||||
* @param mapped_addr Array to receive the mapped public address of the local
|
||||
* UDP sockets, when the function returns PJ_SUCCESS.
|
||||
*
|
||||
* @return This functions returns PJ_SUCCESS if responses are
|
||||
* received from all servers AND all servers returned the
|
||||
* same mapped public address. Otherwise this function may
|
||||
* return one of the following error codes:
|
||||
* - PJLIB_UTIL_ESTUNNOTRESPOND: no respons from servers.
|
||||
* - PJLIB_UTIL_ESTUNSYMMETRIC: different mapped addresses
|
||||
* are returned by servers.
|
||||
* - etc.
|
||||
*
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pjstun_get_mapped_addr( pj_pool_factory *pf,
|
||||
int sock_cnt, pj_sock_t sock[],
|
||||
const pj_str_t *srv1, int port1,
|
||||
const pj_str_t *srv2, int port2,
|
||||
pj_sockaddr_in mapped_addr[]);
|
||||
|
||||
|
||||
/*
|
||||
* This structre describes configurable setting for requesting mapped address.
|
||||
*/
|
||||
typedef struct pjstun_setting
|
||||
{
|
||||
/**
|
||||
* Specifies whether STUN request generated by old STUN library should
|
||||
* insert magic cookie (specified in RFC 5389) in the transaction ID.
|
||||
*/
|
||||
pj_bool_t use_stun2;
|
||||
|
||||
/**
|
||||
* Address family of the STUN servers.
|
||||
*/
|
||||
int af;
|
||||
|
||||
/**
|
||||
* Host name or IP address string of the first STUN server.
|
||||
*/
|
||||
pj_str_t srv1;
|
||||
|
||||
/**
|
||||
* The port number of the first STUN server.
|
||||
*/
|
||||
int port1;
|
||||
|
||||
/**
|
||||
* Host name or IP address string of the second STUN server.
|
||||
*/
|
||||
pj_str_t srv2;
|
||||
|
||||
/**
|
||||
* The port number of the second STUN server.
|
||||
*/
|
||||
int port2;
|
||||
|
||||
} pjstun_setting;
|
||||
|
||||
|
||||
/**
|
||||
* Another version of mapped address resolution of local sockets to multiple
|
||||
* STUN servers configured in #pjstun_setting. This function is able to find
|
||||
* the mapped addresses of multiple sockets simultaneously, and for each
|
||||
* socket, two requests will be sent to two different STUN servers to see if
|
||||
* both servers get the same public address for the same socket. (Note that
|
||||
* application can specify the same address for the two servers, but still
|
||||
* two requests will be sent for each server).
|
||||
*
|
||||
* This function will perform necessary retransmissions of the requests if
|
||||
* response is not received within a predetermined period. When all responses
|
||||
* have been received, the function will compare the mapped addresses returned
|
||||
* by the servers, and when both are equal, the address will be returned in
|
||||
* \a mapped_addr argument.
|
||||
*
|
||||
* @param pf The pool factory where memory will be allocated from.
|
||||
* @param opt The STUN settings.
|
||||
* @param sock_cnt Number of sockets in the socket array.
|
||||
* @param sock Array of local UDP sockets which public addresses are
|
||||
* to be queried from the STUN servers.
|
||||
* @param mapped_addr Array to receive the mapped public address of the local
|
||||
* UDP sockets, when the function returns PJ_SUCCESS.
|
||||
*
|
||||
* @return This functions returns PJ_SUCCESS if responses are
|
||||
* received from all servers AND all servers returned the
|
||||
* same mapped public address. Otherwise this function may
|
||||
* return one of the following error codes:
|
||||
* - PJLIB_UTIL_ESTUNNOTRESPOND: no respons from servers.
|
||||
* - PJLIB_UTIL_ESTUNSYMMETRIC: different mapped addresses
|
||||
* are returned by servers.
|
||||
* - etc.
|
||||
*
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pjstun_get_mapped_addr2( pj_pool_factory *pf,
|
||||
const pjstun_setting *opt,
|
||||
int sock_cnt,
|
||||
pj_sock_t sock[],
|
||||
pj_sockaddr_in mapped_addr[]);
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __PJSTUN_H__ */
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJLIB_UTIL_TYPES_H__
|
||||
#define __PJLIB_UTIL_TYPES_H__
|
||||
|
||||
/**
|
||||
* @file types.h
|
||||
* @brief PJLIB-UTIL types.
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
#include <pjlib-util/config.h>
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_UTIL_BASE Base
|
||||
* @{
|
||||
*/
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Initialize PJLIB UTIL (defined in errno.c)
|
||||
*
|
||||
* @return PJ_SUCCESS on success.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pjlib_util_init(void);
|
||||
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJLIB_TEXT Text and String Manipulation
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJ_PROTOCOLS Protocols
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PJ_FILE_FMT File Formats
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage PJLIB-UTIL
|
||||
*
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* This is the documentation of PJLIB-UTIL, an auxiliary library providing
|
||||
* adjunct functions to PJLIB.
|
||||
*
|
||||
* Please go to the <A HREF="modules.htm"><B>Table of Contents</B></A> page
|
||||
* for list of modules.
|
||||
*
|
||||
*
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
* \n
|
||||
*/
|
||||
|
||||
#endif /* __PJLIB_UTIL_TYPES_H__ */
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __PJ_XML_H__
|
||||
#define __PJ_XML_H__
|
||||
|
||||
/**
|
||||
* @file xml.h
|
||||
* @brief PJLIB XML Parser/Helper.
|
||||
*/
|
||||
|
||||
#include <pj/types.h>
|
||||
#include <pj/list.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* @defgroup PJ_TINY_XML Mini/Tiny XML Parser/Helper
|
||||
* @ingroup PJ_FILE_FMT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Typedef for XML attribute. */
|
||||
typedef struct pj_xml_attr pj_xml_attr;
|
||||
|
||||
/** Typedef for XML nodes. */
|
||||
typedef struct pj_xml_node pj_xml_node;
|
||||
|
||||
/** This structure declares XML attribute. */
|
||||
struct pj_xml_attr
|
||||
{
|
||||
PJ_DECL_LIST_MEMBER(pj_xml_attr); /**< Standard list elements. */
|
||||
pj_str_t name; /**< Attribute name. */
|
||||
pj_str_t value; /**< Attribute value. */
|
||||
};
|
||||
|
||||
/** This structure describes XML node head inside XML node structure.
|
||||
*/
|
||||
typedef struct pj_xml_node_head
|
||||
{
|
||||
PJ_DECL_LIST_MEMBER(pj_xml_node); /**< Standard list elements. */
|
||||
} pj_xml_node_head;
|
||||
|
||||
/** This structure describes XML node. */
|
||||
struct pj_xml_node
|
||||
{
|
||||
PJ_DECL_LIST_MEMBER(pj_xml_node); /**< List @a prev and @a next member */
|
||||
pj_str_t name; /**< Node name. */
|
||||
pj_xml_attr attr_head; /**< Attribute list. */
|
||||
pj_xml_node_head node_head; /**< Node list. */
|
||||
pj_str_t content; /**< Node content. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse XML message into XML document with a single root node. The parser
|
||||
* is capable of parsing XML processing instruction construct ("<?") and
|
||||
* XML comments ("<!--"), however such constructs will be ignored and will not
|
||||
* be included in the resulted XML node tree.
|
||||
*
|
||||
* Note that the XML message input buffer MUST be NULL terminated and have
|
||||
* length at least len+1 (len MUST NOT include the NULL terminator).
|
||||
*
|
||||
* @param pool Pool to allocate memory from.
|
||||
* @param msg The XML message to parse, MUST be NULL terminated.
|
||||
* @param len The length of the message, not including NULL terminator.
|
||||
*
|
||||
* @return XML root node, or NULL if the XML document can not be parsed.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_parse( pj_pool_t *pool, char *msg, pj_size_t len);
|
||||
|
||||
|
||||
/**
|
||||
* Print XML into XML message. Note that the function WILL NOT NULL terminate
|
||||
* the output.
|
||||
*
|
||||
* @param node The XML node to print.
|
||||
* @param buf Buffer to hold the output message.
|
||||
* @param len The length of the buffer.
|
||||
* @param prolog If set to nonzero, will print XML prolog ("<?xml..")
|
||||
*
|
||||
* @return The size of the printed message, or -1 if there is not
|
||||
* sufficient space in the buffer to print the message.
|
||||
*/
|
||||
PJ_DECL(int) pj_xml_print( const pj_xml_node *node, char *buf, pj_size_t len,
|
||||
pj_bool_t prolog);
|
||||
|
||||
/**
|
||||
* Clone XML node and all subnodes.
|
||||
*
|
||||
* @param pool Pool to allocate memory for new nodes.
|
||||
* @param rhs The node to clone.
|
||||
*
|
||||
* @return Cloned XML node, or NULL on fail.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs);
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty node.
|
||||
*
|
||||
* @param pool Pool.
|
||||
* @param name Node name.
|
||||
*
|
||||
* @return The new node.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_node_new(pj_pool_t *pool, const pj_str_t *name);
|
||||
|
||||
|
||||
/**
|
||||
* Create new XML attribute.
|
||||
*
|
||||
* @param pool Pool.
|
||||
* @param name Attribute name.
|
||||
* @param value Attribute value.
|
||||
*
|
||||
* @return The new XML attribute.
|
||||
*/
|
||||
PJ_DECL(pj_xml_attr*) pj_xml_attr_new(pj_pool_t *pool, const pj_str_t *name,
|
||||
const pj_str_t *value);
|
||||
|
||||
/**
|
||||
* Add node to another node.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param node Node to be added to parent.
|
||||
*/
|
||||
PJ_DECL(void) pj_xml_add_node( pj_xml_node *parent, pj_xml_node *node );
|
||||
|
||||
|
||||
/**
|
||||
* Add attribute to a node.
|
||||
*
|
||||
* @param node Node.
|
||||
* @param attr Attribute to add to node.
|
||||
*/
|
||||
PJ_DECL(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr );
|
||||
|
||||
/**
|
||||
* Find first direct child node with the specified name.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Node name to find.
|
||||
*
|
||||
* @return XML node found or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent,
|
||||
const pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Find next direct child node with the specified name.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param node node->next is the starting point.
|
||||
* @param name Node name to find.
|
||||
*
|
||||
* @return XML node found or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_next_node(const pj_xml_node *parent,
|
||||
const pj_xml_node *node,
|
||||
const pj_str_t *name);
|
||||
|
||||
/**
|
||||
* Recursively find the first node with the specified name in the child nodes
|
||||
* and their children.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Node name to find.
|
||||
*
|
||||
* @return XML node found or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent,
|
||||
const pj_str_t *name);
|
||||
|
||||
|
||||
/**
|
||||
* Find first attribute within a node with the specified name and optional
|
||||
* value.
|
||||
*
|
||||
* @param node XML Node.
|
||||
* @param name Attribute name to find.
|
||||
* @param value Optional value to match.
|
||||
*
|
||||
* @return XML attribute found, or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_attr*) pj_xml_find_attr(const pj_xml_node *node,
|
||||
const pj_str_t *name,
|
||||
const pj_str_t *value);
|
||||
|
||||
|
||||
/**
|
||||
* Find a direct child node with the specified name and match the function.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Optional name. If this is NULL, the name will not be
|
||||
* matched.
|
||||
* @param data Data to be passed to matching function.
|
||||
* @param match Optional matching function.
|
||||
*
|
||||
* @return The first matched node, or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find( const pj_xml_node *parent,
|
||||
const pj_str_t *name,
|
||||
const void *data,
|
||||
pj_bool_t (*match)(const pj_xml_node *,
|
||||
const void*));
|
||||
|
||||
|
||||
/**
|
||||
* Recursively find a child node with the specified name and match the
|
||||
* function.
|
||||
*
|
||||
* @param parent Parent node.
|
||||
* @param name Optional name. If this is NULL, the name will not be
|
||||
* matched.
|
||||
* @param data Data to be passed to matching function.
|
||||
* @param match Optional matching function.
|
||||
*
|
||||
* @return The first matched node, or NULL.
|
||||
*/
|
||||
PJ_DECL(pj_xml_node*) pj_xml_find_rec(const pj_xml_node *parent,
|
||||
const pj_str_t *name,
|
||||
const void *data,
|
||||
pj_bool_t (*match)(const pj_xml_node*,
|
||||
const void*));
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJ_XML_H__ */
|
||||
Reference in new issue
Block a user