1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 /** \defgroup sock-adopt Socket adoption helpers 26 * ##Socket adoption helpers 27 * 28 * When integrating with an external app with its own event loop, these can 29 * be used to accept connections from someone else's listening socket. 30 * 31 * When using lws own event loop, these are not needed. 32 */ 33 ///@{ 34 35 /** 36 * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it 37 * for the default vhost of context. 38 * 39 * \param context: lws context 40 * \param accept_fd: fd of already-accepted socket to adopt 41 * 42 * Either returns new wsi bound to accept_fd, or closes accept_fd and 43 * returns NULL, having cleaned up any new wsi pieces. 44 * 45 * LWS adopts the socket in http serving mode, it's ready to accept an upgrade 46 * to ws or just serve http. 47 */ 48 LWS_VISIBLE LWS_EXTERN struct lws * 49 lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); 50 /** 51 * lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted 52 * it for vhost 53 * 54 * \param vh: lws vhost 55 * \param accept_fd: fd of already-accepted socket to adopt 56 * 57 * Either returns new wsi bound to accept_fd, or closes accept_fd and 58 * returns NULL, having cleaned up any new wsi pieces. 59 * 60 * LWS adopts the socket in http serving mode, it's ready to accept an upgrade 61 * to ws or just serve http. 62 */ 63 LWS_VISIBLE LWS_EXTERN struct lws * 64 lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd); 65 66 typedef enum { 67 LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */ 68 LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */ 69 LWS_ADOPT_SOCKET = 2, /* flag: absent implies file descr */ 70 LWS_ADOPT_ALLOW_SSL = 4, /* flag: if set requires LWS_ADOPT_SOCKET */ 71 LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */ 72 LWS_ADOPT_FLAG_RAW_PROXY = 32, /* flag: raw proxy */ 73 74 LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP, 75 } lws_adoption_type; 76 77 typedef union { 78 lws_sockfd_type sockfd; 79 lws_filefd_type filefd; 80 } lws_sock_file_fd_type; 81 82 #if defined(LWS_WITH_UDP) 83 struct lws_udp { 84 struct sockaddr sa; 85 socklen_t salen; 86 87 struct sockaddr sa_pending; 88 socklen_t salen_pending; 89 }; 90 #endif 91 92 /** 93 * lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor 94 * if socket descriptor, should already have been accepted from listen socket 95 * 96 * \param vh: lws vhost 97 * \param type: OR-ed combinations of lws_adoption_type flags 98 * \param fd: union with either .sockfd or .filefd set 99 * \param vh_prot_name: NULL or vh protocol name to bind raw connection to 100 * \param parent: NULL or struct lws to attach new_wsi to as a child 101 * 102 * Either returns new wsi bound to accept_fd, or closes accept_fd and 103 * returns NULL, having cleaned up any new wsi pieces. 104 * 105 * If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's 106 * ready to accept an upgrade to ws or just serve http. 107 * 108 * parent may be NULL, if given it should be an existing wsi that will become the 109 * parent of the new wsi created by this call. 110 */ 111 LWS_VISIBLE LWS_EXTERN struct lws * 112 lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, 113 lws_sock_file_fd_type fd, const char *vh_prot_name, 114 struct lws *parent); 115 116 typedef struct lws_adopt_desc { 117 struct lws_vhost *vh; /**< vhost the wsi should belong to */ 118 lws_adoption_type type; /**< OR-ed combinations of lws_adoption_type flags */ 119 lws_sock_file_fd_type fd; /**< union with either .sockfd or .filefd set */ 120 const char *vh_prot_name; /**< NULL or vh protocol name to bind raw connection to */ 121 struct lws *parent; /**< NULL or struct lws to attach new_wsi to as a child */ 122 void *opaque; /**< opaque pointer to set on created wsi */ 123 } lws_adopt_desc_t; 124 125 /** 126 * lws_adopt_descriptor_vhost_via_info() - adopt foreign socket or file descriptor 127 * if socket descriptor, should already have been accepted from listen socket 128 * 129 * \param info: the struct containing the parameters 130 * 131 * - vh: lws vhost 132 * - type: OR-ed combinations of lws_adoption_type flags 133 * - fd: union with either .sockfd or .filefd set 134 * - vh_prot_name: NULL or vh protocol name to bind raw connection to 135 * - parent: NULL or struct lws to attach new_wsi to as a child 136 * - opaque: opaque pointer to set on created wsi 137 * 138 * Either returns new wsi bound to accept_fd, or closes accept_fd and 139 * returns NULL, having cleaned up any new wsi pieces. 140 * 141 * If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's 142 * ready to accept an upgrade to ws or just serve http. 143 * 144 * parent may be NULL, if given it should be an existing wsi that will become the 145 * parent of the new wsi created by this call. 146 */ 147 LWS_VISIBLE LWS_EXTERN struct lws * 148 lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info); 149 150 /** 151 * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it 152 * for the default vhost of context. 153 * \param context: lws context 154 * \param accept_fd: fd of already-accepted socket to adopt 155 * \param readbuf: NULL or pointer to data that must be drained before reading from 156 * accept_fd 157 * \param len: The length of the data held at \p readbuf 158 * 159 * Either returns new wsi bound to accept_fd, or closes accept_fd and 160 * returns NULL, having cleaned up any new wsi pieces. 161 * 162 * LWS adopts the socket in http serving mode, it's ready to accept an upgrade 163 * to ws or just serve http. 164 * 165 * If your external code did not already read from the socket, you can use 166 * lws_adopt_socket() instead. 167 * 168 * This api is guaranteed to use the data at \p readbuf first, before reading from 169 * the socket. 170 * 171 * \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes. 172 */ 173 LWS_VISIBLE LWS_EXTERN struct lws * 174 lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd, 175 const char *readbuf, size_t len); 176 /** 177 * lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket 178 * accepted it for vhost. 179 * \param vhost: lws vhost 180 * \param accept_fd: fd of already-accepted socket to adopt 181 * \param readbuf: NULL or pointer to data that must be drained before reading from accept_fd 182 * \param len: The length of the data held at \p readbuf 183 * 184 * Either returns new wsi bound to accept_fd, or closes accept_fd and 185 * returns NULL, having cleaned up any new wsi pieces. 186 * 187 * LWS adopts the socket in http serving mode, it's ready to accept an upgrade 188 * to ws or just serve http. 189 * 190 * If your external code did not already read from the socket, you can use 191 * lws_adopt_socket() instead. 192 * 193 * This api is guaranteed to use the data at \p readbuf first, before reading from 194 * the socket. 195 * 196 * \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes. 197 */ 198 LWS_VISIBLE LWS_EXTERN struct lws * 199 lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, 200 lws_sockfd_type accept_fd, const char *readbuf, 201 size_t len); 202 203 #define LWS_CAUDP_BIND (1 << 0) 204 #define LWS_CAUDP_BROADCAST (1 << 1) 205 #define LWS_CAUDP_PF_PACKET (1 << 2) 206 207 #if defined(LWS_WITH_UDP) 208 /** 209 * lws_create_adopt_udp() - create, bind and adopt a UDP socket 210 * 211 * \param vhost: lws vhost 212 * \param ads: NULL or address to do dns lookup on 213 * \param port: UDP port to bind to, -1 means unbound 214 * \param flags: 0 or LWS_CAUDP_NO_BIND 215 * \param protocol_name: Name of protocol on vhost to bind wsi to 216 * \param ifname: NULL, for network interface name to bind socket to 217 * \param parent_wsi: NULL or parent wsi new wsi will be a child of 218 * \param opaque: set created wsi opaque ptr to this 219 * \param retry_policy: NULL for vhost default policy else wsi specific policy 220 * 221 * Either returns new wsi bound to accept_fd, or closes accept_fd and 222 * returns NULL, having cleaned up any new wsi pieces. 223 * */ 224 LWS_VISIBLE LWS_EXTERN struct lws * 225 lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port, 226 int flags, const char *protocol_name, const char *ifname, 227 struct lws *parent_wsi, void *opaque, 228 const lws_retry_bo_t *retry_policy); 229 #endif 230 231 232 233 ///@} 234