📄 extl_tcp.c
字号:
tcp_socket_tab[pos].remote_ip, tcp_socket_tab[pos].remote_port); } else if (i < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not read socket - close it\n")); close (tcp_socket_tab[pos].socket); memset (&(tcp_socket_tab[pos]), 0, sizeof (tcp_socket_tab[pos])); } else if (i == 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "End of stream (read 0 byte from %s:%i)\n", tcp_socket_tab[pos].remote_ip, tcp_socket_tab[pos].remote_port)); close (tcp_socket_tab[pos].socket); memset (&(tcp_socket_tab[pos]), 0, sizeof (tcp_socket_tab[pos])); }#ifndef MINISIZE else { /* we expect at least one byte, otherwise there's no doubt that it is not a sip message ! */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Dummy SIP message received (size=%i)\n", i)); }#endif } } if (buf != NULL) osip_free (buf); return OSIP_SUCCESS;}static int_tcp_tl_find_socket (char *host, int port){ int pos; for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tcp_socket_tab[pos].socket != 0) { if (0 == osip_strcasecmp (tcp_socket_tab[pos].remote_ip, host) && port == tcp_socket_tab[pos].remote_port) return tcp_socket_tab[pos].socket; } } return -1;}static int_tcp_tl_connect_socket (char *host, int port){ int pos; int res; struct addrinfo *addrinfo = NULL; struct addrinfo *curinfo; int sock = -1; char src6host[NI_MAXHOST]; memset (src6host, 0, sizeof (src6host)); for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tcp_socket_tab[pos].socket == 0) { break; } } if (pos == EXOSIP_MAX_SOCKETS) return -1; res = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_TCP); if (res) return -1; for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next) { if (curinfo->ai_protocol && curinfo->ai_protocol != IPPROTO_TCP) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Skipping protocol %d\n", curinfo->ai_protocol)); continue; } res = getnameinfo ((struct sockaddr *) curinfo->ai_addr, curinfo->ai_addrlen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (res == 0) { int i = _tcp_tl_find_socket (src6host, port); if (i >= 0) { eXosip_freeaddrinfo (addrinfo); return i; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "New binding with %s\n", src6host)); } sock = (int) socket (curinfo->ai_family, curinfo->ai_socktype, curinfo->ai_protocol); if (sock < 0) {#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot create socket!\n"));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot create socket %s!\n", strerror (errno)));#endif continue; } if (curinfo->ai_family == AF_INET6) {#ifdef IPV6_V6ONLY if (setsockopt_ipv6only (sock)) { close (sock); sock = -1;#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot set socket option!\n"));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot set socket option %s!\n", strerror (errno)));#endif continue; }#endif /* IPV6_V6ONLY */ } res = connect (sock, curinfo->ai_addr, curinfo->ai_addrlen); if (res < 0) {#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot bind socket node:%s family:%d\n", host, curinfo->ai_family));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot bind socket node:%s family:%d %s\n", host, curinfo->ai_family, strerror (errno)));#endif close (sock); sock = -1; continue; } break; } eXosip_freeaddrinfo (addrinfo); if (sock > 0) { tcp_socket_tab[pos].socket = sock; if (src6host[0] == '\0') osip_strncpy (tcp_socket_tab[pos].remote_ip, host, sizeof (tcp_socket_tab[pos].remote_ip) - 1); else osip_strncpy (tcp_socket_tab[pos].remote_ip, src6host, sizeof (tcp_socket_tab[pos].remote_ip) - 1); tcp_socket_tab[pos].remote_port = port; return sock; } return -1;}static inttcp_tl_send_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ size_t length = 0; char *message; int i; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5060; } /* 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; } /* Step 1: find existing socket to send message */ if (out_socket <= 0) { out_socket = _tcp_tl_find_socket (host, port); /* Step 2: create new socket with host:port */ if (out_socket <= 0) { out_socket = _tcp_tl_connect_socket (host, port); } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (to dest=%s:%i)\n", message, host, port)); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (reusing REQUEST connection)\n", message)); } if (out_socket <= 0) { return -1; } if (0 > send (out_socket, (const void *) message, length, 0)) {#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 { /* SIP_NETWORK_ERROR; */#if !defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "TCP error: \n%s\n", strerror (errno)));#endif osip_free (message); return -1; } } osip_free (message); return OSIP_SUCCESS;}static inttcp_tl_keepalive (void){ return OSIP_SUCCESS;}static inttcp_tl_set_socket (int socket){ tcp_socket = socket; return OSIP_SUCCESS;}static inttcp_tl_masquerade_contact (const char *public_address, int port){ if (public_address == NULL || public_address[0] == '\0') { memset (tcp_firewall_ip, '\0', sizeof (tcp_firewall_ip)); return OSIP_SUCCESS; } snprintf (tcp_firewall_ip, sizeof (tcp_firewall_ip), "%s", public_address); if (port > 0) { snprintf (tcp_firewall_port, sizeof (tcp_firewall_port), "%i", port); } return OSIP_SUCCESS;}static inttcp_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 (tcp_firewall_ip != '\0') snprintf (ip, ip_size, "%s", tcp_firewall_ip); if (tcp_firewall_port != '\0') snprintf (port, port_size, "%s", tcp_firewall_port); return OSIP_SUCCESS;}struct eXtl_protocol eXtl_tcp = { 1, 5060, "TCP", "0.0.0.0", IPPROTO_TCP, AF_INET, 0, 0, &tcp_tl_init, &tcp_tl_free, &tcp_tl_open, &tcp_tl_set_fdset, &tcp_tl_read_message, &tcp_tl_send_message, &tcp_tl_keepalive, &tcp_tl_set_socket, &tcp_tl_masquerade_contact, &tcp_tl_get_masquerade_contact};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -