source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/src/core/altcp.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.7 KB
Line 
1/**
2 * @file
3 * @defgroup altcp Application layered TCP Functions
4 * @ingroup altcp_api
5 *
6 * This file contains the common functions for altcp to work.
7 * For more details see @ref altcp_api.
8 */
9
10/**
11 * @defgroup altcp_api Application layered TCP Introduction
12 * @ingroup callbackstyle_api
13 *
14 * Overview
15 * --------
16 * altcp (application layered TCP connection API; to be used from TCPIP thread)
17 * is an abstraction layer that prevents applications linking hard against the
18 * @ref tcp.h functions while providing the same functionality. It is used to
19 * e.g. add SSL/TLS (see LWIP_ALTCP_TLS) or proxy-connect support to an application
20 * written for the tcp callback API without that application knowing the
21 * protocol details.
22 *
23 * * This interface mimics the tcp callback API to the application while preventing
24 * direct linking (much like virtual functions).
25 * * This way, an application can make use of other application layer protocols
26 * on top of TCP without knowing the details (e.g. TLS, proxy connection).
27 * * This is achieved by simply including "lwip/altcp.h" instead of "lwip/tcp.h",
28 * replacing "struct tcp_pcb" with "struct altcp_pcb" and prefixing all functions
29 * with "altcp_" instead of "tcp_".
30 *
31 * With altcp support disabled (LWIP_ALTCP==0), applications written against the
32 * altcp API can still be compiled but are directly linked against the tcp.h
33 * callback API and then cannot use layered protocols. To minimize code changes
34 * in this case, the use of altcp_allocators is strongly suggested.
35 *
36 * Usage
37 * -----
38 * To make use of this API from an existing tcp raw API application:
39 * * Include "lwip/altcp.h" instead of "lwip/tcp.h"
40 * * Replace "struct tcp_pcb" with "struct altcp_pcb"
41 * * Prefix all called tcp API functions with "altcp_" instead of "tcp_" to link
42 * against the altcp functions
43 * * @ref altcp_new (and @ref altcp_new_ip_type/@ref altcp_new_ip6) take
44 * an @ref altcp_allocator_t as an argument, whereas the original tcp API
45 * functions take no arguments.
46 * * An @ref altcp_allocator_t allocator is an object that holds a pointer to an
47 * allocator object and a corresponding state (e.g. for TLS, the corresponding
48 * state may hold certificates or keys). This way, the application does not
49 * even need to know if it uses TLS or pure TCP, this is handled at runtime
50 * by passing a specific allocator.
51 * * An application can alternatively bind hard to the altcp_tls API by calling
52 * @ref altcp_tls_new or @ref altcp_tls_wrap.
53 * * The TLS layer is not directly implemented by lwIP, but a port to mbedTLS is
54 * provided.
55 * * Another altcp layer is proxy-connect to use TLS behind a HTTP proxy (see
56 * @ref altcp_proxyconnect.h)
57 *
58 * altcp_allocator_t
59 * -----------------
60 * An altcp allocator is created by the application by combining an allocator
61 * callback function and a corresponding state, e.g.:\code{.c}
62 * static const unsigned char cert[] = {0x2D, ... (see mbedTLS doc for how to create this)};
63 * struct altcp_tls_config * conf = altcp_tls_create_config_client(cert, sizeof(cert));
64 * altcp_allocator_t tls_allocator = {
65 * altcp_tls_alloc, conf
66 * };
67 * \endcode
68 *
69 *
70 * struct altcp_tls_config
71 * -----------------------
72 * The struct altcp_tls_config holds state that is needed to create new TLS client
73 * or server connections (e.g. certificates and private keys).
74 *
75 * It is not defined by lwIP itself but by the TLS port (e.g. altcp_tls to mbedTLS
76 * adaption). However, the parameters used to create it are defined in @ref
77 * altcp_tls.h (see @ref altcp_tls_create_config_server_privkey_cert for servers
78 * and @ref altcp_tls_create_config_client/@ref altcp_tls_create_config_client_2wayauth
79 * for clients).
80 *
81 * For mbedTLS, ensure that certificates can be parsed by 'mbedtls_x509_crt_parse()' and
82 * private keys can be parsed by 'mbedtls_pk_parse_key()'.
83 */
84
85/*
86 * Copyright (c) 2017 Simon Goldschmidt
87 * All rights reserved.
88 *
89 * Redistribution and use in source and binary forms, with or without modification,
90 * are permitted provided that the following conditions are met:
91 *
92 * 1. Redistributions of source code must retain the above copyright notice,
93 * this list of conditions and the following disclaimer.
94 * 2. Redistributions in binary form must reproduce the above copyright notice,
95 * this list of conditions and the following disclaimer in the documentation
96 * and/or other materials provided with the distribution.
97 * 3. The name of the author may not be used to endorse or promote products
98 * derived from this software without specific prior written permission.
99 *
100 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
101 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
102 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
103 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
104 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
105 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
106 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
107 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
108 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
109 * OF SUCH DAMAGE.
110 *
111 * This file is part of the lwIP TCP/IP stack.
112 *
113 * Author: Simon Goldschmidt <goldsimon@gmx.de>
114 *
115 */
116
117#include "lwip/opt.h"
118
119#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
120
121#include "lwip/altcp.h"
122#include "lwip/priv/altcp_priv.h"
123#include "lwip/altcp_tcp.h"
124#include "lwip/tcp.h"
125#include "lwip/mem.h"
126
127#include <string.h>
128
129extern const struct altcp_functions altcp_tcp_functions;
130
131/**
132 * For altcp layer implementations only: allocate a new struct altcp_pcb from the pool
133 * and zero the memory
134 */
135struct altcp_pcb *
136altcp_alloc(void)
137{
138 struct altcp_pcb *ret = (struct altcp_pcb *)memp_malloc(MEMP_ALTCP_PCB);
139 if (ret != NULL) {
140 memset(ret, 0, sizeof(struct altcp_pcb));
141 }
142 return ret;
143}
144
145/**
146 * For altcp layer implementations only: return a struct altcp_pcb to the pool
147 */
148void
149altcp_free(struct altcp_pcb *conn)
150{
151 if (conn) {
152 if (conn->fns && conn->fns->dealloc) {
153 conn->fns->dealloc(conn);
154 }
155 memp_free(MEMP_ALTCP_PCB, conn);
156 }
157}
158
159/**
160 * @ingroup altcp
161 * altcp_new_ip6: @ref altcp_new for IPv6
162 */
163struct altcp_pcb *
164altcp_new_ip6(altcp_allocator_t *allocator)
165{
166 return altcp_new_ip_type(allocator, IPADDR_TYPE_V6);
167}
168
169/**
170 * @ingroup altcp
171 * altcp_new: @ref altcp_new for IPv4
172 */
173struct altcp_pcb *
174altcp_new(altcp_allocator_t *allocator)
175{
176 return altcp_new_ip_type(allocator, IPADDR_TYPE_V4);
177}
178
179/**
180 * @ingroup altcp
181 * altcp_new_ip_type: called by applications to allocate a new pcb with the help of an
182 * allocator function.
183 *
184 * @param allocator allocator function and argument
185 * @param ip_type IP version of the pcb (@ref lwip_ip_addr_type)
186 * @return a new altcp_pcb or NULL on error
187 */
188struct altcp_pcb *
189altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type)
190{
191 struct altcp_pcb *conn;
192 if (allocator == NULL) {
193 /* no allocator given, create a simple TCP connection */
194 return altcp_tcp_new_ip_type(ip_type);
195 }
196 if (allocator->alloc == NULL) {
197 /* illegal allocator */
198 return NULL;
199 }
200 conn = allocator->alloc(allocator->arg, ip_type);
201 if (conn == NULL) {
202 /* allocation failed */
203 return NULL;
204 }
205 return conn;
206}
207
208/**
209 * @ingroup altcp
210 * @see tcp_arg()
211 */
212void
213altcp_arg(struct altcp_pcb *conn, void *arg)
214{
215 if (conn) {
216 conn->arg = arg;
217 }
218}
219
220/**
221 * @ingroup altcp
222 * @see tcp_accept()
223 */
224void
225altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept)
226{
227 if (conn != NULL) {
228 conn->accept = accept;
229 }
230}
231
232/**
233 * @ingroup altcp
234 * @see tcp_recv()
235 */
236void
237altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv)
238{
239 if (conn) {
240 conn->recv = recv;
241 }
242}
243
244/**
245 * @ingroup altcp
246 * @see tcp_sent()
247 */
248void
249altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent)
250{
251 if (conn) {
252 conn->sent = sent;
253 }
254}
255
256/**
257 * @ingroup altcp
258 * @see tcp_poll()
259 */
260void
261altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval)
262{
263 if (conn) {
264 conn->poll = poll;
265 conn->pollinterval = interval;
266 if (conn->fns && conn->fns->set_poll) {
267 conn->fns->set_poll(conn, interval);
268 }
269 }
270}
271
272/**
273 * @ingroup altcp
274 * @see tcp_err()
275 */
276void
277altcp_err(struct altcp_pcb *conn, altcp_err_fn err)
278{
279 if (conn) {
280 conn->err = err;
281 }
282}
283
284/* Generic functions calling the "virtual" ones */
285
286/**
287 * @ingroup altcp
288 * @see tcp_recved()
289 */
290void
291altcp_recved(struct altcp_pcb *conn, u16_t len)
292{
293 if (conn && conn->fns && conn->fns->recved) {
294 conn->fns->recved(conn, len);
295 }
296}
297
298/**
299 * @ingroup altcp
300 * @see tcp_bind()
301 */
302err_t
303altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port)
304{
305 if (conn && conn->fns && conn->fns->bind) {
306 return conn->fns->bind(conn, ipaddr, port);
307 }
308 return ERR_VAL;
309}
310
311/**
312 * @ingroup altcp
313 * @see tcp_connect()
314 */
315err_t
316altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected)
317{
318 if (conn && conn->fns && conn->fns->connect) {
319 return conn->fns->connect(conn, ipaddr, port, connected);
320 }
321 return ERR_VAL;
322}
323
324/**
325 * @ingroup altcp
326 * @see tcp_listen_with_backlog_and_err()
327 */
328struct altcp_pcb *
329altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err)
330{
331 if (conn && conn->fns && conn->fns->listen) {
332 return conn->fns->listen(conn, backlog, err);
333 }
334 return NULL;
335}
336
337/**
338 * @ingroup altcp
339 * @see tcp_abort()
340 */
341void
342altcp_abort(struct altcp_pcb *conn)
343{
344 if (conn && conn->fns && conn->fns->abort) {
345 conn->fns->abort(conn);
346 }
347}
348
349/**
350 * @ingroup altcp
351 * @see tcp_close()
352 */
353err_t
354altcp_close(struct altcp_pcb *conn)
355{
356 if (conn && conn->fns && conn->fns->close) {
357 return conn->fns->close(conn);
358 }
359 return ERR_VAL;
360}
361
362/**
363 * @ingroup altcp
364 * @see tcp_shutdown()
365 */
366err_t
367altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx)
368{
369 if (conn && conn->fns && conn->fns->shutdown) {
370 return conn->fns->shutdown(conn, shut_rx, shut_tx);
371 }
372 return ERR_VAL;
373}
374
375/**
376 * @ingroup altcp
377 * @see tcp_write()
378 */
379err_t
380altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
381{
382 if (conn && conn->fns && conn->fns->write) {
383 return conn->fns->write(conn, dataptr, len, apiflags);
384 }
385 return ERR_VAL;
386}
387
388/**
389 * @ingroup altcp
390 * @see tcp_output()
391 */
392err_t
393altcp_output(struct altcp_pcb *conn)
394{
395 if (conn && conn->fns && conn->fns->output) {
396 return conn->fns->output(conn);
397 }
398 return ERR_VAL;
399}
400
401/**
402 * @ingroup altcp
403 * @see tcp_mss()
404 */
405u16_t
406altcp_mss(struct altcp_pcb *conn)
407{
408 if (conn && conn->fns && conn->fns->mss) {
409 return conn->fns->mss(conn);
410 }
411 return 0;
412}
413
414/**
415 * @ingroup altcp
416 * @see tcp_sndbuf()
417 */
418u16_t
419altcp_sndbuf(struct altcp_pcb *conn)
420{
421 if (conn && conn->fns && conn->fns->sndbuf) {
422 return conn->fns->sndbuf(conn);
423 }
424 return 0;
425}
426
427/**
428 * @ingroup altcp
429 * @see tcp_sndqueuelen()
430 */
431u16_t
432altcp_sndqueuelen(struct altcp_pcb *conn)
433{
434 if (conn && conn->fns && conn->fns->sndqueuelen) {
435 return conn->fns->sndqueuelen(conn);
436 }
437 return 0;
438}
439
440void
441altcp_nagle_disable(struct altcp_pcb *conn)
442{
443 if (conn && conn->fns && conn->fns->nagle_disable) {
444 conn->fns->nagle_disable(conn);
445 }
446}
447
448void
449altcp_nagle_enable(struct altcp_pcb *conn)
450{
451 if (conn && conn->fns && conn->fns->nagle_enable) {
452 conn->fns->nagle_enable(conn);
453 }
454}
455
456int
457altcp_nagle_disabled(struct altcp_pcb *conn)
458{
459 if (conn && conn->fns && conn->fns->nagle_disabled) {
460 return conn->fns->nagle_disabled(conn);
461 }
462 return 0;
463}
464
465/**
466 * @ingroup altcp
467 * @see tcp_setprio()
468 */
469void
470altcp_setprio(struct altcp_pcb *conn, u8_t prio)
471{
472 if (conn && conn->fns && conn->fns->setprio) {
473 conn->fns->setprio(conn, prio);
474 }
475}
476
477err_t
478altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port)
479{
480 if (conn && conn->fns && conn->fns->addrinfo) {
481 return conn->fns->addrinfo(conn, local, addr, port);
482 }
483 return ERR_VAL;
484}
485
486ip_addr_t *
487altcp_get_ip(struct altcp_pcb *conn, int local)
488{
489 if (conn && conn->fns && conn->fns->getip) {
490 return conn->fns->getip(conn, local);
491 }
492 return NULL;
493}
494
495u16_t
496altcp_get_port(struct altcp_pcb *conn, int local)
497{
498 if (conn && conn->fns && conn->fns->getport) {
499 return conn->fns->getport(conn, local);
500 }
501 return 0;
502}
503
504#ifdef LWIP_DEBUG
505enum tcp_state
506altcp_dbg_get_tcp_state(struct altcp_pcb *conn)
507{
508 if (conn && conn->fns && conn->fns->dbg_get_tcp_state) {
509 return conn->fns->dbg_get_tcp_state(conn);
510 }
511 return CLOSED;
512}
513#endif
514
515/* Default implementations for the "virtual" functions */
516
517void
518altcp_default_set_poll(struct altcp_pcb *conn, u8_t interval)
519{
520 if (conn && conn->inner_conn) {
521 altcp_poll(conn->inner_conn, conn->poll, interval);
522 }
523}
524
525void
526altcp_default_recved(struct altcp_pcb *conn, u16_t len)
527{
528 if (conn && conn->inner_conn) {
529 altcp_recved(conn->inner_conn, len);
530 }
531}
532
533err_t
534altcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port)
535{
536 if (conn && conn->inner_conn) {
537 return altcp_bind(conn->inner_conn, ipaddr, port);
538 }
539 return ERR_VAL;
540}
541
542err_t
543altcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx)
544{
545 if (conn) {
546 if (shut_rx && shut_tx && conn->fns && conn->fns->close) {
547 /* default shutdown for both sides is close */
548 return conn->fns->close(conn);
549 }
550 if (conn->inner_conn) {
551 return altcp_shutdown(conn->inner_conn, shut_rx, shut_tx);
552 }
553 }
554 return ERR_VAL;
555}
556
557err_t
558altcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
559{
560 if (conn && conn->inner_conn) {
561 return altcp_write(conn->inner_conn, dataptr, len, apiflags);
562 }
563 return ERR_VAL;
564}
565
566err_t
567altcp_default_output(struct altcp_pcb *conn)
568{
569 if (conn && conn->inner_conn) {
570 return altcp_output(conn->inner_conn);
571 }
572 return ERR_VAL;
573}
574
575u16_t
576altcp_default_mss(struct altcp_pcb *conn)
577{
578 if (conn && conn->inner_conn) {
579 return altcp_mss(conn->inner_conn);
580 }
581 return 0;
582}
583
584u16_t
585altcp_default_sndbuf(struct altcp_pcb *conn)
586{
587 if (conn && conn->inner_conn) {
588 return altcp_sndbuf(conn->inner_conn);
589 }
590 return 0;
591}
592
593u16_t
594altcp_default_sndqueuelen(struct altcp_pcb *conn)
595{
596 if (conn && conn->inner_conn) {
597 return altcp_sndqueuelen(conn->inner_conn);
598 }
599 return 0;
600}
601
602void
603altcp_default_nagle_disable(struct altcp_pcb *conn)
604{
605 if (conn && conn->inner_conn) {
606 altcp_nagle_disable(conn->inner_conn);
607 }
608}
609
610void
611altcp_default_nagle_enable(struct altcp_pcb *conn)
612{
613 if (conn && conn->inner_conn) {
614 altcp_nagle_enable(conn->inner_conn);
615 }
616}
617
618int
619altcp_default_nagle_disabled(struct altcp_pcb *conn)
620{
621 if (conn && conn->inner_conn) {
622 return altcp_nagle_disabled(conn->inner_conn);
623 }
624 return 0;
625}
626
627void
628altcp_default_setprio(struct altcp_pcb *conn, u8_t prio)
629{
630 if (conn && conn->inner_conn) {
631 altcp_setprio(conn->inner_conn, prio);
632 }
633}
634
635void
636altcp_default_dealloc(struct altcp_pcb *conn)
637{
638 LWIP_UNUSED_ARG(conn);
639 /* nothing to do */
640}
641
642err_t
643altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port)
644{
645 if (conn && conn->inner_conn) {
646 return altcp_get_tcp_addrinfo(conn->inner_conn, local, addr, port);
647 }
648 return ERR_VAL;
649}
650
651ip_addr_t *
652altcp_default_get_ip(struct altcp_pcb *conn, int local)
653{
654 if (conn && conn->inner_conn) {
655 return altcp_get_ip(conn->inner_conn, local);
656 }
657 return NULL;
658}
659
660u16_t
661altcp_default_get_port(struct altcp_pcb *conn, int local)
662{
663 if (conn && conn->inner_conn) {
664 return altcp_get_port(conn->inner_conn, local);
665 }
666 return 0;
667}
668
669#ifdef LWIP_DEBUG
670enum tcp_state
671altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn)
672{
673 if (conn && conn->inner_conn) {
674 return altcp_dbg_get_tcp_state(conn->inner_conn);
675 }
676 return CLOSED;
677}
678#endif
679
680
681#endif /* LWIP_ALTCP */
Note: See TracBrowser for help on using the repository browser.