xref: /aosp_15_r20/external/libwebsockets/lib/system/dhcpclient/dhcpc4.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker  /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2021 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  *
24*1c60b9acSAndroid Build Coastguard Worker  * The protocol part of dhcp4 client
25*1c60b9acSAndroid Build Coastguard Worker  */
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
28*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-system-dhcpclient.h"
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker #define LDHC_OP_BOOTREQUEST 1
31*1c60b9acSAndroid Build Coastguard Worker #define LDHC_OP_BOOTREPLY 2
32*1c60b9acSAndroid Build Coastguard Worker 
33*1c60b9acSAndroid Build Coastguard Worker /*
34*1c60b9acSAndroid Build Coastguard Worker  *  IPv4... max total 576
35*1c60b9acSAndroid Build Coastguard Worker  *
36*1c60b9acSAndroid Build Coastguard Worker  * 0                   1                   2                   3
37*1c60b9acSAndroid Build Coastguard Worker  * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
38*1c60b9acSAndroid Build Coastguard Worker  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39*1c60b9acSAndroid Build Coastguard Worker  * |     op (1)    |   htype (1)   |   hlen (1)    |   hops (1)    |
40*1c60b9acSAndroid Build Coastguard Worker  * +---------------+---------------+---------------+---------------+
41*1c60b9acSAndroid Build Coastguard Worker  * |  +04                       xid (4)                            |
42*1c60b9acSAndroid Build Coastguard Worker  * +-------------------------------+-------------------------------+
43*1c60b9acSAndroid Build Coastguard Worker  * |  +08      secs (2)            |  +0a         flags (2)        |
44*1c60b9acSAndroid Build Coastguard Worker  * +-------------------------------+-------------------------------+
45*1c60b9acSAndroid Build Coastguard Worker  * |  +0C                     ciaddr  (4)      client IP           |
46*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
47*1c60b9acSAndroid Build Coastguard Worker  * |  +10                     yiaddr  (4)      your IP             |
48*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
49*1c60b9acSAndroid Build Coastguard Worker  * |  +14                     siaddr  (4)      server IP           |
50*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
51*1c60b9acSAndroid Build Coastguard Worker  * |  +18                     giaddr  (4)      gateway IP          |
52*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
53*1c60b9acSAndroid Build Coastguard Worker  * |                                                               |
54*1c60b9acSAndroid Build Coastguard Worker  * |  +1C                     chaddr  (16)     client HWADDR       |
55*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
56*1c60b9acSAndroid Build Coastguard Worker  * |                                                               |
57*1c60b9acSAndroid Build Coastguard Worker  * |  +2C                     sname   (64)                         |
58*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
59*1c60b9acSAndroid Build Coastguard Worker  * |                                                               |
60*1c60b9acSAndroid Build Coastguard Worker  * |  +6C                     file    (128)                        |
61*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
62*1c60b9acSAndroid Build Coastguard Worker  * |                                                               |
63*1c60b9acSAndroid Build Coastguard Worker  * |  +EC                     options (variable)                   |
64*1c60b9acSAndroid Build Coastguard Worker  * +---------------------------------------------------------------+
65*1c60b9acSAndroid Build Coastguard Worker  */
66*1c60b9acSAndroid Build Coastguard Worker 
67*1c60b9acSAndroid Build Coastguard Worker static const uint8_t rawdisc4[] = {
68*1c60b9acSAndroid Build Coastguard Worker 	0x45, 0x00, 0, 0, 0, 0, 0x40, 0, 0x2e, IPPROTO_UDP,
69*1c60b9acSAndroid Build Coastguard Worker 	0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff,
70*1c60b9acSAndroid Build Coastguard Worker 	0, 68, 0, 67, 0, 0, 0, 0
71*1c60b9acSAndroid Build Coastguard Worker };
72*1c60b9acSAndroid Build Coastguard Worker 
73*1c60b9acSAndroid Build Coastguard Worker static const uint32_t botable2[] = { 1500, 1750, 5000 /* in case dog slow */ };
74*1c60b9acSAndroid Build Coastguard Worker static const lws_retry_bo_t bo2 = {
75*1c60b9acSAndroid Build Coastguard Worker 	botable2, LWS_ARRAY_SIZE(botable2), LWS_RETRY_CONCEAL_ALWAYS, 0, 0, 20 };
76*1c60b9acSAndroid Build Coastguard Worker 
77*1c60b9acSAndroid Build Coastguard Worker static int
lws_dhcpc4_prep(uint8_t * start,unsigned int bufsiz,lws_dhcpc_req_t * r,int op)78*1c60b9acSAndroid Build Coastguard Worker lws_dhcpc4_prep(uint8_t *start, unsigned int bufsiz, lws_dhcpc_req_t *r, int op)
79*1c60b9acSAndroid Build Coastguard Worker {
80*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *p = start;
81*1c60b9acSAndroid Build Coastguard Worker 
82*1c60b9acSAndroid Build Coastguard Worker 	memset(start, 0, bufsiz);
83*1c60b9acSAndroid Build Coastguard Worker 
84*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 1;
85*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 1;
86*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 6; /* sizeof ethernet MAC */
87*1c60b9acSAndroid Build Coastguard Worker 
88*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p + 1, r->xid, 4);
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker //	p[7] = 0x80; /* broadcast flag */
91*1c60b9acSAndroid Build Coastguard Worker 
92*1c60b9acSAndroid Build Coastguard Worker 	p += 0x1c - 3;
93*1c60b9acSAndroid Build Coastguard Worker 
94*1c60b9acSAndroid Build Coastguard Worker 	if (lws_plat_ifname_to_hwaddr(r->wsi_raw->desc.sockfd,
95*1c60b9acSAndroid Build Coastguard Worker 				      (const char *)&r[1], r->is.mac, 6) < 0)
96*1c60b9acSAndroid Build Coastguard Worker 		return -1;
97*1c60b9acSAndroid Build Coastguard Worker 
98*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p, r->is.mac, 6);
99*1c60b9acSAndroid Build Coastguard Worker 
100*1c60b9acSAndroid Build Coastguard Worker 	p += 16 + 64 + 128;
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x63; /* RFC2132 Magic Cookie indicates start of options */
103*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x82;
104*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x53;
105*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 0x63;
106*1c60b9acSAndroid Build Coastguard Worker 
107*1c60b9acSAndroid Build Coastguard Worker 	*p++ = LWSDHC4POPT_MESSAGE_TYPE;
108*1c60b9acSAndroid Build Coastguard Worker 	*p++ = 1;	/* length */
109*1c60b9acSAndroid Build Coastguard Worker 	*p++ = (uint8_t)op;
110*1c60b9acSAndroid Build Coastguard Worker 
111*1c60b9acSAndroid Build Coastguard Worker 	switch (op) {
112*1c60b9acSAndroid Build Coastguard Worker 	case LWSDHC4PDISCOVER:
113*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_PARAM_REQ_LIST;
114*1c60b9acSAndroid Build Coastguard Worker 		*p++ = 4; 	/* length */
115*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_SUBNET_MASK;
116*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_ROUTER;
117*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_DNSERVER;
118*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_DOMAIN_NAME;
119*1c60b9acSAndroid Build Coastguard Worker 		break;
120*1c60b9acSAndroid Build Coastguard Worker 
121*1c60b9acSAndroid Build Coastguard Worker 	case LWSDHC4PREQUEST:
122*1c60b9acSAndroid Build Coastguard Worker 		if (r->is.sa46[LWSDH_SA46_IP].sa4.sin_family != AF_INET)
123*1c60b9acSAndroid Build Coastguard Worker 			break;
124*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_REQUESTED_ADS;
125*1c60b9acSAndroid Build Coastguard Worker 		*p++ = 4; 	/* length */
126*1c60b9acSAndroid Build Coastguard Worker 		lws_ser_wu32be(p, r->is.sa46[LWSDH_SA46_IP].sa4.sin_addr.s_addr);
127*1c60b9acSAndroid Build Coastguard Worker 		p += 4;
128*1c60b9acSAndroid Build Coastguard Worker 		*p++ = LWSDHC4POPT_SERVER_ID;
129*1c60b9acSAndroid Build Coastguard Worker 		*p++ = 4; 	/* length */
130*1c60b9acSAndroid Build Coastguard Worker 		lws_ser_wu32be(p, r->is.sa46[LWSDH_SA46_DHCP_SERVER].sa4.sin_addr.s_addr);
131*1c60b9acSAndroid Build Coastguard Worker 		p += 4;
132*1c60b9acSAndroid Build Coastguard Worker 		break;
133*1c60b9acSAndroid Build Coastguard Worker 	}
134*1c60b9acSAndroid Build Coastguard Worker 
135*1c60b9acSAndroid Build Coastguard Worker 	*p++ = LWSDHC4POPT_END_OPTIONS;
136*1c60b9acSAndroid Build Coastguard Worker 
137*1c60b9acSAndroid Build Coastguard Worker 	return lws_ptr_diff(p, start);
138*1c60b9acSAndroid Build Coastguard Worker }
139*1c60b9acSAndroid Build Coastguard Worker 
140*1c60b9acSAndroid Build Coastguard Worker static int
callback_dhcpc4(struct lws * wsi,enum lws_callback_reasons reason,void * user,void * in,size_t len)141*1c60b9acSAndroid Build Coastguard Worker callback_dhcpc4(struct lws *wsi, enum lws_callback_reasons reason, void *user,
142*1c60b9acSAndroid Build Coastguard Worker 	       void *in, size_t len)
143*1c60b9acSAndroid Build Coastguard Worker {
144*1c60b9acSAndroid Build Coastguard Worker 	lws_dhcpc_req_t *r = (lws_dhcpc_req_t *)user;
145*1c60b9acSAndroid Build Coastguard Worker 	uint8_t pkt[LWS_PRE + 576], *p = pkt + LWS_PRE;
146*1c60b9acSAndroid Build Coastguard Worker 	int n, m;
147*1c60b9acSAndroid Build Coastguard Worker 
148*1c60b9acSAndroid Build Coastguard Worker 	switch (reason) {
149*1c60b9acSAndroid Build Coastguard Worker 
150*1c60b9acSAndroid Build Coastguard Worker         case LWS_CALLBACK_RAW_ADOPT:
151*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: LWS_CALLBACK_RAW_ADOPT\n", __func__);
152*1c60b9acSAndroid Build Coastguard Worker 		lws_callback_on_writable(wsi);
153*1c60b9acSAndroid Build Coastguard Worker 		break;
154*1c60b9acSAndroid Build Coastguard Worker 
155*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
156*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: udp conn failed\n", __func__);
157*1c60b9acSAndroid Build Coastguard Worker 
158*1c60b9acSAndroid Build Coastguard Worker 		/* fallthru */
159*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_RAW_CLOSE:
160*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: LWS_CALLBACK_RAW_CLOSE\n", __func__);
161*1c60b9acSAndroid Build Coastguard Worker 		if (!r)
162*1c60b9acSAndroid Build Coastguard Worker 			break;
163*1c60b9acSAndroid Build Coastguard Worker 		r->wsi_raw = NULL;
164*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&r->sul_write);
165*1c60b9acSAndroid Build Coastguard Worker 		if (r->state != LDHC_BOUND) {
166*1c60b9acSAndroid Build Coastguard Worker 			r->state = LDHC_INIT;
167*1c60b9acSAndroid Build Coastguard Worker 			lws_retry_sul_schedule(r->context, 0, &r->sul_conn,
168*1c60b9acSAndroid Build Coastguard Worker 					       &bo2, lws_dhcpc4_retry_conn,
169*1c60b9acSAndroid Build Coastguard Worker 					       &r->retry_count_conn);
170*1c60b9acSAndroid Build Coastguard Worker 		}
171*1c60b9acSAndroid Build Coastguard Worker 		break;
172*1c60b9acSAndroid Build Coastguard Worker 
173*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_RAW_RX:
174*1c60b9acSAndroid Build Coastguard Worker 
175*1c60b9acSAndroid Build Coastguard Worker 		if (lws_dhcpc4_parse(r, in, len))
176*1c60b9acSAndroid Build Coastguard Worker 			break;
177*1c60b9acSAndroid Build Coastguard Worker 
178*1c60b9acSAndroid Build Coastguard Worker 		/*
179*1c60b9acSAndroid Build Coastguard Worker 		 * that's it... commit to the configuration
180*1c60b9acSAndroid Build Coastguard Worker 		 */
181*1c60b9acSAndroid Build Coastguard Worker 
182*1c60b9acSAndroid Build Coastguard Worker 		/* set up our network interface as offered */
183*1c60b9acSAndroid Build Coastguard Worker 
184*1c60b9acSAndroid Build Coastguard Worker 		if (lws_plat_ifconfig(r->wsi_raw->desc.sockfd, &r->is))
185*1c60b9acSAndroid Build Coastguard Worker 			/*
186*1c60b9acSAndroid Build Coastguard Worker 			 * Problem setting the IP... maybe something
187*1c60b9acSAndroid Build Coastguard Worker 			 * transient like racing with NetworkManager?
188*1c60b9acSAndroid Build Coastguard Worker 			 * Since the sul retries are still around it
189*1c60b9acSAndroid Build Coastguard Worker 			 * will retry
190*1c60b9acSAndroid Build Coastguard Worker 			 */
191*1c60b9acSAndroid Build Coastguard Worker 			return -1;
192*1c60b9acSAndroid Build Coastguard Worker 
193*1c60b9acSAndroid Build Coastguard Worker 		/* clear timeouts related to the broadcast socket */
194*1c60b9acSAndroid Build Coastguard Worker 
195*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&r->sul_write);
196*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&r->sul_conn);
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: DHCP configured %s\n", __func__,
199*1c60b9acSAndroid Build Coastguard Worker 				(const char *)&r[1]);
200*1c60b9acSAndroid Build Coastguard Worker 		r->state = LDHC_BOUND;
201*1c60b9acSAndroid Build Coastguard Worker 
202*1c60b9acSAndroid Build Coastguard Worker 		lws_state_transition_steps(&wsi->a.context->mgr_system,
203*1c60b9acSAndroid Build Coastguard Worker 					   LWS_SYSTATE_OPERATIONAL);
204*1c60b9acSAndroid Build Coastguard Worker 
205*1c60b9acSAndroid Build Coastguard Worker 		r->cb(r->opaque, &r->is);
206*1c60b9acSAndroid Build Coastguard Worker 
207*1c60b9acSAndroid Build Coastguard Worker 		r->wsi_raw = NULL;
208*1c60b9acSAndroid Build Coastguard Worker 
209*1c60b9acSAndroid Build Coastguard Worker 		return -1; /* close the broadcast wsi */
210*1c60b9acSAndroid Build Coastguard Worker 
211*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_RAW_WRITEABLE:
212*1c60b9acSAndroid Build Coastguard Worker 
213*1c60b9acSAndroid Build Coastguard Worker 		if (!r)
214*1c60b9acSAndroid Build Coastguard Worker 			break;
215*1c60b9acSAndroid Build Coastguard Worker 
216*1c60b9acSAndroid Build Coastguard Worker 		/*
217*1c60b9acSAndroid Build Coastguard Worker 		 * UDP is not reliable, it can be locally dropped, or dropped
218*1c60b9acSAndroid Build Coastguard Worker 		 * by any intermediary or the remote peer.  So even though we
219*1c60b9acSAndroid Build Coastguard Worker 		 * will do the write in a moment, we schedule another request
220*1c60b9acSAndroid Build Coastguard Worker 		 * for rewrite according to the wsi retry policy.
221*1c60b9acSAndroid Build Coastguard Worker 		 *
222*1c60b9acSAndroid Build Coastguard Worker 		 * If the result came before, we'll cancel it in the close flow.
223*1c60b9acSAndroid Build Coastguard Worker 		 *
224*1c60b9acSAndroid Build Coastguard Worker 		 * If we have already reached the end of our concealed retries
225*1c60b9acSAndroid Build Coastguard Worker 		 * in the policy, just close without another write.
226*1c60b9acSAndroid Build Coastguard Worker 		 */
227*1c60b9acSAndroid Build Coastguard Worker 		if (lws_dll2_is_detached(&r->sul_write.list) &&
228*1c60b9acSAndroid Build Coastguard Worker 		    lws_retry_sul_schedule_retry_wsi(wsi, &r->sul_write,
229*1c60b9acSAndroid Build Coastguard Worker 						     lws_dhcpc_retry_write,
230*1c60b9acSAndroid Build Coastguard Worker 						     &r->retry_count_write)) {
231*1c60b9acSAndroid Build Coastguard Worker 			/* we have reached the end of our concealed retries */
232*1c60b9acSAndroid Build Coastguard Worker 			lwsl_warn("%s: concealed retries done, failing\n",
233*1c60b9acSAndroid Build Coastguard Worker 				  __func__);
234*1c60b9acSAndroid Build Coastguard Worker 			goto retry_conn;
235*1c60b9acSAndroid Build Coastguard Worker 		}
236*1c60b9acSAndroid Build Coastguard Worker 
237*1c60b9acSAndroid Build Coastguard Worker 		switch (r->state) {
238*1c60b9acSAndroid Build Coastguard Worker 		case LDHC_INIT:
239*1c60b9acSAndroid Build Coastguard Worker 			n = LWSDHC4PDISCOVER;
240*1c60b9acSAndroid Build Coastguard Worker 			goto bcast;
241*1c60b9acSAndroid Build Coastguard Worker 
242*1c60b9acSAndroid Build Coastguard Worker 		case LDHC_REQUESTING:
243*1c60b9acSAndroid Build Coastguard Worker 			n = LWSDHC4PREQUEST;
244*1c60b9acSAndroid Build Coastguard Worker 
245*1c60b9acSAndroid Build Coastguard Worker 			/* fallthru */
246*1c60b9acSAndroid Build Coastguard Worker bcast:
247*1c60b9acSAndroid Build Coastguard Worker 			n = lws_dhcpc4_prep(p + 28, (unsigned int)
248*1c60b9acSAndroid Build Coastguard Worker 					(sizeof(pkt) - LWS_PRE - 28), r, n);
249*1c60b9acSAndroid Build Coastguard Worker 			if (n < 0) {
250*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: failed to prep\n", __func__);
251*1c60b9acSAndroid Build Coastguard Worker 				break;
252*1c60b9acSAndroid Build Coastguard Worker 			}
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker 			m = lws_plat_rawudp_broadcast(p, rawdisc4,
255*1c60b9acSAndroid Build Coastguard Worker 						      LWS_ARRAY_SIZE(rawdisc4),
256*1c60b9acSAndroid Build Coastguard Worker 						      (size_t)(n + 28),
257*1c60b9acSAndroid Build Coastguard Worker 						      r->wsi_raw->desc.sockfd,
258*1c60b9acSAndroid Build Coastguard Worker 						      (const char *)&r[1]);
259*1c60b9acSAndroid Build Coastguard Worker 			if (m < 0)
260*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: Failed to write dhcp client req: "
261*1c60b9acSAndroid Build Coastguard Worker 					 "%d %d, errno %d\n", __func__,
262*1c60b9acSAndroid Build Coastguard Worker 					 n, m, LWS_ERRNO);
263*1c60b9acSAndroid Build Coastguard Worker 			break;
264*1c60b9acSAndroid Build Coastguard Worker 		default:
265*1c60b9acSAndroid Build Coastguard Worker 			break;
266*1c60b9acSAndroid Build Coastguard Worker 		}
267*1c60b9acSAndroid Build Coastguard Worker 
268*1c60b9acSAndroid Build Coastguard Worker 		return 0;
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker retry_conn:
271*1c60b9acSAndroid Build Coastguard Worker 		lws_retry_sul_schedule(wsi->a.context, 0, &r->sul_conn, &bo2,
272*1c60b9acSAndroid Build Coastguard Worker 				       lws_dhcpc4_retry_conn,
273*1c60b9acSAndroid Build Coastguard Worker 				       &r->retry_count_conn);
274*1c60b9acSAndroid Build Coastguard Worker 
275*1c60b9acSAndroid Build Coastguard Worker 		return -1;
276*1c60b9acSAndroid Build Coastguard Worker 
277*1c60b9acSAndroid Build Coastguard Worker 	default:
278*1c60b9acSAndroid Build Coastguard Worker 		break;
279*1c60b9acSAndroid Build Coastguard Worker 	}
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker 	return 0;
282*1c60b9acSAndroid Build Coastguard Worker }
283*1c60b9acSAndroid Build Coastguard Worker 
284*1c60b9acSAndroid Build Coastguard Worker struct lws_protocols lws_system_protocol_dhcpc4 =
285*1c60b9acSAndroid Build Coastguard Worker 	{ "lws-dhcp4client", callback_dhcpc4, 0, 128, 0, NULL, 0 };
286*1c60b9acSAndroid Build Coastguard Worker 
287*1c60b9acSAndroid Build Coastguard Worker void
lws_dhcpc4_retry_conn(struct lws_sorted_usec_list * sul)288*1c60b9acSAndroid Build Coastguard Worker lws_dhcpc4_retry_conn(struct lws_sorted_usec_list *sul)
289*1c60b9acSAndroid Build Coastguard Worker {
290*1c60b9acSAndroid Build Coastguard Worker 	lws_dhcpc_req_t *r = lws_container_of(sul, lws_dhcpc_req_t, sul_conn);
291*1c60b9acSAndroid Build Coastguard Worker 
292*1c60b9acSAndroid Build Coastguard Worker 	if (r->wsi_raw || !lws_dll2_is_detached(&r->sul_conn.list))
293*1c60b9acSAndroid Build Coastguard Worker 		return;
294*1c60b9acSAndroid Build Coastguard Worker 
295*1c60b9acSAndroid Build Coastguard Worker 	/* create the UDP socket aimed at the server */
296*1c60b9acSAndroid Build Coastguard Worker 
297*1c60b9acSAndroid Build Coastguard Worker 	r->retry_count_write = 0;
298*1c60b9acSAndroid Build Coastguard Worker 	r->wsi_raw = lws_create_adopt_udp(r->context->vhost_system, "0.0.0.0",
299*1c60b9acSAndroid Build Coastguard Worker 					  68, LWS_CAUDP_PF_PACKET |
300*1c60b9acSAndroid Build Coastguard Worker 					      LWS_CAUDP_BROADCAST,
301*1c60b9acSAndroid Build Coastguard Worker 					  "lws-dhcp4client", (const char *)&r[1],
302*1c60b9acSAndroid Build Coastguard Worker 					  NULL, NULL, &bo2, "dhcpc");
303*1c60b9acSAndroid Build Coastguard Worker 	lwsl_debug("%s: created wsi_raw: %s\n", __func__, lws_wsi_tag(r->wsi_raw));
304*1c60b9acSAndroid Build Coastguard Worker 	if (!r->wsi_raw) {
305*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to create udp skt\n", __func__);
306*1c60b9acSAndroid Build Coastguard Worker 
307*1c60b9acSAndroid Build Coastguard Worker 		lws_retry_sul_schedule(r->context, 0, &r->sul_conn, &bo2,
308*1c60b9acSAndroid Build Coastguard Worker 				       lws_dhcpc4_retry_conn,
309*1c60b9acSAndroid Build Coastguard Worker 				       &r->retry_count_conn);
310*1c60b9acSAndroid Build Coastguard Worker 
311*1c60b9acSAndroid Build Coastguard Worker 		return;
312*1c60b9acSAndroid Build Coastguard Worker 	}
313*1c60b9acSAndroid Build Coastguard Worker 
314*1c60b9acSAndroid Build Coastguard Worker 	/* force the network if up */
315*1c60b9acSAndroid Build Coastguard Worker 	lws_plat_if_up((const char *)&r[1], r->wsi_raw->desc.sockfd, 0);
316*1c60b9acSAndroid Build Coastguard Worker 	lws_plat_if_up((const char *)&r[1], r->wsi_raw->desc.sockfd, 1);
317*1c60b9acSAndroid Build Coastguard Worker 
318*1c60b9acSAndroid Build Coastguard Worker 	r->wsi_raw->user_space = r;
319*1c60b9acSAndroid Build Coastguard Worker 	r->wsi_raw->user_space_externally_allocated = 1;
320*1c60b9acSAndroid Build Coastguard Worker 
321*1c60b9acSAndroid Build Coastguard Worker 	lws_get_random(r->wsi_raw->a.context, r->xid, 4);
322*1c60b9acSAndroid Build Coastguard Worker }
323*1c60b9acSAndroid Build Coastguard Worker 
324*1c60b9acSAndroid Build Coastguard Worker static void
lws_sa46_set_ipv4(lws_dhcpc_req_t * r,unsigned int which,uint8_t * p)325*1c60b9acSAndroid Build Coastguard Worker lws_sa46_set_ipv4(lws_dhcpc_req_t *r, unsigned int which, uint8_t *p)
326*1c60b9acSAndroid Build Coastguard Worker {
327*1c60b9acSAndroid Build Coastguard Worker 	r->is.sa46[which].sa4.sin_family = AF_INET;
328*1c60b9acSAndroid Build Coastguard Worker 	r->is.sa46[which].sa4.sin_addr.s_addr = ntohl(lws_ser_ru32be(p));
329*1c60b9acSAndroid Build Coastguard Worker }
330*1c60b9acSAndroid Build Coastguard Worker 
331*1c60b9acSAndroid Build Coastguard Worker int
lws_dhcpc4_parse(lws_dhcpc_req_t * r,void * in,size_t len)332*1c60b9acSAndroid Build Coastguard Worker lws_dhcpc4_parse(lws_dhcpc_req_t *r, void *in, size_t len)
333*1c60b9acSAndroid Build Coastguard Worker {
334*1c60b9acSAndroid Build Coastguard Worker 	uint8_t pkt[LWS_PRE + 576], *p = pkt + LWS_PRE, *end;
335*1c60b9acSAndroid Build Coastguard Worker 	int n, m;
336*1c60b9acSAndroid Build Coastguard Worker 
337*1c60b9acSAndroid Build Coastguard Worker 	switch (r->state) {
338*1c60b9acSAndroid Build Coastguard Worker 	case LDHC_INIT:		/* expect DHCPOFFER */
339*1c60b9acSAndroid Build Coastguard Worker 	case LDHC_REQUESTING:	/* expect DHCPACK */
340*1c60b9acSAndroid Build Coastguard Worker 		/*
341*1c60b9acSAndroid Build Coastguard Worker 		 * We should check carefully if we like what we were
342*1c60b9acSAndroid Build Coastguard Worker 		 * sent... anything can spam us with crafted replies
343*1c60b9acSAndroid Build Coastguard Worker 		 */
344*1c60b9acSAndroid Build Coastguard Worker 		if (len < 0x100)
345*1c60b9acSAndroid Build Coastguard Worker 			break;
346*1c60b9acSAndroid Build Coastguard Worker 
347*1c60b9acSAndroid Build Coastguard Worker 		p = (uint8_t *)in + 28; /* skip to UDP payload */
348*1c60b9acSAndroid Build Coastguard Worker 		if (p[0] != 2 || p[1] != 1 || p[2] != 6)
349*1c60b9acSAndroid Build Coastguard Worker 			break;
350*1c60b9acSAndroid Build Coastguard Worker 
351*1c60b9acSAndroid Build Coastguard Worker 		if (memcmp(&p[4], r->xid, 4))	/* must be our xid */
352*1c60b9acSAndroid Build Coastguard Worker 			break;
353*1c60b9acSAndroid Build Coastguard Worker 
354*1c60b9acSAndroid Build Coastguard Worker 		if (memcmp(&p[0x1c], r->is.mac, 6)) /* our netif mac? */
355*1c60b9acSAndroid Build Coastguard Worker 			break;
356*1c60b9acSAndroid Build Coastguard Worker 
357*1c60b9acSAndroid Build Coastguard Worker 		/* the DHCP magic cookie must be in place */
358*1c60b9acSAndroid Build Coastguard Worker 		if (lws_ser_ru32be(&p[0xec]) != 0x63825363)
359*1c60b9acSAndroid Build Coastguard Worker 			break;
360*1c60b9acSAndroid Build Coastguard Worker 
361*1c60b9acSAndroid Build Coastguard Worker 		/* "your" client IP address */
362*1c60b9acSAndroid Build Coastguard Worker 		lws_sa46_set_ipv4(r, LWSDH_SA46_IP, p + 0x10);
363*1c60b9acSAndroid Build Coastguard Worker 		/* IP of next server used in bootstrap */
364*1c60b9acSAndroid Build Coastguard Worker 		lws_sa46_set_ipv4(r, LWSDH_SA46_DHCP_SERVER, p + 0x14);
365*1c60b9acSAndroid Build Coastguard Worker 
366*1c60b9acSAndroid Build Coastguard Worker 		/* it looks legit so far... look at the options */
367*1c60b9acSAndroid Build Coastguard Worker 
368*1c60b9acSAndroid Build Coastguard Worker 		end = (uint8_t *)in + len;
369*1c60b9acSAndroid Build Coastguard Worker 		p += 0xec + 4;
370*1c60b9acSAndroid Build Coastguard Worker 		while (p < end) {
371*1c60b9acSAndroid Build Coastguard Worker 			uint8_t c = *p++;
372*1c60b9acSAndroid Build Coastguard Worker 			uint8_t l = 0;
373*1c60b9acSAndroid Build Coastguard Worker 
374*1c60b9acSAndroid Build Coastguard Worker 			if (c && c != 0xff) {
375*1c60b9acSAndroid Build Coastguard Worker 				/* pad 0 and EOT 0xff have no length */
376*1c60b9acSAndroid Build Coastguard Worker 				l = *p++;
377*1c60b9acSAndroid Build Coastguard Worker 				if (!l) {
378*1c60b9acSAndroid Build Coastguard Worker 					lwsl_err("%s: zero length\n",
379*1c60b9acSAndroid Build Coastguard Worker 							__func__);
380*1c60b9acSAndroid Build Coastguard Worker 					goto broken;
381*1c60b9acSAndroid Build Coastguard Worker 				}
382*1c60b9acSAndroid Build Coastguard Worker 				if (p + l > end) {
383*1c60b9acSAndroid Build Coastguard Worker 					/* ...nice try... */
384*1c60b9acSAndroid Build Coastguard Worker 					lwsl_err("%s: bad len\n",
385*1c60b9acSAndroid Build Coastguard Worker 							__func__);
386*1c60b9acSAndroid Build Coastguard Worker 					goto broken;
387*1c60b9acSAndroid Build Coastguard Worker 				}
388*1c60b9acSAndroid Build Coastguard Worker 			}
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker 			if (c == 0xff) /* end of options */
391*1c60b9acSAndroid Build Coastguard Worker 				break;
392*1c60b9acSAndroid Build Coastguard Worker 
393*1c60b9acSAndroid Build Coastguard Worker 			m = 0;
394*1c60b9acSAndroid Build Coastguard Worker 			switch (c) {
395*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_SUBNET_MASK:
396*1c60b9acSAndroid Build Coastguard Worker 				n = LWSDH_IPV4_SUBNET_MASK;
397*1c60b9acSAndroid Build Coastguard Worker 				goto get_ipv4;
398*1c60b9acSAndroid Build Coastguard Worker 
399*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_ROUTER:
400*1c60b9acSAndroid Build Coastguard Worker 				lws_sa46_set_ipv4(r, LWSDH_SA46_IPV4_ROUTER, p);
401*1c60b9acSAndroid Build Coastguard Worker 				break;
402*1c60b9acSAndroid Build Coastguard Worker 
403*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_TIME_SERVER:
404*1c60b9acSAndroid Build Coastguard Worker 				lws_sa46_set_ipv4(r, LWSDH_SA46_NTP_SERVER, p);
405*1c60b9acSAndroid Build Coastguard Worker 				break;
406*1c60b9acSAndroid Build Coastguard Worker 
407*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_BROADCAST_ADS:
408*1c60b9acSAndroid Build Coastguard Worker 				n = LWSDH_IPV4_BROADCAST;
409*1c60b9acSAndroid Build Coastguard Worker 				goto get_ipv4;
410*1c60b9acSAndroid Build Coastguard Worker 
411*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_LEASE_TIME:
412*1c60b9acSAndroid Build Coastguard Worker 				n = LWSDH_LEASE_SECS;
413*1c60b9acSAndroid Build Coastguard Worker 				goto get_ipv4;
414*1c60b9acSAndroid Build Coastguard Worker 
415*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_RENEWAL_TIME: /* AKA T1 */
416*1c60b9acSAndroid Build Coastguard Worker 				n = LWSDH_RENEWAL_SECS;
417*1c60b9acSAndroid Build Coastguard Worker 				goto get_ipv4;
418*1c60b9acSAndroid Build Coastguard Worker 
419*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_REBINDING_TIME: /* AKA T2 */
420*1c60b9acSAndroid Build Coastguard Worker 				n = LWSDH_REBINDING_SECS;
421*1c60b9acSAndroid Build Coastguard Worker 				goto get_ipv4;
422*1c60b9acSAndroid Build Coastguard Worker 
423*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_DNSERVER:
424*1c60b9acSAndroid Build Coastguard Worker 				if (l & 3)
425*1c60b9acSAndroid Build Coastguard Worker 					break;
426*1c60b9acSAndroid Build Coastguard Worker 				m = LWSDH_SA46_DNS_SRV_1;
427*1c60b9acSAndroid Build Coastguard Worker 				while (l && m - LWSDH_SA46_DNS_SRV_1 < 4) {
428*1c60b9acSAndroid Build Coastguard Worker 					lws_sa46_set_ipv4(r, (unsigned int)m++, p);
429*1c60b9acSAndroid Build Coastguard Worker 					l = (uint8_t)(l - 4);
430*1c60b9acSAndroid Build Coastguard Worker 					p += 4;
431*1c60b9acSAndroid Build Coastguard Worker 				}
432*1c60b9acSAndroid Build Coastguard Worker 				break;
433*1c60b9acSAndroid Build Coastguard Worker 
434*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_DOMAIN_NAME:
435*1c60b9acSAndroid Build Coastguard Worker 				m = l;
436*1c60b9acSAndroid Build Coastguard Worker 				if (m > (int)sizeof(r->is.domain) - 1)
437*1c60b9acSAndroid Build Coastguard Worker 					m = sizeof(r->is.domain) - 1;
438*1c60b9acSAndroid Build Coastguard Worker 				lws_strnncpy(r->is.domain, (const char *)p,
439*1c60b9acSAndroid Build Coastguard Worker 					 (unsigned int)m, sizeof(r->is.domain));
440*1c60b9acSAndroid Build Coastguard Worker 				break;
441*1c60b9acSAndroid Build Coastguard Worker 
442*1c60b9acSAndroid Build Coastguard Worker 			case LWSDHC4POPT_MESSAGE_TYPE:
443*1c60b9acSAndroid Build Coastguard Worker 				/*
444*1c60b9acSAndroid Build Coastguard Worker 				 * Confirm this is the right message
445*1c60b9acSAndroid Build Coastguard Worker 				 * for the state of the negotiation
446*1c60b9acSAndroid Build Coastguard Worker 				 */
447*1c60b9acSAndroid Build Coastguard Worker 				if (r->state == LDHC_INIT && *p != LWSDHC4POFFER)
448*1c60b9acSAndroid Build Coastguard Worker 					goto broken;
449*1c60b9acSAndroid Build Coastguard Worker 				if (r->state == LDHC_REQUESTING &&
450*1c60b9acSAndroid Build Coastguard Worker 				    *p != LWSDHC4PACK)
451*1c60b9acSAndroid Build Coastguard Worker 					goto broken;
452*1c60b9acSAndroid Build Coastguard Worker 				break;
453*1c60b9acSAndroid Build Coastguard Worker 
454*1c60b9acSAndroid Build Coastguard Worker 			default:
455*1c60b9acSAndroid Build Coastguard Worker 				break;
456*1c60b9acSAndroid Build Coastguard Worker 			}
457*1c60b9acSAndroid Build Coastguard Worker 
458*1c60b9acSAndroid Build Coastguard Worker 			p += l;
459*1c60b9acSAndroid Build Coastguard Worker 			continue;
460*1c60b9acSAndroid Build Coastguard Worker get_ipv4:
461*1c60b9acSAndroid Build Coastguard Worker 			if (l >= 4)
462*1c60b9acSAndroid Build Coastguard Worker 				r->is.nums[n] = ntohl(lws_ser_ru32be(p));
463*1c60b9acSAndroid Build Coastguard Worker 			p += l;
464*1c60b9acSAndroid Build Coastguard Worker 			continue;
465*1c60b9acSAndroid Build Coastguard Worker broken:
466*1c60b9acSAndroid Build Coastguard Worker 			memset(r->is.sa46, 0, sizeof(r->is.sa46));
467*1c60b9acSAndroid Build Coastguard Worker 			break;
468*1c60b9acSAndroid Build Coastguard Worker 		}
469*1c60b9acSAndroid Build Coastguard Worker 
470*1c60b9acSAndroid Build Coastguard Worker #if defined(_DEBUG)
471*1c60b9acSAndroid Build Coastguard Worker 		/* dump what we have parsed out */
472*1c60b9acSAndroid Build Coastguard Worker 
473*1c60b9acSAndroid Build Coastguard Worker 		for (n = 0; n < (int)_LWSDH_NUMS_COUNT; n++) {
474*1c60b9acSAndroid Build Coastguard Worker 			m = (int)ntohl(r->is.nums[n]);
475*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: %d: 0x%x\n", __func__, n, m);
476*1c60b9acSAndroid Build Coastguard Worker 		}
477*1c60b9acSAndroid Build Coastguard Worker 
478*1c60b9acSAndroid Build Coastguard Worker 		for (n = 0; n < (int)_LWSDH_SA46_COUNT; n++) {
479*1c60b9acSAndroid Build Coastguard Worker 			lws_sa46_write_numeric_address(&r->is.sa46[n],
480*1c60b9acSAndroid Build Coastguard Worker 						       (char *)pkt, 48);
481*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: %d: %s\n", __func__, n, pkt);
482*1c60b9acSAndroid Build Coastguard Worker 		}
483*1c60b9acSAndroid Build Coastguard Worker #endif
484*1c60b9acSAndroid Build Coastguard Worker 
485*1c60b9acSAndroid Build Coastguard Worker 		/*
486*1c60b9acSAndroid Build Coastguard Worker 		 * Having seen everything in there... do we really feel
487*1c60b9acSAndroid Build Coastguard Worker 		 * we could use it?  Everything critical is there?
488*1c60b9acSAndroid Build Coastguard Worker 		 */
489*1c60b9acSAndroid Build Coastguard Worker 
490*1c60b9acSAndroid Build Coastguard Worker 		if (!r->is.sa46[LWSDH_SA46_IP].sa4.sin_family ||
491*1c60b9acSAndroid Build Coastguard Worker 		    !r->is.sa46[LWSDH_SA46_DHCP_SERVER].sa4.sin_family ||
492*1c60b9acSAndroid Build Coastguard Worker 		    !r->is.sa46[LWSDH_SA46_IPV4_ROUTER].sa4.sin_family ||
493*1c60b9acSAndroid Build Coastguard Worker 		    !r->is.nums[LWSDH_IPV4_SUBNET_MASK] ||
494*1c60b9acSAndroid Build Coastguard Worker 		    !r->is.nums[LWSDH_LEASE_SECS] ||
495*1c60b9acSAndroid Build Coastguard Worker 		    !r->is.sa46[LWSDH_SA46_DNS_SRV_1].sa4.sin_family) {
496*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: rejecting on incomplete\n", __func__);
497*1c60b9acSAndroid Build Coastguard Worker 			memset(r->is.sa46, 0, sizeof(r->is.sa46));
498*1c60b9acSAndroid Build Coastguard Worker 			break;
499*1c60b9acSAndroid Build Coastguard Worker 		}
500*1c60b9acSAndroid Build Coastguard Worker 
501*1c60b9acSAndroid Build Coastguard Worker 		/*
502*1c60b9acSAndroid Build Coastguard Worker 		 * Network layout has to be internally consistent...
503*1c60b9acSAndroid Build Coastguard Worker 		 * DHCP server has to be reachable by broadcast and
504*1c60b9acSAndroid Build Coastguard Worker 		 * default route has to be on same subnet
505*1c60b9acSAndroid Build Coastguard Worker 		 */
506*1c60b9acSAndroid Build Coastguard Worker 
507*1c60b9acSAndroid Build Coastguard Worker 		if ((r->is.sa46[LWSDH_SA46_IP].sa4.sin_addr.s_addr &
508*1c60b9acSAndroid Build Coastguard Worker 					r->is.nums[LWSDH_IPV4_SUBNET_MASK]) !=
509*1c60b9acSAndroid Build Coastguard Worker 		    (r->is.sa46[LWSDH_SA46_DHCP_SERVER].sa4.sin_addr.s_addr &
510*1c60b9acSAndroid Build Coastguard Worker 				        r->is.nums[LWSDH_IPV4_SUBNET_MASK])) {
511*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: rejecting on srv %x reachable on mask %x\n",
512*1c60b9acSAndroid Build Coastguard Worker 					__func__, r->is.sa46[LWSDH_SA46_IP].sa4.sin_addr.s_addr,
513*1c60b9acSAndroid Build Coastguard Worker 					r->is.nums[LWSDH_IPV4_SUBNET_MASK]);
514*1c60b9acSAndroid Build Coastguard Worker 			break;
515*1c60b9acSAndroid Build Coastguard Worker 		}
516*1c60b9acSAndroid Build Coastguard Worker 
517*1c60b9acSAndroid Build Coastguard Worker 		if (r->state == LDHC_INIT) {
518*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: moving to REQ\n", __func__);
519*1c60b9acSAndroid Build Coastguard Worker 			r->state = LDHC_REQUESTING;
520*1c60b9acSAndroid Build Coastguard Worker 			lws_callback_on_writable(r->wsi_raw);
521*1c60b9acSAndroid Build Coastguard Worker 			//break;
522*1c60b9acSAndroid Build Coastguard Worker 		}
523*1c60b9acSAndroid Build Coastguard Worker 
524*1c60b9acSAndroid Build Coastguard Worker 		return 0;
525*1c60b9acSAndroid Build Coastguard Worker 
526*1c60b9acSAndroid Build Coastguard Worker 	default:
527*1c60b9acSAndroid Build Coastguard Worker 		break;
528*1c60b9acSAndroid Build Coastguard Worker 	}
529*1c60b9acSAndroid Build Coastguard Worker 
530*1c60b9acSAndroid Build Coastguard Worker 	return 1;
531*1c60b9acSAndroid Build Coastguard Worker }
532*1c60b9acSAndroid Build Coastguard Worker 
533