int test_rtsp(void) { /* RTSP urls */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t rtsp[1] = { URL_INIT_AS(rtsp) }; url_t *u, url[1]; char *tst; char rtspurl[] = "rtsp://example.com:42/barfoo.rm"; char rtspuurl[] = "rtspu://example.com:42/barfoo.rm"; char rtsp2[sizeof(rtspurl) + 32]; BEGIN(); TEST_S(url_scheme(url_rtsp), "rtsp"); TEST_S(url_scheme(url_rtspu), "rtspu"); rtsp->url_root = 1; rtsp->url_host = "example.com"; rtsp->url_port = "42"; rtsp->url_path = "barfoo.rm"; TEST_1(tst = su_strdup(home, rtspurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(rtsp, url) == 0); TEST(url->url_type, url_rtsp); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_rtsp); TEST_1(url_cmp(rtsp, u) == 0); TEST(url_e(rtsp2, sizeof(rtsp2), u), strlen(rtspurl)); TEST_1(strcmp(rtsp2, rtspurl) == 0); TEST_SIZE(snprintf(rtsp2, sizeof(rtsp2), URL_PRINT_FORMAT, URL_PRINT_ARGS(rtsp)), strlen(rtspurl)); TEST_1(strcmp(rtsp2, rtspurl) == 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)rtspurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); rtsp->url_type = url_rtspu, rtsp->url_scheme = "rtspu"; TEST_1(tst = su_strdup(home, rtspuurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(rtsp, url) == 0); TEST(url->url_type, url_rtspu); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)rtspuurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); END(); }
/**Check that we support all features which UAC requires. * * The list of supported features is compared with the list of features * required by the UAC. If some features are not listed as supported, return * 420. If @a irq is non-NULL, the 420 response message is sent to the * client along with list of unsupported features in the @Unsupported * header, too. * * @param irq incoming transaction object (may be NULL). * @param sip contents of the SIP message * @param supported list of protocol features supported * @param tag, value, ... optional list of tagged arguments used * when responding to the transaction * * @return 0 if successful. * 420 if any of the required features is not supported. */ int nta_check_required(nta_incoming_t *irq, sip_t const *sip, sip_supported_t const *supported, tag_type_t tag, tag_value_t value, ...) { int status = 0; if (sip->sip_require) { su_home_t home[SU_HOME_AUTO_SIZE(512)]; sip_unsupported_t *us; su_home_auto(home, sizeof home); us = sip_has_unsupported(home, supported, sip->sip_require); if (us) { status = 420; if (irq) { ta_list ta; ta_start(ta, tag, value); nta_incoming_treply(irq, SIP_420_BAD_EXTENSION, SIPTAG_UNSUPPORTED(us), SIPTAG_SUPPORTED(supported), ta_tags(ta)); ta_end(ta); } } su_home_deinit(home); } return status; }
int test_ldap(void) { /* Test a LDAP url */ char ldapurl[] = "ldap://cn=Manager,o=nokia:secret@localhost:389/ou=devices,o=nokia"; url_t ldap[1] = { URL_INIT_AS(file) }; su_home_t home[1] = { SU_HOME_INIT(home) }; char *tst; url_t *u, url[1]; char buf1[sizeof(ldapurl) + 32]; char buf2[sizeof(ldapurl) + 32]; BEGIN(); ldap->url_type = url_unknown; ldap->url_scheme = "ldap"; /* TEST_S(url_scheme(url_ldap), "ldap"); */ TEST_1(tst = su_strdup(home, ldapurl)); TEST(url_d(url, tst), 0); TEST_S(url->url_user, "cn=Manager,o=nokia:secret"); /* TEST_S(url->url_password, "secret"); */ TEST_S(url->url_host, "localhost"); TEST_S(url->url_port, "389"); TEST_S(url->url_path, "ou=devices,o=nokia"); ldap->url_user = "******"; ldap->url_password = "******"; ldap->url_user = "******", ldap->url_password = NULL; ldap->url_host = "localhost"; ldap->url_port = "389"; ldap->url_path = "ou=devices,o=nokia"; TEST(url_cmp(ldap, url), 0); TEST(url->url_type, url_unknown); TEST_S(url->url_scheme, "ldap"); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_unknown); TEST_S(u->url_scheme, "ldap"); TEST(url_cmp(ldap, u), 0); TEST_SIZE(url_e(buf1, sizeof(buf1), u), strlen(ldapurl)); TEST_S(buf1, ldapurl); TEST_SIZE(snprintf(buf2, sizeof(buf2), URL_PRINT_FORMAT, URL_PRINT_ARGS(u)), strlen(ldapurl)); TEST_S(buf2, ldapurl); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)ldapurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); END(); }
int test_tel(void) { /* tel urls: RFC 3906 */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t tel[1] = { URL_INIT_AS(tel) }; url_t *u, url[1]; char *tst; char telurl[] = "tel:+12345678" ";param=1;param=2" "?From=foo@bar&To=bar@baz#unf"; char tel2[sizeof(telurl) + 32]; url_t *a, *b; BEGIN(); TEST_S(url_scheme(url_tel), "tel"); tel->url_user = "******"; tel->url_params = "param=1;param=2"; tel->url_headers = "From=foo@bar&To=bar@baz"; tel->url_fragment = "unf"; TEST_1(tst = su_strdup(home, telurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(tel, url) == 0); TEST_1(url_cmp(url_hdup(home, (url_t const *)"tel:+12345678" ";param=1;param=2" "?From=foo@bar&To=bar@baz#unf"), url) == 0); TEST(url->url_type, url_tel); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_tel); TEST_1(url_cmp(tel, u) == 0); TEST_SIZE(url_e(tel2, sizeof(tel2), u), strlen(telurl)); TEST_1(strcmp(tel2, telurl) == 0); TEST_SIZE(snprintf(tel2, sizeof(tel2), URL_PRINT_FORMAT, URL_PRINT_ARGS(tel)), strlen(telurl)); TEST_1(strcmp(tel2, telurl) == 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)telurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); a = url_hdup(home, (void *)"tel:+1.245.62357"); b = url_hdup(home, (void *)"tel:+(1).245.62357"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) == 0); TEST_1(url_cmp_all(a, b) == 0); su_home_deinit(home); END(); }
void pr_deinit(proxy_t *pr) { if (pr->pr_addrinfo) su_freeaddrinfo(pr->pr_addrinfo), pr->pr_addrinfo = NULL; if (pr->pr_root) su_root_destroy(pr->pr_root), pr->pr_root = NULL; su_home_deinit(pr->pr_home); su_deinit(); }
int test_tags(void) { url_t u0[1]; url_t *u1 = NULL; url_t const *u2 = (void *)-1; url_t const u3[1] = { URL_INIT_AS(sip) }; char c0[] = "http://www.nokia.com"; char const *c1 = "http://goodfeel.nokia.com"; char *c2 = "http://forum.nokia.com"; char const c3[] = "http://www.research.nokia.com"; url_string_t *us0 = NULL; tagi_t *lst, *dup; tag_value_t value; char *s; su_home_t home[1] = { SU_HOME_INIT(home) }; BEGIN(); TEST(t_scan(urltag_url, home, c0, &value), 0); TEST_S(s = url_as_string(home, (url_t *)value), c0); TEST(t_scan(urltag_url, home, c3, &value), 0); TEST_S(s = url_as_string(home, (url_t *)value), c3); TEST_1(url_d(u0, c0) == 0); lst = tl_list(URLTAG_URL(u0), URLTAG_URL(u1), URLTAG_URL(u2), URLTAG_URL(u3), URLTAG_URL(c0), URLTAG_URL(c1), URLTAG_URL(c2), URLTAG_URL(c3), URLTAG_URL(us0), TAG_NULL()); TEST_1(lst); dup = tl_adup(home, lst); tl_vfree(lst); su_free(home, dup); su_home_deinit(home); END(); }
static int test_strdupcat(void) { su_home_t home[1] = { SU_HOME_INIT(home) }; BEGIN(); TEST_S(su_strdup(home, "foo"), "foo"); TEST_S(su_strcat(home, "foo", "bar"), "foobar"); TEST_S(su_strndup(home, "foobar", 3), "foo"); TEST_S(su_strcat_all(home, NULL), ""); TEST_S(su_strcat_all(home, "a", "", "b", "", NULL), "ab"); su_home_deinit(home); END(); }
int test_fax(void) { /* fax urls */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t fax[1] = { URL_INIT_AS(fax) }; url_t *u, url[1]; char *tst; char faxurl[] = "fax:+12345678" ";param=1;param=2" "?From=foo@bar&To=bar@baz#unf"; char fax2[sizeof(faxurl) + 32]; BEGIN(); TEST_S(url_scheme(url_fax), "fax"); fax->url_user = "******"; fax->url_params = "param=1;param=2"; fax->url_headers = "From=foo@bar&To=bar@baz"; fax->url_fragment = "unf"; TEST_1(tst = su_strdup(home, faxurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(fax, url) == 0); TEST(url->url_type, url_fax); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_fax); TEST_1(url_cmp(fax, u) == 0); TEST_SIZE(url_e(fax2, sizeof(fax2), u), strlen(faxurl)); TEST_1(strcmp(fax2, faxurl) == 0); TEST_SIZE(snprintf(fax2, sizeof(fax2), URL_PRINT_FORMAT, URL_PRINT_ARGS(fax)), strlen(faxurl)); TEST_1(strcmp(fax2, faxurl) == 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)faxurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); END(); }
int test_modem(void) { /* modem urls */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t modem[1] = { URL_INIT_AS(modem) }; url_t *u, url[1]; char *tst; char modemurl[] = "modem:+12345678" ";param=1;param=2" "?From=foo@bar&To=bar@baz#unf"; char modem2[sizeof(modemurl) + 32]; BEGIN(); TEST_S(url_scheme(url_modem), "modem"); modem->url_user = "******"; modem->url_params = "param=1;param=2"; modem->url_headers = "From=foo@bar&To=bar@baz"; modem->url_fragment = "unf"; TEST_1(tst = su_strdup(home, modemurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(modem, url) == 0); TEST(url->url_type, url_modem); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_modem); TEST_1(url_cmp(modem, u) == 0); TEST_SIZE(url_e(modem2, sizeof(modem2), u), strlen(modemurl)); TEST_1(strcmp(modem2, modemurl) == 0); TEST_SIZE(snprintf(modem2, sizeof(modem2), URL_PRINT_FORMAT, URL_PRINT_ARGS(modem)), strlen(modemurl)); TEST_1(strcmp(modem2, modemurl) == 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)modemurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); END(); }
int test_wv(void) { /* wv urls */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t wv[1] = { URL_INIT_AS(wv) }; url_t *u, url[1]; char *tst; char wvurl[] = "wv:[email protected]"; char wv2[sizeof(wvurl) + 32]; BEGIN(); TEST_S(url_scheme(url_wv), "wv"); wv->url_user = "******"; wv->url_host = "imps.com"; TEST_1(tst = su_strdup(home, wvurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(wv, url) == 0); TEST_1(url_cmp(url_hdup(home, (void *)"wv:[email protected]"), url) == 0); TEST(url->url_type, url_wv); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_wv); TEST_1(url_cmp(wv, u) == 0); TEST_SIZE(url_e(wv2, sizeof(wv2), u), strlen(wvurl)); TEST_1(strcmp(wv2, wvurl) == 0); TEST_SIZE(snprintf(wv2, sizeof(wv2), URL_PRINT_FORMAT, URL_PRINT_ARGS(wv)), strlen(wvurl)); TEST_1(strcmp(wv2, wvurl) == 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)wvurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); TEST_1(u = url_hdup(home, (void*)"wv:/[email protected]")); TEST_S(u->url_user, "/managers"); su_home_deinit(home); END(); }
static void su_source_port_deinit(su_port_t *self) { su_base_port_deinit(self); g_static_mutex_free(self->sup_mutex); g_static_mutex_free(self->sup_obtained); if (self->sup_indices) free (self->sup_indices), self->sup_indices = NULL; if (self->sup_waits) free (self->sup_waits), self->sup_waits = NULL; if (self->sup_wait_cbs) free (self->sup_wait_cbs), self->sup_wait_cbs = NULL; if (self->sup_wait_args) free (self->sup_wait_args), self->sup_wait_args = NULL; if (self->sup_wait_roots) free (self->sup_wait_roots), self->sup_wait_roots = NULL; su_home_deinit(self->sup_base->sup_home); }
void nth_request_destroy(nth_request_t *req) { if (req == NULL) return; if (req->req_status < 200) nth_request_treply(req, HTTP_500_INTERNAL_SERVER, TAG_END()); req->req_destroyed = 1; if (req->req_in_callback) return; if (req->req_as) su_home_deinit(req->req_as->as_home); tport_decref(&req->req_tport), req->req_tport = NULL; msg_destroy(req->req_request), req->req_request = NULL; msg_destroy(req->req_response), req->req_response = NULL; su_free(req->req_server->srv_home, req); }
int test_file(void) { /* Test a url with path like file:/foo/bar */ char fileurl[] = "file:///foo/bar"; url_t file[1] = { URL_INIT_AS(file) }; su_home_t home[1] = { SU_HOME_INIT(home) }; char *tst; url_t *u, url[1]; char buf1[sizeof(fileurl) + 32]; char buf2[sizeof(fileurl) + 32]; BEGIN(); TEST_S(url_scheme(url_file), "file"); TEST_1(tst = su_strdup(home, fileurl)); TEST(url_d(url, tst), 0); TEST_S(url->url_host, ""); file->url_root = '/'; file->url_host = ""; file->url_path = "foo/bar"; TEST(url_cmp(file, url), 0); TEST(url->url_type, url_file); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_file); TEST(url_cmp(file, u), 0); TEST_SIZE(url_e(buf1, sizeof(buf1), u), strlen(fileurl)); TEST_S(buf1, fileurl); TEST_SIZE(snprintf(buf2, sizeof(buf2), URL_PRINT_FORMAT, URL_PRINT_ARGS(u)), strlen(fileurl)); TEST_S(buf2, fileurl); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)fileurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); END(); }
static int test_sprintf(char const *fmt, ...) { BEGIN(); su_home_t home[1] = { SU_HOME_INIT(home) }; va_list va; TEST_S(su_sprintf(home, "foo%s", "bar"), "foobar"); va_start(va, fmt); TEST_S(su_vsprintf(home, fmt, va), "foo.bar"); TEST_S(su_sprintf(home, "foo%200s", "bar"), "foo " " " " " " bar"); su_home_deinit(home); END(); }
static int test_lock(void) { su_home_t home[1] = { SU_HOME_INIT(home) }; BEGIN(); TEST(su_home_mutex_lock(home), -1); TEST(su_home_mutex_unlock(home), -1); TEST(su_home_lock(home), -1); TEST(su_home_trylock(home), -1); TEST(su_home_unlock(home), -1); TEST(su_home_init(home), 0); TEST(su_home_mutex_lock(home), 0); TEST(su_home_trylock(home), -1); TEST(su_home_mutex_unlock(home), 0); TEST(su_home_trylock(home), -1); TEST(su_home_threadsafe(home), 0); TEST(su_home_mutex_lock(home), 0); TEST(su_home_trylock(home), EBUSY); TEST(su_home_mutex_unlock(home), 0); TEST(su_home_lock(home), 0); TEST(su_home_trylock(home), EBUSY); TEST(su_home_unlock(home), 0); TEST(su_home_trylock(home), 0); TEST(su_home_unlock(home), 0); TEST_VOID(su_home_deinit(home)); END(); }
/** * Updates the modified copy of local SDP based * on application provided local SDP and remote SDP. */ static int offer_answer_step(soa_session_t *ss, enum offer_answer_action action, char const *by) { soa_static_session_t *sss = (soa_static_session_t *)ss; sdp_session_t *local = ss->ss_local->ssd_sdp; sdp_session_t local0[1]; sdp_session_t *user = ss->ss_user->ssd_sdp; unsigned user_version = ss->ss_user_version; sdp_session_t *remote = ss->ss_remote->ssd_sdp; unsigned remote_version = ss->ss_remote_version; int fresh = 0; sdp_origin_t o[1] = {{ sizeof(o) }}; sdp_connection_t *c, c0[1] = {{ sizeof(c0) }}; char c0_buffer[64]; sdp_time_t t[1] = {{ sizeof(t) }}; int *u2s = NULL, *s2u = NULL, *tbf; sdp_session_t *latest = NULL, *previous = NULL; char const *phrase = "Internal Media Error"; su_home_t tmphome[SU_HOME_AUTO_SIZE(8192)]; su_home_auto(tmphome, sizeof tmphome); SU_DEBUG_7(("soa_static_offer_answer_action(%p, %s): called\n", (void *)ss, by)); if (user == NULL) return soa_set_status(ss, 500, "No session set by user"); if (action == generate_offer) remote = NULL; else if (remote == NULL) return soa_set_status(ss, 500, "No remote SDP"); /* Pre-negotiation Step: Expand truncated remote SDP */ if (local && remote) switch (action) { case generate_answer: case process_answer: if (sdp_media_count(remote, sdp_media_any, "*", (sdp_proto_e)0, (sdp_text_t)0) < sdp_media_count(local, sdp_media_any, "*", (sdp_proto_e)0, (sdp_text_t)0)) { SU_DEBUG_5(("%s: remote %s is truncated: expanding\n", by, action == generate_answer ? "offer" : "answer")); remote = soa_sdp_expand_media(tmphome, remote, local); if (remote == NULL) return soa_set_status(ss, 500, "Cannot expand remote session"); } default: break; } /* Step A: Create local SDP session (based on user-supplied SDP) */ if (local == NULL) switch (action) { case generate_offer: case generate_answer: SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, "generating local description")); fresh = 1; local = local0; *local = *user, local->sdp_media = NULL; o->o_username = "******"; o->o_address = c0; c0->c_address = c0_buffer; if (!local->sdp_origin) local->sdp_origin = o; break; case process_answer: default: goto internal_error; } /* Step B: upgrade local SDP (add m= lines to it) */ switch (action) { case generate_offer: /* Upgrade local SDP based on user SDP */ if (local != local0 && ss->ss_local_user_version == user_version) break; if (local != local0) *local0 = *local, local = local0; SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, "upgrade with local description")); if (soa_sdp_upgrade(ss, tmphome, local, user, NULL, &u2s, &s2u) < 0) goto internal_error; break; case generate_answer: /* Upgrade local SDP based on remote SDP */ if (ss->ss_local_user_version == user_version && ss->ss_local_remote_version == remote_version) break; if (1) { if (local != local0) *local0 = *local, local = local0; SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, "upgrade with remote description")); if (soa_sdp_upgrade(ss, tmphome, local, user, remote, &u2s, &s2u) < 0) goto internal_error; } break; case process_answer: default: break; } /* Step C: reject media */ switch (action) { case generate_offer: /* Local media is marked as rejected already in upgrade phase */ break; case generate_answer: case process_answer: if (ss->ss_local_remote_version == remote_version) break; if (soa_sdp_reject_is_needed(local, remote)) { if (local != local0) { *local0 = *local, local = local0; #define DUP_LOCAL(local) \ do { \ if (!local->sdp_media) break; \ local->sdp_media = \ sdp_media_dup_all(tmphome, local->sdp_media, local); \ if (!local->sdp_media) \ goto internal_error; \ } while (0) DUP_LOCAL(local); } SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, "marking rejected media")); soa_sdp_reject(tmphome, local, remote); } break; default: break; } /* Step D: Set media mode bits */ switch (action) { int const *s2u_; case generate_offer: case generate_answer: case process_answer: s2u_ = s2u; if (!s2u_) s2u_ = sss->sss_s2u; if (soa_sdp_mode_set(user, s2u_, local, remote, ss->ss_hold, 1)) { if (local != local0) { *local0 = *local, local = local0; DUP_LOCAL(local); } soa_sdp_mode_set(user, s2u_, local, remote, ss->ss_hold, 0); } break; default: break; } /* Step E: Upgrade codecs by answer. */ switch (action) { case process_answer: /* Upgrade local SDP based on remote SDP */ if (ss->ss_local_remote_version == remote_version) break; if (1 /* We don't have good test for codecs */) { SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, "upgrade codecs with remote description")); if (local != local0) { *local0 = *local, local = local0; DUP_LOCAL(local); } soa_sdp_session_upgrade_rtpmaps(ss, local, remote); } break; case generate_offer: case generate_answer: default: break; } /* Step F0: Initialize o= line */ if (fresh) { if (user->sdp_origin) { o->o_username = user->sdp_origin->o_username; if (user->sdp_origin->o_address) o->o_address = user->sdp_origin->o_address; if (user->sdp_origin->o_id) o->o_id = user->sdp_origin->o_id; if (user->sdp_origin->o_version && user->sdp_origin->o_version != o->o_version) { o->o_version = user->sdp_origin->o_version; o->o_version--; } } if (soa_init_sdp_origin_with_session(ss, o, c0_buffer, local) < 0) { phrase = "Cannot Get IP Address for Session Description"; goto internal_error; } local->sdp_origin = o; } /* Step F: Update c= line(s) */ switch (action) { sdp_connection_t *user_c, *local_c; case generate_offer: case generate_answer: user_c = user->sdp_connection; if (!soa_check_sdp_connection(user_c)) user_c = NULL; local_c = local->sdp_connection; if (!soa_check_sdp_connection(local_c)) local_c = NULL; if (ss->ss_local_user_version != user_version || local_c == NULL || (user_c != NULL && sdp_connection_cmp(local_c, user_c))) { sdp_media_t *m; if (user_c) c = user_c; else c = local->sdp_origin->o_address; /* Every m= line (even rejected one) must have a c= line * or there must be a c= line at session level */ for (m = local->sdp_media; m; m = m->m_next) if (m->m_connections == NULL) break; if (m) { if (local != local0) { *local0 = *local, local = local0; DUP_LOCAL(local); } local->sdp_connection = c; } } break; default: break; } soa_description_free(ss, ss->ss_previous); su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL; su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL; if (u2s) { u2s = u2s_alloc(ss->ss_home, u2s); s2u = u2s_alloc(ss->ss_home, s2u); if (!u2s || !s2u) goto internal_error; } if (ss->ss_local->ssd_sdp != local && sdp_session_cmp(ss->ss_local->ssd_sdp, local)) { int bump; switch (action) { case generate_offer: bump = sdp_session_cmp(local, sss->sss_latest); break; case generate_answer: bump = 1; break; case process_answer: default: bump = 0; break; } if (bump) { /* Upgrade the version number */ if (local->sdp_origin != o) *o = *local->sdp_origin, local->sdp_origin = o; o->o_version++; } /* Do sanity checks for the created SDP */ if (!local->sdp_subject) /* s= is mandatory */ local->sdp_subject = "-"; if (!local->sdp_time) /* t= is mandatory */ local->sdp_time = t; if (action == generate_offer) { /* Keep a copy of previous session state */ int *previous_u2s = u2s_alloc(ss->ss_home, sss->sss_u2s); int *previous_s2u = u2s_alloc(ss->ss_home, sss->sss_s2u); if ((sss->sss_u2s && !previous_u2s) || (sss->sss_s2u && !previous_s2u)) goto internal_error; *ss->ss_previous = *ss->ss_local; memset(ss->ss_local, 0, (sizeof *ss->ss_local)); ss->ss_previous_user_version = ss->ss_local_user_version; ss->ss_previous_remote_version = ss->ss_local_remote_version; sss->sss_previous.u2s = previous_u2s; sss->sss_previous.s2u = previous_s2u; } SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, "storing local description")); /* Update the unparsed and pretty-printed descriptions */ if (soa_description_set(ss, ss->ss_local, local, NULL, 0) < 0) { if (action == generate_offer) { /* Remove 2nd reference to local session state */ memset(ss->ss_previous, 0, (sizeof *ss->ss_previous)); ss->ss_previous_user_version = 0; ss->ss_previous_remote_version = 0; su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL; su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL; } su_free(ss->ss_home, u2s), su_free(ss->ss_home, s2u); goto internal_error; } if (bump) { latest = sdp_session_dup(ss->ss_home, ss->ss_local->ssd_sdp); previous = sss->sss_latest; } } if (u2s) { tbf = sss->sss_u2s, sss->sss_u2s = u2s, su_free(ss->ss_home, tbf); tbf = sss->sss_s2u, sss->sss_s2u = s2u, su_free(ss->ss_home, tbf); } /* Update version numbers */ switch (action) { case generate_offer: ss->ss_local_user_version = user_version; sss->sss_latest = latest; break; case generate_answer: ss->ss_local_user_version = user_version; ss->ss_local_remote_version = remote_version; sss->sss_latest = latest; break; case process_answer: ss->ss_local_remote_version = remote_version; default: break; } if (previous) su_free(ss->ss_home, previous); su_home_deinit(tmphome); return 0; internal_error: su_home_deinit(tmphome); return soa_set_status(ss, 500, phrase); }
int test_sip(void) { /* sip urls */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t sip[1] = { URL_INIT_AS(sip) }; url_t *u, url[1]; char *tst, *s; char sipurl0[] = "sip:pekka%2Epessi@nokia%2Ecom;method=%4D%45%53%53%41%47%45" "?body=CANNED%20MSG"; char sipurl[] = "sip:user:pass@host:32;param=1" "?From=foo@bar&To=bar@baz#unf"; char sip2url[] = "sip:user/path;tel-param:pass@host:32;param=1%3d%3d1" "?From=foo@bar&body=CANNED%20MSG&To=bar@baz#unf"; char sip2[sizeof(sipurl) + 32]; char sipsurl[] = "sips:user:pass@host:32;param=1" "?From=foo@bar&To=bar@baz#unf"; size_t i, j; url_t *a, *b; BEGIN(); TEST_S(url_scheme(url_sip), "sip"); TEST_S(url_scheme(url_sips), "sips"); memset(url, 255, sizeof url); TEST(url_d(url, sipurl0), 0); TEST(url->url_type, url_sip); TEST(url->url_root, 0); TEST_S(url->url_scheme, "sip"); TEST_S(url->url_user, "pekka.pessi"); TEST_P(url->url_password, NULL); TEST_S(url->url_host, "nokia.com"); TEST_P(url->url_port, NULL); TEST_P(url->url_path, NULL); TEST_S(url->url_params, "method=MESSAGE"); TEST_S(url->url_headers, "body=CANNED%20MSG"); TEST_P(url->url_fragment, NULL); TEST_S(url_query_as_header_string(home, url->url_headers), "\n\nCANNED MSG"); sip->url_user = "******"; sip->url_password = "******"; sip->url_host = "host"; sip->url_port = "32"; sip->url_params = "param=1"; sip->url_headers = "From=foo@bar&To=bar@baz"; sip->url_fragment = "unf"; memset(url, 255, sizeof url); TEST_1(tst = su_strdup(home, sipurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(sip, url) == 0); TEST(url->url_type, url_sip); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_sip); TEST_1(url_cmp(sip, u) == 0); TEST(url_e(sip2, sizeof(sip2), u), strlen(sipurl)); TEST_1(strcmp(sip2, sipurl) == 0); TEST_SIZE(snprintf(sip2, sizeof(sip2), URL_PRINT_FORMAT, URL_PRINT_ARGS(sip)), strlen(sipurl)); TEST_1(strcmp(sip2, sipurl) == 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t const *)sipurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); TEST_1(tst = su_strdup(home, sip2url)); TEST_1(url_d(url, tst) == 0); TEST_S(url->url_user, "user/path;tel-param"); TEST_S(url->url_params, "param=1%3D%3D1"); TEST_S(url_query_as_header_string(home, url->url_headers), "From:foo@bar\nTo:bar@baz\n\nCANNED MSG"); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)sip2url, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); sip->url_type = url_sips; sip->url_scheme = "sips"; TEST_1(tst = su_strdup(home, sipsurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(sip, url) == 0); TEST(url->url_type, url_sips); /* Test url_dup() */ for (i = 0; i <= sizeof(sipsurl); i++) { char buf[sizeof(sipsurl) + 1]; url_t dst[1]; buf[i] = '\377'; TEST_SIZE(url_dup(buf, i, dst, url), sizeof(sipsurl) - 1 - strlen("sips")); TEST(buf[i], '\377'); } url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)sipsurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); u = url_hdup(home, (url_t*)"SIP:[email protected]:55"); TEST_1(u); TEST(u->url_type, url_sip); u = url_hdup(home, (url_t*)"SIP:[email protected]:"); TEST_1(u); TEST(u->url_type, url_sip); TEST_P(url_hdup(home, (url_t*)"sip:[email protected]::55"), NULL); TEST_P(url_hdup(home, (url_t*)"sip:[email protected]:55:"), NULL); TEST_P(url_hdup(home, (url_t*)"sip:[email protected]:sip"), NULL); u = url_hdup(home, (url_t*)"SIP:#**00**#;foo=/[email protected]"); TEST_1(u); TEST(u->url_type, url_sip); TEST_S(u->url_user, "#**00**#;foo=/bar"); TEST_1(!url_hdup(home, (url_t*)"SIP:#**00**#;foo=/bar@#127.0.0.1")); TEST_1(!url_hdup(home, (url_t*)"SIP:#**00**#;foo=/bar;127.0.0.1")); for (i = 32; i <= 256; i++) { char pu[512]; char param[512]; for (j = 0; j < i; j++) param[j] = 'x'; param[j] = '\0'; memcpy(param, "x=", 2); snprintf(pu, sizeof(pu), "sip:test@host;%s", param); u = url_hdup(home, (url_t*)pu); TEST_1(u); s = url_as_string(home, u); TEST_S(pu, s); } s = su_strdup(home, "ttl;transport=tcp;ttl=15;ttl=;method=INVITE;ttl"); TEST_1(s); s = url_strip_param_string(s, "ttl"); TEST_S(s, "transport=tcp;method=INVITE"); u = url_hdup(home, (void*)"sip:u:p@host:5060;maddr=127.0.0.1;transport=tcp"); TEST_1(u); TEST_1(url_have_transport(u)); TEST_1(url_strip_transport(u)); TEST_P(u->url_params, NULL); TEST_1(!url_have_transport(u)); u = url_hdup(home, (void*)"sip:u:p@host:5060;user=phone;ttl=1;isfocus"); TEST_1(u); TEST_1(url_have_transport(u)); TEST_1(url_strip_transport(u)); TEST_S(u->url_params, "user=phone;isfocus"); TEST_1(!url_have_transport(u)); u = url_hdup(home, (void*)"sip:u:p@host:5060;maddr=127.0.0.1;user=phone"); TEST_1(u); TEST_1(url_have_transport(u)); TEST_1(url_strip_transport(u)); TEST_S(u->url_params, "user=phone"); TEST_1(!url_have_transport(u)); u = url_hdup(home, (void*)"sip:u:p@host:5060;user=phone;transport=tcp"); TEST_1(u); TEST_1(url_have_transport(u)); TEST_1(url_strip_transport(u)); TEST_S(u->url_params, "user=phone"); TEST_1(!url_have_transport(u)); u = url_hdup(home, (void*)"sip:u:p@host;user=phone;;"); TEST_1(u); /* We don't have transport params */ TEST_1(!url_have_transport(u)); /* ...but we still strip empty params */ TEST_1(url_strip_transport(u)); TEST_S(u->url_params, "user=phone"); TEST_1(!url_have_transport(u)); u = url_hdup(home, (void*)"sip:u:p@host:5060;ttl=1;isfocus;transport=udp;"); TEST_1(u); TEST_1(url_have_transport(u)); TEST_1(url_strip_transport(u)); TEST_S(u->url_params, "isfocus"); TEST_1(!url_have_transport(u)); u = url_hdup(home, (void *)"sip:%22foo%[email protected]:5060"); TEST_1(u); TEST_S(u->url_user, "%22foo%22"); a = url_hdup(home, (void *)"sip:172.21.55.55:5060"); b = url_hdup(home, (void *)"sip:172.21.55.55"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) == 0); TEST(url_cmp_all(a, b), 0); a = url_hdup(home, (void *)"sips:172.21.55.55:5060"); b = url_hdup(home, (void *)"sips:172.21.55.55"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) != 0); TEST_1(url_cmp_all(a, b) < 0); a = url_hdup(home, (void *)"sips:172.21.55.55:5061"); b = url_hdup(home, (void *)"sips:172.21.55.55"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) == 0); TEST(url_cmp_all(a, b), 0); a = url_hdup(home, (void *)"sip:my.domain:5060"); b = url_hdup(home, (void *)"sip:my.domain"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) > 0); TEST_1(url_cmp_all(a, b) > 0); a = url_hdup(home, (void *)"sips:my.domain:5061"); b = url_hdup(home, (void *)"sips:my.domain"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) > 0); TEST_1(url_cmp_all(a, b) > 0); a = url_hdup(home, (void *)"sip:my.domain"); b = url_hdup(home, (void *)"SIP:MY.DOMAIN"); TEST_1(a); TEST_1(b); TEST_1(url_cmp(a, b) == 0); TEST_1(url_cmp_all(a, b) == 0); su_home_deinit(home); END(); }
void nua_stack_notifier(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *tags) { su_home_t home[1] = { SU_HOME_INIT(home) }; sip_event_t const *event = NULL; sip_content_type_t const *ct = NULL; sip_payload_t const *pl = NULL; url_string_t const *url = NULL; char const *event_s = NULL, *ct_s = NULL, *pl_s = NULL; nea_event_t *ev; int status = 900; char const *phrase = nua_internal_error; nua_stack_init_handle(nua, nh, tags); tl_gets(tags, NUTAG_URL_REF(url), SIPTAG_EVENT_REF(event), SIPTAG_EVENT_STR_REF(event_s), SIPTAG_CONTENT_TYPE_STR_REF(ct_s), SIPTAG_PAYLOAD_REF(pl), SIPTAG_PAYLOAD_STR_REF(pl_s), TAG_END()); if (!event && !event_s) status = 400, phrase = "Missing Event"; else if (!ct && !ct_s) status = 400, phrase = "Missing Content-Type"; else if (!nh->nh_notifier && !(nh->nh_notifier = nea_server_create(nua->nua_nta, nua->nua_root, url->us_url, NH_PGET(nh, max_subscriptions), NULL, nh, TAG_NEXT(tags)))) status = 900, phrase = nua_internal_error; else if (!event && !(event = sip_event_make(home, event_s))) status = 900, phrase = "Could not create an event header"; else if (!(ev = nh_notifier_event(nh, home, event, tags))) status = 900, phrase = "Could not create an event view"; else if (nea_server_update(nh->nh_notifier, ev, TAG_NEXT(tags)) < 0) status = 900, phrase = "No content for event"; else if (nea_server_notify(nh->nh_notifier, ev) < 0) status = 900, phrase = "Error when notifying watchers"; else nua_stack_tevent(nua, nh, NULL, e, status = SIP_200_OK, SIPTAG_EVENT(event), SIPTAG_CONTENT_TYPE(ct), TAG_END()); if (status != 200) nua_stack_event(nua, nh, NULL, e, status, phrase, NULL); su_home_deinit(home); }
static int test_auto(void) { BEGIN(); int i; su_home_t tmphome[SU_HOME_AUTO_SIZE(8000)]; char *b = NULL; su_home_stat_t hs[1]; TEST_1(!su_home_auto(tmphome, sizeof tmphome[0])); TEST_1(su_home_auto(tmphome, sizeof tmphome)); for (i = 0; i < 8192; i++) TEST_1(su_alloc(tmphome, 12)); TEST_VOID(su_home_deinit(tmphome)); TEST_1(su_home_auto(tmphome, sizeof tmphome)); su_home_init_stats(tmphome); for (i = 1; i < 8192; i++) { TEST_1(b = su_realloc(tmphome, b, i)); b[i - 1] = '\125'; } for (i = 1; i < 8192; i++) { TEST(b[i - 1], '\125'); } for (i = 1; i < 8192; i++) { TEST_1(b = su_realloc(tmphome, b, i)); b[i - 1] = '\125'; if ((i % 32) == 0) TEST_1(b = su_realloc(tmphome, b, 1)); } su_home_get_stats(tmphome, 0, hs, sizeof *hs); TEST64(hs->hs_allocs.hsa_preload + hs->hs_allocs.hsa_number, 8191 + 8191 + 8191 / 32); TEST64(hs->hs_frees.hsf_preload + hs->hs_frees.hsf_number, 8191 + 8191 + 8191 / 32 - 1); /* This test depends on macro SU_HOME_AUTO_SIZE() calculating offsetof(su_block_t, sub_nodes[7]) correctly with ((3 * sizeof (void *) + 4 * sizeof(unsigned) + 7 * (sizeof (long) + sizeof(void *)) + 7) */ TEST_1(hs->hs_frees.hsf_preload == hs->hs_allocs.hsa_preload); su_free(tmphome, b); for (i = 1; i < 8192; i++) TEST_1(b = su_alloc(tmphome, 1)); TEST_VOID(su_home_deinit(tmphome)); END(); }
/** Test basic memory home operations */ static int test_alloc(void) { exhome_t *h0, *h1, *h2, *h3; su_home_t home[1] = { SU_HOME_INIT(home) }; su_home_t home0[1]; enum { N = 40 }; void *m0[N], *m1[N], *m; char *c, *c0, *p0, *p1; int i; enum { destructed_once = 1 }; int d0, d1a, d1, d2, d3; BEGIN(); /* su_home_init() was not initializing suh_locks */ memset(home0, 0xff, sizeof home0); TEST(su_home_init(home0), 0); TEST_VOID(su_home_deinit(home0)); TEST_1(h0 = su_home_new(sizeof(*h0))); TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1))); d0 = d1a = d1 = d2 = d3 = 0; h0->p = &d0; h1->p = &d1a; TEST(su_home_destructor(h0->home, exdestructor), 0); TEST(su_home_destructor(h1->home, exdestructor), 0); TEST_1(h2 = su_home_ref(h0->home)); su_home_unref(h0->home); TEST(d0, 0); for (i = 0; i < 128; i++) TEST_1(su_alloc(h0->home, 16)); for (i = 0; i < 128; i++) TEST_1(su_alloc(h1->home, 16)); su_home_unref(h1->home); TEST(d1a, destructed_once); TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1))); TEST(su_home_destructor(h1->home, exdestructor), 0); h1->p = &d1; for (i = 0; i < 128; i++) TEST_1(su_alloc(h1->home, 16)); for (i = 0; i < 128; i++) TEST_1(su_alloc(h2->home, 16)); su_home_unref(h2->home); /* Should call destructor of cloned home, too */ TEST(d0, destructed_once); TEST(d1, destructed_once); TEST_1(h0 = su_home_new(sizeof(*h0))); TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1))); TEST_1(h2 = su_home_clone(h1->home, sizeof(*h2))); TEST_1(h3 = su_home_clone(h2->home, sizeof(*h3))); TEST(su_home_threadsafe(h0->home), 0); for (i = 0; i < N; i++) { TEST_1(m0[i] = su_zalloc(h3->home, 20)); TEST_1(m1[i] = su_zalloc(h2->home, 20)); } TEST_1(m = su_zalloc(h2->home, 20)); TEST_1(su_in_home(h2->home, m)); TEST_1(!su_in_home(h2->home, (char *)m + 1)); TEST_1(!su_in_home(h2->home, (void *)(intptr_t)su_in_home)); TEST_1(!su_in_home(h3->home, m)); TEST_1(!su_in_home(NULL, m)); TEST_1(!su_in_home(h3->home, NULL)); TEST(su_home_move(home, NULL), 0); TEST(su_home_move(NULL, home), 0); TEST(su_home_move(home, h3->home), 0); TEST(su_home_move(h2->home, h3->home), 0); TEST(su_home_move(h1->home, h2->home), 0); su_home_preload(home, 1, 1024 + 2 * 8); TEST_1(c = su_zalloc(home, 64)); p0 = c; p1 = c + 1024; c0 = c; TEST_P(c = su_realloc(home, c0, 127), c0); TEST_1(c = c0 = su_zalloc(home, 1024 - 128)); TEST_1(p0 <= c); TEST_1(c < p1); TEST_P(c = su_realloc(home, c, 128), c0); TEST_P(c = su_realloc(home, c, 1023 - 128), c0); TEST_P(c = su_realloc(home, c, 1024 - 128), c0); TEST_1(c = su_realloc(home, c, 1024)); TEST_1(c = su_realloc(home, c, 2 * 1024)); TEST_P(c = su_realloc(home, p0, 126), p0); TEST_1(c = su_realloc(home, p0, 1024)); TEST_P(c = su_realloc(home, c, 0), NULL); su_home_check(home); su_home_deinit(home); su_home_check(h2->home); su_home_zap(h2->home); su_home_check(h0->home); su_home_zap(h0->home); { su_home_t h1[1]; memset(h1, 0, sizeof h1); TEST(su_home_init(h1), 0); TEST(su_home_threadsafe(h1), 0); TEST_1(su_home_ref(h1)); TEST_1(su_home_ref(h1)); TEST(su_home_destructor(h1, test_destructor), 0); TEST_1(!su_home_unref(h1)); TEST_1(!su_home_unref(h1)); TEST_1(su_home_unref(h1)); TEST(h1->suh_size, 13); } /* Test su_home_parent() */ TEST_1(h0 = su_home_new(sizeof *h0)); TEST_1(h1 = su_home_clone(h0->home, sizeof *h1)); TEST_1(h2 = su_home_clone(h1->home, sizeof *h2)); TEST_1(h3 = su_home_clone(h2->home, sizeof *h3)); TEST_P(su_home_parent(h0->home), NULL); TEST_P(su_home_parent(h1->home), h0); TEST_P(su_home_parent(h2->home), h1); TEST_P(su_home_parent(h3->home), h2); TEST(su_home_move(h0->home, h1->home), 0); TEST_P(su_home_parent(h2->home), h0); TEST_P(su_home_parent(h3->home), h2); TEST(su_home_move(h0->home, h2->home), 0); TEST_P(su_home_parent(h3->home), h0); su_home_move(NULL, h0->home); TEST_P(su_home_parent(h0->home), NULL); TEST_P(su_home_parent(h1->home), NULL); TEST_P(su_home_parent(h2->home), NULL); TEST_P(su_home_parent(h3->home), NULL); su_home_unref(h0->home); su_home_unref(h1->home); su_home_unref(h2->home); su_home_unref(h3->home); END(); }
static int test_vectors(void) { su_home_t home[1] = { SU_HOME_INIT(home) }; su_vector_t *v, *w; test_data_t *data1, *data2, *data3, *data4; char foo[] = "foo"; char bar[] = "bar"; char baz[] = "baz"; void **a; int i; BEGIN(); TEST_1(v = su_vector_create(home, NULL)); TEST_1(su_vector_is_empty(v)); TEST(su_vector_append(v, foo), 0); TEST(su_vector_append(v, bar), 0); TEST(su_vector_insert(v, 0, baz), 0); TEST_P(su_vector_item(v, 0), baz); TEST_P(su_vector_item(v, 1), foo); TEST_P(su_vector_item(v, 2), bar); TEST_P(su_vector_item(v, 3), NULL); TEST_P(su_vector_item(v, (unsigned)-1), NULL); TEST_1(!su_vector_is_empty(v)); su_vector_destroy(v); TEST_1(v = su_vector_create(home, NULL)); TEST(su_vector_insert(v, 0, "j"), 0); TEST(su_vector_insert(v, 0, "i"), 0); TEST(su_vector_insert(v, 0, "h"), 0); TEST(su_vector_insert(v, 0, "g"), 0); TEST(su_vector_insert(v, 0, "f"), 0); TEST(su_vector_insert(v, 0, "e"), 0); TEST(su_vector_insert(v, 0, "d"), 0); TEST(su_vector_insert(v, 0, "c"), 0); TEST(su_vector_insert(v, 0, "b"), 0); TEST(su_vector_insert(v, 0, "a"), 0); TEST_SIZE(su_vector_len(v), 10); TEST_1(a = su_vector_get_array(v)); for (i = 0; i < 10; i++) { TEST_S(su_vector_item(v, i), a[i]); } TEST_P(su_vector_item(v, 10), NULL); TEST_P(a[10], NULL); TEST_1(w = su_vector_create(home, NULL)); TEST(su_vector_append(w, "a"), 0); TEST(su_vector_append(w, "b"), 0); TEST(su_vector_append(w, "c"), 0); TEST(su_vector_append(w, "d"), 0); TEST(su_vector_append(w, "e"), 0); TEST(su_vector_append(w, "f"), 0); TEST(su_vector_append(w, "g"), 0); TEST(su_vector_append(w, "h"), 0); TEST(su_vector_append(w, "i"), 0); TEST(su_vector_append(w, "j"), 0); TEST_SIZE(su_vector_len(w), 10); for (i = 0; i < 10; i++) { TEST_S(su_vector_item(v, i), a[i]); } su_vector_empty(w); TEST_1(su_vector_is_empty(w)); su_vector_destroy(v); su_vector_destroy(w); TEST_1(v = su_vector_create(home, test_vector_free)); data1 = su_home_clone(home, sizeof(test_data_t)); data1->data = 1; data2 = su_home_clone(home, sizeof(test_data_t)); data2->data = 2; data3 = su_home_clone(home, sizeof(test_data_t)); data3->data = 3; data4 = su_home_clone(home, sizeof(test_data_t)); data4->data = 4; TEST(su_vector_append(v, data1), 0); TEST(su_vector_append(v, data2), 0); TEST(su_vector_append(v, data3), 0); TEST(su_vector_append(v, data4), 0); TEST_SIZE(su_vector_len(v), 4); TEST_P(su_vector_item(v, 0), data1); TEST_P(su_vector_item(v, 1), data2); TEST_P(su_vector_item(v, 2), data3); TEST_P(su_vector_item(v, 3), data4); TEST(data1->data, 1); TEST(data2->data, 2); TEST(data3->data, 3); TEST(data4->data, 4); TEST(su_vector_remove(v, 2), 0); TEST_SIZE(su_vector_len(v), 3); TEST_P(su_vector_item(v, 0), data1); TEST_P(su_vector_item(v, 1), data2); TEST_P(su_vector_item(v, 2), data4); TEST(data1->data, 1); TEST(data2->data, 2); TEST(data4->data, 4); su_vector_destroy(v); su_home_check(home); su_home_deinit(home); END(); }
static int test_strlst(void) { su_home_t home[1] = { SU_HOME_INIT(home) }; su_strlst_t *l, *l1, *l2; char *s; char foo[] = "foo"; char bar[] = "bar"; char baz[] = "baz"; su_home_stat_t parent[1], kids[2]; BEGIN(); parent->hs_size = (sizeof parent); kids[0].hs_size = (sizeof kids[0]); kids[1].hs_size = (sizeof kids[1]); su_home_init_stats(home); /* Test API for invalid arguments */ TEST_1(l = su_strlst_create(NULL)); TEST_1(l2 = su_strlst_dup(home, l)); TEST_VOID(su_strlst_destroy(l2)); TEST_1(!su_strlst_dup(home, NULL)); TEST_1(l1 = su_strlst_copy(home, l)); TEST_VOID(su_strlst_destroy(l1)); TEST_1(!su_strlst_copy(home, NULL)); TEST_VOID(su_strlst_destroy(NULL)); TEST_VOID(su_strlst_destroy(l)); TEST_1(!su_strlst_dup_append(NULL, "aa")); TEST_1(!su_strlst_append(NULL, "bee")); TEST_1(!su_strlst_item(NULL, 1)); TEST_1(!su_strlst_set_item(NULL, 1, "cee")); TEST_1(!su_strlst_remove(NULL, 1)); TEST_S(s = su_strlst_join(NULL, home, "a"), ""); TEST_VOID(su_free(home, s)); TEST_1(!su_strlst_split(home, NULL, ".")); TEST_1(s = su_strdup(home, "aaa")); TEST_1(l = su_strlst_split(home, s, NULL)); TEST_S(su_strlst_item(l, 0), "aaa"); TEST_VOID(su_strlst_destroy(l)); TEST_VOID(su_free(home, s)); TEST_1(!su_strlst_dup_split(home, NULL, ".")); TEST_1(l1 = su_strlst_dup_split(home, "aaa", "")); TEST_S(su_strlst_item(l1, 0), "aaa"); TEST_VOID(su_strlst_destroy(l1)); TEST_SIZE(su_strlst_len(NULL), 0); TEST_1(!su_strlst_get_array(NULL)); TEST_VOID(su_strlst_free_array(NULL, NULL)); TEST_1(l = su_strlst_create(home)); TEST_VOID(su_strlst_free_array(l, NULL)); TEST_S(su_strlst_dup_append(l, "oh"), "oh"); TEST_VOID(su_strlst_free_array(l, NULL)); TEST_VOID(su_strlst_destroy(l)); /* Test functionality */ TEST_1(l = su_strlst_create(home)); su_home_init_stats(su_strlst_home(l)); TEST_S(su_strlst_join(l, home, "bar"), ""); TEST_S(su_strlst_append(l, foo), "foo"); TEST_S(su_strlst_dup_append(l, bar), "bar"); TEST_S(su_strlst_append(l, baz), "baz"); TEST_S((s = su_strlst_join(l, home, "!")), "foo!bar!baz"); TEST_S(su_strlst_item(l, 0), foo); TEST_S(su_strlst_item(l, 1), bar); TEST_S(su_strlst_item(l, 2), baz); TEST_P(su_strlst_item(l, 3), NULL); TEST_P(su_strlst_item(l, (unsigned)-1), NULL); TEST_1(l1 = su_strlst_copy(su_strlst_home(l), l)); TEST_1(l2 = su_strlst_dup(su_strlst_home(l), l)); strcpy(foo, "hum"); strcpy(bar, "pah"); strcpy(baz, "hah"); TEST_S(su_strlst_dup_append(l1, "kuik"), "kuik"); TEST_S(su_strlst_dup_append(l2, "uik"), "uik"); TEST_S((s = su_strlst_join(l, home, ".")), "hum.bar.hah"); TEST_S((su_strlst_join(l1, home, ".")), "hum.bar.hah.kuik"); TEST_S((su_strlst_join(l2, home, ".")), "foo.bar.baz.uik"); su_strlst_destroy(l2); su_home_get_stats(su_strlst_home(l), 0, kids, sizeof kids); TEST_SIZE(kids->hs_clones, 2); TEST64(kids->hs_allocs.hsa_number, 3); TEST64(kids->hs_frees.hsf_number, 1); su_strlst_destroy(l); TEST_S(s, "hum.bar.hah"); TEST_1(l = su_strlst_create(home)); su_home_init_stats(su_strlst_home(l)); TEST_S(su_strlst_join(l, home, "bar"), ""); TEST_S(su_strlst_append(l, "a"), "a"); TEST_S(su_strlst_append(l, "b"), "b"); TEST_S(su_strlst_append(l, "c"), "c"); TEST_S(su_strlst_append(l, "d"), "d"); TEST_S(su_strlst_append(l, "e"), "e"); TEST_S(su_strlst_append(l, "f"), "f"); TEST_S(su_strlst_append(l, "g"), "g"); TEST_S(su_strlst_append(l, "h"), "h"); TEST_S(su_strlst_append(l, "i"), "i"); TEST_S(su_strlst_append(l, "j"), "j"); TEST_S((s = su_strlst_join(l, home, "")), "abcdefghij"); TEST_S(su_strlst_append(l, "a"), "a"); TEST_S(su_strlst_append(l, "b"), "b"); TEST_S(su_strlst_append(l, "c"), "c"); TEST_S(su_strlst_append(l, "d"), "d"); TEST_S(su_strlst_append(l, "e"), "e"); TEST_S(su_strlst_append(l, "f"), "f"); TEST_S(su_strlst_append(l, "g"), "g"); TEST_S(su_strlst_append(l, "h"), "h"); TEST_S(su_strlst_append(l, "i"), "i"); TEST_S(su_strlst_append(l, "j"), "j"); TEST_S((s = su_strlst_join(l, home, "")), "abcdefghijabcdefghij"); su_home_get_stats(su_strlst_home(l), 0, kids + 1, (sizeof kids[1])); su_home_stat_add(kids, kids + 1); su_strlst_destroy(l); su_home_get_stats(home, 1, parent, (sizeof parent)); su_home_check(home); su_home_deinit(home); su_home_init(home); { char s[] = "foo\nfaa\n"; TEST_1((l = su_strlst_split(home, s, "\n"))); TEST_SIZE(su_strlst_len(l), 3); TEST_1(su_strlst_append(l, "bar")); TEST_S(su_strlst_join(l, home, "\n"), "foo\nfaa\n\nbar"); } { char s[] = "foo"; TEST_1((l = su_strlst_split(home, s, "\n"))); TEST_SIZE(su_strlst_len(l), 1); } { char s[] = "\n\n"; TEST_1((l = su_strlst_split(home, s, "\n"))); TEST_SIZE(su_strlst_len(l), 3); } { char s[] = ""; TEST_1((l = su_strlst_split(home, s, "\n"))); TEST_SIZE(su_strlst_len(l), 1); } { int i; #define S \ "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\n" \ "n\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n" \ "A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\n" \ "N\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n" char s[] = S; TEST_1((l = su_strlst_split(home, s, "\n"))); TEST_SIZE(su_strlst_len(l), 53); TEST_1(su_strlst_append(l, "bar")); TEST_S(su_strlst_join(l, home, "\n"), S "\nbar"); TEST_1(!su_strlst_remove(l, 54)); for (i = 0; i < 54; i++) { TEST_1(su_strlst_remove(l, 0)); TEST_1(!su_strlst_remove(l, 53 - i)); TEST_SIZE(su_strlst_len(l), 53 - i); } TEST_1(!su_strlst_remove(l, 0)); TEST_SIZE(su_strlst_len(l), 0); } { char const *s0; TEST_1(l = su_strlst_create_with(NULL, s0 = "a", "b", NULL)); TEST_1(su_strlst_item(l, 0) == s0); TEST_S(su_strlst_item(l, 0), "a"); TEST_S(su_strlst_item(l, 1), "b"); TEST_1(su_strlst_item(l, 2) == NULL); TEST_S(su_slprintf(l, "1: %u", 1), "1: 1"); TEST_S(su_slprintf(l, "1.0: %g", 1.0), "1.0: 1"); TEST_1(su_strlst_append(l, "")); TEST_S(su_strlst_join(l, home, "\n"), "a\n" "b\n" "1: 1\n" "1.0: 1\n"); TEST_VOID(su_strlst_destroy(l)); TEST_1(l2 = su_strlst_create_with_dup(NULL, s0 = "0", "1", "2", "3", "4", "5", "6", "7", NULL)); TEST_1(su_strlst_item(l2, 0) != s0); TEST_S(su_strlst_item(l2, 0), "0"); TEST_S(su_strlst_item(l2, 1), "1"); TEST_S(su_strlst_item(l2, 2), "2"); TEST_S(su_strlst_item(l2, 3), "3"); TEST_S(su_strlst_item(l2, 4), "4"); TEST_S(su_strlst_item(l2, 5), "5"); TEST_S(su_strlst_item(l2, 6), "6"); TEST_S(su_strlst_item(l2, 7), "7"); TEST_1(su_strlst_item(l2, 8) == NULL); TEST_S(su_strlst_join(l2, home, ""), "01234567"); TEST_VOID(su_strlst_destroy(l2)); } su_home_check(home); su_home_deinit(home); END(); }
void janus_sdp_deinit(void) { su_home_deinit(home); su_home_unref(home); home = NULL; }
int test_any(void) { /* Test any (*) urls */ url_t any[1] = { URL_INIT_AS(any) }; su_home_t home[1] = { SU_HOME_INIT(home) }; url_t *u, url[1]; char *tst; BEGIN(); TEST_S(url_scheme(url_any), "*"); TEST_S(url_scheme(url_mailto), "mailto"); TEST_S(url_scheme(url_im), "im"); TEST_S(url_scheme(url_cid), "cid"); TEST_S(url_scheme(url_msrp), "msrp"); TEST_S(url_scheme(url_msrps), "msrps"); TEST_1(tst = su_strdup(home, "*")); TEST(url_d(url, tst), 0); TEST(url_cmp(any, url), 0); TEST(url->url_type, url_any); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_any); TEST(url_cmp(any, u), 0); url_digest(hash1, sizeof(hash1), url, NULL); url_digest(hash2, sizeof(hash2), (url_t *)"*", NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); { char buf[6]; TEST_1(u = url_hdup(home, (void *)"error")); TEST_SIZE(url_xtra(u), 6); TEST_SIZE(url_dup(buf, 6, url, u), 6); TEST_S(buf, "error"); } { TEST_1(u = url_hdup(home, (void *)"scheme:test")); TEST(u->url_type, url_unknown); } { TEST_1(u = url_hdup(home, (void *)"*;param=foo?query=bar")); TEST(u->url_type, url_unknown); TEST_S(u->url_host, "*"); TEST_S(u->url_params, "param=foo"); TEST_S(u->url_headers, "query=bar"); } { TEST_1(u = url_hdup(home, (void *)"#foo")); TEST(u->url_type, url_unknown); TEST_S(u->url_fragment, "foo"); } { url_t u[1]; char b2[6] = ""; memset(u, 0xff, sizeof u); TEST(url_d(u, b2), 0); TEST(u->url_type, url_unknown); } su_home_deinit(home); END(); }
void janus_sdp_deinit() { su_home_deinit(home); }
int test_http(void) { /* http urls */ su_home_t home[1] = { SU_HOME_INIT(home) }; url_t http[1] = { URL_INIT_AS(http) }; url_t *u, url[1]; char *tst; char httpurl[] = "http://*****:*****@host:32/foo;param=1/bar;param=3" "?From=foo@bar&To=bar@baz#unf"; char http2[sizeof(httpurl) + 32]; char queryonly[] = "http://some.host?query"; BEGIN(); TEST_S(url_scheme(url_http), "http"); TEST_S(url_scheme(url_https), "https"); http->url_root = '/'; http->url_user = "******"; http->url_password = "******"; http->url_host = "host"; http->url_port = "32"; http->url_path = "foo;param=1/bar;param=3"; http->url_headers = "From=foo@bar&To=bar@baz"; http->url_fragment = "unf"; TEST_1(tst = su_strdup(home, httpurl)); TEST_1(url_d(url, tst) == 0); TEST_1(url_cmp(http, url) == 0); TEST(url->url_type, url_http); TEST_1(u = url_hdup(home, url)); TEST(u->url_type, url_http); TEST_1(url_cmp(http, u) == 0); TEST_SIZE(url_e(http2, sizeof(http2), u), strlen(httpurl)); TEST_1(strcmp(http2, httpurl) == 0); TEST_SIZE(snprintf(http2, sizeof(http2), URL_PRINT_FORMAT, URL_PRINT_ARGS(http)), strlen(httpurl)); TEST_1(strcmp(http2, httpurl) == 0); url_digest(hash1, sizeof(hash1), http, NULL); url_digest(hash2, sizeof(hash2), (url_t *)httpurl, NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); memset(url, 0, sizeof url); TEST_1(tst = su_strdup(home, queryonly)); TEST(url_d(url, tst), 0); TEST_S(url->url_host, "some.host"); TEST_S(url->url_headers, "query"); TEST_S(url->url_params, NULL); TEST_1(u = url_hdup(home, (void *)"http://[::1]/test;ing?here")); TEST_S(u->url_host, "[::1]"); TEST_S(u->url_path, "test;ing"); TEST_S(u->url_headers, "here"); url_digest(hash1, sizeof(hash1), u, NULL); url_digest(hash2, sizeof(hash2), (url_t *)"http://[::1]/test;ing?here", NULL); TEST(memcmp(hash1, hash2, sizeof(hash1)), 0); su_home_deinit(home); END(); }
/** Create a http site object. * * The function nth_site_create() allocates and initializes a web site * object. A web site object can be either * - a primary http server (@a parent is NULL), * - a virtual http server (@a address contains hostpart), or * - a site within a server * (@a address does not have hostpart, only path part). * * @param parent pointer to parent site * (NULL when creating a primary server object) * @param callback pointer to callback function called when * a request is received * @param magic application context included in callback parameters * @param address absolute or relative URI specifying the address of * site * @param tag, value, ... list of tagged parameters * * @TAGS * If the @a parent is NULL, the list of tagged parameters must contain * NTHTAG_ROOT() used to create the server engine. Tags supported when @a * parent is NULL are NTHTAG_ROOT(), NTHTAG_MCLASS(), TPTAG_REUSE(), * HTTPTAG_SERVER(), and HTTPTAG_SERVER_STR(). All the tags are passed to * tport_tcreate() and tport_tbind(), too. * * @since Support for multiple sites was added to @VERSION_1_12_4 */ nth_site_t *nth_site_create(nth_site_t *parent, nth_request_f *callback, nth_site_magic_t *magic, url_string_t const *address, tag_type_t tag, tag_value_t value, ...) { nth_site_t *site = NULL, **prev = NULL; su_home_t home[SU_HOME_AUTO_SIZE(256)]; url_t *url, url0[1]; server_t *srv = NULL; ta_list ta; char *path = NULL; size_t usize; int is_host, is_path, wildcard = 0; su_home_auto(home, sizeof home); if (parent && url_is_string(address)) { char const *s = (char const *)address; size_t sep = strcspn(s, "/:"); if (parent->site_path) { /* subpath */ url_init(url0, (enum url_type_e)parent->site_url->url_type); url0->url_path = s; address = (url_string_t*)url0; } else if (s[sep] == ':') /* absolute URL with scheme */; else if (s[sep] == '\0' && strchr(s, '.') && host_is_valid(s)) { /* looks like a domain name */; url_init(url0, (enum url_type_e)parent->site_url->url_type); url0->url_host = s; address = (url_string_t*)url0; } else { /* looks like a path */ url_init(url0, (enum url_type_e)parent->site_url->url_type); url0->url_path = s; address = (url_string_t*)url0; } } url = url_hdup(home, address->us_url); if (!url || !callback) return NULL; is_host = url->url_host != NULL; is_path = url->url_path != NULL; if (is_host && is_path) { SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n")); errno = EINVAL; goto error; } if (!parent && !is_host) { SU_DEBUG_3(("nth_site_create(): host is required\n")); errno = EINVAL; goto error; } if (parent) { if (!parent->site_isdir) { SU_DEBUG_3(("nth_site_create(): invalid parent resource \n")); errno = EINVAL; goto error; } srv = parent->site_server; assert(srv); if (is_host) { prev = site_get_host(&srv->srv_sites, url->url_host, url->url_port); if (prev == NULL) { SU_DEBUG_3(("nth_site_create(): host %s:%s already exists\n", url->url_host, url->url_port ? url->url_port : "")); errno = EEXIST; goto error; } } else { size_t i, j; path = (char *)url->url_path; while (path[0] == '/') path++; /* Remove duplicate // */ for (i = j = 0; path[i];) { while (path[i] == '/' && path[i + 1] == '/') i++; path[j++] = path[i++]; } path[j] = path[i]; url = url0, *url = *parent->site_url; if (url->url_path) { url->url_path = su_strcat(home, url->url_path, path); if (!url->url_path) goto error; path = (char *)url->url_path + strlen(parent->site_url->url_path); } else url->url_path = path; prev = site_get_rslot(parent, path, &path); if (!prev || path[0] == '\0') { SU_DEBUG_3(("nth_site_create(): directory \"%s\" already exists\n", url->url_path)); errno = EEXIST; goto error; } } } if (!parent) { if (strcmp(url->url_host, "*") == 0 || host_cmp(url->url_host, "0.0.0.0") == 0 || host_cmp(url->url_host, "::") == 0) wildcard = 1, url->url_host = "*"; } usize = sizeof(*url) + url_xtra(url); ta_start(ta, tag, value); if (!parent) { srv = server_create(url, ta_tags(ta)); prev = &srv->srv_sites; } if (srv && (site = su_zalloc(srv->srv_home, (sizeof *site) + usize))) { site->site_url = (url_t *)(site + 1); url_dup((void *)(site->site_url + 1), usize - sizeof(*url), site->site_url, url); assert(prev); if ((site->site_next = *prev)) site->site_next->site_prev = &site->site_next; *prev = site, site->site_prev = prev; site->site_server = srv; if (path) { size_t path_len; site->site_path = site->site_url->url_path + (path - url->url_path); path_len = strlen(site->site_path); assert(path_len > 0); if (path_len > 0 && site->site_path[path_len - 1] == '/') path_len--, site->site_isdir = 1; site->site_path_len = path_len; } else { site->site_isdir = is_host; site->site_path = ""; site->site_path_len = 0; } site->site_wildcard = wildcard; site->site_callback = callback; site->site_magic = magic; if (parent) site->site_auth = parent->site_auth; nth_site_set_params(site, ta_tags(ta)); } ta_end(ta); error: su_home_deinit(home); return site; }
int sofsip_loop(int ac, char *av[], const int input_fd, const int output_fd) { cli_t cli[1] = {{{{sizeof(cli)}}}}; int res = 0; global_cli_p = cli; #ifndef _WIN32 /* see: http://www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html */ struct sigaction sigact; memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = sofsip_signal_handler; sigaction(SIGINT, &sigact, NULL); /* ctrl-c */ sigaction(SIGABRT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); #endif cli->cli_input_fd = input_fd; cli->cli_output_fd = output_fd; /* step: initialize sofia su OS abstraction layer */ su_init(); su_home_init(cli->cli_home); /* step: initialize glib and gstreamer */ #if HAVE_GLIB g_type_init(); #if HAVE_GST { //guint major, minor, micro, nano; //gst_init (NULL, NULL); //gst_version (&major, &minor, µ, &nano); //g_message ("This program is linked against GStreamer %d.%d.%d\n", major, minor, micro); } #endif #endif /* step: create a su event loop and connect it mainloop */ sofsip_mainloop_create(cli); assert(cli->cli_root); /* Disable threading by command line switch? */ su_root_threading(cli->cli_root, 0); /* step: parse command line arguments and initialize app event loop */ res = sofsip_init(cli, ac, av); assert(res == 0); /* step: create ssc signaling and media subsystem instance */ cli->cli_ssc = ssc_create(cli->cli_home, cli->cli_root, cli->cli_conf, cli->cli_input_fd, cli->cli_output_fd); if (res != -1 && cli->cli_ssc) { cli->cli_ssc->ssc_exit_cb = sofsip_shutdown_cb; cli->cli_ssc->ssc_auth_req_cb = sofsip_auth_req_cb; cli->cli_ssc->ssc_event_cb = sofsip_event_cb; ssc_input_install_handler(SOFSIP_PROMPT, sofsip_handle_input_cb); /* enter the main loop */ sofsip_mainloop_run(cli); ssc_destroy(cli->cli_ssc), cli->cli_ssc = NULL; } sofsip_deinit(cli); ssc_input_clear_history(); sofsip_mainloop_destroy(cli); su_home_deinit(cli->cli_home); su_deinit(); return 0; }