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