1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <sal/config.h>
21
22 #include <utility>
23
24 #include "system.h"
25
26 #include <osl/socket.h>
27 #include <osl/thread.h>
28 #include <osl/diagnose.h>
29 #include <rtl/alloc.h>
30 #include <rtl/byteseq.h>
31 #include <sal/log.hxx>
32 #include <o3tl/char16_t2wchar_t.hxx>
33 #include <comphelper/windowserrorstring.hxx>
34
35 #include "sockimpl.hxx"
36
37 /*
38 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
39 I refrained from using sockaddr_in because of possible further
40 extensions of this socket-interface (IP-NG?).
41 The intention was to hide all Berkeley data-structures from
42 direct access past the osl-interface.
43
44 The current implementation is internet (IP) centered. All
45 the constructor-functions (osl_create...) take parameters
46 that will probably make sense only in the IP-environment
47 (e.g. because of using the dotted-Addr-format).
48
49 If the interface will be extended to host other protocol-
50 families, I expect no externally visible changes in the
51 existing functions. You'll probably need only new
52 constructor-functions who take the different Addr
53 formats into consideration (maybe a long dotted Addr
54 or whatever).
55 */
56
57 /*
58 _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
59 are the same! I don't like it very much but see no other easy way to
60 conceal the struct sockaddr from the eyes of the user.
61 */
62
63 #define OSL_INVALID_SOCKET INVALID_SOCKET /* WIN32 */
64 #define OSL_SOCKET_ERROR SOCKET_ERROR /* WIN32 */
65
66 static DWORD FamilyMap[]= {
67 AF_INET, /* osl_Socket_FamilyInet */
68 AF_IPX, /* osl_Socket_FamilyIpx */
69 0 /* osl_Socket_FamilyInvalid */
70 };
71
osl_AddrFamilyFromNative(DWORD nativeType)72 static oslAddrFamily osl_AddrFamilyFromNative(DWORD nativeType)
73 {
74 oslAddrFamily i= oslAddrFamily(0);
75 while(i != osl_Socket_FamilyInvalid)
76 {
77 if(FamilyMap[i] == nativeType)
78 return i;
79 i = static_cast<oslAddrFamily>( static_cast<int>(i) + 1);
80 }
81 return i;
82 }
83
84 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
85 #define FAMILY_TO_NATIVE(x) static_cast<short>(FamilyMap[x])
86
87 static DWORD ProtocolMap[]= {
88 0, /* osl_Socket_FamilyInet */
89 NSPROTO_IPX, /* osl_Socket_FamilyIpx */
90 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
91 NSPROTO_SPXII, /* osl_Socket_ProtocolSpx_ii */
92 0 /* osl_Socket_ProtocolInvalid */
93 };
94
95 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
96
97 static DWORD TypeMap[]= {
98 SOCK_STREAM, /* osl_Socket_TypeStream */
99 SOCK_DGRAM, /* osl_Socket_TypeDgram */
100 SOCK_RAW, /* osl_Socket_TypeRaw */
101 SOCK_RDM, /* osl_Socket_TypeRdm */
102 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
103 0 /* osl_Socket_TypeInvalid */
104 };
105
osl_SocketTypeFromNative(DWORD nativeType)106 static oslSocketType osl_SocketTypeFromNative(DWORD nativeType)
107 {
108 oslSocketType i= oslSocketType(0);
109 while(i != osl_Socket_TypeInvalid)
110 {
111 if(TypeMap[i] == nativeType)
112 return i;
113 i = static_cast<oslSocketType>(static_cast<int>(i)+1);
114 }
115 return i;
116 }
117
118 #define TYPE_TO_NATIVE(x) TypeMap[x]
119 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
120
121 static DWORD OptionMap[]= {
122 SO_DEBUG, /* osl_Socket_OptionDebug */
123 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
124 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
125 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
126 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
127 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
128 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
129 SO_LINGER, /* osl_Socket_OptionLinger */
130 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
131 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
132 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
133 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
134 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
135 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
136 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
137 SO_ERROR, /* osl_Socket_OptionError */
138 SO_TYPE, /* osl_Socket_OptionType */
139 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
140 0 /* osl_Socket_OptionInvalid */
141 };
142
143 #define OPTION_TO_NATIVE(x) OptionMap[x]
144
145 static DWORD OptionLevelMap[]= {
146 SOL_SOCKET, /* osl_Socket_LevelSocket */
147 IPPROTO_TCP, /* osl_Socket_LevelTcp */
148 0 /* osl_invalid_SocketLevel */
149 };
150
151 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
152
153 static DWORD SocketMsgFlagMap[]= {
154 0, /* osl_Socket_MsgNormal */
155 MSG_OOB, /* osl_Socket_MsgOOB */
156 MSG_PEEK, /* osl_Socket_MsgPeek */
157 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
158 MSG_MAXIOVLEN /* osl_Socket_MsgMaxIOVLen */
159 };
160
161 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
162
163 static DWORD SocketDirection[]= {
164 SD_RECEIVE, /* osl_Socket_DirRead */
165 SD_SEND, /* osl_Socket_DirWrite */
166 SD_BOTH /* osl_Socket_DirReadwrite */
167 };
168
169 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
170
171 static int SocketError[]= {
172 0, /* no error */
173 WSAENOTSOCK, /* Socket operation on non-socket */
174 WSAEDESTADDRREQ, /* Destination address required */
175 WSAEMSGSIZE, /* Message too long */
176 WSAEPROTOTYPE, /* Protocol wrong type for socket */
177 WSAENOPROTOOPT, /* Protocol not available */
178 WSAEPROTONOSUPPORT, /* Protocol not supported */
179 WSAESOCKTNOSUPPORT, /* Socket type not supported */
180 WSAEOPNOTSUPP, /* Operation not supported on socket */
181 WSAEPFNOSUPPORT, /* Protocol family not supported */
182 WSAEAFNOSUPPORT, /* Address family not supported by protocol family */
183 WSAEADDRINUSE, /* Address already in use */
184 WSAEADDRNOTAVAIL, /* Can't assign requested address */
185 WSAENETDOWN, /* Network is down */
186 WSAENETUNREACH, /* Network is unreachable */
187 WSAENETRESET, /* Network dropped connection because of reset */
188 WSAECONNABORTED, /* Software caused connection abort */
189 WSAECONNRESET, /* Connection reset by peer */
190 WSAENOBUFS, /* No buffer space available */
191 WSAEISCONN, /* Socket is already connected */
192 WSAENOTCONN, /* Socket is not connected */
193 WSAESHUTDOWN, /* Can't send after socket shutdown */
194 WSAETOOMANYREFS, /* Too many references: can't splice */
195 WSAETIMEDOUT, /* Connection timed out */
196 WSAECONNREFUSED, /* Connection refused */
197 WSAEHOSTDOWN, /* Host is down */
198 WSAEHOSTUNREACH, /* No route to host */
199 WSAEWOULDBLOCK, /* call would block on non-blocking socket */
200 WSAEALREADY, /* operation already in progress */
201 WSAEINPROGRESS /* operation now in progress */
202 };
203
osl_SocketErrorFromNative(int nativeType)204 static oslSocketError osl_SocketErrorFromNative(int nativeType)
205 {
206 oslSocketError i= oslSocketError(0);
207
208 while(i != osl_Socket_E_InvalidError)
209 {
210 if(SocketError[i] == nativeType)
211 return i;
212
213 i = static_cast<oslSocketError>( static_cast<int>(i) + 1);
214 }
215 return i;
216 }
217
218 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
219
220 #if OSL_DEBUG_LEVEL > 0
221 static sal_uInt32 g_nSocketAddr = 0;
222 struct LeakWarning
223 {
~LeakWarningLeakWarning224 ~LeakWarning()
225 {
226 SAL_WARN_IF( g_nSocketAddr, "sal.osl", "sal_socket: " << g_nSocketAddr << " socket address instances leak" );
227 }
228 };
229 static LeakWarning socketWarning;
230 #endif
231
createSocketImpl(SOCKET Socket)232 static oslSocket createSocketImpl(SOCKET Socket)
233 {
234 oslSocket pSockImpl = static_cast<oslSocket>(rtl_allocateZeroMemory( sizeof(struct oslSocketImpl)));
235 pSockImpl->m_Socket = Socket;
236 pSockImpl->m_nRefCount = 1;
237 return pSockImpl;
238 }
239
destroySocketImpl(oslSocketImpl * pImpl)240 static void destroySocketImpl(oslSocketImpl *pImpl)
241 {
242 if (pImpl)
243 {
244 free (pImpl);
245 }
246 }
247
createSocketAddr()248 static oslSocketAddr createSocketAddr( )
249 {
250 oslSocketAddr pAddr = static_cast<oslSocketAddr>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl )));
251 pAddr->m_nRefCount = 1;
252 #if OSL_DEBUG_LEVEL > 0
253 g_nSocketAddr ++;
254 #endif
255 return pAddr;
256 }
257
createSocketAddrWithFamily(oslAddrFamily family,sal_Int32 port,sal_uInt32 nAddr)258 static oslSocketAddr createSocketAddrWithFamily(
259 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
260 {
261 OSL_ASSERT( family == osl_Socket_FamilyInet );
262
263 oslSocketAddr pAddr = createSocketAddr();
264 switch( family )
265 {
266 case osl_Socket_FamilyInet:
267 {
268 struct sockaddr_in* pInetAddr= reinterpret_cast<struct sockaddr_in*>(&pAddr->m_sockaddr);
269
270 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
271 pInetAddr->sin_addr.s_addr = nAddr;
272 pInetAddr->sin_port = static_cast<sal_uInt16>(port&0xffff);
273 break;
274 }
275 default:
276 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
277 }
278 return pAddr;
279 }
280
createSocketAddFromSystem(struct sockaddr * pSystemSockAddr)281 static oslSocketAddr createSocketAddFromSystem( struct sockaddr *pSystemSockAddr )
282 {
283 oslSocketAddr pAddr = createSocketAddr();
284 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( sockaddr ) );
285 return pAddr;
286 }
287
destroySocketAddr(oslSocketAddr addr)288 static void destroySocketAddr( oslSocketAddr addr )
289 {
290 #if OSL_DEBUG_LEVEL > 0
291 g_nSocketAddr --;
292 #endif
293 free( addr );
294 }
295
osl_createEmptySocketAddr(oslAddrFamily Family)296 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
297 {
298 oslSocketAddr pAddr = nullptr;
299
300 /* is it an internet-Addr? */
301 if (Family == osl_Socket_FamilyInet)
302 pAddr = createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
303 else
304 pAddr = createSocketAddrWithFamily( Family , 0 , 0 );
305
306 return pAddr;
307 }
308
309 /** @deprecated, to be removed */
osl_copySocketAddr(oslSocketAddr Addr)310 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
311 {
312 oslSocketAddr pCopy = nullptr;
313 if (Addr)
314 {
315 pCopy = createSocketAddr();
316
317 if (pCopy)
318 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
319 }
320 return pCopy;
321 }
322
osl_isEqualSocketAddr(oslSocketAddr Addr1,oslSocketAddr Addr2)323 sal_Bool SAL_CALL osl_isEqualSocketAddr(oslSocketAddr Addr1, oslSocketAddr Addr2)
324 {
325 OSL_ASSERT(Addr1);
326 OSL_ASSERT(Addr2);
327 struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
328 struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
329
330 OSL_ASSERT(pAddr1);
331 OSL_ASSERT(pAddr2);
332
333 if (pAddr1->sa_family == pAddr2->sa_family)
334 {
335 switch (pAddr1->sa_family)
336 {
337 case AF_INET:
338 {
339 struct sockaddr_in* pInetAddr1= reinterpret_cast<struct sockaddr_in*>(pAddr1);
340 struct sockaddr_in* pInetAddr2= reinterpret_cast<struct sockaddr_in*>(pAddr2);
341
342 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
343 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
344 (pInetAddr1->sin_port == pInetAddr2->sin_port))
345 return true;
346 [[fallthrough]];
347 }
348
349 default:
350 {
351 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
352 }
353 }
354 }
355
356 return false;
357 }
358
osl_createInetBroadcastAddr(rtl_uString * strDottedAddr,sal_Int32 Port)359 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
360 rtl_uString *strDottedAddr,
361 sal_Int32 Port)
362 {
363 sal_uInt32 nAddr = OSL_INADDR_NONE;
364
365 if (strDottedAddr && strDottedAddr->length)
366 {
367 IN_ADDR addr;
368 INT ret = InetPtonW(AF_INET, o3tl::toW(strDottedAddr->buffer), & addr);
369 if (1 == ret)
370 {
371 nAddr = addr.S_un.S_addr;
372 }
373 }
374
375 if (nAddr != OSL_INADDR_NONE)
376 {
377 /* Limited broadcast */
378 nAddr = ntohl(nAddr);
379 if (IN_CLASSA(nAddr))
380 {
381 nAddr &= IN_CLASSA_NET;
382 nAddr |= IN_CLASSA_HOST;
383 }
384 else if (IN_CLASSB(nAddr))
385 {
386 nAddr &= IN_CLASSB_NET;
387 nAddr |= IN_CLASSB_HOST;
388 }
389 else if (IN_CLASSC(nAddr))
390 {
391 nAddr &= IN_CLASSC_NET;
392 nAddr |= IN_CLASSC_HOST;
393 }
394 else
395 {
396 /* No broadcast in class D */
397 return nullptr;
398 }
399 nAddr = htonl(nAddr);
400 }
401
402 oslSocketAddr pAddr =
403 createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( static_cast<sal_uInt16>(Port)), nAddr );
404 return pAddr;
405 }
406
osl_createInetSocketAddr(rtl_uString * strDottedAddr,sal_Int32 Port)407 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
408 rtl_uString *strDottedAddr,
409 sal_Int32 Port)
410 {
411 sal_uInt32 Addr;
412
413 IN_ADDR addr;
414 INT ret = InetPtonW(AF_INET, o3tl::toW(strDottedAddr->buffer), & addr);
415 Addr = ret == 1 ? addr.S_un.S_addr : OSL_INADDR_NONE;
416
417 oslSocketAddr pAddr = nullptr;
418 if(Addr != OSL_INADDR_NONE)
419 {
420 pAddr = createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( static_cast<sal_uInt16>(Port)), Addr );
421 }
422 return pAddr;
423 }
424
osl_setAddrOfSocketAddr(oslSocketAddr pAddr,sal_Sequence * pByteSeq)425 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
426 {
427 OSL_ASSERT( pAddr );
428 OSL_ASSERT( pByteSeq );
429
430 oslSocketResult res = osl_Socket_Error;
431 if( pAddr && pByteSeq )
432 {
433 OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
434 OSL_ASSERT( pByteSeq->nElements == 4 );
435 struct sockaddr_in * pSystemInetAddr = reinterpret_cast<struct sockaddr_in *>(&pAddr->m_sockaddr);
436 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
437 res = osl_Socket_Ok;
438 }
439 return res;
440 }
441
442 /** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
443 either be 0 or contain a constructed sal_Sequence.
444 */
osl_getAddrOfSocketAddr(oslSocketAddr pAddr,sal_Sequence ** ppByteSeq)445 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
446 {
447 OSL_ASSERT( pAddr );
448 OSL_ASSERT( ppByteSeq );
449
450 oslSocketResult res = osl_Socket_Error;
451 if( pAddr && ppByteSeq )
452 {
453 struct sockaddr_in * pSystemInetAddr = reinterpret_cast<struct sockaddr_in *>(&pAddr->m_sockaddr);
454 rtl_byte_sequence_constructFromArray( ppByteSeq , reinterpret_cast<sal_Int8 *>(&pSystemInetAddr->sin_addr),4);
455 res = osl_Socket_Ok;
456 }
457 return res;
458 }
459
460 struct oslHostAddrImpl {
461 rtl_uString *pHostName;
462 oslSocketAddr pSockAddr;
463 } ;
464
osl_createHostAddr(rtl_uString * strHostname,const oslSocketAddr pSocketAddr)465 oslHostAddr SAL_CALL osl_createHostAddr (
466 rtl_uString *strHostname,
467 const oslSocketAddr pSocketAddr)
468 {
469 oslHostAddr pAddr;
470 rtl_uString *cn= nullptr;
471
472 if ((strHostname == nullptr) || (strHostname->length == 0) || (pSocketAddr == nullptr))
473 return nullptr;
474
475 rtl_uString_newFromString( &cn, strHostname);
476
477 pAddr= static_cast<oslHostAddr>(malloc (sizeof (struct oslHostAddrImpl)));
478
479 if (pAddr == nullptr)
480 {
481 rtl_uString_release(cn);
482 return nullptr;
483 }
484
485 pAddr->pHostName= cn;
486 pAddr->pSockAddr= osl_copySocketAddr( pSocketAddr );
487
488 return pAddr;
489 }
490
osl_createHostAddrByName(rtl_uString * strHostname)491 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname)
492 {
493 if ((strHostname == nullptr) || (strHostname->length == 0))
494 return nullptr;
495
496 PADDRINFOW pAddrInfo = nullptr;
497 int ret = GetAddrInfoW(
498 o3tl::toW(strHostname->buffer), nullptr, nullptr, & pAddrInfo);
499 if (0 == ret)
500 {
501 oslHostAddr pRet = nullptr;
502 for (PADDRINFOW pIter = pAddrInfo; pIter; pIter = pIter->ai_next)
503 {
504 if (AF_INET == pIter->ai_family)
505 {
506 pRet = static_cast<oslHostAddr>(
507 rtl_allocateZeroMemory(sizeof(struct oslHostAddrImpl)));
508 rtl_uString_newFromStr(&pRet->pHostName, o3tl::toU(pIter->ai_canonname));
509 pRet->pSockAddr = createSocketAddr();
510 memcpy(& pRet->pSockAddr->m_sockaddr,
511 pIter->ai_addr, pIter->ai_addrlen);
512 break; // ignore other results
513 }
514 }
515 FreeAddrInfoW(pAddrInfo);
516 return pRet;
517 }
518 else
519 {
520 SAL_INFO("sal.osl", "GetAddrInfoW failed: " << WSAGetLastError());
521 }
522 return nullptr;
523 }
524
osl_createHostAddrByAddr(const oslSocketAddr pAddr)525 oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr pAddr)
526 {
527 if (pAddr == nullptr)
528 return nullptr;
529
530 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
531 {
532 const struct sockaddr_in *sin= reinterpret_cast<const struct sockaddr_in *>(&pAddr->m_sockaddr);
533
534 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
535 return nullptr;
536
537 WCHAR buf[NI_MAXHOST];
538 int ret = GetNameInfoW(
539 & pAddr->m_sockaddr, sizeof(struct sockaddr),
540 buf, NI_MAXHOST,
541 nullptr, 0, 0);
542 if (0 == ret)
543 {
544 oslHostAddr pRet = static_cast<oslHostAddr>(
545 rtl_allocateZeroMemory(sizeof(struct oslHostAddrImpl)));
546 rtl_uString_newFromStr(&pRet->pHostName, o3tl::toU(buf));
547 pRet->pSockAddr = createSocketAddr();
548 memcpy(& pRet->pSockAddr->m_sockaddr,
549 & pAddr->m_sockaddr, sizeof(struct sockaddr));
550 return pRet;
551 }
552 else
553 {
554 SAL_INFO("sal.osl", "GetNameInfoW failed: " << WSAGetLastError());
555 }
556 }
557
558 return nullptr;
559 }
560
osl_copyHostAddr(const oslHostAddr Addr)561 oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr)
562 {
563 oslHostAddr pAddr = Addr;
564
565 if (pAddr)
566 return osl_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
567 else
568 return nullptr;
569 }
570
osl_getHostnameOfHostAddr(const oslHostAddr pAddr,rtl_uString ** strHostname)571 void SAL_CALL osl_getHostnameOfHostAddr(
572 const oslHostAddr pAddr, rtl_uString **strHostname)
573 {
574 if (pAddr)
575 rtl_uString_assign (strHostname, pAddr->pHostName);
576 else
577 rtl_uString_new (strHostname);
578 }
579
osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)580 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)
581 {
582 if (pAddr)
583 return pAddr->pSockAddr;
584 else
585 return nullptr;
586 }
587
osl_destroyHostAddr(oslHostAddr pAddr)588 void SAL_CALL osl_destroyHostAddr(oslHostAddr pAddr)
589 {
590 if (pAddr)
591 {
592 if (pAddr->pHostName)
593 rtl_uString_release (pAddr->pHostName);
594 if (pAddr->pSockAddr)
595 osl_destroySocketAddr( pAddr->pSockAddr );
596
597 free (pAddr);
598 }
599 }
600
osl_getLocalHostname(rtl_uString ** strLocalHostname)601 oslSocketResult SAL_CALL osl_getLocalHostname (rtl_uString **strLocalHostname)
602 {
603 static auto const init = []() -> std::pair<oslSocketResult, OUString> {
604 sal_Unicode LocalHostname[256] = {0};
605
606 sal_Char Host[256]= "";
607 if (gethostname(Host, sizeof(Host)) == 0)
608 {
609 /* check if we have an FQDN; if not, try to determine it via dns first: */
610 if (strchr(Host, '.') == nullptr)
611 {
612 oslHostAddr pAddr;
613 rtl_uString *hostName= nullptr;
614
615 rtl_string2UString(
616 &hostName, Host, strlen(Host),
617 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
618 OSL_ASSERT(hostName != nullptr);
619
620 pAddr = osl_createHostAddrByName(hostName);
621 rtl_uString_release (hostName);
622
623 if (pAddr && pAddr->pHostName)
624 memcpy(LocalHostname, pAddr->pHostName->buffer, sizeof(sal_Unicode)*(rtl_ustr_getLength(pAddr->pHostName->buffer)+1));
625 else
626 memset(LocalHostname, 0, sizeof(LocalHostname));
627
628 osl_destroyHostAddr (pAddr);
629 }
630 if (LocalHostname[0] == u'\0')
631 {
632 OUString u;
633 if (rtl_convertStringToUString(
634 &u.pData, Host, strlen(Host), osl_getThreadTextEncoding(),
635 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
636 | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
637 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
638 && sal_uInt32(u.getLength()) < SAL_N_ELEMENTS(LocalHostname))
639 {
640 memcpy(LocalHostname, u.getStr(), (u.getLength() + 1) * sizeof (sal_Unicode));
641 }
642 }
643 }
644
645 if (rtl_ustr_getLength(LocalHostname) > 0)
646 {
647 return {osl_Socket_Ok, LocalHostname};
648 }
649
650 return {osl_Socket_Error, OUString()};
651 }();
652
653 rtl_uString_assign (strLocalHostname, init.second.pData);
654
655 return init.first;
656 }
657
osl_resolveHostname(rtl_uString * strHostname)658 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString* strHostname)
659 {
660 oslHostAddr pAddr = osl_createHostAddrByName (strHostname);
661 if (pAddr)
662 {
663 oslSocketAddr SockAddr = osl_copySocketAddr( pAddr->pSockAddr );
664 osl_destroyHostAddr(pAddr);
665 return SockAddr;
666 }
667 return nullptr;
668 }
669
osl_getServicePort(rtl_uString * strServicename,rtl_uString * strProtocol)670 sal_Int32 SAL_CALL osl_getServicePort (
671 rtl_uString* strServicename,
672 rtl_uString* strProtocol)
673 {
674 struct servent* ps;
675
676 rtl_String *str_Servicename=nullptr;
677 rtl_String *str_Protocol=nullptr;
678
679 rtl_uString2String(
680 &str_Servicename,
681 rtl_uString_getStr(strServicename),
682 rtl_uString_getLength(strServicename),
683 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
684 rtl_uString2String(
685 &str_Protocol,
686 rtl_uString_getStr(strProtocol),
687 rtl_uString_getLength(strProtocol),
688 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
689
690 ps= getservbyname(
691 rtl_string_getStr(str_Servicename),
692 rtl_string_getStr(str_Protocol));
693
694 rtl_string_release( str_Servicename );
695 rtl_string_release( str_Protocol );
696
697 if (ps != nullptr)
698 return ntohs(ps->s_port);
699
700 return OSL_INVALID_PORT;
701 }
702
osl_destroySocketAddr(oslSocketAddr pAddr)703 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
704 {
705 destroySocketAddr( pAddr );
706 }
707
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)708 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
709 {
710 if (pAddr)
711 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
712 else
713 return osl_Socket_FamilyInvalid;
714 }
715
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)716 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
717 {
718 if( pAddr )
719 {
720 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<struct sockaddr_in*>(&pAddr->m_sockaddr);
721
722 if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
723 return ntohs(pSystemInetAddr->sin_port);
724 }
725 return OSL_INVALID_PORT;
726 }
727
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr,sal_Int32 Port)728 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr (
729 oslSocketAddr pAddr,
730 sal_Int32 Port)
731 {
732 if (pAddr == nullptr)
733 return false;
734
735 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<struct sockaddr_in*>(&pAddr->m_sockaddr);
736
737 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
738 return false;
739
740 pSystemInetAddr->sin_port= htons(static_cast<short>(Port));
741 return true;
742 }
743
osl_getHostnameOfSocketAddr(oslSocketAddr Addr,rtl_uString ** strHostName)744 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr (
745 oslSocketAddr Addr,
746 rtl_uString **strHostName)
747 {
748 oslHostAddr pAddr= osl_createHostAddrByAddr (Addr);
749
750 if (pAddr)
751 {
752 rtl_uString_newFromString(strHostName, pAddr->pHostName);
753
754 osl_destroyHostAddr(pAddr);
755
756 return osl_Socket_Ok;
757 }
758
759 return osl_Socket_Error;
760 }
761
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,rtl_uString ** strDottedInetAddr)762 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr (
763 oslSocketAddr pAddr,
764 rtl_uString **strDottedInetAddr)
765 {
766 if (pAddr == nullptr)
767 return osl_Socket_Error;
768
769 struct sockaddr_in *pSystemInetAddr = reinterpret_cast<struct sockaddr_in*>(&pAddr->m_sockaddr);
770 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
771 return osl_Socket_Error;
772
773 *strDottedInetAddr = nullptr;
774 WCHAR buf[16]; // 16 for IPV4, 46 for IPV6
775 PCWSTR ret = InetNtopW(
776 AF_INET, & pSystemInetAddr->sin_addr,
777 buf, SAL_N_ELEMENTS(buf));
778 if (nullptr == ret)
779 {
780 SAL_INFO("sal.osl", "InetNtopW failed: " << WSAGetLastError());
781 return osl_Socket_Error;
782 }
783 rtl_uString_newFromStr(strDottedInetAddr, o3tl::toU(ret));
784 OSL_ASSERT(*strDottedInetAddr != nullptr);
785
786 return osl_Socket_Ok;
787 }
788
osl_createSocket(oslAddrFamily Family,oslSocketType Type,oslProtocol Protocol)789 oslSocket SAL_CALL osl_createSocket(
790 oslAddrFamily Family,
791 oslSocketType Type,
792 oslProtocol Protocol)
793 {
794 /* alloc memory */
795 oslSocket pSocket = createSocketImpl(0);
796
797 if (pSocket == nullptr)
798 return nullptr;
799
800 /* create socket */
801 pSocket->m_Socket = socket(FAMILY_TO_NATIVE(Family),
802 TYPE_TO_NATIVE(Type),
803 PROTOCOL_TO_NATIVE(Protocol));
804
805 /* creation failed => free memory */
806 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
807 {
808 int nErrno = WSAGetLastError();
809 SAL_WARN("sal.osl", "socket creation failed: (" << nErrno << "): " << WindowsErrorString(nErrno));
810
811 destroySocketImpl(pSocket);
812 pSocket = nullptr;
813 }
814 else
815 {
816 pSocket->m_Flags = 0;
817 }
818
819 return pSocket;
820 }
821
osl_acquireSocket(oslSocket pSocket)822 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
823 {
824 osl_atomic_increment(&(pSocket->m_nRefCount));
825 }
826
osl_releaseSocket(oslSocket pSocket)827 void SAL_CALL osl_releaseSocket(oslSocket pSocket)
828 {
829 if (pSocket && osl_atomic_decrement(&(pSocket->m_nRefCount)) == 0)
830 {
831 osl_closeSocket(pSocket);
832 destroySocketImpl(pSocket);
833 }
834 }
835
osl_closeSocket(oslSocket pSocket)836 void SAL_CALL osl_closeSocket(oslSocket pSocket)
837 {
838 /* socket already invalid */
839 if (!pSocket)
840 return;
841
842 /* close */
843 closesocket(pSocket->m_Socket);
844
845 pSocket->m_Socket = OSL_INVALID_SOCKET;
846 }
847
848 /**
849 Note that I rely on the fact that oslSocketAddr and struct sockaddr
850 are the same! I don't like it very much but see no other easy way
851 to conceal the struct sockaddr from the eyes of the user.
852 */
osl_getLocalAddrOfSocket(oslSocket pSocket)853 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
854 {
855 struct sockaddr Addr;
856 int AddrLen;
857
858 if (pSocket == nullptr) /* ENOTSOCK */
859 return nullptr;
860
861 AddrLen= sizeof(struct sockaddr);
862
863 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
864 return nullptr;
865
866 oslSocketAddr pAddr = createSocketAddFromSystem( &Addr );
867 return pAddr;
868 }
869
osl_getPeerAddrOfSocket(oslSocket pSocket)870 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
871 {
872 struct sockaddr Addr;
873 int AddrLen;
874
875 if (pSocket == nullptr) /* ENOTSOCK */
876 return nullptr;
877
878 AddrLen= sizeof(struct sockaddr);
879
880 if (getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
881 return nullptr;
882
883 oslSocketAddr pAddr = createSocketAddFromSystem( &Addr );
884 return pAddr;
885 }
886
osl_bindAddrToSocket(oslSocket pSocket,oslSocketAddr pAddr)887 sal_Bool SAL_CALL osl_bindAddrToSocket ( oslSocket pSocket, oslSocketAddr pAddr)
888 {
889 OSL_ASSERT( pAddr );
890
891 if (pSocket == nullptr) /* ENOTSOCK */
892 return false;
893
894 return (bind(pSocket->m_Socket,
895 &(pAddr->m_sockaddr),
896 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR);
897 }
898
osl_connectSocketTo(oslSocket pSocket,oslSocketAddr pAddr,const TimeValue * pTimeout)899 oslSocketResult SAL_CALL osl_connectSocketTo (
900 oslSocket pSocket,
901 oslSocketAddr pAddr,
902 const TimeValue* pTimeout)
903 {
904
905 if (pSocket == nullptr) /* ENOTSOCK */
906 return osl_Socket_Error;
907
908 if (pAddr == nullptr) /* EDESTADDRREQ */
909 return osl_Socket_Error;
910
911 if (pTimeout == nullptr)
912 {
913 if(connect(pSocket->m_Socket,
914 &(pAddr->m_sockaddr),
915 sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
916 return osl_Socket_Error;
917 else
918 return osl_Socket_Ok;
919 }
920 else
921 {
922 fd_set fds;
923 int error;
924 struct timeval tv;
925 unsigned long Param;
926 oslSocketResult Result= osl_Socket_Ok;
927
928 if (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING)
929 {
930 if (connect(pSocket->m_Socket,
931 &(pAddr->m_sockaddr),
932 sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
933 {
934 switch (WSAGetLastError())
935 {
936 case WSAEWOULDBLOCK:
937 case WSAEINPROGRESS:
938 return osl_Socket_InProgress;
939
940 default:
941 return osl_Socket_Error;
942 }
943 }
944 else
945 return osl_Socket_Ok;
946 }
947
948 /* set socket temporarily to non-blocking */
949 Param= 1;
950 OSL_VERIFY(ioctlsocket(
951 pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
952
953 /* initiate connect */
954 if (connect(pSocket->m_Socket,
955 &(pAddr->m_sockaddr),
956 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
957 {
958 /* immediate connection */
959
960 Param= 0;
961 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
962
963 return osl_Socket_Ok;
964 }
965 else
966 {
967 error = WSAGetLastError();
968
969 /* really an error or just delayed? */
970 if (error != WSAEWOULDBLOCK && error != WSAEINPROGRESS)
971 {
972 Param= 0;
973 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
974
975 return osl_Socket_Error;
976 }
977 }
978
979 /* prepare select set for socket */
980 FD_ZERO(&fds);
981 FD_SET(pSocket->m_Socket, &fds);
982
983 /* divide milliseconds into seconds and microseconds */
984 tv.tv_sec= pTimeout->Seconds;
985 tv.tv_usec= pTimeout->Nanosec / 1000L;
986
987 /* select */
988 error= select(pSocket->m_Socket+1,
989 nullptr,
990 &fds,
991 nullptr,
992 &tv);
993
994 if (error > 0) /* connected */
995 {
996 SAL_WARN_IF(
997 !FD_ISSET(pSocket->m_Socket, &fds),
998 "sal.osl",
999 "osl_connectSocketTo(): select returned but socket not set");
1000
1001 Result= osl_Socket_Ok;
1002
1003 }
1004 else if(error < 0) /* error */
1005 {
1006 /* errno == EBADF: most probably interrupted by close() */
1007 if(WSAGetLastError() == WSAEBADF)
1008 {
1009 /* do not access pSockImpl because it is about to be or */
1010 /* already destroyed */
1011 return osl_Socket_Interrupted;
1012 }
1013 else
1014 Result= osl_Socket_Error;
1015
1016 }
1017 else /* timeout */
1018 Result= osl_Socket_TimedOut;
1019
1020 /* clean up */
1021 Param= 0;
1022 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1023
1024 return Result;
1025 }
1026 }
1027
osl_listenOnSocket(oslSocket pSocket,sal_Int32 MaxPendingConnections)1028 sal_Bool SAL_CALL osl_listenOnSocket (
1029 oslSocket pSocket,
1030 sal_Int32 MaxPendingConnections)
1031 {
1032 if (pSocket == nullptr) /* ENOTSOCK */
1033 return false;
1034
1035 return (listen(pSocket->m_Socket,
1036 MaxPendingConnections == -1 ?
1037 SOMAXCONN :
1038 MaxPendingConnections) != OSL_SOCKET_ERROR);
1039 }
1040
osl_acceptConnectionOnSocket(oslSocket pSocket,oslSocketAddr * ppAddr)1041 oslSocket SAL_CALL osl_acceptConnectionOnSocket (
1042 oslSocket pSocket,
1043 oslSocketAddr* ppAddr)
1044 {
1045 if (pSocket == nullptr) /* ENOTSOCK */
1046 return nullptr;
1047
1048 SOCKET Connection;
1049 if(ppAddr)
1050 {
1051 if( *ppAddr )
1052 {
1053 osl_destroySocketAddr( *ppAddr );
1054 *ppAddr = nullptr;
1055 }
1056 int AddrLen= sizeof(struct sockaddr);
1057
1058 /* user wants to know peer Addr */
1059 struct sockaddr Addr;
1060
1061 Connection= accept(pSocket->m_Socket, &Addr, &AddrLen);
1062 OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
1063
1064 if(Connection != static_cast<SOCKET>(OSL_SOCKET_ERROR))
1065 *ppAddr= createSocketAddFromSystem(&Addr);
1066 else
1067 *ppAddr = nullptr;
1068 }
1069 else
1070 {
1071 /* user is not interested in peer-addr */
1072 Connection= accept(pSocket->m_Socket, nullptr, nullptr);
1073 }
1074
1075 /* accept failed? */
1076 if(Connection == static_cast<SOCKET>(OSL_SOCKET_ERROR))
1077 return nullptr;
1078
1079 /* alloc memory */
1080 oslSocket pConnectionSocket;
1081 pConnectionSocket= createSocketImpl(Connection);
1082
1083 pConnectionSocket->m_Flags = 0;
1084
1085 return pConnectionSocket;
1086 }
1087
osl_receiveSocket(oslSocket pSocket,void * pBuffer,sal_uInt32 BytesToRead,oslSocketMsgFlag Flag)1088 sal_Int32 SAL_CALL osl_receiveSocket (
1089 oslSocket pSocket,
1090 void* pBuffer,
1091 sal_uInt32 BytesToRead,
1092 oslSocketMsgFlag Flag)
1093 {
1094 if (pSocket == nullptr) /* ENOTSOCK */
1095 return osl_Socket_Error;
1096
1097 return recv(pSocket->m_Socket,
1098 static_cast<sal_Char*>(pBuffer),
1099 BytesToRead,
1100 MSG_FLAG_TO_NATIVE(Flag));
1101 }
1102
osl_receiveFromSocket(oslSocket pSocket,oslSocketAddr SenderAddr,void * pBuffer,sal_uInt32 BufferSize,oslSocketMsgFlag Flag)1103 sal_Int32 SAL_CALL osl_receiveFromSocket (
1104 oslSocket pSocket,
1105 oslSocketAddr SenderAddr,
1106 void* pBuffer,
1107 sal_uInt32 BufferSize,
1108 oslSocketMsgFlag Flag)
1109 {
1110 struct sockaddr *pSystemSockAddr = nullptr;
1111 int AddrLen = 0;
1112 if( SenderAddr )
1113 {
1114 AddrLen = sizeof( struct sockaddr );
1115 pSystemSockAddr = &(SenderAddr->m_sockaddr);
1116 }
1117
1118 if (pSocket == nullptr) /* ENOTSOCK */
1119 return osl_Socket_Error;
1120
1121 return recvfrom(pSocket->m_Socket,
1122 static_cast<sal_Char*>(pBuffer),
1123 BufferSize,
1124 MSG_FLAG_TO_NATIVE(Flag),
1125 pSystemSockAddr,
1126 &AddrLen);
1127 }
1128
osl_sendSocket(oslSocket pSocket,const void * pBuffer,sal_uInt32 BytesToSend,oslSocketMsgFlag Flag)1129 sal_Int32 SAL_CALL osl_sendSocket (
1130 oslSocket pSocket,
1131 const void* pBuffer,
1132 sal_uInt32 BytesToSend,
1133 oslSocketMsgFlag Flag)
1134 {
1135 if (pSocket == nullptr) /* ENOTSOCK */
1136 return osl_Socket_Error;
1137
1138 return send(pSocket->m_Socket,
1139 static_cast<sal_Char const *>(pBuffer),
1140 BytesToSend,
1141 MSG_FLAG_TO_NATIVE(Flag));
1142 }
1143
osl_sendToSocket(oslSocket pSocket,oslSocketAddr ReceiverAddr,const void * pBuffer,sal_uInt32 BytesToSend,oslSocketMsgFlag Flag)1144 sal_Int32 SAL_CALL osl_sendToSocket (
1145 oslSocket pSocket,
1146 oslSocketAddr ReceiverAddr,
1147 const void* pBuffer,
1148 sal_uInt32 BytesToSend,
1149 oslSocketMsgFlag Flag)
1150 {
1151 if (pSocket == nullptr) /* ENOTSOCK */
1152 return osl_Socket_Error;
1153
1154 /* ReceiverAddr might be 0 when used on a connected socket. */
1155 /* Then sendto should behave like send. */
1156
1157 struct sockaddr *pSystemSockAddr = nullptr;
1158 if( ReceiverAddr )
1159 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1160
1161 return sendto(pSocket->m_Socket,
1162 static_cast<sal_Char const *>(pBuffer),
1163 BytesToSend,
1164 MSG_FLAG_TO_NATIVE(Flag),
1165 pSystemSockAddr,
1166 pSystemSockAddr == nullptr ? 0 : sizeof(struct sockaddr));
1167 }
1168
osl_readSocket(oslSocket pSocket,void * pBuffer,sal_Int32 n)1169 sal_Int32 SAL_CALL osl_readSocket( oslSocket pSocket, void *pBuffer, sal_Int32 n )
1170 {
1171 sal_uInt8 * Ptr = static_cast<sal_uInt8 *>(pBuffer);
1172
1173 OSL_ASSERT( pSocket);
1174
1175 /* loop until all desired bytes were read or an error occurred */
1176 sal_uInt32 BytesRead= 0;
1177 sal_uInt32 BytesToRead= n;
1178 while (BytesToRead > 0)
1179 {
1180 sal_Int32 RetVal;
1181 RetVal= osl_receiveSocket(pSocket,
1182 Ptr,
1183 BytesToRead,
1184 osl_Socket_MsgNormal);
1185
1186 /* error occurred? */
1187 if(RetVal <= 0)
1188 {
1189 break;
1190 }
1191
1192 BytesToRead -= RetVal;
1193 BytesRead += RetVal;
1194 Ptr += RetVal;
1195 }
1196
1197 return BytesRead;
1198 }
1199
osl_writeSocket(oslSocket pSocket,const void * pBuffer,sal_Int32 n)1200 sal_Int32 SAL_CALL osl_writeSocket( oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1201 {
1202 OSL_ASSERT( pSocket );
1203
1204 /* loop until all desired bytes were send or an error occurred */
1205 sal_uInt32 BytesSend= 0;
1206 sal_uInt32 BytesToSend= n;
1207 sal_uInt8 const *Ptr = static_cast<sal_uInt8 const *>(pBuffer);
1208 while (BytesToSend > 0)
1209 {
1210 sal_Int32 RetVal;
1211
1212 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1213
1214 /* error occurred? */
1215 if(RetVal <= 0)
1216 {
1217 break;
1218 }
1219
1220 BytesToSend -= RetVal;
1221 BytesSend += RetVal;
1222 Ptr += RetVal;
1223
1224 }
1225 return BytesSend;
1226 }
1227
osl_isReceiveReady(oslSocket pSocket,const TimeValue * pTimeout)1228 sal_Bool SAL_CALL osl_isReceiveReady (
1229 oslSocket pSocket,
1230 const TimeValue* pTimeout)
1231 {
1232 fd_set fds;
1233 struct timeval tv;
1234
1235 if (pSocket == nullptr) /* ENOTSOCK */
1236 return false;
1237
1238 FD_ZERO(&fds);
1239 FD_SET(pSocket->m_Socket, &fds);
1240
1241 if (pTimeout)
1242 {
1243 tv.tv_sec = pTimeout->Seconds;
1244 tv.tv_usec = pTimeout->Nanosec / 1000L;
1245 }
1246
1247 return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
1248 &fds, /* check read operations */
1249 nullptr, /* check write ops */
1250 nullptr, /* ckeck for OOB */
1251 pTimeout ? &tv : nullptr)==1); /* use timeout? */
1252 }
1253
1254 /*****************************************************************************/
1255 /* osl_isSendReady */
1256 /*****************************************************************************/
osl_isSendReady(oslSocket pSocket,const TimeValue * pTimeout)1257 sal_Bool SAL_CALL osl_isSendReady (
1258 oslSocket pSocket,
1259 const TimeValue* pTimeout)
1260 {
1261 fd_set fds;
1262 struct timeval tv;
1263
1264 if (pSocket == nullptr) /* ENOTSOCK */
1265 return false;
1266
1267 FD_ZERO(&fds);
1268 FD_SET(pSocket->m_Socket, &fds);
1269
1270 if (pTimeout)
1271 {
1272 tv.tv_sec = pTimeout->Seconds;
1273 tv.tv_usec = pTimeout->Nanosec / 1000L;
1274 }
1275
1276 return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
1277 nullptr, /* check read operations */
1278 &fds, /* check write ops */
1279 nullptr, /* ckeck for OOB */
1280 pTimeout ? &tv : nullptr)==1); /* use timeout? */
1281 }
1282
osl_isExceptionPending(oslSocket pSocket,const TimeValue * pTimeout)1283 sal_Bool SAL_CALL osl_isExceptionPending (
1284 oslSocket pSocket,
1285 const TimeValue* pTimeout)
1286 {
1287 fd_set fds;
1288 struct timeval tv;
1289
1290 if (pSocket == nullptr) /* ENOTSOCK */
1291 return false;
1292
1293 FD_ZERO(&fds);
1294 FD_SET(pSocket->m_Socket, &fds);
1295
1296 if (pTimeout)
1297 {
1298 tv.tv_sec = pTimeout->Seconds;
1299 tv.tv_usec = pTimeout->Nanosec / 1000L;
1300 }
1301
1302 return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
1303 nullptr, /* check read operations */
1304 nullptr, /* check write ops */
1305 &fds, /* ckeck for OOB */
1306 pTimeout ? &tv : nullptr)==1); /* use timeout? */
1307 }
1308
osl_shutdownSocket(oslSocket pSocket,oslSocketDirection Direction)1309 sal_Bool SAL_CALL osl_shutdownSocket (
1310 oslSocket pSocket,
1311 oslSocketDirection Direction)
1312 {
1313 if (pSocket == nullptr) /* ENOTSOCK */
1314 return false;
1315
1316 return (shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction))==0);
1317 }
1318
osl_getSocketOption(oslSocket pSocket,oslSocketOptionLevel Level,oslSocketOption Option,void * pBuffer,sal_uInt32 BufferLen)1319 sal_Int32 SAL_CALL osl_getSocketOption (
1320 oslSocket pSocket,
1321 oslSocketOptionLevel Level,
1322 oslSocketOption Option,
1323 void* pBuffer,
1324 sal_uInt32 BufferLen)
1325 {
1326 if (pSocket == nullptr) /* ENOTSOCK */
1327 return osl_Socket_Error;
1328
1329 int len = BufferLen;
1330 if (getsockopt(pSocket->m_Socket,
1331 OPTION_LEVEL_TO_NATIVE(Level),
1332 OPTION_TO_NATIVE(Option),
1333 static_cast<char *>(pBuffer),
1334 &len) == -1)
1335 {
1336 return -1;
1337 }
1338
1339 return len;
1340 }
1341
osl_setSocketOption(oslSocket pSocket,oslSocketOptionLevel Level,oslSocketOption Option,void * pBuffer,sal_uInt32 BufferLen)1342 sal_Bool SAL_CALL osl_setSocketOption (
1343 oslSocket pSocket,
1344 oslSocketOptionLevel Level,
1345 oslSocketOption Option,
1346 void* pBuffer,
1347 sal_uInt32 BufferLen)
1348 {
1349 if (pSocket == nullptr) /* ENOTSOCK */
1350 return false;
1351
1352 return(setsockopt(pSocket->m_Socket,
1353 OPTION_LEVEL_TO_NATIVE(Level),
1354 OPTION_TO_NATIVE(Option),
1355 static_cast<sal_Char*>(pBuffer),
1356 BufferLen) == 0);
1357 }
1358
osl_enableNonBlockingMode(oslSocket pSocket,sal_Bool On)1359 sal_Bool SAL_CALL osl_enableNonBlockingMode ( oslSocket pSocket, sal_Bool On)
1360 {
1361 unsigned long Param= On ? 1 : 0;
1362
1363 if (pSocket == nullptr) /* ENOTSOCK */
1364 return false;
1365
1366 pSocket->m_Flags = Param ?
1367 (pSocket->m_Flags | OSL_SOCKET_FLAGS_NONBLOCKING) :
1368 (pSocket->m_Flags & ~OSL_SOCKET_FLAGS_NONBLOCKING) ;
1369
1370 return (
1371 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1372 }
1373
osl_isNonBlockingMode(oslSocket pSocket)1374 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
1375 {
1376 if (pSocket == nullptr) /* ENOTSOCK */
1377 return false;
1378
1379 return (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING) != 0;
1380 }
1381
osl_getSocketType(oslSocket pSocket)1382 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
1383 {
1384 int Type=0;
1385 int TypeSize= sizeof(Type);
1386
1387 if (pSocket == nullptr) /* ENOTSOCK */
1388 return osl_Socket_TypeInvalid;
1389
1390 if(getsockopt(pSocket->m_Socket,
1391 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
1392 OPTION_TO_NATIVE(osl_Socket_OptionType),
1393 reinterpret_cast<char *>(&Type),
1394 &TypeSize) == -1)
1395 {
1396 /* error */
1397 return osl_Socket_TypeInvalid;
1398 }
1399
1400 return TYPE_FROM_NATIVE(Type);
1401 }
1402
osl_getLastSocketErrorDescription(oslSocket,rtl_uString ** strError)1403 void SAL_CALL osl_getLastSocketErrorDescription (
1404 oslSocket /*Socket*/,
1405 rtl_uString **strError)
1406 {
1407 int error;
1408
1409 switch(error = WSAGetLastError())
1410 {
1411 case WSAENOTSOCK:
1412 rtl_uString_newFromAscii (strError, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1413 break;
1414
1415 case WSAEDESTADDRREQ:
1416 rtl_uString_newFromAscii (strError, "WSAEDESTADDRREQ, Destination Addr required");
1417 break;
1418
1419 case WSAEMSGSIZE:
1420 rtl_uString_newFromAscii (strError, "WSAEMSGSIZE, Message too long");
1421 break;
1422
1423 case WSAEPROTOTYPE:
1424 rtl_uString_newFromAscii (strError, "WSAEPROTOTYPE, Protocol wrong type for socket");
1425 break;
1426
1427 case WSAENOPROTOOPT:
1428 rtl_uString_newFromAscii (strError, "WSAENOPROTOOPT, Protocol not available");
1429 break;
1430
1431 case WSAEPROTONOSUPPORT:
1432 rtl_uString_newFromAscii (strError, "WSAEPROTONOSUPPORT, Protocol not supported");
1433 break;
1434
1435 case WSAESOCKTNOSUPPORT:
1436 rtl_uString_newFromAscii (strError, "WSAESOCKTNOSUPPORT, Socket type not supported");
1437 break;
1438
1439 case WSAEOPNOTSUPP:
1440 rtl_uString_newFromAscii (strError, "WSAEOPNOTSUPP, Operation not supported on socket");
1441 break;
1442
1443 case WSAEPFNOSUPPORT:
1444 rtl_uString_newFromAscii (strError, "WSAEPFNOSUPPORT, Protocol family not supported");
1445 break;
1446
1447 case WSAEAFNOSUPPORT:
1448 rtl_uString_newFromAscii (strError, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1449 break;
1450
1451 case WSAEADDRINUSE:
1452 rtl_uString_newFromAscii (strError, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1453 break;
1454
1455 case WSAEADDRNOTAVAIL:
1456 rtl_uString_newFromAscii (strError, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1457 break;
1458
1459 case WSAENETDOWN:
1460 rtl_uString_newFromAscii (strError, "WSAENETDOWN, Network is down");
1461 break;
1462
1463 case WSAENETUNREACH:
1464 rtl_uString_newFromAscii (strError, "WSAENETUNREACH, Network is unreachable");
1465 break;
1466
1467 case WSAENETRESET:
1468 rtl_uString_newFromAscii (strError, "WSAENETRESET, Network dropped connection or reset");
1469 break;
1470
1471 case WSAECONNABORTED:
1472 rtl_uString_newFromAscii (strError, "WSAECONNABORTED, Software caused connection abort");
1473 break;
1474
1475 case WSAECONNRESET:
1476 rtl_uString_newFromAscii (strError, "WSAECONNRESET, Connection reset by peer");
1477 break;
1478
1479 case WSAENOBUFS:
1480 rtl_uString_newFromAscii (strError, "WSAENOBUFS, No buffer space available.");
1481 break;
1482
1483 case WSAEISCONN:
1484 rtl_uString_newFromAscii (strError, "WSAEISCONN, Socket is already connected");
1485 break;
1486
1487 case WSAENOTCONN:
1488 rtl_uString_newFromAscii (strError, "WSAENOTCONN, Socket is not connected");
1489 break;
1490
1491 case WSAESHUTDOWN:
1492 rtl_uString_newFromAscii (strError, "WSAESHUTDOWN, Can't send after socket shutdown");
1493 break;
1494
1495 case WSAETIMEDOUT:
1496 rtl_uString_newFromAscii (strError, "WSAETIMEDOUT, Connection timed out");
1497 break;
1498
1499 case WSAECONNREFUSED:
1500 rtl_uString_newFromAscii (strError, "WSAECONNREFUSED, Connection refused");
1501 break;
1502
1503 case WSAEHOSTDOWN:
1504 rtl_uString_newFromAscii (strError, "WSAEHOSTDOWN, Networking subsystem not started");
1505 break;
1506
1507 case WSAEHOSTUNREACH:
1508 rtl_uString_newFromAscii (strError, "WSAEHOSTUNREACH, No route to host");
1509 break;
1510
1511 case WSAEWOULDBLOCK:
1512 rtl_uString_newFromAscii (strError, "WSAEWOULDBLOCK, Operation would block");
1513 break;
1514
1515 case WSAEINPROGRESS:
1516 rtl_uString_newFromAscii (strError, "WSAEINPROGRESS, Operation now in progress");
1517 break;
1518
1519 case WSAEALREADY:
1520 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation already in progress");
1521 break;
1522
1523 case WSAEINTR:
1524 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation was interrupted");
1525 break;
1526
1527 case WSAEBADF:
1528 rtl_uString_newFromAscii (strError, "WSAEBADF, Bad file number");
1529 break;
1530
1531 case WSAEACCES:
1532 rtl_uString_newFromAscii (strError, "WSAEACCES, Access is denied");
1533 break;
1534
1535 case WSAEFAULT:
1536 rtl_uString_newFromAscii (strError, "WSAEFAULT, Bad memory Addr");
1537 break;
1538
1539 case WSAEINVAL:
1540 rtl_uString_newFromAscii (strError, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1541 break;
1542
1543 case WSAEMFILE:
1544 rtl_uString_newFromAscii (strError, "WSAEMFILE, No more file descriptors are available");
1545 break;
1546
1547 case WSAETOOMANYREFS:
1548 rtl_uString_newFromAscii (strError, "WSAETOOMANYREFS, Undocumented WinSock error");
1549 break;
1550
1551 case WSAENAMETOOLONG:
1552 rtl_uString_newFromAscii (strError, "WSAENAMETOOLONG, Undocumented WinSock error");
1553 break;
1554
1555 case WSAENOTEMPTY:
1556 rtl_uString_newFromAscii (strError, "WSAENOTEMPTY, Undocumented WinSock error");
1557 break;
1558
1559 case WSAEPROCLIM:
1560 rtl_uString_newFromAscii (strError, "WSAEPROCLIM, Undocumented WinSock error");
1561 break;
1562
1563 case WSAEUSERS:
1564 rtl_uString_newFromAscii (strError, "WSAEUSERS, Undocumented WinSock error");
1565 break;
1566
1567 case WSAEDQUOT:
1568 rtl_uString_newFromAscii (strError, "WSAEDQUOT, Undocumented WinSock error");
1569 break;
1570
1571 case WSAESTALE:
1572 rtl_uString_newFromAscii (strError, "WSAESTALE, Undocumented WinSock error");
1573 break;
1574
1575 case WSAEREMOTE:
1576 rtl_uString_newFromAscii (strError, "WSAEREMOTE, Undocumented WinSock error");
1577 break;
1578
1579 case WSAEDISCON:
1580 rtl_uString_newFromAscii (strError, "WSAEDISCON, Circuit was gracefully terminated");
1581 break;
1582
1583 case WSASYSNOTREADY:
1584 rtl_uString_newFromAscii (strError, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
1585 break;
1586
1587 case WSAVERNOTSUPPORTED:
1588 rtl_uString_newFromAscii (strError, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
1589 break;
1590
1591 case WSANOTINITIALISED:
1592 rtl_uString_newFromAscii (strError, "WSANOTINITIALISED, WSAStartup() has not been called");
1593 break;
1594
1595 case WSAHOST_NOT_FOUND:
1596 rtl_uString_newFromAscii (strError, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1597 break;
1598
1599 case WSATRY_AGAIN:
1600 rtl_uString_newFromAscii (strError, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1601 break;
1602
1603 case WSANO_RECOVERY:
1604 rtl_uString_newFromAscii (strError, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1605 break;
1606
1607 case WSANO_DATA:
1608 rtl_uString_newFromAscii (strError, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1609 break;
1610
1611 default:
1612 {
1613 sal_Unicode message[128];
1614
1615 wsprintfW(o3tl::toW(message), L"Unknown WinSock Error Number %d", error);
1616 rtl_uString_newFromStr (strError, message);
1617 }
1618
1619 return;
1620
1621 }
1622 }
1623
osl_getLastSocketError(oslSocket)1624 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket /*Socket*/)
1625 {
1626 return ERROR_FROM_NATIVE(WSAGetLastError());
1627 }
1628
1629 struct oslSocketSetImpl
1630 {
1631 fd_set m_Set; /* the set of descriptors */
1632
1633 };
1634
osl_createSocketSet()1635 oslSocketSet SAL_CALL osl_createSocketSet()
1636 {
1637 oslSocketSetImpl* pSet;
1638
1639 pSet = static_cast<oslSocketSetImpl*>(malloc(sizeof(oslSocketSetImpl)));
1640
1641 if(pSet)
1642 {
1643 FD_ZERO(&pSet->m_Set);
1644 }
1645
1646 return pSet;
1647 }
1648
osl_destroySocketSet(oslSocketSet Set)1649 void SAL_CALL osl_destroySocketSet (oslSocketSet Set)
1650 {
1651 if(Set)
1652 free(Set);
1653 }
1654
osl_clearSocketSet(oslSocketSet Set)1655 void SAL_CALL osl_clearSocketSet (oslSocketSet Set)
1656 {
1657 if (Set)
1658 FD_ZERO(&Set->m_Set);
1659 }
1660
osl_addToSocketSet(oslSocketSet Set,oslSocket Socket)1661 void SAL_CALL osl_addToSocketSet (
1662 oslSocketSet Set,
1663 oslSocket Socket)
1664 {
1665 if (Set && Socket)
1666 FD_SET(Socket->m_Socket, &Set->m_Set);
1667 }
1668
osl_removeFromSocketSet(oslSocketSet Set,oslSocket Socket)1669 void SAL_CALL osl_removeFromSocketSet (
1670 oslSocketSet Set,
1671 oslSocket Socket)
1672 {
1673 if (Set && Socket)
1674 FD_CLR(Socket->m_Socket, &Set->m_Set);
1675 }
1676
osl_isInSocketSet(oslSocketSet Set,oslSocket Socket)1677 sal_Bool SAL_CALL osl_isInSocketSet (
1678 oslSocketSet Set,
1679 oslSocket Socket)
1680 {
1681 if (Set && Socket)
1682 return (FD_ISSET(Socket->m_Socket, &Set->m_Set) != 0);
1683 else
1684 return false;
1685 }
1686
osl_demultiplexSocketEvents(oslSocketSet IncomingSet,oslSocketSet OutgoingSet,oslSocketSet OutOfBandSet,const TimeValue * pTimeout)1687 sal_Int32 SAL_CALL osl_demultiplexSocketEvents (
1688 oslSocketSet IncomingSet,
1689 oslSocketSet OutgoingSet,
1690 oslSocketSet OutOfBandSet,
1691 const TimeValue* pTimeout)
1692 {
1693 struct timeval tv;
1694
1695 if(pTimeout)
1696 {
1697 /* divide milliseconds into seconds and microseconds */
1698 tv.tv_sec = pTimeout->Seconds;
1699 tv.tv_usec = pTimeout->Nanosec / 1000L;
1700 }
1701
1702 return select(0, /* redundant in WIN32 */
1703 IncomingSet ? &IncomingSet->m_Set : nullptr,
1704 OutgoingSet ? &OutgoingSet->m_Set : nullptr,
1705 OutOfBandSet ? &OutOfBandSet->m_Set : nullptr,
1706 pTimeout ? &tv : nullptr);
1707 }
1708
1709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1710