Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
U
UERANSIM
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
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
Libraries
UERANSIM
Commits
3a9c992b
Unverified
Commit
3a9c992b
authored
Dec 07, 2021
by
Ali Güngör
Committed by
GitHub
Dec 07, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #444 from louisroyer/ipv6-ran
Allow RLS to work over IPv6
parents
59c13021
801d2fb3
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
132 additions
and
24 deletions
+132
-24
src/gnb.cpp
src/gnb.cpp
+1
-1
src/lib/udp/server.cpp
src/lib/udp/server.cpp
+26
-8
src/lib/udp/server.hpp
src/lib/udp/server.hpp
+4
-3
src/utils/common.cpp
src/utils/common.cpp
+8
-6
src/utils/io.cpp
src/utils/io.cpp
+30
-0
src/utils/io.hpp
src/utils/io.hpp
+2
-0
src/utils/network.cpp
src/utils/network.cpp
+37
-4
src/utils/network.hpp
src/utils/network.hpp
+5
-2
src/utils/yaml_utils.cpp
src/utils/yaml_utils.cpp
+18
-0
src/utils/yaml_utils.hpp
src/utils/yaml_utils.hpp
+1
-0
No files found.
src/gnb.cpp
View file @
3a9c992b
...
...
@@ -48,7 +48,7 @@ static nr::gnb::GnbConfig *ReadConfigYaml()
result
->
gnbIdLength
=
yaml
::
GetInt32
(
config
,
"idLength"
,
22
,
32
);
result
->
tac
=
yaml
::
GetInt32
(
config
,
"tac"
,
0
,
0xFFFFFF
);
result
->
portalIp
=
yaml
::
GetIp
4
(
config
,
"linkIp"
);
result
->
portalIp
=
yaml
::
GetIp
(
config
,
"linkIp"
);
result
->
ngapIp
=
yaml
::
GetIp4
(
config
,
"ngapIp"
);
result
->
gtpIp
=
yaml
::
GetIp4
(
config
,
"gtpIp"
);
...
...
src/lib/udp/server.cpp
View file @
3a9c992b
...
...
@@ -9,31 +9,49 @@
#include "server.hpp"
#include <cstring>
#include <utils/common.hpp>
namespace
udp
{
UdpServer
::
UdpServer
()
:
socket
{
Socket
::
CreateUdp4
()
}
UdpServer
::
UdpServer
()
:
sockets
{
}
{
sockets
.
push_back
(
Socket
::
CreateUdp6
());
sockets
.
push_back
(
Socket
::
CreateUdp4
());
}
UdpServer
::
UdpServer
(
const
std
::
string
&
address
,
uint16_t
port
)
:
socket
{
Socket
::
CreateAndBindUdp
({
address
,
port
})
}
UdpServer
::
UdpServer
(
const
std
::
string
&
address
,
uint16_t
port
)
:
sockets
{
}
{
sockets
.
push_back
(
Socket
::
CreateAndBindUdp
({
address
,
port
}));
}
int
UdpServer
::
Receive
(
uint8_t
*
buffer
,
size_t
bufferSize
,
int
timeoutMs
,
InetAddress
&
outPeerAddress
)
const
int
UdpServer
::
Receive
(
uint8_t
*
buffer
,
size_t
bufferSize
,
int
timeoutMs
,
InetAddress
&
outPeerAddress
)
{
return
socket
.
receive
(
buffer
,
bufferSize
,
timeoutMs
,
outPeerAddress
);
// Choose at random a ready socket for receiving data
std
::
vector
<
Socket
>
ws
;
return
Socket
::
Select
(
sockets
,
ws
,
timeoutMs
).
receive
(
buffer
,
bufferSize
,
0
,
outPeerAddress
);
}
void
UdpServer
::
Send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
bufferSize
)
const
int
UdpServer
::
Send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
bufferSize
)
const
{
socket
.
send
(
address
,
buffer
,
bufferSize
);
int
version
=
address
.
getIpVersion
();
// invalid family
if
(
!
version
)
return
-
1
;
// send on first socket matching ip version
for
(
const
Socket
&
s
:
sockets
)
{
if
(
s
.
getIpVersion
()
==
version
)
return
s
.
send
(
address
,
buffer
,
bufferSize
);
}
// no socket found
return
-
1
;
}
UdpServer
::~
UdpServer
()
{
socket
.
close
();
for
(
Socket
&
s
:
sockets
)
s
.
close
();
}
}
// namespace udp
\ No newline at end of file
}
// namespace udp
src/lib/udp/server.hpp
View file @
3a9c992b
...
...
@@ -9,6 +9,7 @@
#pragma once
#include <string>
#include <unistd.h>
#include <utils/network.hpp>
...
...
@@ -18,15 +19,15 @@ namespace udp
class
UdpServer
{
private:
Socket
socket
;
std
::
vector
<
Socket
>
sockets
;
public:
UdpServer
();
UdpServer
(
const
std
::
string
&
address
,
uint16_t
port
);
~
UdpServer
();
int
Receive
(
uint8_t
*
buffer
,
size_t
bufferSize
,
int
timeoutMs
,
InetAddress
&
outPeerAddress
)
const
;
void
Send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
bufferSize
)
const
;
int
Receive
(
uint8_t
*
buffer
,
size_t
bufferSize
,
int
timeoutMs
,
InetAddress
&
outPeerAddress
);
int
Send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
bufferSize
)
const
;
};
}
// namespace udp
src/utils/common.cpp
View file @
3a9c992b
...
...
@@ -30,7 +30,7 @@ static_assert(sizeof(long long) == sizeof(uint64_t));
static
std
::
atomic
<
int
>
g_idCounter
=
1
;
static
bool
IPv6FromString
(
const
char
*
szAddress
,
uint8_t
*
address
)
static
bool
IPv6FromString
(
const
char
*
szAddress
,
std
::
vector
<
uint8_t
>&
address
)
{
auto
asciiToHex
=
[](
char
c
)
->
int
{
c
|=
0x20
;
...
...
@@ -46,7 +46,9 @@ static bool IPv6FromString(const char *szAddress, uint8_t *address)
uint8_t
colons
=
0
;
uint8_t
pos
=
0
;
memset
(
address
,
0
,
16
);
address
.
clear
();
std
::
vector
<
uint8_t
>
emptyAddress
{
16
};
address
.
insert
(
address
.
begin
(),
emptyAddress
.
begin
(),
emptyAddress
.
end
());
for
(
uint8_t
i
=
1
;
i
<=
39
;
i
++
)
{
...
...
@@ -60,12 +62,12 @@ static bool IPv6FromString(const char *szAddress, uint8_t *address)
else
if
(
szAddress
[
i
]
==
'\0'
)
break
;
}
for
(
uint8_t
i
=
0
;
i
<=
39
&&
pos
<
16
;
i
++
)
for
(
uint8_t
i
=
0
;
i
<=
39
&&
pos
<
address
.
size
()
;
i
++
)
{
if
(
szAddress
[
i
]
==
':'
||
szAddress
[
i
]
==
'\0'
)
{
address
[
pos
]
=
acc
>>
8
;
address
[
pos
+
1
]
=
acc
;
address
.
at
(
pos
)
=
acc
>>
8
;
address
.
at
(
pos
+
1
)
=
acc
;
acc
=
0
;
if
(
colons
&&
i
&&
szAddress
[
i
-
1
]
==
':'
)
...
...
@@ -197,7 +199,7 @@ OctetString utils::IpToOctetString(const std::string &address)
else
if
(
ipVersion
==
6
)
{
std
::
vector
<
uint8_t
>
data
{
16
};
if
(
!
IPv6FromString
(
address
.
c_str
(),
data
.
data
()
))
if
(
!
IPv6FromString
(
address
.
c_str
(),
data
))
return
{};
return
OctetString
(
std
::
move
(
data
));
}
...
...
src/utils/io.cpp
View file @
3a9c992b
...
...
@@ -219,6 +219,36 @@ std::string GetIp4OfInterface(const std::string &ifName)
return
std
::
string
{
str
};
}
std
::
string
GetIp6OfInterface
(
const
std
::
string
&
ifName
)
{
std
::
string
res
;
struct
ifreq
ifr
=
{};
int
fd
=
socket
(
AF_INET6
,
SOCK_DGRAM
,
0
);
if
(
fd
<=
0
)
return
""
;
ifr
.
ifr_addr
.
sa_family
=
AF_INET6
;
strncpy
(
ifr
.
ifr_name
,
ifName
.
c_str
(),
IFNAMSIZ
-
1
);
if
(
ioctl
(
fd
,
SIOCGIFADDR
,
&
ifr
))
{
close
(
fd
);
return
""
;
}
close
(
fd
);
auto
address
=
((
struct
sockaddr_in
*
)
&
ifr
.
ifr_addr
)
->
sin_addr
;
char
str
[
INET6_ADDRSTRLEN
]
=
{
0
};
if
(
inet_ntop
(
AF_INET6
,
&
address
,
str
,
INET6_ADDRSTRLEN
)
==
nullptr
)
return
""
;
return
std
::
string
{
str
};
}
std
::
string
GetHostByName
(
const
std
::
string
&
name
)
{
struct
addrinfo
hints
=
{};
...
...
src/utils/io.hpp
View file @
3a9c992b
...
...
@@ -42,6 +42,8 @@ void AppendPath(std::string &source, const std::string &target);
std
::
string
GetIp4OfInterface
(
const
std
::
string
&
ifName
);
std
::
string
GetIp6OfInterface
(
const
std
::
string
&
ifName
);
std
::
string
GetHostByName
(
const
std
::
string
&
name
);
}
// namespace io
src/utils/network.cpp
View file @
3a9c992b
...
...
@@ -13,6 +13,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <random>
#include <stdexcept>
#include <sys/socket.h>
#include <sys/types.h>
...
...
@@ -78,7 +79,7 @@ InetAddress::InetAddress(const std::string &address, uint16_t port) : storage{},
if
(
s
!=
0
)
throw
LibError
(
"Bad Inet address: "
+
address
,
errno
);
if
(
result
->
ai_family
!=
AF_INET
&&
result
->
ai_family
=
=
AF_INET6
)
if
(
result
->
ai_family
!=
AF_INET
&&
result
->
ai_family
!
=
AF_INET6
)
{
freeaddrinfo
(
result
);
throw
std
::
runtime_error
(
"Bad Inet address: "
+
address
);
...
...
@@ -89,6 +90,16 @@ InetAddress::InetAddress(const std::string &address, uint16_t port) : storage{},
freeaddrinfo
(
result
);
}
int
InetAddress
::
getIpVersion
()
const
{
if
(
storage
.
ss_family
==
AF_INET
)
return
4
;
else
if
(
storage
.
ss_family
==
AF_INET6
)
return
6
;
else
return
0
;
}
InetAddress
::
InetAddress
(
const
OctetString
&
address
,
uint16_t
port
)
:
InetAddress
(
OctetStringToIpString
(
address
),
port
)
{
}
...
...
@@ -111,6 +122,7 @@ uint16_t InetAddress::getPort() const
Socket
::
Socket
(
int
domain
,
int
type
,
int
protocol
)
{
int
sd
=
socket
(
domain
,
type
,
protocol
);
socketDomain
=
domain
;
if
(
sd
<
0
)
throw
LibError
(
"Socket could not be created:"
,
errno
);
this
->
fd
=
sd
;
...
...
@@ -185,7 +197,7 @@ int Socket::receive(uint8_t *buffer, size_t bufferSize, int timeoutMs, InetAddre
return
0
;
}
void
Socket
::
send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
size
)
const
int
Socket
::
send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
size
)
const
{
ssize_t
rc
=
sendto
(
fd
,
buffer
,
size
,
MSG_DONTWAIT
,
address
.
getSockAddr
(),
address
.
getSockLen
());
if
(
rc
==
-
1
)
...
...
@@ -194,6 +206,7 @@ void Socket::send(const InetAddress &address, const uint8_t *buffer, size_t size
if
(
err
!=
EAGAIN
)
throw
LibError
(
"sendto failed: "
,
errno
);
}
return
rc
;
}
bool
Socket
::
hasFd
()
const
...
...
@@ -261,10 +274,20 @@ Socket Socket::Select(const std::vector<Socket> &readSockets, const std::vector<
std
::
vector
<
Socket
>
rs
,
ws
;
Select
(
readSockets
,
writeSockets
,
rs
,
ws
,
timeout
);
// Return a socket choosen at random from selection
// to avoid starvation
std
::
default_random_engine
generator
;
if
(
!
rs
.
empty
())
return
rs
[
0
];
{
std
::
uniform_int_distribution
<
int
>
drs
(
0
,
rs
.
size
()
-
1
);
return
rs
[
drs
(
generator
)];
}
if
(
!
ws
.
empty
())
return
rs
[
0
];
{
std
::
uniform_int_distribution
<
int
>
dws
(
0
,
ws
.
size
()
-
1
);
return
rs
[
dws
(
generator
)];
}
return
{};
}
...
...
@@ -297,3 +320,13 @@ InetAddress Socket::getAddress() const
return
{
storage
,
len
};
}
int
Socket
::
getIpVersion
()
const
{
if
(
socketDomain
==
AF_INET6
)
return
6
;
else
if
(
socketDomain
==
AF_INET
)
return
4
;
else
return
0
;
}
src/utils/network.hpp
View file @
3a9c992b
...
...
@@ -38,6 +38,7 @@ struct InetAddress
return
len
;
}
[[
nodiscard
]]
int
getIpVersion
()
const
;
[[
nodiscard
]]
uint16_t
getPort
()
const
;
};
...
...
@@ -45,6 +46,7 @@ class Socket
{
private:
int
fd
;
int
socketDomain
;
public:
Socket
();
...
...
@@ -53,10 +55,11 @@ class Socket
public:
void
bind
(
const
InetAddress
&
address
)
const
;
int
receive
(
uint8_t
*
buffer
,
size_t
bufferSize
,
int
timeoutMs
,
InetAddress
&
outAddress
)
const
;
void
send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
size
)
const
;
int
send
(
const
InetAddress
&
address
,
const
uint8_t
*
buffer
,
size_t
size
)
const
;
void
close
();
[[
nodiscard
]]
bool
hasFd
()
const
;
[[
nodiscard
]]
InetAddress
getAddress
()
const
;
[[
nodiscard
]]
int
getIpVersion
()
const
;
/* Socket options */
void
setReuseAddress
()
const
;
...
...
@@ -76,4 +79,4 @@ class Socket
int
timeout
=
0
);
static
bool
Select
(
const
Socket
&
socket
,
int
timeout
=
0
);
};
\ No newline at end of file
};
src/utils/yaml_utils.cpp
View file @
3a9c992b
...
...
@@ -158,6 +158,24 @@ std::string GetIp4(const YAML::Node &node, const std::string &name)
return
ipFromIf
;
}
std
::
string
GetIp
(
const
YAML
::
Node
&
node
,
const
std
::
string
&
name
)
{
std
::
string
s
=
GetString
(
node
,
name
);
int
version
=
utils
::
GetIpVersion
(
s
);
if
(
version
==
6
||
version
==
4
)
return
s
;
auto
ip4FromIf
=
io
::
GetIp4OfInterface
(
s
);
if
(
!
ip4FromIf
.
empty
())
return
ip4FromIf
;
auto
ip6FromIf
=
io
::
GetIp6OfInterface
(
s
);
if
(
!
ip6FromIf
.
empty
())
return
ip6FromIf
;
FieldError
(
name
,
"must be a valid IP address or a valid network interface with an IP address"
);
}
void
AssertHasBool
(
const
YAML
::
Node
&
node
,
const
std
::
string
&
name
)
{
AssertHasField
(
node
,
name
);
...
...
src/utils/yaml_utils.hpp
View file @
3a9c992b
...
...
@@ -42,6 +42,7 @@ std::string GetString(const YAML::Node &node, const std::string &name, std::opti
std
::
optional
<
int
>
maxLength
);
std
::
string
GetIp4
(
const
YAML
::
Node
&
node
,
const
std
::
string
&
name
);
std
::
string
GetIp
(
const
YAML
::
Node
&
node
,
const
std
::
string
&
name
);
bool
GetBool
(
const
YAML
::
Node
&
node
,
const
std
::
string
&
name
);
...
...
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