diff --git a/scripts/scons_helpers/build-3rdparty.py b/scripts/scons_helpers/build-3rdparty.py index 16ecf9b61..236754a08 100644 --- a/scripts/scons_helpers/build-3rdparty.py +++ b/scripts/scons_helpers/build-3rdparty.py @@ -1148,7 +1148,7 @@ def die(text, *args): elif ctx.pkg_name == 'libatomic_ops': download( ctx, - 'https://github.com/ivmai/libatomic_ops/releases/download/' + 'https://github.com/bdwgc/libatomic_ops/releases/download/' 'v{ctx.pkg_ver}/libatomic_ops-{ctx.pkg_ver}.tar.gz', 'libatomic_ops-{ctx.pkg_ver}.tar.gz') unpack(ctx, @@ -1221,7 +1221,8 @@ def die(text, *args): setattr(ctx, 'res_dir', 'bin/Release') download( ctx, - 'https://github.com/roc-streaming/openfec/archive/v{ctx.pkg_ver}.tar.gz', + #'https://github.com/roc-streaming/openfec/archive/v{ctx.pkg_ver}.tar.gz', + 'https://www.jmd-tech.com/public/openfec-mgw-v{ctx.pkg_ver}.tar.gz', 'openfec_v{ctx.pkg_ver}.tar.gz') unpack(ctx, 'openfec_v{ctx.pkg_ver}.tar.gz', diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index de3585886..914288726 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -6,11 +6,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifdef ROC_TARGET_POSIX #include +#endif #include "roc_address/socket_addr.h" #include "roc_core/endian.h" +namespace { + +#ifdef ROC_TARGET_WINDOWS +typedef ADDRESS_FAMILY sa_family_t; +typedef USHORT in_port_t; +typedef size_t ntop_bufsz; +#else +typedef socklen_t ntop_bufsz; +#endif + +socklen_t saddr_size(sa_family_t family) { + switch (family) { + case AF_INET: + return sizeof(sockaddr_in); + case AF_INET6: + return sizeof(sockaddr_in6); + default: + return 0; + } +} + +sa_family_t saddr_family(const sockaddr_in& sa4) { + return (sa_family_t)sa4.sin_family; +} + +} // namespace + namespace roc { namespace address { @@ -23,11 +52,12 @@ void SocketAddr::clear() { } bool SocketAddr::has_host_port() const { - return saddr_family_() == AF_INET || saddr_family_() == AF_INET6; + return saddr_family(saddr_.addr4) == AF_INET + || saddr_family(saddr_.addr4) == AF_INET6; } bool SocketAddr::set_host_port_saddr(const sockaddr* sa) { - const socklen_t sa_size = saddr_size_(sa->sa_family); + const socklen_t sa_size = saddr_size(sa->sa_family); if (sa_size == 0) { return false; } @@ -88,15 +118,15 @@ const sockaddr* SocketAddr::saddr() const { } socklen_t SocketAddr::slen() const { - return saddr_size_(saddr_family_()); + return saddr_size(saddr_family(saddr_.addr4)); } socklen_t SocketAddr::max_slen() const { - return saddr_size_(AF_INET6); + return saddr_size(AF_INET6); } AddrFamily SocketAddr::family() const { - switch (saddr_family_()) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: return Family_IPv4; case AF_INET6: @@ -107,7 +137,7 @@ AddrFamily SocketAddr::family() const { } int SocketAddr::port() const { - switch (saddr_family_()) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: return core::ntoh16u((uint16_t)saddr_.addr4.sin_port); case AF_INET6: @@ -117,10 +147,19 @@ int SocketAddr::port() const { } } +#ifndef ROC_TARGET_WINDOWS +#define IN_MULTICAST_U(i) IN_MULTICAST(i) +#else +// Defined as (((long)(i) & 0xf0000000) == 0xe0000000) in Windows, causes Wsign-conversion +// clang-format off +#define IN_MULTICAST_U(i) (((unsigned long)(i) & 0xf0000000u) == 0xe0000000u) +// clang-format on +#endif + bool SocketAddr::is_multicast() const { - switch (saddr_family_()) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: - return IN_MULTICAST(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); + return IN_MULTICAST_U(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); case AF_INET6: return IN6_IS_ADDR_MULTICAST(&saddr_.addr6.sin6_addr); default: @@ -129,15 +168,15 @@ bool SocketAddr::is_multicast() const { } bool SocketAddr::get_host(char* buf, size_t bufsz) const { - switch (saddr_family_()) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: - if (!inet_ntop(AF_INET, &saddr_.addr4.sin_addr, buf, (socklen_t)bufsz)) { + if (!inet_ntop(AF_INET, &saddr_.addr4.sin_addr, buf, (ntop_bufsz)bufsz)) { return false; } break; case AF_INET6: - if (!inet_ntop(AF_INET6, &saddr_.addr6.sin6_addr, buf, (socklen_t)bufsz)) { + if (!inet_ntop(AF_INET6, &saddr_.addr6.sin6_addr, buf, (ntop_bufsz)bufsz)) { return false; } break; @@ -154,11 +193,11 @@ SocketAddr::operator const struct unspecified_bool *() const { } bool SocketAddr::operator==(const SocketAddr& other) const { - if (saddr_family_() != other.saddr_family_()) { + if (saddr_family(saddr_.addr4) != saddr_family(other.saddr_.addr4)) { return false; } - switch (saddr_family_()) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: if (saddr_.addr4.sin_addr.s_addr != other.saddr_.addr4.sin_addr.s_addr) { return false; @@ -190,20 +229,5 @@ bool SocketAddr::operator!=(const SocketAddr& other) const { return !(*this == other); } -socklen_t SocketAddr::saddr_size_(sa_family_t family) { - switch (family) { - case AF_INET: - return sizeof(sockaddr_in); - case AF_INET6: - return sizeof(sockaddr_in6); - default: - return 0; - } -} - -sa_family_t SocketAddr::saddr_family_() const { - return saddr_.addr4.sin_family; -} - } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index 1db2959ed..7de9654af 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -12,8 +12,13 @@ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #define ROC_ADDRESS_SOCKET_ADDR_H_ +#ifdef ROC_TARGET_POSIX #include #include +#else // ! ROC_TARGET_POSIX +#include +#include +#endif // ROC_TARGET_POSIX #include "roc_address/addr_family.h" #include "roc_core/attributes.h" @@ -82,10 +87,6 @@ class SocketAddr { }; private: - static socklen_t saddr_size_(sa_family_t family); - - sa_family_t saddr_family_() const; - bool set_host_port_ipv4_(const char* ip, int port); bool set_host_port_ipv6_(const char* ip, int port); diff --git a/src/internal_modules/roc_audio/depacketizer.cpp b/src/internal_modules/roc_audio/depacketizer.cpp index 39b4cac0c..daa109bbc 100644 --- a/src/internal_modules/roc_audio/depacketizer.cpp +++ b/src/internal_modules/roc_audio/depacketizer.cpp @@ -526,14 +526,15 @@ void Depacketizer::commit_frame_(Frame& frame, && frame_stats.n_missing_samples != 0, "depacketizer: incorrect sample counters"); - roc_log(LogTrace, - "depacketizer: returning frame:" - " stream_ts=%lu n_decoded=%lu n_missing=%lu n_dropped=%lu", - (unsigned long)stream_ts_ - - (frame_stats.n_written_samples / sample_spec_.num_channels()), - (unsigned long)frame_stats.n_decoded_samples / sample_spec_.num_channels(), - (unsigned long)frame_stats.n_missing_samples / sample_spec_.num_channels(), - (unsigned long)frame_stats.n_dropped_packets); + roc_log( + LogTrace, + "depacketizer: returning frame:" + " stream_ts=%lu n_decoded=%lu n_missing=%lu n_dropped=%lu", + (unsigned long)(stream_ts_ + - (frame_stats.n_written_samples / sample_spec_.num_channels())), + (unsigned long)(frame_stats.n_decoded_samples / sample_spec_.num_channels()), + (unsigned long)(frame_stats.n_missing_samples / sample_spec_.num_channels()), + (unsigned long)frame_stats.n_dropped_packets); unsigned flags = 0; if (frame_stats.n_decoded_samples != 0) { diff --git a/src/internal_modules/roc_audio/frame.cpp b/src/internal_modules/roc_audio/frame.cpp index 09ff9463c..8506df7e8 100644 --- a/src/internal_modules/roc_audio/frame.cpp +++ b/src/internal_modules/roc_audio/frame.cpp @@ -91,7 +91,7 @@ void Frame::set_num_raw_samples(size_t n_samples) { roc_panic("frame: frame buffer does not have enough capacity:" " requested=%lu available=%lu", (unsigned long)n_samples, - (unsigned long)buffer_.capacity() / sizeof(sample_t)); + (unsigned long)(buffer_.capacity() / sizeof(sample_t))); } buffer_.reslice(0, n_samples * sizeof(sample_t)); diff --git a/src/internal_modules/roc_core/buffer.cpp b/src/internal_modules/roc_core/buffer.cpp index 07451f013..ed8f26e47 100644 --- a/src/internal_modules/roc_core/buffer.cpp +++ b/src/internal_modules/roc_core/buffer.cpp @@ -18,7 +18,7 @@ Buffer::Buffer(IPool& buffer_pool, size_t buffer_size) roc_panic_if_msg(sizeof(Buffer) + buffer_size != buffer_pool.object_size(), "buffer: attempt to create buffer with wrong size:" " requested=%lu expected=%lu", - (unsigned long)sizeof(Buffer) + buffer_size, + (unsigned long)(sizeof(Buffer) + buffer_size), (unsigned long)buffer_pool.object_size()); new (data_) uint8_t[size_]; diff --git a/src/internal_modules/roc_core/print_memory.cpp b/src/internal_modules/roc_core/print_memory.cpp index 629f0ca9a..4f66fb38d 100644 --- a/src/internal_modules/roc_core/print_memory.cpp +++ b/src/internal_modules/roc_core/print_memory.cpp @@ -176,7 +176,7 @@ void print_memory_slice_t(const T* inner, p.writef("@ slice: type=%s off=%lu size=%lu cap=%lu\n", type_to_str(), (unsigned long)off, (unsigned long)inner_size, - (unsigned long)outer_size - off); + (unsigned long)(outer_size - off)); if (outer) { print_impl_t(p, outer, outer_size, off, off + inner_size); diff --git a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp index a2645933f..ac8900031 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp @@ -7,6 +7,7 @@ */ #include "roc_core/cond.h" +#include "roc_core/errno_to_str.h" #include "roc_core/panic.h" namespace roc { @@ -34,7 +35,8 @@ bool Cond::timed_wait(nanoseconds_t timeout) const { if (err == ERROR_TIMEOUT || err == WAIT_TIMEOUT) { return false; } - roc_panic("cond: SleepConditionVariableCS(): error %lu", error); + roc_panic("cond: SleepConditionVariableCS(): %s", + core::errno_to_str((int)err).c_str()); } return true; @@ -42,8 +44,7 @@ bool Cond::timed_wait(nanoseconds_t timeout) const { void Cond::wait() const { if (!SleepConditionVariableCS(&cond_, &mutex_, INFINITE)) { - DWORD error = GetLastError(); - roc_panic("cond: SleepConditionVariableCS(): error %lu", error); + roc_panic("cond: SleepConditionVariableCS(): %s", core::errno_to_str().c_str()); } } diff --git a/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp b/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp index abc0e06e1..0be4de8b6 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp @@ -13,7 +13,7 @@ namespace roc { namespace core { errno_to_str::errno_to_str() { - format_(GetLastError()); + format_((int)GetLastError()); } errno_to_str::errno_to_str(int err) { @@ -23,10 +23,10 @@ errno_to_str::errno_to_str(int err) { void errno_to_str::format_(int err) { wchar_t wbuf[sizeof(buffer_)] = {}; - const size_t size = + size_t size = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), wbuf, - sizeof(wbuf) / sizeof(wchar_t) - 1, nullptr); + nullptr, (DWORD)err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + wbuf, sizeof(wbuf) / sizeof(wchar_t) - 1, nullptr); if (size == 0) { strcpy(buffer_, ""); diff --git a/src/internal_modules/roc_core/target_windows/roc_core/time.cpp b/src/internal_modules/roc_core/target_windows/roc_core/time.cpp new file mode 100644 index 000000000..80d5c9ed6 --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/time.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "roc_core/time.h" +#include "roc_core/errno_to_str.h" +#include "roc_core/panic.h" + +#include + +// Present when compiling with MinGW in Windows, +// but not defined when cross-compiling from Linux (Debian 12) +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION (0x00000002) +#endif + +namespace roc { +namespace core { + +namespace { + +#if defined(CLOCK_REALTIME) + +clockid_t map_clock(clock_t clock) { + if (clock == ClockMonotonic) { +#if defined(CLOCK_MONOTONIC) + return CLOCK_MONOTONIC; +#endif + } + + return CLOCK_REALTIME; +} + +#endif + +} // namespace + +nanoseconds_t timestamp(clock_t clock) { + timespec ts; + if (clock_gettime(map_clock(clock), &ts) == -1) { + roc_panic("time: clock_gettime(): %s", errno_to_str().c_str()); + } + + return nanoseconds_t(ts.tv_sec) * 1000000000 + nanoseconds_t(ts.tv_nsec); +} + +void sleep_for(clock_t clock, nanoseconds_t ns) { + // TODO: handle fallback to non high-resolution timer? (waitable high resolution timer + // supported only from W10 1803) + HANDLE hTimer = CreateWaitableTimerEx( + NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); + if (!hTimer) { + roc_panic("time: CreateWaitableTimerEx(): %s", errno_to_str().c_str()); + } + LARGE_INTEGER dueTime; + dueTime.QuadPart = ns / -100; // In 100 nanoseconds interval, negative = relative + // value. + // should we add -1 to round for "at least" xx ns? + if (!SetWaitableTimer(hTimer, &dueTime, 0 /*once*/, NULL, NULL, FALSE)) { + roc_panic("time: SetWaitableTimer(): %s", errno_to_str().c_str()); + } + if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) { + roc_panic("time: WaitForSingleObject(): %s", errno_to_str().c_str()); + } + CloseHandle(hTimer); +} + +void sleep_until(clock_t clock, nanoseconds_t ns) { + nanoseconds_t now = timestamp(clock); + if (ns > now) { + sleep_for(clock, ns - now); + } +} + +std::tm nanoseconds_2_tm(nanoseconds_t timestamp) { + const time_t sec = time_t(timestamp / Second); + + std::tm tm; + errno_t err = localtime_s(&tm, &sec); + if (err) + roc_panic("time: localtime_s(): %s", errno_to_str(err).c_str()); + + return tm; +} + +nanoseconds_t tm_2_nanoseconds(std::tm tm) { + const time_t sec = mktime(&tm); + + if (sec == (time_t)-1) { + roc_panic("time: mktime(): %s", errno_to_str().c_str()); + } + + return nanoseconds_t(sec) * Second; +} + +} // namespace core +} // namespace roc diff --git a/src/internal_modules/roc_fec/composer.h b/src/internal_modules/roc_fec/composer.h index 753def05d..6d37f21f2 100644 --- a/src/internal_modules/roc_fec/composer.h +++ b/src/internal_modules/roc_fec/composer.h @@ -43,7 +43,7 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { //! Adjust buffer to align payload. ROC_NODISCARD virtual status::StatusCode align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { - if ((unsigned long)buffer.data() % payload_alignment != 0) { + if ((size_t)buffer.data() % payload_alignment != 0) { roc_panic("fec composer: unexpected non-aligned buffer"); } diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index a01e09b1e..7a4b53bfe 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -8,10 +8,17 @@ #include #include + +#ifdef ROC_TARGET_POSIX #include #include -#include #include +#else // ! ROC_TARGET_POSIX +#include +#include +#endif // ROC_TARGET_POSIX + +#include #include #include #include @@ -26,6 +33,16 @@ namespace netio { namespace { +#ifndef ROC_TARGET_WINDOWS +typedef void sockbuf_t; +typedef int sockopt_t; +#else // ROC_TARGET_WINDOWS +typedef char sockbuf_t; +typedef char sockopt_t; +typedef ADDRESS_FAMILY sa_family_t; +typedef USHORT in_port_t; +#endif // ! ROC_TARGET_WINDOWS + int to_domain(address::AddrFamily family) { switch (family) { case address::Family_IPv4: @@ -75,6 +92,20 @@ bool is_malformed(int err) { return err == EBADF || err == EFAULT || err == ENOTSOCK; } +#ifndef ROC_TARGET_WINDOWS + +bool valid_socket(SocketHandle sock) { + return sock >= 0; +} + +#else + +bool valid_socket(SocketHandle sock) { + return sock != SocketInvalid; +} + +#endif + bool get_local_address(SocketHandle sock, address::SocketAddr& address) { socklen_t addrlen = address.max_slen(); @@ -98,7 +129,7 @@ bool get_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int& opt_val) { socklen_t opt_len = sizeof(opt_val); - if (getsockopt(sock, level, opt, &opt_val, &opt_len) == -1) { + if (getsockopt(sock, level, opt, (sockopt_t*)&opt_val, &opt_len) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: getsockopt(%s): %s", opt_name, @@ -118,7 +149,7 @@ bool get_int_option( bool set_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int opt_val) { - if (setsockopt(sock, level, opt, &opt_val, sizeof(opt_val)) == -1) { + if (setsockopt(sock, level, opt, (const sockopt_t*)&opt_val, sizeof(opt_val)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(%s): %s", opt_name, @@ -140,6 +171,9 @@ bool set_int_option( // creation and fcntl() call, during which fork() can be called from another thread // // - for performance reasons: without SOCK_CLOEXEC there are two more system calls + +#if defined(ROC_TARGET_POSIX) && defined(FD_CLOEXEC) + bool set_cloexec(SocketHandle sock) { int flags; @@ -170,6 +204,14 @@ bool set_cloexec(SocketHandle sock) { return true; } +#else // !defined(ROC_TARGET_POSIX) || !defined(FD_CLOEXEC) + +bool set_cloexec(SocketHandle sock) { + return true; +} + +#endif // defined(ROC_TARGET_POSIX) && defined(FD_CLOEXEC) + #endif // !defined(SOCK_CLOEXEC) #if !defined(SOCK_NONBLOCK) @@ -178,6 +220,9 @@ bool set_cloexec(SocketHandle sock) { // // Using SOCK_NONBLOCK is preferred because of performance reasons. // Without SOCK_NONBLOCK there are two more system calls. + +#if defined(ROC_TARGET_POSIX) + bool set_nonblock(SocketHandle sock) { int flags; @@ -208,11 +253,66 @@ bool set_nonblock(SocketHandle sock) { return true; } +#elif defined(ROC_TARGET_WINDOWS) + +bool set_nonblock(SocketHandle sock) { + unsigned long mode = 1; // 0 for blocking, nonzero for non blocking + + int res = ioctlsocket(sock, (long)FIONBIO, &mode); + if (res == SOCKET_ERROR) { + roc_log(LogError, "socket: ioctlsocket(FIONBIO): %s", + core::errno_to_str(WSAGetLastError()).c_str()); + return false; + } + + return (res == NO_ERROR); +} + +#endif // defined(ROC_TARGET_POSIX) + #endif // !defined(SOCK_NONBLOCK) } // namespace -#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#ifdef ROC_TARGET_WINDOWS + +bool socket_init() { + WSADATA wsaData; + int err = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (err) { + roc_log(LogError, "WSAStartup: %s", core::errno_to_str(err).c_str()); + return false; + } + return true; +} + +bool socket_deinit() { + int res = WSACleanup(); + if (res) { + if (res == SOCKET_ERROR) { + roc_log(LogError, "WSACleanup: %s", + core::errno_to_str(WSAGetLastError()).c_str()); + } else { + roc_log(LogError, "WSACleanup: returned unexpected value %d", res); + } + return false; + } + return true; +} + +#else // !ROC_TARTGET_WINDOWS + +bool socket_init() { + return true; +} + +bool socket_deinit() { + return true; +} + +#endif // ROC_TARGET_WINDOWS + +#if defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock) { new_sock = socket(to_domain(family), to_type(type) | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); @@ -227,16 +327,16 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne return true; } -#else // !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) +#else // !defined(ROC_TARGET_POSIX) || !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock) { new_sock = socket(to_domain(family), to_type(type), 0); - if (new_sock == -1) { + if (new_sock == SocketInvalid) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: socket(): %s", core::errno_to_str().c_str()); - return SockErr_Failure; + return false; } if (!set_cloexec(new_sock)) { @@ -252,14 +352,14 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne return true; } -#endif // defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#endif // defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) -#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#if defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_accept(SocketHandle sock, SocketHandle& new_sock, address::SocketAddr& remote_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); socklen_t addrlen = remote_address.max_slen(); @@ -285,18 +385,18 @@ bool socket_accept(SocketHandle sock, return true; } -#else // !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) +#else // !defined(ROC_TARGET_POSIX) || !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) bool socket_accept(SocketHandle sock, SocketHandle& new_sock, address::SocketAddr& remote_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); socklen_t addrlen = remote_address.max_slen(); new_sock = accept(sock, remote_address.saddr(), &addrlen); - if (new_sock == -1) { + if (new_sock == SocketInvalid) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: accept(): %s", core::errno_to_str().c_str()); @@ -323,10 +423,10 @@ bool socket_accept(SocketHandle sock, return true; } -#endif // defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#endif // defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_setup(SocketHandle sock, const SocketOpts& options) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); // If SO_NOSIGPIPE is available, enable it here for socket_try_send(). #if defined(SO_NOSIGPIPE) @@ -344,7 +444,7 @@ bool socket_setup(SocketHandle sock, const SocketOpts& options) { } bool socket_bind(SocketHandle sock, address::SocketAddr& local_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!local_address.has_host_port()); // If IPV6_V6ONLY is available, use it for IPv6 addresses. @@ -372,7 +472,7 @@ bool socket_bind(SocketHandle sock, address::SocketAddr& local_address) { } bool socket_listen(SocketHandle sock, size_t backlog) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); if (listen(sock, (int)backlog) == -1) { roc_panic_if(is_malformed(errno)); @@ -387,7 +487,7 @@ bool socket_listen(SocketHandle sock, size_t backlog) { bool socket_begin_connect(SocketHandle sock, const address::SocketAddr& remote_address, bool& completed_immediately) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!remote_address.has_host_port()); int saved_errno = errno; @@ -415,7 +515,7 @@ bool socket_begin_connect(SocketHandle sock, } bool socket_end_connect(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); int err = 0; @@ -435,15 +535,20 @@ bool socket_end_connect(SocketHandle sock) { } ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); if (bufsz == 0) { return 0; } + int flags = 0; +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#endif + ssize_t ret; - while ((ret = recv(sock, buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = recv(sock, (sockbuf_t*)buf, bufsz, flags)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -467,7 +572,8 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { return ret; } -#if defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL) +#if (defined(ROC_TARGET_POSIX) && (defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL))) \ + || defined(ROC_TARGET_WINDOWS) // This version is used if either SO_NOSIGPIPE or MSG_NOSIGNAL is available //. @@ -479,20 +585,25 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { // // If MSG_NOSIGNAL is available (e.g. on Linux), we pass it to send(). ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); if (bufsz == 0) { return 0; } - int flags = MSG_DONTWAIT; + int flags = 0; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#endif + #if defined(MSG_NOSIGNAL) flags |= MSG_NOSIGNAL; #endif ssize_t ret; - while ((ret = send(sock, buf, bufsz, flags)) == -1) { + while ((ret = send(sock, (const sockbuf_t*)buf, bufsz, flags)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -517,7 +628,8 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return ret; } -#else // !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) +#else // !defined(ROC_TARGET_POSIX) || (!defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL))) + // && !defined(ROC_TARGET_WINDOWS) // This version is used when both SO_NOSIGPIPE and MSG_NOSIGNAL aren't available. // @@ -533,7 +645,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { // // This implementation requires POSIX 2001. ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); if (bufsz == 0) { @@ -565,7 +677,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { } ssize_t ret; - while ((ret = send(sock, buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = send(sock, (sockbuf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -612,19 +724,26 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return ret; } -#endif // defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL) +#endif // (defined(ROC_TARGET_POSIX) && (defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL))) + // || defined(ROC_TARGET_WINDOWS) ssize_t socket_try_send_to(SocketHandle sock, const void* buf, size_t bufsz, const address::SocketAddr& remote_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); roc_panic_if(!remote_address.has_host_port()); + int flags = 0; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#endif + ssize_t ret; - while ((ret = sendto(sock, buf, bufsz, MSG_DONTWAIT, remote_address.saddr(), - remote_address.slen())) + while ((ret = sendto(sock, (const sockbuf_t*)buf, bufsz, flags, + remote_address.saddr(), remote_address.slen())) == -1) { roc_panic_if(is_malformed(errno)); @@ -653,10 +772,22 @@ ssize_t socket_try_send_to(SocketHandle sock, return ret; } +#ifdef ROC_TARGET_WINDOWS +#define SHUT_RDWR (SD_BOTH) +#endif + bool socket_shutdown(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); + + int flags = 0; - if (shutdown(sock, SHUT_RDWR) == -1) { +#ifdef SHUT_RDWR + flags |= SHUT_RDWR; +#else + flags |= SD_BOTH; +#endif + + if (shutdown(sock, flags) == -1) { roc_panic_if(is_malformed(errno)); // shutdown() on macOS may return ENOTCONN if the other side gracefully @@ -673,8 +804,10 @@ bool socket_shutdown(SocketHandle sock) { return true; } +#ifndef ROC_TARGET_WINDOWS + bool socket_close(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); if (close(sock) == -1) { roc_panic_if(is_malformed(errno)); @@ -696,8 +829,24 @@ bool socket_close(SocketHandle sock) { return true; } +#else // ROC_TARGET_WINDOWS + +bool socket_close(SocketHandle sock) { + roc_panic_if(sock == SocketInvalid); + + if (closesocket(sock) == SOCKET_ERROR) { + roc_log(LogError, "socket: closesocket(): %s", + core::errno_to_str(WSAGetLastError()).c_str()); + return false; + } + + return true; +} + +#endif // ROC_TARGET_WINDOWS + bool socket_close_with_reset(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); // SO_LINGER with zero timeout instructs close() to send RST instead of FIN. struct linger ling; @@ -705,7 +854,8 @@ bool socket_close_with_reset(SocketHandle sock) { ling.l_linger = 0; bool setsockopt_failed = false; - if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)) == -1) { + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (const sockopt_t*)&ling, sizeof(ling)) + == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(SO_LINGER): %s", diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h index 0abcd8bbc..50c7ce982 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h @@ -48,10 +48,24 @@ enum SocketError { }; //! Platform-specific socket handle. +#ifndef ROC_TARGET_WINDOWS typedef int SocketHandle; +#else +typedef SOCKET SocketHandle; +#endif //! Invalid socket handle. +#ifndef ROC_TARGET_WINDOWS const SocketHandle SocketInvalid = -1; +#else +const SocketHandle SocketInvalid = INVALID_SOCKET; +#endif + +//! Initialize environment for socket functions. +ROC_NODISCARD bool socket_init(); + +//! Cleans socket functions environment. +ROC_NODISCARD bool socket_deinit(); //! Create non-blocking socket. ROC_NODISCARD bool diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp index 4f3a1c101..95097e7b9 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp @@ -804,7 +804,7 @@ void TcpConnectionPort::format_descriptor(core::StringBuilder& b) { } b.append_str(" 0x"); - b.append_uint((unsigned long)this, 16); + b.append_uint((size_t)this, 16); b.append_str(" local="); b.append_str(address::socket_addr_to_str(local_address_).c_str()); diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp index 58147844c..9df574f41 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp @@ -325,7 +325,7 @@ void TcpServerPort::format_descriptor(core::StringBuilder& b) { b.append_str("udp(); const bool success = - socket_try_send_to(fd_, pp->buffer().data(), pp->buffer().size(), udp.dst_addr); + socket_try_send_to(sock_, pp->buffer().data(), pp->buffer().size(), udp.dst_addr); if (success) { const int packet_num = ++sent_packets_; @@ -580,7 +584,7 @@ void UdpPort::format_descriptor(core::StringBuilder& b) { b.append_str("buffer().size()); + " provided=%llu needed=%llu", + (unsigned long long)n_bytes, (unsigned long long)packet->buffer().size()); return status::StatusBadBuffer; } diff --git a/src/internal_modules/roc_node/sender_encoder.cpp b/src/internal_modules/roc_node/sender_encoder.cpp index 624cec50e..391c79567 100644 --- a/src/internal_modules/roc_node/sender_encoder.cpp +++ b/src/internal_modules/roc_node/sender_encoder.cpp @@ -205,8 +205,8 @@ SenderEncoder::read_packet(address::Interface iface, void* bytes, size_t* n_byte roc_log(LogError, "sender encoder node:" " not enough space in provided packet:" - " provided=%lu needed=%lu", - (unsigned long)n_bytes, (unsigned long)packet->buffer().size()); + " provided=%llu needed=%llu", + (unsigned long long)n_bytes, (unsigned long long)packet->buffer().size()); return status::StatusBadBuffer; } @@ -230,9 +230,9 @@ SenderEncoder::write_packet(address::Interface iface, const void* bytes, size_t roc_log(LogError, "sender encoder node:" " provided packet exceeds maximum packet size (see roc_context_config):" - " provided=%lu maximum=%lu", - (unsigned long)n_bytes, - (unsigned long)packet_factory_.packet_buffer_size()); + " provided=%llu maximum=%llu", + (unsigned long long)n_bytes, + (unsigned long long)packet_factory_.packet_buffer_size()); return status::StatusBadBuffer; } diff --git a/src/internal_modules/roc_rtcp/composer.cpp b/src/internal_modules/roc_rtcp/composer.cpp index 951913cbb..5858afb92 100644 --- a/src/internal_modules/roc_rtcp/composer.cpp +++ b/src/internal_modules/roc_rtcp/composer.cpp @@ -25,7 +25,7 @@ ROC_NODISCARD status::StatusCode Composer::init_status() const { ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { - if ((unsigned long)buffer.data() % payload_alignment != 0) { + if ((size_t)buffer.data() % payload_alignment != 0) { roc_panic("rtcp composer: unexpected non-aligned buffer"); } diff --git a/src/internal_modules/roc_rtp/composer.cpp b/src/internal_modules/roc_rtp/composer.cpp index 017ff2060..cceabde08 100644 --- a/src/internal_modules/roc_rtp/composer.cpp +++ b/src/internal_modules/roc_rtp/composer.cpp @@ -27,7 +27,7 @@ ROC_NODISCARD status::StatusCode Composer::init_status() const { ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { - if ((unsigned long)buffer.data() % payload_alignment != 0) { + if ((size_t)buffer.data() % payload_alignment != 0) { roc_panic("rtp composer: unexpected non-aligned buffer"); } diff --git a/src/internal_modules/roc_sndio/wav_sink.cpp b/src/internal_modules/roc_sndio/wav_sink.cpp index b739e69a8..f40918422 100644 --- a/src/internal_modules/roc_sndio/wav_sink.cpp +++ b/src/internal_modules/roc_sndio/wav_sink.cpp @@ -11,6 +11,7 @@ #include "roc_audio/pcm_subformat.h" #include "roc_audio/sample_spec_to_str.h" #include "roc_core/endian_ops.h" +#include "roc_core/errno_to_str.h" #include "roc_core/log.h" #include "roc_core/panic.h" #include "roc_status/code_to_str.h" diff --git a/src/internal_modules/roc_sndio/wav_source.cpp b/src/internal_modules/roc_sndio/wav_source.cpp index 9c6516cc1..ee7e90f64 100644 --- a/src/internal_modules/roc_sndio/wav_source.cpp +++ b/src/internal_modules/roc_sndio/wav_source.cpp @@ -8,6 +8,7 @@ #include "roc_sndio/wav_source.h" #include "roc_audio/sample_spec_to_str.h" +#include "roc_core/errno_to_str.h" #include "roc_core/log.h" #include "roc_core/panic.h" #include "roc_status/code_to_str.h"