libcoap  4.2.1
coap_io.c
Go to the documentation of this file.
1 /* coap_io.c -- Default network I/O functions for libcoap
2  *
3  * Copyright (C) 2012,2014,2016-2019 Olaf Bergmann <bergmann@tzi.org> and others
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use.
7  */
8 
9 #include "coap_internal.h"
10 
11 #ifdef HAVE_STDIO_H
12 # include <stdio.h>
13 #endif
14 
15 #ifdef HAVE_SYS_SELECT_H
16 # include <sys/select.h>
17 #endif
18 #ifdef HAVE_SYS_SOCKET_H
19 # include <sys/socket.h>
20 # define OPTVAL_T(t) (t)
21 # define OPTVAL_GT(t) (t)
22 #endif
23 #ifdef HAVE_SYS_IOCTL_H
24  #include <sys/ioctl.h>
25 #endif
26 #ifdef HAVE_NETINET_IN_H
27 # include <netinet/in.h>
28 #endif
29 #ifdef HAVE_WS2TCPIP_H
30 #include <ws2tcpip.h>
31 # define OPTVAL_T(t) (const char*)(t)
32 # define OPTVAL_GT(t) (char*)(t)
33 # undef CMSG_DATA
34 # define CMSG_DATA WSA_CMSG_DATA
35 #endif
36 #ifdef HAVE_SYS_UIO_H
37 # include <sys/uio.h>
38 #endif
39 #ifdef HAVE_UNISTD_H
40 # include <unistd.h>
41 #endif
42 #include <errno.h>
43 #ifdef COAP_EPOLL_SUPPORT
44 #include <sys/epoll.h>
45 #include <sys/timerfd.h>
46 #endif /* COAP_EPOLL_SUPPORT */
47 
48 #ifdef WITH_CONTIKI
49 # include "uip.h"
50 #endif
51 
52 #if !defined(WITH_CONTIKI)
53  /* define generic PKTINFO for IPv4 */
54 #if defined(IP_PKTINFO)
55 # define GEN_IP_PKTINFO IP_PKTINFO
56 #elif defined(IP_RECVDSTADDR)
57 # define GEN_IP_PKTINFO IP_RECVDSTADDR
58 #else
59 # error "Need IP_PKTINFO or IP_RECVDSTADDR to request ancillary data from OS."
60 #endif /* IP_PKTINFO */
61 
62 /* define generic KTINFO for IPv6 */
63 #ifdef IPV6_RECVPKTINFO
64 # define GEN_IPV6_PKTINFO IPV6_RECVPKTINFO
65 #elif defined(IPV6_PKTINFO)
66 # define GEN_IPV6_PKTINFO IPV6_PKTINFO
67 #else
68 # error "Need IPV6_PKTINFO or IPV6_RECVPKTINFO to request ancillary data from OS."
69 #endif /* IPV6_RECVPKTINFO */
70 #endif
71 
73 
74 #ifdef WITH_CONTIKI
75 static int ep_initialized = 0;
76 
77 struct coap_endpoint_t *
79  static struct coap_endpoint_t ep;
80 
81  if (ep_initialized) {
82  return NULL;
83  } else {
84  ep_initialized = 1;
85  return &ep;
86  }
87 }
88 
89 void
91  ep_initialized = 0;
92 }
93 
94 int
96  const coap_address_t *listen_addr,
97  coap_address_t *bound_addr) {
98  sock->conn = udp_new(NULL, 0, NULL);
99 
100  if (!sock->conn) {
101  coap_log(LOG_WARNING, "coap_socket_bind_udp");
102  return 0;
103  }
104 
105  coap_address_init(bound_addr);
106  uip_ipaddr_copy(&bound_addr->addr, &listen_addr->addr);
107  bound_addr->port = listen_addr->port;
108  udp_bind((struct uip_udp_conn *)sock->conn, bound_addr->port);
109  return 1;
110 }
111 
112 int
114  const coap_address_t *local_if,
115  const coap_address_t *server,
116  int default_port,
117  coap_address_t *local_addr,
118  coap_address_t *remote_addr) {
119  return 0;
120 }
121 
122 int
124  const coap_address_t *local_if,
125  const coap_address_t *server,
126  int default_port,
127  coap_address_t *local_addr,
128  coap_address_t *remote_addr) {
129  return 0;
130 }
131 
132 int
134  coap_address_t *local_addr,
135  coap_address_t *remote_addr) {
136  return 0;
137 }
138 
139 int
141  const coap_address_t *listen_addr,
142  coap_address_t *bound_addr) {
143  return 0;
144 }
145 
146 int
148  coap_socket_t *new_client,
149  coap_address_t *local_addr,
150  coap_address_t *remote_addr) {
151  return 0;
152 }
153 
154 ssize_t
155 coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len) {
156  return -1;
157 }
158 
159 ssize_t
160 coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len) {
161  return -1;
162 }
163 
164 void coap_socket_close(coap_socket_t *sock) {
165  if (sock->conn)
166  uip_udp_remove((struct uip_udp_conn *)sock->conn);
167  sock->flags = COAP_SOCKET_EMPTY;
168 }
169 
170 #else
171 
172 static const char *coap_socket_format_errno( int error );
173 
174 struct coap_endpoint_t *
176  return (struct coap_endpoint_t *)coap_malloc_type(COAP_ENDPOINT, sizeof(struct coap_endpoint_t));
177 }
178 
179 void
182 }
183 
184 int
186  const coap_address_t *listen_addr,
187  coap_address_t *bound_addr) {
188  int on = 1, off = 0;
189 #ifdef _WIN32
190  u_long u_on = 1;
191 #endif
192 
193  sock->fd = socket(listen_addr->addr.sa.sa_family, SOCK_DGRAM, 0);
194 
195  if (sock->fd == COAP_INVALID_SOCKET) {
197  "coap_socket_bind_udp: socket: %s\n", coap_socket_strerror());
198  goto error;
199  }
200 
201 #ifdef _WIN32
202  if (ioctlsocket(sock->fd, FIONBIO, &u_on) == COAP_SOCKET_ERROR) {
203 #else
204  if (ioctl(sock->fd, FIONBIO, &on) == COAP_SOCKET_ERROR) {
205 #endif
207  "coap_socket_bind_udp: ioctl FIONBIO: %s\n", coap_socket_strerror());
208  }
209 
210  if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on), sizeof(on)) == COAP_SOCKET_ERROR)
212  "coap_socket_bind_udp: setsockopt SO_REUSEADDR: %s\n",
214 
215  switch (listen_addr->addr.