xref: /trunk/main/sal/osl/w32/socket.cxx (revision 86e1cf34)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sal.hxx"
26 
27 #include "system.h"
28 
29 #include <osl/socket.h>
30 #include <osl/diagnose.h>
31 #include <rtl/alloc.h>
32 
33 #include "sockimpl.h"
34 
35 extern "C" {
36 
37 /* defines for shutdown */
38 #ifdef GCC
39 #	define SD_RECEIVE 0
40 #	define SD_SEND 1
41 #	define SD_BOTH 2
42 #endif
43 
44 /*
45 	oslSocketAddr is a pointer to a Berkeley struct sockaddr.
46 	I refrained from using sockaddr_in because of possible further
47 	extensions of this socket-interface (IP-NG?).
48 	The intention was to hide all Berkeley data-structures from
49 	direct access past the osl-interface.
50 
51 	The current implementation is internet (IP) centered. All
52 	the constructor-functions (osl_create...) take parameters
53 	that will probably make sense only in the IP-environment
54 	(e.g. because of using the dotted-Addr-format).
55 
56 	If the interface will be extended to host other protocol-
57 	families, I expect no externally visible changes in the
58 	existing functions. You'll probably need only new
59 	constructor-functions who take the different Addr
60 	formats into consideration (maybe a long dotted Addr
61 	or whatever).
62 */
63 
64 /*
65   _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
66   are the same! I don't like it very much but see no other easy way to
67   conceal the struct sockaddr from the eyes of the user.
68 */
69 
70 #define OSL_INVALID_SOCKET		INVALID_SOCKET			/* WIN32 */
71 #define OSL_SOCKET_ERROR		SOCKET_ERROR			/* WIN32 */
72 
73 /*****************************************************************************/
74 /* enum oslAddrFamily */
75 /*****************************************************************************/
76 
77 /* map */
78 static DWORD FamilyMap[]= {
79 	AF_INET,					/* osl_Socket_FamilyInet */
80 	AF_IPX,						/* osl_Socket_FamilyIpx */
81 	0							/* osl_Socket_FamilyInvalid */
82 };
83 
84 /* reverse map */
osl_AddrFamilyFromNative(DWORD nativeType)85 static oslAddrFamily osl_AddrFamilyFromNative(DWORD nativeType)
86 {
87 	oslAddrFamily i= (oslAddrFamily) 0;
88 	while(i != osl_Socket_FamilyInvalid)
89 	{
90 		if(FamilyMap[i] == nativeType)
91 			return i;
92 		i = (oslAddrFamily) ( (int)i + 1);
93 	}
94 	return i;
95 }
96 
97 /* macros */
98 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
99 #define FAMILY_TO_NATIVE(x)	(short)FamilyMap[x]
100 
101 /*****************************************************************************/
102 /* enum oslProtocol */
103 /*****************************************************************************/
104 
105 /* map */
106 static DWORD ProtocolMap[]= {
107 	0,							/* osl_Socket_FamilyInet */
108 	NSPROTO_IPX,				/* osl_Socket_FamilyIpx */
109 	NSPROTO_SPX,				/* osl_Socket_ProtocolSpx */
110 	NSPROTO_SPXII,				/* osl_Socket_ProtocolSpx_ii */
111 	0							/* osl_Socket_ProtocolInvalid */
112 };
113 
114 /* macros */
115 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
116 #define PROTOCOL_TO_NATIVE(x)	ProtocolMap[x]
117 
118 /*****************************************************************************/
119 /* enum oslSocketType */
120 /*****************************************************************************/
121 
122 /* map */
123 static DWORD TypeMap[]= {
124 	SOCK_STREAM,				/* osl_Socket_TypeStream */
125 	SOCK_DGRAM,					/* osl_Socket_TypeDgram  */
126 	SOCK_RAW,					/* osl_Socket_TypeRaw */
127 	SOCK_RDM,					/* osl_Socket_TypeRdm */
128 	SOCK_SEQPACKET,				/* osl_Socket_TypeSeqPacket */
129 	0							/* osl_Socket_TypeInvalid */
130 };
131 
132 /* reverse map */
osl_SocketTypeFromNative(DWORD nativeType)133 static oslSocketType osl_SocketTypeFromNative(DWORD nativeType)
134 {
135 	oslSocketType i= (oslSocketType)0;
136 	while(i != osl_Socket_TypeInvalid)
137 	{
138 		if(TypeMap[i] == nativeType)
139 			return i;
140 		i = (oslSocketType)((int)i+1);
141 	}
142 	return i;
143 }
144 
145 /* macros */
146 #define TYPE_TO_NATIVE(x)		TypeMap[x]
147 #define TYPE_FROM_NATIVE(y)		osl_SocketTypeFromNative(y)
148 
149 /*****************************************************************************/
150 /* enum oslSocketOption */
151 /*****************************************************************************/
152 
153 /* map */
154 static DWORD OptionMap[]= {
155 	SO_DEBUG,					/* osl_Socket_OptionDebug */
156 	SO_ACCEPTCONN,				/* osl_Socket_OptionAcceptConn */
157 	SO_REUSEADDR,				/* osl_Socket_OptionReuseAddr */
158 	SO_KEEPALIVE,				/* osl_Socket_OptionKeepAlive */
159 	SO_DONTROUTE,				/* osl_Socket_OptionDontRoute */
160 	SO_BROADCAST,				/* osl_Socket_OptionBroadcast */
161 	SO_USELOOPBACK,				/* osl_Socket_OptionUseLoopback */
162 	SO_LINGER,					/* osl_Socket_OptionLinger */
163 	SO_OOBINLINE,				/* osl_Socket_OptionOOBinLine */
164 	SO_SNDBUF,					/* osl_Socket_OptionSndBuf */
165 	SO_RCVBUF,					/* osl_Socket_OptionRcvBuf */
166 	SO_SNDLOWAT,				/* osl_Socket_OptionSndLowat */
167 	SO_RCVLOWAT,				/* osl_Socket_OptionRcvLowat */
168 	SO_SNDTIMEO,				/* osl_Socket_OptionSndTimeo */
169 	SO_RCVTIMEO,				/* osl_Socket_OptionRcvTimeo */
170 	SO_ERROR,					/* osl_Socket_OptionError */
171 	SO_TYPE,					/* osl_Socket_OptionType */
172 	TCP_NODELAY,				/* osl_Socket_OptionTcpNoDelay */
173 	0							/* osl_Socket_OptionInvalid */
174 };
175 
176 /* macros */
177 #define OPTION_TO_NATIVE(x)		OptionMap[x]
178 #define OPTION_FROM_NATIVE(y)	osl_SocketOptionFromNative(y)
179 
180 /*****************************************************************************/
181 /* enum oslSocketOptionLevel */
182 /*****************************************************************************/
183 
184 static DWORD OptionLevelMap[]= {
185 	SOL_SOCKET,					/* osl_Socket_LevelSocket */
186 	IPPROTO_TCP,				/* osl_Socket_LevelTcp */
187 	0							/* osl_invalid_SocketLevel */
188 };
189 
190 /* macros */
191 #define OPTION_LEVEL_TO_NATIVE(x)		OptionLevelMap[x]
192 #define OPTION_LEVEL_FROM_NATIVE(y)		osl_SocketOptionLevelFromNative(y)
193 
194 /*****************************************************************************/
195 /* enum oslSocketMsgFlag */
196 /*****************************************************************************/
197 
198 static DWORD SocketMsgFlagMap[]= {
199 	0,							/* osl_Socket_MsgNormal */
200 	MSG_OOB,					/* osl_Socket_MsgOOB */
201 	MSG_PEEK,					/* osl_Socket_MsgPeek */
202 	MSG_DONTROUTE,				/* osl_Socket_MsgDontRoute */
203 	MSG_MAXIOVLEN				/* osl_Socket_MsgMaxIOVLen */
204 };
205 
206 /* macros */
207 #define MSG_FLAG_TO_NATIVE(x)		SocketMsgFlagMap[x]
208 #define MSG_FLAG_FROM_NATIVE(y)		osl_SocketMsgFlagFromNative(y)
209 
210 /*****************************************************************************/
211 /* enum oslSocketDirection */
212 /*****************************************************************************/
213 
214 static DWORD SocketDirection[]= {
215 	SD_RECEIVE,					/* osl_Socket_DirRead */
216 	SD_SEND,					/* osl_Socket_DirWrite */
217 	SD_BOTH						/* osl_Socket_DirReadwrite */
218 };
219 
220 /* macros */
221 #define DIRECTION_TO_NATIVE(x)		SocketDirection[x]
222 #define DIRECTION_FROM_NATIVE(y)	osl_SocketDirectionFromNative(y)
223 
224 /*****************************************************************************/
225 /* enum oslSocketError */
226 /*****************************************************************************/
227 
228 static int SocketError[]= {
229 
230 	0,					/* no error */
231 	WSAENOTSOCK,			/* Socket operation on non-socket */
232 	WSAEDESTADDRREQ,		/* Destination address required */
233 	WSAEMSGSIZE,			/* Message too long */
234 	WSAEPROTOTYPE,			/* Protocol wrong type for socket */
235 	WSAENOPROTOOPT,		/* Protocol not available */
236 	WSAEPROTONOSUPPORT,	/* Protocol not supported */
237 	WSAESOCKTNOSUPPORT,	/* Socket type not supported */
238 	WSAEOPNOTSUPP,			/* Operation not supported on socket */
239 	WSAEPFNOSUPPORT,		/* Protocol family not supported */
240 	WSAEAFNOSUPPORT,		/* Address family not supported by */
241 							/* protocol family */
242 	WSAEADDRINUSE,			/* Address already in use */
243 	WSAEADDRNOTAVAIL,		/* Can't assign requested address */
244 	WSAENETDOWN,			/* Network is down */
245 	WSAENETUNREACH,		/* Network is unreachable */
246 	WSAENETRESET,			/* Network dropped connection because */
247 							/* of reset */
248 	WSAECONNABORTED,		/* Software caused connection abort */
249 	WSAECONNRESET,			/* Connection reset by peer */
250 	WSAENOBUFS,			/* No buffer space available */
251 	WSAEISCONN,			/* Socket is already connected */
252 	WSAENOTCONN,			/* Socket is not connected */
253 	WSAESHUTDOWN,			/* Can't send after socket shutdown */
254 	WSAETOOMANYREFS,		/* Too many references: can't splice */
255 	WSAETIMEDOUT,			/* Connection timed out */
256 	WSAECONNREFUSED,		/* Connection refused */
257 	WSAEHOSTDOWN,			/* Host is down */
258 	WSAEHOSTUNREACH,		/* No route to host */
259 	WSAEWOULDBLOCK,		/* call would block on non-blocking socket */
260 	WSAEALREADY,			/* operation already in progress */
261 	WSAEINPROGRESS		/* operation now in progress */
262 };
263 
264 /* reverse map */
osl_SocketErrorFromNative(int nativeType)265 static oslSocketError osl_SocketErrorFromNative(int nativeType)
266 {
267 	oslSocketError i= (oslSocketError)0;
268 
269 	while(i != osl_Socket_E_InvalidError)
270 	{
271 		if(SocketError[i] == nativeType)
272 			return i;
273 
274 		i = (oslSocketError)( (int) i + 1);
275 	}
276 	return i;
277 }
278 
279 /* macros */
280 #define ERROR_TO_NATIVE(x)		SocketError[x]
281 #define ERROR_FROM_NATIVE(y)	osl_SocketErrorFromNative(y)
282 
283 /*****************************************************************************/
284 /* oslSocketDialupImpl */
285 /*****************************************************************************/
286 static oslSocketDialupImpl *pDialupImpl = NULL;
287 
288 #if 0  /* INTERNAL DEBUG ONLY */
289 BOOL WINAPI __osl_autodial_Impl (DWORD dwFlags, DWORD dwReserved)
290 {
291 	return 0;
292 }
293 
294 BOOL WINAPI __osl_autodialHangup_Impl (DWORD dwReserved)
295 {
296 	return 1;
297 }
298 
299 BOOL WINAPI __osl_getConnectedState_Impl (LPDWORD lpdwFlags, DWORD dwReserved)
300 {
301 	if (lpdwFlags)
302 		*lpdwFlags = 0;
303 	return 0;
304 }
305 #endif /* INTERNAL DEBUG ONLY */
306 
307 /*
308  * __osl_createSocketDialupImpl.
309  */
__osl_createSocketDialupImpl(void)310 static oslSocketDialupImpl* __osl_createSocketDialupImpl (void)
311 {
312 	oslSocketDialupImpl *pImpl;
313 	pImpl = (oslSocketDialupImpl*)rtl_allocateZeroMemory( sizeof (oslSocketDialupImpl));
314 
315 	InitializeCriticalSection (&pImpl->m_hMutex);
316 
317 	return (pImpl);
318 }
319 
320 /*
321  * __osl_initSocketDialupImpl.
322  */
__osl_initSocketDialupImpl(oslSocketDialupImpl * pImpl)323 static void __osl_initSocketDialupImpl (oslSocketDialupImpl *pImpl)
324 {
325 #ifdef SOCKET_USE_AUTODIAL
326 	if (pImpl)
327 	{
328 		HINSTANCE hModule;
329 
330 		EnterCriticalSection (&pImpl->m_hMutex);
331 
332 		hModule = LoadLibrary (INTERNET_MODULE_NAME);
333 		if (!(hModule <= (HINSTANCE)HINSTANCE_ERROR))
334 		{
335 			pImpl->m_pfnAttemptConnect = (INTERNETATTEMPTCONNECT)
336 				(GetProcAddress (hModule, "InternetAttemptConnect"));
337 			pImpl->m_pfnAutodial = (INTERNETAUTODIAL)
338 				(GetProcAddress (hModule, "InternetAutodial"));
339 			pImpl->m_pfnAutodialHangup = (INTERNETAUTODIALHANGUP)
340 				(GetProcAddress (hModule, "InternetAutodialHangup"));
341 			pImpl->m_pfnGetConnectedState = (INTERNETGETCONNECTEDSTATE)
342 				(GetProcAddress (hModule, "InternetGetConnectedState"));
343 			pImpl->m_hModule = hModule;
344 		}
345 
346 		LeaveCriticalSection (&pImpl->m_hMutex);
347 	}
348 #else
349     pImpl = pImpl; /* avoid warnings */
350 #endif
351 }
352 
353 /*
354  * __osl_destroySocketDialupImpl.
355  */
__osl_destroySocketDialupImpl(oslSocketDialupImpl * pImpl)356 static void __osl_destroySocketDialupImpl (oslSocketDialupImpl *pImpl)
357 {
358 	if (pImpl)
359 	{
360 		EnterCriticalSection (&pImpl->m_hMutex);
361 
362 		if (pImpl->m_dwFlags & INTERNET_CONNECTION_HANGUP)
363 		{
364 			if (pImpl->m_pfnAutodialHangup)
365 			{
366 				(pImpl->m_pfnAutodialHangup)(0);
367 				pImpl->m_dwFlags &= ~INTERNET_CONNECTION_HANGUP;
368 			}
369 		}
370 
371 		if (pImpl->m_hModule)
372 			FreeLibrary (pImpl->m_hModule);
373 
374 		LeaveCriticalSection (&pImpl->m_hMutex);
375 		DeleteCriticalSection (&pImpl->m_hMutex);
376 
377 		rtl_freeMemory (pImpl);
378 	}
379 }
380 
381 /*
382  * __osl_querySocketDialupImpl.
383  */
__osl_querySocketDialupImpl(void)384 static sal_Bool __osl_querySocketDialupImpl (void)
385 {
386 	sal_Bool result;
387 
388 	if (pDialupImpl == NULL)
389 	{
390 		pDialupImpl = __osl_createSocketDialupImpl();
391 		__osl_initSocketDialupImpl (pDialupImpl);
392 	}
393 
394 	EnterCriticalSection (&pDialupImpl->m_hMutex);
395 
396 	result = sal_True;
397 	if (pDialupImpl->m_pfnGetConnectedState)
398 	{
399 		DWORD dwFlags = 0;
400 
401 		result = (sal_Bool)(pDialupImpl->m_pfnGetConnectedState)(&dwFlags, 0);
402 		pDialupImpl->m_dwFlags |= dwFlags;
403 	}
404 
405 	LeaveCriticalSection (&pDialupImpl->m_hMutex);
406 	return (result);
407 }
408 
409 /*
410  * __osl_attemptSocketDialupImpl.
411  */
__osl_attemptSocketDialupImpl(void)412 static sal_Bool __osl_attemptSocketDialupImpl (void)
413 {
414 	sal_Bool result;
415 
416 	if (pDialupImpl == NULL)
417 	{
418 		pDialupImpl = __osl_createSocketDialupImpl();
419 		__osl_initSocketDialupImpl (pDialupImpl);
420 	}
421 
422 	EnterCriticalSection (&pDialupImpl->m_hMutex);
423 
424 	result = __osl_querySocketDialupImpl();
425 	if (!result)
426 	{
427 		result = sal_True;
428 		if (pDialupImpl->m_pfnAutodial)
429 		{
430 			result = (sal_Bool)(pDialupImpl->m_pfnAutodial)(0, 0);
431 			if (result)
432 				pDialupImpl->m_dwFlags |= INTERNET_CONNECTION_HANGUP;
433 			else
434 				WSASetLastError (WSAENETDOWN);
435 		}
436 	}
437 
438 	LeaveCriticalSection (&pDialupImpl->m_hMutex);
439 	return (result);
440 }
441 
442 /*****************************************************************************/
443 /* oslSocketImpl */
444 /*****************************************************************************/
445 static sal_uInt32 g_nSocketImpl = 0;
446 
447 #if OSL_DEBUG_LEVEL > 1
448 static sal_uInt32 g_nSocketAddr = 0;
449 struct LeakWarning
450 {
~LeakWarningLeakWarning451 	~LeakWarning()
452 	{
453 		if( g_nSocketImpl )
454 			OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
455 		if( g_nSocketAddr )
456 			OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
457 	}
458 };
459 LeakWarning socketWarning;
460 #endif
461 
462 /*
463  * __osl_createSocketImpl.
464  */
__osl_createSocketImpl(SOCKET Socket)465 oslSocket __osl_createSocketImpl(SOCKET Socket)
466 {
467 	oslSocket pSockImpl = (oslSocket) rtl_allocateZeroMemory( sizeof(struct oslSocketImpl));
468 	pSockImpl->m_Socket = Socket;
469 	pSockImpl->m_nRefCount = 1;
470 
471 	g_nSocketImpl++;
472 
473 	return (pSockImpl);
474 }
475 
476 /*
477  * __osl_destroySocketImpl.
478  */
__osl_destroySocketImpl(oslSocketImpl * pImpl)479 void __osl_destroySocketImpl(oslSocketImpl *pImpl)
480 {
481 	if (pImpl)
482 	{
483 		if (--g_nSocketImpl == 0)
484 		{
485 			__osl_destroySocketDialupImpl (pDialupImpl);
486 			pDialupImpl = NULL;
487 		}
488 		rtl_freeMemory (pImpl);
489 	}
490 }
491 /*****************************************************************************/
__osl_createSocketAddr()492 static oslSocketAddr __osl_createSocketAddr(  )
493 {
494 	oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
495 	pAddr->m_nRefCount = 1;
496 #if OSL_DEBUG_LEVEL > 1
497 	g_nSocketAddr ++;
498 #endif
499 	return pAddr;
500 }
501 
__osl_createSocketAddrWithFamily(oslAddrFamily family,sal_Int32 port,sal_uInt32 nAddr)502 static oslSocketAddr __osl_createSocketAddrWithFamily(
503 	oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
504 {
505 	OSL_ASSERT( family == osl_Socket_FamilyInet );
506 
507 	oslSocketAddr pAddr = __osl_createSocketAddr();
508 	switch( family )
509 	{
510 	case osl_Socket_FamilyInet:
511 	{
512 		struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
513 
514 		pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
515 		pInetAddr->sin_addr.s_addr = nAddr;
516 		pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
517 		break;
518    	}
519 	default:
520 		pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
521 	}
522 	return pAddr;
523 }
524 
__osl_createSocketAddrFromSystem(struct sockaddr * pSystemSockAddr)525 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
526 {
527 	oslSocketAddr pAddr = __osl_createSocketAddr();
528 	memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( sockaddr ) );
529 	return pAddr;
530 }
531 
__osl_destroySocketAddr(oslSocketAddr addr)532 static void __osl_destroySocketAddr( oslSocketAddr addr )
533 {
534 #if OSL_DEBUG_LEVEL > 1
535 	g_nSocketAddr --;
536 #endif
537 	rtl_freeMemory( addr );
538 }
539 /*****************************************************************************/
540 /* osl_createEmptySocketAddr */
541 /*****************************************************************************/
osl_createEmptySocketAddr(oslAddrFamily Family)542 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
543 {
544 	oslSocketAddr pAddr = 0;
545 
546 	/* is it an internet-Addr? */
547 	if (Family == osl_Socket_FamilyInet)
548 	{
549 		pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
550 	}
551 	else
552 	{
553 		pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
554 	}
555 
556 	return pAddr;
557 }
558 
559 /*****************************************************************************/
560 /* osl_copySocketAddr */
561 /*****************************************************************************/
562 // @deprecated, to be removed
osl_copySocketAddr(oslSocketAddr Addr)563 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
564 {
565 	oslSocketAddr pCopy = 0;
566 	if (Addr)
567 	{
568 		pCopy = __osl_createSocketAddr();
569 
570 		if (pCopy)
571 			memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
572 	}
573 	return pCopy;
574 }
575 
576 /*****************************************************************************/
577 /* osl_isEqualSocketAddr */
578 /*****************************************************************************/
osl_isEqualSocketAddr(oslSocketAddr Addr1,oslSocketAddr Addr2)579 sal_Bool SAL_CALL osl_isEqualSocketAddr(oslSocketAddr Addr1, oslSocketAddr Addr2)
580 {
581 	struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
582 	struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
583 
584 	OSL_ASSERT(pAddr1);
585 	OSL_ASSERT(pAddr2);
586 
587 	if (pAddr1->sa_family == pAddr2->sa_family)
588 	{
589 		switch (pAddr1->sa_family)
590 		{
591 			case AF_INET:
592 			{
593 				struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
594 				struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
595 
596 				if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
597 					(pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
598 					(pInetAddr1->sin_port == pInetAddr2->sin_port))
599 					return (sal_True);
600 			}
601 
602 			default:
603 			{
604 				return (memcmp(pAddr1, Addr2, sizeof(struct sockaddr)) == 0);
605 			}
606 		}
607 	}
608 
609 	return (sal_False);
610 }
611 
612 /*****************************************************************************/
613 /* osl_createInetBroadcastAddr */
614 /*****************************************************************************/
osl_createInetBroadcastAddr(rtl_uString * strDottedAddr,sal_Int32 Port)615 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
616 	rtl_uString *strDottedAddr,
617 	sal_Int32    Port)
618 {
619 	sal_uInt32          nAddr = OSL_INADDR_NONE;
620 
621 	if (strDottedAddr && strDottedAddr->length)
622 	{
623 		/* Dotted host address for limited broadcast */
624 		rtl_String *pDottedAddr = NULL;
625 
626 		rtl_uString2String (
627 			&pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
628 			RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
629 
630 		nAddr = inet_addr (pDottedAddr->buffer);
631 		rtl_string_release (pDottedAddr);
632 	}
633 
634 	if (nAddr != OSL_INADDR_NONE)
635 	{
636 		/* Limited broadcast */
637 		nAddr = ntohl(nAddr);
638 		if (IN_CLASSA(nAddr))
639 		{
640 			nAddr &= IN_CLASSA_NET;
641 			nAddr |= IN_CLASSA_HOST;
642 		}
643 		else if (IN_CLASSB(nAddr))
644 		{
645 			nAddr &= IN_CLASSB_NET;
646 			nAddr |= IN_CLASSB_HOST;
647 		}
648 		else if (IN_CLASSC(nAddr))
649 		{
650 			nAddr &= IN_CLASSC_NET;
651 			nAddr |= IN_CLASSC_HOST;
652 		}
653 		else
654 		{
655 			/* No broadcast in class D */
656 			return ((oslSocketAddr)NULL);
657 		}
658 		nAddr = htonl(nAddr);
659 	}
660 
661 	oslSocketAddr pAddr =
662 		__osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( (sal_uInt16) Port), nAddr );
663 	return pAddr;
664 }
665 
666 /*****************************************************************************/
667 /* osl_createInetSocketAddr */
668 /*****************************************************************************/
osl_createInetSocketAddr(rtl_uString * strDottedAddr,sal_Int32 Port)669 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
670 	rtl_uString *strDottedAddr,
671 	sal_Int32    Port)
672 {
673 	DWORD Addr;
674 	rtl_String	*pDottedAddr=NULL;
675 
676 	rtl_uString2String(
677 		&pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
678 		RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
679 
680 	Addr= inet_addr (pDottedAddr->buffer);
681 	rtl_string_release (pDottedAddr);
682 
683 	oslSocketAddr pAddr = 0;
684 	if(Addr != -1)
685 	{
686 		pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( (sal_uInt16)Port), Addr );
687 	}
688 	return pAddr;
689 }
690 
osl_setAddrOfSocketAddr(oslSocketAddr pAddr,sal_Sequence * pByteSeq)691 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
692 {
693 	OSL_ASSERT( pAddr );
694 	OSL_ASSERT( pByteSeq );
695 
696 	oslSocketResult res = osl_Socket_Error;
697 	if( pAddr && pByteSeq )
698 	{
699 		OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
700 		OSL_ASSERT( pByteSeq->nElements == 4 );
701 		struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
702 		memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
703 		res = osl_Socket_Ok;
704 	}
705 	return res;
706 }
707 
708 /** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
709 	either be 0 or contain a constructed sal_Sequence.
710  */
osl_getAddrOfSocketAddr(oslSocketAddr pAddr,sal_Sequence ** ppByteSeq)711 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
712 {
713 	OSL_ASSERT( pAddr );
714 	OSL_ASSERT( ppByteSeq );
715 
716 	oslSocketResult res = osl_Socket_Error;
717 	if( pAddr && ppByteSeq )
718 	{
719 		struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
720 		rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
721 		res = osl_Socket_Ok;
722 	}
723 	return res;
724 }
725 
726 /*****************************************************************************/
727 /* oslHostAddr */
728 /*****************************************************************************/
729 struct oslHostAddrImpl {
730 	rtl_uString     *pHostName;
731 	oslSocketAddr   pSockAddr;
732 } ;
733 
__osl_hostentToHostAddr(const struct hostent * he)734 static oslHostAddr __osl_hostentToHostAddr (const struct hostent *he)
735 {
736 	oslHostAddr pAddr= NULL;
737 	oslSocketAddr pSocketAddr = 0;
738 
739 	rtl_uString     *cn= NULL;
740 
741 	if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
742 		return ((oslHostAddr)NULL);
743 
744 	rtl_string2UString(
745 		&cn, he->h_name, strlen(he->h_name),
746 		RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
747     OSL_ASSERT(cn != 0);
748 
749 	pSocketAddr = __osl_createSocketAddr();
750 
751 	if (pSocketAddr == NULL)
752 	{
753 		rtl_uString_release(cn);
754 		return ((oslHostAddr)NULL);
755 	}
756 
757 	pSocketAddr->m_sockaddr.sa_family = he->h_addrtype;
758 	if (pSocketAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
759 	{
760 		struct sockaddr_in *sin= (struct sockaddr_in *)&(pSocketAddr->m_sockaddr);
761 		memcpy (
762 			&(sin->sin_addr.s_addr),
763 			he->h_addr_list[0],
764 			he->h_length);
765 	}
766 	else
767 	{
768 		/* unknown address family */
769 		/* future extensions for new families might be implemented here */
770 
771         OSL_TRACE("_osl_hostentToHostAddr(): unknown address family.\n");
772 		OSL_ASSERT(sal_False);
773 
774 		__osl_destroySocketAddr( pSocketAddr );
775 		rtl_uString_release(cn);
776 		return ((oslHostAddr)NULL);
777 	}
778 
779 	pAddr= (oslHostAddr )rtl_allocateMemory (sizeof (struct oslHostAddrImpl));
780 
781 	if (pAddr == NULL)
782 	{
783 		__osl_destroySocketAddr( pSocketAddr );
784 		rtl_uString_release(cn);
785 		return ((oslHostAddr)NULL);
786 	}
787 
788 	pAddr->pHostName= cn;
789 	pAddr->pSockAddr= pSocketAddr;
790 
791 	return pAddr;
792 }
793 
794 /*****************************************************************************/
795 /* osl_createHostAddr */
796 /*****************************************************************************/
osl_createHostAddr(rtl_uString * strHostname,const oslSocketAddr pSocketAddr)797 oslHostAddr SAL_CALL osl_createHostAddr (
798 	rtl_uString         *strHostname,
799 	const oslSocketAddr  pSocketAddr)
800 {
801 	oslHostAddr pAddr;
802 	rtl_uString     *cn= NULL;
803 
804 	if ((strHostname == NULL)  || (strHostname->length == 0) || (pSocketAddr == NULL))
805 		return ((oslHostAddr)NULL);
806 
807 	rtl_uString_newFromString( &cn, strHostname);
808 
809 	if ( ! pSocketAddr )
810 	{
811 		rtl_uString_release(cn);
812 		return ((oslHostAddr)NULL);
813 	}
814 
815 	pAddr= (oslHostAddr)rtl_allocateMemory (sizeof (struct oslHostAddrImpl));
816 
817 	if (pAddr == NULL)
818 	{
819 		rtl_uString_release(cn);
820 		return ((oslHostAddr)NULL);
821 	}
822 
823 	pAddr->pHostName= cn;
824 	pAddr->pSockAddr= osl_copySocketAddr( pSocketAddr );
825 
826 	return ((oslHostAddr)pAddr);
827 }
828 
829 /*****************************************************************************/
830 /* osl_createHostAddrByName */
831 /*****************************************************************************/
osl_createHostAddrByName(rtl_uString * strHostname)832 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname)
833 {
834 	if ((strHostname == NULL) || (strHostname->length == 0))
835 		return ((oslHostAddr)NULL);
836 
837 	if (__osl_attemptSocketDialupImpl())
838 	{
839 		struct hostent *he;
840 		rtl_String     *Hostname= NULL;
841 
842 		rtl_uString2String(
843 			&Hostname, strHostname->buffer, strHostname->length,
844 			RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
845 
846 		he= gethostbyname (Hostname->buffer);
847 
848 		rtl_string_release (Hostname);
849 		return __osl_hostentToHostAddr (he);
850 	}
851 	return ((oslHostAddr)NULL);
852 }
853 
854 /*****************************************************************************/
855 /* osl_createHostAddrByAddr */
856 /*****************************************************************************/
osl_createHostAddrByAddr(const oslSocketAddr pAddr)857 oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr pAddr)
858 {
859 	if (pAddr == NULL)
860 		return ((oslHostAddr)NULL);
861 
862 	if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
863 	{
864 		const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
865 
866 		if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
867 			return ((oslHostAddr)NULL);
868 
869 		if (__osl_attemptSocketDialupImpl())
870 		{
871 			struct hostent *he;
872 			he= gethostbyaddr ((const sal_Char *)&(sin->sin_addr),
873 							   sizeof (sin->sin_addr),
874 							   sin->sin_family);
875 			return __osl_hostentToHostAddr (he);
876 		}
877 	}
878 
879 	return ((oslHostAddr)NULL);
880 }
881 
882 /*****************************************************************************/
883 /* osl_copyHostAddr */
884 /*****************************************************************************/
osl_copyHostAddr(const oslHostAddr Addr)885 oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr)
886 {
887 	oslHostAddr pAddr= (oslHostAddr)Addr;
888 
889 	if (pAddr)
890 		return osl_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
891 	else
892 		return ((oslHostAddr)NULL);
893 }
894 
895 /*****************************************************************************/
896 /* osl_getHostnameOfHostAddr */
897 /*****************************************************************************/
osl_getHostnameOfHostAddr(const oslHostAddr pAddr,rtl_uString ** strHostname)898 void SAL_CALL osl_getHostnameOfHostAddr(
899 	const oslHostAddr pAddr, rtl_uString **strHostname)
900 {
901 	if (pAddr)
902 		rtl_uString_assign (strHostname, pAddr->pHostName);
903 	else
904 		rtl_uString_new (strHostname);
905 }
906 
907 /*****************************************************************************/
908 /* osl_getSocketAddrOfHostAddr */
909 /*****************************************************************************/
osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)910 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)
911 {
912 	if (pAddr)
913 		return (const oslSocketAddr)(pAddr->pSockAddr);
914 	else
915 		return NULL;
916 }
917 
918 /*****************************************************************************/
919 /* osl_destroyHostAddr */
920 /*****************************************************************************/
osl_destroyHostAddr(oslHostAddr pAddr)921 void SAL_CALL osl_destroyHostAddr(oslHostAddr pAddr)
922 {
923 	if (pAddr)
924 	{
925 		if (pAddr->pHostName)
926 			rtl_uString_release (pAddr->pHostName);
927 		if (pAddr->pSockAddr)
928 			osl_destroySocketAddr( pAddr->pSockAddr );
929 
930 		rtl_freeMemory (pAddr);
931 	}
932 }
933 
934 /*****************************************************************************/
935 /* osl_getLocalHostname */
936 /*****************************************************************************/
osl_getLocalHostname(rtl_uString ** strLocalHostname)937 oslSocketResult SAL_CALL osl_getLocalHostname (rtl_uString **strLocalHostname)
938 {
939 	static sal_Unicode LocalHostname[256] = {0};
940 
941 	if (rtl_ustr_getLength(LocalHostname) == 0)
942 	{
943 		sal_Char Host[256]= "";
944 		if (gethostname(Host, sizeof(Host)) == 0)
945 		{
946 			/* check if we have an FQDN */
947 	    	if (strchr(Host, '.') == NULL)
948 	        {
949 				oslHostAddr pAddr;
950 				rtl_uString     *hostName= NULL;
951 
952 				rtl_string2UString(
953 					&hostName, Host, strlen(Host),
954 					RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
955                 OSL_ASSERT(hostName != 0);
956 
957 				/* no, determine it via dns */
958 				pAddr = osl_createHostAddrByName(hostName);
959 				rtl_uString_release (hostName);
960 
961 				if (pAddr && pAddr->pHostName)
962 					memcpy(LocalHostname, pAddr->pHostName->buffer, sizeof(sal_Unicode)*(rtl_ustr_getLength(pAddr->pHostName->buffer)+1));
963 				else
964 					memset(LocalHostname, 0, sizeof(LocalHostname));
965 
966 				osl_destroyHostAddr ((oslHostAddr)pAddr);
967 			}
968 		}
969 	}
970 
971 	if (rtl_ustr_getLength(LocalHostname) > 0)
972 	{
973 		rtl_uString_newFromStr (strLocalHostname, LocalHostname);
974 		return osl_Socket_Ok;
975 	}
976 
977 	return osl_Socket_Error;
978 }
979 
980 /*****************************************************************************/
981 /* osl_resolveHostname */
982 /*****************************************************************************/
osl_resolveHostname(rtl_uString * strHostname)983 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString* strHostname)
984 {
985 	oslHostAddr pAddr=
986 		(oslHostAddr )osl_createHostAddrByName (strHostname);
987 	if (pAddr)
988 	{
989 		oslSocketAddr SockAddr = osl_copySocketAddr( pAddr->pSockAddr );
990 		osl_destroyHostAddr(pAddr);
991 		return (SockAddr);
992 	}
993 	return ((oslSocketAddr)NULL);
994 }
995 
996 /*****************************************************************************/
997 /* osl_getServicePort */
998 /*****************************************************************************/
osl_getServicePort(rtl_uString * strServicename,rtl_uString * strProtocol)999 sal_Int32 SAL_CALL osl_getServicePort (
1000 	rtl_uString* strServicename,
1001 	rtl_uString* strProtocol)
1002 {
1003 	struct servent* ps;
1004 
1005 	rtl_String *str_Servicename=NULL;
1006 	rtl_String *str_Protocol=NULL;
1007 
1008 	rtl_uString2String(
1009 		&str_Servicename,
1010 		rtl_uString_getStr(strServicename),
1011 		rtl_uString_getLength(strServicename),
1012 		RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
1013 	rtl_uString2String(
1014 		&str_Protocol,
1015 		rtl_uString_getStr(strProtocol),
1016 		rtl_uString_getLength(strProtocol),
1017 		RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
1018 
1019 	ps= getservbyname(
1020 		rtl_string_getStr(str_Servicename),
1021 		rtl_string_getStr(str_Protocol));
1022 
1023 	rtl_string_release( str_Servicename );
1024 	rtl_string_release( str_Protocol );
1025 
1026 	if (ps != 0)
1027 		return ntohs(ps->s_port);
1028 
1029 	return OSL_INVALID_PORT;
1030 }
1031 
1032 /*****************************************************************************/
1033 /* osl_destroySocketAddr */
1034 /*****************************************************************************/
osl_destroySocketAddr(oslSocketAddr pAddr)1035 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1036 {
1037 	__osl_destroySocketAddr( pAddr );
1038 }
1039 
1040 /*****************************************************************************/
1041 /* osl_getFamilyOfSocketAddr */
1042 /*****************************************************************************/
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)1043 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1044 {
1045 	if (pAddr)
1046 		return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1047 	else
1048 		return osl_Socket_FamilyInvalid;
1049 }
1050 
1051 /*****************************************************************************/
1052 /* osl_getInetPortOfSocketAddr */
1053 /*****************************************************************************/
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)1054 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1055 {
1056 	if( pAddr )
1057 	{
1058 		struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1059 
1060 		if ( (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet)))
1061 			return ntohs(pSystemInetAddr->sin_port);
1062 	}
1063 	return OSL_INVALID_PORT;
1064 }
1065 
1066 /*****************************************************************************/
1067 /* osl_setInetPortOfSocketAddr */
1068 /*****************************************************************************/
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr,sal_Int32 Port)1069 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr (
1070 	oslSocketAddr pAddr,
1071 	sal_Int32     Port)
1072 {
1073 	if (pAddr == NULL)
1074 		return sal_False;
1075 
1076 	struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1077 
1078 	if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1079 		return sal_False;
1080 
1081 	pSystemInetAddr->sin_port= htons((short)Port);
1082 	return sal_True;
1083 }
1084 
1085 /*****************************************************************************/
1086 /* osl_getHostnameOfSocketAddr */
1087 /*****************************************************************************/
osl_getHostnameOfSocketAddr(oslSocketAddr Addr,rtl_uString ** strHostName)1088 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr (
1089 	oslSocketAddr   Addr,
1090 	rtl_uString   **strHostName)
1091 {
1092 	oslHostAddr pAddr= osl_createHostAddrByAddr (Addr);
1093 
1094 	if (pAddr)
1095 	{
1096 		rtl_uString_newFromString(strHostName, pAddr->pHostName);
1097 
1098 		osl_destroyHostAddr(pAddr);
1099 
1100 		return osl_Socket_Ok;
1101 	}
1102 
1103 	return osl_Socket_Error;
1104 }
1105 
1106 /*****************************************************************************/
1107 /* osl_getDottedInetAddrOfSocketAddr */
1108 /*****************************************************************************/
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,rtl_uString ** strDottedInetAddr)1109 oslSocketResult	SAL_CALL osl_getDottedInetAddrOfSocketAddr (
1110 	oslSocketAddr   pAddr,
1111 	rtl_uString   **strDottedInetAddr)
1112 {
1113 	sal_Char           *pDotted;
1114 
1115 	if (pAddr == NULL)
1116 		return osl_Socket_Error;
1117 
1118 	struct sockaddr_in *pSystemInetAddr = (struct sockaddr_in*) &(pAddr->m_sockaddr);
1119 	if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1120 		return osl_Socket_Error;
1121 
1122 	pDotted = inet_ntoa (pSystemInetAddr->sin_addr);
1123 	rtl_string2UString(
1124 		strDottedInetAddr, pDotted, strlen (pDotted),
1125 		RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
1126     OSL_ASSERT(*strDottedInetAddr != 0);
1127 
1128 	return osl_Socket_Ok;
1129 }
1130 
1131 /*****************************************************************************/
1132 /* osl_createSocket  */
1133 /*****************************************************************************/
osl_createSocket(oslAddrFamily Family,oslSocketType Type,oslProtocol Protocol)1134 oslSocket SAL_CALL osl_createSocket (
1135 	oslAddrFamily Family,
1136 	oslSocketType Type,
1137 	oslProtocol   Protocol)
1138 {
1139 	/* alloc memory */
1140 	oslSocket pSocket = __osl_createSocketImpl(0);
1141 
1142 	if (pSocket == NULL)
1143 		return 0;
1144 
1145 	/* create socket */
1146 	pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1147 								TYPE_TO_NATIVE(Type),
1148 								PROTOCOL_TO_NATIVE(Protocol));
1149 
1150 	/* creation failed => free memory */
1151 	if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1152 	{
1153 		__osl_destroySocketImpl(pSocket);
1154 		pSocket= 0;
1155 	}
1156 	else
1157 	{
1158 		pSocket->m_Flags			= 0;
1159 		pSocket->m_CloseCallback	= NULL;
1160 		pSocket->m_CallbackArg	= NULL;
1161 	}
1162 
1163 	return pSocket;
1164 }
1165 
osl_acquireSocket(oslSocket pSocket)1166 void SAL_CALL osl_acquireSocket( oslSocket pSocket )
1167 {
1168 	osl_incrementInterlockedCount( &(pSocket->m_nRefCount) );
1169 }
1170 
osl_releaseSocket(oslSocket pSocket)1171 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1172 {
1173 	if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
1174 	{
1175 		osl_closeSocket( pSocket );
1176 		__osl_destroySocketImpl( pSocket );
1177 	}
1178 }
1179 
1180 /*****************************************************************************/
1181 /* osl_closeSocket  */
1182 /*****************************************************************************/
osl_closeSocket(oslSocket pSocket)1183 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1184 {
1185 	/* socket already invalid */
1186 	if(pSocket==0)
1187 		return;
1188 
1189 	/* close */
1190 	closesocket(pSocket->m_Socket);
1191 
1192 	pSocket->m_Socket = OSL_INVALID_SOCKET;
1193 
1194 	/* registrierten Callback ausfuehren */
1195 	if (pSocket->m_CloseCallback != NULL)
1196 	{
1197 		pSocket->m_CloseCallback(pSocket->m_CallbackArg);
1198 	}
1199 }
1200 
1201 /*****************************************************************************/
1202 /* osl_getLocalAddrOfSocket  */
1203 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1204 /* are the same! I don't like it very much but see no other easy way */
1205 /* to conceal the struct sockaddr from the eyes of the user. */
1206 /*****************************************************************************/
osl_getLocalAddrOfSocket(oslSocket pSocket)1207 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1208 {
1209 	struct sockaddr Addr;
1210 	int             AddrLen;
1211 
1212 	if (pSocket == NULL) /* ENOTSOCK */
1213 		return ((oslSocketAddr)NULL);
1214 
1215 	AddrLen= sizeof(struct sockaddr);
1216 
1217 	if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1218 		return ((oslSocketAddr)NULL);
1219 
1220 	oslSocketAddr pAddr = __osl_createSocketAddrFromSystem( &Addr );
1221 	return pAddr;
1222 }
1223 
1224 /*****************************************************************************/
1225 /* osl_getPeerAddrOfSocket  */
1226 /*****************************************************************************/
osl_getPeerAddrOfSocket(oslSocket pSocket)1227 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1228 {
1229 	struct sockaddr Addr;
1230 	int             AddrLen;
1231 
1232 	if (pSocket == NULL) /* ENOTSOCK */
1233 		return ((oslSocketAddr)NULL);
1234 
1235 	AddrLen= sizeof(struct sockaddr);
1236 
1237 	if (getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1238 		return ((oslSocketAddr)NULL);
1239 
1240 	oslSocketAddr pAddr = __osl_createSocketAddrFromSystem( &Addr );
1241 	return pAddr;
1242 }
1243 
1244 /*****************************************************************************/
1245 /* osl_bindAddrToSocket  */
1246 /*****************************************************************************/
osl_bindAddrToSocket(oslSocket pSocket,oslSocketAddr pAddr)1247 sal_Bool SAL_CALL osl_bindAddrToSocket ( oslSocket pSocket, oslSocketAddr pAddr)
1248 {
1249 	OSL_ASSERT( pAddr );
1250 
1251 	if (pSocket == NULL) /* ENOTSOCK */
1252 		return sal_False;
1253 
1254 	return (bind(pSocket->m_Socket,
1255 				 &(pAddr->m_sockaddr),
1256 				 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR);
1257 }
1258 
1259 /*****************************************************************************/
1260 /* osl_connectSocketTo  */
1261 /*****************************************************************************/
osl_connectSocketTo(oslSocket pSocket,oslSocketAddr pAddr,const TimeValue * pTimeout)1262 oslSocketResult SAL_CALL osl_connectSocketTo (
1263 	oslSocket        pSocket,
1264 	oslSocketAddr    pAddr,
1265 	const TimeValue* pTimeout)
1266 {
1267 
1268 	if (pSocket == NULL) /* ENOTSOCK */
1269 		return osl_Socket_Error;
1270 
1271 	if (pAddr == NULL) /* EDESTADDRREQ */
1272 		return osl_Socket_Error;
1273 
1274 	if (!__osl_attemptSocketDialupImpl()) /* ENETDOWN */
1275 		return osl_Socket_Error;
1276 
1277 	if (pTimeout == NULL)
1278 	{
1279 		if(connect(pSocket->m_Socket,
1280 				   &(pAddr->m_sockaddr),
1281 					sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
1282 			return osl_Socket_Error;
1283 		else
1284 			return osl_Socket_Ok;
1285 	}
1286 	else
1287 	{
1288 		fd_set          fds;
1289 		int	            error;
1290 	    struct timeval  tv;
1291 		unsigned long   Param;
1292 		oslSocketResult Result= osl_Socket_Ok;
1293 
1294 		if (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING)
1295 	    {
1296 			if (connect(pSocket->m_Socket,
1297 			    	    &(pAddr->m_sockaddr),
1298 						sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
1299 			{
1300 			    switch (WSAGetLastError())
1301 			    {
1302 					case WSAEWOULDBLOCK:
1303 					case WSAEINPROGRESS:
1304 						return osl_Socket_InProgress;
1305 
1306 					default:
1307 						return osl_Socket_Error;
1308 				}
1309 			}
1310 			else
1311 				return osl_Socket_Ok;
1312 		}
1313 
1314 		/* set socket temporarily to non-blocking */
1315 		Param= 1;
1316 		OSL_VERIFY(ioctlsocket(
1317 			pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1318 
1319 		/* initiate connect */
1320 		if (connect(pSocket->m_Socket,
1321 		     	    &(pAddr->m_sockaddr),
1322 				    sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1323 		{
1324 		   /* immediate connection */
1325 
1326 			Param= 0;
1327 			ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1328 
1329 			return osl_Socket_Ok;
1330 	    }
1331 		else
1332 		{
1333 			error = WSAGetLastError();
1334 
1335 		    /* really an error or just delayed? */
1336 		    if (error != WSAEWOULDBLOCK && error != WSAEINPROGRESS)
1337 		    {
1338 			     Param= 0;
1339 			     ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1340 
1341 			     return osl_Socket_Error;
1342 		    }
1343 		}
1344 
1345 		/* prepare select set for socket  */
1346 		FD_ZERO(&fds);
1347 		FD_SET(pSocket->m_Socket, &fds);
1348 
1349 		/* divide milliseconds into seconds and microseconds */
1350 		tv.tv_sec=	pTimeout->Seconds;
1351 		tv.tv_usec=	pTimeout->Nanosec / 1000L;
1352 
1353 		/* select */
1354 	    error= select(pSocket->m_Socket+1,
1355 		 		      0,
1356 					  &fds,
1357 					  0,
1358 					  &tv);
1359 
1360 		if (error > 0)  /* connected */
1361 		{
1362 			OSL_POSTCOND(
1363 				FD_ISSET(pSocket->m_Socket, &fds),
1364 				"osl_connectSocketTo(): select returned but socket not set\n");
1365 
1366 			Result= osl_Socket_Ok;
1367 
1368 		}
1369 		else if(error < 0)  /* error */
1370 		{
1371 		    /* errno == EBADF: most probably interrupted by close() */
1372 		    if(WSAGetLastError() == WSAEBADF)
1373 			{
1374 			    /* do not access pSockImpl because it is about to be or */
1375 			    /* already destroyed */
1376 			    return osl_Socket_Interrupted;
1377 			}
1378 			else
1379 			    Result= osl_Socket_Error;
1380 
1381 		}
1382 		else    /* timeout */
1383 			Result= osl_Socket_TimedOut;
1384 
1385 
1386 		/* clean up */
1387 		Param= 0;
1388 		ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1389 
1390 		return Result;
1391 	}
1392 }
1393 
1394 /*****************************************************************************/
1395 /* osl_listenOnSocket  */
1396 /*****************************************************************************/
osl_listenOnSocket(oslSocket pSocket,sal_Int32 MaxPendingConnections)1397 sal_Bool SAL_CALL osl_listenOnSocket (
1398 	oslSocket  pSocket,
1399 	sal_Int32  MaxPendingConnections)
1400 {
1401 	if (pSocket == NULL) /* ENOTSOCK */
1402 		return sal_False;
1403 
1404 	return (listen(pSocket->m_Socket,
1405 				   MaxPendingConnections == -1 ?
1406 				   SOMAXCONN :
1407 				   MaxPendingConnections) != OSL_SOCKET_ERROR);
1408 }
1409 
1410 /*****************************************************************************/
1411 /* osl_acceptConnectionOnSocket  */
1412 /*****************************************************************************/
osl_acceptConnectionOnSocket(oslSocket pSocket,oslSocketAddr * ppAddr)1413 oslSocket SAL_CALL osl_acceptConnectionOnSocket (
1414 	oslSocket      pSocket,
1415 	oslSocketAddr* ppAddr)
1416 {
1417 	if (pSocket == NULL) /* ENOTSOCK */
1418 		return ((oslSocket)NULL);
1419 
1420 	SOCKET          Connection;
1421 	if(ppAddr)
1422 	{
1423 		if( *ppAddr )
1424 		{
1425 			osl_destroySocketAddr( *ppAddr );
1426 			*ppAddr = 0;
1427 		}
1428 		int AddrLen= sizeof(struct sockaddr);
1429 
1430 		/* user wants to know peer Addr */
1431 		struct sockaddr Addr;
1432 
1433 		Connection=	accept(pSocket->m_Socket, &Addr, &AddrLen);
1434 		OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
1435 
1436 		if(Connection != OSL_SOCKET_ERROR)
1437 			*ppAddr= __osl_createSocketAddrFromSystem(&Addr);
1438 		else
1439 			*ppAddr = NULL;
1440 	}
1441 	else
1442 	{
1443 		/* user is not interested in peer-addr */
1444 		Connection=	accept(pSocket->m_Socket, 0, 0);
1445 	}
1446 
1447 	/* accept failed? */
1448 	if(Connection == OSL_SOCKET_ERROR)
1449 		return ((oslSocket)NULL);
1450 
1451 	/* alloc memory */
1452 	oslSocket  pConnectionSocket;
1453 	pConnectionSocket= __osl_createSocketImpl(Connection);
1454 
1455 	pConnectionSocket->m_Flags			= 0;
1456 	pConnectionSocket->m_CloseCallback	= NULL;
1457 	pConnectionSocket->m_CallbackArg	= NULL;
1458 
1459 	return pConnectionSocket;
1460 }
1461 
1462 /*****************************************************************************/
1463 /* osl_receiveSocket  */
1464 /*****************************************************************************/
osl_receiveSocket(oslSocket pSocket,void * pBuffer,sal_uInt32 BytesToRead,oslSocketMsgFlag Flag)1465 sal_Int32 SAL_CALL osl_receiveSocket (
1466 	oslSocket        pSocket,
1467 	void*            pBuffer,
1468 	sal_uInt32       BytesToRead,
1469 	oslSocketMsgFlag Flag)
1470 {
1471 	if (pSocket == NULL) /* ENOTSOCK */
1472 		return osl_Socket_Error;
1473 
1474 	return recv(pSocket->m_Socket,
1475 				(sal_Char*)pBuffer,
1476 				BytesToRead,
1477 				MSG_FLAG_TO_NATIVE(Flag));
1478 }
1479 
1480 /*****************************************************************************/
1481 /* osl_receiveFromSocket  */
1482 /*****************************************************************************/
osl_receiveFromSocket(oslSocket pSocket,oslSocketAddr SenderAddr,void * pBuffer,sal_uInt32 BufferSize,oslSocketMsgFlag Flag)1483 sal_Int32 SAL_CALL osl_receiveFromSocket (
1484 	oslSocket        pSocket,
1485 	oslSocketAddr    SenderAddr,
1486 	void*            pBuffer,
1487 	sal_uInt32       BufferSize,
1488 	oslSocketMsgFlag Flag)
1489 {
1490 	struct sockaddr *pSystemSockAddr = 0;
1491 	int AddrLen = 0;
1492 	if( SenderAddr )
1493 	{
1494 		AddrLen = sizeof( struct sockaddr );
1495 		pSystemSockAddr = &(SenderAddr->m_sockaddr);
1496 	}
1497 
1498 	if (pSocket == NULL) /* ENOTSOCK */
1499 		return osl_Socket_Error;
1500 
1501 	return recvfrom(pSocket->m_Socket,
1502 					 (sal_Char*)pBuffer,
1503 					 BufferSize,
1504 					 MSG_FLAG_TO_NATIVE(Flag),
1505 					 pSystemSockAddr,
1506 					 &AddrLen);
1507 }
1508 
1509 /*****************************************************************************/
1510 /* osl_sendSocket  */
1511 /*****************************************************************************/
osl_sendSocket(oslSocket pSocket,const void * pBuffer,sal_uInt32 BytesToSend,oslSocketMsgFlag Flag)1512 sal_Int32 SAL_CALL osl_sendSocket (
1513 	oslSocket        pSocket,
1514 	const void*      pBuffer,
1515 	sal_uInt32       BytesToSend,
1516 	oslSocketMsgFlag Flag)
1517 {
1518 	if (pSocket == NULL) /* ENOTSOCK */
1519 		return osl_Socket_Error;
1520 
1521 	return send(pSocket->m_Socket,
1522 				(sal_Char*)pBuffer,
1523 				BytesToSend,
1524 				MSG_FLAG_TO_NATIVE(Flag));
1525 }
1526 
1527 /*****************************************************************************/
1528 /* osl_sendToSocket  */
1529 /*****************************************************************************/
osl_sendToSocket(oslSocket pSocket,oslSocketAddr ReceiverAddr,const void * pBuffer,sal_uInt32 BytesToSend,oslSocketMsgFlag Flag)1530 sal_Int32 SAL_CALL osl_sendToSocket (
1531 	oslSocket        pSocket,
1532 	oslSocketAddr    ReceiverAddr,
1533 	const void*      pBuffer,
1534 	sal_uInt32       BytesToSend,
1535 	oslSocketMsgFlag Flag)
1536 {
1537 	if (pSocket == NULL) /* ENOTSOCK */
1538 		return osl_Socket_Error;
1539 
1540 	/* ReceiverAddr might be 0 when used on a connected socket. */
1541 	/* Then sendto should behave like send. */
1542 
1543 	struct sockaddr *pSystemSockAddr = 0;
1544 	if( ReceiverAddr )
1545 		pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1546 
1547 	return sendto(pSocket->m_Socket,
1548 				  (sal_Char*)pBuffer,
1549 				  BytesToSend,
1550 				  MSG_FLAG_TO_NATIVE(Flag),
1551 				  pSystemSockAddr,
1552 				  pSystemSockAddr == 0 ? 0 : sizeof(struct sockaddr));
1553 }
1554 
1555 /*****************************************************************************/
1556 /* osl_readSocket  */
1557 /*****************************************************************************/
osl_readSocket(oslSocket pSocket,void * pBuffer,sal_Int32 n)1558 sal_Int32 SAL_CALL osl_readSocket( oslSocket pSocket, void *pBuffer, sal_Int32 n )
1559 {
1560 	sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
1561 
1562 	OSL_ASSERT( pSocket);
1563 
1564 	/* loop until all desired bytes were read or an error occurred */
1565 	sal_uInt32 BytesRead= 0;
1566 	sal_uInt32 BytesToRead= n;
1567 	while (BytesToRead > 0)
1568 	{
1569 		sal_Int32 RetVal;
1570 		RetVal= osl_receiveSocket(pSocket,
1571 								   Ptr,
1572 								   BytesToRead,
1573 								   osl_Socket_MsgNormal);
1574 
1575 		/* error occurred? */
1576 		if(RetVal <= 0)
1577 		{
1578 			break;
1579 		}
1580 
1581 		BytesToRead -= RetVal;
1582 		BytesRead += RetVal;
1583 		Ptr += RetVal;
1584 	}
1585 
1586 	return BytesRead;
1587 }
1588 
1589 /*****************************************************************************/
1590 /* osl_writeSocket  */
1591 /*****************************************************************************/
osl_writeSocket(oslSocket pSocket,const void * pBuffer,sal_Int32 n)1592 sal_Int32 SAL_CALL osl_writeSocket( oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1593 {
1594     OSL_ASSERT( pSocket );
1595 
1596 	/* loop until all desired bytes were send or an error occurred */
1597 	sal_uInt32 BytesSend= 0;
1598 	sal_uInt32 BytesToSend= n;
1599 	sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
1600 	while (BytesToSend > 0)
1601 	{
1602 		sal_Int32 RetVal;
1603 
1604 		RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1605 
1606 		/* error occurred? */
1607 		if(RetVal <= 0)
1608 		{
1609 			break;
1610 		}
1611 
1612 		BytesToSend -= RetVal;
1613 		BytesSend += RetVal;
1614 		Ptr += RetVal;
1615 
1616 	}
1617 	return BytesSend;
1618 }
1619 
1620 
1621 /*****************************************************************************/
1622 /* osl_isReceiveReady  */
1623 /*****************************************************************************/
osl_isReceiveReady(oslSocket pSocket,const TimeValue * pTimeout)1624 sal_Bool SAL_CALL osl_isReceiveReady (
1625 	oslSocket        pSocket,
1626 	const TimeValue* pTimeout)
1627 {
1628 	fd_set         fds;
1629 	struct timeval tv;
1630 
1631 	if (pSocket == NULL) /* ENOTSOCK */
1632 		return sal_False;
1633 
1634 	FD_ZERO(&fds);
1635 	FD_SET(pSocket->m_Socket, &fds);
1636 
1637 	if (pTimeout)
1638 	{
1639 		tv.tv_sec  = pTimeout->Seconds;
1640 		tv.tv_usec = pTimeout->Nanosec / 1000L;
1641 	}
1642 
1643 	return (select(pSocket->m_Socket + 1,		/* no of sockets to monitor */
1644 				   &fds,						/* check read operations */
1645 				   0,							/* check write ops */
1646 				   0,							/* ckeck for OOB */
1647 				   (pTimeout) ? &tv : 0)==1);	/* use timeout? */
1648 }
1649 
1650 /*****************************************************************************/
1651 /* osl_isSendReady  */
1652 /*****************************************************************************/
osl_isSendReady(oslSocket pSocket,const TimeValue * pTimeout)1653 sal_Bool SAL_CALL osl_isSendReady (
1654 	oslSocket        pSocket,
1655 	const TimeValue* pTimeout)
1656 {
1657 	fd_set         fds;
1658 	struct timeval tv;
1659 
1660 	if (pSocket == NULL) /* ENOTSOCK */
1661 		return sal_False;
1662 
1663 	FD_ZERO(&fds);
1664 	FD_SET(pSocket->m_Socket, &fds);
1665 
1666 	if (pTimeout)
1667 	{
1668 		tv.tv_sec  = pTimeout->Seconds;
1669 		tv.tv_usec = pTimeout->Nanosec / 1000L;
1670 	}
1671 
1672 	return (select(pSocket->m_Socket + 1,		/* no of sockets to monitor */
1673 				   0,							/* check read operations */
1674 				   &fds,						/* check write ops */
1675 				   0,							/* ckeck for OOB */
1676 				   (pTimeout) ? &tv : 0)==1);	/* use timeout? */
1677 }
1678 
1679 /*****************************************************************************/
1680 /* osl_isExceptionPending  */
1681 /*****************************************************************************/
osl_isExceptionPending(oslSocket pSocket,const TimeValue * pTimeout)1682 sal_Bool SAL_CALL osl_isExceptionPending (
1683 	oslSocket        pSocket,
1684 	const TimeValue* pTimeout)
1685 {
1686 	fd_set         fds;
1687 	struct timeval tv;
1688 
1689 	if (pSocket == NULL) /* ENOTSOCK */
1690 		return sal_False;
1691 
1692 	FD_ZERO(&fds);
1693 	FD_SET(pSocket->m_Socket, &fds);
1694 
1695 	if (pTimeout)
1696 	{
1697 		tv.tv_sec  = pTimeout->Seconds;
1698 		tv.tv_usec = pTimeout->Nanosec / 1000L;
1699 	}
1700 
1701 	return (select(pSocket->m_Socket + 1,	    /* no of sockets to monitor */
1702 				   0,							/* check read operations */
1703 				   0,							/* check write ops */
1704 				   &fds,						/* ckeck for OOB */
1705 				   (pTimeout) ? &tv : 0)==1);	/* use timeout? */
1706 }
1707 
1708 /*****************************************************************************/
1709 /* osl_shutdownSocket  */
1710 /*****************************************************************************/
osl_shutdownSocket(oslSocket pSocket,oslSocketDirection Direction)1711 sal_Bool SAL_CALL osl_shutdownSocket (
1712 	oslSocket          pSocket,
1713 	oslSocketDirection Direction)
1714 {
1715 	if (pSocket == NULL) /* ENOTSOCK */
1716 		return sal_False;
1717 
1718 	return (shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction))==0);
1719 }
1720 
1721 /*****************************************************************************/
1722 /* osl_getSocketOption  */
1723 /*****************************************************************************/
osl_getSocketOption(oslSocket pSocket,oslSocketOptionLevel Level,oslSocketOption Option,void * pBuffer,sal_uInt32 BufferLen)1724 sal_Int32 SAL_CALL osl_getSocketOption (
1725 	oslSocket            pSocket,
1726 	oslSocketOptionLevel Level,
1727 	oslSocketOption      Option,
1728 	void*                pBuffer,
1729 	sal_uInt32           BufferLen)
1730 {
1731 	if (pSocket == NULL) /* ENOTSOCK */
1732 		return osl_Socket_Error;
1733 
1734 	if (getsockopt(pSocket->m_Socket,
1735 	     		   OPTION_LEVEL_TO_NATIVE(Level),
1736 				   OPTION_TO_NATIVE(Option),
1737 				   (sal_Char*)pBuffer,
1738 				   (int*)&BufferLen) == -1)
1739 	{
1740 		return -1;
1741 	}
1742 
1743 	return (sal_Int32)BufferLen;
1744 }
1745 
1746 /*****************************************************************************/
1747 /* osl_setSocketOption  */
1748 /*****************************************************************************/
osl_setSocketOption(oslSocket pSocket,oslSocketOptionLevel Level,oslSocketOption Option,void * pBuffer,sal_uInt32 BufferLen)1749 sal_Bool SAL_CALL osl_setSocketOption (
1750 	oslSocket            pSocket,
1751 	oslSocketOptionLevel Level,
1752 	oslSocketOption      Option,
1753 	void*                pBuffer,
1754 	sal_uInt32           BufferLen)
1755 {
1756 	if (pSocket == NULL) /* ENOTSOCK */
1757 		return sal_False;
1758 
1759 	return(setsockopt(pSocket->m_Socket,
1760 					  OPTION_LEVEL_TO_NATIVE(Level),
1761 					  OPTION_TO_NATIVE(Option),
1762 					  (sal_Char*)pBuffer,
1763 					  BufferLen) == 0);
1764 }
1765 
1766 /*****************************************************************************/
1767 /* osl_enableNonBlockingMode  */
1768 /*****************************************************************************/
osl_enableNonBlockingMode(oslSocket pSocket,sal_Bool On)1769 sal_Bool SAL_CALL osl_enableNonBlockingMode ( oslSocket pSocket, sal_Bool  On)
1770 {
1771 	unsigned long  Param= On ? 1 : 0;
1772 
1773 	if (pSocket == NULL) /* ENOTSOCK */
1774 		return sal_False;
1775 
1776 	pSocket->m_Flags = Param ?
1777 		(pSocket->m_Flags |  OSL_SOCKET_FLAGS_NONBLOCKING) :
1778 		(pSocket->m_Flags & ~OSL_SOCKET_FLAGS_NONBLOCKING) ;
1779 
1780 	return (
1781 		ioctlsocket(pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1782 }
1783 
1784 /*****************************************************************************/
1785 /* osl_isNonBlockingMode  */
1786 /*****************************************************************************/
osl_isNonBlockingMode(oslSocket pSocket)1787 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
1788 {
1789 	if (pSocket == NULL) /* ENOTSOCK */
1790 		return sal_False;
1791 
1792 	return (sal_Bool)((pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING) != 0);
1793 }
1794 
1795 /*****************************************************************************/
1796 /* osl_getSocketType  */
1797 /*****************************************************************************/
osl_getSocketType(oslSocket pSocket)1798 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
1799 {
1800 	int            Type=0;
1801 	int            TypeSize= sizeof(Type);
1802 
1803 	if (pSocket == NULL) /* ENOTSOCK */
1804 		return osl_Socket_TypeInvalid;
1805 
1806 	if(getsockopt(pSocket->m_Socket,
1807 				  OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
1808 				  OPTION_TO_NATIVE(osl_Socket_OptionType),
1809 				  (sal_Char *)&Type,
1810 				  &TypeSize) == -1)
1811 	{
1812 		/* error */
1813 		return osl_Socket_TypeInvalid;
1814 	}
1815 
1816 	return TYPE_FROM_NATIVE(Type);
1817 }
1818 
1819 /*****************************************************************************/
1820 /* osl_getLastSocketErrorDescription  */
1821 /*****************************************************************************/
osl_getLastSocketErrorDescription(oslSocket,rtl_uString ** strError)1822 void SAL_CALL osl_getLastSocketErrorDescription (
1823 	oslSocket  /*Socket*/,
1824 	rtl_uString	**strError)
1825 {
1826 	int error;
1827 
1828 	switch(error = WSAGetLastError())
1829 	{
1830 		case WSAENOTSOCK:
1831 			rtl_uString_newFromAscii (strError, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1832             break;
1833 
1834         case WSAEDESTADDRREQ:
1835 			rtl_uString_newFromAscii (strError, "WSAEDESTADDRREQ, Destination Addr required");
1836             break;
1837 
1838         case WSAEMSGSIZE:
1839             rtl_uString_newFromAscii (strError, "WSAEMSGSIZE, Message too long");
1840             break;
1841 
1842         case WSAEPROTOTYPE:
1843 			rtl_uString_newFromAscii (strError, "WSAEPROTOTYPE, Protocol wrong type for socket");
1844             break;
1845 
1846         case WSAENOPROTOOPT:
1847 			rtl_uString_newFromAscii (strError, "WSAENOPROTOOPT, Protocol not available");
1848             break;
1849 
1850         case WSAEPROTONOSUPPORT:
1851 			rtl_uString_newFromAscii (strError, "WSAEPROTONOSUPPORT, Protocol not supported");
1852             break;
1853 
1854         case WSAESOCKTNOSUPPORT:
1855 			rtl_uString_newFromAscii (strError, "WSAESOCKTNOSUPPORT, Socket type not supported");
1856             break;
1857 
1858         case WSAEOPNOTSUPP:
1859 			rtl_uString_newFromAscii (strError, "WSAEOPNOTSUPP, Operation not supported on socket");
1860             break;
1861 
1862         case WSAEPFNOSUPPORT:
1863 			rtl_uString_newFromAscii (strError, "WSAEPFNOSUPPORT, Protocol family not supported");
1864             break;
1865 
1866         case WSAEAFNOSUPPORT:
1867 			rtl_uString_newFromAscii (strError, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1868             break;
1869 
1870         case WSAEADDRINUSE:
1871 			rtl_uString_newFromAscii (strError, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1872             break;
1873 
1874         case WSAEADDRNOTAVAIL:
1875 			rtl_uString_newFromAscii (strError, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1876             break;
1877 
1878         case WSAENETDOWN:
1879 			rtl_uString_newFromAscii (strError, "WSAENETDOWN, Network is down");
1880             break;
1881 
1882         case WSAENETUNREACH:
1883 			rtl_uString_newFromAscii (strError, "WSAENETUNREACH, Network is unreachable");
1884             break;
1885 
1886         case WSAENETRESET:
1887 			rtl_uString_newFromAscii (strError, "WSAENETRESET, Network dropped connection or reset");
1888             break;
1889 
1890         case WSAECONNABORTED:
1891 			rtl_uString_newFromAscii (strError, "WSAECONNABORTED, Software caused connection abort");
1892             break;
1893 
1894         case WSAECONNRESET:
1895 			rtl_uString_newFromAscii (strError, "WSAECONNRESET, Connection reset by peer");
1896             break;
1897 
1898         case WSAENOBUFS:
1899 			rtl_uString_newFromAscii (strError, "WSAENOBUFS, No buffer space available.");
1900             break;
1901 
1902         case WSAEISCONN:
1903 			rtl_uString_newFromAscii (strError, "WSAEISCONN, Socket is already connected");
1904             break;
1905 
1906         case WSAENOTCONN:
1907 			rtl_uString_newFromAscii (strError, "WSAENOTCONN, Socket is not connected");
1908             break;
1909 
1910         case WSAESHUTDOWN:
1911 			rtl_uString_newFromAscii (strError, "WSAESHUTDOWN, Can't send after socket shutdown");
1912             break;
1913 
1914         case WSAETIMEDOUT:
1915 			rtl_uString_newFromAscii (strError, "WSAETIMEDOUT, Connection timed out");
1916             break;
1917 
1918         case WSAECONNREFUSED:
1919 			rtl_uString_newFromAscii (strError, "WSAECONNREFUSED, Connection refused");
1920             break;
1921 
1922         case WSAEHOSTDOWN:
1923 			rtl_uString_newFromAscii (strError, "WSAEHOSTDOWN, Networking subsystem not started");
1924             break;
1925 
1926         case WSAEHOSTUNREACH:
1927 			rtl_uString_newFromAscii (strError, "WSAEHOSTUNREACH, No route to host");
1928             break;
1929 
1930         case WSAEWOULDBLOCK:
1931 			rtl_uString_newFromAscii (strError, "WSAEWOULDBLOCK, Operation would block");
1932             break;
1933 
1934         case WSAEINPROGRESS:
1935 			rtl_uString_newFromAscii (strError, "WSAEINPROGRESS, Operation now in progress");
1936             break;
1937 
1938         case WSAEALREADY:
1939 			rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation already in progress");
1940             break;
1941 
1942         case WSAEINTR:
1943 			rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation was interrupted");
1944             break;
1945 
1946         case WSAEBADF:
1947 			rtl_uString_newFromAscii (strError, "WSAEBADF, Bad file number");
1948             break;
1949 
1950         case WSAEACCES:
1951 			rtl_uString_newFromAscii (strError, "WSAEACCES, Access is denied");
1952             break;
1953 
1954         case WSAEFAULT:
1955 			rtl_uString_newFromAscii (strError, "WSAEFAULT, Bad memory Addr");
1956             break;
1957 
1958         case WSAEINVAL:
1959 			rtl_uString_newFromAscii (strError, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1960             break;
1961 
1962         case WSAEMFILE:
1963 			rtl_uString_newFromAscii (strError, "WSAEMFILE, No more file descriptors are available");
1964             break;
1965 
1966         case WSAETOOMANYREFS:
1967 			rtl_uString_newFromAscii (strError, "WSAETOOMANYREFS, Undocumented WinSock error");
1968             break;
1969 
1970         case WSAENAMETOOLONG:
1971 			rtl_uString_newFromAscii (strError, "WSAENAMETOOLONG, Undocumented WinSock error");
1972             break;
1973 
1974         case WSAENOTEMPTY:
1975 			rtl_uString_newFromAscii (strError, "WSAENOTEMPTY, Undocumented WinSock error");
1976             break;
1977 
1978         case WSAEPROCLIM:
1979 			rtl_uString_newFromAscii (strError, "WSAEPROCLIM, Undocumented WinSock error");
1980             break;
1981 
1982         case WSAEUSERS:
1983 			rtl_uString_newFromAscii (strError, "WSAEUSERS, Undocumented WinSock error");
1984             break;
1985 
1986         case WSAEDQUOT:
1987 			rtl_uString_newFromAscii (strError, "WSAEDQUOT, Undocumented WinSock error");
1988             break;
1989 
1990         case WSAESTALE:
1991 			rtl_uString_newFromAscii (strError, "WSAESTALE, Undocumented WinSock error");
1992             break;
1993 
1994         case WSAEREMOTE:
1995 			rtl_uString_newFromAscii (strError, "WSAEREMOTE, Undocumented WinSock error");
1996             break;
1997 
1998         case WSAEDISCON:
1999 			rtl_uString_newFromAscii (strError, "WSAEDISCON, Circuit was gracefully terminated");
2000             break;
2001 
2002         case WSASYSNOTREADY:
2003 			rtl_uString_newFromAscii (strError, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
2004             break;
2005 
2006         case WSAVERNOTSUPPORTED:
2007 			rtl_uString_newFromAscii (strError, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
2008             break;
2009 
2010         case WSANOTINITIALISED:
2011 			rtl_uString_newFromAscii (strError, "WSANOTINITIALISED, WSAStartup() has not been called");
2012             break;
2013 
2014         case WSAHOST_NOT_FOUND:
2015 			rtl_uString_newFromAscii (strError, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
2016             break;
2017 
2018         case WSATRY_AGAIN:
2019 			rtl_uString_newFromAscii (strError, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
2020             break;
2021 
2022         case WSANO_RECOVERY:
2023 			rtl_uString_newFromAscii (strError, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
2024             break;
2025 
2026         case WSANO_DATA:
2027 			rtl_uString_newFromAscii (strError, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
2028             break;
2029 
2030 		default:
2031 		{
2032 			sal_Unicode message[128];
2033 
2034             wsprintfW(reinterpret_cast<LPWSTR>(message), L"Unknown WinSock Error Number %d", error);
2035 			rtl_uString_newFromStr (strError, message);
2036         }
2037 
2038         return;
2039 
2040 	}
2041 }
2042 
2043 /*****************************************************************************/
2044 /* osl_getLastSocketError  */
2045 /*****************************************************************************/
osl_getLastSocketError(oslSocket)2046 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket /*Socket*/)
2047 {
2048 	return ERROR_FROM_NATIVE(WSAGetLastError());
2049 }
2050 
2051 /*****************************************************************************/
2052 /* SocketSet                                                                 */
2053 /*****************************************************************************/
2054 typedef struct _TSocketSetImpl
2055 {
2056 	fd_set	m_Set;			/* the set of descriptors */
2057 
2058 } TSocketSetImpl;
2059 
2060 /*****************************************************************************/
2061 /* osl_createSocketSet  */
2062 /*****************************************************************************/
osl_createSocketSet()2063 oslSocketSet SAL_CALL osl_createSocketSet()
2064 {
2065 	TSocketSetImpl* pSet;
2066 
2067 	pSet = (TSocketSetImpl*) rtl_allocateMemory(sizeof(TSocketSetImpl));
2068 
2069 	if(pSet)
2070 	{
2071 		FD_ZERO(&pSet->m_Set);
2072 	}
2073 
2074 	return (oslSocketSet)pSet;
2075 }
2076 
2077 /*****************************************************************************/
2078 /* osl_destroySocketSet  */
2079 /*****************************************************************************/
osl_destroySocketSet(oslSocketSet Set)2080 void SAL_CALL osl_destroySocketSet (oslSocketSet Set)
2081 {
2082 	if(Set)
2083 		rtl_freeMemory(Set);
2084 }
2085 
2086 /*****************************************************************************/
2087 /* osl_clearSocketSet  */
2088 /*****************************************************************************/
osl_clearSocketSet(oslSocketSet Set)2089 void SAL_CALL osl_clearSocketSet (oslSocketSet Set)
2090 {
2091 	TSocketSetImpl* pSet;
2092 
2093 	pSet= (TSocketSetImpl*)Set;
2094 
2095 	if (pSet)
2096 		FD_ZERO(&pSet->m_Set);
2097 }
2098 
2099 /*****************************************************************************/
2100 /* osl_addToSocketSet  */
2101 /*****************************************************************************/
osl_addToSocketSet(oslSocketSet Set,oslSocket Socket)2102 void SAL_CALL osl_addToSocketSet (
2103 	oslSocketSet Set,
2104 	oslSocket    Socket)
2105 {
2106 	TSocketSetImpl* pSet;
2107 	oslSocketImpl*  pSockImpl;
2108 
2109 	pSet= (TSocketSetImpl*)Set;
2110 	pSockImpl= (oslSocketImpl*)Socket;
2111 
2112 	if (pSet && pSockImpl)
2113 		FD_SET(pSockImpl->m_Socket, &pSet->m_Set);
2114 }
2115 
2116 /*****************************************************************************/
2117 /* osl_removeFromSocketSet  */
2118 /*****************************************************************************/
osl_removeFromSocketSet(oslSocketSet Set,oslSocket Socket)2119 void SAL_CALL osl_removeFromSocketSet (
2120 	oslSocketSet Set,
2121 	oslSocket    Socket)
2122 {
2123 	TSocketSetImpl* pSet;
2124 	oslSocketImpl*  pSockImpl;
2125 
2126 	pSet= (TSocketSetImpl*)Set;
2127 	pSockImpl= (oslSocketImpl*)Socket;
2128 
2129 	if (pSet && pSockImpl)
2130 		FD_CLR(pSockImpl->m_Socket, &pSet->m_Set);
2131 }
2132 
2133 /*****************************************************************************/
2134 /* osl_isInSocketSet  */
2135 /*****************************************************************************/
osl_isInSocketSet(oslSocketSet Set,oslSocket Socket)2136 sal_Bool SAL_CALL osl_isInSocketSet (
2137 	oslSocketSet Set,
2138 	oslSocket    Socket)
2139 {
2140 	TSocketSetImpl* pSet;
2141 	oslSocketImpl*  pSockImpl;
2142 
2143 	pSet= (TSocketSetImpl*)Set;
2144 	pSockImpl= (oslSocketImpl*)Socket;
2145 
2146 	if (pSet && pSockImpl)
2147 		return (FD_ISSET(pSockImpl->m_Socket, &pSet->m_Set) != 0);
2148 	else
2149 		return sal_False;
2150 }
2151 
2152 /*****************************************************************************/
2153 /* osl_demultiplexSocketEvents  */
2154 /*****************************************************************************/
osl_demultiplexSocketEvents(oslSocketSet IncomingSet,oslSocketSet OutgoingSet,oslSocketSet OutOfBandSet,const TimeValue * pTimeout)2155 sal_Int32 SAL_CALL osl_demultiplexSocketEvents (
2156 	oslSocketSet IncomingSet,
2157 	oslSocketSet OutgoingSet,
2158 	oslSocketSet OutOfBandSet,
2159 	const TimeValue* pTimeout)
2160 {
2161 	int             MaxHandle= 0;
2162 	struct timeval  tv;
2163 	TSocketSetImpl* pInSet;
2164 	TSocketSetImpl* pOutSet;
2165 	TSocketSetImpl* pOOBSet;
2166 
2167 	if(pTimeout)
2168 	{
2169 		/* divide milliseconds into seconds and microseconds */
2170 		tv.tv_sec  = pTimeout->Seconds;
2171 		tv.tv_usec = pTimeout->Nanosec / 1000L;
2172 	}
2173 
2174 	/* map opaque data to impl-types */
2175 	pInSet= (TSocketSetImpl*)IncomingSet;
2176 	pOutSet= (TSocketSetImpl*)OutgoingSet;
2177 	pOOBSet= (TSocketSetImpl*)OutOfBandSet;
2178 
2179 	return select(MaxHandle,				/* redundant in WIN32 */
2180 				  pInSet ? &pInSet->m_Set : 0,
2181 				  pOutSet ? &pOutSet->m_Set : 0,
2182 				  pOOBSet ? &pOOBSet->m_Set : 0,
2183 				  pTimeout ? &tv : 0);
2184 }
2185 
2186 }
2187