Improved proxy server controls
This commit is contained in:
@@ -85,7 +85,7 @@ extern char *debug_logfile;
|
|||||||
|
|
||||||
// NOTE: Each platform specific exposed API will be implemented in terms of zts_*
|
// NOTE: Each platform specific exposed API will be implemented in terms of zts_*
|
||||||
// SOCKS5 Proxy Controls
|
// SOCKS5 Proxy Controls
|
||||||
int zts_start_proxy_server(const char *nwid, struct sockaddr_storage *addr);
|
int zts_start_proxy_server(const char *homepath, const char * nwid, struct sockaddr_storage * addr);
|
||||||
int zts_stop_proxy_server(const char *nwid);
|
int zts_stop_proxy_server(const char *nwid);
|
||||||
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage *addr);
|
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage *addr);
|
||||||
// ZT Service Controls
|
// ZT Service Controls
|
||||||
|
|||||||
@@ -129,16 +129,10 @@ NetconEthernetTap::NetconEthernetTap(
|
|||||||
_enabled(true),
|
_enabled(true),
|
||||||
_run(true)
|
_run(true)
|
||||||
{
|
{
|
||||||
|
sockstate = -1;
|
||||||
char sockPath[4096],lwipPath[4096];
|
char sockPath[4096],lwipPath[4096];
|
||||||
Utils::snprintf(sockPath,sizeof(sockPath),"%s%snc_%.16llx",homePath,ZT_PATH_SEPARATOR_S,_nwid,ZT_PATH_SEPARATOR_S,(unsigned long long)nwid);
|
Utils::snprintf(sockPath,sizeof(sockPath),"%s%snc_%.16llx",homePath,ZT_PATH_SEPARATOR_S,_nwid,ZT_PATH_SEPARATOR_S,(unsigned long long)nwid);
|
||||||
_dev = sockPath; // in SDK mode, set device to be just the network ID
|
_dev = sockPath; // in SDK mode, set device to be just the network ID
|
||||||
|
|
||||||
// Start SOCKS5 Proxy server
|
|
||||||
// For use when traditional syscall hooking isn't available (ex. some APIs on iOS and Android)
|
|
||||||
#if defined(USE_SOCKS_PROXY)
|
|
||||||
StartProxy(sockPath, _homePath.c_str(), _nwid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Utils::snprintf(lwipPath,sizeof(lwipPath),"%s%sliblwip.so",homePath,ZT_PATH_SEPARATOR_S);
|
Utils::snprintf(lwipPath,sizeof(lwipPath),"%s%sliblwip.so",homePath,ZT_PATH_SEPARATOR_S);
|
||||||
|
|
||||||
lwipstack = new LWIPStack(lwipPath);
|
lwipstack = new LWIPStack(lwipPath);
|
||||||
@@ -1383,7 +1377,6 @@ void NetconEthernetTap::handleWrite(Connection *conn)
|
|||||||
if(buf_remaining)
|
if(buf_remaining)
|
||||||
memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining);
|
memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining);
|
||||||
conn->txsz -= udp_trans_len;
|
conn->txsz -= udp_trans_len;
|
||||||
int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ;
|
|
||||||
|
|
||||||
#if DEBUG_LEVEL >= MSG_TRANSFER
|
#if DEBUG_LEVEL >= MSG_TRANSFER
|
||||||
struct sockaddr_in * addr_in2 = (struct sockaddr_in *)conn->peer_addr;
|
struct sockaddr_in * addr_in2 = (struct sockaddr_in *)conn->peer_addr;
|
||||||
|
|||||||
@@ -155,7 +155,17 @@ namespace ZeroTier {
|
|||||||
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
|
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
|
||||||
void *_arg;
|
void *_arg;
|
||||||
|
|
||||||
int proxyListenPort;
|
// --- Proxy
|
||||||
|
struct sockaddr_storage proxyServerAddress;
|
||||||
|
int sockstate; // Use as flag to determine whether proxy has been started, TODO: Rename
|
||||||
|
int proxyListenSocket;
|
||||||
|
PhySocket *proxyListenPhySocket;
|
||||||
|
int startProxyServer(const char *homepath, uint64_t nwid, struct sockaddr_storage *addr);
|
||||||
|
int stopProxyServer();
|
||||||
|
int getProxyServerAddress(struct sockaddr_storage *addr);
|
||||||
|
int getProxyServerPort();
|
||||||
|
void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable);
|
||||||
|
// --- end Proxy
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// LWIP callbacks
|
// LWIP callbacks
|
||||||
@@ -462,15 +472,6 @@ namespace ZeroTier {
|
|||||||
*/
|
*/
|
||||||
void closeConnection(PhySocket *sock);
|
void closeConnection(PhySocket *sock);
|
||||||
|
|
||||||
// --- Proxy
|
|
||||||
int sockstate;
|
|
||||||
int proxyListenSocket;
|
|
||||||
PhySocket *proxyListenPhySocket;
|
|
||||||
void StartProxy(const char *sockpath, const char *homepath, uint64_t nwid);
|
|
||||||
void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable);
|
|
||||||
|
|
||||||
// --- end Proxy
|
|
||||||
|
|
||||||
ip_addr_t convert_ip(struct sockaddr_in * addr)
|
ip_addr_t convert_ip(struct sockaddr_in * addr)
|
||||||
{
|
{
|
||||||
ip_addr_t conn_addr;
|
ip_addr_t conn_addr;
|
||||||
|
|||||||
@@ -64,9 +64,52 @@ void dwr(int level, const char *fmt, ... );
|
|||||||
|
|
||||||
namespace ZeroTier
|
namespace ZeroTier
|
||||||
{
|
{
|
||||||
void NetconEthernetTap::StartProxy(const char *sockpath, const char *homepath, uint64_t nwid)
|
int NetconEthernetTap::getProxyServerAddress(struct sockaddr_storage *addr) {
|
||||||
|
if(sockstate >= 0) {
|
||||||
|
addr = &proxyServerAddress;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetconEthernetTap::getProxyServerPort() {
|
||||||
|
struct sockaddr_in *in4;
|
||||||
|
in4 = (struct sockaddr_in *)&proxyServerAddress;
|
||||||
|
return in4->sin_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetconEthernetTap::stopProxyServer()
|
||||||
{
|
{
|
||||||
dwr(MSG_ERROR, "StartProxy()\n");
|
dwr(MSG_DEBUG, "stopProxyServer()");
|
||||||
|
if(proxyListenPhySocket) {
|
||||||
|
_phy.close(proxyListenPhySocket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dwr(MSG_ERROR, "stopProxyServer(): Invalid proxyListenPhySocket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetconEthernetTap::startProxyServer(const char *homepath, uint64_t nwid, struct sockaddr_storage *addr)
|
||||||
|
{
|
||||||
|
// Address of proxy server is determined in the following order:
|
||||||
|
// - Provided address in param: addr
|
||||||
|
// - If no address, assume 127.0.0.1:<networks.d/nwid.port>
|
||||||
|
// - If no port assignment file, 127.0.0.1:RANDOM_PORT
|
||||||
|
|
||||||
|
dwr(MSG_DEBUG, "startProxyServer()\n");
|
||||||
|
int portno = -1;
|
||||||
|
if(addr) {
|
||||||
|
dwr(MSG_DEBUG, "startProxyServer(): Using provided address");
|
||||||
|
// This address pointer may come from a different memory space and might be de-allocated, so we keep a copy
|
||||||
|
memcpy(&proxyServerAddress, addr, sizeof(struct sockaddr_storage));
|
||||||
|
struct sockaddr_in *in4 = (struct sockaddr_in *)&addr;
|
||||||
|
proxyListenPhySocket = _phy.tcpListen((const struct sockaddr*)&in4,(void *)this);
|
||||||
|
sockstate = SOCKS_OPEN;
|
||||||
|
dwr(MSG_DEBUG, "SOCKS5 proxy server address for <%.16llx> is: <%s> (sock=%p)\n", nwid, inet_ntoa(in4->sin_addr), /*ntohs(in4->sin_port), */(void*)&proxyListenPhySocket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dwr(MSG_DEBUG, "startProxyServer(): No address provided. Checking port file.");
|
||||||
// Look for a port file for this network's proxy server instance
|
// Look for a port file for this network's proxy server instance
|
||||||
char portFile[4096];
|
char portFile[4096];
|
||||||
Utils::snprintf(portFile,sizeof(portFile),"%s/networks.d/%.16llx.port",homepath,nwid);
|
Utils::snprintf(portFile,sizeof(portFile),"%s/networks.d/%.16llx.port",homepath,nwid);
|
||||||
@@ -75,31 +118,31 @@ namespace ZeroTier
|
|||||||
if(ZeroTier::OSUtils::fileExists(portFile,true))
|
if(ZeroTier::OSUtils::fileExists(portFile,true))
|
||||||
{
|
{
|
||||||
if(ZeroTier::OSUtils::readFile(portFile, portStr)) {
|
if(ZeroTier::OSUtils::readFile(portFile, portStr)) {
|
||||||
proxyListenPort = atoi(portStr.c_str());
|
portno = atoi(portStr.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
unsigned int randp = 0;
|
unsigned int randp = 0;
|
||||||
Utils::getSecureRandom(&randp,sizeof(randp));
|
Utils::getSecureRandom(&randp,sizeof(randp));
|
||||||
proxyListenPort = 1000 + (randp % 1000);
|
portno = 1000 + (randp % 1000);
|
||||||
dwr(MSG_DEBUG, "Proxy(): No port specified in networks.d/%.16llx.port, randomly picking port\n", nwid);
|
dwr(MSG_DEBUG, "Proxy(): No port specified in networks.d/%.16llx.port, randomly picking port\n", nwid);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << proxyListenPort;
|
ss << portno;
|
||||||
portStr = ss.str();
|
portStr = ss.str();
|
||||||
if(!ZeroTier::OSUtils::writeFile(portFile, portStr)) {
|
if(!ZeroTier::OSUtils::writeFile(portFile, portStr)) {
|
||||||
dwr(MSG_ERROR, "unable to write proxy port file: %s\n", portFile);
|
dwr(MSG_ERROR, "unable to write proxy port file: %s\n", portFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in in4;
|
struct sockaddr_in in4;
|
||||||
memset(&in4,0,sizeof(in4));
|
memset(&in4,0,sizeof(in4));
|
||||||
in4.sin_family = AF_INET;
|
in4.sin_family = AF_INET;
|
||||||
in4.sin_addr.s_addr = Utils::hton((uint32_t)0x00000000); // right now we just listen for TCP @0.0.0.0
|
in4.sin_addr.s_addr = Utils::hton((uint32_t)0x00000000); // right now we just listen for TCP @0.0.0.0
|
||||||
in4.sin_port = Utils::hton((uint16_t)proxyListenPort);
|
in4.sin_port = Utils::hton((uint16_t)portno);
|
||||||
proxyListenPhySocket = _phy.tcpListen((const struct sockaddr*)&in4,(void *)this);
|
proxyListenPhySocket = _phy.tcpListen((const struct sockaddr*)&in4,(void *)this);
|
||||||
sockstate = SOCKS_OPEN;
|
sockstate = SOCKS_OPEN;
|
||||||
dwr(MSG_DEBUG, "SOCKS5 proxy server address for <%.16llx> is: <0.0.0.0:%d> (sock=%p)\n", nwid, proxyListenPort, (void*)&proxyListenPhySocket);
|
//dwr(MSG_DEBUG, "SOCKS5 proxy server address for <%.16llx> is: <%s:%d> (sock=%p)\n", nwid, , portno, (void*)&proxyListenPhySocket);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractAddress(int addr_type, unsigned char *buf, struct sockaddr_in * addr)
|
void ExtractAddress(int addr_type, unsigned char *buf, struct sockaddr_in * addr)
|
||||||
|
|||||||
@@ -94,10 +94,49 @@ void dwr(int level, const char *fmt, ... );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int zts_start_proxy_server(const char *homepath, const char * nwid, struct sockaddr_storage * addr) {
|
||||||
|
LOGV("zts_start_proxy_server\n");
|
||||||
|
|
||||||
|
dwr(MSG_DEBUG, "zts_start_proxy_server()");
|
||||||
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
|
ZeroTier::NetconEthernetTap * tap = zt1Service->getTaps()[nwid_int];
|
||||||
|
if(tap) {
|
||||||
|
if(tap->startProxyServer(homepath, nwid_int, addr) < 0) {
|
||||||
|
dwr(MSG_ERROR, "zts_start_proxy_server(%s): Problem while starting server.", nwid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dwr(MSG_ERROR, "zts_start_proxy_server(%s): Invalid tap. Possibly incorrect NWID", nwid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int zts_stop_proxy_server(const char *nwid) {
|
||||||
|
dwr(MSG_DEBUG, "zts_stop_proxy_server()");
|
||||||
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
|
ZeroTier::NetconEthernetTap * tap = zt1Service->getTaps()[nwid_int];
|
||||||
|
if(tap) {
|
||||||
|
if(tap->stopProxyServer() < 0) {
|
||||||
|
dwr(MSG_ERROR, "zts_stop_proxy_server(%s): Problem while stopping server.", nwid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dwr(MSG_ERROR, "zts_stop_proxy_server(%s): Invalid tap. Possibly incorrect NWID", nwid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage * addr) {
|
||||||
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
|
ZeroTier::NetconEthernetTap * tap = zt1Service->getTaps()[nwid_int];
|
||||||
|
if(tap) {
|
||||||
|
tap->getProxyServerAddress(addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Basic ZT service controls
|
// Basic ZT service controls
|
||||||
|
// Will also spin up a SOCKS5 proxy server if USE_SOCKS_PROXY is set
|
||||||
void zts_join_network(const char * nwid) {
|
void zts_join_network(const char * nwid) {
|
||||||
|
LOGV("zts_join_network\n");
|
||||||
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
|
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
|
||||||
dwr(MSG_ERROR, "writing conf file = %s\n", confFile.c_str());
|
|
||||||
if(!ZeroTier::OSUtils::mkdir(netDir)) {
|
if(!ZeroTier::OSUtils::mkdir(netDir)) {
|
||||||
dwr(MSG_ERROR, "unable to create %s\n", netDir.c_str());
|
dwr(MSG_ERROR, "unable to create %s\n", netDir.c_str());
|
||||||
}
|
}
|
||||||
@@ -106,6 +145,15 @@ void zts_join_network(const char * nwid) {
|
|||||||
}
|
}
|
||||||
// Provide the API with the RPC information
|
// Provide the API with the RPC information
|
||||||
zt_init_rpc(homeDir.c_str(), nwid);
|
zt_init_rpc(homeDir.c_str(), nwid);
|
||||||
|
|
||||||
|
// SOCKS5 Proxy server
|
||||||
|
// Default is 127.0.0.1:RANDOM_PORT
|
||||||
|
LOGV("-----USE_SOCKS_PROXY ?\n");
|
||||||
|
#if defined(USE_SOCKS_PROXY)
|
||||||
|
LOGV("-----USE_SOCKS_PROXY!\\n");
|
||||||
|
|
||||||
|
zts_start_proxy_server(homeDir.c_str(), nwid, NULL); // NULL addr for default
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void zts_leave_network(const char * nwid) { zt1Service->leave(nwid); }
|
void zts_leave_network(const char * nwid) { zt1Service->leave(nwid); }
|
||||||
bool zts_is_running() { return zt1Service->isRunning(); }
|
bool zts_is_running() { return zt1Service->isRunning(); }
|
||||||
@@ -145,22 +193,6 @@ bool zts_is_relayed() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_start_proxy_server(const char * nwid, struct sockaddr_storage * addr) {
|
|
||||||
//uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
|
||||||
//return zt1Service->getTaps()[nwid_int]->proxyListenPort;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int zts_stop_proxy_server(const char * nwid) {
|
|
||||||
//uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
|
||||||
//return zt1Service->getTaps()[nwid_int]->proxyListenPort;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage * addr) {
|
|
||||||
//uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
|
||||||
//zt1Service->getTaps()[nwid_int]->proxyListenPort;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Android JNI wrapper
|
// Android JNI wrapper
|
||||||
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
|
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
@@ -284,6 +316,9 @@ int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage * ad
|
|||||||
* Starts a new service instance
|
* Starts a new service instance
|
||||||
*/
|
*/
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
/* NOTE: Since on Android devices the sdcard is formatted as fat32, we can't use just any
|
||||||
|
location to set up the RPC unix domain socket. Rather we must use the application's specific
|
||||||
|
data directory given by getApplicationContext().getFilesDir() */
|
||||||
JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1start_1service(JNIEnv *env, jobject thisObj, jstring path) {
|
JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1start_1service(JNIEnv *env, jobject thisObj, jstring path) {
|
||||||
if(path)
|
if(path)
|
||||||
homeDir = env->GetStringUTFChars(path, NULL);
|
homeDir = env->GetStringUTFChars(path, NULL);
|
||||||
@@ -314,14 +349,6 @@ int zts_get_proxy_server_address(const char * nwid, struct sockaddr_storage * ad
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
|
||||||
/* NOTE: Since on Android devices the sdcard is formatted as fat32, we can't use this
|
|
||||||
location to set up the RPC unix domain socket. Rather we must use the application's
|
|
||||||
specific data directory given by getApplicationContext().getFilesDir() */
|
|
||||||
//rpcDir = homeDir; // Take given homeDir as rpcDir
|
|
||||||
//homeDir = "/sdcard/zerotier"; // Use fat32-formatted sdcard for writing network conf & supporting files
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__APPLE__) && !defined(__IOS__)
|
#if defined(__APPLE__) && !defined(__IOS__)
|
||||||
homeDir = givenHomeDir;
|
homeDir = givenHomeDir;
|
||||||
localHomeDir = givenHomeDir; // Used for RPC and *can* differ from homeDir on some platforms
|
localHomeDir = givenHomeDir; // Used for RPC and *can* differ from homeDir on some platforms
|
||||||
|
|||||||
Reference in New Issue
Block a user