static void run_spdylay_frame_pack_settings(void) { spdylay_frame frame, oframe; uint8_t *buf = NULL; size_t buflen = 0; ssize_t framelen; spdylay_settings_entry iv[2], *iv_copy; int rv; iv[0].settings_id = SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH; iv[0].flags = SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE; iv[0].value = 256; iv[1].settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS; iv[1].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE; iv[1].value = 100; iv_copy = spdylay_frame_iv_copy(iv, 2); if(iv_copy == NULL) { goto iv_copy_fail; } spdylay_frame_settings_init(&frame.settings, SPDYLAY_PROTO_SPDY3, SPDYLAY_FLAG_SETTINGS_CLEAR_SETTINGS, iv_copy, 2); framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings); if(framelen < 0) { goto fail; } rv = spdylay_frame_unpack_settings(&oframe.settings, &buf[0], SPDYLAY_FRAME_HEAD_LENGTH, &buf[SPDYLAY_FRAME_HEAD_LENGTH], framelen-SPDYLAY_FRAME_HEAD_LENGTH); if(rv != 0) { goto fail; } spdylay_frame_settings_free(&oframe.settings); fail: free(buf); spdylay_frame_settings_free(&frame.settings); iv_copy_fail: ; }
int spdylay_submit_settings(spdylay_session *session, uint8_t flags, const spdylay_settings_entry *iv, size_t niv) { spdylay_frame *frame; spdylay_settings_entry *iv_copy; int check[SPDYLAY_SETTINGS_MAX+1]; size_t i; int r; memset(check, 0, sizeof(check)); for(i = 0; i < niv; ++i) { if(iv[i].settings_id > SPDYLAY_SETTINGS_MAX || iv[i].settings_id == 0 || check[iv[i].settings_id] == 1) { return SPDYLAY_ERR_INVALID_ARGUMENT; } else { check[iv[i].settings_id] = 1; } } frame = malloc(sizeof(spdylay_frame)); if(frame == NULL) { return SPDYLAY_ERR_NOMEM; } iv_copy = spdylay_frame_iv_copy(iv, niv); if(iv_copy == NULL) { free(frame); return SPDYLAY_ERR_NOMEM; } spdylay_frame_iv_sort(iv_copy, niv); spdylay_frame_settings_init(&frame->settings, session->version, flags, iv_copy, niv); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL); if(r == 0) { spdylay_session_update_local_settings(session, iv_copy, niv); } else { spdylay_frame_settings_free(&frame->settings); free(frame); } return r; }
static void run_spdylay_session_recv(void) { spdylay_session *session; spdylay_session_callbacks callbacks; spdylay_zlib deflater; spdylay_frame frame; uint8_t *buf = NULL, *nvbuf = NULL; size_t buflen = 0, nvbuflen = 0; ssize_t framelen; const char *nv[] = { ":host", "example.org", ":scheme", "https", NULL }; spdylay_settings_entry iv[2]; spdylay_mem_chunk proof; spdylay_mem_chunk *certs; size_t ncerts; my_user_data ud; data_feed df; int rv; memset(&callbacks, 0, sizeof(spdylay_session_callbacks)); callbacks.recv_callback = data_feed_recv_callback; ud.df = &df; spdylay_failmalloc_pause(); spdylay_zlib_deflate_hd_init(&deflater, SPDYLAY_PROTO_SPDY3); spdylay_session_server_new(&session, SPDYLAY_PROTO_SPDY3, &callbacks, &ud); spdylay_failmalloc_unpause(); /* SYN_STREAM */ spdylay_failmalloc_pause(); spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_PROTO_SPDY3, SPDYLAY_CTRL_FLAG_FIN, 1, 0, 2, spdylay_frame_nv_copy(nv)); framelen = spdylay_frame_pack_syn_stream(&buf, &buflen, &nvbuf, &nvbuflen, &frame.syn_stream, &deflater); spdylay_frame_syn_stream_free(&frame.syn_stream); data_feed_init(&df, buf, framelen); spdylay_failmalloc_unpause(); rv = spdylay_session_recv(session); if(rv != 0) { goto fail; } /* PING */ spdylay_failmalloc_pause(); spdylay_frame_ping_init(&frame.ping, SPDYLAY_PROTO_SPDY3, 1); framelen = spdylay_frame_pack_ping(&buf, &buflen, &frame.ping); spdylay_frame_ping_free(&frame.ping); data_feed_init(&df, buf, framelen); spdylay_failmalloc_unpause(); rv = spdylay_session_recv(session); if(rv != 0) { goto fail; } /* RST_STREAM */ spdylay_failmalloc_pause(); spdylay_frame_rst_stream_init(&frame.rst_stream, SPDYLAY_PROTO_SPDY3, 1, SPDYLAY_PROTOCOL_ERROR); framelen = spdylay_frame_pack_rst_stream(&buf, &buflen, &frame.rst_stream); spdylay_frame_rst_stream_free(&frame.rst_stream); spdylay_failmalloc_unpause(); rv = spdylay_session_recv(session); if(rv != 0) { goto fail; } /* SETTINGS */ spdylay_failmalloc_pause(); iv[0].settings_id = SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH; iv[0].flags = SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE; iv[0].value = 256; iv[1].settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS; iv[1].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE; iv[1].value = 100; spdylay_frame_settings_init(&frame.settings, SPDYLAY_PROTO_SPDY3, SPDYLAY_FLAG_SETTINGS_CLEAR_SETTINGS, spdylay_frame_iv_copy(iv, 2), 2); framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings); spdylay_frame_settings_free(&frame.settings); spdylay_failmalloc_unpause(); rv = spdylay_session_recv(session); if(rv != 0) { goto fail; } /* CREDENTIAL */ spdylay_failmalloc_pause(); proof.data = (uint8_t*)strcopy("PROOF"); proof.length = strlen("PROOF"); ncerts = 2; certs = malloc(sizeof(spdylay_mem_chunk)*ncerts); certs[0].data = (uint8_t*)strcopy("CERT0"); certs[0].length = strlen("CERT0"); certs[1].data = (uint8_t*)strcopy("CERT1"); certs[1].length = strlen("CERT1"); spdylay_frame_credential_init(&frame.credential, SPDYLAY_PROTO_SPDY3, 1, &proof, certs, ncerts); framelen = spdylay_frame_pack_credential(&buf, &buflen, &frame.credential); spdylay_frame_credential_free(&frame.credential); spdylay_failmalloc_unpause(); rv = spdylay_session_recv(session); if(rv != 0) { goto fail; } fail: free(buf); free(nvbuf); spdylay_session_del(session); spdylay_zlib_deflate_free(&deflater); }