1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
14 #include <osl/socket.hxx>
15 #include <config_features.h>
16 #include <sal/log.hxx>
18 #include "DiscoveryService.hxx"
19 #include "ZeroconfService.hxx"
22 // LO vs WinAPI conflict
29 #include "WINNetworkService.hxx"
30 typedef int socklen_t
;
33 #include <sys/socket.h>
34 #include <netinet/in.h>
38 #include <osl/conditn.hxx>
40 #import <CoreFoundation/CoreFoundation.h>
42 #import "OSXNetworkService.hxx"
45 #if HAVE_FEATURE_AVAHI
46 #include "AvahiNetworkService.hxx"
52 DiscoveryService::DiscoveryService()
58 DiscoveryService::~DiscoveryService()
63 closesocket( mSocket
);
73 void DiscoveryService::setupSockets()
78 zService
= new OSXNetworkService();
82 #if HAVE_FEATURE_AVAHI
85 hostname
[1023] = '\0';
86 gethostname(hostname
, 1023);
88 zService
= new AvahiNetworkService(hostname
);
93 zService
= new WINNetworkService();
97 // Old implementation for backward compatibility matter
98 mSocket
= socket( AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
101 SAL_WARN("sd", "DiscoveryService: socket failed: " << errno
);
102 return; // would be better to throw, but unsure if caller handles that
105 sockaddr_in aAddr
= {};
106 aAddr
.sin_family
= AF_INET
;
107 aAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
108 aAddr
.sin_port
= htons( PORT_DISCOVERY
);
110 int rc
= bind( mSocket
, reinterpret_cast<sockaddr
*>(&aAddr
), sizeof(sockaddr_in
) );
114 SAL_WARN("sd", "DiscoveryService: bind failed: " << errno
);
115 return; // would be better to throw, but unsure if caller handles that
118 struct ip_mreq multicastRequest
;
120 multicastRequest
.imr_multiaddr
.s_addr
= htonl((239U << 24) | 1U); // 239.0.0.1
121 multicastRequest
.imr_interface
.s_addr
= htonl(INADDR_ANY
);
123 rc
= setsockopt( mSocket
, IPPROTO_IP
, IP_ADD_MEMBERSHIP
,
125 reinterpret_cast<const char*>(&multicastRequest
),
129 sizeof(multicastRequest
));
133 SAL_WARN("sd", "DiscoveryService: setsockopt failed: " << errno
);
134 return; // would be better to throw, but unsure if caller handles that
138 void SAL_CALL
DiscoveryService::run()
140 osl::Thread::setName("DiscoveryService");
144 // Kept for backward compatibility
147 char aBuffer
[BUFFER_SIZE
] = {};
149 socklen_t aLen
= sizeof( aAddr
);
150 if(recvfrom( mSocket
, aBuffer
, BUFFER_SIZE
, 0, reinterpret_cast<sockaddr
*>(&aAddr
), &aLen
) > 0)
152 OString
aString( aBuffer
, strlen( "LOREMOTE_SEARCH" ) );
153 if ( aString
== "LOREMOTE_SEARCH" )
155 OString aStringBuffer
= "LOREMOTE_ADVERTISE\n" +
156 OUStringToOString(osl::SocketAddr::getLocalHostname(), RTL_TEXTENCODING_UTF8
) +
158 if ( sendto( mSocket
, aStringBuffer
.getStr(),
159 aStringBuffer
.getLength(), 0, reinterpret_cast<sockaddr
*>(&aAddr
),
160 sizeof(aAddr
) ) <= 0 )
162 // Write error or closed socket -- we are done.
169 // Read error or closed socket -- we are done.
175 DiscoveryService
*sd::DiscoveryService::spService
= nullptr;
177 void DiscoveryService::setup()
182 spService
= new DiscoveryService();
186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */