Annotation of embedaddon/libpdel/http/http_connection.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (c) 2001-2002 Packet Design, LLC.
4: * All rights reserved.
5: *
6: * Subject to the following obligations and disclaimer of warranty,
7: * use and redistribution of this software, in source or object code
8: * forms, with or without modifications are expressly permitted by
9: * Packet Design; provided, however, that:
10: *
11: * (i) Any and all reproductions of the source or object code
12: * must include the copyright notice above and the following
13: * disclaimer of warranties; and
14: * (ii) No rights are granted, in any manner or form, to use
15: * Packet Design trademarks, including the mark "PACKET DESIGN"
16: * on advertising, endorsements, or otherwise except as such
17: * appears in the above copyright notice or in the software.
18: *
19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
36: * THE POSSIBILITY OF SUCH DAMAGE.
37: *
38: * Author: Archie Cobbs <archie@freebsd.org>
39: */
40:
41: #include <sys/types.h>
42: #include <sys/socket.h>
43: #include <sys/syslog.h>
44: #include <sys/queue.h>
45:
46: #include <netinet/in_systm.h>
47: #include <netinet/in.h>
48: #include <arpa/inet.h>
49:
50: #include <stdio.h>
51: #include <stdlib.h>
52: #include <stdarg.h>
53: #include <string.h>
54: #include <unistd.h>
55: #include <assert.h>
56: #include <pthread.h>
57:
58: #include <openssl/ssl.h>
59: #include <openssl/err.h>
60:
61: #include "structs/structs.h"
62: #include "structs/type/array.h"
63:
64: #include "io/ssl_fp.h"
65: #include "io/timeout_fp.h"
66: #include "util/typed_mem.h"
67:
68: #include "http/http_server.h"
69: #include "http/http_internal.h"
70:
71: /* Internal functions */
72: static ssl_logger_t http_connection_ssl_logger;
73:
74: /*
75: * Create a new connection from a raw socket/stream.
76: *
77: * If fp != NULL, we assume the stream already exists and that
78: * sock is valid and will be implicitly closed by fclose(fp).
79: * Otherwise, we assume sock is valid but has no stream on top of it.
80: * Parameter "server" tells whether we are the server or the client.
81: */
82: struct http_connection *
83: _http_connection_create(FILE *fp, int sock, int server,
84: struct in_addr ip, u_int16_t port, SSL_CTX *ssl,
85: http_logger_t *logger, u_int timeout)
86: {
87: struct http_connection *conn;
88: struct sockaddr_in sin;
89: socklen_t slen;
90:
91: /* Sanity */
92: if (sock < 0 || ip.s_addr == 0 || port == 0) {
93: errno = EINVAL;
94: return (NULL);
95: }
96:
97: /* Get local address */
98: slen = sizeof(sin);
99: if (getsockname(sock, (struct sockaddr *)&sin, &slen) == -1) {
100: (*logger)(LOG_ERR, "%s: %s", "getsockname", strerror(errno));
101: return (NULL);
102: }
103:
104: /* Get new connection object */
105: if ((conn = MALLOC("http_connection", sizeof(*conn))) == NULL) {
106: (*logger)(LOG_ERR, "%s: %s", "malloc", strerror(errno));
107: return (NULL);
108: }
109: memset(conn, 0, sizeof(*conn));
110: conn->remote_ip = ip;
111: conn->remote_port = port;
112: conn->local_ip = sin.sin_addr;
113: conn->local_port = ntohs(sin.sin_port);
114: conn->logger = logger;
115: conn->server = !!server;
116: conn->sock = sock;
117: conn->ssl = ssl;
118:
119: /* Create associated request and response */
120: if (_http_request_new(conn) == -1)
121: goto fail;
122: if (_http_response_new(conn) == -1)
123: goto fail;
124:
125: /* Wrap socket descriptor with a stream (if not already supplied) */
126: if (fp == NULL) {
127: if (ssl != NULL) {
128: fp = ssl_fdopen(ssl, sock, server,
129: "http_connection.fp", http_connection_ssl_logger,
130: conn, timeout);
131: } else
132: fp = timeout_fdopen(sock, "r+", timeout);
133: if (fp == NULL) {
134: (*logger)(LOG_ERR, "%s: %s", "fdopen", strerror(errno));
135: goto fail;
136: }
137: }
138: conn->fp = fp;
139:
140: /* Make stream not buffered */
141: setbuf(conn->fp, NULL);
142:
143: /* Done */
144: return (conn);
145:
146: fail:
147: _http_connection_free(&conn);
148: return (NULL);
149: }
150:
151: /*
152: * Free a connection.
153: */
154: void
155: _http_connection_free(struct http_connection **connp)
156: {
157: struct http_connection *const conn = *connp;
158:
159: /* Check for NULL */
160: if (conn == NULL)
161: return;
162: DBG(HTTP, "freeing connection %p", conn);
163:
164: /* Tell the caller that the connection went away */
165: *connp = NULL;
166:
167: /* Close stream and socket */
168: if (conn->fp != NULL)
169: fclose(conn->fp);
170: else if (conn->sock != -1)
171: (void)close(conn->sock);
172:
173: /* Free request and response */
174: _http_request_free(&conn->req);
175: _http_response_free(&conn->resp);
176:
177: /* Free structure */
178: FREE("http_connection", conn);
179: }
180:
181: /*
182: * Logging callback for SSL code.
183: */
184: static void
185: http_connection_ssl_logger(void *arg, int sev, const char *fmt, ...)
186: {
187: #if 0 /* SSL errors are quite common, so don't log them */
188: struct http_connection *const conn = arg;
189: va_list args;
190: char *s;
191:
192: /* Prepend remote IP address to error message */
193: va_start(args, fmt);
194: VASPRINTF(TYPED_MEM_TEMP, &s, fmt, args);
195: va_end(args);
196: if (s == NULL)
197: return;
198: (*conn->logger)(sev, "%s: %s", inet_ntoa(conn->remote_ip), s);
199: FREE(TYPED_MEM_TEMP, s);
200: #endif
201: }
202:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>