Skip to content

Commit

Permalink
Merge pull request #820 from ApexAI/iox-#33-implement-uds-with-named-…
Browse files Browse the repository at this point in the history
…pipes

Iox #33 implement uds with named pipes
  • Loading branch information
elfenpiff authored Jun 9, 2021
2 parents ea6ea66 + 48e33ae commit 7697383
Show file tree
Hide file tree
Showing 47 changed files with 1,296 additions and 217 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ jobs:
# we have to exclude the tests explicitly until everyone is running
- name: Run tests, excluding timing_tests
run: |
build\hoofs\test\Debug\hoofs_moduletests.exe --gtest_filter="-*TimingTest*"
build\hoofs\test\Debug\hoofs_moduletests.exe --gtest_filter="-*TimingTest*:IpcChannel*:Mutex*:UnixDomainSocket*"
build\hoofs\test\Debug\hoofs_integrationtests.exe
build\binding_c\test\Debug\binding_c_moduletests.exe --gtest_filter="-Chunk*:iox_listener*:iox_node*:iox_pub*:BindingC_Runtime*:iox_sub*:iox_ws*:iox_types*:*TimingTest*"
build\posh\test\Debug\posh_moduletests.exe --gtest_filter="-PoshRuntime*:IceoryxRoudiApp*:IceoryxRoudiMemoryManager*:PortManager*:ProcessIntrospection*:ProcessManager*:PosixShmMemoryProvider*:Process_test*:ParseAllMalformedInput*:*TimingTest*"
build\binding_c\test\Debug\binding_c_moduletests.exe --gtest_filter="-BindingC_Runtime*:*TimingTest*"
build\posh\test\Debug\posh_moduletests.exe --gtest_filter="-PoshRuntime*:IceoryxRoudiApp*:IceoryxRoudiMemoryManager*:ProcessIntrospection*:ParseAllMalformedInput*:*TimingTest*"
build\posh\test\Debug\posh_integrationtests.exe --gtest_filter="-*ChunkBuildingBlocks*:PortUser*:RoudiFindService*:*TimingTest*"
6 changes: 6 additions & 0 deletions iceoryx_binding_c/include/iceoryx_binding_c/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ struct iox_user_trigger_storage_t_
// sizeof(UserTrigger) / 8
#if defined(__APPLE__)
uint64_t do_not_touch_me[17];
#elif defined(_WIN32)
uint64_t do_not_touch_me[16];
#else
uint64_t do_not_touch_me[14];
#endif
Expand All @@ -57,6 +59,8 @@ struct iox_sub_storage_t_
// sizeof(cpp2c_Subscriber) / 8
#if defined(__APPLE__)
uint64_t do_not_touch_me[17];
#elif defined(_WIN32)
uint64_t do_not_touch_me[17];
#else
uint64_t do_not_touch_me[14];
#endif
Expand All @@ -77,6 +81,8 @@ struct iox_listener_storage_t_
// sizeof(Listener) / 8
#if defined(__APPLE__)
uint64_t do_not_touch_me[2643];
#elif defined(_WIN32)
uint64_t do_not_touch_me[2774];
#else
uint64_t do_not_touch_me[2567];
#endif
Expand Down
1 change: 1 addition & 0 deletions iceoryx_hoofs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ add_library(iceoryx_hoofs
source/posix_wrapper/shared_memory_object.cpp
source/posix_wrapper/signal_handler.cpp
source/posix_wrapper/message_queue.cpp
source/posix_wrapper/named_pipe.cpp
source/posix_wrapper/unix_domain_socket.cpp
source/posix_wrapper/shared_memory_object/allocator.cpp
source/posix_wrapper/shared_memory_object/memory_map.cpp
Expand Down
29 changes: 29 additions & 0 deletions iceoryx_hoofs/include/iceoryx_hoofs/cxx/helplets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,22 @@

#include <assert.h>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <limits>
#include <type_traits>

#include "iceoryx_hoofs/platform/platform_correction.hpp"
#include "iceoryx_hoofs/platform/platform_settings.hpp"

namespace iox
{
namespace cxx
{
template <uint64_t Capacity>
class string;
struct TruncateToCapacity_t;

namespace internal
{
inline void
Expand Down Expand Up @@ -66,6 +72,17 @@ struct BestFittingTypeImpl<true, true, false>
{
using Type_t = uint32_t;
};

constexpr char ASCII_A = 'a';
constexpr char ASCII_Z = 'z';
constexpr char ASCII_CAPITAL_A = 'A';
constexpr char ASCII_CAPITAL_Z = 'Z';
constexpr char ASCII_0 = '0';
constexpr char ASCII_9 = '9';
constexpr char ASCII_MINUS = '-';
constexpr char ASCII_DOT = '.';
constexpr char ASCII_COLON = ':';
constexpr char ASCII_UNDERSCORE = '_';
} // namespace internal

// implementing C++ Core Guideline, I.6. Prefer Expects
Expand Down Expand Up @@ -250,7 +267,19 @@ constexpr bool isPowerOfTwo(const T n)
return n && ((n & (n - 1U)) == 0U);
}

/// @brief checks if the given string is a valid filename
/// @return true if the string is a filename, otherwise false
template <uint64_t StringCapacity>
bool isValidFileName(const string<StringCapacity>& name) noexcept;

/// @brief verifies if the given string is a valid path to a file
/// @return true if the string is a path to a file, otherwise false
template <uint64_t StringCapacity>
bool isValidFilePath(const string<StringCapacity>& name) noexcept;

} // namespace cxx
} // namespace iox

#include "iceoryx_hoofs/internal/cxx/helplets.inl"

#endif // IOX_HOOFS_CXX_HELPLETS_HPP
132 changes: 132 additions & 0 deletions iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/helplets.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_HOOFS_CXX_HELPLETS_INL
#define IOX_HOOFS_CXX_HELPLETS_INL

namespace iox
{
namespace cxx
{
template <uint64_t StringCapacity>
inline bool isValidFileName(const string<StringCapacity>& name) noexcept
{
if (name.empty())
{
return false;
}

uint64_t nameSize = name.size();

const string<StringCapacity> currentDirectory(".");
const string<StringCapacity> parentDirectory("..");

if (name == currentDirectory || name == parentDirectory)
{
return false;
}

// dot at the end is invalid to be compatible with windows api
const char lastCharacter = name.c_str()[nameSize - 1U];
if (lastCharacter == '.')
{
return false;
}

// check if the file contains only valid characters
for (uint64_t i = 0; i < nameSize; ++i)
{
const char c = name.c_str()[i];
if (!((internal::ASCII_A <= c && c <= internal::ASCII_Z)
|| (internal::ASCII_CAPITAL_A <= c && c <= internal::ASCII_CAPITAL_Z)
|| (internal::ASCII_0 <= c && c <= internal::ASCII_9) || c == internal::ASCII_MINUS
|| c == internal::ASCII_DOT || c == internal::ASCII_COLON || c == internal::ASCII_UNDERSCORE))
{
return false;
}
}

return true;
}

template <uint64_t StringCapacity>
inline bool isValidFilePath(const string<StringCapacity>& name) noexcept
{
if (name.empty())
{
return false;
}

uint64_t nameSize = name.size();

// a file path ends with the filename and not the path separator, only a
// directory can end with a path separator
auto numberOfPathSeparators = strlen(platform::IOX_PATH_SEPARATORS);
for (uint64_t i = 0; i < numberOfPathSeparators; ++i)
{
const char lastCharacter = name.c_str()[nameSize - 1U];
if (lastCharacter == platform::IOX_PATH_SEPARATORS[i])
{
return false;
}
}

auto temp = name;

const string<StringCapacity> currentDirectory(".");
const string<StringCapacity> parentDirectory("..");

while (!temp.empty())
{
auto separatorPosition = temp.find_first_of(platform::IOX_PATH_SEPARATORS);

// multiple slashes are explicitly allowed. the following paths
// are equivalent:
// /some/fuu/bar
// //some///fuu////bar
if (separatorPosition && *separatorPosition == 0)
{
temp = *temp.substr(*separatorPosition + 1);
continue;
}

// verify if the entry between two path separators is a valid directory
// name, e.g. either it has the relative component . or .. or conforms
// with a valid file name
if (separatorPosition)
{
auto filenameToVerify = temp.substr(0, *separatorPosition);
bool isValidDirectory = isValidFileName(*filenameToVerify) || *filenameToVerify == currentDirectory
|| *filenameToVerify == parentDirectory;
if (!isValidDirectory)
{
return false;
}

temp = *temp.substr(*separatorPosition + 1);
}
// we reached the last entry, if its a valid file name the path is valid
else if (!separatorPosition)
{
return isValidFileName(temp);
}
}

return false;
}
} // namespace cxx
} // namespace iox

#endif
6 changes: 1 addition & 5 deletions iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/string.inl
Original file line number Diff line number Diff line change
Expand Up @@ -512,11 +512,7 @@ inline iox::cxx::optional<string<Capacity>> string<Capacity>::substr(const uint6
return iox::cxx::nullopt;
}

uint64_t length = count;
if (m_rawstringSize < (pos + count))
{
length = m_rawstringSize - pos;
}
uint64_t length = std::min(count, m_rawstringSize - pos);
string subString;
std::memcpy(&(subString.m_rawstring[0]), &m_rawstring[pos], length);
subString.m_rawstring[length] = '\0';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ static constexpr const char* ACCESS_MODE_STRING[] = {"AccessMode::READ_ONLY", "A
enum class OwnerShip : uint64_t
{
MINE = 0U,
OPEN_EXISTING = 1U
OPEN_EXISTING_SHM = 1U
};
static constexpr const char* OWNERSHIP_STRING[] = {"OwnerShip::MINE", "OwnerShip::OPEN_EXISTING"};
static constexpr const char* OWNERSHIP_STRING[] = {"OwnerShip::MINE", "OwnerShip::OPEN_EXISTING_SHM"};

enum class SharedMemoryError
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#include "iceoryx_hoofs/internal/posix_wrapper/ipc_channel.hpp"
#include "iceoryx_hoofs/internal/units/duration.hpp"
#include "iceoryx_hoofs/platform/fcntl.hpp"
#include "iceoryx_hoofs/platform/mqueue.hpp"
#include "iceoryx_hoofs/platform/platform_settings.hpp"
#include "iceoryx_hoofs/platform/socket.hpp"
#include "iceoryx_hoofs/platform/stat.hpp"
#include "iceoryx_hoofs/platform/un.hpp"

Expand All @@ -38,16 +39,13 @@ class UnixDomainSocket : public DesignPattern::Creation<UnixDomainSocket, IpcCha
{
};
static constexpr NoPathPrefix_t NoPathPrefix{};
static constexpr char PATH_PREFIX[] = "/tmp/";

static constexpr uint64_t NULL_TERMINATOR_SIZE = 1U;
/// @brief Max message size is on linux = 4096 and on mac os = 2048. To have
/// the same behavior on every platform we use 2048.
static constexpr uint64_t MAX_MESSAGE_SIZE = 2048U - NULL_TERMINATOR_SIZE;
/// @brief The name length is limited by the size of the sockaddr_un::sun_path buffer and the path prefix
static constexpr uint64_t MAX_MESSAGE_SIZE = platform::IOX_UDS_SOCKET_MAX_MESSAGE_SIZE - NULL_TERMINATOR_SIZE;
/// @brief The name length is limited by the size of the sockaddr_un::sun_path buffer and the IOX_SOCKET_PATH_PREFIX
static constexpr size_t LONGEST_VALID_NAME = sizeof(sockaddr_un::sun_path) - 1;

using UdsName_t = cxx::string<LONGEST_VALID_NAME>;
using Message_t = cxx::string<MAX_MESSAGE_SIZE>;

/// @brief for calling private constructor in create method
friend class DesignPattern::Creation<UnixDomainSocket, IpcChannelError>;
Expand Down Expand Up @@ -125,7 +123,6 @@ class UnixDomainSocket : public DesignPattern::Creation<UnixDomainSocket, IpcCha
const size_t maxMsgSize = MAX_MESSAGE_SIZE,
const uint64_t maxMsgNumber = 10U) noexcept;


/// @brief initializes the unix domain socket
/// @return IpcChannelError if error occured
cxx::expected<IpcChannelError> initalizeSocket() noexcept;
Expand All @@ -134,8 +131,6 @@ class UnixDomainSocket : public DesignPattern::Creation<UnixDomainSocket, IpcCha
/// @return IpcChannelError if error occured
IpcChannelError convertErrnoToIpcChannelError(const int32_t errnum) const noexcept;

static bool isNameValid(const UdsName_t& name) noexcept;

/// @brief Tries to close the file descriptor
/// @return IpcChannelError if error occured
cxx::expected<IpcChannelError> closeFileDescriptor() noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ class Duration
template <typename T>
static constexpr Duration fromDays(const T value) noexcept;

/// @brief Constructs a new Duration object of maximum allowed length. Useful for functions which should have an
/// "infinite" timeout.
static constexpr Duration max() noexcept;

/// @brief Constructs a new Duration object with a duration of zero
static constexpr Duration zero() noexcept;
// END CREATION FROM STATIC FUNCTIONS

// BEGIN CONSTRUCTORS AND ASSIGNMENT
Expand Down Expand Up @@ -313,9 +319,6 @@ class Duration
/// from public methods
static constexpr Duration createDuration(const Seconds_t seconds, const Nanoseconds_t nanoseconds) noexcept;

static constexpr Duration max() noexcept;
static constexpr Duration zero() noexcept;

private:
template <typename T, typename String>
static constexpr unsigned long long int positiveValueOrClampToZero(const T value, const String fromMethod) noexcept;
Expand Down
Loading

0 comments on commit 7697383

Please sign in to comment.