1251877Speter/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
2251877Speter *
3251877Speter * Licensed under the Apache License, Version 2.0 (the "License");
4251877Speter * you may not use this file except in compliance with the License.
5251877Speter * You may obtain a copy of the License at
6251877Speter *
7251877Speter *     http://www.apache.org/licenses/LICENSE-2.0
8251877Speter *
9251877Speter * Unless required by applicable law or agreed to in writing, software
10251877Speter * distributed under the License is distributed on an "AS IS" BASIS,
11251877Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12251877Speter * See the License for the specific language governing permissions and
13251877Speter * limitations under the License.
14251877Speter */
15251877Speter
16251877Speter#include <apr_pools.h>
17251877Speter#include <apr_poll.h>
18251877Speter#include <apr_version.h>
19251877Speter
20251877Speter#include "serf.h"
21251877Speter#include "serf_bucket_util.h"
22251877Speter
23251877Speter#include "serf_private.h"
24251877Speter
25251877Speterstatic apr_status_t read_from_client(serf_incoming_t *client)
26251877Speter{
27251877Speter    return APR_ENOTIMPL;
28251877Speter}
29251877Speter
30251877Speterstatic apr_status_t write_to_client(serf_incoming_t *client)
31251877Speter{
32251877Speter    return APR_ENOTIMPL;
33251877Speter}
34251877Speter
35251877Speterapr_status_t serf__process_client(serf_incoming_t *client, apr_int16_t events)
36251877Speter{
37251877Speter    apr_status_t rv;
38251877Speter    if ((events & APR_POLLIN) != 0) {
39251877Speter        rv = read_from_client(client);
40251877Speter        if (rv) {
41251877Speter            return rv;
42251877Speter        }
43251877Speter    }
44251877Speter
45251877Speter    if ((events & APR_POLLHUP) != 0) {
46251877Speter        return APR_ECONNRESET;
47251877Speter    }
48251877Speter
49251877Speter    if ((events & APR_POLLERR) != 0) {
50251877Speter        return APR_EGENERAL;
51251877Speter    }
52251877Speter
53251877Speter    if ((events & APR_POLLOUT) != 0) {
54251877Speter        rv = write_to_client(client);
55251877Speter        if (rv) {
56251877Speter            return rv;
57251877Speter        }
58251877Speter    }
59251877Speter
60251877Speter    return APR_SUCCESS;
61251877Speter}
62251877Speter
63251877Speterapr_status_t serf__process_listener(serf_listener_t *l)
64251877Speter{
65251877Speter    apr_status_t rv;
66251877Speter    apr_socket_t *in;
67251877Speter    apr_pool_t *p;
68251877Speter    /* THIS IS NOT OPTIMAL */
69251877Speter    apr_pool_create(&p, l->pool);
70251877Speter
71251877Speter    rv = apr_socket_accept(&in, l->skt, p);
72251877Speter
73251877Speter    if (rv) {
74251877Speter        apr_pool_destroy(p);
75251877Speter        return rv;
76251877Speter    }
77251877Speter
78251877Speter    rv = l->accept_func(l->ctx, l, l->accept_baton, in, p);
79251877Speter
80251877Speter    if (rv) {
81251877Speter        apr_pool_destroy(p);
82251877Speter        return rv;
83251877Speter    }
84251877Speter
85251877Speter    return rv;
86251877Speter}
87251877Speter
88251877Speter
89251877Speterapr_status_t serf_incoming_create(
90251877Speter    serf_incoming_t **client,
91251877Speter    serf_context_t *ctx,
92251877Speter    apr_socket_t *insock,
93251877Speter    void *request_baton,
94251877Speter    serf_incoming_request_cb_t request,
95251877Speter    apr_pool_t *pool)
96251877Speter{
97251877Speter    apr_status_t rv;
98251877Speter    serf_incoming_t *ic = apr_palloc(pool, sizeof(*ic));
99251877Speter
100251877Speter    ic->ctx = ctx;
101251877Speter    ic->baton.type = SERF_IO_CLIENT;
102251877Speter    ic->baton.u.client = ic;
103251877Speter    ic->request_baton =  request_baton;
104251877Speter    ic->request = request;
105251877Speter    ic->skt = insock;
106251877Speter    ic->desc.desc_type = APR_POLL_SOCKET;
107251877Speter    ic->desc.desc.s = ic->skt;
108251877Speter    ic->desc.reqevents = APR_POLLIN;
109251877Speter
110251877Speter    rv = ctx->pollset_add(ctx->pollset_baton,
111251877Speter                         &ic->desc, &ic->baton);
112251877Speter    *client = ic;
113251877Speter
114251877Speter    return rv;
115251877Speter}
116251877Speter
117251877Speter
118251877Speterapr_status_t serf_listener_create(
119251877Speter    serf_listener_t **listener,
120251877Speter    serf_context_t *ctx,
121251877Speter    const char *host,
122251877Speter    apr_uint16_t port,
123251877Speter    void *accept_baton,
124251877Speter    serf_accept_client_t accept,
125251877Speter    apr_pool_t *pool)
126251877Speter{
127251877Speter    apr_sockaddr_t *sa;
128251877Speter    apr_status_t rv;
129251877Speter    serf_listener_t *l = apr_palloc(pool, sizeof(*l));
130251877Speter
131251877Speter    l->ctx = ctx;
132251877Speter    l->baton.type = SERF_IO_LISTENER;
133251877Speter    l->baton.u.listener = l;
134251877Speter    l->accept_func = accept;
135251877Speter    l->accept_baton = accept_baton;
136251877Speter
137251877Speter    apr_pool_create(&l->pool, pool);
138251877Speter
139251877Speter    rv = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, l->pool);
140251877Speter    if (rv)
141251877Speter        return rv;
142251877Speter
143251877Speter    rv = apr_socket_create(&l->skt, sa->family,
144251877Speter                           SOCK_STREAM,
145251877Speter#if APR_MAJOR_VERSION > 0
146251877Speter                           APR_PROTO_TCP,
147251877Speter#endif
148251877Speter                           l->pool);
149251877Speter    if (rv)
150251877Speter        return rv;
151251877Speter
152251877Speter    rv = apr_socket_opt_set(l->skt, APR_SO_REUSEADDR, 1);
153251877Speter    if (rv)
154251877Speter        return rv;
155253895Speter
156251877Speter    rv = apr_socket_bind(l->skt, sa);
157251877Speter    if (rv)
158251877Speter        return rv;
159251877Speter
160251877Speter    rv = apr_socket_listen(l->skt, 5);
161251877Speter    if (rv)
162251877Speter        return rv;
163251877Speter
164251877Speter    l->desc.desc_type = APR_POLL_SOCKET;
165251877Speter    l->desc.desc.s = l->skt;
166251877Speter    l->desc.reqevents = APR_POLLIN;
167251877Speter
168251877Speter    rv = ctx->pollset_add(ctx->pollset_baton,
169251877Speter                            &l->desc, &l->baton);
170251877Speter    if (rv)
171251877Speter        return rv;
172251877Speter
173251877Speter    *listener = l;
174251877Speter
175251877Speter    return APR_SUCCESS;
176251877Speter}
177