SOCK_CODgram.cpp

Go to the documentation of this file.
00001 // $Id: SOCK_CODgram.cpp 81509 2008-04-28 22:00:49Z shuston $
00002 
00003 #include "ace/SOCK_CODgram.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_sys_socket.h"
00006 
00007 #if !defined (__ACE_INLINE__)
00008 #include "ace/SOCK_CODgram.inl"
00009 #endif /* __ACE_INLINE__ */
00010 
00011 ACE_RCSID(ace, SOCK_CODgram, "$Id: SOCK_CODgram.cpp 81509 2008-04-28 22:00:49Z shuston $")
00012 
00013 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00014 
00015 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_CODgram)
00016 
00017 void
00018 ACE_SOCK_CODgram::dump (void) const
00019 {
00020 #if defined (ACE_HAS_DUMP)
00021   ACE_TRACE ("ACE_SOCK_CODgram::dump");
00022 #endif /* ACE_HAS_DUMP */
00023 }
00024 
00025 // Here's the general-purpose constructor.
00026 
00027 ACE_SOCK_CODgram::ACE_SOCK_CODgram (const ACE_Addr &remote,
00028                                     const ACE_Addr &local,
00029                                     int protocol_family,
00030                                     int protocol,
00031                                     int reuse_addr)
00032 {
00033   ACE_TRACE ("ACE_SOCK_CODgram::ACE_SOCK_CODgram");
00034   if (this->open (remote,
00035                   local,
00036                   protocol_family,
00037                   protocol,
00038                   reuse_addr) == -1)
00039     ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_SOCK_CODgram")));
00040 }
00041 
00042 /* This is the general-purpose open routine.  Note that it performs
00043    a different set of functions depending on the LOCAL and REMOTE
00044    addresses passed to it.  Here's the basic logic:
00045 
00046    1. remote == ACE_Addr::sap_any && local == ACE_Addr::sap_any
00047          if protocol_family == PF_INET || PF_INET6 then
00048              bind the local address to a randomly generated port number...
00049 
00050    2. remote == ACE_Addr::sap_any && local != ACE_Addr::sap_any
00051          we are just binding the local address
00052          (used primarily by servers)
00053 
00054    3. remote != ACE_Addr::sap_any && local == ACE_Addr::sap_any
00055          we are connecting to the remote address
00056          (used primarily by clients)
00057 
00058    4. remote != ACE_Addr::sap_any && local != ACE_Addr::sap_any
00059          we are binding to the local address
00060          and connecting to the remote address
00061 */
00062 
00063 int
00064 ACE_SOCK_CODgram::open (const ACE_Addr &remote, const ACE_Addr &local,
00065                         int protocol_family, int protocol,
00066                         int reuse_addr)
00067 {
00068   ACE_TRACE ("ACE_SOCK_CODgram::open");
00069   // Depending on the addresses passed as described above, figure out what
00070   // address family to specify for the new socket. If either address is
00071   // !ACE_Addr::sap_any, use that family. If they don't match, it's an error.
00072   if (remote != ACE_Addr::sap_any)
00073     {
00074       if (local == ACE_Addr::sap_any)
00075         protocol_family = remote.get_type ();
00076       else
00077         { // Both specified; family must match
00078           if (local.get_type () != remote.get_type ())
00079             {
00080               errno = EAFNOSUPPORT;
00081               return -1;
00082             }
00083           protocol_family = remote.get_type ();
00084         }
00085     }
00086   else
00087     {
00088       if (local != ACE_Addr::sap_any)
00089         protocol_family = local.get_type ();
00090     }
00091   if (ACE_SOCK::open (SOCK_DGRAM,
00092                       protocol_family,
00093                       protocol,
00094                       reuse_addr) == -1)
00095     return -1;
00096   else
00097     {
00098       int error = 0;
00099 
00100       if (local == ACE_Addr::sap_any && remote == ACE_Addr::sap_any)
00101         {
00102           // Assign an arbitrary port number from the transient range!!
00103           if (protocol_family == PF_INET
00104 #if defined (ACE_HAS_IPV6)
00105                || protocol_family == PF_INET6
00106 #endif /* ACE_HAS_IPV6 */
00107               && ACE::bind_port (this->get_handle ()) == -1)
00108             error = 1;
00109         }
00110       // We are binding just the local address.
00111       else if (local != ACE_Addr::sap_any && remote == ACE_Addr::sap_any)
00112         {
00113           if (ACE_OS::bind (this->get_handle (),
00114                             (sockaddr *) local.get_addr (),
00115                             local.get_size ()) == -1)
00116             error = 1;
00117         }
00118       // We are connecting to the remote address.
00119       else if (local == ACE_Addr::sap_any && remote != ACE_Addr::sap_any)
00120         {
00121           if (ACE_OS::connect (this->get_handle (),
00122                                (sockaddr *) remote.get_addr (),
00123                                remote.get_size ()) == -1)
00124             error = 1;
00125         }
00126       // We are binding to the local address and connecting to the
00127       // remote addresses.
00128       else
00129         {
00130           if (ACE_OS::bind (this->get_handle (),
00131                             (sockaddr *) local.get_addr (),
00132                             local.get_size ()) == -1
00133               || ACE_OS::connect (this->get_handle (),
00134                                   (sockaddr *) remote.get_addr (),
00135                                   remote.get_size ()) == -1)
00136             error = 1;
00137         }
00138       if (error)
00139         {
00140           this->close ();
00141           this->set_handle (ACE_INVALID_HANDLE);
00142         }
00143       return error ? -1 : 0;
00144     }
00145 }
00146 
00147 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:42 2010 for ACE by  doxygen 1.4.7