Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gdamore/udp #1879

Merged
merged 6 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@ if (NOT WIN32 AND NOT CYGWIN)
endif ()
endif ()

# Detect endianness -- this only handles little and big endian.
# PDP users, sorry, but you're out of luck.'
if (DEFINED CMAKE_LANG_C_BYTE_ORDER)
if (CMAKE_LANG_BYTE_ORDER EQUAL BIG_ENDIAN)
add_definitions(-DNNG_BIG_ENDIAN=1)
else()
add_definitions(-DNNG_LITTLE_ENDIAN=1)
endif()
else()
include(TestBigEndian)
test_big_endian(NNG_BIG_ENDIAN)
if (NNG_BIG_ENDIAN)
add_definitions(-DNNG_BIG_EDNDIAN=1)
else()
add_definitions(-DNNG_LITTLE_ENDIAN=1)
endif()
endif()

if (CMAKE_SYSTEM_NAME MATCHES "Linux")
add_definitions(-DNNG_PLATFORM_POSIX)
add_definitions(-DNNG_PLATFORM_LINUX)
Expand Down
64 changes: 64 additions & 0 deletions src/core/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define CORE_DEFS_H

#include <stdint.h>
#include <stdbool.h>

// C compilers may get unhappy when named arguments are not used. While
// there are things like __attribute__((unused)) which are arguably
Expand Down Expand Up @@ -121,6 +122,54 @@ typedef void (*nni_cb)(void *);
(((uint64_t) ((uint8_t) (ptr)[6])) << 8u) + \
(((uint64_t) (uint8_t) (ptr)[7]))

// Modern CPUs are all little endian. Let's stop paying the endian tax.

#define NNI_PUT16LE(ptr, u) \
do { \
(ptr)[1] = (uint8_t) (((uint16_t) (u)) >> 8u); \
(ptr)[0] = (uint8_t) ((uint16_t) (u)); \
} while (0)

#define NNI_PUT32LE(ptr, u) \
do { \
(ptr)[3] = (uint8_t) (((uint32_t) (u)) >> 24u); \
(ptr)[2] = (uint8_t) (((uint32_t) (u)) >> 16u); \
(ptr)[1] = (uint8_t) (((uint32_t) (u)) >> 8u); \
(ptr)[0] = (uint8_t) ((uint32_t) (u)); \
} while (0)

#define NNI_PUT64LE(ptr, u) \
do { \
(ptr)[7] = (uint8_t) (((uint64_t) (u)) >> 56u); \
(ptr)[6] = (uint8_t) (((uint64_t) (u)) >> 48u); \
(ptr)[5] = (uint8_t) (((uint64_t) (u)) >> 40u); \
(ptr)[4] = (uint8_t) (((uint64_t) (u)) >> 32u); \
(ptr)[3] = (uint8_t) (((uint64_t) (u)) >> 24u); \
(ptr)[2] = (uint8_t) (((uint64_t) (u)) >> 16u); \
(ptr)[1] = (uint8_t) (((uint64_t) (u)) >> 8u); \
(ptr)[0] = (uint8_t) ((uint64_t) (u)); \
} while (0)

#define NNI_GET16LE(ptr, v) \
v = (((uint16_t) ((uint8_t) (ptr)[1])) << 8u) + \
(((uint16_t) (uint8_t) (ptr)[0]))

#define NNI_GET32LE(ptr, v) \
v = (((uint32_t) ((uint8_t) (ptr)[3])) << 24u) + \
(((uint32_t) ((uint8_t) (ptr)[2])) << 16u) + \
(((uint32_t) ((uint8_t) (ptr)[1])) << 8u) + \
(((uint32_t) (uint8_t) (ptr)[0]))

#define NNI_GET64LE(ptr, v) \
v = (((uint64_t) ((uint8_t) (ptr)[7])) << 56u) + \
(((uint64_t) ((uint8_t) (ptr)[6])) << 48u) + \
(((uint64_t) ((uint8_t) (ptr)[5])) << 40u) + \
(((uint64_t) ((uint8_t) (ptr)[4])) << 32u) + \
(((uint64_t) ((uint8_t) (ptr)[3])) << 24u) + \
(((uint64_t) ((uint8_t) (ptr)[2])) << 16u) + \
(((uint64_t) ((uint8_t) (ptr)[1])) << 8u) + \
(((uint64_t) (uint8_t) (ptr)[0]))

// This increments a pointer a fixed number of byte cells.
#define NNI_INCPTR(ptr, n) ((ptr) = (void *) ((char *) (ptr) + (n)))

Expand Down Expand Up @@ -178,4 +227,19 @@ typedef nni_type nni_opt_type;
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif

#if !defined(NNG_BIG_ENDIAN) && !defined(NNG_LITTLE_ENDIAN)
#if defined(__BYTE_ORDER__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define NNG_BIG_ENDIAN 1
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define NNG_LITTLE_ENDIAN 1
#else // middle-endian? (aka PDP-11)
#error "Unsupported or unknown endian"
#endif // __BYTE_ORDER__
#else // defined(__BYTE_ORDER__)
#define NNG_LITTLE_ENDIAN 1
#error "Unknown endian: specify -DNNG_BIG_ENDIAN=1 or -DNNG_LITTLE_ENDIAN=1"
#endif // defined(__BYTE_ORDER)
#endif // defined() endianness

#endif // CORE_DEFS_H
6 changes: 6 additions & 0 deletions src/core/idhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,9 @@
*cursor = index;
return (false);
}

uint32_t
nni_id_count(const nni_id_map *m)

Check warning on line 394 in src/core/idhash.c

View check run for this annotation

Codecov / codecov/patch

src/core/idhash.c#L394

Added line #L394 was not covered by tests
{
return (m->id_count);

Check warning on line 396 in src/core/idhash.c

View check run for this annotation

Codecov / codecov/patch

src/core/idhash.c#L396

Added line #L396 was not covered by tests
}
19 changes: 10 additions & 9 deletions src/core/idhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,16 @@ struct nni_id_map {
#define NNI_ID_FLAG_RANDOM 2 // start at a random value
#define NNI_ID_FLAG_REGISTER 4 // map is registered for finalization

extern void nni_id_map_init(nni_id_map *, uint64_t, uint64_t, bool);
extern void nni_id_map_fini(nni_id_map *);
extern void *nni_id_get(nni_id_map *, uint64_t);
extern int nni_id_set(nni_id_map *, uint64_t, void *);
extern int nni_id_alloc(nni_id_map *, uint64_t *, void *);
extern int nni_id_alloc32(nni_id_map *, uint32_t *, void *);
extern int nni_id_remove(nni_id_map *, uint64_t);
extern void nni_id_map_sys_fini(void);
extern bool nni_id_visit(nni_id_map *, uint64_t *, void **, uint32_t *);
extern void nni_id_map_init(nni_id_map *, uint64_t, uint64_t, bool);
extern void nni_id_map_fini(nni_id_map *);
extern void *nni_id_get(nni_id_map *, uint64_t);
extern int nni_id_set(nni_id_map *, uint64_t, void *);
extern int nni_id_alloc(nni_id_map *, uint64_t *, void *);
extern int nni_id_alloc32(nni_id_map *, uint32_t *, void *);
extern int nni_id_remove(nni_id_map *, uint64_t);
extern void nni_id_map_sys_fini(void);
extern bool nni_id_visit(nni_id_map *, uint64_t *, void **, uint32_t *);
extern uint32_t nni_id_count(const nni_id_map *);

#define NNI_ID_MAP_INITIALIZER(min, max, flags) \
{ \
Expand Down
13 changes: 13 additions & 0 deletions src/core/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
nni_chunk m_body;
uint32_t m_pipe; // set on receive
nni_atomic_int m_refcnt;
nng_sockaddr m_addr; // set on receive, transport use
};

#if 0
Expand Down Expand Up @@ -656,3 +657,15 @@
{
return (m->m_pipe);
}

const nng_sockaddr *
nni_msg_address(const nni_msg *msg)

Check warning on line 662 in src/core/message.c

View check run for this annotation

Codecov / codecov/patch

src/core/message.c#L662

Added line #L662 was not covered by tests
{
return (&msg->m_addr);

Check warning on line 664 in src/core/message.c

View check run for this annotation

Codecov / codecov/patch

src/core/message.c#L664

Added line #L664 was not covered by tests
}

void
nni_msg_set_address(nng_msg *msg, const nng_sockaddr *addr)

Check warning on line 668 in src/core/message.c

View check run for this annotation

Codecov / codecov/patch

src/core/message.c#L668

Added line #L668 was not covered by tests
{
msg->m_addr = *addr;

Check warning on line 670 in src/core/message.c

View check run for this annotation

Codecov / codecov/patch

src/core/message.c#L670

Added line #L670 was not covered by tests
}
12 changes: 10 additions & 2 deletions src/core/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ extern int nni_msg_realloc(nni_msg *, size_t);
extern int nni_msg_reserve(nni_msg *, size_t);
extern size_t nni_msg_capacity(nni_msg *);
extern int nni_msg_dup(nni_msg **, const nni_msg *);
extern void * nni_msg_header(nni_msg *);
extern void *nni_msg_header(nni_msg *);
extern size_t nni_msg_header_len(const nni_msg *);
extern void * nni_msg_body(nni_msg *);
extern void *nni_msg_body(nni_msg *);
extern size_t nni_msg_len(const nni_msg *);
extern int nni_msg_append(nni_msg *, const void *, size_t);
extern int nni_msg_insert(nni_msg *, const void *, size_t);
Expand Down Expand Up @@ -55,6 +55,14 @@ extern void nni_msg_clone(nni_msg *);
extern nni_msg *nni_msg_unique(nni_msg *);
extern bool nni_msg_shared(nni_msg *);

// Socket address access. Principally useful for transports like UDP,
// which may need to remember or add the socket address later.
// SP transports will generally not support upper layers setting the
// address on send, but will take the information from the pipe.
// It may be set on receive, depending upon the transport.
extern const nng_sockaddr *nni_msg_address(const nni_msg *);
extern void nni_msg_set_address(nng_msg *, const nng_sockaddr *);

// nni_msg_pull_up ensures that the message is unique, and that any
// header present is "pulled up" into the message body. If the function
// cannot do this for any reason (out of space in the body), then NULL
Expand Down
63 changes: 18 additions & 45 deletions src/core/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@

#include <nng/nng.h>

#include "core/nng_impl.h"
#include "core/tcp.h"
#include "core/url.h"
#include "nng_impl.h"
#include "tcp.h"

typedef struct {
nng_stream_dialer ops;
char * host;
char * port;
char *host;
char *port;
int af; // address family
bool closed;
nng_sockaddr sa;
nni_tcp_dialer * d; // platform dialer implementation
nni_aio * resaio; // resolver aio
nni_aio * conaio; // platform connection aio
nni_tcp_dialer *d; // platform dialer implementation
nni_aio *resaio; // resolver aio
nni_aio *conaio; // platform connection aio
nni_list conaios;
nni_mtx mtx;
} tcp_dialer;
Expand Down Expand Up @@ -62,7 +63,7 @@
tcp_dial_res_cb(void *arg)
{
tcp_dialer *d = arg;
nni_aio * aio;
nni_aio *aio;
int rv;

nni_mtx_lock(&d->mtx);
Expand Down Expand Up @@ -94,7 +95,7 @@
tcp_dial_con_cb(void *arg)
{
tcp_dialer *d = arg;
nng_aio * aio;
nng_aio *aio;
int rv;

nni_mtx_lock(&d->mtx);
Expand Down Expand Up @@ -124,7 +125,7 @@
tcp_dialer_close(void *arg)
{
tcp_dialer *d = arg;
nni_aio * aio;
nni_aio *aio;
nni_mtx_lock(&d->mtx);
d->closed = true;
while ((aio = nni_list_first(&d->conaios)) != NULL) {
Expand Down Expand Up @@ -186,8 +187,7 @@
}

static int
tcp_dialer_get(
void *arg, const char *name, void *buf, size_t *szp, nni_type t)
tcp_dialer_get(void *arg, const char *name, void *buf, size_t *szp, nni_type t)
{
tcp_dialer *d = arg;
return (nni_tcp_dialer_get(d->d, name, buf, szp, t));
Expand Down Expand Up @@ -238,10 +238,6 @@
int rv;
const char *p;

if ((rv = nni_init()) != 0) {
return (rv);
}

if ((rv = tcp_dialer_alloc(&d)) != 0) {
return (rv);
}
Expand Down Expand Up @@ -276,7 +272,7 @@

typedef struct {
nng_stream_listener ops;
nni_tcp_listener * l;
nni_tcp_listener *l;
nng_sockaddr sa;
} tcp_listener;

Expand Down Expand Up @@ -317,7 +313,7 @@
nng_sockaddr sa;
size_t sz;
int port;
uint8_t * paddr;
uint8_t *paddr;

sz = sizeof(sa);
rv = nni_tcp_listener_get(
Expand Down Expand Up @@ -373,6 +369,9 @@
tcp_listener *l;
int rv;

if ((rv = nni_init()) != 0) {
return (rv);

Check warning on line 373 in src/core/tcp.c

View check run for this annotation

Codecov / codecov/patch

src/core/tcp.c#L373

Added line #L373 was not covered by tests
}
if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
return (NNG_ENOMEM);
}
Expand All @@ -396,41 +395,15 @@
int
nni_tcp_listener_alloc(nng_stream_listener **lp, const nng_url *url)
{
nni_aio * aio;
int af;
int rv;
nng_sockaddr sa;
const char * h;

if ((rv = nni_init()) != 0) {
return (rv);
}
if (strchr(url->u_scheme, '4') != NULL) {
af = NNG_AF_INET;
} else if (strchr(url->u_scheme, '6') != NULL) {
af = NNG_AF_INET6;
} else {
af = NNG_AF_UNSPEC;
}

if ((rv = nng_aio_alloc(&aio, NULL, NULL)) != 0) {
return (rv);
}

h = url->u_hostname;

// Wildcard special case, which means bind to INADDR_ANY.
if ((h != NULL) && ((strcmp(h, "*") == 0) || (strcmp(h, "") == 0))) {
h = NULL;
}
nni_resolv_ip(h, url->u_port, af, true, &sa, aio);
nni_aio_wait(aio);

if ((rv = nni_aio_result(aio)) != 0) {
nni_aio_free(aio);
if ((rv = nni_url_to_address(&sa, url)) != 0) {
return (rv);
}
nni_aio_free(aio);

return (tcp_listener_alloc_addr(lp, &sa));
}
34 changes: 34 additions & 0 deletions src/core/url.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,3 +598,37 @@
}

#undef URL_COPYSTR

// nni_url_to_address resolves a URL into a sockaddr, assuming the URL is for
// an IP address.
int
nni_url_to_address(nng_sockaddr *sa, const nng_url *url)
{
int af;
nni_aio aio;
const char *h;
int rv;

// This assumes the scheme is one that uses TCP/IP addresses.

if (strchr(url->u_scheme, '4') != NULL) {
af = NNG_AF_INET;
} else if (strchr(url->u_scheme, '6') != NULL) {
af = NNG_AF_INET6;
} else {

Check warning on line 618 in src/core/url.c

View check run for this annotation

Codecov / codecov/patch

src/core/url.c#L617-L618

Added lines #L617 - L618 were not covered by tests
af = NNG_AF_UNSPEC;
}

nni_aio_init(&aio, NULL, NULL);

h = url->u_hostname;
if ((h != NULL) && ((strcmp(h, "*") == 0) || (strcmp(h, "") == 0))) {
h = NULL;
}

nni_resolv_ip(h, url->u_port, af, true, sa, &aio);
nni_aio_wait(&aio);
rv = nni_aio_result(&aio);
nni_aio_fini(&aio);
return (rv);
}
1 change: 1 addition & 0 deletions src/core/url.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ extern const char *nni_url_default_port(const char *);
extern int nni_url_asprintf(char **, const nni_url *);
extern int nni_url_asprintf_port(char **, const nni_url *, int);
extern size_t nni_url_decode(uint8_t *, const char *, size_t);
extern int nni_url_to_address(nng_sockaddr *, const nni_url *);

#endif // CORE_URL_H
Loading
Loading