Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / SOCK_SEQPACK_Association.cpp
blob73841eea7a47c1e008e868bd874692e45f5ed825
1 #include "ace/SOCK_SEQPACK_Association.h"
3 #include "ace/Log_Category.h"
4 #include "ace/OS_Memory.h"
5 #include "ace/OS_NS_string.h"
6 #include <memory>
8 #if !defined (__ACE_INLINE__)
9 #include "ace/SOCK_SEQPACK_Association.inl"
10 #endif /* __ACE_INLINE__ */
12 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
14 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_SEQPACK_Association)
16 void
17 ACE_SOCK_SEQPACK_Association::dump () const
19 #if defined (ACE_HAS_DUMP)
20 ACE_TRACE ("ACE_SOCK_SEQPACK_Association::dump");
21 #endif /* ACE_HAS_DUMP */
24 int
25 ACE_SOCK_SEQPACK_Association::close ()
27 #if defined (ACE_WIN32)
28 // We need the following call to make things work correctly on
29 // Win32, which requires use to do a <close_writer> before doing the
30 // close in order to avoid losing data. Note that we don't need to
31 // do this on UNIX since it doesn't have this "feature". Moreover,
32 // this will cause subtle problems on UNIX due to the way that
33 // fork() works.
34 this->close_writer ();
35 #endif /* ACE_WIN32 */
36 // Close down the socket.
37 return ACE_SOCK::close ();
40 // Developed according to the API discussed in 7.1.4 of
41 // draft-ietf-tsvwg-sctpsocket-09.txt to abruptly free a transport
42 // transport association's resources.
43 int
44 ACE_SOCK_SEQPACK_Association::abort ()
47 // setsockopt() SO_LINGER configures socket to reap immediately.
48 // Normal close then aborts the association.
50 linger slinger = { 0, 0 };
51 slinger.l_onoff = 1;
53 if (-1 == ACE_OS::setsockopt (this->get_handle (),
54 SOL_SOCKET,
55 SO_LINGER,
56 reinterpret_cast<const char *> (&slinger),
57 sizeof (linger)))
59 return -1;
62 return this->close ();
65 int
66 ACE_SOCK_SEQPACK_Association::get_local_addrs (ACE_INET_Addr *addrs, size_t &size) const
68 ACE_TRACE ("ACE_SOCK_SEQPACK_Association::get_local_addrs");
70 #if defined (ACE_HAS_LKSCTP)
72 The size of ACE_INET_Addr must be large enough to hold the number of
73 local addresses on the machine. If the array is too small, the function
74 will only return the number of addresses that will fit. If the array is
75 too large, the 'size' parameter will be modified to indicate the number
76 of addrs.
78 We will call sctp_getladdrs() which accepts 3 parameters
79 1. a socket fd
80 2. a sctp association_id which will be ignored since we are using
81 tcp sockets
82 3. a pointer to sockaddr
84 lksctp/draft will allocate memory and we are responsible for freeing
85 it by calling sctp_freeladdrs().
88 sockaddr_in *si = 0;
89 sockaddr *laddrs = 0;
90 int err = 0;
91 size_t len = 0;
93 err = sctp_getladdrs(this->get_handle(), 0, &laddrs);
94 if (err > 0)
96 len = err;
97 // check to see if we have more addresses than we have
98 // space in our ACE_INET_Addr array
99 if (len > size)
101 // since our array is too small, we will only copy the first
102 // few that fit
103 len = size;
106 for (size_t i = 0; i < len; i++)
108 // first we cast the sockaddr to sockaddr_in
109 // since we only support ipv4 at this time.
110 si = (sockaddr_in *) (&(laddrs[i]));
112 // now we fillup the ace_inet_addr array
113 addrs[i].set_addr(si, sizeof(sockaddr_in));
114 addrs[i].set_type(si->sin_family);
115 addrs[i].set_size(sizeof(sockaddr_in));
118 else /* err < 0 */
120 // sctp_getladdrs will return -1 on error
121 return -1;
124 // indicate the num of addrs returned to the calling function
125 size = len;
127 // make sure we free the struct using the system function
128 sctp_freeladdrs(laddrs);
130 #else
133 We will be calling ACE_OS::getsockname, which accepts (and
134 potentially modifies) two reference parameters:
136 1. a sockaddr_in* that points to a buffer
137 2. an int* that points to the size of this buffer
139 The OpenSS7 implementation of SCTP copies an array of ipv4
140 sockaddr_in into the buffer. Then, if the size of the buffer is
141 greater than the size used, the size parameter is reduced
142 accordingly.
146 // The array of sockaddr_in will be stored in an std::unique_ptr,
147 // which causes dynamically-allocated memory to be released as soon
148 // as the std::unique_ptr goes out of scope.
149 std::unique_ptr<sockaddr_in[]> addr_structs;
151 // Allocate memory for this array. Return -1 if the memory cannot
152 // be allocated. (This activity requires a temporary variable---a
153 // bare sockaddr_in* --- because ACE_NEW_RETURN cannot act directory on
154 // an ACE_Auto_Array_Ptr.)
156 sockaddr_in *addr_structs_bootstrap = 0;
157 #if defined(ACE_HAS_ALLOC_HOOKS)
158 ACE_ALLOCATOR_RETURN (addr_structs_bootstrap, static_cast<sockaddr_in*>(ACE_Allocator::instance()->malloc(sizeof(sockaddr_in) * size)), -1);
159 #else
160 ACE_NEW_RETURN (addr_structs_bootstrap, sockaddr_in[size], -1);
161 #endif
162 addr_structs.reset(addr_structs_bootstrap);
165 // Physical size of this array is its logical size multiplied by
166 // the physical size of one of its elements.
167 size_t physical_size = size * sizeof(sockaddr_in);
169 /* Clear the array */
170 ACE_OS::memset(addr_structs.get(),
172 physical_size);
175 ** Populate the array with real values from the getsockname system
176 ** call. addr_structs is modified, and name_size is modified to contain
177 ** the number of bytes written to addr_structs.
178 ** Use name_size to get the data types right across the call.
180 int name_size = static_cast<int> (physical_size);
181 if (ACE_OS::getsockname (this->get_handle (),
182 reinterpret_cast<sockaddr *> (addr_structs.get()),
183 &name_size) == -1)
184 return -1;
186 /* Calculate the NEW physical size of the array */
187 name_size /= sizeof (sockaddr_in);
188 size = static_cast<size_t> (name_size);
190 /* Copy each sockaddr_in to the address structure of an ACE_Addr from
191 the passed-in array */
192 const int addrlen (static_cast<int> (sizeof (sockaddr_in)));
193 for (int i = 0; i < name_size; ++i)
195 addrs[i].set_addr (&(addr_structs[i]), addrlen);
196 addrs[i].set_type (addr_structs[i].sin_family);
197 addrs[i].set_size (addrlen);
199 #endif /* ACE_HAS_LKSCTP */
200 return 0;
205 ACE_SOCK_SEQPACK_Association::get_remote_addrs (ACE_INET_Addr *addrs, size_t &size) const
207 ACE_TRACE ("ACE_SOCK_SEQPACK_Association::get_remote_addrs");
208 #if defined (ACE_HAS_LKSCTP)
210 The size of ACE_INET_Addr must be large enough to hold the number of
211 remotes addresses in the association. If the array is too small, the
212 function will only return the number of addresses that will fit. If the
213 array is too large, the 'size' parameter will be modified to indicate
214 the number of addrs.
216 We will call sctp_getpaddrs() which accepts 3 parameters
217 1. a socket fd
218 2. a sctp association_id which will be ignored since we are using
219 tcp sockets
220 3. a pointer to a sockaddr
222 lksctp/draft will allocate memory and we are responsible for freeing
223 it by calling sctp_freepaddrs().
226 sockaddr_in *si = 0;
227 sockaddr *paddrs = 0;
228 int err = 0;
229 size_t len = 0;
231 #ifndef ACE_HAS_VOID_PTR_SCTP_GETPADDRS
232 err = sctp_getpaddrs(this->get_handle(), 0, &paddrs);
233 #else
234 err = sctp_getpaddrs(this->get_handle(), 0, reinterpret_cast<void**>(&paddrs));
235 #endif /* ACE_HAS_VOID_PTR_SCTP_GETPADDRS */
237 if (err > 0)
239 len = err;
240 // check to see if we have more addresses than we have
241 // space in our ACE_INET_Addr array
242 if (len > size)
244 // since our array is too small, we will only copy the first
245 // few that fit
246 len = size;
249 for (size_t i = 0; i < len; i++)
251 // first we cast the sockaddr to sockaddr_in
252 // since we only support ipv4 at this time.
253 si = (sockaddr_in *) (&(paddrs[i]));
255 // now we fillup the ace_inet_addr array
256 addrs[i].set_addr(si, sizeof(sockaddr_in));
257 addrs[i].set_type(si->sin_family);
258 addrs[i].set_size(sizeof(sockaddr_in));
261 else /* err < 0 */
263 // sctp_getpaddrs will return -1 on error
264 return -1;
267 // indicate the num of addrs returned to the calling function
268 size = len;
270 // make sure we free the struct using the system function
271 sctp_freepaddrs(paddrs);
273 #else
276 We will be calling ACE_OS::getpeername, which accepts (and
277 potentially modifies) two reference parameters:
279 1. a sockaddr_in* that points to a buffer
280 2. an int* that points to the size of this buffer
282 The OpenSS7 implementation of SCTP copies an array of ipv4
283 sockaddr_in into the buffer. Then, if the size of the buffer is
284 greater than the size used, the size parameter is reduced
285 accordingly.
289 // The array of sockaddr_in will be stored in an std::unique_ptr,
290 // which causes dynamically-allocated memory to be released as soon
291 // as the std::unique_ptr goes out of scope.
292 std::unique_ptr<sockaddr_in[]> addr_structs;
294 // Allocate memory for this array. Return -1 if the memory cannot
295 // be allocated. (This activity requires a temporary variable---a
296 // bare sockaddr_in* --- because ACE_NEW_RETURN cannot act directory on
297 // an ACE_Auto_Array_Ptr.)
299 sockaddr_in *addr_structs_bootstrap = 0;
300 #if defined (ACE_HAS_ALLOC_HOOKS)
301 ACE_ALLOCATOR_RETURN (addr_structs_bootstrap, static_cast<sockaddr_in*>(ACE_Allocator::instance()->malloc(sizeof(sockaddr_in) * (size))), -1);
302 #else
303 ACE_NEW_RETURN (addr_structs_bootstrap, sockaddr_in[size], -1);
304 #endif
305 addr_structs.reset(addr_structs_bootstrap);
308 // Physical size of this array is its logical size multiplied by
309 // the physical size of one of its elements.
310 size_t physical_size = size * sizeof(sockaddr_in);
312 /* Clear the array */
313 ACE_OS::memset(addr_structs.get(),
315 physical_size);
318 ** Populate the array with real values from the getpeername system
319 ** call. addr_structs is modified, and name_size is modified to contain
320 ** the number of bytes written to addr_structs.
321 ** Use name_size to get the data types right across the call.
323 int name_size = static_cast<int> (physical_size);
324 if (ACE_OS::getpeername (this->get_handle (),
325 reinterpret_cast<sockaddr *> (addr_structs.get()),
326 &name_size) == -1)
327 return -1;
329 /* Calculate the NEW physical size of the array */
330 name_size /= sizeof (sockaddr_in);
331 size = static_cast<size_t> (name_size);
333 /* Copy each sockaddr_in to the address structure of an ACE_Addr from
334 the passed-in array */
335 const int addrlen (static_cast<int> (sizeof (sockaddr_in)));
336 for (int i = 0; i < name_size; ++i)
338 addrs[i].set_addr (&(addr_structs[i]), addrlen);
339 addrs[i].set_type (addr_structs[i].sin_family);
340 addrs[i].set_size (addrlen);
342 #endif /* ACE_HAS_LKSCTP */
343 return 0;
346 ACE_END_VERSIONED_NAMESPACE_DECL