improved performance, minor bugfix
This commit is contained in:
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
BUILD=build
|
BUILD=build
|
||||||
INT=integrations
|
INT=integrations
|
||||||
ZT1=zerotierone
|
ZT1=zto
|
||||||
|
|
||||||
OSTYPE=$(shell uname -s)
|
OSTYPE=$(shell uname -s)
|
||||||
|
|
||||||
|
|||||||
70
objects.mk
70
objects.mk
@@ -1,36 +1,36 @@
|
|||||||
OBJS=\
|
OBJS=\
|
||||||
zerotierone/controller/EmbeddedNetworkController.o \
|
zto/controller/EmbeddedNetworkController.o \
|
||||||
zerotierone/controller/JSONDB.o \
|
zto/controller/JSONDB.o \
|
||||||
zerotierone/node/C25519.o \
|
zto/node/C25519.o \
|
||||||
zerotierone/node/Capability.o \
|
zto/node/Capability.o \
|
||||||
zerotierone/node/CertificateOfMembership.o \
|
zto/node/CertificateOfMembership.o \
|
||||||
zerotierone/node/CertificateOfOwnership.o \
|
zto/node/CertificateOfOwnership.o \
|
||||||
zerotierone/node/Cluster.o \
|
zto/node/Cluster.o \
|
||||||
zerotierone/node/Identity.o \
|
zto/node/Identity.o \
|
||||||
zerotierone/node/IncomingPacket.o \
|
zto/node/IncomingPacket.o \
|
||||||
zerotierone/node/InetAddress.o \
|
zto/node/InetAddress.o \
|
||||||
zerotierone/node/Membership.o \
|
zto/node/Membership.o \
|
||||||
zerotierone/node/Multicaster.o \
|
zto/node/Multicaster.o \
|
||||||
zerotierone/node/Network.o \
|
zto/node/Network.o \
|
||||||
zerotierone/node/NetworkConfig.o \
|
zto/node/NetworkConfig.o \
|
||||||
zerotierone/node/Node.o \
|
zto/node/Node.o \
|
||||||
zerotierone/node/OutboundMulticast.o \
|
zto/node/OutboundMulticast.o \
|
||||||
zerotierone/node/Packet.o \
|
zto/node/Packet.o \
|
||||||
zerotierone/node/Path.o \
|
zto/node/Path.o \
|
||||||
zerotierone/node/Peer.o \
|
zto/node/Peer.o \
|
||||||
zerotierone/node/Poly1305.o \
|
zto/node/Poly1305.o \
|
||||||
zerotierone/node/Revocation.o \
|
zto/node/Revocation.o \
|
||||||
zerotierone/node/Salsa20.o \
|
zto/node/Salsa20.o \
|
||||||
zerotierone/node/SelfAwareness.o \
|
zto/node/SelfAwareness.o \
|
||||||
zerotierone/node/SHA512.o \
|
zto/node/SHA512.o \
|
||||||
zerotierone/node/Switch.o \
|
zto/node/Switch.o \
|
||||||
zerotierone/node/Tag.o \
|
zto/node/Tag.o \
|
||||||
zerotierone/node/Topology.o \
|
zto/node/Topology.o \
|
||||||
zerotierone/node/Utils.o \
|
zto/node/Utils.o \
|
||||||
zerotierone/osdep/ManagedRoute.o \
|
zto/osdep/ManagedRoute.o \
|
||||||
zerotierone/osdep/Http.o \
|
zto/osdep/Http.o \
|
||||||
zerotierone/osdep/OSUtils.o \
|
zto/osdep/OSUtils.o \
|
||||||
zerotierone/service/ClusterGeoIpService.o \
|
zto/service/ClusterGeoIpService.o \
|
||||||
zerotierone/service/ControlPlane.o \
|
zto/service/SoftwareUpdater.o \
|
||||||
zerotierone/service/SoftwareUpdater.o \
|
zto/ext/http-parser/http_parser.o
|
||||||
zerotierone/ext/http-parser/http_parser.o
|
|
||||||
|
|||||||
27
src/debug.h
27
src/debug.h
@@ -26,11 +26,14 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifndef _SDK_DEBUG_H_
|
#ifndef _SDK_DEBUG_H_
|
||||||
#define _SDK_DEBUG_H_
|
#define _SDK_DEBUG_H_
|
||||||
|
|
||||||
#define DEBUG_LEVEL 5 // Set this to adjust what you'd like to see in the debug traces
|
#define DEBUG_LEVEL 1 // Set this to adjust what you'd like to see in the debug traces
|
||||||
|
|
||||||
#define MSG_ERROR 1 // Errors
|
#define MSG_ERROR 1 // Errors
|
||||||
#define MSG_TRANSFER 2 // RX/TX specific statements
|
#define MSG_TRANSFER 2 // RX/TX specific statements
|
||||||
@@ -80,6 +83,12 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#define THREAD_ID (long)getpid()
|
||||||
|
#elif __APPLE__
|
||||||
|
#define THREAD_ID (long)syscall(SYS_thread_selfid)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
@@ -88,7 +97,7 @@ extern "C" {
|
|||||||
|
|
||||||
//#if defined(SDK_DEBUG)
|
//#if defined(SDK_DEBUG)
|
||||||
#if DEBUG_LEVEL >= MSG_ERROR
|
#if DEBUG_LEVEL >= MSG_ERROR
|
||||||
#define DEBUG_ERROR(fmt, args...) fprintf(stderr, RED "ZT_ERROR: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_ERROR(fmt, args...) fprintf(stderr, RED "ZT_ERROR[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#else
|
#else
|
||||||
#define DEBUG_ERROR(fmt, args...)
|
#define DEBUG_ERROR(fmt, args...)
|
||||||
#endif
|
#endif
|
||||||
@@ -100,10 +109,10 @@ extern "C" {
|
|||||||
#define DEBUG_ATTN(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
#define DEBUG_ATTN(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
||||||
#define DEBUG_STACK(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_STACK: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
#define DEBUG_STACK(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_STACK: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
||||||
#else
|
#else
|
||||||
#define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_INFO(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#define DEBUG_ATTN(fmt, args...) fprintf(stderr, CYN "ZT_INFO : %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_ATTN(fmt, args...) fprintf(stderr, CYN "ZT_ATTN [%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#define DEBUG_STACK(fmt, args...) fprintf(stderr, YEL "ZT_STACK: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_STACK(fmt, args...) fprintf(stderr, YEL "ZT_STACK[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO : %14s:%4d:" fmt "\n", __FILENAME__, __LINE__, ##args)
|
#define DEBUG_BLANK(fmt, args...) fprintf(stderr, "ZT_INFO [%ld] : %14s:%4d:" fmt "\n", THREAD_ID, __FILENAME__, __LINE__, ##args)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_INFO(fmt, args...)
|
#define DEBUG_INFO(fmt, args...)
|
||||||
@@ -116,7 +125,7 @@ extern "C" {
|
|||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#define DEBUG_TRANS(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_TRANS : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
#define DEBUG_TRANS(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_TRANS : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
||||||
#else
|
#else
|
||||||
#define DEBUG_TRANS(fmt, args...) fprintf(stderr, GRN "ZT_TRANS: %14s:%4d:%25s: " fmt "\n" RESET, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_TRANS(fmt, args...) fprintf(stderr, GRN "ZT_TRANS[%ld] : %14s:%4d:%25s: " fmt "\n" RESET, THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_TRANS(fmt, args...)
|
#define DEBUG_TRANS(fmt, args...)
|
||||||
@@ -126,7 +135,7 @@ extern "C" {
|
|||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#define DEBUG_EXTRA(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_EXTRA : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
#define DEBUG_EXTRA(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_EXTRA : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EXTRA(fmt, args...) fprintf(stderr, "ZT_EXTRA: %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_EXTRA(fmt, args...) fprintf(stderr, "ZT_EXTRA[%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EXTRA(fmt, args...)
|
#define DEBUG_EXTRA(fmt, args...)
|
||||||
@@ -136,7 +145,7 @@ extern "C" {
|
|||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#define DEBUG_FLOW(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
#define DEBUG_FLOW(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args))
|
||||||
#else
|
#else
|
||||||
#define DEBUG_FLOW(fmt, args...) fprintf(stderr, "ZT_FLOW : %14s:%4d:%25s: " fmt "\n", __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
#define DEBUG_FLOW(fmt, args...) fprintf(stderr, "ZT_FLOW [%ld] : %14s:%4d:%25s: " fmt "\n", THREAD_ID, __FILENAME__, __LINE__, __FUNCTION__, ##args)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DEBUG_FLOW(fmt, args...)
|
#define DEBUG_FLOW(fmt, args...)
|
||||||
|
|||||||
22
src/defs.h
22
src/defs.h
@@ -25,22 +25,15 @@
|
|||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SDK_MTU ZT_MAX_MTU // 2800, usually
|
#define SDK_MTU 1200//ZT_MAX_MTU // 2800, usually
|
||||||
|
|
||||||
#define UNIX_SOCK_BUF_SIZE 1024*1024
|
#define UNIX_SOCK_BUF_SIZE 1024*1024
|
||||||
|
#define ZT_PHY_POLL_INTERVAL 50 // in ms
|
||||||
|
|
||||||
// --- lwIP
|
// picoTCP
|
||||||
#define APPLICATION_POLL_FREQ 2
|
|
||||||
#define ZT_LWIP_TCP_TIMER_INTERVAL 50
|
|
||||||
#define STATUS_TMR_INTERVAL 500 // How often we check connection statuses (in ms)
|
|
||||||
|
|
||||||
// --- picoTCP
|
|
||||||
#define MAX_PICO_FRAME_RX_BUF_SZ ZT_MAX_MTU * 128
|
#define MAX_PICO_FRAME_RX_BUF_SZ ZT_MAX_MTU * 128
|
||||||
|
|
||||||
// --- jip
|
// General
|
||||||
|
|
||||||
// --- General
|
|
||||||
|
|
||||||
// TCP Buffer sizes
|
// TCP Buffer sizes
|
||||||
#define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024
|
#define DEFAULT_TCP_TX_BUF_SZ 1024 * 1024
|
||||||
#define DEFAULT_TCP_RX_BUF_SZ 1024 * 1024
|
#define DEFAULT_TCP_RX_BUF_SZ 1024 * 1024
|
||||||
@@ -53,4 +46,9 @@
|
|||||||
|
|
||||||
// UDP Buffer sizes (should be about the size of your MTU)
|
// UDP Buffer sizes (should be about the size of your MTU)
|
||||||
#define DEFAULT_UDP_TX_BUF_SZ ZT_MAX_MTU
|
#define DEFAULT_UDP_TX_BUF_SZ ZT_MAX_MTU
|
||||||
#define DEFAULT_UDP_RX_BUF_SZ ZT_MAX_MTU * 10
|
#define DEFAULT_UDP_RX_BUF_SZ ZT_MAX_MTU * 10
|
||||||
|
|
||||||
|
// lwIP
|
||||||
|
#define APPLICATION_POLL_FREQ 2
|
||||||
|
#define ZT_LWIP_TCP_TIMER_INTERVAL 50
|
||||||
|
#define STATUS_TMR_INTERVAL 500 // How often we check connection statuses (in ms)
|
||||||
@@ -146,8 +146,10 @@ void zts_join_network_soft(const char * filepath, const char * nwid) {
|
|||||||
if(!ZeroTier::OSUtils::mkdir(net_dir)) {
|
if(!ZeroTier::OSUtils::mkdir(net_dir)) {
|
||||||
DEBUG_ERROR("unable to create: %s", net_dir.c_str());
|
DEBUG_ERROR("unable to create: %s", net_dir.c_str());
|
||||||
}
|
}
|
||||||
if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) {
|
if(!ZeroTier::OSUtils::fileExists(confFile.c_str(),false)) {
|
||||||
DEBUG_ERROR("unable to write network conf file: %s", confFile.c_str());
|
if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) {
|
||||||
|
DEBUG_ERROR("unable to write network conf file: %s", confFile.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -308,23 +308,27 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
ssize_t zts_recvfrom(RECVFROM_SIG)
|
ssize_t zts_recvfrom(RECVFROM_SIG)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int payload_offset, tmpsz=0, pnum=0; // payload size
|
int read_chunk_sz = 0, payload_offset, tmpsz=0, pnum=0; // payload size
|
||||||
char tmpbuf[SDK_MTU];
|
char tmpbuf[SDK_MTU];
|
||||||
memset(tmpbuf, 0, SDK_MTU);
|
memset(tmpbuf, 0, SDK_MTU);
|
||||||
|
|
||||||
// Attempt to read SDK_MTU sized chunk
|
// Attempt to read SDK_MTU sized chunk
|
||||||
int total_read = 0, n=0;
|
int total_read = 0, n=0;
|
||||||
//fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
||||||
|
// Read the entire SDK_MTU-sized chunk from the service socket
|
||||||
while(total_read < SDK_MTU) {
|
while(total_read < SDK_MTU) {
|
||||||
//DEBUG_ERROR(" READING...");
|
|
||||||
n = read(fd, tmpbuf+total_read, SDK_MTU);
|
n = read(fd, tmpbuf+total_read, SDK_MTU);
|
||||||
if(n>0)
|
if(n>0)
|
||||||
total_read += n;
|
total_read += n;
|
||||||
//DEBUG_ERROR(" R... (read=%d, total_read=%d, errno=%d)", n, total_read, errno);
|
else
|
||||||
if(n<0)
|
return n;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n > 0) {
|
if(n > 0) {
|
||||||
|
// No matter how much we read from the service, only copy 'read_chunk_sz'
|
||||||
|
// into the app's buffer
|
||||||
|
read_chunk_sz = len < SDK_MTU ? len : SDK_MTU;
|
||||||
|
|
||||||
// TODO: case for address size mismatch?
|
// TODO: case for address size mismatch?
|
||||||
memcpy(addr, tmpbuf, *addrlen);
|
memcpy(addr, tmpbuf, *addrlen);
|
||||||
memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz));
|
memcpy(&tmpsz, tmpbuf + sizeof(struct sockaddr_storage), sizeof(tmpsz));
|
||||||
@@ -334,13 +338,12 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
|
payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
|
||||||
memcpy(buf, tmpbuf + payload_offset, tmpsz);
|
memcpy(buf, tmpbuf + payload_offset, read_chunk_sz);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
perror("read:\n");
|
return -1;
|
||||||
}
|
}
|
||||||
//DEBUG_ERROR("recvfrom=%d", tmpsz);
|
return read_chunk_sz;
|
||||||
return tmpsz;
|
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
|||||||
@@ -39,20 +39,6 @@
|
|||||||
#include "pico_eth.h"
|
#include "pico_eth.h"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
// This may be removed in production
|
|
||||||
void check_buffer_states(Connection *conn)
|
|
||||||
{
|
|
||||||
#if defined(SDK_DEBUG)
|
|
||||||
if(conn->rxsz < 0) {
|
|
||||||
DEBUG_ERROR("conn->rxsz < 0");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if(conn->txsz < 0) {
|
|
||||||
DEBUG_ERROR("conn->txsz < 0");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reference to the tap interface
|
// Reference to the tap interface
|
||||||
// This is needed due to the fact that there's a lot going on in the tap interface
|
// This is needed due to the fact that there's a lot going on in the tap interface
|
||||||
@@ -120,19 +106,19 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// I/O thread loop
|
// Main stack loop
|
||||||
void pico_loop(NetconEthernetTap *tap)
|
void pico_loop(NetconEthernetTap *tap)
|
||||||
{
|
{
|
||||||
while(tap->_run)
|
while(tap->_run)
|
||||||
{
|
{
|
||||||
tap->_phy.poll(50); // in ms
|
tap->_phy.poll(ZT_PHY_POLL_INTERVAL); // in ms
|
||||||
//usleep(50);
|
|
||||||
tap->picostack->__pico_stack_tick();
|
tap->picostack->__pico_stack_tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RX packets from network onto internal buffer
|
// RX packets from [ZT->STACK] onto RXBUF
|
||||||
// Also notifies the tap service that data can be read
|
// Also notify the tap service that data can be read:
|
||||||
|
// [RXBUF -> (ZTSOCK->APP)]
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
// | |
|
// | |
|
||||||
@@ -142,8 +128,7 @@ namespace ZeroTier {
|
|||||||
// After this step, buffer will be emptied periodically by pico_handleRead()
|
// After this step, buffer will be emptied periodically by pico_handleRead()
|
||||||
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
// TODO: Verify
|
DEBUG_INFO();
|
||||||
// DEBUG_INFO("picosock=%p", s);
|
|
||||||
Connection *conn = tap->getConnection(s);
|
Connection *conn = tap->getConnection(s);
|
||||||
if(conn) {
|
if(conn) {
|
||||||
int r;
|
int r;
|
||||||
@@ -156,11 +141,9 @@ namespace ZeroTier {
|
|||||||
do {
|
do {
|
||||||
int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz;
|
int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz;
|
||||||
if(avail) {
|
if(avail) {
|
||||||
// r = tap->picostack->__pico_socket_read(s, conn->rxbuf + (conn->rxsz), SDK_MTU);
|
|
||||||
r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), SDK_MTU, (void *)&peer.ip4.addr, &port);
|
r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), SDK_MTU, (void *)&peer.ip4.addr, &port);
|
||||||
// DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(port));
|
// DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(port));
|
||||||
tap->_phy.setNotifyWritable(conn->sock, true);
|
tap->_phy.setNotifyWritable(conn->sock, true);
|
||||||
//DEBUG_EXTRA("read=%d", r);
|
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
conn->rxsz += r;
|
conn->rxsz += r;
|
||||||
}
|
}
|
||||||
@@ -173,7 +156,7 @@ namespace ZeroTier {
|
|||||||
DEBUG_ERROR("invalid connection");
|
DEBUG_ERROR("invalid connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
// RX packets from network onto internal buffer
|
// RX packets from the stack onto internal buffer
|
||||||
// Also notifies the tap service that data can be read
|
// Also notifies the tap service that data can be read
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
@@ -188,6 +171,8 @@ namespace ZeroTier {
|
|||||||
//
|
//
|
||||||
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
|
DEBUG_INFO();
|
||||||
|
|
||||||
Connection *conn = tap->getConnection(s);
|
Connection *conn = tap->getConnection(s);
|
||||||
if(conn) {
|
if(conn) {
|
||||||
|
|
||||||
@@ -212,11 +197,11 @@ namespace ZeroTier {
|
|||||||
// addr_in6.sin6_addr.s6_addr;
|
// addr_in6.sin6_addr.s6_addr;
|
||||||
// addr_in6.sin6_port = Utils::ntoh(s->remote_port);
|
// addr_in6.sin6_port = Utils::ntoh(s->remote_port);
|
||||||
// DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port));
|
// DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port));
|
||||||
|
|
||||||
picotap->_rx_buf_m.lock();
|
picotap->_rx_buf_m.lock();
|
||||||
|
|
||||||
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
|
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
|
||||||
DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
|
//DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
|
||||||
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
|
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
|
||||||
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); // TODO:
|
addr_pos = conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - SDK_MTU); // TODO:
|
||||||
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
|
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
|
||||||
@@ -241,9 +226,7 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
|
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
|
||||||
//DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r);
|
//DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r);
|
||||||
|
|
||||||
picotap->_rx_buf_m.unlock();
|
picotap->_rx_buf_m.unlock();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -279,6 +262,7 @@ namespace ZeroTier {
|
|||||||
// Main callback for TCP connections
|
// Main callback for TCP connections
|
||||||
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
|
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
|
DEBUG_INFO();
|
||||||
int err;
|
int err;
|
||||||
Mutex::Lock _l(picotap->_tcpconns_m);
|
Mutex::Lock _l(picotap->_tcpconns_m);
|
||||||
Connection *conn = picotap->getConnection(s);
|
Connection *conn = picotap->getConnection(s);
|
||||||
@@ -392,14 +376,10 @@ namespace ZeroTier {
|
|||||||
// It will then periodically be transfered into the network stack via pico_eth_poll()
|
// It will then periodically be transfered into the network stack via pico_eth_poll()
|
||||||
void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
|
void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
//DEBUG_INFO("len=%d", len);
|
DEBUG_INFO();
|
||||||
// Since picoTCP only allows the reception of frames from within the polling function, we
|
// Since picoTCP only allows the reception of frames from within the polling function, we
|
||||||
// must enqueue each frame into a memory structure shared by both threads. This structure will
|
// must enqueue each frame into a memory structure shared by both threads. This structure will
|
||||||
Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
|
Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
|
||||||
//if(len != memcpy(pico_frame_rxbuf, data, len)) {
|
|
||||||
// DEBUG_ERROR("dropping packet (len = %d) - unable to copy contents of frame to RX frame buffer", len);
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// assemble new eth header
|
// assemble new eth header
|
||||||
struct pico_eth_hdr ethhdr;
|
struct pico_eth_hdr ethhdr;
|
||||||
@@ -425,8 +405,13 @@ namespace ZeroTier {
|
|||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), ðhdr, sizeof(ethhdr)); // new eth header
|
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), ðhdr, sizeof(ethhdr)); // new eth header
|
||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
|
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
|
||||||
tap->pico_frame_rxbuf_tot += newlen;
|
tap->pico_frame_rxbuf_tot += newlen;
|
||||||
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Moved FRAME(sz=%d) into FBUF(sz=%d), data_len=%d, ethhdr.proto=%d", newlen, picotap->pico_frame_rxbuf_tot, len, ethhdr.proto);
|
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Move FRAME(sz=%d) into FBUF(sz=%d), data_len=%d", newlen, picotap->pico_frame_rxbuf_tot, len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
char graph[GRAPH_BUF_SZ];
|
||||||
|
gengraph(&graph, GRAPH_BUF_SZ, '|', 0.6);
|
||||||
|
DEBUG_FLOW(graph);
|
||||||
|
*/
|
||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
@@ -445,7 +430,7 @@ namespace ZeroTier {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called periodically by the stack, this removes data from the locked memory buffer and feeds it into the stack.
|
// Called periodically by the stack, this removes data from the locked memory buffer (FBUF) and feeds it into the stack.
|
||||||
// A maximum of 'loop_score' frames can be processed in each call
|
// A maximum of 'loop_score' frames can be processed in each call
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
@@ -455,12 +440,13 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int pico_eth_poll(struct pico_device *dev, int loop_score)
|
int pico_eth_poll(struct pico_device *dev, int loop_score)
|
||||||
{
|
{
|
||||||
|
//DEBUG_ERROR();
|
||||||
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
|
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
|
||||||
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
|
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
|
||||||
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
|
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
|
||||||
unsigned char frame[SDK_MTU];
|
unsigned char frame[SDK_MTU];
|
||||||
int len;
|
int len;
|
||||||
while (picotap->pico_frame_rxbuf_tot > 0) {
|
while (picotap->pico_frame_rxbuf_tot > 0 && loop_score > 0) {
|
||||||
DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
|
DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
|
||||||
memset(frame, 0, sizeof(frame));
|
memset(frame, 0, sizeof(frame));
|
||||||
len = 0;
|
len = 0;
|
||||||
@@ -476,7 +462,6 @@ namespace ZeroTier {
|
|||||||
DEBUG_ERROR("Skipping frame of size (%d)",len);
|
DEBUG_ERROR("Skipping frame of size (%d)",len);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_score--;
|
loop_score--;
|
||||||
}
|
}
|
||||||
return loop_score;
|
return loop_score;
|
||||||
@@ -509,7 +494,7 @@ namespace ZeroTier {
|
|||||||
*uptr = newConn;
|
*uptr = newConn;
|
||||||
newConn->type = socket_rpc->socket_type;
|
newConn->type = socket_rpc->socket_type;
|
||||||
newConn->sock = sock;
|
newConn->sock = sock;
|
||||||
|
/*
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int sendbuff = UNIX_SOCK_BUF_SIZE;
|
int sendbuff = UNIX_SOCK_BUF_SIZE;
|
||||||
socklen_t optlen = sizeof(sendbuff);
|
socklen_t optlen = sizeof(sendbuff);
|
||||||
@@ -524,8 +509,8 @@ namespace ZeroTier {
|
|||||||
// Get buffer size
|
// Get buffer size
|
||||||
// optlen = sizeof(sendbuff);
|
// optlen = sizeof(sendbuff);
|
||||||
// res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
|
// res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
|
||||||
// DEBUG_ERROR("buflen=%d", sendbuff);
|
// DEBUG_INFO("buflen=%d", sendbuff);
|
||||||
|
*/
|
||||||
newConn->local_addr = NULL;
|
newConn->local_addr = NULL;
|
||||||
// newConn->peer_addr = NULL;
|
// newConn->peer_addr = NULL;
|
||||||
newConn->picosock = psock;
|
newConn->picosock = psock;
|
||||||
@@ -597,7 +582,6 @@ namespace ZeroTier {
|
|||||||
//DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
//DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
||||||
// (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
|
// (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
|
||||||
}
|
}
|
||||||
check_buffer_states(conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instructs the stack to connect to a remote host
|
// Instructs the stack to connect to a remote host
|
||||||
@@ -713,6 +697,7 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Feeds data into the local app socket from the I/O buffer associated with the "connection"
|
// Feeds data into the local app socket from the I/O buffer associated with the "connection"
|
||||||
|
// [ (APP<-ZTSOCK) <- RXBUF ]
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
// | TAP <-> MEM BUFFER <-> STACK <-> APP |
|
||||||
// | |
|
// | |
|
||||||
@@ -721,33 +706,28 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
|
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR();
|
DEBUG_INFO();
|
||||||
if(!lwip_invoked) {
|
if(!lwip_invoked) {
|
||||||
|
// The stack thread writes to RXBUF as well
|
||||||
picotap->_tcpconns_m.lock();
|
picotap->_tcpconns_m.lock();
|
||||||
picotap->_rx_buf_m.lock();
|
picotap->_rx_buf_m.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tot = 0, n = -1;
|
||||||
|
|
||||||
Connection *conn = picotap->getConnection(sock);
|
Connection *conn = picotap->getConnection(sock);
|
||||||
if(conn && conn->rxsz) {
|
if(conn && conn->rxsz) {
|
||||||
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
|
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
|
||||||
int n = -1;
|
|
||||||
|
|
||||||
if(conn->type==SOCK_DGRAM) {
|
if(conn->type==SOCK_DGRAM) {
|
||||||
|
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] attempting write, RXBUF(%d)", conn->rxsz);
|
||||||
// DEBUG_ERROR("about to enter write loop, conn->sock=%p conn->rxsz=%d", conn->sock, conn->rxsz);
|
|
||||||
|
|
||||||
int pending = 0;
|
|
||||||
//ioctl(picotap->_phy.getDescriptor(conn->sock), SIOCOUTQ, &pending);
|
|
||||||
|
|
||||||
// Try to write SDK_MTU-sized chunk to app socket
|
// Try to write SDK_MTU-sized chunk to app socket
|
||||||
int total_written = 0;
|
while(tot < SDK_MTU) {
|
||||||
while(total_written < SDK_MTU) {
|
n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+tot, SDK_MTU);
|
||||||
//DEBUG_ERROR(" [ ZTSOCK <- RXBUF] WRITING.... (pending=%d)", pending);
|
tot += n;
|
||||||
n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+total_written, SDK_MTU);
|
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] wrote = %d, total = %d", n, tot);
|
||||||
total_written += n;
|
|
||||||
//DEBUG_ERROR(" [ ZTSOCK <- RXBUF] W... %d, written=%d, errno=%d", n, total_written, errno);
|
|
||||||
}
|
}
|
||||||
//DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
|
// DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
|
||||||
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
|
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
|
||||||
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int));
|
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int));
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
@@ -761,12 +741,10 @@ namespace ZeroTier {
|
|||||||
////conn->rxsz=SDK_MTU;
|
////conn->rxsz=SDK_MTU;
|
||||||
}
|
}
|
||||||
conn->rxsz -= SDK_MTU;
|
conn->rxsz -= SDK_MTU;
|
||||||
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] conn->rxsz=%d", conn->rxsz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->type==SOCK_STREAM) {
|
if(conn->type==SOCK_STREAM) {
|
||||||
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz);
|
n = picotap->_phy.streamSend(conn->sock, conn->rxbuf, conn->rxsz);
|
||||||
//DEBUG_EXTRA("SOCK_STREAM, conn=%p, physock=%p, n=%d", conn, sock, n);
|
|
||||||
if(conn->rxsz-n > 0) // If more remains on buffer
|
if(conn->rxsz-n > 0) // If more remains on buffer
|
||||||
memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n);
|
memcpy(conn->rxbuf, conn->rxbuf+n, conn->rxsz - n);
|
||||||
conn->rxsz -= n;
|
conn->rxsz -= n;
|
||||||
@@ -787,13 +765,12 @@ namespace ZeroTier {
|
|||||||
picotap->_phy.setNotifyWritable(sock, false);
|
picotap->_phy.setNotifyWritable(sock, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
picotap->_phy.whack();
|
//picotap->_phy.whack();
|
||||||
check_buffer_states(conn);
|
|
||||||
|
|
||||||
if(!lwip_invoked) {
|
if(!lwip_invoked) {
|
||||||
picotap->_tcpconns_m.unlock();
|
picotap->_tcpconns_m.unlock();
|
||||||
picotap->_rx_buf_m.unlock();
|
picotap->_rx_buf_m.unlock();
|
||||||
}
|
}
|
||||||
|
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Emitted (%d) from RXBUF(%d) to socket", tot, conn->rxsz);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closes a pico_socket
|
// Closes a pico_socket
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#define MAXBUF 65536
|
#define MAXBUF 65536
|
||||||
|
|
||||||
|
#define TESTBUF 1024
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int status, sock, portno, n;
|
int status, sock, portno, n;
|
||||||
@@ -45,16 +47,19 @@ int main(int argc, char* argv[])
|
|||||||
memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
|
memmove((char *) &serv_addr.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
|
||||||
serv_addr.sin6_port = htons(portno);
|
serv_addr.sin6_port = htons(portno);
|
||||||
|
|
||||||
sprintf(buffer,"Ciao");
|
sprintf(buffer,"Welcome to the machine");
|
||||||
|
//memset(buffer, 1, TESTBUF);
|
||||||
|
|
||||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
sleep(1);
|
//usleep(50000);
|
||||||
status = zts_sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
status = zts_sendto(sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||||
printf("Sent : %s \t%d\n", buffer, status);
|
if(status > 0)
|
||||||
|
printf("sendto() : %s \t%d\n", buffer, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(sock);
|
close(sock);
|
||||||
|
|
||||||
|
zts_stop(); /* Shut down ZT */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -52,14 +52,17 @@ int main(int argc, char *argv[])
|
|||||||
//n = getsockname(sock, (struct sockaddr *)&sin6, &sin6len);
|
//n = getsockname(sock, (struct sockaddr *)&sin6, &sin6len);
|
||||||
//printf("%d\n", ntohs(sin6.sin6_port));
|
//printf("%d\n", ntohs(sin6.sin6_port));
|
||||||
|
|
||||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
//fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||||
while (1) {
|
while (1) {
|
||||||
sleep(1);
|
//usleep(50000);
|
||||||
n = zts_recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len);
|
n = zts_recvfrom(sock, buffer, MAXBUF, 0, (struct sockaddr *)&sin6, &sin6len);
|
||||||
printf("n = %d, buffer : %s\n", n, buffer);
|
//if(n > 0)
|
||||||
|
printf("recvfrom(): n = %d, buffer : %s\n", n, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown(sock, 2);
|
shutdown(sock, 2);
|
||||||
close(sock);
|
close(sock);
|
||||||
|
|
||||||
|
zts_stop(); /* Shut down ZT */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user