added QSE_HTTPD_SERVER_TRANSPARENT to allow optional support for TPROXY.

changed to set the target to SECURE when the intercepted connection is known to be SECURE
This commit is contained in:
hyung-hwan 2015-11-15 14:23:59 +00:00
parent c7bd05b419
commit 028646bb54
5 changed files with 98 additions and 69 deletions

View File

@ -527,10 +527,18 @@ static int get_server_root (
}
if (mth == QSE_HTTP_CONNECT)
{
root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_RAW;
else if (loccfg->proxy.pseudonym[0])
}
else
{
if (loccfg->proxy.pseudonym[0])
root->u.proxy.pseudonym = loccfg->proxy.pseudonym;
if (server->dope.flags & QSE_HTTPD_SERVER_SECURE)
root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_DST_SECURE;
}
goto proxy_ok;
}
}
@ -2047,6 +2055,7 @@ static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, int num, qse_xli_l
if (pair && pair->val->type == QSE_XLI_STR &&
qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("yes")) == 0) dope.flags |= QSE_HTTPD_SERVER_SECURE;
dope.flags |= QSE_HTTPD_SERVER_TRANSPARENT; /* need this to support TPROXY when proxy.allow_intercept is enabled */
dope.detach = free_server_config;
xserver = qse_httpd_attachserverstd (httpd, &dope, QSE_SIZEOF(server_xtn_t));
if (xserver == QSE_NULL)

View File

@ -211,6 +211,9 @@ struct qse_httpd_peer_t
/* == PRIVATE == */
/* set by httpd to the client this peer has been created for */
qse_httpd_client_t* client;
/* peer links for the proxy peer cache list in client.
* internal use only. don't mess with these */
qse_httpd_peer_t* next;
@ -751,7 +754,8 @@ enum qse_httpd_server_flag_t
{
QSE_HTTPD_SERVER_ACTIVE = (1 << 0),
QSE_HTTPD_SERVER_SECURE = (1 << 1),
QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2)
QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2),
QSE_HTTPD_SERVER_TRANSPARENT = (1 << 3)
};
typedef enum qse_httpd_server_flag_t qse_httpd_server_flag_t;

View File

@ -2270,8 +2270,7 @@ static void on_url_rewritten (qse_httpd_t* httpd, const qse_mchar_t* url, const
}
}
static int task_main_proxy (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
static int task_main_proxy (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
{
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
proxy_peer_htrd_xtn_t* xtn;
@ -2383,8 +2382,7 @@ static int task_main_proxy (
if (!(proxy->flags & PROXY_RAW))
{
/* set up a http reader to read a response from the peer */
proxy->peer_htrd = qse_htrd_open (
httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t));
proxy->peer_htrd = qse_htrd_open (httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t));
if (proxy->peer_htrd == QSE_NULL) goto oops;
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (proxy->peer_htrd);
xtn->proxy = proxy;
@ -2400,7 +2398,9 @@ static int task_main_proxy (
proxy->res_pending = 0;
/* get a cached peer connection */
peer_from_cache = qse_httpd_decacheproxypeer (httpd, client, &proxy->peer->nwad, &proxy->peer->local, (proxy->peer->flags & QSE_HTTPD_PEER_SECURE));
peer_from_cache = qse_httpd_decacheproxypeer (
httpd, client, &proxy->peer->nwad,
&proxy->peer->local, (proxy->peer->flags & QSE_HTTPD_PEER_SECURE));
if (peer_from_cache)
{
qse_mchar_t tmpch;
@ -2445,6 +2445,8 @@ static int task_main_proxy (
}
else
{
proxy->peer->client = client;
httpd->errnum = QSE_HTTPD_ENOERR;
n = httpd->opt.scb.peer.open (httpd, proxy->peer);
if (n <= -1)

View File

@ -964,12 +964,14 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
{
/* TODO: logging. warning only */
/* this is not a hard failure */
HTTPD_DBGOUT1 ("Failed to enable SO_REUSERPORT on %zd\n", (qse_size_t)fd);
HTTPD_DBGOUT1 ("Failed to set SO_REUSERPORT on %zd\n", (qse_size_t)fd);
}
#endif
/* TODO: linux. use capset() to set required capabilities just in case */
if (server->dope.flags & QSE_HTTPD_SERVER_TRANSPARENT)
{
#if defined(IP_TRANSPARENT)
/* remove the ip routing restriction that a packet can only
* be sent using a local ip address. this option is useful
@ -1019,11 +1021,16 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
- accepting TPROXYed connections
- binding to a non-local IP address (IP address the local system doesn't have)
- using a non-local IP address as a source
-
*/
flag = 1;
setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag));
if (setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag)) <= -1)
{
/* TODO: logging. warning only */
/* this is not a hard failure */
HTTPD_DBGOUT1 ("Failed to set IP_TRANSPARENT on %zd\n", (qse_size_t)fd);
}
#endif
}
if (server->dope.flags & QSE_HTTPD_SERVER_BINDTONWIF)
{
@ -1032,11 +1039,10 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
qse_size_t len;
len = qse_nwifindextombs (server->dope.nwif, tmp, QSE_COUNTOF(tmp));
if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1)
{
/* TODO: logging ... */
qse_httpd_seterrnum (httpd, ((len <= 0)? QSE_HTTPD_EINVAL: SKERR_TO_ERRNUM()));
HTTPD_DBGOUT2 ("Failed to set SO_BINDTODEVICE to %hs on %zd\n", tmp, (qse_size_t)fd);
goto oops;
}
#endif
@ -1294,7 +1300,6 @@ static int client_accepted (qse_httpd_t* httpd, qse_httpd_client_t* client)
server_xtn = (server_xtn_t*)qse_httpd_getserverxtn (httpd, client->server);
if (!server_xtn->ssl_ctx)
{
/* performed the delayed ssl initialization */
@ -1422,11 +1427,18 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
goto oops;
}
/* TODO: set transparent and bind only if the server is transparent */
if (peer->client && peer->client->server &&
(peer->client->server->dope.flags & QSE_HTTPD_SERVER_TRANSPARENT))
{
#if defined(IP_TRANSPARENT)
flag = 1;
setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag));
if (setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag)) <= -1)
{
/* this is not a hard failure */
HTTPD_DBGOUT1 ("Failed to set IP_TRANSPARENT on peer socket %zd\n", (qse_size_t)fd);
}
#endif
}
/* don't use invalid binding address */
if (bindaddrsize >= 0 &&
@ -3457,7 +3469,7 @@ static int query_server (
{
case QSE_HTTPD_SERVERSTD_SSL:
/* you must specify the certificate and the key file to be able
* to use SSL */
* to use SSL. not supported by this sample implmentation. */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOENT);
return -1;

View File

@ -822,7 +822,9 @@ static int accept_client (
/* TODO: check maximum number of client. if exceed call client.close */
if (server->dope.flags & QSE_HTTPD_SERVER_SECURE) clibuf.status |= QSE_HTTPD_CLIENT_SECURE;
if (server->dope.flags & QSE_HTTPD_SERVER_SECURE)
clibuf.status |= QSE_HTTPD_CLIENT_SECURE;
clibuf.server = server;
#if 0