mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Redesigned TCP accepting: one listen/accept loop, passing the connected socket.
Instead of using bind() and passing the listening socket to the children threads using uv_export/uv_import use one thread that does the accepting, and then passes the connected socket using uv_export/uv_import to a random worker. The previous solution had thundering herd problems (all workers waking up on one connection and trying to accept()), this one avoids this and is simpler. The tcp clients quota is simplified with isc_quota_attach_cb - a callback is issued when the quota is available.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netmgr.h>
|
||||
#include <isc/queue.h>
|
||||
#include <isc/quota.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/region.h>
|
||||
@@ -131,8 +132,8 @@ typedef enum isc__netievent_type {
|
||||
netievent_tcprecv,
|
||||
netievent_tcpstartread,
|
||||
netievent_tcppauseread,
|
||||
netievent_tcpchildlisten,
|
||||
netievent_tcpchildstop,
|
||||
netievent_tcpchildaccept,
|
||||
netievent_tcpaccept,
|
||||
netievent_tcpstop,
|
||||
netievent_tcpclose,
|
||||
netievent_tcpdnsclose,
|
||||
@@ -211,7 +212,6 @@ typedef struct isc__netievent__socket {
|
||||
typedef isc__netievent__socket_t isc__netievent_udplisten_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_udpstop_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpstop_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpchildstop_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpclose_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_startread_t;
|
||||
@@ -228,13 +228,15 @@ typedef isc__netievent__socket_req_t isc__netievent_tcpconnect_t;
|
||||
typedef isc__netievent__socket_req_t isc__netievent_tcplisten_t;
|
||||
typedef isc__netievent__socket_req_t isc__netievent_tcpsend_t;
|
||||
|
||||
typedef struct isc__netievent__socket_streaminfo {
|
||||
typedef struct isc__netievent__socket_streaminfo_quota {
|
||||
isc__netievent_type type;
|
||||
isc_nmsocket_t *sock;
|
||||
isc_uv_stream_info_t streaminfo;
|
||||
} isc__netievent__socket_streaminfo_t;
|
||||
isc_quota_t *quota;
|
||||
} isc__netievent__socket_streaminfo_quota_t;
|
||||
|
||||
typedef isc__netievent__socket_streaminfo_t isc__netievent_tcpchildlisten_t;
|
||||
typedef isc__netievent__socket_streaminfo_quota_t
|
||||
isc__netievent_tcpchildaccept_t;
|
||||
|
||||
typedef struct isc__netievent__socket_handle {
|
||||
isc__netievent_type type;
|
||||
@@ -242,6 +244,14 @@ typedef struct isc__netievent__socket_handle {
|
||||
isc_nmhandle_t *handle;
|
||||
} isc__netievent__socket_handle_t;
|
||||
|
||||
typedef struct isc__netievent__socket_quota {
|
||||
isc__netievent_type type;
|
||||
isc_nmsocket_t *sock;
|
||||
isc_quota_t *quota;
|
||||
} isc__netievent__socket_quota_t;
|
||||
|
||||
typedef isc__netievent__socket_quota_t isc__netievent_tcpaccept_t;
|
||||
|
||||
typedef struct isc__netievent_udpsend {
|
||||
isc__netievent_type type;
|
||||
isc_nmsocket_t *sock;
|
||||
@@ -261,7 +271,8 @@ typedef union {
|
||||
isc__netievent__socket_t nis;
|
||||
isc__netievent__socket_req_t nisr;
|
||||
isc__netievent_udpsend_t nius;
|
||||
isc__netievent__socket_streaminfo_t niss;
|
||||
isc__netievent__socket_quota_t nisq;
|
||||
isc__netievent__socket_streaminfo_quota_t nissq;
|
||||
} isc__netievent_storage_t;
|
||||
|
||||
/*
|
||||
@@ -324,7 +335,6 @@ typedef enum isc_nmsocket_type {
|
||||
isc_nm_udplistener, /* Aggregate of nm_udpsocks */
|
||||
isc_nm_tcpsocket,
|
||||
isc_nm_tcplistener,
|
||||
isc_nm_tcpchildlistener,
|
||||
isc_nm_tcpdnslistener,
|
||||
isc_nm_tcpdnssocket
|
||||
} isc_nmsocket_type;
|
||||
@@ -370,16 +380,7 @@ struct isc_nmsocket {
|
||||
*/
|
||||
isc_quota_t *quota;
|
||||
isc_quota_t *pquota;
|
||||
|
||||
/*%
|
||||
* How many connections we have not accepted due to quota?
|
||||
* When we close a connection we need to accept a new one.
|
||||
*/
|
||||
int overquota;
|
||||
/*%
|
||||
* How many active connections we have?
|
||||
*/
|
||||
int conns;
|
||||
isc_quota_cb_t quotacb;
|
||||
|
||||
/*%
|
||||
* Socket statistics
|
||||
@@ -704,12 +705,12 @@ isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_tcpchildlisten(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
isc__nm_async_tcpaccept(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_tcpstop(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_tcpchildstop(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_tcpsend(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
void
|
||||
isc__nm_async_startread(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
|
Reference in New Issue
Block a user