📄 extl_udp.c
字号:
static inteXtl_update_local_target (osip_message_t * req){ int pos = 0; struct eXosip_account_info *ainfo = NULL; char *proxy = NULL; int i; if (MSG_IS_REQUEST (req)) { if (req->from != NULL && req->from->url != NULL && req->from->url->host != NULL) proxy = req->from->url->host; } else { if (req->to != NULL && req->to->url != NULL && req->to->url->host != NULL) proxy = req->to->url->host; } if (proxy != NULL) { for (i = 0; i < MAX_EXOSIP_ACCOUNT_INFO; i++) { if (eXosip.account_entries[i].proxy[0] != '\0') { if (strstr (eXosip.account_entries[i].proxy, proxy) != NULL || strstr (proxy, eXosip.account_entries[i].proxy) != NULL) { /* use ainfo */ if (eXosip.account_entries[i].nat_ip[0] != '\0') { ainfo = &eXosip.account_entries[i]; break; } } } } } if (udp_firewall_ip != '\0') { while (!osip_list_eol (&req->contacts, pos)) { osip_contact_t *co; co = (osip_contact_t *) osip_list_get (&req->contacts, pos); pos++; if (co != NULL && co->url != NULL && co->url->host != NULL && 0 == osip_strcasecmp (co->url->host, udp_firewall_ip)) { if (ainfo == NULL) { if (co->url->port == NULL && 0 != osip_strcasecmp (udp_firewall_port, "5060")) { co->url->port = osip_strdup (udp_firewall_port); } else if (co->url->port != NULL && 0 != osip_strcasecmp (udp_firewall_port, co->url->port)) { osip_free (co->url->port); co->url->port = osip_strdup (udp_firewall_port); } } else { if (co->url->port == NULL && ainfo->nat_port != 5060) { co->url->port = osip_malloc (10); if (co->url->port == NULL) return OSIP_NOMEM; snprintf (co->url->port, 9, "%i", ainfo->nat_port); } else if (co->url->port != NULL && ainfo->nat_port != atoi (co->url->port)) { osip_free (co->url->port); co->url->port = osip_malloc (10); if (co->url->port == NULL) return OSIP_NOMEM; snprintf (co->url->port, 9, "%i", ainfo->nat_port); } } } } } return OSIP_SUCCESS;}#ifndef INET6_ADDRSTRLEN#define INET6_ADDRSTRLEN 46#endifstatic intudp_tl_send_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ int len = 0; size_t length = 0; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; char *message; char ipbuf[INET6_ADDRSTRLEN]; int i; if (udp_socket <= 0) return -1; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5060; } eXtl_update_local_target (sip); i = -1;#ifndef MINISIZE if (tr != NULL && tr->record.name[0] != '\0' && tr->record.srventry[0].srv[0] != '\0') { /* always choose the first here. if a network error occur, remove first entry and replace with next entries. */ osip_srv_entry_t *srv; int n = 0; for (srv = &tr->record.srventry[0]; n < 10 && tr->record.srventry[0].srv[0]; srv = &tr->record.srventry[0]) { i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP); if (i == 0) { host = srv->srv; port = srv->port; break; } memmove (&tr->record.srventry[0], &tr->record.srventry[1], 9 * sizeof (osip_srv_entry_t)); memset (&tr->record.srventry[9], 0, sizeof (osip_srv_entry_t)); i = -1; /* copy next element */ n++; } }#endif /* if SRV was used, distination may be already found */ if (i != 0) { i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP); } if (i != 0) { return -1; } memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); len = addrinfo->ai_addrlen; eXosip_freeaddrinfo (addrinfo); /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove (&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_add (&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } switch (((struct sockaddr *) &addr)->sa_family) { case AF_INET: inet_ntop (((struct sockaddr *) &addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf, sizeof (ipbuf)); break; case AF_INET6: inet_ntop (((struct sockaddr *) &addr)->sa_family, &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf, sizeof (ipbuf)); break; default: strncpy (ipbuf, "(unknown)", sizeof (ipbuf)); break; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: (to dest=%s:%i)\n%s\n", ipbuf, port, message)); if (tr != NULL) { if (tr->ict_context != NULL) osip_ict_set_destination (tr->ict_context, osip_strdup (ipbuf), port); if (tr->nict_context != NULL) osip_nict_set_destination (tr->nict_context, osip_strdup (ipbuf), port); } if (0 > sendto (udp_socket, (const void *) message, length, 0, (struct sockaddr *) &addr, len)) {#ifdef WIN32 if (WSAECONNREFUSED == WSAGetLastError ())#else if (ECONNREFUSED == errno)#endif { /* This can be considered as an error, but for the moment, I prefer that the application continue to try sending message again and again... so we are not in a error case. Nevertheless, this error should be announced! ALSO, UAS may not have any other options than retry always on the same port. */ osip_free (message); return 1; } else {#ifndef MINISIZE /* delete first SRV entry that is not reachable */ if (tr != NULL && tr->record.name[0] != '\0' && tr->record.srventry[0].srv[0] != '\0') { memmove (&tr->record.srventry[0], &tr->record.srventry[1], 9 * sizeof (osip_srv_entry_t)); memset (&tr->record.srventry[9], 0, sizeof (osip_srv_entry_t)); osip_free (message); return OSIP_SUCCESS; /* retry for next retransmission! */ }#endif /* SIP_NETWORK_ERROR; */ osip_free (message); return -1; } } if (eXosip.keep_alive > 0) { if (MSG_IS_REGISTER (sip)) { eXosip_reg_t *reg = NULL; if (_eXosip_reg_find (®, tr) == 0) { memcpy (&(reg->addr), &addr, len); reg->len = len; } } } osip_free (message); return OSIP_SUCCESS;}static intudp_tl_keepalive (void){ char buf[4] = "jaK"; eXosip_reg_t *jr; for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) { if (jr->len > 0) { if (sendto (udp_socket, (const void *) buf, 4, 0, (struct sockaddr *) &(jr->addr), jr->len) > 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: Keep Alive sent on UDP!\n")); } } } return OSIP_SUCCESS;}static intudp_tl_set_socket (int socket){ udp_socket = socket; return OSIP_SUCCESS;}static intudp_tl_masquerade_contact (const char *public_address, int port){ if (public_address == NULL || public_address[0] == '\0') { memset (udp_firewall_ip, '\0', sizeof (udp_firewall_ip)); return OSIP_SUCCESS; } snprintf (udp_firewall_ip, sizeof (udp_firewall_ip), "%s", public_address); if (port > 0) { snprintf (udp_firewall_port, sizeof (udp_firewall_port), "%i", port); } return OSIP_SUCCESS;}static intudp_tl_get_masquerade_contact (char *ip, int ip_size, char *port, int port_size){ memset (ip, 0, ip_size); memset (port, 0, port_size); if (udp_firewall_ip != '\0') snprintf (ip, ip_size, "%s", udp_firewall_ip); if (udp_firewall_port != '\0') snprintf (port, port_size, "%s", udp_firewall_port); return OSIP_SUCCESS;}struct eXtl_protocol eXtl_udp = { 1, 5060, "UDP", "0.0.0.0", IPPROTO_UDP, AF_INET, 0, 0, &udp_tl_init, &udp_tl_free, &udp_tl_open, &udp_tl_set_fdset, &udp_tl_read_message, &udp_tl_send_message, &udp_tl_keepalive, &udp_tl_set_socket, &udp_tl_masquerade_contact, &udp_tl_get_masquerade_contact};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -