00001
00002
00003 #include "SOCK_Dgram_Mcast_QoS.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_sys_socket.h"
00006
00007 #if defined (ACE_WIN32)
00008 #include "ace/Sock_Connect.h"
00009 #endif
00010
00011 #if !defined (__ACE_INLINE__)
00012 #include "SOCK_Dgram_Mcast_QoS.inl"
00013 #endif
00014
00015
00016
00017 #if ! defined (IMR_MULTIADDR)
00018 #define IMR_MULTIADDR imr_multiaddr
00019 #endif
00020
00021
00022 ACE_RCSID (QoS,
00023 SOCK_Dgram_Mcast_QoS,
00024 "$Id: SOCK_Dgram_Mcast_QoS.cpp 80826 2008-03-04 14:51:23Z wotte $")
00025
00026 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00027
00028 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Mcast_QoS)
00029
00030
00031
00032 ACE_SOCK_Dgram_Mcast_QoS::ACE_SOCK_Dgram_Mcast_QoS (options opts)
00033 : ACE_SOCK_Dgram_Mcast (opts)
00034 {
00035 ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::ACE_SOCK_Dgram_Mcast_QoS");
00036 }
00037
00038 int
00039 ACE_SOCK_Dgram_Mcast_QoS::open (const ACE_INET_Addr &addr,
00040 const ACE_QoS_Params &qos_params,
00041 int protocol_family,
00042 int protocol,
00043 ACE_Protocol_Info *protocolinfo,
00044 ACE_SOCK_GROUP g,
00045 u_long flags,
00046 int reuse_addr)
00047 {
00048 ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::open");
00049
00050 ACE_UNUSED_ARG (qos_params);
00051
00052
00053
00054 if (this->get_handle () != ACE_INVALID_HANDLE)
00055 return 0;
00056
00057 ACE_DEBUG ((LM_DEBUG,
00058 "Get Handle Returns Invalid Handle\n"));
00059
00060 if (ACE_SOCK::open (SOCK_DGRAM,
00061 protocol_family,
00062 protocol,
00063 protocolinfo,
00064 g,
00065 flags,
00066 reuse_addr) == -1)
00067 return -1;
00068
00069 return this->open_i (addr, 0, reuse_addr);
00070 }
00071
00072
00073 int
00074 ACE_SOCK_Dgram_Mcast_QoS::subscribe_ifs (const ACE_INET_Addr &mcast_addr,
00075 const ACE_QoS_Params &qos_params,
00076 const ACE_TCHAR *net_if,
00077 int protocol_family,
00078 int protocol,
00079 int reuse_addr,
00080 ACE_Protocol_Info *protocolinfo)
00081 {
00082 ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::subscribe_ifs");
00083 #if defined (ACE_WIN32)
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 if (net_if == 0)
00104 {
00105 ACE_INET_Addr *if_addrs = 0;
00106 size_t if_cnt;
00107
00108 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
00109 return -1;
00110
00111 size_t nr_subscribed = 0;
00112
00113 if (if_cnt < 2)
00114 {
00115 if (this->subscribe (mcast_addr,
00116 qos_params,
00117 reuse_addr,
00118 ACE_TEXT ("0.0.0.0"),
00119 protocol_family,
00120 protocol,
00121 protocolinfo) == 0)
00122 ++nr_subscribed;
00123 }
00124 else
00125
00126
00127 while (if_cnt > 0)
00128 {
00129 --if_cnt;
00130
00131
00132 if (if_addrs[if_cnt].is_loopback())
00133 continue;
00134 if (this->subscribe (mcast_addr,
00135 qos_params,
00136 reuse_addr,
00137 ACE_TEXT_CHAR_TO_TCHAR
00138 (if_addrs[if_cnt].get_host_addr()),
00139 protocol_family,
00140 protocol,
00141 protocolinfo) == 0)
00142 ++nr_subscribed;
00143 }
00144
00145 delete [] if_addrs;
00146
00147 if (nr_subscribed == 0)
00148 {
00149 errno = ENODEV;
00150 return -1;
00151 }
00152 else
00153
00154
00155
00156 return 1;
00157 }
00158 #else
00159 ACE_UNUSED_ARG (mcast_addr);
00160 ACE_UNUSED_ARG (qos_params);
00161 ACE_UNUSED_ARG (protocol_family);
00162 ACE_UNUSED_ARG (protocol);
00163 ACE_UNUSED_ARG (reuse_addr);
00164 ACE_UNUSED_ARG (protocolinfo);
00165 #endif
00166
00167
00168
00169 if (this->make_multicast_ifaddr (0,
00170 mcast_addr,
00171 net_if) == -1)
00172 return -1;
00173 else
00174 return 0;
00175 }
00176
00177 int
00178 ACE_SOCK_Dgram_Mcast_QoS::subscribe (const ACE_INET_Addr &mcast_addr,
00179 const ACE_QoS_Params &qos_params,
00180 int reuse_addr,
00181 const ACE_TCHAR *net_if,
00182 int protocol_family,
00183 int protocol,
00184 ACE_Protocol_Info *protocolinfo,
00185 ACE_SOCK_GROUP g,
00186 u_long flags,
00187 ACE_QoS_Session *qos_session)
00188 {
00189 ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::subscribe");
00190
00191 if (this->open (mcast_addr,
00192 qos_params,
00193 protocol_family,
00194 protocol,
00195 protocolinfo,
00196 g,
00197 flags,
00198 reuse_addr) == -1)
00199 return -1;
00200
00201
00202 int result = this->subscribe_ifs (mcast_addr,
00203 qos_params,
00204 net_if,
00205 protocol_family,
00206 protocol,
00207 reuse_addr,
00208 protocolinfo);
00209
00210 if (result != 0)
00211 return result;
00212
00213
00214
00215 else
00216 {
00217
00218
00219 if (qos_session != 0 && mcast_addr == qos_session->dest_addr ())
00220 {
00221
00222 if (this->qos_manager_.join_qos_session (qos_session) == -1)
00223 ACE_ERROR_RETURN ((LM_ERROR,
00224 ACE_TEXT ("Unable to join QoS Session\n")),
00225 -1);
00226 }
00227 else
00228 {
00229 if (this->close () != 0)
00230 ACE_ERROR ((LM_ERROR,
00231 ACE_TEXT ("Unable to close socket\n")));
00232 ACE_ERROR_RETURN ((LM_ERROR,
00233 ACE_TEXT ("Dest Addr in the QoS Session does")
00234 ACE_TEXT (" not match the address passed into")
00235 ACE_TEXT (" subscribe\n")),
00236 -1);
00237 }
00238
00239 ip_mreq ret_mreq;
00240 this->make_multicast_ifaddr (&ret_mreq, mcast_addr, net_if);
00241
00242
00243 if (ACE_OS::join_leaf (this->get_handle (),
00244 reinterpret_cast<const sockaddr *> (&ret_mreq.IMR_MULTIADDR.s_addr),
00245 sizeof ret_mreq.IMR_MULTIADDR.s_addr,
00246 qos_params) == ACE_INVALID_HANDLE
00247 && errno != ENOTSUP)
00248 return -1;
00249
00250 else
00251 if (qos_params.socket_qos () != 0 && qos_session != 0)
00252 qos_session->qos (*(qos_params.socket_qos ()));
00253
00254 return 0;
00255 }
00256 }
00257
00258 ACE_END_VERSIONED_NAMESPACE_DECL