123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- /*
- * 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_ASYNCSOCK_H__
- #define __PJ_ASYNCSOCK_H__
- /**
- * @file activesock.h
- * @brief Active socket
- */
- #include <pj/ioqueue.h>
- #include <pj/sock.h>
- PJ_BEGIN_DECL
- /**
- * @defgroup PJ_ACTIVESOCK Active socket I/O
- * @brief Active socket performs active operations on socket.
- * @ingroup PJ_IO
- * @{
- *
- * Active socket is a higher level abstraction to the ioqueue. It provides
- * automation to socket operations which otherwise would have to be done
- * manually by the applications. For example with socket recv(), recvfrom(),
- * and accept() operations, application only needs to invoke these
- * operation once, and it will be notified whenever data or incoming TCP
- * connection (in the case of accept()) arrives.
- */
- /**
- * This opaque structure describes the active socket.
- */
- typedef struct pj_activesock_t pj_activesock_t;
- /**
- * This structure contains the callbacks to be called by the active socket.
- */
- typedef struct pj_activesock_cb
- {
- /**
- * This callback is called when a data arrives as the result of
- * pj_activesock_start_read().
- *
- * @param asock The active socket.
- * @param data The buffer containing the new data, if any. If
- * the status argument is non-PJ_SUCCESS, this
- * argument may be NULL.
- * @param size The length of data in the buffer.
- * @param status The status of the read operation. This may contain
- * non-PJ_SUCCESS for example when the TCP connection
- * has been closed. In this case, the buffer may
- * contain left over data from previous callback which
- * the application may want to process.
- * @param remainder If application wishes to leave some data in the
- * buffer (common for TCP applications), it should
- * move the remainder data to the front part of the
- * buffer and set the remainder length here. The value
- * of this parameter will be ignored for datagram
- * sockets.
- *
- * @return PJ_TRUE if further read is desired, and PJ_FALSE
- * when application no longer wants to receive data.
- * Application may destroy the active socket in the
- * callback and return PJ_FALSE here.
- */
- pj_bool_t (*on_data_read)(pj_activesock_t *asock,
- void *data,
- pj_size_t size,
- pj_status_t status,
- pj_size_t *remainder);
- /**
- * This callback is called when a packet arrives as the result of
- * pj_activesock_start_recvfrom().
- *
- * @param asock The active socket.
- * @param data The buffer containing the packet, if any. If
- * the status argument is non-PJ_SUCCESS, this
- * argument will be set to NULL.
- * @param size The length of packet in the buffer. If
- * the status argument is non-PJ_SUCCESS, this
- * argument will be set to zero.
- * @param src_addr Source address of the packet.
- * @param addr_len Length of the source address.
- * @param status This contains
- *
- * @return PJ_TRUE if further read is desired, and PJ_FALSE
- * when application no longer wants to receive data.
- * Application may destroy the active socket in the
- * callback and return PJ_FALSE here.
- */
- pj_bool_t (*on_data_recvfrom)(pj_activesock_t *asock,
- void *data,
- pj_size_t size,
- const pj_sockaddr_t *src_addr,
- int addr_len,
- pj_status_t status);
- /**
- * This callback is called when data has been sent.
- *
- * @param asock The active socket.
- * @param send_key Key associated with the send operation.
- * @param sent If value is positive non-zero it indicates the
- * number of data sent. When the value is negative,
- * it contains the error code which can be retrieved
- * by negating the value (i.e. status=-sent).
- *
- * @return Application may destroy the active socket in the
- * callback and return PJ_FALSE here.
- */
- pj_bool_t (*on_data_sent)(pj_activesock_t *asock,
- pj_ioqueue_op_key_t *send_key,
- pj_ssize_t sent);
- /**
- * This callback is called when new connection arrives as the result
- * of pj_activesock_start_accept(). If the status of accept operation is
- * needed use on_accept_complete2 instead of this callback.
- *
- * @param asock The active socket.
- * @param newsock The new incoming socket.
- * @param src_addr The source address of the connection.
- * @param addr_len Length of the source address.
- *
- * @return PJ_TRUE if further accept() is desired, and PJ_FALSE
- * when application no longer wants to accept incoming
- * connection. Application may destroy the active socket
- * in the callback and return PJ_FALSE here.
- */
- pj_bool_t (*on_accept_complete)(pj_activesock_t *asock,
- pj_sock_t newsock,
- const pj_sockaddr_t *src_addr,
- int src_addr_len);
- /**
- * This callback is called when new connection arrives as the result
- * of pj_activesock_start_accept().
- *
- * @param asock The active socket.
- * @param newsock The new incoming socket.
- * @param src_addr The source address of the connection.
- * @param addr_len Length of the source address.
- * @param status The status of the accept operation. This may contain
- * non-PJ_SUCCESS for example when the TCP listener is in
- * bad state for example on iOS platform after the
- * application waking up from background.
- *
- * @return PJ_TRUE if further accept() is desired, and PJ_FALSE
- * when application no longer wants to accept incoming
- * connection. Application may destroy the active socket
- * in the callback and return PJ_FALSE here.
- */
- pj_bool_t (*on_accept_complete2)(pj_activesock_t *asock,
- pj_sock_t newsock,
- const pj_sockaddr_t *src_addr,
- int src_addr_len,
- pj_status_t status);
- /**
- * This callback is called when pending connect operation has been
- * completed.
- *
- * @param asock The active socket.
- * @param status The connection result. If connection has been
- * successfully established, the status will contain
- * PJ_SUCCESS.
- *
- * @return Application may destroy the active socket in the
- * callback and return PJ_FALSE here.
- */
- pj_bool_t (*on_connect_complete)(pj_activesock_t *asock,
- pj_status_t status);
- } pj_activesock_cb;
- /**
- * Settings that can be given during active socket creation. Application
- * must initialize this structure with #pj_activesock_cfg_default().
- */
- typedef struct pj_activesock_cfg
- {
- /**
- * Optional group lock to be assigned to the ioqueue key.
- */
- pj_grp_lock_t *grp_lock;
- /**
- * Number of concurrent asynchronous operations that is to be supported
- * by the active socket. This value only affects socket receive and
- * accept operations -- the active socket will issue one or more
- * asynchronous read and accept operations based on the value of this
- * field. Setting this field to more than one will allow more than one
- * incoming data or incoming connections to be processed simultaneously
- * on multiprocessor systems, when the ioqueue is polled by more than
- * one threads.
- *
- * The default value is 1.
- */
- unsigned async_cnt;
- /**
- * The ioqueue concurrency to be forced on the socket when it is
- * registered to the ioqueue. See #pj_ioqueue_set_concurrency() for more
- * info about ioqueue concurrency.
- *
- * When this value is -1, the concurrency setting will not be forced for
- * this socket, and the socket will inherit the concurrency setting of
- * the ioqueue. When this value is zero, the active socket will disable
- * concurrency for the socket. When this value is +1, the active socket
- * will enable concurrency for the socket.
- *
- * The default value is -1.
- */
- int concurrency;
- /**
- * If this option is specified, the active socket will make sure that
- * asynchronous send operation with stream oriented socket will only
- * call the callback after all data has been sent. This means that the
- * active socket will automatically resend the remaining data until
- * all data has been sent.
- *
- * Please note that when this option is specified, it is possible that
- * error is reported after partial data has been sent. Also setting
- * this will disable the ioqueue concurrency for the socket.
- *
- * Default value is PJ_TRUE.
- */
- pj_bool_t whole_data;
- /**
- * If this option is specified, set close-on-exec flag for socket.
- * This option is only used by #pj_activesock_create_udp()
- *
- * Default value is PJ_TRUE.
- */
- pj_bool_t sock_cloexec;
- } pj_activesock_cfg;
- /**
- * Initialize the active socket configuration with the default values.
- *
- * @param cfg The configuration to be initialized.
- */
- PJ_DECL(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg);
- /**
- * Create the active socket for the specified socket. This will register
- * the socket to the specified ioqueue.
- *
- * @param pool Pool to allocate memory from.
- * @param sock The socket handle.
- * @param sock_type Specify socket type, either pj_SOCK_DGRAM() or
- * pj_SOCK_STREAM(). The active socket needs this
- * information to handle connection closure for
- * connection oriented sockets.
- * @param ioqueue The ioqueue to use.
- * @param opt Optional settings. When this setting is not specifed,
- * the default values will be used.
- * @param cb Pointer to structure containing application
- * callbacks.
- * @param user_data Arbitrary user data to be associated with this
- * active socket.
- * @param p_asock Pointer to receive the active socket instance.
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_create(pj_pool_t *pool,
- pj_sock_t sock,
- int sock_type,
- const pj_activesock_cfg *opt,
- pj_ioqueue_t *ioqueue,
- const pj_activesock_cb *cb,
- void *user_data,
- pj_activesock_t **p_asock);
- /**
- * Create UDP socket descriptor, bind it to the specified address, and
- * create the active socket for the socket descriptor.
- *
- * @param pool Pool to allocate memory from.
- * @param addr Specifies the address family of the socket and the
- * address where the socket should be bound to. If
- * this argument is NULL, then AF_INET is assumed and
- * the socket will be bound to any addresses and port.
- * @param ioqueue The ioqueue.
- * @param opt Optional settings. When this setting is not specifed,
- * the default values will be used.
- * @param cb Pointer to structure containing application
- * callbacks.
- * @param user_data Arbitrary user data to be associated with this
- * active socket.
- * @param p_asock Pointer to receive the active socket instance.
- * @param bound_addr If this argument is specified, it will be filled with
- * the bound address on return.
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_create_udp(pj_pool_t *pool,
- const pj_sockaddr *addr,
- const pj_activesock_cfg *opt,
- pj_ioqueue_t *ioqueue,
- const pj_activesock_cb *cb,
- void *user_data,
- pj_activesock_t **p_asock,
- pj_sockaddr *bound_addr);
- /**
- * Close the active socket. This will unregister the socket from the
- * ioqueue and ultimately close the socket.
- *
- * @param asock The active socket.
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_close(pj_activesock_t *asock);
- #if (defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
- PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0) || \
- defined(DOXYGEN)
- /**
- * Set iPhone OS background mode setting. Setting to 1 will enable TCP
- * active socket to receive incoming data when application is in the
- * background. Setting to 0 will disable it. Default value of this
- * setting is PJ_ACTIVESOCK_TCP_IPHONE_OS_BG.
- *
- * This API is only available if PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT
- * is set to non-zero.
- *
- * @param asock The active socket.
- * @param val The value of background mode setting.
- *
- */
- PJ_DECL(void) pj_activesock_set_iphone_os_bg(pj_activesock_t *asock,
- int val);
- /**
- * Enable/disable support for iPhone OS background mode. This setting
- * will apply globally and will affect any active sockets created
- * afterwards, if you want to change the setting for a particular
- * active socket, use #pj_activesock_set_iphone_os_bg() instead.
- * By default, this setting is enabled.
- *
- * This API is only available if PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT
- * is set to non-zero.
- *
- * @param val The value of global background mode setting.
- *
- */
- PJ_DECL(void) pj_activesock_enable_iphone_os_bg(pj_bool_t val);
- #endif
- /**
- * Associate arbitrary data with the active socket. Application may
- * inspect this data in the callbacks and associate it with higher
- * level processing.
- *
- * @param asock The active socket.
- * @param user_data The user data to be associated with the active
- * socket.
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_set_user_data(pj_activesock_t *asock,
- void *user_data);
- /**
- * Retrieve the user data previously associated with this active
- * socket.
- *
- * @param asock The active socket.
- *
- * @return The user data.
- */
- PJ_DECL(void*) pj_activesock_get_user_data(pj_activesock_t *asock);
- /**
- * Starts read operation on this active socket. This function will create
- * \a async_cnt number of buffers (the \a async_cnt parameter was given
- * in \a pj_activesock_create() function) where each buffer is \a buff_size
- * long. The buffers are allocated from the specified \a pool. Once the
- * buffers are created, it then issues \a async_cnt number of asynchronous
- * \a recv() operations to the socket and returns back to caller. Incoming
- * data on the socket will be reported back to application via the
- * \a on_data_read() callback.
- *
- * Application only needs to call this function once to initiate read
- * operations. Further read operations will be done automatically by the
- * active socket when \a on_data_read() callback returns non-zero.
- *
- * @param asock The active socket.
- * @param pool Pool used to allocate buffers for incoming data.
- * @param buff_size The size of each buffer, in bytes.
- * @param flags Flags to be given to pj_ioqueue_recv().
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock,
- pj_pool_t *pool,
- unsigned buff_size,
- pj_uint32_t flags);
- /**
- * Same as #pj_activesock_start_read(), except that the application
- * supplies the buffers for the read operation so that the acive socket
- * does not have to allocate the buffers.
- *
- * @param asock The active socket.
- * @param pool Pool used to allocate buffers for incoming data.
- * @param buff_size The size of each buffer, in bytes.
- * @param readbuf Array of packet buffers, each has buff_size size.
- * @param flags Flags to be given to pj_ioqueue_recv().
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_start_read2(pj_activesock_t *asock,
- pj_pool_t *pool,
- unsigned buff_size,
- void *readbuf[],
- pj_uint32_t flags);
- /**
- * Same as pj_activesock_start_read(), except that this function is used
- * only for datagram sockets, and it will trigger \a on_data_recvfrom()
- * callback instead.
- *
- * @param asock The active socket.
- * @param pool Pool used to allocate buffers for incoming data.
- * @param buff_size The size of each buffer, in bytes.
- * @param flags Flags to be given to pj_ioqueue_recvfrom().
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock,
- pj_pool_t *pool,
- unsigned buff_size,
- pj_uint32_t flags);
- /**
- * Same as #pj_activesock_start_recvfrom() except that the recvfrom()
- * operation takes the buffer from the argument rather than creating
- * new ones.
- *
- * @param asock The active socket.
- * @param pool Pool used to allocate buffers for incoming data.
- * @param buff_size The size of each buffer, in bytes.
- * @param readbuf Array of packet buffers, each has buff_size size.
- * @param flags Flags to be given to pj_ioqueue_recvfrom().
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_start_recvfrom2(pj_activesock_t *asock,
- pj_pool_t *pool,
- unsigned buff_size,
- void *readbuf[],
- pj_uint32_t flags);
- /**
- * Send data using the socket.
- *
- * @param asock The active socket.
- * @param send_key The operation key to send the data, which is useful
- * if application wants to submit multiple pending
- * send operations and want to track which exact data
- * has been sent in the \a on_data_sent() callback.
- * @param data The data to be sent. This data must remain valid
- * until the data has been sent.
- * @param size The size of the data.
- * @param flags Flags to be given to pj_ioqueue_send().
- *
- *
- * @return PJ_SUCCESS if data has been sent immediately, or
- * PJ_EPENDING if data cannot be sent immediately. In
- * this case the \a on_data_sent() callback will be
- * called when data is actually sent. Any other return
- * value indicates error condition.
- */
- PJ_DECL(pj_status_t) pj_activesock_send(pj_activesock_t *asock,
- pj_ioqueue_op_key_t *send_key,
- const void *data,
- pj_ssize_t *size,
- unsigned flags);
- /**
- * Send datagram using the socket.
- *
- * @param asock The active socket.
- * @param send_key The operation key to send the data, which is useful
- * if application wants to submit multiple pending
- * send operations and want to track which exact data
- * has been sent in the \a on_data_sent() callback.
- * @param data The data to be sent. This data must remain valid
- * until the data has been sent.
- * @param size The size of the data.
- * @param flags Flags to be given to pj_ioqueue_send().
- * @param addr The destination address.
- * @param addr_len The length of the address.
- *
- * @return PJ_SUCCESS if data has been sent immediately, or
- * PJ_EPENDING if data cannot be sent immediately. In
- * this case the \a on_data_sent() callback will be
- * called when data is actually sent. Any other return
- * value indicates error condition.
- */
- PJ_DECL(pj_status_t) pj_activesock_sendto(pj_activesock_t *asock,
- pj_ioqueue_op_key_t *send_key,
- const void *data,
- pj_ssize_t *size,
- unsigned flags,
- const pj_sockaddr_t *addr,
- int addr_len);
- #if PJ_HAS_TCP
- /**
- * Starts asynchronous socket accept() operations on this active socket.
- * Application must bind the socket before calling this function. This
- * function will issue \a async_cnt number of asynchronous \a accept()
- * operations to the socket and returns back to caller. Incoming
- * connection on the socket will be reported back to application via the
- * \a on_accept_complete() callback.
- *
- * Application only needs to call this function once to initiate accept()
- * operations. Further accept() operations will be done automatically by
- * the active socket when \a on_accept_complete() callback returns non-zero.
- *
- * @param asock The active socket.
- * @param pool Pool used to allocate some internal data for the
- * operation.
- *
- * @return PJ_SUCCESS if the operation has been successful,
- * or the appropriate error code on failure.
- */
- PJ_DECL(pj_status_t) pj_activesock_start_accept(pj_activesock_t *asock,
- pj_pool_t *pool);
- /**
- * Starts asynchronous socket connect() operation for this socket. Once
- * the connection is done (either successfully or not), the
- * \a on_connect_complete() callback will be called.
- *
- * @param asock The active socket.
- * @param pool The pool to allocate some internal data for the
- * operation.
- * @param remaddr Remote address.
- * @param addr_len Length of the remote address.
- *
- * @return PJ_SUCCESS if connection can be established immediately,
- * or PJ_EPENDING if connection cannot be established
- * immediately. In this case the \a on_connect_complete()
- * callback will be called when connection is complete.
- * Any other return value indicates error condition.
- */
- PJ_DECL(pj_status_t) pj_activesock_start_connect(pj_activesock_t *asock,
- pj_pool_t *pool,
- const pj_sockaddr_t *remaddr,
- int addr_len);
- #endif /* PJ_HAS_TCP */
- /**
- * @}
- */
- PJ_END_DECL
- #endif /* __PJ_ASYNCSOCK_H__ */
|