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

📄 tport.c

📁 Internet Phone, Chat, Conferencing
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Register receiving function with events specified above */  if ((index = su_root_register(mr->mr_root, wait, wakeup, self, 0)) == -1)    TPORT_CONNECT_ERROR(su_errno(), su_root_register);  /* */  if (tport_setname(self, tpn->tpn_proto, 		    (void *)ai->ai_addr, tpn->tpn_canon) == -1)     TPORT_CONNECT_ERROR(su_errno(), tport_setname);  self->tp_socket   = s;  self->tp_index    = index;  self->tp_events   = events;  self->tp_connected = ai->ai_socktype != SOCK_DGRAM;  self->tp_conn_orient = 1;#if HAVE_SIGCOMP  if (tpn->tpn_comp == pri->pri_primary->tp_name->tpn_comp)    self->tp_name->tpn_comp = pri->pri_primary->tp_name->tpn_comp;  if (!pri->pri_primary->tp_name->tpn_comp)    self->tp_sigcomp->sc_infmt = format_is_noncomp;#endif#if HAVE_TLS  if (pri->pri_primary->tp_tls) {    self->tp_tls = tls_init_client(pri->pri_primary->tp_tls, s);    if (!self->tp_tls)      TPORT_CONNECT_ERROR(errno, tls_init_client);  }#endif  memcpy(self->tp_addr, ai->ai_addr, self->tp_addrlen = ai->ai_addrlen);    SU_DEBUG_5(("%s(%p): %s " TPN_FORMAT "\n", 	      __func__, self, "connecting to",	      TPN_ARGS(self->tp_name)));  tprb_append(&pri->pri_secondary, self);  return self;}/** Destroy a secondary transport. @internal */static void tport_zap_secondary(tport_t *self){  tport_master_t *mr;  if (self == NULL)    return;  /* Remove from rbtree */  tprb_remove(&self->tp_pri->pri_secondary, self);  if (self->tp_msg) {    msg_destroy(self->tp_msg), self->tp_msg = NULL;    SU_DEBUG_3(("%s(%p): zapped partially received message\n", 		__func__, self));  }  if (self->tp_queue && self->tp_queue[self->tp_qhead]) {    size_t n = 0, i, N = self->tp_params->tpp_qsize;    for (i = self->tp_qhead; self->tp_queue[i]; i = (i + 1) % N) {      msg_destroy(self->tp_queue[i]), self->tp_queue[i] = NULL;      n++;    }    SU_DEBUG_3(("%s(%p): zapped %lu queued messages\n", 		__func__, self, (LU)n));  }  if (self->tp_pused) {    SU_DEBUG_3(("%s(%p): zapped with pending requests\n", __func__, self));  }  mr = self->tp_master;  if (self->tp_index)    su_root_deregister(mr->mr_root, self->tp_index);  self->tp_index = 0;  if (self->tp_socket != -1)    su_close(self->tp_socket);  self->tp_socket = -1;#if HAVE_TLS  if (self->tp_tls)    tls_free(self->tp_tls);#endif#if HAVE_SIGCOMP  if (self->tp_sigcomp) {    tport_sigcomp_t *sc = self->tp_sigcomp;    if (sc->sc_udvm)      sigcomp_udvm_free(sc->sc_udvm), sc->sc_udvm = NULL;    if (sc->sc_compressor)      sigcomp_compressor_free(sc->sc_compressor), sc->sc_compressor = NULL;  }#endif  su_home_zap(self->tp_home);}/** Create a new transport reference. */tport_t *tport_incref(tport_t *tp){  if (tp) {    if (tp->tp_refs >= 0)      tp->tp_refs++;    else if (tp->tp_refs == -1)      tp->tp_refs = 1;  }  return tp;}/** Destroy a transport reference. */void tport_decref(tport_t **ttp){  assert(ttp);  if (*ttp) {    if ((*ttp)->tp_refs > 0)      if (--(*ttp)->tp_refs == 0 && (*ttp)->tp_params->tpp_idle == 0)	if (!tport_is_closed(*ttp))	  tport_close(*ttp);    *ttp = NULL;  }}/** Get transport parameters. * * @param self          pointer to a transport object * @param tag,value,... list of tags */int tport_get_params(tport_t const *self,		     tag_type_t tag, tag_value_t value, ...){  ta_list ta;  int n;  tport_params_t const *tpp;  if (self == NULL)    return su_seterrno(EINVAL);  tpp = self->tp_params;  ta_start(ta, tag, value);  n = tl_tgets(ta_args(ta),	       TPTAG_MTU(tpp->tpp_mtu),	       TPTAG_REUSE(self->tp_reusable),	       TPTAG_CONNECT(tpp->tpp_conn_orient),	       TPTAG_QUEUESIZE(tpp->tpp_qsize),	       TPTAG_IDLE(tpp->tpp_idle),	       TPTAG_TIMEOUT(tpp->tpp_timeout),	       TPTAG_SDWN_ERROR(tpp->tpp_sdwn_error),	       TPTAG_DEBUG_DROP(tpp->tpp_drop),	       TPTAG_THRPSIZE(tpp->tpp_thrpsize),	       TPTAG_THRPRQSIZE(tpp->tpp_thrprqsize),	       TAG_END());  ta_end(ta);  return n;}/** Set transport parameters. * * @param self          pointer to a transport object * @param tag,value,... list of tags */int tport_set_params(tport_t *self,		     tag_type_t tag, tag_value_t value, ...){  ta_list ta;  int n;  tport_params_t tpp[1], *tpp0;  int connect, sdwn_error, reusable;  struct sigcomp_compartment *cc = NONE;  if (self == NULL)    return su_seterrno(EINVAL);  memcpy(tpp, tpp0 = self->tp_params, sizeof *tpp);  connect = tpp->tpp_conn_orient;  sdwn_error = tpp->tpp_sdwn_error;  reusable = self->tp_reusable;  ta_start(ta, tag, value);  n = tl_gets(ta_args(ta),	      TPTAG_MTU_REF(tpp->tpp_mtu),	      TAG_IF(!self->tp_queue, TPTAG_QUEUESIZE_REF(tpp->tpp_qsize)),	      TPTAG_IDLE_REF(tpp->tpp_idle),	      TPTAG_TIMEOUT_REF(tpp->tpp_timeout),	      TPTAG_DEBUG_DROP_REF(tpp->tpp_drop),	      TPTAG_THRPSIZE_REF(tpp->tpp_thrpsize),	      TPTAG_THRPRQSIZE_REF(tpp->tpp_thrprqsize),	      TPTAG_SIGCOMP_LIFETIME_REF(tpp->tpp_sigcomp_lifetime),	      TPTAG_CONNECT_REF(connect),	      TPTAG_SDWN_ERROR_REF(sdwn_error),	      TPTAG_REUSE_REF(reusable),	      TPTAG_COMPARTMENT_REF(cc),	      TAG_END());  ta_end(ta);  if (n == 0)    return 0;  if (tpp->tpp_idle > 0 && tpp->tpp_idle < 2000)    tpp->tpp_idle = 2000;  if (tpp->tpp_timeout < 1000)    tpp->tpp_timeout = 1000;  if (tpp->tpp_drop > 1000)    tpp->tpp_drop = 1000;  if (tpp->tpp_thrprqsize > 0)    tpp->tpp_thrprqsize = tpp0->tpp_thrprqsize;  if (tpp->tpp_sigcomp_lifetime != 0 && tpp->tpp_sigcomp_lifetime < 30)    tpp->tpp_sigcomp_lifetime = 30;  if (tpp->tpp_qsize >= 1000)    tpp->tpp_qsize = 1000;  tpp->tpp_sdwn_error = sdwn_error;  self->tp_reusable = reusable;  /* Currently only primary UDP transport can *not* be connection oriented */   tpp->tpp_conn_orient = connect     || !tport_is_primary(self) || !tport_is_dgram(self);  if (tport_is_secondary(self) &&       self->tp_params == self->tp_pri->pri_primary->tp_params) {    tpp0 = su_zalloc(self->tp_home, sizeof *tpp0); if (!tpp0) return -1;  }#if HAVE_SIGCOMP  if (cc != NONE && self == self->tp_master->mr_master) {    if (self->tp_master->mr_compartment)      sigcomp_compartment_unref(self->tp_master->mr_compartment);    self->tp_master->mr_compartment = sigcomp_compartment_ref(cc);  }#endif  memcpy(tpp0, tpp, sizeof *tpp);  return n;}/** Bind transport objects.  * * @deprecated  * Use tport_tbind(). */int tport_bind(tport_t *self,	       tp_name_t const *tpn,	       char const * const transports[],	       int flags){  return tport_tbind(self, tpn, transports, TAG_END());}/** Bind transport objects. * * @param self        pointer to a transport object * @param tpn         desired transport address * @param transports  list of protocol names supported by stack * @param tag,value,... tagged argument list */int tport_tbind(tport_t *self,		tp_name_t const *tpn,		char const * const transports[],		tag_type_t tag, tag_value_t value, ...){  ta_list ta;  int server = 1, retval;  tp_name_t mytpn[1];  tport_master_t *mr;  if (self == NULL || tport_is_secondary(self) ||      tpn == NULL || transports == NULL) {    su_seterrno(EINVAL);    return -1;  }  *mytpn = *tpn;  if (mytpn->tpn_ident == NULL)    mytpn->tpn_ident = self->tp_ident;  ta_start(ta, tag, value);  tl_gets(ta_args(ta),	  TPTAG_SERVER_REF(server),	  TPTAG_IDENT_REF(mytpn->tpn_ident),	  TAG_END());  mr = self->tp_master; assert(mr);  if (server)    retval = tport_bind_server(mr, mytpn, transports, ta_args(ta));  else    retval = tport_bind_client(mr, mytpn, transports, ta_args(ta));  ta_end(ta);  return retval;}/** Bind primary transport objects used by a client-only application. * @internal */int tport_bind_client(tport_master_t *mr,                      tp_name_t const *tpn,                      char const * const transports[],		      tagi_t *tags){  int i;  tport_primary_t *pri = NULL, **tbf;  tport_t *tp;  SU_DEBUG_5(("%s(%p) to " TPN_FORMAT "\n", __func__, mr, TPN_ARGS(tpn)));  for (tbf = &mr->mr_primaries; *tbf; tbf = &(*tbf)->pri_next)    ;  for (i = 0; transports[i]; i++) {    su_addrinfo_t hints[1];    char const *proto = transports[i];        if (strcmp(proto, tpn->tpn_proto) != 0 &&         strcmp(tpn->tpn_proto, tpn_any) != 0)      continue;    /* Resolve protocol, skip unknown transport protocols */    if (getprotohints(hints, proto, AI_PASSIVE) < 0)      continue;    if (!(pri = tport_alloc_primary(mr)))      break;    tp = pri->pri_primary;    #if HAVE_TLS    if (strcasecmp(proto, "tls") == 0) {      tp->tp_tls = tport_init_tls(tags);      if (tp->tp_tls == NULL)	break;    }#endif    pri->pri_family   = hints->ai_family;    pri->pri_socktype = hints->ai_socktype;    pri->pri_protocol = hints->ai_protocol;    tp->tp_name->tpn_proto = proto;    tp->tp_name->tpn_host = "*";    tp->tp_name->tpn_port = "*";    tp->tp_name->tpn_canon = "*";    tp->tp_name->tpn_ident = su_strdup(tp->tp_home, tpn->tpn_ident);    tport_init_compression(pri, tpn->tpn_comp, tags);  }  if (!pri)    tport_zap_primary(*tbf);  return pri ? 0 : -1;}/** Bind primary transport objects used by a server application. */int tport_bind_server(tport_master_t *mr,                      tp_name_t const *tpn,                      char const * const transports[],		      tagi_t *tags){  char hostname[256];  char const *proto, *canon = NULL, *host, *port;  char port0[16];  int ephemeral_port;  int i, error = 0, not_supported, family = 0;  tport_primary_t *pri = NULL, **tbf;  su_localinfo_t *li = NULL;  unsigned p;  unsigned short step = 0;  struct tport_nat_s *nat;#if SU_HAVE_IN6  if (!mr->mr_boundserver) {    /* Check if we can bind to IPv6 separately */    su_sockaddr_t su[1], su4[1];    socklen_t sulen, su4len;    int s6, s4;    s4 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    s6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);    memset(su, 0, sizeof *su);    su->su_len = sulen = (sizeof su->su_sin6);    su->su_family = AF_INET6;    memset(su4, 0, sizeof *su4);    su4->su_len = su4len = (sizeof su->su_sin);    su4->su_family = AF_INET;    if (bind(s6, &su->su_sa, sulen) < 0)      ;    else if (getsockname(s6, &su->su_sa, &sulen) < 0)      ;    else if ((su4->su_port = su->su_port) != 0 && 	     bind(s4, &su4->su_sa, su4len) == 0)      mr->mr_bindv6only = 1;    su_close(s6), su_close(s4);    mr->mr_boundserver = 1;  }#endif  for (tbf = &mr->mr_primaries; *tbf; tbf = &(*tbf)->pri_next)    ;  SU_DEBUG_5(("%s(%p) to " TPN_FORMAT "\n", __func__, mr, TPN_ARGS(tpn)));  nat = tport_nat_initialize_nat_traversal(mr, tpn, &transports, tags);  if (!nat)     SU_DEBUG_1(("%s: %s\n", __func__, strerror(errno)));  if (tpn->tpn_host == NULL || strcmp(tpn->tpn_host, tpn_any) == 0) {    /* Use a local IP address */    host = NULL;  }#ifdef SU_HAVE_IN6  else if (tpn->tpn_host && tpn->tpn_host[0] == '[') {    /* Remove [] around IPv6 addresses. */    host = strcpy(hostname, tpn->tpn_host + 1);    hostname[strlen(hostname) - 1] = '\0';  }#endif  else    host = tpn->tpn_host;   if (tpn->tpn_port != NULL && strlen(tpn->tpn_port) > 0 &&      strcmp(tpn->tpn_port, tpn_any) != 0)    port = tpn->tpn_port, ephemeral_port = 0;  else     port = "", ephemeral_port = -1;			/* XXX */  if (host && (strcmp(host, "0.0.0.0") == 0 || strcmp(host, "0") == 0))    host = NULL, family = AF_INET;#if SU_HAVE_IN6  else if (host && strcmp(host, "::") == 0)    host = NULL, family = AF_INET6;#endif  if (tpn->tpn_canon && strcmp(tpn->tpn_canon, tpn_any) &&      (host || tpn->tpn_canon != tpn->tpn_host))    canon = tpn->tpn_canon;  else if (nat) {    /* NULL if UPnP not present */    canon = tport_nat_get_external_ip_address(nat);  }  if (host == NULL) {    su_localinfo_t hints[1] = {{ 0 }};        hints->li_flags = 0;    hints->li_family = family;    hints->li_scope = LI_SCOPE_GLOBAL | LI_SCOPE_SITE | LI_SCOPE_HOST;    error = su_getlocalinfo(hints, &li);    if (error) {#if SU_HAVE_IN6      SU_DEBUG_3(("%s(%p): su_getlocalinfo() for %s address: %s\n", 		  __func__, mr, 		  family == AF_INET6 ? "ip6" 		  : family == AF_INET ? "ip4" : "ip",		  su_gli_strerror(error)));#else      SU_DEBUG_3(("%s(%p): su_getlocalinfo() for %s address: %s\n", 		  __func__, mr, 		  family == AF_INET ? "ip4" : "ip",		  su_gli_strerror(error)));#endif      su_seterrno(ENOENT);      return -1;    }  }  /* 

⌨️ 快捷键说明

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