[MAJOR] implemented client-side support for PF_UNIX sockets

A new file, proto_uxst.c, implements support of PF_UNIX sockets
of type SOCK_STREAM. It relies on generic stream_sock_read/write
and uses its own accept primitive which also tries to be generic.

Right now it only implements an echo service in sight of a general
support for start dumping via unix socket. The echo code is more
of a proof of concept than useful code.
This commit is contained in:
Willy Tarreau 2007-10-16 17:34:28 +02:00
parent dd81598553
commit 92fb9836ee
8 changed files with 1484 additions and 25 deletions

View File

@ -229,7 +229,7 @@ all: haproxy
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/uri_auth.o src/standard.o src/buffers.o src/log.o src/task.o \
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
src/checks.o src/queue.o src/client.o src/proxy.o \
src/checks.o src/queue.o src/client.o src/proxy.o src/proto_uxst.o \
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
src/session.o src/hdr_idx.o src/ev_select.o src/acl.o src/memory.o

View File

@ -101,7 +101,7 @@ LDFLAGS = -g
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/uri_auth.o src/standard.o src/buffers.o src/log.o src/task.o \
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
src/checks.o src/queue.o src/client.o src/proxy.o \
src/checks.o src/queue.o src/client.o src/proxy.o src/proto_uxst.o \
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
src/session.o src/hdr_idx.o src/ev_select.o src/ev_poll.o \
src/ev_kqueue.o src/acl.o src/memory.o

View File

@ -98,7 +98,7 @@ LDFLAGS = -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/uri_auth.o src/standard.o src/buffers.o src/log.o src/task.o \
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
src/checks.o src/queue.o src/client.o src/proxy.o \
src/checks.o src/queue.o src/client.o src/proxy.o src/proto_uxst.o \
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
src/session.o src/hdr_idx.o src/ev_select.o src/ev_poll.o src/acl.o \
src/memory.o

View File

@ -0,0 +1,40 @@
/*
include/proto/proto_uxst.h
This file contains UNIX-stream socket protocol definitions.
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, version 2.1
exclusively.
This 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _PROTO_PROTO_UXST_H
#define _PROTO_PROTO_UXST_H
#include <common/config.h>
#include <types/session.h>
#include <types/task.h>
int uxst_event_accept(int fd);
void uxst_add_listener(struct listener *listener);
void process_uxst_stats(struct task *t, struct timeval *next);
#endif /* _PROTO_PROTO_UXST_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -2,7 +2,7 @@
include/types/global.h
Global variables.
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -25,6 +25,7 @@
#include <netinet/in.h>
#include <common/config.h>
#include <types/protocols.h>
#include <types/task.h>
/* modes of operation (global.mode) */
@ -64,6 +65,8 @@ struct global {
struct {
int maxpollevents; /* max number of poll events at once */
} tune;
struct listener stats_sock; /* unix socket listener for statistics */
struct timeval stats_timeout;
};
extern struct global global;

View File

@ -38,9 +38,10 @@
/* listener state */
#define LI_NEW 0 /* not initialized yet */
#define LI_LISTEN 1 /* started, listening but not enabled */
#define LI_READY 2 /* started, listening and enabled */
#define LI_FULL 3 /* reached its connection limit */
#define LI_INIT 1 /* attached to the protocol, but not listening yet */
#define LI_LISTEN 2 /* started, listening but not enabled */
#define LI_READY 3 /* started, listening and enabled */
#define LI_FULL 4 /* reached its connection limit */
/* The listener will be directly referenced by the fdtab[] which holds its
* socket. The listener provides the protocol-specific accept() function to
@ -48,7 +49,7 @@
*/
struct listener {
int fd; /* the listen socket */
int state; /* state: NEW, READY, FULL */
int state; /* state: NEW, INIT, LISTEN, READY, FULL */
struct sockaddr_storage addr; /* the address we listen to */
struct protocol *proto; /* protocol this listener belongs to */
int nbconn; /* current number of connections on this listener */

1414
src/proto_uxst.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -45,26 +45,27 @@ void session_free(struct session *s)
if (s->rep)
pool_free2(pool2_buffer, s->rep);
if (txn->hdr_idx.v != NULL)
pool_free2(fe->hdr_idx_pool, txn->hdr_idx.v);
if (fe) {
if (txn->hdr_idx.v != NULL)
pool_free2(fe->hdr_idx_pool, txn->hdr_idx.v);
if (txn->rsp.cap != NULL) {
struct cap_hdr *h;
for (h = fe->rsp_cap; h; h = h->next) {
if (txn->rsp.cap[h->index] != NULL)
pool_free2(h->pool, txn->rsp.cap[h->index]);
if (txn->rsp.cap != NULL) {
struct cap_hdr *h;
for (h = fe->rsp_cap; h; h = h->next) {
if (txn->rsp.cap[h->index] != NULL)
pool_free2(h->pool, txn->rsp.cap[h->index]);
}
pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
}
pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
}
if (txn->req.cap != NULL) {
struct cap_hdr *h;
for (h = fe->req_cap; h; h = h->next) {
if (txn->req.cap[h->index] != NULL)
pool_free2(h->pool, txn->req.cap[h->index]);
if (txn->req.cap != NULL) {
struct cap_hdr *h;
for (h = fe->req_cap; h; h = h->next) {
if (txn->req.cap[h->index] != NULL)
pool_free2(h->pool, txn->req.cap[h->index]);
}
pool_free2(fe->req_cap_pool, txn->req.cap);
}
pool_free2(fe->req_cap_pool, txn->req.cap);
}
if (txn->uri)
pool_free2(pool2_requri, txn->uri);
if (txn->cli_cookie)
@ -75,7 +76,7 @@ void session_free(struct session *s)
pool_free2(pool2_session, s);
/* We may want to free the maximum amount of pools if the proxy is stopping */
if (unlikely(fe->state == PR_STSTOPPED)) {
if (fe && unlikely(fe->state == PR_STSTOPPED)) {
if (pool2_buffer)
pool_flush2(pool2_buffer);
if (fe->hdr_idx_pool)