00001 #include "ace_pch.h"
00002 #include "ace/SOCK_Dgram.h"
00003 #include "ace/Handle_Set.h"
00004 #include "ace/Synch.h"
00005 #include "ace/Log_Msg.h"
00006 #include "ace/INET_Addr.h"
00007 #include "ace/ACE.h"
00008
00009 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00010 #include "ace/SOCK_Dgram.i"
00011 #endif
00012
00013 ACE_RCSID (ace,
00014 SOCK_Dgram,
00015 "$Id: SOCK_Dgram.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $")
00016
00017 ACE_ALLOC_HOOK_DEFINE (ACE_SOCK_Dgram)
00018
00019 void
00020 ACE_SOCK_Dgram::dump (void) const
00021 {
00022 ACE_TRACE ("ACE_SOCK_Dgram::dump");
00023 }
00024
00025
00026
00027
00028
00029
00030 ssize_t
00031 ACE_SOCK_Dgram::recv (iovec *io_vec,
00032 ACE_Addr &addr,
00033 int flags,
00034 const ACE_Time_Value *timeout) const
00035 {
00036 ACE_TRACE ("ACE_SOCK_Dgram::recv");
00037 #if defined (FIONREAD)
00038 ACE_Handle_Set handle_set;
00039 handle_set.reset ();
00040 handle_set.set_bit (this->get_handle ());
00041
00042
00043
00044 int select_width;
00045 # if defined (ACE_WIN64)
00046
00047
00048 select_width = 0;
00049 # else
00050 select_width = int (this->get_handle ()) + 1;
00051 # endif
00052 switch (ACE_OS::select (select_width,
00053 handle_set,
00054 0, 0,
00055 timeout))
00056 {
00057 case -1:
00058 return -1;
00059
00060 case 0:
00061 errno = ETIME;
00062 return -1;
00063
00064 default:
00065
00066 break;
00067 }
00068
00069 sockaddr *saddr = (sockaddr *) addr.get_addr ();
00070 int addr_len = addr.get_size ();
00071 u_long inlen;
00072
00073 if (ACE_OS::ioctl (this->get_handle (),
00074 FIONREAD, (u_long *) &inlen) == -1)
00075 return -1;
00076 else if (inlen > 0)
00077 {
00078 ACE_NEW_RETURN (io_vec->iov_base,
00079 char[inlen],
00080 -1);
00081 io_vec->iov_len = ACE_OS::recvfrom (this->get_handle (),
00082 (char *) io_vec->iov_base,
00083 inlen,
00084 flags,
00085 (sockaddr *) saddr,
00086 &addr_len);
00087 addr.set_size (addr_len);
00088 return io_vec->iov_len;
00089 }
00090 else
00091 return 0;
00092 #else
00093 ACE_UNUSED_ARG (flags);
00094 ACE_UNUSED_ARG (addr);
00095 ACE_UNUSED_ARG (io_vec);
00096 ACE_UNUSED_ARG (timeout);
00097 ACE_NOTSUP_RETURN (-1);
00098 #endif
00099 }
00100
00101
00102
00103
00104
00105
00106 int
00107 ACE_SOCK_Dgram::shared_open (const ACE_Addr &local,
00108 int protocol_family)
00109 {
00110 ACE_TRACE ("ACE_SOCK_Dgram::shared_open");
00111 int error = 0;
00112
00113 if (local == ACE_Addr::sap_any)
00114 {
00115 if (protocol_family == PF_INET
00116 #if defined (ACE_HAS_IPV6)
00117 || protocol_family == PF_INET6
00118 #endif
00119 )
00120 {
00121 if (ACE::bind_port (this->get_handle ()) == -1)
00122 error = 1;
00123 }
00124 }
00125 else if (ACE_OS::bind (this->get_handle (),
00126 ACE_reinterpret_cast (sockaddr *,
00127 local.get_addr ()),
00128 local.get_size ()) == -1)
00129 error = 1;
00130
00131 if (error != 0)
00132 this->close ();
00133
00134 return error ? -1 : 0;
00135 }
00136
00137 int
00138 ACE_SOCK_Dgram::open (const ACE_Addr &local,
00139 int protocol_family,
00140 int protocol,
00141 ACE_Protocol_Info *protocolinfo,
00142 ACE_SOCK_GROUP g,
00143 u_long flags,
00144 int reuse_addr)
00145 {
00146 if (ACE_SOCK::open (SOCK_DGRAM,
00147 protocol_family,
00148 protocol,
00149 protocolinfo,
00150 g,
00151 flags,
00152 reuse_addr) == -1)
00153 return -1;
00154 else if (this->shared_open (local,
00155 protocol_family) == -1)
00156 return -1;
00157 else
00158 return 0;
00159 }
00160
00161
00162
00163 int
00164 ACE_SOCK_Dgram::open (const ACE_Addr &local,
00165 int protocol_family,
00166 int protocol,
00167 int reuse_addr)
00168 {
00169 ACE_TRACE ("ACE_SOCK_Dgram::open");
00170
00171 if (local != ACE_Addr::sap_any)
00172 protocol_family = local.get_type ();
00173 else if (protocol_family == PF_UNSPEC)
00174 {
00175 #if defined (ACE_HAS_IPV6)
00176 protocol_family = ACE_Sock_Connect::ipv6_enabled () ? PF_INET6 : PF_INET;
00177 #else
00178 protocol_family = PF_INET;
00179 #endif
00180 }
00181
00182 if (ACE_SOCK::open (SOCK_DGRAM,
00183 protocol_family,
00184 protocol,
00185 reuse_addr) == -1)
00186 return -1;
00187 else
00188 return this->shared_open (local,
00189 protocol_family);
00190 }
00191
00192
00193
00194
00195 ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
00196 int protocol_family,
00197 int protocol,
00198 int reuse_addr)
00199 {
00200 ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
00201
00202 if (this->open (local,
00203 protocol_family,
00204 protocol,
00205 reuse_addr) == -1)
00206 ACE_ERROR ((LM_ERROR,
00207 ACE_LIB_TEXT ("%p\n"),
00208 ACE_LIB_TEXT ("ACE_SOCK_Dgram")));
00209 }
00210
00211 ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
00212 int protocol_family,
00213 int protocol,
00214 ACE_Protocol_Info *protocolinfo,
00215 ACE_SOCK_GROUP g,
00216 u_long flags,
00217 int reuse_addr)
00218 {
00219 ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
00220 if (this->open (local,
00221 protocol_family,
00222 protocol,
00223 protocolinfo,
00224 g,
00225 flags,
00226 reuse_addr) == -1)
00227 ACE_ERROR ((LM_ERROR,
00228 ACE_LIB_TEXT ("%p\n"),
00229 ACE_LIB_TEXT ("ACE_SOCK_Dgram")));
00230 }
00231
00232 #if defined (ACE_HAS_MSG)
00233
00234
00235
00236 ssize_t
00237 ACE_SOCK_Dgram::send (const iovec iov[],
00238 int n,
00239 const ACE_Addr &addr,
00240 int flags) const
00241 {
00242 ACE_TRACE ("ACE_SOCK_Dgram::send");
00243 msghdr send_msg;
00244
00245 send_msg.msg_iov = (iovec *) iov;
00246 send_msg.msg_iovlen = n;
00247 #if defined (ACE_HAS_SOCKADDR_MSG_NAME)
00248 send_msg.msg_name = (struct sockaddr *) addr.get_addr ();
00249 #else
00250 send_msg.msg_name = (char *) addr.get_addr ();
00251 #endif
00252 send_msg.msg_namelen = addr.get_size ();
00253
00254 #if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
00255 send_msg.msg_control = 0;
00256 send_msg.msg_controllen = 0;
00257 send_msg.msg_flags = 0;
00258 #else
00259 send_msg.msg_accrights = 0;
00260 send_msg.msg_accrightslen = 0;
00261 #endif
00262
00263 return ACE_OS::sendmsg (this->get_handle (),
00264 &send_msg,
00265 flags);
00266 }
00267
00268
00269
00270
00271 ssize_t
00272 ACE_SOCK_Dgram::recv (iovec iov[],
00273 int n,
00274 ACE_Addr &addr,
00275 int flags) const
00276 {
00277 ACE_TRACE ("ACE_SOCK_Dgram::recv");
00278 msghdr recv_msg;
00279
00280 recv_msg.msg_iov = (iovec *) iov;
00281 recv_msg.msg_iovlen = n;
00282 #if defined (ACE_HAS_SOCKADDR_MSG_NAME)
00283 recv_msg.msg_name = (struct sockaddr *) addr.get_addr ();
00284 #else
00285 recv_msg.msg_name = (char *) addr.get_addr ();
00286 #endif
00287 recv_msg.msg_namelen = addr.get_size ();
00288
00289 #if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
00290 recv_msg.msg_control = 0 ;
00291 recv_msg.msg_controllen = 0 ;
00292 #else
00293 recv_msg.msg_accrights = 0;
00294 recv_msg.msg_accrightslen = 0;
00295 #endif
00296
00297 ssize_t status = ACE_OS::recvmsg (this->get_handle (),
00298 &recv_msg,
00299 flags);
00300 addr.set_size (recv_msg.msg_namelen);
00301 return status;
00302 }
00303
00304 #else
00305
00306
00307
00308
00309 ssize_t
00310 ACE_SOCK_Dgram::send (const iovec iov[],
00311 int n,
00312 const ACE_Addr &addr,
00313 int flags) const
00314 {
00315 ACE_TRACE ("ACE_SOCK_Dgram::send");
00316
00317 size_t length = 0;
00318 int i;
00319
00320
00321 for (i = 0; i < n; i++)
00322 #if ! (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0530))
00323
00324
00325 if (iov[i].iov_len < 0)
00326 return -1;
00327 else
00328 #endif
00329 length += iov[i].iov_len;
00330
00331 char *buf;
00332
00333 #if defined (ACE_HAS_ALLOCA)
00334 buf = alloca (length);
00335 #else
00336 ACE_NEW_RETURN (buf,
00337 char[length],
00338 -1);
00339 #endif
00340
00341 char *ptr = buf;
00342
00343 for (i = 0; i < n; i++)
00344 {
00345 ACE_OS::memcpy (ptr, iov[i].iov_base, iov[i].iov_len);
00346 ptr += iov[i].iov_len;
00347 }
00348
00349 ssize_t result = ACE_SOCK_Dgram::send (buf, length, addr, flags);
00350 #if !defined (ACE_HAS_ALLOCA)
00351 delete [] buf;
00352 #endif
00353 return result;
00354 }
00355
00356
00357
00358
00359 ssize_t
00360 ACE_SOCK_Dgram::recv (iovec iov[],
00361 int n,
00362 ACE_Addr &addr,
00363 int flags) const
00364 {
00365 ACE_TRACE ("ACE_SOCK_Dgram::recv");
00366
00367 ssize_t length = 0;
00368 int i;
00369
00370 for (i = 0; i < n; i++)
00371 #if ! (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0530))
00372
00373
00374 if (iov[i].iov_len < 0)
00375 return -1;
00376 else
00377 #endif
00378 length += iov[i].iov_len;
00379
00380 char *buf;
00381
00382 #if defined (ACE_HAS_ALLOCA)
00383 buf = alloca (length);
00384 #else
00385 ACE_NEW_RETURN (buf,
00386 char[length],
00387 -1);
00388 #endif
00389
00390 length = ACE_SOCK_Dgram::recv (buf, length, addr, flags);
00391
00392 if (length != -1)
00393 {
00394 char *ptr = buf;
00395 int copyn = length;
00396
00397 for (i = 0;
00398 i < n && copyn > 0;
00399 i++)
00400 {
00401 ACE_OS::memcpy (iov[i].iov_base, ptr,
00402
00403 copyn > (int) iov[i].iov_len
00404 ? (size_t) iov[i].iov_len
00405 : (size_t) copyn);
00406 ptr += iov[i].iov_len;
00407 copyn -= iov[i].iov_len;
00408 }
00409 }
00410
00411 #if !defined (ACE_HAS_ALLOCA)
00412 delete [] buf;
00413 #endif
00414 return length;
00415 }
00416
00417 #endif
00418
00419 ssize_t
00420 ACE_SOCK_Dgram::recv (void *buf,
00421 size_t n,
00422 ACE_Addr &addr,
00423 int flags,
00424 const ACE_Time_Value *timeout) const
00425 {
00426 ACE_Handle_Set handle_set;
00427 handle_set.reset ();
00428 handle_set.set_bit (this->get_handle ());
00429
00430
00431 int select_width;
00432 #if defined (ACE_WIN64)
00433
00434
00435 select_width = 0;
00436 #else
00437 select_width = int (this->get_handle ()) + 1;
00438 #endif
00439 switch (ACE_OS::select (select_width,
00440 handle_set,
00441 0,
00442 0,
00443 timeout))
00444 {
00445 case -1:
00446 return -1;
00447
00448 case 0:
00449 errno = ETIME;
00450 return -1;
00451
00452 default:
00453
00454 return this->recv (buf, n, addr, flags);
00455 }
00456 }
00457
00458 ssize_t
00459 ACE_SOCK_Dgram::send (const void *buf,
00460 size_t n,
00461 const ACE_Addr &addr,
00462 int flags,
00463 const ACE_Time_Value *timeout) const
00464 {
00465 ACE_Handle_Set handle_set;
00466 handle_set.reset ();
00467 handle_set.set_bit (this->get_handle ());
00468
00469
00470 int select_width;
00471 #if defined (ACE_WIN64)
00472
00473
00474 select_width = 0;
00475 #else
00476 select_width = int (this->get_handle ()) + 1;
00477 #endif
00478 switch (ACE_OS::select (select_width,
00479 0,
00480 handle_set,
00481 0,
00482 timeout))
00483 {
00484 case -1:
00485 return -1;
00486
00487 case 0:
00488 errno = ETIME;
00489 return -1;
00490
00491 default:
00492
00493 return this->send (buf, n, addr, flags);
00494 }
00495 }
00496
00497 void
00498 ACE_SOCK_Dgram::set_nic (const char *option_value)
00499 {
00500
00501
00502 ip_mreq multicast_address;
00503 ACE_INET_Addr mcast_addr;
00504 #if defined (ACE_WIN32)
00505
00506 ACE_INET_Addr interface_addr;
00507 if (interface_addr.set (mcast_addr.get_port_number (),
00508 option_value) == -1)
00509 return;
00510 multicast_address.imr_interface.s_addr =
00511 htonl (interface_addr.get_ip_address ());
00512 #else
00513 ifreq if_address;
00514
00515 #if defined (ACE_PSOS)
00516
00517 if_address.ifr_ifno = ACE_OS::atoi (option_value);
00518 #else
00519 ACE_OS::strcpy (if_address.ifr_name, option_value);
00520 #endif
00521
00522 if (ACE_OS::ioctl (this->get_handle (),
00523 SIOCGIFADDR,
00524 &if_address) == -1)
00525 return;
00526
00527
00528 sockaddr_in *socket_address;
00529 socket_address = ACE_reinterpret_cast(sockaddr_in *,
00530 &if_address.ifr_addr);
00531 multicast_address.imr_interface.s_addr = socket_address->sin_addr.s_addr;
00532 #endif
00533
00534
00535
00536
00537
00538
00539 this->ACE_SOCK::set_option (IPPROTO_IP,
00540 IP_MULTICAST_IF,
00541 &multicast_address.imr_interface.s_addr,
00542 sizeof (struct in_addr));
00543 }