mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-05-21 12:24:29 +02:00
Add experimental SOCKS5 support for the clients.
This commit is contained in:
parent
e9c18f8347
commit
42420cae46
|
|
@ -65,6 +65,11 @@ else (${WITH_TLS} STREQUAL ON)
|
||||||
set (OPENSSL_INCLUDE_DIR "")
|
set (OPENSSL_INCLUDE_DIR "")
|
||||||
endif (${WITH_TLS} STREQUAL ON)
|
endif (${WITH_TLS} STREQUAL ON)
|
||||||
|
|
||||||
|
option(WITH_SOCKS "Include SOCKS5 support?" ON)
|
||||||
|
if (${WITH_SOCKS} STREQUAL ON)
|
||||||
|
add_definitions("-DWITH_SOCKS")
|
||||||
|
endif (${WITH_SOCKS} STREQUAL ON)
|
||||||
|
|
||||||
option(WITH_SRV "Include SRV lookup support?" ON)
|
option(WITH_SRV "Include SRV lookup support?" ON)
|
||||||
|
|
||||||
# ========================================
|
# ========================================
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ Important changes:
|
||||||
connected.
|
connected.
|
||||||
- New use_username_as_clientid option on the broker, for preventing hijacking
|
- New use_username_as_clientid option on the broker, for preventing hijacking
|
||||||
of a client id.
|
of a client id.
|
||||||
|
- The client library and clients now have experimental SOCKS5 support.
|
||||||
|
|
||||||
|
|
||||||
Broker:
|
Broker:
|
||||||
|
|
@ -46,8 +47,10 @@ Broker:
|
||||||
Clients:
|
Clients:
|
||||||
- Both clients can now load default configuration options from a file.
|
- Both clients can now load default configuration options from a file.
|
||||||
- Add -1 (oneshot) option to mosquitto_sub.
|
- Add -1 (oneshot) option to mosquitto_sub.
|
||||||
|
- Add --proxy SOCKS5 support for both clients.
|
||||||
|
|
||||||
Client library:
|
Client library:
|
||||||
|
- Add experimental SOCKS5 support.
|
||||||
- mosquitto_loop_forever now quits after a fatal error, rather than blindly
|
- mosquitto_loop_forever now quits after a fatal error, rather than blindly
|
||||||
retrying.
|
retrying.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Contributors:
|
||||||
#include <mosquitto.h>
|
#include <mosquitto.h>
|
||||||
#include "client_shared.h"
|
#include "client_shared.h"
|
||||||
|
|
||||||
|
static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url);
|
||||||
static int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]);
|
static int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]);
|
||||||
|
|
||||||
void init_config(struct mosq_config *cfg)
|
void init_config(struct mosq_config *cfg)
|
||||||
|
|
@ -359,6 +360,18 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
|
||||||
}else{
|
}else{
|
||||||
cfg->pub_mode = MSGMODE_NULL;
|
cfg->pub_mode = MSGMODE_NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
}else if(!strcmp(argv[i], "--proxy")){
|
||||||
|
if(i==argc-1){
|
||||||
|
fprintf(stderr, "Error: --proxy argument given but no proxy url specified.\n\n");
|
||||||
|
return 1;
|
||||||
|
}else{
|
||||||
|
if(mosquitto__parse_socks_url(cfg, argv[i+1])){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
}else if(!strcmp(argv[i], "--psk")){
|
}else if(!strcmp(argv[i], "--psk")){
|
||||||
if(i==argc-1){
|
if(i==argc-1){
|
||||||
|
|
@ -544,6 +557,8 @@ unknown_option:
|
||||||
|
|
||||||
int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
|
int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
if(cfg->will_topic && mosquitto_will_set(mosq, cfg->will_topic,
|
if(cfg->will_topic && mosquitto_will_set(mosq, cfg->will_topic,
|
||||||
cfg->will_payloadlen, cfg->will_payload, cfg->will_qos,
|
cfg->will_payloadlen, cfg->will_payload, cfg->will_qos,
|
||||||
cfg->will_retain)){
|
cfg->will_retain)){
|
||||||
|
|
@ -584,6 +599,15 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
mosquitto_max_inflight_messages_set(mosq, cfg->max_inflight);
|
mosquitto_max_inflight_messages_set(mosq, cfg->max_inflight);
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
if(cfg->socks5_host){
|
||||||
|
rc = mosquitto_socks5_set(mosq, cfg->socks5_host, cfg->socks5_port, cfg->socks5_username, cfg->socks5_password);
|
||||||
|
if(rc){
|
||||||
|
mosquitto_lib_cleanup();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return MOSQ_ERR_SUCCESS;
|
return MOSQ_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -648,3 +672,174 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
|
||||||
}
|
}
|
||||||
return MOSQ_ERR_SUCCESS;
|
return MOSQ_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
/* Convert %25 -> %, %3a, %3A -> :, %40 -> @ */
|
||||||
|
static int mosquitto__urldecode(char *str)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int len;
|
||||||
|
if(!str) return 0;
|
||||||
|
|
||||||
|
if(!strchr(str, '%')) return 0;
|
||||||
|
|
||||||
|
len = strlen(str);
|
||||||
|
for(i=0; i<len; i++){
|
||||||
|
if(str[i] == '%'){
|
||||||
|
if(i+2 >= len){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(str[i+1] == '2' && str[i+2] == '5'){
|
||||||
|
str[i] = '%';
|
||||||
|
len -= 2;
|
||||||
|
for(j=i+1; j<len; j++){
|
||||||
|
str[j] = str[j+2];
|
||||||
|
}
|
||||||
|
str[j] = '\0';
|
||||||
|
}else if(str[i+1] == '3' && (str[i+2] == 'A' || str[i+2] == 'a')){
|
||||||
|
str[i] = ':';
|
||||||
|
len -= 2;
|
||||||
|
for(j=i+1; j<len; j++){
|
||||||
|
str[j] = str[j+2];
|
||||||
|
}
|
||||||
|
str[j] = '\0';
|
||||||
|
}else if(str[i+1] == '4' && str[i+2] == '0'){
|
||||||
|
str[i] = ':';
|
||||||
|
len -= 2;
|
||||||
|
for(j=i+1; j<len; j++){
|
||||||
|
str[j] = str[j+2];
|
||||||
|
}
|
||||||
|
str[j] = '\0';
|
||||||
|
}else{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
int i;
|
||||||
|
char *username = NULL, *password = NULL, *host = NULL, *port = NULL;
|
||||||
|
char *username_or_host = NULL;
|
||||||
|
int start;
|
||||||
|
int len;
|
||||||
|
bool have_auth = false;
|
||||||
|
int port_int;
|
||||||
|
|
||||||
|
if(!strncmp(url, "socks5h://", strlen("socks5h://"))){
|
||||||
|
str = url + strlen("socks5h://");
|
||||||
|
}else{
|
||||||
|
fprintf(stderr, "Error: Unsupported proxy protocol: %s\n", url);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = 0;
|
||||||
|
for(i=0; i<strlen(str); i++){
|
||||||
|
if(str[i] == ':'){
|
||||||
|
if(i == start){
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if(have_auth){
|
||||||
|
len = i-start;
|
||||||
|
host = malloc(len + 1);
|
||||||
|
memcpy(host, &(str[start]), len);
|
||||||
|
host[len] = '\0';
|
||||||
|
start = i+1;
|
||||||
|
}else if(!username_or_host){
|
||||||
|
len = i-start;
|
||||||
|
username_or_host = malloc(len + 1);
|
||||||
|
memcpy(username_or_host, &(str[start]), len);
|
||||||
|
username_or_host[len] = '\0';
|
||||||
|
start = i+1;
|
||||||
|
}
|
||||||
|
}else if(str[i] == '@'){
|
||||||
|
if(i == start){
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
have_auth = true;
|
||||||
|
if(username_or_host){
|
||||||
|
username = username_or_host;
|
||||||
|
username_or_host = NULL;
|
||||||
|
|
||||||
|
len = i-start;
|
||||||
|
password = malloc(len + 1);
|
||||||
|
memcpy(password, &(str[start]), len);
|
||||||
|
password[len] = '\0';
|
||||||
|
start = i+1;
|
||||||
|
}else{
|
||||||
|
len = i-start;
|
||||||
|
username = malloc(len + 1);
|
||||||
|
memcpy(username, &(str[start]), len);
|
||||||
|
username[len] = '\0';
|
||||||
|
start = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deal with remainder */
|
||||||
|
if(i > start){
|
||||||
|
len = i-start;
|
||||||
|
if(host){
|
||||||
|
port = malloc(len + 1);
|
||||||
|
memcpy(port, &(str[start]), len);
|
||||||
|
port[len] = '\0';
|
||||||
|
}else if(username_or_host){
|
||||||
|
if(have_auth){
|
||||||
|
host = malloc(len + 1);
|
||||||
|
memcpy(host, &(str[start]), len);
|
||||||
|
host[len] = '\0';
|
||||||
|
}else{
|
||||||
|
host = username_or_host;
|
||||||
|
username_or_host = NULL;
|
||||||
|
port = malloc(len + 1);
|
||||||
|
memcpy(port, &(str[start]), len);
|
||||||
|
port[len] = '\0';
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
host = malloc(len + 1);
|
||||||
|
memcpy(host, &(str[start]), len);
|
||||||
|
host[len] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!host){
|
||||||
|
fprintf(stderr, "Error: Invalid proxy.\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mosquitto__urldecode(username)){
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if(mosquitto__urldecode(password)){
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if(port){
|
||||||
|
port_int = atoi(port);
|
||||||
|
if(port_int < 1 || port_int > 65535){
|
||||||
|
fprintf(stderr, "Error: Invalid proxy port %d\n", port_int);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
free(port);
|
||||||
|
}else{
|
||||||
|
port_int = 1080;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg->socks5_username = username;
|
||||||
|
cfg->socks5_password = password;
|
||||||
|
cfg->socks5_host = host;
|
||||||
|
cfg->socks5_port = port_int;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
cleanup:
|
||||||
|
if(username_or_host) free(username_or_host);
|
||||||
|
if(username) free(username);
|
||||||
|
if(password) free(password);
|
||||||
|
if(host) free(host);
|
||||||
|
if(port) free(port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,12 @@ struct mosq_config {
|
||||||
bool verbose; /* sub */
|
bool verbose; /* sub */
|
||||||
bool eol; /* sub */
|
bool eol; /* sub */
|
||||||
bool oneshot; /* sub */
|
bool oneshot; /* sub */
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
char *socks5_host;
|
||||||
|
int socks5_port;
|
||||||
|
char *socks5_username;
|
||||||
|
char *socks5_password;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int client_config_load(struct mosq_config *config, int pub_or_sub, int argc, char *argv[]);
|
int client_config_load(struct mosq_config *config, int pub_or_sub, int argc, char *argv[]);
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,9 @@ void print_usage(void)
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
printf(" [--proxy socks-url]\n");
|
||||||
#endif
|
#endif
|
||||||
printf(" mosquitto_pub --help\n\n");
|
printf(" mosquitto_pub --help\n\n");
|
||||||
printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n");
|
printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n");
|
||||||
|
|
@ -263,10 +266,15 @@ void print_usage(void)
|
||||||
printf(" hostname. Using this option means that you cannot be sure that the\n");
|
printf(" hostname. Using this option means that you cannot be sure that the\n");
|
||||||
printf(" remote host is the server you wish to connect to and so is insecure.\n");
|
printf(" remote host is the server you wish to connect to and so is insecure.\n");
|
||||||
printf(" Do not use this option in a production environment.\n");
|
printf(" Do not use this option in a production environment.\n");
|
||||||
#ifdef WITH_TLS_PSK
|
# ifdef WITH_TLS_PSK
|
||||||
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
||||||
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
printf(" --proxy : SOCKS5 proxy URL of the form:\n");
|
||||||
|
printf(" socks5h://[username[:password]@]hostname[:port]\n");
|
||||||
|
printf(" Only \"none\" and \"username\" authentication is supported.\n");
|
||||||
#endif
|
#endif
|
||||||
printf("\nSee http://mosquitto.org/ for more information.\n\n");
|
printf("\nSee http://mosquitto.org/ for more information.\n\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,9 @@ void print_usage(void)
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
printf(" [--proxy socks-url]\n");
|
||||||
#endif
|
#endif
|
||||||
printf(" mosquitto_sub --help\n\n");
|
printf(" mosquitto_sub --help\n\n");
|
||||||
printf(" -1 : disconnect and exit after receiving the first message.\n");
|
printf(" -1 : disconnect and exit after receiving the first message.\n");
|
||||||
|
|
@ -192,6 +195,11 @@ void print_usage(void)
|
||||||
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
||||||
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SOCKS
|
||||||
|
printf(" --proxy : SOCKS5 proxy URL of the form:\n");
|
||||||
|
printf(" socks5h://[username[:password]@]hostname[:port]\n");
|
||||||
|
printf(" Only \"none\" and \"username\" authentication is supported.\n");
|
||||||
#endif
|
#endif
|
||||||
printf("\nSee http://mosquitto.org/ for more information.\n\n");
|
printf("\nSee http://mosquitto.org/ for more information.\n\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,9 @@ WITH_EC:=yes
|
||||||
# Build man page documentation by default.
|
# Build man page documentation by default.
|
||||||
WITH_DOCS:=yes
|
WITH_DOCS:=yes
|
||||||
|
|
||||||
|
# Build with client support for SOCK5 proxy.
|
||||||
|
WITH_SOCKS:=yes
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# End of user configuration
|
# End of user configuration
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
@ -174,6 +177,11 @@ ifeq ($(WITH_THREADING),yes)
|
||||||
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_THREADING
|
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_THREADING
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WITH_SOCKS),yes)
|
||||||
|
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_SOCKS
|
||||||
|
CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_SOCKS
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(WITH_UUID),yes)
|
ifeq ($(WITH_UUID),yes)
|
||||||
ifeq ($(UNAME),Linux)
|
ifeq ($(UNAME),Linux)
|
||||||
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_UUID
|
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_UUID
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ add_library(libmosquitto SHARED
|
||||||
read_handle_shared.c
|
read_handle_shared.c
|
||||||
send_client_mosq.c
|
send_client_mosq.c
|
||||||
send_mosq.c send_mosq.h
|
send_mosq.c send_mosq.h
|
||||||
|
socks_mosq.c
|
||||||
srv_mosq.c
|
srv_mosq.c
|
||||||
thread_mosq.c
|
thread_mosq.c
|
||||||
time_mosq.c
|
time_mosq.c
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ MOSQ_OBJS=mosquitto.o \
|
||||||
read_handle_shared.o \
|
read_handle_shared.o \
|
||||||
send_mosq.o \
|
send_mosq.o \
|
||||||
send_client_mosq.o \
|
send_client_mosq.o \
|
||||||
|
socks_mosq.o \
|
||||||
srv_mosq.o \
|
srv_mosq.o \
|
||||||
thread_mosq.o \
|
thread_mosq.o \
|
||||||
time_mosq.o \
|
time_mosq.o \
|
||||||
|
|
@ -76,6 +77,9 @@ send_mosq.o : send_mosq.c send_mosq.h
|
||||||
send_client_mosq.o : send_client_mosq.c send_mosq.h
|
send_client_mosq.o : send_client_mosq.c send_mosq.h
|
||||||
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
|
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
socks_mosq.o : socks_mosq.c
|
||||||
|
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
srv_mosq.o : srv_mosq.c
|
srv_mosq.o : srv_mosq.c
|
||||||
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
|
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,4 +75,5 @@ MOSQ_1.4 {
|
||||||
mosquitto_threaded_set;
|
mosquitto_threaded_set;
|
||||||
mosquitto_pub_topic_check;
|
mosquitto_pub_topic_check;
|
||||||
mosquitto_sub_topic_check;
|
mosquitto_sub_topic_check;
|
||||||
|
mosquitto_socks5_set;
|
||||||
} MOSQ_1.3;
|
} MOSQ_1.3;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ typedef int ssize_t;
|
||||||
#include <net_mosq.h>
|
#include <net_mosq.h>
|
||||||
#include <read_handle.h>
|
#include <read_handle.h>
|
||||||
#include <send_mosq.h>
|
#include <send_mosq.h>
|
||||||
|
#include <socks_mosq.h>
|
||||||
#include <time_mosq.h>
|
#include <time_mosq.h>
|
||||||
#include <tls_mosq.h>
|
#include <tls_mosq.h>
|
||||||
#include <util_mosq.h>
|
#include <util_mosq.h>
|
||||||
|
|
@ -461,7 +462,11 @@ static int _mosquitto_reconnect(struct mosquitto *mosq, bool blocking)
|
||||||
if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
|
if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
|
||||||
|
|
||||||
pthread_mutex_lock(&mosq->state_mutex);
|
pthread_mutex_lock(&mosq->state_mutex);
|
||||||
mosq->state = mosq_cs_new;
|
if(mosq->socks5_host){
|
||||||
|
mosq->state = mosq_cs_socks5_new;
|
||||||
|
}else{
|
||||||
|
mosq->state = mosq_cs_new;
|
||||||
|
}
|
||||||
pthread_mutex_unlock(&mosq->state_mutex);
|
pthread_mutex_unlock(&mosq->state_mutex);
|
||||||
|
|
||||||
pthread_mutex_lock(&mosq->msgtime_mutex);
|
pthread_mutex_lock(&mosq->msgtime_mutex);
|
||||||
|
|
@ -497,12 +502,20 @@ static int _mosquitto_reconnect(struct mosquitto *mosq, bool blocking)
|
||||||
|
|
||||||
_mosquitto_messages_reconnect_reset(mosq);
|
_mosquitto_messages_reconnect_reset(mosq);
|
||||||
|
|
||||||
rc = _mosquitto_socket_connect(mosq, mosq->host, mosq->port, mosq->bind_address, blocking);
|
if(mosq->socks5_host){
|
||||||
|
rc = _mosquitto_socket_connect(mosq, mosq->socks5_host, mosq->socks5_port, mosq->bind_address, blocking);
|
||||||
|
}else{
|
||||||
|
rc = _mosquitto_socket_connect(mosq, mosq->host, mosq->port, mosq->bind_address, blocking);
|
||||||
|
}
|
||||||
if(rc){
|
if(rc){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _mosquitto_send_connect(mosq, mosq->keepalive, mosq->clean_session);
|
if(mosq->socks5_host){
|
||||||
|
return mosquitto__socks5_send(mosq);
|
||||||
|
}else{
|
||||||
|
return _mosquitto_send_connect(mosq, mosq->keepalive, mosq->clean_session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mosquitto_disconnect(struct mosquitto *mosq)
|
int mosquitto_disconnect(struct mosquitto *mosq)
|
||||||
|
|
@ -951,6 +964,7 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
|
||||||
case MOSQ_ERR_UNKNOWN:
|
case MOSQ_ERR_UNKNOWN:
|
||||||
case MOSQ_ERR_ERRNO:
|
case MOSQ_ERR_ERRNO:
|
||||||
case MOSQ_ERR_EAI:
|
case MOSQ_ERR_EAI:
|
||||||
|
case MOSQ_ERR_PROXY:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if(errno == EPROTO){
|
if(errno == EPROTO){
|
||||||
|
|
@ -1075,7 +1089,11 @@ int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
|
||||||
* have QoS > 0. We should try to deal with that many in this loop in order
|
* have QoS > 0. We should try to deal with that many in this loop in order
|
||||||
* to keep up. */
|
* to keep up. */
|
||||||
for(i=0; i<max_packets; i++){
|
for(i=0; i<max_packets; i++){
|
||||||
rc = _mosquitto_packet_read(mosq);
|
if(mosq->socks5_host){
|
||||||
|
rc = mosquitto__socks5_read(mosq);
|
||||||
|
}else{
|
||||||
|
rc = _mosquitto_packet_read(mosq);
|
||||||
|
}
|
||||||
if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
|
if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
|
||||||
return _mosquitto_loop_rc_handle(mosq, rc);
|
return _mosquitto_loop_rc_handle(mosq, rc);
|
||||||
}
|
}
|
||||||
|
|
@ -1212,6 +1230,8 @@ const char *mosquitto_strerror(int mosq_errno)
|
||||||
return "Unknown error.";
|
return "Unknown error.";
|
||||||
case MOSQ_ERR_ERRNO:
|
case MOSQ_ERR_ERRNO:
|
||||||
return strerror(errno);
|
return strerror(errno);
|
||||||
|
case MOSQ_ERR_PROXY:
|
||||||
|
return "Proxy error.";
|
||||||
default:
|
default:
|
||||||
return "Unknown error.";
|
return "Unknown error.";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,8 @@ enum mosq_err_t {
|
||||||
MOSQ_ERR_ACL_DENIED = 12,
|
MOSQ_ERR_ACL_DENIED = 12,
|
||||||
MOSQ_ERR_UNKNOWN = 13,
|
MOSQ_ERR_UNKNOWN = 13,
|
||||||
MOSQ_ERR_ERRNO = 14,
|
MOSQ_ERR_ERRNO = 14,
|
||||||
MOSQ_ERR_EAI = 15
|
MOSQ_ERR_EAI = 15,
|
||||||
|
MOSQ_ERR_PROXY = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
/* MQTT specification restricts client ids to a maximum of 23 characters */
|
/* MQTT specification restricts client ids to a maximum of 23 characters */
|
||||||
|
|
@ -1294,6 +1295,29 @@ libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned
|
||||||
*/
|
*/
|
||||||
libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj);
|
libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj);
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
*
|
||||||
|
* Section: SOCKS5 proxy functions
|
||||||
|
*
|
||||||
|
* =============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: mosquitto_socks5_set
|
||||||
|
*
|
||||||
|
* Configure the client to use a SOCKS5 proxy when connecting. Must be called
|
||||||
|
* before connecting. "None" and "username/password" authentication is
|
||||||
|
* supported.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* mosq - a valid mosquitto instance.
|
||||||
|
* host - the SOCKS5 proxy host to connect to.
|
||||||
|
* port - the SOCKS5 proxy port to use.
|
||||||
|
* username - if not NULL, use this username when authenticating with the proxy.
|
||||||
|
* password - if not NULL and username is not NULL, use this password when
|
||||||
|
* authenticating with the proxy.
|
||||||
|
*/
|
||||||
|
libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password);
|
||||||
|
|
||||||
/* =============================================================================
|
/* =============================================================================
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,14 @@ enum mosquitto_client_state {
|
||||||
mosq_cs_connect_pending = 4,
|
mosq_cs_connect_pending = 4,
|
||||||
mosq_cs_connect_srv = 5,
|
mosq_cs_connect_srv = 5,
|
||||||
mosq_cs_disconnect_ws = 6,
|
mosq_cs_disconnect_ws = 6,
|
||||||
mosq_cs_disconnected = 7
|
mosq_cs_disconnected = 7,
|
||||||
|
mosq_cs_socks5_new = 8,
|
||||||
|
mosq_cs_socks5_start = 9,
|
||||||
|
mosq_cs_socks5_request = 10,
|
||||||
|
mosq_cs_socks5_reply = 11,
|
||||||
|
mosq_cs_socks5_auth_ok = 12,
|
||||||
|
mosq_cs_socks5_userpass_reply = 13,
|
||||||
|
mosq_cs_socks5_send_userpass = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum _mosquitto_protocol {
|
enum _mosquitto_protocol {
|
||||||
|
|
@ -199,6 +206,12 @@ struct mosquitto {
|
||||||
struct libwebsocket *wsi;
|
struct libwebsocket *wsi;
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
|
# ifdef WITH_SOCKS
|
||||||
|
char *socks5_host;
|
||||||
|
int socks5_port;
|
||||||
|
char *socks5_username;
|
||||||
|
char *socks5_password;
|
||||||
|
# endif
|
||||||
void *userdata;
|
void *userdata;
|
||||||
bool in_callback;
|
bool in_callback;
|
||||||
unsigned int message_retry;
|
unsigned int message_retry;
|
||||||
|
|
@ -239,6 +252,9 @@ struct mosquitto {
|
||||||
# ifdef WITH_BRIDGE
|
# ifdef WITH_BRIDGE
|
||||||
UT_hash_handle hh_bridge;
|
UT_hash_handle hh_bridge;
|
||||||
# endif
|
# endif
|
||||||
|
# ifdef WITH_WEBSOCKETS
|
||||||
|
UT_hash_handle hh_websockets;
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@
|
||||||
<arg><option>--tls-version</option> <replaceable>version</replaceable></arg>
|
<arg><option>--tls-version</option> <replaceable>version</replaceable></arg>
|
||||||
</arg>
|
</arg>
|
||||||
</group>
|
</group>
|
||||||
|
<arg><option>--proxy</option> <replaceable>socks-url</replaceable></arg>
|
||||||
|
|
||||||
<arg choice='plain'><option>-t</option> <replaceable>message-topic</replaceable></arg>
|
<arg choice='plain'><option>-t</option> <replaceable>message-topic</replaceable></arg>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
|
|
@ -252,6 +254,25 @@
|
||||||
MQTT v3.1. See also the <option>--username</option> option.</para>
|
MQTT v3.1. See also the <option>--username</option> option.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--proxy</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Specify a SOCKS5 proxy to connect through. "None" and
|
||||||
|
"username" authentication types are supported. The
|
||||||
|
<option>socks-url</option> must be of the form
|
||||||
|
<option>socks5h://[username[:password]@]host[:port]</option>.
|
||||||
|
The protocol prefix <option>socks5h</option> means that
|
||||||
|
hostnames are resolved by the proxy. The symbols %25,
|
||||||
|
%3A and %40 are URL decoded into %, : and @
|
||||||
|
respectively, if present in the username or
|
||||||
|
password.</para>
|
||||||
|
<para>More SOCKS versions may be available in the future,
|
||||||
|
depending on demand, and will use different protocol
|
||||||
|
prefixes as described in <citerefentry>
|
||||||
|
<refentrytitle>curl</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--psk</option></term>
|
<term><option>--psk</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
</group>
|
</group>
|
||||||
<arg choice='opt' rep='repeat'><option>-T</option> <replaceable>filter-out</replaceable></arg>
|
<arg choice='opt' rep='repeat'><option>-T</option> <replaceable>filter-out</replaceable></arg>
|
||||||
<arg choice='plain' rep='repeat'><option>-t</option> <replaceable>message-topic</replaceable></arg>
|
<arg choice='plain' rep='repeat'><option>-t</option> <replaceable>message-topic</replaceable></arg>
|
||||||
|
<arg><option>--proxy</option> <replaceable>socks-url</replaceable></arg>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>mosquitto_sub</command>
|
<command>mosquitto_sub</command>
|
||||||
|
|
@ -269,6 +270,25 @@
|
||||||
MQTT v3.1. See also the <option>--username</option> option.</para>
|
MQTT v3.1. See also the <option>--username</option> option.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--proxy</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Specify a SOCKS5 proxy to connect through. "None" and
|
||||||
|
"username" authentication types are supported. The
|
||||||
|
<option>socks-url</option> must be of the form
|
||||||
|
<option>socks5h://[username[:password]@]host[:port]</option>.
|
||||||
|
The protocol prefix <option>socks5h</option> means that
|
||||||
|
hostnames are resolved by the proxy. The symbols %25,
|
||||||
|
%3A and %40 are URL decoded into %, : and @
|
||||||
|
respectively, if present in the username or
|
||||||
|
password.</para>
|
||||||
|
<para>More SOCKS versions may be available in the future,
|
||||||
|
depending on demand, and will use different protocol
|
||||||
|
prefixes as described in <citerefentry>
|
||||||
|
<refentrytitle>curl</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--psk</option></term>
|
<term><option>--psk</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue