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

📄 test_s2.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 3 页
字号:
  FLAGS_OPCODE = (15 << 11),	/* mask */  FLAGS_AA = (1 << 10),		/*  */  FLAGS_TC = (1 << 9),  FLAGS_RD = (1 << 8),  FLAGS_RA = (1 << 7),  FLAGS_RCODE = (15 << 0),	/* mask of return code */  FLAGS_OK = 0,			/* No error condition. */  FLAGS_FORMAT_ERR = 1,		/* Server could not interpret query. */  FLAGS_SERVER_ERR = 2,		/* Server error. */  FLAGS_NAME_ERR = 3,		/* No domain name. */  FLAGS_UNIMPL_ERR = 4,		/* Not implemented. */  FLAGS_AUTH_ERR = 5,		/* Refused */};uint32_t s2_dns_ttl = 3600;static ints2_dns_query(struct tester *s2,	     su_wait_t *w,	     su_wakeup_arg_t *arg){  union {    struct m_header header[1];    uint8_t buffer[1500];  } request;  ssize_t len;  su_socket_t socket;  su_sockaddr_t su[1];  socklen_t sulen = sizeof su;  uint16_t flags;  struct s2_dns_response *r;  size_t const hlen = sizeof r->header;  (void)arg;  socket = s2->dns.socket;  len = su_recvfrom(socket, request.buffer, sizeof request.buffer, 0,		    &su->su_sa, &sulen);  flags = ntohs(request.header->mh_flags);  if (len < (ssize_t)hlen)    return 0;  if ((flags & FLAGS_QR) == FLAGS_QR)    return 0;  if ((flags & FLAGS_RCODE) != FLAGS_OK)    return 0;  if ((flags & FLAGS_OPCODE) != FLAGS_QUERY      || ntohs(request.header->mh_qdcount) != 1) {    flags |= FLAGS_QR | FLAGS_UNIMPL_ERR;    request.header->mh_flags = htons(flags);    su_sendto(socket, request.buffer, len, 0, &su->su_sa, sulen);    return 0;  }  for (r = zonedata; r; r = r->next) {    if (memcmp(r->data, request.buffer + hlen, r->qlen) == 0)      break;  }  if (r) {    flags |= FLAGS_QR | FLAGS_AA | FLAGS_OK;    request.header->mh_flags = htons(flags);    request.header->mh_ancount = htons(r->header->mh_ancount);    request.header->mh_nscount = htons(r->header->mh_nscount);    request.header->mh_arcount = htons(r->header->mh_arcount);    memcpy(request.buffer + hlen + r->qlen,	   r->data + r->qlen,	   r->dlen - r->qlen);    len = hlen + r->dlen;  }  else {    flags |= FLAGS_QR | FLAGS_AA | FLAGS_NAME_ERR;  }  request.header->mh_flags = htons(flags);  su_sendto(socket, request.buffer, len, 0, &su->su_sa, sulen);  return 0;}static void put_uint16(struct s2_dns_response *m, uint16_t h){  uint8_t *p = m->data + m->dlen;  assert(m->dlen + (sizeof h) < sizeof m->data);  p[0] = h >> 8; p[1] = h;  m->dlen += (sizeof h);}static void put_uint32(struct s2_dns_response *m, uint32_t w){  uint8_t *p = m->data + m->dlen;  assert(m->dlen + (sizeof w) < sizeof m->data);  p[0] = w >> 24; p[1] = w >> 16; p[2] = w >> 8; p[3] = w;  m->dlen += (sizeof w);}static void put_domain(struct s2_dns_response *m, char const *domain){  char const *label;  size_t llen;  /* Copy domain into query label at a time */  for (label = domain; label && label[0]; label += llen) {    assert(!(label[0] == '.' && label[1] != '\0'));    llen = strcspn(label, ".");    assert(llen < 64);    assert(m->dlen + llen + 1 < sizeof m->data);    m->data[m->dlen++] = (uint8_t)llen;    if (llen == 0)      return;    memcpy(m->data + m->dlen, label, llen);    m->dlen += (uint16_t)llen;    if (label[llen] == '\0')      break;    if (label[llen + 1])      llen++;  }  assert(m->dlen < sizeof m->data);  m->data[m->dlen++] = '\0';}static void put_string(struct s2_dns_response *m, char const *string){  uint8_t *p = m->data + m->dlen;  size_t len = strlen(string);  assert(len <= 255);  assert(m->dlen + len + 1 < sizeof m->data);  *p++ = (uint8_t)len;  memcpy(p, string, len);  m->dlen += len + 1;}static uint16_t put_len_at(struct s2_dns_response *m){  uint16_t at = m->dlen;  assert(m->dlen + sizeof(at) < sizeof m->data);  memset(m->data + m->dlen, 0, sizeof(at));  m->dlen += sizeof(at);  return at;}static void put_len(struct s2_dns_response *m, uint16_t start){  uint8_t *p = m->data + start;  uint16_t len = m->dlen - (start + 2);  p[0] = len >> 8; p[1] = len;}static void put_data(struct s2_dns_response *m, void *data, uint16_t len){  assert(m->dlen + len < sizeof m->data);  memcpy(m->data + m->dlen, data, len);  m->dlen += len;}static void put_query(struct s2_dns_response *m, char const *domain,		      uint16_t qtype){  assert(m->header->mh_qdcount == 0);  put_domain(m, domain), put_uint16(m, qtype), put_uint16(m, sres_class_in);  m->header->mh_qdcount++;  m->qlen = m->dlen;}static void put_a_record(struct s2_dns_response *m,			 char const *domain,			 struct in_addr addr){  uint16_t start;  put_domain(m, domain);  put_uint16(m, sres_type_a);  put_uint16(m, sres_class_in);  put_uint32(m, s2_dns_ttl);  start = put_len_at(m);  put_data(m, &addr, sizeof addr);  put_len(m, start);}static void put_srv_record(struct s2_dns_response *m,			   char const *domain,			   uint16_t prio, uint16_t weight,			   uint16_t port, char const *target){  uint16_t start;  put_domain(m, domain);  put_uint16(m, sres_type_srv);  put_uint16(m, sres_class_in);  put_uint32(m, s2_dns_ttl);  start = put_len_at(m);  put_uint16(m, prio);  put_uint16(m, weight);  put_uint16(m, port);  put_domain(m, target);  put_len(m, start);}static void put_naptr_record(struct s2_dns_response *m,			     char const *domain,			     uint16_t order, uint16_t preference,			     char const *flags,			     char const *services,			     char const *regexp,			     char const *replace){  uint16_t start;  put_domain(m, domain);  put_uint16(m, sres_type_naptr);  put_uint16(m, sres_class_in);  put_uint32(m, s2_dns_ttl);  start = put_len_at(m);  put_uint16(m, order);  put_uint16(m, preference);  put_string(m, flags);  put_string(m, services);  put_string(m, regexp);  put_domain(m, replace);  put_len(m, start);}static void put_srv_record_from_uri(struct s2_dns_response *m,				    char const *base,				    uint16_t prio, uint16_t weight,				    url_t const *uri, char const *server){  char domain[1024] = "none";  char const *service = url_port(uri);  uint16_t port;  if (uri->url_type == url_sips) {    strcpy(domain, "_sips._tcp.");  }  else if (uri->url_type == url_sip) {    if (url_has_param(uri, "transport=udp")) {      strcpy(domain, "_sip._udp.");    }    else if (url_has_param(uri, "transport=tcp")) {      strcpy(domain, "_sip._tcp.");    }  }  assert(strcmp(domain, "none"));  strcat(domain, base);  if (m->header->mh_qdcount == 0)    put_query(m, domain, sres_type_srv);  port = (uint16_t)strtoul(service, NULL, 10);  put_srv_record(m, domain, prio, weight, port, server);}staticvoid s2_add_to_zone(struct s2_dns_response *_r){  size_t size = offsetof(struct s2_dns_response, data[_r->dlen]);  struct s2_dns_response *r = malloc(size); assert(r);  memcpy(r, _r, size);  r->next = zonedata;  zonedata = r;}static void make_server(char *server, char const *prefix, char const *domain){  strcpy(server, prefix);  if (strlen(server) == 0 || server[strlen(server) - 1] != '.') {    strcat(server, ".");    strcat(server, domain);  }}/** Set up DNS domain */void s2_dns_domain(char const *domain, int use_naptr,		   /* char *prefix, int priority, url_t const *uri, */		   ...){  struct s2_dns_response m[1];  char server[1024], target[1024];  va_list va0, va;  char const *prefix; int priority; url_t const *uri;  struct in_addr localhost;  assert(s2->dns.reg != 0);  su_inet_pton(AF_INET, "127.0.0.1", &localhost);  va_start(va0, use_naptr);  if (use_naptr) {    memset(m, 0, sizeof m);    put_query(m, domain, sres_type_naptr);    va_copy(va, va0);    for (;(prefix = va_arg(va, char *));) {      char *services = NULL;      priority = va_arg(va, int);      uri = va_arg(va, url_t *); assert(uri);      if (uri->url_type == url_sips) {	services = "SIPS+D2T";	strcpy(target, "_sips._tcp.");      }      else if (uri->url_type == url_sip) {	if (url_has_param(uri, "transport=udp")) {	  services = "SIP+D2U";	  strcpy(target, "_sip._udp.");	}	else if (url_has_param(uri, "transport=tcp")) {	  services = "SIP+D2T";	  strcpy(target, "_sip._tcp.");	}      }      strcat(target, domain);      assert(services);      put_naptr_record(m, domain, 1, priority, "s", services, "", target);      m->header->mh_ancount++;    }    va_end(va);    va_copy(va, va0);    for (;(prefix = va_arg(va, char *));) {      priority = va_arg(va, int);      uri = va_arg(va, url_t *); assert(uri);      make_server(server, prefix, domain);      put_srv_record_from_uri(m, domain, priority, 10, uri, server);      m->header->mh_arcount++;      put_a_record(m, server, localhost);      m->header->mh_arcount++;    }    va_end(va);    s2_add_to_zone(m);  }  /* Add SRV records */  va_copy(va, va0);  for (;(prefix = va_arg(va, char *));) {    priority = va_arg(va, int);    uri = va_arg(va, url_t *); assert(uri);    make_server(server, prefix, domain);    memset(m, 0, sizeof m);    put_srv_record_from_uri(m, domain, priority, 10, uri, server);    m->header->mh_ancount++;    strcpy(server, prefix); strcat(server, domain);    put_a_record(m, server, localhost);    m->header->mh_arcount++;    s2_add_to_zone(m);  }  va_end(va);  /* Add A records */  va_copy(va, va0);  for (;(prefix = va_arg(va, char *));) {    (void)va_arg(va, int);    (void)va_arg(va, url_t *);    memset(m, 0, sizeof m);    make_server(server, prefix, domain);    put_query(m, server, sres_type_a);    put_a_record(m, server, localhost);    m->header->mh_ancount++;    s2_add_to_zone(m);  }  va_end(va);  va_end(va0);}voids2_teardown(void){  s2 = NULL;  su_deinit();}/* ====================================================================== */#include <sofia-sip/sresolv.h>nua_t *s2_nua_setup(tag_type_t tag, tag_value_t value, ...){  ta_list ta;  s2_setup_base(NULL);  s2_setup_dns();  s2_setup_logs(0);  s2_setup_tport(NULL, TPTAG_LOG(0), TAG_END());  assert(s2->contact);  s2_dns_domain("example.org", 1,		"s2", 1, s2->udp.contact->m_url,		"s2", 1, s2->tcp.contact->m_url,		NULL);  ta_start(ta, tag, value);  s2->nua =     nua_create(s2->root,	       s2_nua_callback,	       s2,	       SIPTAG_FROM_STR("Alice <sip:alice@example.org>"),	       /* NUTAG_PROXY((url_string_t *)s2->contact->m_url), */	       /* Use internal DNS server */	       NUTAG_PROXY("sip:example.org"),#if HAVE_WIN32	       SRESTAG_RESOLV_CONF("NUL"),#else	       SRESTAG_RESOLV_CONF("/dev/null"),#endif	       ta_tags(ta));  ta_end(ta);    return s2->nua;}void s2_nua_teardown(void){  nua_destroy(s2->nua);  s2->nua = NULL;  s2_teardown();}/* ====================================================================== *//** Register NUA user. * * <pre> *  A                  B *  |-----REGISTER---->| *  |<-----200 OK------| *  |                  | * </pre> */void s2_register_setup(void){  nua_handle_t *nh;  struct message *m;  assert(s2 && s2->nua);  assert(!s2->registration->nh);  nh = nua_handle(s2->nua, NULL, TAG_END());  nua_register(nh, TAG_END());  m = s2_wait_for_request(SIP_METHOD_REGISTER);  assert(m);  s2_save_register(m);  s2_respond_to(m, NULL,		SIP_200_OK,		SIPTAG_CONTACT(s2->registration->contact),		TAG_END());  s2_free_message(m);  assert(s2->registration->contact != NULL);  s2_check_event(nua_r_register, 200);  s2->registration->nh = nh;}/** Un-register NUA user. * * <pre> *  A                  B *  |-----REGISTER---->| *  |<-----200 OK------| *  |                  | * </pre> */void s2_register_teardown(void){  if (s2 && s2->registration->nh) {    nua_handle_t *nh = s2->registration->nh;    struct message *m;    nua_unregister(nh, TAG_END());        m = s2_wait_for_request(SIP_METHOD_REGISTER); assert(m);    s2_save_register(m);    s2_respond_to(m, NULL,		  SIP_200_OK,		  SIPTAG_CONTACT(s2->registration->contact),		  TAG_END());    assert(s2->registration->contact == NULL);    s2_free_message(m);    s2_check_event(nua_r_unregister, 200);    nua_handle_destroy(nh);    s2->registration->nh = NULL;  }}

⌨️ 快捷键说明

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