⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_s2.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (target == NULL)      goto error;    rq = sip_request_create(msg_home(msg), method, name, target, NULL);    sip_header_insert(msg, sip, (sip_header_t *)rq);  }  if (!d->local && sip->sip_from)    d->local = sip_from_dup(d->home, sip->sip_from);  if (!d->contact && sip->sip_contact)     d->contact = sip_contact_dup(d->home, sip->sip_contact);  if (!d->remote && sip->sip_to)    d->remote = sip_to_dup(d->home, sip->sip_to);  if (!d->target && sip->sip_request)    d->target = sip_contact_create(d->home,				   (url_string_t *)sip->sip_request->rq_url,				   NULL);  if (!d->call_id && sip->sip_call_id)    d->call_id = sip_call_id_dup(d->home, sip->sip_call_id);  if (!d->lseq && sip->sip_cseq)    d->lseq = sip->sip_cseq->cs_seq;    if (!d->local)    d->local = sip_from_dup(d->home, s2->local);  if (!d->contact)    d->contact = sip_contact_dup(d->home, s2->contact);  if (!d->remote)    d->remote = sip_to_dup(d->home, s2->registration->aor);  if (!d->call_id)    d->call_id = sip_call_id_create(d->home, NULL);  assert(d->local && d->contact);  assert(d->remote && d->target);  assert(d->call_id);  if (tport == NULL)    tport = d->tport;  if (tport == NULL)    tport = s2->registration->tport;  if (tport == NULL && d->target->m_url->url_type == url_sips)    tport = s2->tls.tport;  if (tport == NULL)    tport = s2->udp.tport;  else if (tport == NULL)    tport = s2->tcp.tport;  else if (tport == NULL)    tport = s2->tls.tport;  assert(tport);  *tpn = *tport_name(tport);  if (tport_is_udp(tport)) {    tpn->tpn_host = d->target->m_url->url_host;    tpn->tpn_port = url_port(d->target->m_url);    if (!tpn->tpn_port || !tpn->tpn_port[0])      tpn->tpn_port = url_port_default(d->target->m_url->url_type);  }  magic = tport_magic(tport);  assert(magic != NULL);  sip_cseq_init(cseq);  cseq->cs_method = method;  cseq->cs_method_name = name;    if (d->invite && (method == sip_method_ack || method == sip_method_cancel)) {    cseq->cs_seq = sip_object(d->invite)->sip_cseq->cs_seq;  }  else {    cseq->cs_seq = ++d->lseq;  }  if (d->invite && method == sip_method_cancel) {    *via = *sip_object(d->invite)->sip_via;  }  else {    *via = *magic->via;    via->v_params = v_params;    v_params[0] = su_sprintf(msg_home(msg), "branch=z9hG4bK%lx", ++s2->tid);    v_params[1] = NULL;  }  sip_content_length_init(l);  if (sip->sip_payload)    l->l_length = sip->sip_payload->pl_len;  sip_add_tl(msg, sip, 	     TAG_IF(!sip->sip_from, SIPTAG_FROM(d->local)),	     TAG_IF(!sip->sip_contact, SIPTAG_CONTACT(d->contact)),	     TAG_IF(!sip->sip_to, SIPTAG_TO(d->remote)),	     TAG_IF(!sip->sip_call_id, SIPTAG_CALL_ID(d->call_id)),	     TAG_IF(!sip->sip_cseq, SIPTAG_CSEQ(cseq)),	     SIPTAG_VIA(via),	     TAG_IF(!sip->sip_content_length, SIPTAG_CONTENT_LENGTH(l)),	     TAG_IF(!sip->sip_separator, SIPTAG_SEPARATOR_STR("\r\n")),	     TAG_END());  msg_serialize(msg, NULL);  if (method == sip_method_invite) {    msg_destroy(d->invite);    d->invite = msg_ref_create(msg);  }  tport = tport_tsend(tport, msg, tpn, ta_tags(ta));  ta_end(ta);  if (d->tport != tport) {    tport_unref(d->tport);    d->tport = tport_ref(tport);  }  return tport ? 0 : -1;   error:  ta_end(ta);  return -1;}/** Save information from response. * * Send ACK for error messages to INVITE. */int s2_update_dialog(struct dialog *d, struct message *m){  int status = 0;  if (m->sip->sip_status)    status = m->sip->sip_status->st_status;  if (100 < status && status < 300) {    d->remote = sip_to_dup(d->home, m->sip->sip_to);    if (m->sip->sip_contact)      d->contact = sip_contact_dup(d->home, m->sip->sip_contact);  }  if (300 <= status && m->sip->sip_cseq &&      m->sip->sip_cseq->cs_method == sip_method_invite &&      d->invite) {    msg_t *ack = s2_msg(0);    sip_t *sip = sip_object(ack);    sip_t *invite = sip_object(d->invite);    sip_request_t rq[1];    sip_cseq_t cseq[1];    tp_name_t tpn[1];    *rq = *invite->sip_request;    rq->rq_method = sip_method_ack, rq->rq_method_name = "ACK";    *cseq = *invite->sip_cseq;    cseq->cs_method = sip_method_ack, cseq->cs_method_name = "ACK";    sip_add_tl(ack, sip,	       SIPTAG_REQUEST(rq),	       SIPTAG_VIA(invite->sip_via),	       SIPTAG_FROM(invite->sip_from),	       SIPTAG_TO(invite->sip_to),	       SIPTAG_CALL_ID(invite->sip_call_id),	       SIPTAG_CSEQ(cseq),	       SIPTAG_CONTENT_LENGTH_STR("0"),	       SIPTAG_SEPARATOR_STR("\r\n"),	       TAG_END());    *tpn = *tport_name(d->tport);    if (!tport_is_secondary(d->tport) ||	!tport_is_clear_to_send(d->tport)) {      tpn->tpn_host = rq->rq_url->url_host;      tpn->tpn_port = rq->rq_url->url_port;    }    msg_serialize(ack, NULL);    tport_tsend(d->tport, ack, tpn, TAG_END());  }  return 0;}/* ---------------------------------------------------------------------- */ints2_save_register(struct message *rm){  sip_contact_t *contact, *m, **m_prev;  sip_expires_t const *ex;  sip_date_t const *date;  sip_time_t now = rm->when.tv_sec, expires;  msg_header_free_all(s2->home, (msg_header_t *)s2->registration->aor);  msg_header_free_all(s2->home, (msg_header_t *)s2->registration->contact);  tport_unref(s2->registration->tport);  s2->registration->aor = NULL;  s2->registration->contact = NULL;  s2->registration->tport = NULL;  if (rm == NULL)    return 0;  assert(rm && rm->sip && rm->sip->sip_request);  assert(rm->sip->sip_request->rq_method == sip_method_register);  ex = rm->sip->sip_expires;  date = rm->sip->sip_date;  contact = sip_contact_dup(s2->home, rm->sip->sip_contact);  for (m_prev = &contact; *m_prev;) {    m = *m_prev;    expires = sip_contact_expires(m, ex, date,				  s2_default_registration_duration,				  now);    if (expires) {      char *p = su_sprintf(s2->home, "expires=%lu", (unsigned long)expires);      msg_header_add_param(s2->home, m->m_common, p);      m_prev = &m->m_next;    }    else {      *m_prev = m->m_next;      m->m_next = NULL;      msg_header_free(s2->home, (msg_header_t *)m);    }  }  if (contact == NULL)    return 0;  s2->registration->aor = sip_to_dup(s2->home, rm->sip->sip_to);  s2->registration->contact = contact;  s2->registration->tport = tport_ref(rm->tport);  return 0;}/* ---------------------------------------------------------------------- */static char *s2_generate_tag(su_home_t *home){  s2_tag_generator += 1;  return su_sprintf(home, "tag=N2-%s/%u", _s2case, s2_tag_generator);}void s2_case(char const *number,	     char const *title,	     char const *desciption){  _s2case = number;}/* ---------------------------------------------------------------------- *//* tport interface */static void s2_stack_recv(struct tester *s2,	      tport_t *tp,	      msg_t *msg,	      tp_magic_t *magic,	      su_time_t now){  struct message *next = calloc(1, sizeof *next), **prev;  next->msg = msg;  next->sip = sip_object(msg);  next->when = now;  next->tport = tport_ref(tp);#if 0  if (next->sip->sip_request)    printf("nua sent: %s\n", next->sip->sip_request->rq_method_name);  else    printf("nua sent: SIP/2.0 %u %s\n",	   next->sip->sip_status->st_status,	   next->sip->sip_status->st_phrase);#endif  for (prev = &s2->received; *prev; prev = &(*prev)->next)    ;  next->prev = prev, *prev = next;}static voids2_stack_error(struct tester *s2,	       tport_t *tp,	       int errcode,	       char const *remote){  fprintf(stderr, "%s(%p): error %d (%s) from %s\n", 	  "nua_tester_error",	  (void *)tp, errcode, su_strerror(errcode), 	  remote ? remote : "<unknown destination>");}static msg_t *s2_stack_alloc(struct tester *s2, int flags,	       char const data[], usize_t size,	       tport_t const *tport, 	       tp_client_t *tpc){  return msg_create(s2->mclass, flags | s2->flags);}static msg_t *s2_msg(int flags){  return msg_create(s2->mclass, flags | s2->flags);}tp_stack_class_t const s2_stack[1] =  {{      /* tpac_size */ (sizeof s2_stack),      /* tpac_recv */  s2_stack_recv,      /* tpac_error */ s2_stack_error,      /* tpac_alloc */ s2_stack_alloc,  }};/** Basic setup for test cases */void s2_setup_base(char const *hostname){  assert(s2 == NULL);  su_init();  s2 = su_home_new(sizeof *s2);  assert(s2 != NULL);  s2->root = su_root_create(s2);  assert(s2->root != NULL);  su_root_threading(s2->root, 0);	/* disable multithreading */  s2->local = sip_from_format(s2->home, "Bob <sip:bob@%s>",			     hostname ? hostname : "example.net");    if (hostname == NULL)    hostname = "127.0.0.1";  s2->hostname = hostname;  s2->tid = (unsigned long)time(NULL) * 510633671UL;}SOFIAPUBVAR su_log_t nua_log[];SOFIAPUBVAR su_log_t soa_log[];SOFIAPUBVAR su_log_t nea_log[];SOFIAPUBVAR su_log_t nta_log[];SOFIAPUBVAR su_log_t tport_log[];SOFIAPUBVAR su_log_t su_log_default[];voids2_setup_logs(int level){  assert(s2);  su_log_soft_set_level(nua_log, level);  su_log_soft_set_level(soa_log, level);  su_log_soft_set_level(su_log_default, level);  su_log_soft_set_level(nea_log, level);  su_log_soft_set_level(nta_log, level);  su_log_soft_set_level(tport_log, level);}static char const * default_protocols[] = { "udp", "tcp", NULL };voids2_setup_tport(char const * const *protocols,	       tag_type_t tag, tag_value_t value, ...){  ta_list ta;  tp_name_t tpn[1];  int bound;  tport_t *tp;  assert(s2 != NULL);  ta_start(ta, tag, value);  if (s2->master == NULL) {    s2->master = tport_tcreate(s2, s2_stack, s2->root, ta_tags(ta));    if (s2->master == NULL) {      assert(s2->master);    }    s2->mclass = sip_default_mclass();    s2->flags = 0;  }  memset(tpn, 0, (sizeof tpn));  tpn->tpn_proto = "*";  tpn->tpn_host = s2->hostname;  tpn->tpn_port = "*";  if (protocols == NULL)    protocols = default_protocols;    bound = tport_tbind(s2->master, tpn, protocols, 		      TPTAG_SERVER(1),		      ta_tags(ta));  assert(bound != -1);  tp = tport_primaries(s2->master);  if (protocols == default_protocols && s2->contact == NULL) {    *tpn = *tport_name(tp);    s2->contact = sip_contact_format(s2->home, "<sip:%s:%s>",				    tpn->tpn_host,				    tpn->tpn_port);  }  for (;tp; tp = tport_next(tp)) {    sip_via_t *v;    sip_contact_t *m;    tp_magic_t *magic;    if (tport_magic(tp))      continue;    *tpn = *tport_name(tp);    v = sip_via_format(s2->home, "SIP/2.0/%s %s:%s",		       tpn->tpn_proto,		       tpn->tpn_host, 		       tpn->tpn_port);    assert(v != NULL);    if (strncasecmp(tpn->tpn_proto, "tls", 3)) {      m = sip_contact_format(s2->home, "<sip:%s:%s;transport=%s>",			     tpn->tpn_host,			     tpn->tpn_port,			     tpn->tpn_proto);      if (s2->udp.contact == NULL && strcasecmp(tpn->tpn_proto, "udp") == 0) {	s2->udp.tport = tport_ref(tp); 	s2->udp.contact = m;      }      if (s2->tcp.contact == NULL && strcasecmp(tpn->tpn_proto, "tcp") == 0) {	s2->tcp.tport = tport_ref(tp); 	s2->tcp.contact = m;      }    }    else if (strcasecmp(tpn->tpn_proto, "tls")) {      m = sip_contact_format(s2->home, "<sips:%s:%s;transport=%s>",			     tpn->tpn_host,			     tpn->tpn_port,			     tpn->tpn_proto);    }    else {      m = sip_contact_format(s2->home, "<sips:%s:%s>",			     tpn->tpn_host,			     tpn->tpn_port);      if (s2->tls.contact == NULL) {	s2->tls.tport = tport_ref(tp); 	s2->tls.contact = m;      }    }    assert(m != NULL);    magic = su_zalloc(s2->home, (sizeof *magic));    magic->via = v, magic->contact = m;    if (s2->contact == NULL)      s2->contact = m;    tport_set_magic(tp, magic);  }}/* ---------------------------------------------------------------------- *//* S2 DNS server */#include <sofia-resolv/sres_record.h>extern uint16_t _sres_default_port;static int s2_dns_query(struct tester *s2,			su_wait_t *w,			su_wakeup_arg_t *arg);void s2_setup_dns(void){  int n;  su_socket_t socket;  su_wait_t *wait;  su_sockaddr_t su[1];  socklen_t sulen = sizeof su->su_sin;  assert(s2->nua == NULL); assert(s2->root != NULL);  memset(su, 0, sulen);  su->su_len = sulen;  su->su_family = AF_INET;  /* su->su_port = htons(1053); */  socket = su_socket(su->su_family, SOCK_DGRAM, 0);  n = bind(socket, &su->su_sa, sulen); assert(n == 0);  n = getsockname(socket, &su->su_sa, &sulen); assert(n == 0);  _sres_default_port = ntohs(su->su_port);  wait = s2->dns.wait;  n = su_wait_create(wait, socket, SU_WAIT_IN); assert(n == 0);  s2->dns.reg = su_root_register(s2->root, wait, s2_dns_query, NULL, 0);  assert(s2->dns.reg > 0);  s2->dns.socket = socket;}staticstruct s2_dns_response {  struct s2_dns_response *next;  uint16_t qlen, dlen;  struct m_header {    /* Header defined in RFC 1035 section 4.1.1 (page 26) */    uint16_t mh_id;		/* Query ID */    uint16_t mh_flags;		/* Flags */    uint16_t mh_qdcount;	/* Question record count */    uint16_t mh_ancount;	/* Answer record count */    uint16_t mh_nscount;	/* Authority records count */    uint16_t mh_arcount;	/* Additional records count */  } header[1];  uint8_t data[1500];} *zonedata;enum {  FLAGS_QR = (1 << 15),  FLAGS_QUERY = (0 << 11),  FLAGS_IQUERY = (1 << 11),  FLAGS_STATUS = (2 << 11),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -