internal Boolean AddTransport(String localHost, ushort localPort, TNET_Socket.tnet_socket_type_t type, String description) { TSIP_Transport transport = TNET_Socket.IsStreamType(type) ? (TSIP_Transport) new TSIP_TransportTCP(mStack, localHost, localPort, TNET_Socket.IsIPv6Type(type), description) : (TSIP_Transport) new TSIP_TransportUDP(mStack, localHost, localPort, TNET_Socket.IsIPv6Type(type), description); if (transport != null) { // FIXME:DO not forget to call "transport.NetworkEvent -= this.TSIP_Transport_NetworkEvent;" before removing the transport transport.NetworkEvent += this.TSIP_Transport_NetworkEvent; mTransports.Add(transport); } return(transport != null); }
internal Boolean SendMessage(String branch, TSIP_Message message) { String destIP = null; ushort destPort = 5060; TSIP_Transport transport = this.FindTransport(message, out destIP, out destPort); if (transport != null) { return(transport.Send(branch, message, destIP, destPort)); } return(false); }
private TSIP_Transport FindTransport(TSIP_Message msg, out String destIP, out ushort destPort) { TSIP_Transport transport = null; destIP = mStack.ProxyHost; destPort = mStack.ProxyPort; /* =========== Sending Request ========= */ if (msg.IsRequest) { /* Request are always sent to the Proxy-CSCF */ foreach (TSIP_Transport t in mTransports) { if (t.Type == mStack.ProxyType) { transport = t; break; } } } /* =========== Sending Response ========= */ else if (msg.FirstVia != null) { if (!String.Equals(msg.FirstVia.Transport, "UDP", StringComparison.InvariantCultureIgnoreCase)) // Reliable { /* RFC 3261 - 18.2.2 Sending Responses * If the "sent-protocol" is a reliable transport protocol such as * TCP or SCTP, or TLS over those, the response MUST be sent using * the existing connection to the source of the original request * that created the transaction, if that connection is still open. * This requires the server transport to maintain an association * between server transactions and transport connections. If that * connection is no longer open, the server SHOULD open a * connection to the IP address in the "received" parameter, if * present, using the port in the "sent-by" value, or the default * port for that transport, if no port is specified. If that * connection attempt fails, the server SHOULD use the procedures * in [4] for servers in order to determine the IP address and * port to open the connection and send the response to. */ } else { if (!String.IsNullOrEmpty(msg.FirstVia.Maddr))/*== UNRELIABLE MULTICAST ===*/ { /* RFC 3261 - 18.2.2 Sending Responses * Otherwise, if the Via header field value contains a "maddr" parameter, the * response MUST be forwarded to the address listed there, using * the port indicated in "sent-by", or port 5060 if none is present. * If the address is a multicast address, the response SHOULD be * sent using the TTL indicated in the "ttl" parameter, or with a * TTL of 1 if that parameter is not present. */ } else /*=== UNRELIABLE UNICAST ===*/ { if (!String.IsNullOrEmpty(msg.FirstVia.Received)) { if (msg.FirstVia.RPort > 0) { /* RFC 3581 - 4. Server Behavior * When a server attempts to send a response, it examines the topmost * Via header field value of that response. If the "sent-protocol" * component indicates an unreliable unicast transport protocol, such as * UDP, and there is no "maddr" parameter, but there is both a * "received" parameter and an "rport" parameter, the response MUST be * sent to the IP address listed in the "received" parameter, and the * port in the "rport" parameter. The response MUST be sent from the * same address and port that the corresponding request was received on. * This effectively adds a new processing step between bullets two and * three in Section 18.2.2 of SIP [1]. */ destIP = msg.FirstVia.Received; destPort = (ushort)msg.FirstVia.RPort; } else { /* RFC 3261 - 18.2.2 Sending Responses * Otherwise (for unreliable unicast transports), if the top Via * has a "received" parameter, the response MUST be sent to the * address in the "received" parameter, using the port indicated * in the "sent-by" value, or using port 5060 if none is specified * explicitly. If this fails, for example, elicits an ICMP "port * unreachable" response, the procedures of Section 5 of [4] * SHOULD be used to determine where to send the response. */ destIP = msg.FirstVia.Received; destPort = (ushort)(msg.FirstVia.Port > 0 ? msg.FirstVia.Port : 5060); } } else if (String.IsNullOrEmpty(msg.FirstVia.Received)) { /* RFC 3261 - 18.2.2 Sending Responses * Otherwise, if it is not receiver-tagged, the response MUST be * sent to the address indicated by the "sent-by" value, using the * procedures in Section 5 of [4]. */ destIP = msg.FirstVia.Host; if (msg.FirstVia.Port > 0) { destPort = (ushort)msg.FirstVia.Port; } } } } } //tsk_list_item_t *item; //tsip_transport_t *curr; //tsk_list_foreach(item, self->transports) //{ // curr = item->data; // if(tsip_transport_have_socket(curr, msg->local_fd)) // { // transport = curr; // break; // } //} return(transport); }