1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <apr_pools.h>
17 #include <apr_poll.h>
18 #include <apr_version.h>
19
20 #include "serf.h"
21 #include "serf_bucket_util.h"
22
23 #include "serf_private.h"
24
read_from_client(serf_incoming_t * client)25 static apr_status_t read_from_client(serf_incoming_t *client)
26 {
27 return APR_ENOTIMPL;
28 }
29
write_to_client(serf_incoming_t * client)30 static apr_status_t write_to_client(serf_incoming_t *client)
31 {
32 return APR_ENOTIMPL;
33 }
34
serf__process_client(serf_incoming_t * client,apr_int16_t events)35 apr_status_t serf__process_client(serf_incoming_t *client, apr_int16_t events)
36 {
37 apr_status_t rv;
38 if ((events & APR_POLLIN) != 0) {
39 rv = read_from_client(client);
40 if (rv) {
41 return rv;
42 }
43 }
44
45 if ((events & APR_POLLHUP) != 0) {
46 return APR_ECONNRESET;
47 }
48
49 if ((events & APR_POLLERR) != 0) {
50 return APR_EGENERAL;
51 }
52
53 if ((events & APR_POLLOUT) != 0) {
54 rv = write_to_client(client);
55 if (rv) {
56 return rv;
57 }
58 }
59
60 return APR_SUCCESS;
61 }
62
serf__process_listener(serf_listener_t * l)63 apr_status_t serf__process_listener(serf_listener_t *l)
64 {
65 apr_status_t rv;
66 apr_socket_t *in;
67 apr_pool_t *p;
68 /* THIS IS NOT OPTIMAL */
69 apr_pool_create(&p, l->pool);
70
71 rv = apr_socket_accept(&in, l->skt, p);
72
73 if (rv) {
74 apr_pool_destroy(p);
75 return rv;
76 }
77
78 rv = l->accept_func(l->ctx, l, l->accept_baton, in, p);
79
80 if (rv) {
81 apr_pool_destroy(p);
82 return rv;
83 }
84
85 return rv;
86 }
87
88
serf_incoming_create(serf_incoming_t ** client,serf_context_t * ctx,apr_socket_t * insock,void * request_baton,serf_incoming_request_cb_t request,apr_pool_t * pool)89 apr_status_t serf_incoming_create(
90 serf_incoming_t **client,
91 serf_context_t *ctx,
92 apr_socket_t *insock,
93 void *request_baton,
94 serf_incoming_request_cb_t request,
95 apr_pool_t *pool)
96 {
97 apr_status_t rv;
98 serf_incoming_t *ic = apr_palloc(pool, sizeof(*ic));
99
100 ic->ctx = ctx;
101 ic->baton.type = SERF_IO_CLIENT;
102 ic->baton.u.client = ic;
103 ic->request_baton = request_baton;
104 ic->request = request;
105 ic->skt = insock;
106 ic->desc.desc_type = APR_POLL_SOCKET;
107 ic->desc.desc.s = ic->skt;
108 ic->desc.reqevents = APR_POLLIN;
109
110 rv = ctx->pollset_add(ctx->pollset_baton,
111 &ic->desc, &ic->baton);
112 *client = ic;
113
114 return rv;
115 }
116
117
serf_listener_create(serf_listener_t ** listener,serf_context_t * ctx,const char * host,apr_uint16_t port,void * accept_baton,serf_accept_client_t accept,apr_pool_t * pool)118 apr_status_t serf_listener_create(
119 serf_listener_t **listener,
120 serf_context_t *ctx,
121 const char *host,
122 apr_uint16_t port,
123 void *accept_baton,
124 serf_accept_client_t accept,
125 apr_pool_t *pool)
126 {
127 apr_sockaddr_t *sa;
128 apr_status_t rv;
129 serf_listener_t *l = apr_palloc(pool, sizeof(*l));
130
131 l->ctx = ctx;
132 l->baton.type = SERF_IO_LISTENER;
133 l->baton.u.listener = l;
134 l->accept_func = accept;
135 l->accept_baton = accept_baton;
136
137 apr_pool_create(&l->pool, pool);
138
139 rv = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, l->pool);
140 if (rv)
141 return rv;
142
143 rv = apr_socket_create(&l->skt, sa->family,
144 SOCK_STREAM,
145 #if APR_MAJOR_VERSION > 0
146 APR_PROTO_TCP,
147 #endif
148 l->pool);
149 if (rv)
150 return rv;
151
152 rv = apr_socket_opt_set(l->skt, APR_SO_REUSEADDR, 1);
153 if (rv)
154 return rv;
155
156 rv = apr_socket_bind(l->skt, sa);
157 if (rv)
158 return rv;
159
160 rv = apr_socket_listen(l->skt, 5);
161 if (rv)
162 return rv;
163
164 l->desc.desc_type = APR_POLL_SOCKET;
165 l->desc.desc.s = l->skt;
166 l->desc.reqevents = APR_POLLIN;
167
168 rv = ctx->pollset_add(ctx->pollset_baton,
169 &l->desc, &l->baton);
170 if (rv)
171 return rv;
172
173 *listener = l;
174
175 return APR_SUCCESS;
176 }
177