aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-01-04 02:10:13 -0800
committerGarrett D'Amore <garrett@damore.org>2017-01-04 02:10:13 -0800
commit1d650869f32c56f6d49d898c38f7525191a60bd1 (patch)
tree7a27136068de192a3166ce40ea7a541f68be9d96 /src/core
parent856c5c8e2aa4e07b2b628dd194a63ae13dae7ae3 (diff)
downloadnng-1d650869f32c56f6d49d898c38f7525191a60bd1.tar.gz
nng-1d650869f32c56f6d49d898c38f7525191a60bd1.tar.bz2
nng-1d650869f32c56f6d49d898c38f7525191a60bd1.zip
Initial cut at TCP, totally untested beyond compilation.
This also adds checks in the protocols to verify that pipe peers are of the proper protocol.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/defs.h77
-rw-r--r--src/core/pipe.h2
-rw-r--r--src/core/platform.h38
-rw-r--r--src/core/transport.c2
4 files changed, 86 insertions, 33 deletions
diff --git a/src/core/defs.h b/src/core/defs.h
index be7f71f7..ed2e353f 100644
--- a/src/core/defs.h
+++ b/src/core/defs.h
@@ -52,43 +52,54 @@ typedef struct {
#define NNI_ALLOC_STRUCT(s) nni_alloc(sizeof (*s))
#define NNI_FREE_STRUCT(s) nni_free((s), sizeof (*s))
-#define NNI_PUT32(ptr, u) \
- do { \
- ptr[0] = (uint8_t) (((uint32_t) u) >> 24); \
- ptr[1] = (uint8_t) (((uint32_t) u) >> 16); \
- ptr[2] = (uint8_t) (((uint32_t) u) >> 8); \
- ptr[3] = (uint8_t) ((uint32_t) u); \
- } \
+#define NNI_PUT16(ptr, u) \
+ do { \
+ (ptr)[0] = (uint8_t) (((uint16_t) (u)) >> 8); \
+ (ptr)[0] = (uint8_t) ((uint16_t) (u)); \
+ } \
while (0)
-#define NNI_PUT64(ptr, u) \
- do { \
- ptr[0] = (uint8_t) (((uint64_t) u) >> 56); \
- ptr[1] = (uint8_t) (((uint64_t) u) >> 48); \
- ptr[2] = (uint8_t) (((uint64_t) u) >> 40); \
- ptr[3] = (uint8_t) (((uint64_t) u) >> 32); \
- ptr[4] = (uint8_t) (((uint64_t) u) >> 24); \
- ptr[5] = (uint8_t) (((uint64_t) u) >> 16); \
- ptr[6] = (uint8_t) (((uint64_t) u) >> 8); \
- ptr[7] = (uint8_t) ((uint64_t) u); \
- } \
+#define NNI_PUT32(ptr, u) \
+ do { \
+ (ptr)[0] = (uint8_t) (((uint32_t) (u)) >> 24); \
+ (ptr)[1] = (uint8_t) (((uint32_t) (u)) >> 16); \
+ (ptr)[2] = (uint8_t) (((uint32_t) (u)) >> 8); \
+ (ptr)[3] = (uint8_t) ((uint32_t) (u)); \
+ } \
while (0)
-#define NNI_GET32(ptr, v) \
- v = (((uint32_t) ((uint8_t) ptr[0])) << 24) + \
- (((uint32_t) ((uint8_t) ptr[1])) << 16) + \
- (((uint32_t) ((uint8_t) ptr[2])) << 8) + \
- (((uint32_t) (uint8_t) ptr[3]))
-
-#define NNI_GET64(ptr, v) \
- v = (((uint64_t) ((uint8_t) ptr[0])) << 56) + \
- (((uint64_t) ((uint8_t) ptr[1])) << 48) + \
- (((uint64_t) ((uint8_t) ptr[2])) << 40) + \
- (((uint64_t) ((uint8_t) ptr[3])) << 32) + \
- (((uint64_t) ((uint8_t) ptr[4])) << 24) + \
- (((uint64_t) ((uint8_t) ptr[5])) << 16) + \
- (((uint64_t) ((uint8_t) ptr[6])) << 8) + \
- (((uint64_t) (uint8_t) ptr[7]))
+#define NNI_PUT64(ptr, u) \
+ do { \
+ (ptr)[0] = (uint8_t) (((uint64_t) (u)) >> 56); \
+ (ptr)[1] = (uint8_t) (((uint64_t) (u)) >> 48); \
+ (ptr)[2] = (uint8_t) (((uint64_t) (u)) >> 40); \
+ (ptr)[3] = (uint8_t) (((uint64_t) (u)) >> 32); \
+ (ptr)[4] = (uint8_t) (((uint64_t) (u)) >> 24); \
+ (ptr)[5] = (uint8_t) (((uint64_t) (u)) >> 16); \
+ (ptr)[6] = (uint8_t) (((uint64_t) (u)) >> 8); \
+ (ptr)[7] = (uint8_t) ((uint64_t) (u)); \
+ } \
+ while (0)
+
+#define NNI_GET16(ptr, v) \
+ v = (((uint32_t) ((uint8_t) (ptr)[0])) << 8) + \
+ (((uint32_t) (uint8_t) (ptr)[1]))
+
+#define NNI_GET32(ptr, v) \
+ v = (((uint32_t) ((uint8_t) (ptr)[0])) << 24) + \
+ (((uint32_t) ((uint8_t) (ptr)[1])) << 16) + \
+ (((uint32_t) ((uint8_t) (ptr)[2])) << 8) + \
+ (((uint32_t) (uint8_t) (ptr)[3]))
+
+#define NNI_GET64(ptr, v) \
+ v = (((uint64_t) ((uint8_t) (ptr)[0])) << 56) + \
+ (((uint64_t) ((uint8_t) (ptr)[1])) << 48) + \
+ (((uint64_t) ((uint8_t) (ptr)[2])) << 40) + \
+ (((uint64_t) ((uint8_t) (ptr)[3])) << 32) + \
+ (((uint64_t) ((uint8_t) (ptr)[4])) << 24) + \
+ (((uint64_t) ((uint8_t) (ptr)[5])) << 16) + \
+ (((uint64_t) ((uint8_t) (ptr)[6])) << 8) + \
+ (((uint64_t) (uint8_t) (ptr)[7]))
// A few assorted other items.
#define NNI_FLAG_IPV4ONLY 1
diff --git a/src/core/pipe.h b/src/core/pipe.h
index a8d7b286..6ebb7090 100644
--- a/src/core/pipe.h
+++ b/src/core/pipe.h
@@ -44,6 +44,8 @@ extern int nni_pipe_create(nni_pipe **, nni_ep *);
extern void nni_pipe_destroy(nni_pipe *);
+extern uint16_t nni_pipe_proto(nni_pipe *);
+extern uint16_t nni_pipe_peer(nni_pipe *);
extern int nni_pipe_start(nni_pipe *);
extern int nni_pipe_getopt(nni_pipe *, int, void *, size_t *sizep);
diff --git a/src/core/platform.h b/src/core/platform.h
index 2134ed97..3292d6f9 100644
--- a/src/core/platform.h
+++ b/src/core/platform.h
@@ -63,6 +63,7 @@ extern void nni_free(void *, size_t);
typedef struct nni_plat_mtx nni_plat_mtx;
typedef struct nni_plat_cv nni_plat_cv;
typedef struct nni_plat_thr nni_plat_thr;
+typedef struct nni_plat_tcpsock nni_plat_tcpsock;
// Mutex handling.
@@ -166,6 +167,43 @@ extern uint32_t nni_plat_nextid(void);
// used.)
extern const char *nni_plat_strerror(int);
+// nni_plat_lookup_host looks up a hostname in DNS, or the local hosts
+// file, or whatever. If your platform lacks support for naming, it must
+// at least cope with converting IP addresses in string form. The final
+// flags may include NNI_FLAG_IPV4ONLY to prevent IPv6 names from being
+// returned on dual stack machines.
+extern int nni_plat_lookup_host(const char *, nni_sockaddr *, int);
+
+// nni_plat_tcp_close just closes a TCP socket.
+extern void nni_plat_tcp_close(nni_plat_tcpsock *);
+
+// nni_plat_tcp_listen creates a TCP socket in listening mode, bound
+// to the specified address. Note that nni_plat_tcpsock should be defined
+// to whatever your platform uses. For most systems its just "int".
+extern int nni_plat_tcp_listen(nni_plat_tcpsock *, const nni_sockaddr *);
+
+// nni_plat_tcp_accept does the accept to accept an inbound connection.
+// The tcpsock used for the server will have been set up with the
+// nni_plat_tcp_listen.
+extern int nni_plat_tcp_accept(nni_plat_tcpsock *, nni_plat_tcpsock *);
+
+// nni_plat_tcp_connect is the client side. Two addresses are supplied,
+// as the client may specify a local address to which to bind. This
+// second address may be NULL to use ephemeral ports, which is the
+// usual default.
+extern int nni_plat_tcp_connect(nni_plat_tcpsock *, const nni_sockaddr *,
+ const nni_sockaddr *);
+
+// nni_plat_tcp_send sends data to the remote side. The platform is
+// responsible for attempting to send all of the data. The iov count
+// will never be larger than 4. THe platform may modify the iovs.
+extern int nni_plat_tcp_send(nni_plat_tcpsock *, nni_iov *, int);
+
+// nni_plat_tcp_recv recvs data into the buffers provided by the
+// iovs. The implementation does not return until the iovs are completely
+// full, or an error condition occurs.
+extern int nni_plat_tcp_recv(nni_plat_tcpsock *, nni_iov *, int);
+
// Actual platforms we support. This is included up front so that we can
// get the specific types that are supplied by the platform.
#if defined(PLATFORM_POSIX)
diff --git a/src/core/transport.c b/src/core/transport.c
index b6ebe3c2..cf9f38c3 100644
--- a/src/core/transport.c
+++ b/src/core/transport.c
@@ -14,9 +14,11 @@
// For now the list of transports is hard-wired. Adding new transports
// to the system dynamically is something that might be considered later.
extern nni_tran nni_inproc_tran;
+extern nni_tran nni_tcp_tran;
static nni_tran *transports[] = {
&nni_inproc_tran,
+ &nni_tcp_tran,
NULL
};