Exemplo n.º 1
0
int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
{
	int rc;
	int i;
	if(max_packets < 1) return MOSQ_ERR_INVAL;

	pthread_mutex_lock(&mosq->out_message_mutex);
	max_packets = mosq->out_queue_len;
	pthread_mutex_unlock(&mosq->out_message_mutex);

	pthread_mutex_lock(&mosq->in_message_mutex);
	max_packets += mosq->in_queue_len;
	pthread_mutex_unlock(&mosq->in_message_mutex);

	if(max_packets < 1) max_packets = 1;
	/* Queue len here tells us how many messages are awaiting processing and
	 * have QoS > 0. We should try to deal with that many in this loop in order
	 * to keep up. */
	for(i=0; i<max_packets; i++){
#ifdef WITH_SOCKS
		if(mosq->socks5_host){
			rc = mosquitto__socks5_read(mosq);
		}else
#endif
		{
			rc = _mosquitto_packet_read(mosq);
		}
		if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
			return _mosquitto_loop_rc_handle(mosq, rc);
		}
	}
	return rc;
}
Exemplo n.º 2
0
static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pollfds)
{
	int i;

	for(i=0; i<db->context_count; i++){
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			assert(pollfds[db->contexts[i]->pollfd_index].fd == db->contexts[i]->sock);
#ifdef WITH_TLS
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLOUT ||
					db->contexts[i]->want_write ||
					(db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)){
#else
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLOUT){
#endif
				if(_mosquitto_packet_write(db->contexts[i])){
					if(db->config->connection_messages == true){
						if(db->contexts[i]->state != mosq_cs_disconnecting){
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket write error on client %s, disconnecting.", db->contexts[i]->id);
						}else{
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
						}
					}
					/* Write error or other that means we should disconnect */
					mqtt3_context_disconnect(db, db->contexts[i]);
				}
			}
		}
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			assert(pollfds[db->contexts[i]->pollfd_index].fd == db->contexts[i]->sock);
#ifdef WITH_TLS
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLIN ||
					db->contexts[i]->want_read ||
					(db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)){
#else
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLIN){
#endif
				if(_mosquitto_packet_read(db, db->contexts[i])){
					if(db->config->connection_messages == true){
						if(db->contexts[i]->state != mosq_cs_disconnecting){
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket read error on client %s, disconnecting.", db->contexts[i]->id);
						}else{
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
						}
					}
					/* Read error or other that means we should disconnect */
					mqtt3_context_disconnect(db, db->contexts[i]);
				}
			}
		}
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			if(pollfds[db->contexts[i]->pollfd_index].revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)){
				do_disconnect(db, i);
			}
		}
	}
}
Exemplo n.º 3
0
int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
{
    int rc;
    int i;
    if(max_packets < 1) return MOSQ_ERR_INVAL;

    max_packets = mosq->queue_len;
    if(max_packets < 1) max_packets = 1;
    /* Queue len here tells us how many messages are awaiting processing and
     * have QoS > 0. We should try to deal with that many in this loop in order
     * to keep up. */
    for(i=0; i<max_packets; i++) {
        rc = _mosquitto_packet_read(mosq);
        if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK) {
            return _mosquitto_loop_rc_handle(mosq, rc);
        }
    }
    return rc;
}
Exemplo n.º 4
0
int mosquitto__socks5_read(struct mosquitto *mosq)
{
	ssize_t len;
	uint8_t *payload;
	uint8_t i;

	if(mosq->state == mosq_cs_socks5_start){
		while(mosq->in_packet.to_process > 0){
			len = _mosquitto_net_read(mosq, &(mosq->in_packet.payload[mosq->in_packet.pos]), mosq->in_packet.to_process);
			if(len > 0){
				mosq->in_packet.pos += len;
				mosq->in_packet.to_process -= len;
			}else{
#ifdef WIN32
				errno = WSAGetLastError();
#endif
				if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
					return MOSQ_ERR_SUCCESS;
				}else{
					_mosquitto_packet_cleanup(&mosq->in_packet);
					switch(errno){
						case 0:
							return MOSQ_ERR_PROXY;
						case COMPAT_ECONNRESET:
							return MOSQ_ERR_CONN_LOST;
						default:
							return MOSQ_ERR_ERRNO;
					}
				}
			}
		}
		if(mosq->in_packet.payload[0] != 5){
			_mosquitto_packet_cleanup(&mosq->in_packet);
			return MOSQ_ERR_PROXY;
		}
		switch(mosq->in_packet.payload[1]){
			case SOCKS_AUTH_NONE:
				_mosquitto_packet_cleanup(&mosq->in_packet);
				mosq->state = mosq_cs_socks5_auth_ok;
				return mosquitto__socks5_send(mosq);
			case SOCKS_AUTH_USERPASS:
				_mosquitto_packet_cleanup(&mosq->in_packet);
				mosq->state = mosq_cs_socks5_send_userpass;
				return mosquitto__socks5_send(mosq);
			default:
				_mosquitto_packet_cleanup(&mosq->in_packet);
				return MOSQ_ERR_AUTH;
		}
	}else if(mosq->state == mosq_cs_socks5_userpass_reply){
		while(mosq->in_packet.to_process > 0){
			len = _mosquitto_net_read(mosq, &(mosq->in_packet.payload[mosq->in_packet.pos]), mosq->in_packet.to_process);
			if(len > 0){
				mosq->in_packet.pos += len;
				mosq->in_packet.to_process -= len;
			}else{
#ifdef WIN32
				errno = WSAGetLastError();
#endif
				if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
					return MOSQ_ERR_SUCCESS;
				}else{
					_mosquitto_packet_cleanup(&mosq->in_packet);
					switch(errno){
						case 0:
							return MOSQ_ERR_PROXY;
						case COMPAT_ECONNRESET:
							return MOSQ_ERR_CONN_LOST;
						default:
							return MOSQ_ERR_ERRNO;
					}
				}
			}
		}
		if(mosq->in_packet.payload[0] != 1){
			_mosquitto_packet_cleanup(&mosq->in_packet);
			return MOSQ_ERR_PROXY;
		}
		if(mosq->in_packet.payload[1] == 0){
			_mosquitto_packet_cleanup(&mosq->in_packet);
			mosq->state = mosq_cs_socks5_auth_ok;
			return mosquitto__socks5_send(mosq);
		}else{
			i = mosq->in_packet.payload[1];
			_mosquitto_packet_cleanup(&mosq->in_packet);
			switch(i){
				case SOCKS_REPLY_CONNECTION_NOT_ALLOWED:
					return MOSQ_ERR_AUTH;

				case SOCKS_REPLY_NETWORK_UNREACHABLE:
				case SOCKS_REPLY_HOST_UNREACHABLE:
				case SOCKS_REPLY_CONNECTION_REFUSED:
					return MOSQ_ERR_NO_CONN;

				case SOCKS_REPLY_GENERAL_FAILURE:
				case SOCKS_REPLY_TTL_EXPIRED:
				case SOCKS_REPLY_COMMAND_NOT_SUPPORTED:
				case SOCKS_REPLY_ADDRESS_TYPE_NOT_SUPPORTED:
					return MOSQ_ERR_PROXY;

				default:
					return MOSQ_ERR_INVAL;
			}
			return MOSQ_ERR_PROXY;
		}
	}else if(mosq->state == mosq_cs_socks5_request){
		while(mosq->in_packet.to_process > 0){
			len = _mosquitto_net_read(mosq, &(mosq->in_packet.payload[mosq->in_packet.pos]), mosq->in_packet.to_process);
			if(len > 0){
				mosq->in_packet.pos += len;
				mosq->in_packet.to_process -= len;
			}else{
#ifdef WIN32
				errno = WSAGetLastError();
#endif
				if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
					return MOSQ_ERR_SUCCESS;
				}else{
					_mosquitto_packet_cleanup(&mosq->in_packet);
					switch(errno){
						case 0:
							return MOSQ_ERR_PROXY;
						case COMPAT_ECONNRESET:
							return MOSQ_ERR_CONN_LOST;
						default:
							return MOSQ_ERR_ERRNO;
					}
				}
			}
		}

		if(mosq->in_packet.packet_length == 5){
			/* First part of the packet has been received, we now know what else to expect. */
			if(mosq->in_packet.payload[3] == SOCKS_ATYPE_IP_V4){
				mosq->in_packet.to_process += 4+2-1; /* 4 bytes IPv4, 2 bytes port, -1 byte because we've already read the first byte */
				mosq->in_packet.packet_length += 4+2-1;
			}else if(mosq->in_packet.payload[3] == SOCKS_ATYPE_IP_V6){
				mosq->in_packet.to_process += 16+2-1; /* 16 bytes IPv6, 2 bytes port, -1 byte because we've already read the first byte */
				mosq->in_packet.packet_length += 16+2-1;
			}else if(mosq->in_packet.payload[3] == SOCKS_ATYPE_DOMAINNAME){
				if(mosq->in_packet.payload[4] > 0 && mosq->in_packet.payload[4] <= 255){
					mosq->in_packet.to_process += mosq->in_packet.payload[4];
					mosq->in_packet.packet_length += mosq->in_packet.payload[4];
				}
			}else{
				_mosquitto_packet_cleanup(&mosq->in_packet);
				return MOSQ_ERR_PROTOCOL;
			}
			payload = _mosquitto_realloc(mosq->in_packet.payload, mosq->in_packet.packet_length);
			if(payload){
				mosq->in_packet.payload = payload;
			}else{
				_mosquitto_packet_cleanup(&mosq->in_packet);
				return MOSQ_ERR_NOMEM;
			}
			payload = _mosquitto_realloc(mosq->in_packet.payload, mosq->in_packet.packet_length);
			if(payload){
				mosq->in_packet.payload = payload;
			}else{
				_mosquitto_packet_cleanup(&mosq->in_packet);
				return MOSQ_ERR_NOMEM;
			}
			return MOSQ_ERR_SUCCESS;
		}

		/* Entire packet is now read. */
		if(mosq->in_packet.payload[0] != 5){
			_mosquitto_packet_cleanup(&mosq->in_packet);
			return MOSQ_ERR_PROXY;
		}
		if(mosq->in_packet.payload[1] == 0){
			/* Auth passed */
			_mosquitto_packet_cleanup(&mosq->in_packet);
			mosq->state = mosq_cs_new;
			return _mosquitto_send_connect(mosq, mosq->keepalive, mosq->clean_session);
		}else{
			i = mosq->in_packet.payload[1];
			_mosquitto_packet_cleanup(&mosq->in_packet);
			mosq->state = mosq_cs_socks5_new;
			switch(i){
				case SOCKS_REPLY_CONNECTION_NOT_ALLOWED:
					return MOSQ_ERR_AUTH;

				case SOCKS_REPLY_NETWORK_UNREACHABLE:
				case SOCKS_REPLY_HOST_UNREACHABLE:
				case SOCKS_REPLY_CONNECTION_REFUSED:
					return MOSQ_ERR_NO_CONN;

				case SOCKS_REPLY_GENERAL_FAILURE:
				case SOCKS_REPLY_TTL_EXPIRED:
				case SOCKS_REPLY_COMMAND_NOT_SUPPORTED:
				case SOCKS_REPLY_ADDRESS_TYPE_NOT_SUPPORTED:
					return MOSQ_ERR_PROXY;

				default:
					return MOSQ_ERR_INVAL;
			}
		}
	}else{
		return _mosquitto_packet_read(mosq);
	}
	return MOSQ_ERR_SUCCESS;
}
Exemplo n.º 5
0
static void loop_handle_reads_writes(struct mosquitto_db *db, struct epoll_event *events, int efd)
{
    int i, s;

    for (i = 0; i < db->context_count; i++) {
        if (db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
            /* if (events[db->contexts[i]->pollfd_index].data.fd != db->contexts[i]->sock) { */
            /*     printf ("%d---%d\n", events[db->contexts[i]->pollfd_index].data.fd, db->contexts[i]->sock); */
            /*     printf ("%d\n", i); */
            /*     int n; */
            /*     for (n = 0; n < sizeof (db->contexts); ++n) */
            /*     { */
            /*         printf ("%d----%d\n", db->contexts[n]->pollfd_index, events[db->contexts[i]->pollfd_index].data.fd); */
            /*     } */
            /* } */
            /* assert(events[db->contexts[i]->pollfd_index].data.fd == db->contexts[i]->sock); */
#ifdef WITH_TLS
            if (events[db->contexts[i]->pollfd_index].events & EPOLLOUT ||
               db->contexts[i]->want_write ||
               (db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)) {
#else
                if(events[db->contexts[i]->epollfd_index].events & EPOLLOUT){
#endif
                    if(_mosquitto_packet_write(db->contexts[i])){
                        if(db->config->connection_messages == true){
                            if(db->contexts[i]->state != mosq_cs_disconnecting){
                                _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket write error on client %s, disconnecting.", db->contexts[i]->id);
                            }else{
                                _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
                            }
                        }
                        /* Write error or other that means we should disconnect */
                        mqtt3_context_disconnect(db, db->contexts[i]);
                    }
                }
            }
            if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
                /* assert(events[db->contexts[i]->pollfd_index].data.fd == db->contexts[i]->sock); */
#ifdef WITH_TLS
                if(events[db->contexts[i]->pollfd_index].events & EPOLLIN ||
                   db->contexts[i]->want_read ||
                   (db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)){
#else
                    if(events[db->contexts[i]->pollfd_index].events & EPOLLIN){
#endif
                        if(_mosquitto_packet_read(db, db->contexts[i])){
                            if(db->config->connection_messages == true){
                                if(db->contexts[i]->state != mosq_cs_disconnecting){
                                    _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket read error on client %s, disconnecting.", db->contexts[i]->id);
                                }else{
                                    _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
                                }
                            }
                            /* Read error or other that means we should disconnect */
                            mqtt3_context_disconnect(db, db->contexts[i]);
                        }
                    }
                }

                if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
                    if(events[db->contexts[i]->pollfd_index].events & (EPOLLHUP | POLLRDHUP | EPOLLERR)){
                        s = epoll_ctl (efd, EPOLL_CTL_DEL, events[db->contexts[i]->pollfd_index].data.fd, &events[db->contexts[i]->pollfd_index]);
                        do_disconnect(db, i);
                    }
                }
       }
}
Exemplo n.º 6
0
int mosquitto_loop_read(struct mosquitto *mosq)
{
	return _mosquitto_packet_read(mosq);
}