1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * lws-minimal-secure-streams-seq
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Written in 2010-2020 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker  * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker  *
9*1c60b9acSAndroid Build Coastguard Worker  *
10*1c60b9acSAndroid Build Coastguard Worker  * This demonstrates the a minimal http client using secure streams api.
11*1c60b9acSAndroid Build Coastguard Worker  *
12*1c60b9acSAndroid Build Coastguard Worker  * It visits https://warmcat.com/ and receives the html page there.
13*1c60b9acSAndroid Build Coastguard Worker  *
14*1c60b9acSAndroid Build Coastguard Worker  * This is the "secure streams" api equivalent of minimal-http-client...
15*1c60b9acSAndroid Build Coastguard Worker  * it shows how to use a sequencer to make it easy to build more complex
16*1c60b9acSAndroid Build Coastguard Worker  * schemes on top of this example.
17*1c60b9acSAndroid Build Coastguard Worker  *
18*1c60b9acSAndroid Build Coastguard Worker  * The layering looks like this
19*1c60b9acSAndroid Build Coastguard Worker  *
20*1c60b9acSAndroid Build Coastguard Worker  *                        lifetime
21*1c60b9acSAndroid Build Coastguard Worker  *
22*1c60b9acSAndroid Build Coastguard Worker  * ------   app   ------  process
23*1c60b9acSAndroid Build Coastguard Worker  * ----  sequencer  ----  process
24*1c60b9acSAndroid Build Coastguard Worker  * --- secure stream ---  process
25*1c60b9acSAndroid Build Coastguard Worker  * -------  wsi  -------  connection
26*1c60b9acSAndroid Build Coastguard Worker  *
27*1c60b9acSAndroid Build Coastguard Worker  * see minimal-secure-streams for a similar example without the sequencer.
28*1c60b9acSAndroid Build Coastguard Worker  */
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
31*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
32*1c60b9acSAndroid Build Coastguard Worker #include <signal.h>
33*1c60b9acSAndroid Build Coastguard Worker 
34*1c60b9acSAndroid Build Coastguard Worker static int interrupted, bad = 1, flag_conn_fail, flag_h1post;
35*1c60b9acSAndroid Build Coastguard Worker static const char * const default_ss_policy =
36*1c60b9acSAndroid Build Coastguard Worker 	"{"
37*1c60b9acSAndroid Build Coastguard Worker 	  "\"release\":"			"\"01234567\","
38*1c60b9acSAndroid Build Coastguard Worker 	  "\"product\":"			"\"myproduct\","
39*1c60b9acSAndroid Build Coastguard Worker 	  "\"schema-version\":"			"1,"
40*1c60b9acSAndroid Build Coastguard Worker 	  "\"retry\": ["	/* named backoff / retry strategies */
41*1c60b9acSAndroid Build Coastguard Worker 		"{\"default\": {"
42*1c60b9acSAndroid Build Coastguard Worker 			"\"backoff\": ["	 "1000,"
43*1c60b9acSAndroid Build Coastguard Worker 						 "2000,"
44*1c60b9acSAndroid Build Coastguard Worker 						 "3000,"
45*1c60b9acSAndroid Build Coastguard Worker 						 "5000,"
46*1c60b9acSAndroid Build Coastguard Worker 						"10000"
47*1c60b9acSAndroid Build Coastguard Worker 				"],"
48*1c60b9acSAndroid Build Coastguard Worker 			"\"conceal\":"		"5,"
49*1c60b9acSAndroid Build Coastguard Worker 			"\"jitterpc\":"		"20,"
50*1c60b9acSAndroid Build Coastguard Worker 			"\"svalidping\":"	"300,"
51*1c60b9acSAndroid Build Coastguard Worker 			"\"svalidhup\":"	"310"
52*1c60b9acSAndroid Build Coastguard Worker 		"}}"
53*1c60b9acSAndroid Build Coastguard Worker 	  "],"
54*1c60b9acSAndroid Build Coastguard Worker 	  "\"certs\": [" /* named individual certificates in BASE64 DER */
55*1c60b9acSAndroid Build Coastguard Worker 		/*
56*1c60b9acSAndroid Build Coastguard Worker 		 * Need to be in order from root cert... notice sometimes as
57*1c60b9acSAndroid Build Coastguard Worker 		 * with Let's Encrypt there are multiple possible validation
58*1c60b9acSAndroid Build Coastguard Worker 		 * paths, all the pieces for one validation path must be
59*1c60b9acSAndroid Build Coastguard Worker 		 * given, excluding the server cert itself.  Let's Encrypt
60*1c60b9acSAndroid Build Coastguard Worker 		 * intermediate is signed by their ISRG Root CA but also is
61*1c60b9acSAndroid Build Coastguard Worker 		 * cross-signed by an IdenTrust intermediate that's widely
62*1c60b9acSAndroid Build Coastguard Worker 		 * deployed in browsers.  We use the ISRG path because that
63*1c60b9acSAndroid Build Coastguard Worker 		 * way we can skip the extra IdenTrust root cert.
64*1c60b9acSAndroid Build Coastguard Worker 		 */
65*1c60b9acSAndroid Build Coastguard Worker 		"{\"isrg_root_x1\": \""
66*1c60b9acSAndroid Build Coastguard Worker 	"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw"
67*1c60b9acSAndroid Build Coastguard Worker 	"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh"
68*1c60b9acSAndroid Build Coastguard Worker 	"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4"
69*1c60b9acSAndroid Build Coastguard Worker 	"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu"
70*1c60b9acSAndroid Build Coastguard Worker 	"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY"
71*1c60b9acSAndroid Build Coastguard Worker 	"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc"
72*1c60b9acSAndroid Build Coastguard Worker 	"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+"
73*1c60b9acSAndroid Build Coastguard Worker 	"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U"
74*1c60b9acSAndroid Build Coastguard Worker 	"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW"
75*1c60b9acSAndroid Build Coastguard Worker 	"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH"
76*1c60b9acSAndroid Build Coastguard Worker 	"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC"
77*1c60b9acSAndroid Build Coastguard Worker 	"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv"
78*1c60b9acSAndroid Build Coastguard Worker 	"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn"
79*1c60b9acSAndroid Build Coastguard Worker 	"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn"
80*1c60b9acSAndroid Build Coastguard Worker 	"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw"
81*1c60b9acSAndroid Build Coastguard Worker 	"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI"
82*1c60b9acSAndroid Build Coastguard Worker 	"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV"
83*1c60b9acSAndroid Build Coastguard Worker 	"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq"
84*1c60b9acSAndroid Build Coastguard Worker 	"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL"
85*1c60b9acSAndroid Build Coastguard Worker 	"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ"
86*1c60b9acSAndroid Build Coastguard Worker 	"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK"
87*1c60b9acSAndroid Build Coastguard Worker 	"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5"
88*1c60b9acSAndroid Build Coastguard Worker 	"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur"
89*1c60b9acSAndroid Build Coastguard Worker 	"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC"
90*1c60b9acSAndroid Build Coastguard Worker 	"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc"
91*1c60b9acSAndroid Build Coastguard Worker 	"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq"
92*1c60b9acSAndroid Build Coastguard Worker 	"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA"
93*1c60b9acSAndroid Build Coastguard Worker 	"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d"
94*1c60b9acSAndroid Build Coastguard Worker 	"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc="
95*1c60b9acSAndroid Build Coastguard Worker 		  "\"}"
96*1c60b9acSAndroid Build Coastguard Worker 	  "],"
97*1c60b9acSAndroid Build Coastguard Worker 	  "\"trust_stores\": [" /* named cert chains */
98*1c60b9acSAndroid Build Coastguard Worker 		"{"
99*1c60b9acSAndroid Build Coastguard Worker 			"\"name\": \"le_via_isrg\","
100*1c60b9acSAndroid Build Coastguard Worker 			"\"stack\": ["
101*1c60b9acSAndroid Build Coastguard Worker 				"\"isrg_root_x1\""
102*1c60b9acSAndroid Build Coastguard Worker 			"]"
103*1c60b9acSAndroid Build Coastguard Worker 		"}"
104*1c60b9acSAndroid Build Coastguard Worker 	  "],"
105*1c60b9acSAndroid Build Coastguard Worker 	  "\"s\": [" /* the supported stream types */
106*1c60b9acSAndroid Build Coastguard Worker 		"{\"mintest\": {"
107*1c60b9acSAndroid Build Coastguard Worker 			"\"endpoint\":"		"\"warmcat.com\","
108*1c60b9acSAndroid Build Coastguard Worker 			"\"port\":"		"443,"
109*1c60b9acSAndroid Build Coastguard Worker 			"\"protocol\":"		"\"h1\","
110*1c60b9acSAndroid Build Coastguard Worker 			"\"http_method\":"	"\"GET\","
111*1c60b9acSAndroid Build Coastguard Worker 			"\"http_url\":"		"\"index.html\","
112*1c60b9acSAndroid Build Coastguard Worker 			"\"plugins\":"		"[],"
113*1c60b9acSAndroid Build Coastguard Worker 			"\"tls\":"		"true,"
114*1c60b9acSAndroid Build Coastguard Worker 			"\"opportunistic\":"	"true,"
115*1c60b9acSAndroid Build Coastguard Worker 			"\"retry\":"		"\"default\","
116*1c60b9acSAndroid Build Coastguard Worker 			"\"tls_trust_store\":"	"\"le_via_isrg\""
117*1c60b9acSAndroid Build Coastguard Worker 		"}},"
118*1c60b9acSAndroid Build Coastguard Worker 		"{\"mintest-fail\": {"
119*1c60b9acSAndroid Build Coastguard Worker 			"\"endpoint\":"		"\"warmcat.com\","
120*1c60b9acSAndroid Build Coastguard Worker 			"\"port\":"		"22,"
121*1c60b9acSAndroid Build Coastguard Worker 			"\"protocol\":"		"\"h1\","
122*1c60b9acSAndroid Build Coastguard Worker 			"\"http_method\":"	"\"GET\","
123*1c60b9acSAndroid Build Coastguard Worker 			"\"http_url\":"		"\"index.html\","
124*1c60b9acSAndroid Build Coastguard Worker 			"\"plugins\":"		"[],"
125*1c60b9acSAndroid Build Coastguard Worker 			"\"tls\":"		"true,"
126*1c60b9acSAndroid Build Coastguard Worker 			"\"opportunistic\":"	"true,"
127*1c60b9acSAndroid Build Coastguard Worker 			"\"retry\":"		"\"default\","
128*1c60b9acSAndroid Build Coastguard Worker 			"\"tls_trust_store\":"	"\"le_via_isrg\""
129*1c60b9acSAndroid Build Coastguard Worker 		"}},"
130*1c60b9acSAndroid Build Coastguard Worker 		"{\"minpost\": {"
131*1c60b9acSAndroid Build Coastguard Worker 			"\"endpoint\":"		"\"warmcat.com\","
132*1c60b9acSAndroid Build Coastguard Worker 			"\"port\":"		"443,"
133*1c60b9acSAndroid Build Coastguard Worker 			"\"protocol\":"		"\"h1\","
134*1c60b9acSAndroid Build Coastguard Worker 			"\"http_method\":"	"\"POST\","
135*1c60b9acSAndroid Build Coastguard Worker 			"\"http_url\":"		"\"testserver/formtest\","
136*1c60b9acSAndroid Build Coastguard Worker 			"\"plugins\":"		"[],"
137*1c60b9acSAndroid Build Coastguard Worker 			"\"tls\":"		"true,"
138*1c60b9acSAndroid Build Coastguard Worker 			"\"opportunistic\":"	"true,"
139*1c60b9acSAndroid Build Coastguard Worker 			"\"retry\":"		"\"default\","
140*1c60b9acSAndroid Build Coastguard Worker 			"\"tls_trust_store\":"	"\"le_via_isrg\""
141*1c60b9acSAndroid Build Coastguard Worker 		"}}"
142*1c60b9acSAndroid Build Coastguard Worker 	  "]"
143*1c60b9acSAndroid Build Coastguard Worker 	"}"
144*1c60b9acSAndroid Build Coastguard Worker ;
145*1c60b9acSAndroid Build Coastguard Worker 
146*1c60b9acSAndroid Build Coastguard Worker typedef struct myss {
147*1c60b9acSAndroid Build Coastguard Worker 	struct lws_ss_handle 	*ss;
148*1c60b9acSAndroid Build Coastguard Worker 	void			*opaque_data;
149*1c60b9acSAndroid Build Coastguard Worker 	/* ... application specific state ... */
150*1c60b9acSAndroid Build Coastguard Worker } myss_t;
151*1c60b9acSAndroid Build Coastguard Worker 
152*1c60b9acSAndroid Build Coastguard Worker /* secure streams payload interface */
153*1c60b9acSAndroid Build Coastguard Worker 
154*1c60b9acSAndroid Build Coastguard Worker static lws_ss_state_return_t
myss_rx(void * userobj,const uint8_t * buf,size_t len,int flags)155*1c60b9acSAndroid Build Coastguard Worker myss_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
156*1c60b9acSAndroid Build Coastguard Worker {
157*1c60b9acSAndroid Build Coastguard Worker //	myss_t *m = (myss_t *)userobj;
158*1c60b9acSAndroid Build Coastguard Worker 
159*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags);
160*1c60b9acSAndroid Build Coastguard Worker 	lwsl_hexdump_info(buf, len);
161*1c60b9acSAndroid Build Coastguard Worker 
162*1c60b9acSAndroid Build Coastguard Worker 	/*
163*1c60b9acSAndroid Build Coastguard Worker 	 * If we received the whole message, we let the sequencer know it
164*1c60b9acSAndroid Build Coastguard Worker 	 * was a success
165*1c60b9acSAndroid Build Coastguard Worker 	 */
166*1c60b9acSAndroid Build Coastguard Worker 	if (flags & LWSSS_FLAG_EOM) {
167*1c60b9acSAndroid Build Coastguard Worker 		bad = 0;
168*1c60b9acSAndroid Build Coastguard Worker 		interrupted = 1;
169*1c60b9acSAndroid Build Coastguard Worker 	}
170*1c60b9acSAndroid Build Coastguard Worker 
171*1c60b9acSAndroid Build Coastguard Worker 	return 0;
172*1c60b9acSAndroid Build Coastguard Worker }
173*1c60b9acSAndroid Build Coastguard Worker 
174*1c60b9acSAndroid Build Coastguard Worker static lws_ss_state_return_t
myss_tx(void * userobj,lws_ss_tx_ordinal_t ord,uint8_t * buf,size_t * len,int * flags)175*1c60b9acSAndroid Build Coastguard Worker myss_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len,
176*1c60b9acSAndroid Build Coastguard Worker 	int *flags)
177*1c60b9acSAndroid Build Coastguard Worker {
178*1c60b9acSAndroid Build Coastguard Worker 	// myss_t *m = (myss_t *)userobj;
179*1c60b9acSAndroid Build Coastguard Worker 
180*1c60b9acSAndroid Build Coastguard Worker 	/* in this example, we don't send any payload */
181*1c60b9acSAndroid Build Coastguard Worker 
182*1c60b9acSAndroid Build Coastguard Worker 	return 0;
183*1c60b9acSAndroid Build Coastguard Worker }
184*1c60b9acSAndroid Build Coastguard Worker 
185*1c60b9acSAndroid Build Coastguard Worker static lws_ss_state_return_t
myss_state(void * userobj,void * sh,lws_ss_constate_t state,lws_ss_tx_ordinal_t ack)186*1c60b9acSAndroid Build Coastguard Worker myss_state(void *userobj, void *sh, lws_ss_constate_t state,
187*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_tx_ordinal_t ack)
188*1c60b9acSAndroid Build Coastguard Worker {
189*1c60b9acSAndroid Build Coastguard Worker 	myss_t *m = (myss_t *)userobj;
190*1c60b9acSAndroid Build Coastguard Worker 
191*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("%s: %s, ord 0x%x\n", __func__, lws_ss_state_name(state),
192*1c60b9acSAndroid Build Coastguard Worker 		  (unsigned int)ack);
193*1c60b9acSAndroid Build Coastguard Worker 
194*1c60b9acSAndroid Build Coastguard Worker 	switch (state) {
195*1c60b9acSAndroid Build Coastguard Worker 	case LWSSSCS_CREATING:
196*1c60b9acSAndroid Build Coastguard Worker 		return lws_ss_request_tx(m->ss);
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker 	case LWSSSCS_ALL_RETRIES_FAILED:
199*1c60b9acSAndroid Build Coastguard Worker 		/* if we're out of retries, we want to close the app and FAIL */
200*1c60b9acSAndroid Build Coastguard Worker 		interrupted = 1;
201*1c60b9acSAndroid Build Coastguard Worker 		break;
202*1c60b9acSAndroid Build Coastguard Worker 	default:
203*1c60b9acSAndroid Build Coastguard Worker 		break;
204*1c60b9acSAndroid Build Coastguard Worker 	}
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 	return 0;
207*1c60b9acSAndroid Build Coastguard Worker }
208*1c60b9acSAndroid Build Coastguard Worker 
209*1c60b9acSAndroid Build Coastguard Worker typedef enum {
210*1c60b9acSAndroid Build Coastguard Worker 	SEQ_IDLE,
211*1c60b9acSAndroid Build Coastguard Worker 	SEQ_TRY_CONNECT,
212*1c60b9acSAndroid Build Coastguard Worker 	SEQ_RECONNECT_WAIT,
213*1c60b9acSAndroid Build Coastguard Worker 	SEQ_CONNECTED,
214*1c60b9acSAndroid Build Coastguard Worker } myseq_state_t;
215*1c60b9acSAndroid Build Coastguard Worker 
216*1c60b9acSAndroid Build Coastguard Worker typedef struct myseq {
217*1c60b9acSAndroid Build Coastguard Worker 	struct lws_ss_handle	*ss;
218*1c60b9acSAndroid Build Coastguard Worker 
219*1c60b9acSAndroid Build Coastguard Worker 	myseq_state_t		state;
220*1c60b9acSAndroid Build Coastguard Worker 	int			http_resp;
221*1c60b9acSAndroid Build Coastguard Worker 
222*1c60b9acSAndroid Build Coastguard Worker 	uint16_t		try;
223*1c60b9acSAndroid Build Coastguard Worker } myseq_t;
224*1c60b9acSAndroid Build Coastguard Worker 
225*1c60b9acSAndroid Build Coastguard Worker /*
226*1c60b9acSAndroid Build Coastguard Worker  * This defines the sequence of things the test app does.
227*1c60b9acSAndroid Build Coastguard Worker  */
228*1c60b9acSAndroid Build Coastguard Worker 
229*1c60b9acSAndroid Build Coastguard Worker static lws_seq_cb_return_t
min_sec_str_sequencer_cb(struct lws_sequencer * seq,void * user,int event,void * v,void * a)230*1c60b9acSAndroid Build Coastguard Worker min_sec_str_sequencer_cb(struct lws_sequencer *seq, void *user, int event,
231*1c60b9acSAndroid Build Coastguard Worker 			 void *v, void *a)
232*1c60b9acSAndroid Build Coastguard Worker {
233*1c60b9acSAndroid Build Coastguard Worker 	struct myseq *s = (struct myseq *)user;
234*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_info_t ssi;
235*1c60b9acSAndroid Build Coastguard Worker 
236*1c60b9acSAndroid Build Coastguard Worker 	switch ((int)event) {
237*1c60b9acSAndroid Build Coastguard Worker 
238*1c60b9acSAndroid Build Coastguard Worker 	/* these messages are created just by virtue of being a sequencer */
239*1c60b9acSAndroid Build Coastguard Worker 
240*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_CREATED: /* our sequencer just got started */
241*1c60b9acSAndroid Build Coastguard Worker 		s->state = SEQ_IDLE;
242*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: LWSSEQ_CREATED\n", __func__);
243*1c60b9acSAndroid Build Coastguard Worker 
244*1c60b9acSAndroid Build Coastguard Worker 		/* We're making an outgoing secure stream ourselves */
245*1c60b9acSAndroid Build Coastguard Worker 
246*1c60b9acSAndroid Build Coastguard Worker 		memset(&ssi, 0, sizeof(ssi));
247*1c60b9acSAndroid Build Coastguard Worker 		ssi.handle_offset = offsetof(myss_t, ss);
248*1c60b9acSAndroid Build Coastguard Worker 		ssi.opaque_user_data_offset = offsetof(myss_t, opaque_data);
249*1c60b9acSAndroid Build Coastguard Worker 		ssi.rx = myss_rx;
250*1c60b9acSAndroid Build Coastguard Worker 		ssi.tx = myss_tx;
251*1c60b9acSAndroid Build Coastguard Worker 		ssi.state = myss_state;
252*1c60b9acSAndroid Build Coastguard Worker 		ssi.user_alloc = sizeof(myss_t);
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker 		/* requested to fail (to check backoff)? */
255*1c60b9acSAndroid Build Coastguard Worker 		if (flag_conn_fail)
256*1c60b9acSAndroid Build Coastguard Worker 			ssi.streamtype = "mintest-fail";
257*1c60b9acSAndroid Build Coastguard Worker 		else
258*1c60b9acSAndroid Build Coastguard Worker 			/* request to check h1 POST */
259*1c60b9acSAndroid Build Coastguard Worker 			if (flag_h1post)
260*1c60b9acSAndroid Build Coastguard Worker 				ssi.streamtype = "minpost";
261*1c60b9acSAndroid Build Coastguard Worker 			else
262*1c60b9acSAndroid Build Coastguard Worker 				/* default to h1 GET */
263*1c60b9acSAndroid Build Coastguard Worker 				ssi.streamtype = "mintest";
264*1c60b9acSAndroid Build Coastguard Worker 
265*1c60b9acSAndroid Build Coastguard Worker 		if (lws_ss_create(lws_seq_get_context(seq), 0, &ssi, NULL,
266*1c60b9acSAndroid Build Coastguard Worker 				  &s->ss, seq, NULL)) {
267*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: failed to create secure stream\n",
268*1c60b9acSAndroid Build Coastguard Worker 				 __func__);
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker 			return LWSSEQ_RET_DESTROY;
271*1c60b9acSAndroid Build Coastguard Worker 		}
272*1c60b9acSAndroid Build Coastguard Worker 		break;
273*1c60b9acSAndroid Build Coastguard Worker 
274*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_DESTROYED:
275*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: LWSSEQ_DESTROYED\n", __func__);
276*1c60b9acSAndroid Build Coastguard Worker 		break;
277*1c60b9acSAndroid Build Coastguard Worker 
278*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_TIMED_OUT: /* current step timed out */
279*1c60b9acSAndroid Build Coastguard Worker 		if (s->state == SEQ_RECONNECT_WAIT)
280*1c60b9acSAndroid Build Coastguard Worker 			return lws_ss_request_tx(s->ss);
281*1c60b9acSAndroid Build Coastguard Worker 		break;
282*1c60b9acSAndroid Build Coastguard Worker 
283*1c60b9acSAndroid Build Coastguard Worker 	/*
284*1c60b9acSAndroid Build Coastguard Worker 	 * These messages are created because we have a secure stream that was
285*1c60b9acSAndroid Build Coastguard Worker 	 * bound to this sequencer at creation time.  It copies its state
286*1c60b9acSAndroid Build Coastguard Worker 	 * events to us as its sequencer parent.  v is the lws_ss_handle_t *
287*1c60b9acSAndroid Build Coastguard Worker 	 */
288*1c60b9acSAndroid Build Coastguard Worker 
289*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_CREATING:
290*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_CREATING\n", __func__);
291*1c60b9acSAndroid Build Coastguard Worker 		return lws_ss_request_tx(s->ss);
292*1c60b9acSAndroid Build Coastguard Worker 
293*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_DISCONNECTED:
294*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_DISCONNECTED\n", __func__);
295*1c60b9acSAndroid Build Coastguard Worker 		break;
296*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_UNREACHABLE:
297*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_UNREACHABLE\n", __func__);
298*1c60b9acSAndroid Build Coastguard Worker 		break;
299*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_AUTH_FAILED:
300*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_AUTH_FAILED\n", __func__);
301*1c60b9acSAndroid Build Coastguard Worker 		break;
302*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_CONNECTED:
303*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_CONNECTED\n", __func__);
304*1c60b9acSAndroid Build Coastguard Worker 		break;
305*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_CONNECTING:
306*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_CONNECTING\n", __func__);
307*1c60b9acSAndroid Build Coastguard Worker 		break;
308*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_DESTROYING:
309*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_DESTROYING\n", __func__);
310*1c60b9acSAndroid Build Coastguard Worker 		break;
311*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_POLL:
312*1c60b9acSAndroid Build Coastguard Worker 		/* somebody called lws_ss_poll() on the stream */
313*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_POLL\n", __func__);
314*1c60b9acSAndroid Build Coastguard Worker 		break;
315*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_ALL_RETRIES_FAILED:
316*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_ALL_RETRIES_FAILED\n", __func__);
317*1c60b9acSAndroid Build Coastguard Worker 		interrupted = 1;
318*1c60b9acSAndroid Build Coastguard Worker 		break;
319*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_QOS_ACK_REMOTE:
320*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_QOS_ACK_REMOTE\n", __func__);
321*1c60b9acSAndroid Build Coastguard Worker 		break;
322*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_SS_STATE_BASE + LWSSSCS_QOS_ACK_LOCAL:
323*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: seq LWSSSCS_QOS_ACK_LOCAL\n", __func__);
324*1c60b9acSAndroid Build Coastguard Worker 		break;
325*1c60b9acSAndroid Build Coastguard Worker 
326*1c60b9acSAndroid Build Coastguard Worker 	/*
327*1c60b9acSAndroid Build Coastguard Worker 	 * This is the message we send from the ss handler to inform the
328*1c60b9acSAndroid Build Coastguard Worker 	 * sequencer we had the payload properly
329*1c60b9acSAndroid Build Coastguard Worker 	 */
330*1c60b9acSAndroid Build Coastguard Worker 
331*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_USER_BASE:
332*1c60b9acSAndroid Build Coastguard Worker 		bad = 0;
333*1c60b9acSAndroid Build Coastguard Worker 		interrupted = 1;
334*1c60b9acSAndroid Build Coastguard Worker 		break;
335*1c60b9acSAndroid Build Coastguard Worker 
336*1c60b9acSAndroid Build Coastguard Worker 	default:
337*1c60b9acSAndroid Build Coastguard Worker 		break;
338*1c60b9acSAndroid Build Coastguard Worker 	}
339*1c60b9acSAndroid Build Coastguard Worker 
340*1c60b9acSAndroid Build Coastguard Worker 	return LWSSEQ_RET_CONTINUE;
341*1c60b9acSAndroid Build Coastguard Worker }
342*1c60b9acSAndroid Build Coastguard Worker 
343*1c60b9acSAndroid Build Coastguard Worker static void
sigint_handler(int sig)344*1c60b9acSAndroid Build Coastguard Worker sigint_handler(int sig)
345*1c60b9acSAndroid Build Coastguard Worker {
346*1c60b9acSAndroid Build Coastguard Worker 	interrupted = 1;
347*1c60b9acSAndroid Build Coastguard Worker }
348*1c60b9acSAndroid Build Coastguard Worker 
main(int argc,const char ** argv)349*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
350*1c60b9acSAndroid Build Coastguard Worker {
351*1c60b9acSAndroid Build Coastguard Worker 	int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
352*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_creation_info info;
353*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context;
354*1c60b9acSAndroid Build Coastguard Worker 	lws_seq_info_t i;
355*1c60b9acSAndroid Build Coastguard Worker 	const char *p;
356*1c60b9acSAndroid Build Coastguard Worker 	myseq_t *ms;
357*1c60b9acSAndroid Build Coastguard Worker 
358*1c60b9acSAndroid Build Coastguard Worker 	signal(SIGINT, sigint_handler);
359*1c60b9acSAndroid Build Coastguard Worker 
360*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-d")))
361*1c60b9acSAndroid Build Coastguard Worker 		logs = atoi(p);
362*1c60b9acSAndroid Build Coastguard Worker 
363*1c60b9acSAndroid Build Coastguard Worker 	lws_set_log_level(logs, NULL);
364*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("LWS minimal secure streams [-d<verbosity>][-f][--h1post]\n");
365*1c60b9acSAndroid Build Coastguard Worker 
366*1c60b9acSAndroid Build Coastguard Worker 	flag_conn_fail = !!lws_cmdline_option(argc, argv, "-f");
367*1c60b9acSAndroid Build Coastguard Worker 	flag_h1post = !!lws_cmdline_option(argc, argv, "--h1post");
368*1c60b9acSAndroid Build Coastguard Worker 
369*1c60b9acSAndroid Build Coastguard Worker 	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
370*1c60b9acSAndroid Build Coastguard Worker 
371*1c60b9acSAndroid Build Coastguard Worker 	info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
372*1c60b9acSAndroid Build Coastguard Worker 		       LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
373*1c60b9acSAndroid Build Coastguard Worker 	info.fd_limit_per_thread = 1 + 1 + 1;
374*1c60b9acSAndroid Build Coastguard Worker 	info.pss_policies_json = default_ss_policy;
375*1c60b9acSAndroid Build Coastguard Worker 	info.port = CONTEXT_PORT_NO_LISTEN;
376*1c60b9acSAndroid Build Coastguard Worker 
377*1c60b9acSAndroid Build Coastguard Worker 	context = lws_create_context(&info);
378*1c60b9acSAndroid Build Coastguard Worker 	if (!context) {
379*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("lws init failed\n");
380*1c60b9acSAndroid Build Coastguard Worker 		return 1;
381*1c60b9acSAndroid Build Coastguard Worker 	}
382*1c60b9acSAndroid Build Coastguard Worker 
383*1c60b9acSAndroid Build Coastguard Worker 	/*
384*1c60b9acSAndroid Build Coastguard Worker 	 * Create the sequencer that performs the steps of the test action
385*1c60b9acSAndroid Build Coastguard Worker 	 * from inside the event loop.
386*1c60b9acSAndroid Build Coastguard Worker 	 */
387*1c60b9acSAndroid Build Coastguard Worker 
388*1c60b9acSAndroid Build Coastguard Worker 	memset(&i, 0, sizeof(i));
389*1c60b9acSAndroid Build Coastguard Worker 	i.context	= context;
390*1c60b9acSAndroid Build Coastguard Worker 	i.user_size	= sizeof(myseq_t);
391*1c60b9acSAndroid Build Coastguard Worker 	i.puser		= (void **)&ms;
392*1c60b9acSAndroid Build Coastguard Worker 	i.cb		= min_sec_str_sequencer_cb;
393*1c60b9acSAndroid Build Coastguard Worker 	i.name		= "min-sec-stream-seq";
394*1c60b9acSAndroid Build Coastguard Worker 
395*1c60b9acSAndroid Build Coastguard Worker 	if (!lws_seq_create(&i)) {
396*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: failed to create sequencer\n", __func__);
397*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
398*1c60b9acSAndroid Build Coastguard Worker 	}
399*1c60b9acSAndroid Build Coastguard Worker 
400*1c60b9acSAndroid Build Coastguard Worker 	/* the event loop */
401*1c60b9acSAndroid Build Coastguard Worker 
402*1c60b9acSAndroid Build Coastguard Worker 	while (n >= 0 && !interrupted)
403*1c60b9acSAndroid Build Coastguard Worker 		n = lws_service(context, 0);
404*1c60b9acSAndroid Build Coastguard Worker 
405*1c60b9acSAndroid Build Coastguard Worker bail:
406*1c60b9acSAndroid Build Coastguard Worker 	lws_context_destroy(context);
407*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("Completed: %s\n", bad ? "failed" : "OK");
408*1c60b9acSAndroid Build Coastguard Worker 
409*1c60b9acSAndroid Build Coastguard Worker 	return bad;
410*1c60b9acSAndroid Build Coastguard Worker }
411