Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
45cdea3d
Commit
45cdea3d
authored
Jun 29, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add IPv4 address abstraction
parent
316a7eeb
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
517 additions
and
0 deletions
+517
-0
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/byte_address.hpp
libcaf_core/caf/byte_address.hpp
+131
-0
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
+92
-0
libcaf_core/caf/ipv4_address.hpp
libcaf_core/caf/ipv4_address.hpp
+119
-0
libcaf_core/src/ipv4_address.cpp
libcaf_core/src/ipv4_address.cpp
+95
-0
libcaf_core/test/ipv4_address.cpp
libcaf_core/test/ipv4_address.cpp
+79
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
45cdea3d
...
@@ -65,6 +65,7 @@ set(LIBCAF_CORE_SRCS
...
@@ -65,6 +65,7 @@ set(LIBCAF_CORE_SRCS
src/inbound_path.cpp
src/inbound_path.cpp
src/ini_consumer.cpp
src/ini_consumer.cpp
src/invoke_result_visitor.cpp
src/invoke_result_visitor.cpp
src/ipv4_address.cpp
src/local_actor.cpp
src/local_actor.cpp
src/logger.cpp
src/logger.cpp
src/mailbox_element.cpp
src/mailbox_element.cpp
...
...
libcaf_core/caf/byte_address.hpp
0 → 100644
View file @
45cdea3d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstdint>
#include <cstring>
#include "caf/config.hpp"
#include "caf/detail/comparable.hpp"
namespace
caf
{
/// Base type for addresses based on a byte representation such as IP or
/// Ethernet addresses.
template
<
class
Derived
>
class
byte_address
:
detail
::
comparable
<
Derived
>
{
public:
// -- element access ---------------------------------------------------------
/// Returns the byte at given index.
uint8_t
&
operator
[](
size_t
index
)
noexcept
{
return
dref
().
bytes
()[
index
];
}
/// Returns the byte at given index.
const
uint8_t
&
operator
[](
size_t
index
)
const
noexcept
{
return
dref
().
bytes
()[
index
];
}
// -- comparison -------------------------------------------------------------
/// Returns a negative number if `*this < other`, zero if `*this == other`
/// and a positive number if `*this > other`.
int
compare
(
const
Derived
&
other
)
const
noexcept
{
auto
&
buf
=
dref
().
bytes
();
return
memcmp
(
buf
.
data
(),
other
.
bytes
().
data
(),
Derived
::
num_bytes
);
}
// -- mutators ---------------------------------------------------------------
/// Masks out lower bytes of the address. For example, calling `mask(1)` on
/// the IPv4 address `192.168.1.1` would produce `192.0.0.0`.
/// @pre `bytes_to_keep < num_bytes`
void
mask
(
int
bytes_to_keep
)
noexcept
{
auto
&
buf
=
dref
().
bytes
();
memset
(
buf
.
data
()
+
bytes_to_keep
,
0
,
Derived
::
num_bytes
-
bytes_to_keep
);
}
/// Returns a copy of this address with that masks out lower bytes. For
/// example, calling `masked(1)` on the IPv4 address `192.168.1.1` would
/// return `192.0.0.0`.
/// @pre `bytes_to_keep < num_bytes`
Derived
masked
(
int
bytes_to_keep
)
const
noexcept
{
Derived
result
{
dref
()};
result
.
mask
(
bytes_to_keep
);
return
result
;
}
// -- bitwise member operators -----------------------------------------------
/// Bitwise ANDs `*this` and `other`.
Derived
&
operator
&=
(
const
Derived
&
other
)
{
auto
&
buf
=
dref
().
bytes
();
for
(
size_t
index
=
0
;
index
<
Derived
::
num_bytes
;
++
index
)
buf
[
index
]
&=
other
[
index
];
return
dref
();
}
/// Bitwise ORs `*this` and `other`.
Derived
&
operator
|=
(
const
Derived
&
other
)
{
auto
&
buf
=
dref
().
bytes
();
for
(
size_t
index
=
0
;
index
<
Derived
::
num_bytes
;
++
index
)
buf
[
index
]
|=
other
[
index
];
return
dref
();
}
/// Bitwise XORs `*this` and `other`.
Derived
&
operator
^=
(
const
Derived
&
other
)
{
auto
&
buf
=
dref
().
bytes
();
for
(
size_t
index
=
0
;
index
<
Derived
::
num_bytes
;
++
index
)
buf
[
index
]
^=
other
[
index
];
return
dref
();
}
// -- bitwise free operators -------------------------------------------------
friend
Derived
operator
&
(
const
Derived
&
x
,
const
Derived
&
y
)
{
Derived
result
{
x
};
result
&=
y
;
return
result
;
}
friend
Derived
operator
|
(
const
Derived
&
x
,
const
Derived
&
y
)
{
Derived
result
{
x
};
result
|=
y
;
return
result
;
}
friend
Derived
operator
^
(
const
Derived
&
x
,
const
Derived
&
y
)
{
Derived
result
{
x
};
result
^=
y
;
return
result
;
}
private:
Derived
&
dref
()
noexcept
{
return
*
static_cast
<
Derived
*>
(
this
);
}
const
Derived
&
dref
()
const
noexcept
{
return
*
static_cast
<
const
Derived
*>
(
this
);
}
};
}
// namespace caf
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
0 → 100644
View file @
45cdea3d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstdint>
#include "caf/config.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/add_ascii.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
CAF_PUSH_UNUSED_LABEL_WARNING
#include "caf/detail/parser/fsm.hpp"
namespace
caf
{
namespace
detail
{
namespace
parser
{
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ipv4_octet
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
)
{
uint8_t
res
=
0
;
// Reads the a decimal place.
auto
rd_decimal
=
[
&
](
char
c
)
{
return
add_ascii
<
10
>
(
res
,
c
);
};
// Computes the result on success.
auto
g
=
caf
::
detail
::
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
consumer
.
value
(
res
);
});
start
();
state
(
init
)
{
transition
(
read
,
decimal_chars
,
rd_decimal
(
ch
),
pec
::
integer_overflow
)
}
term_state
(
read
)
{
transition
(
read
,
decimal_chars
,
rd_decimal
(
ch
),
pec
::
integer_overflow
)
}
fin
();
}
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
void
read_ipv4_address
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&
consumer
)
{
int
octets
=
0
;
start
();
state
(
init
)
{
fsm_epsilon
(
read_ipv4_octet
(
ps
,
consumer
),
rd_dot
,
decimal_chars
,
++
octets
)
}
state
(
rd_dot
)
{
transition
(
rd_oct
,
'.'
)
}
state
(
rd_oct
)
{
fsm_epsilon_if
(
octets
<
3
,
read_ipv4_octet
(
ps
,
consumer
),
rd_dot
,
decimal_chars
,
++
octets
)
fsm_epsilon_if
(
octets
==
3
,
read_ipv4_octet
(
ps
,
consumer
),
done
)
}
term_state
(
done
)
{
// nop
}
fin
();
}
}
// namespace parser
}
// namespace detail
}
// namespace caf
#include "caf/detail/parser/fsm_undef.hpp"
CAF_POP_WARNINGS
libcaf_core/caf/ipv4_address.hpp
0 → 100644
View file @
45cdea3d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <array>
#include <cstdint>
#include <string>
#include "caf/byte_address.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/fwd.hpp"
namespace
caf
{
class
ipv4_address
:
public
byte_address
<
ipv4_address
>
,
detail
::
comparable
<
ipv4_address
,
ipv6_address
>
{
public:
// -- constants --------------------------------------------------------------
static
constexpr
size_t
num_bytes
=
4
;
// -- member types -----------------------------------------------------------
using
super
=
byte_address
<
ipv4_address
>
;
using
array_type
=
std
::
array
<
uint8_t
,
num_bytes
>
;
// -- constructors, destructors, and assignment operators --------------------
ipv4_address
();
ipv4_address
(
array_type
bytes
);
// -- comparison -------------------------------------------------------------
using
super
::
compare
;
/// Returns a negative number if `*this < other`, zero if `*this == other`
/// and a positive number if `*this > other`.
int
compare
(
const
ipv6_address
&
other
)
const
noexcept
;
// -- properties -------------------------------------------------------------
/// Returns whether this is a loopback address.
bool
is_loopback
()
const
noexcept
;
/// Returns whether this is a multicast address.
bool
is_multicast
()
const
noexcept
;
/// Returns the bits of the IP address in a single integer.
inline
uint32_t
bits
()
const
noexcept
{
return
bits_
;
}
/// Returns the bytes of the IP address as array.
inline
array_type
&
bytes
()
noexcept
{
return
bytes_
;
}
/// Returns the bytes of the IP address as array.
inline
const
array_type
&
bytes
()
const
noexcept
{
return
bytes_
;
}
/// Alias for `bytes()`.
inline
array_type
&
data
()
noexcept
{
return
bytes_
;
}
/// Alias for `bytes()`.
inline
const
array_type
&
data
()
const
noexcept
{
return
bytes_
;
}
constexpr
size_t
size
()
const
noexcept
{
return
bytes_
.
size
();
}
private:
// -- member variables -------------------------------------------------------
union
{
uint32_t
bits_
;
array_type
bytes_
;
};
// -- sanity checks ----------------------------------------------------------
static_assert
(
sizeof
(
array_type
)
==
sizeof
(
uint32_t
),
"array<char, 4> has a different size than uint32"
);
};
// -- related free functions ---------------------------------------------------
/// Returns a human-readable string representation of the address.
/// @relates ipv4_address
std
::
string
to_string
(
const
ipv4_address
&
x
);
/// Tries to parse the content of `str` into `dest`.
/// @relates ipv4_address
error
parse
(
string_view
str
,
ipv4_address
&
dest
);
}
// namespace caf
libcaf_core/src/ipv4_address.cpp
0 → 100644
View file @
45cdea3d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/ipv4_address.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/detail/parser/read_ipv4_address.hpp"
#include "caf/error.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
namespace
{
inline
uint32_t
net_order
(
uint32_t
value
)
{
return
detail
::
to_network_order
(
value
);
}
struct
ipv4_address_consumer
{
size_t
pos
;
ipv4_address
&
dest
;
ipv4_address_consumer
(
ipv4_address
&
ref
)
:
pos
(
0
),
dest
(
ref
)
{
// nop
}
void
value
(
uint8_t
octet
)
{
dest
[
pos
++
]
=
octet
;
}
};
}
// namespace <anonymous>
// -- constructors, destructors, and assignment operators ----------------------
ipv4_address
::
ipv4_address
()
{
bits_
=
0u
;
}
ipv4_address
::
ipv4_address
(
array_type
bytes
)
{
memcpy
(
bytes_
.
data
(),
bytes
.
data
(),
bytes
.
size
());
}
// -- properties ---------------------------------------------------------------
bool
ipv4_address
::
is_loopback
()
const
noexcept
{
// All addresses in 127.0.0.0/8 are considered loopback addresses.
return
(
bits_
&
net_order
(
0xFF000000
))
==
net_order
(
0x7F000000
);
}
bool
ipv4_address
::
is_multicast
()
const
noexcept
{
// All addresses in 224.0.0.0/8 are considered loopback addresses.
return
(
bits_
&
net_order
(
0xFF000000
))
==
net_order
(
0xE0000000
);
}
// -- related free functions ---------------------------------------------------
std
::
string
to_string
(
const
ipv4_address
&
x
)
{
using
std
::
to_string
;
std
::
string
result
;
result
+=
to_string
(
x
[
0
]);
for
(
size_t
i
=
1
;
i
<
x
.
data
().
size
();
++
i
)
{
result
+=
'.'
;
result
+=
to_string
(
x
[
i
]);
}
return
result
;
}
error
parse
(
string_view
str
,
ipv4_address
&
dest
)
{
using
namespace
detail
;
parser
::
state
<
string_view
::
iterator
>
res
{
str
.
begin
(),
str
.
end
()};
ipv4_address_consumer
f
{
dest
};
parser
::
read_ipv4_address
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
return
none
;
return
make_error
(
res
.
code
,
res
.
line
,
res
.
column
);
}
}
// namespace caf
libcaf_core/test/ipv4_address.cpp
0 → 100644
View file @
45cdea3d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE ipv4_address
#include "caf/test/dsl.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/detail/network_order.hpp"
using
caf
::
detail
::
to_network_order
;
using
namespace
caf
;
namespace
{
using
array_type
=
ipv4_address
::
array_type
;
ipv4_address
addr
(
uint8_t
oct1
,
uint8_t
oct2
,
uint8_t
oct3
,
uint8_t
oct4
)
{
return
ipv4_address
({
oct1
,
oct2
,
oct3
,
oct4
});
}
}
// namespace <anonymous>
CAF_TEST
(
constructing
)
{
ipv4_address
localhost
({
127
,
0
,
0
,
1
});
CAF_CHECK_EQUAL
(
localhost
.
bits
(),
to_network_order
(
0x7F000001u
));
CAF_CHECK_EQUAL
(
localhost
.
data
(),
array_type
({
127
,
0
,
0
,
1
}));
CAF_CHECK_EQUAL
(
ipv4_address
().
data
(),
array_type
({
0
,
0
,
0
,
0
}));
}
CAF_TEST
(
to
and
from
string
)
{
ipv4_address
x
;
auto
err
=
parse
(
"255.255.255.255"
,
x
);
CAF_CHECK_EQUAL
(
err
,
pec
::
success
);
CAF_CHECK_EQUAL
(
x
.
bits
(),
0xFFFFFFFF
);
CAF_CHECK_EQUAL
(
to_string
(
x
),
"255.255.255.255"
);
CAF_CHECK_EQUAL
(
x
,
addr
(
255
,
255
,
255
,
255
));
}
CAF_TEST
(
properties
)
{
CAF_CHECK_EQUAL
(
addr
(
127
,
0
,
0
,
1
).
is_loopback
(),
true
);
CAF_CHECK_EQUAL
(
addr
(
127
,
0
,
0
,
254
).
is_loopback
(),
true
);
CAF_CHECK_EQUAL
(
addr
(
127
,
0
,
1
,
1
).
is_loopback
(),
true
);
CAF_CHECK_EQUAL
(
addr
(
128
,
0
,
0
,
1
).
is_loopback
(),
false
);
CAF_CHECK_EQUAL
(
addr
(
224
,
0
,
0
,
1
).
is_multicast
(),
true
);
CAF_CHECK_EQUAL
(
addr
(
224
,
0
,
0
,
254
).
is_multicast
(),
true
);
CAF_CHECK_EQUAL
(
addr
(
224
,
0
,
1
,
1
).
is_multicast
(),
true
);
CAF_CHECK_EQUAL
(
addr
(
225
,
0
,
0
,
1
).
is_multicast
(),
false
);
CAF_CHECK_EQUAL
(
addr
(
1
,
2
,
3
,
4
).
masked
(
0
),
addr
(
0
,
0
,
0
,
0
));
CAF_CHECK_EQUAL
(
addr
(
1
,
2
,
3
,
4
).
masked
(
1
),
addr
(
1
,
0
,
0
,
0
));
CAF_CHECK_EQUAL
(
addr
(
1
,
2
,
3
,
4
).
masked
(
2
),
addr
(
1
,
2
,
0
,
0
));
CAF_CHECK_EQUAL
(
addr
(
1
,
2
,
3
,
4
).
masked
(
3
),
addr
(
1
,
2
,
3
,
0
));
CAF_CHECK_EQUAL
(
addr
(
1
,
2
,
3
,
4
).
masked
(
4
),
addr
(
1
,
2
,
3
,
4
));
}
CAF_TEST
(
operators
)
{
CAF_CHECK_EQUAL
(
addr
(
16
,
0
,
0
,
8
)
&
addr
(
255
,
2
,
4
,
6
),
addr
(
16
,
0
,
0
,
0
));
CAF_CHECK_EQUAL
(
addr
(
16
,
0
,
0
,
8
)
|
addr
(
255
,
2
,
4
,
6
),
addr
(
255
,
2
,
4
,
14
));
CAF_CHECK_EQUAL
(
addr
(
16
,
0
,
0
,
8
)
^
addr
(
255
,
2
,
4
,
6
),
addr
(
239
,
2
,
4
,
14
));
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment