Пример #1
0
int _mosquitto_packet_write(struct mosquitto *mosq)
{
	ssize_t write_length;
	struct _mosquitto_packet *packet;

	if(!mosq) return MOSQ_ERR_INVAL;
	if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;

	while(mosq->out_packet){
		packet = mosq->out_packet;

		while(packet->to_process > 0){
			write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process);
			if(write_length > 0){
#ifdef WITH_BROKER
				bytes_sent += write_length;
#endif
				packet->to_process -= write_length;
				packet->pos += write_length;
			}else{
#ifdef WIN32
				errno = WSAGetLastError();
#endif
				if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
					return MOSQ_ERR_SUCCESS;
				}else{
					switch(errno){
						case COMPAT_ECONNRESET:
							return MOSQ_ERR_CONN_LOST;
						default:
							return MOSQ_ERR_ERRNO;
					}
				}
			}
		}

#ifdef WITH_BROKER
		msgs_sent++;
#else
		if(((packet->command)&0xF6) == PUBLISH && mosq->on_publish){
			/* This is a QoS=0 message */
			mosq->in_callback = true;
			mosq->on_publish(mosq->obj, packet->mid);
			mosq->in_callback = false;
		}
#endif

		/* Free data and reset values */
		mosq->out_packet = packet->next;
		_mosquitto_packet_cleanup(packet);
		_mosquitto_free(packet);

		mosq->last_msg_out = time(NULL);
	}
	return MOSQ_ERR_SUCCESS;
}
Пример #2
0
int _mosquitto_packet_write(struct mosquitto *mosq)
{
	ssize_t write_length;
	struct _mosquitto_packet *packet;

	if(!mosq) return MOSQ_ERR_INVAL;
	if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;

	pthread_mutex_lock(&mosq->current_out_packet_mutex);
	pthread_mutex_lock(&mosq->out_packet_mutex);
	if(mosq->out_packet && !mosq->current_out_packet){
		mosq->current_out_packet = mosq->out_packet;
		mosq->out_packet = mosq->out_packet->next;
		if(!mosq->out_packet){
			mosq->out_packet_last = NULL;
		}
	}
	pthread_mutex_unlock(&mosq->out_packet_mutex);

	if(mosq->state == mosq_cs_connect_pending){
		pthread_mutex_unlock(&mosq->current_out_packet_mutex);
		return MOSQ_ERR_SUCCESS;
	}

	while(mosq->current_out_packet){
		packet = mosq->current_out_packet;

		while(packet->to_process > 0){
			write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process);
			if(write_length > 0){
#if defined(WITH_BROKER) && defined(WITH_SYS_TREE)
				g_bytes_sent += write_length;
#endif
				packet->to_process -= write_length;
				packet->pos += write_length;
			}else{
#ifdef WIN32
				errno = WSAGetLastError();
#endif
				if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
					pthread_mutex_unlock(&mosq->current_out_packet_mutex);
					return MOSQ_ERR_SUCCESS;
				}else{
					pthread_mutex_unlock(&mosq->current_out_packet_mutex);
					switch(errno){
						case COMPAT_ECONNRESET:
							return MOSQ_ERR_CONN_LOST;
						default:
							return MOSQ_ERR_ERRNO;
					}
				}
			}
		}

#ifdef WITH_BROKER
#  ifdef WITH_SYS_TREE
		g_msgs_sent++;
		if(((packet->command)&0xF6) == PUBLISH){
			g_pub_msgs_sent++;
		}
#  endif
#else
		if(((packet->command)&0xF6) == PUBLISH){
			pthread_mutex_lock(&mosq->callback_mutex);
			if(mosq->on_publish){
				/* This is a QoS=0 message */
				mosq->in_callback = true;
				mosq->on_publish(mosq, mosq->userdata, packet->mid);
				mosq->in_callback = false;
			}
			pthread_mutex_unlock(&mosq->callback_mutex);
		}else if(((packet->command)&0xF0) == DISCONNECT){
			/* FIXME what cleanup needs doing here? 
			 * incoming/outgoing messages? */
			_mosquitto_socket_close(mosq);

			/* Start of duplicate, possibly unnecessary code.
			 * This does leave things in a consistent state at least. */
			/* Free data and reset values */
			pthread_mutex_lock(&mosq->out_packet_mutex);
			mosq->current_out_packet = mosq->out_packet;
			if(mosq->out_packet){
				mosq->out_packet = mosq->out_packet->next;
				if(!mosq->out_packet){
					mosq->out_packet_last = NULL;
				}
			}
			pthread_mutex_unlock(&mosq->out_packet_mutex);

			_mosquitto_packet_cleanup(packet);
			_mosquitto_free(packet);

			pthread_mutex_lock(&mosq->msgtime_mutex);
			mosq->last_msg_out = mosquitto_time();
			pthread_mutex_unlock(&mosq->msgtime_mutex);
			/* End of duplicate, possibly unnecessary code */

			pthread_mutex_lock(&mosq->callback_mutex);
			if(mosq->on_disconnect){
				mosq->in_callback = true;
				mosq->on_disconnect(mosq, mosq->userdata, 0);
				mosq->in_callback = false;
			}
			pthread_mutex_unlock(&mosq->callback_mutex);
			pthread_mutex_unlock(&mosq->current_out_packet_mutex);
			return MOSQ_ERR_SUCCESS;
		}
#endif

		/* Free data and reset values */
		pthread_mutex_lock(&mosq->out_packet_mutex);
		mosq->current_out_packet = mosq->out_packet;
		if(mosq->out_packet){
			mosq->out_packet = mosq->out_packet->next;
			if(!mosq->out_packet){
				mosq->out_packet_last = NULL;
			}
		}
		pthread_mutex_unlock(&mosq->out_packet_mutex);

		_mosquitto_packet_cleanup(packet);
		_mosquitto_free(packet);

		pthread_mutex_lock(&mosq->msgtime_mutex);
		mosq->last_msg_out = mosquitto_time();
		pthread_mutex_unlock(&mosq->msgtime_mutex);
	}
	pthread_mutex_unlock(&mosq->current_out_packet_mutex);
	return MOSQ_ERR_SUCCESS;
}
Пример #3
0
int _mosquitto_packet_write(struct mosquitto *mosq)
{
	ssize_t write_length;
	struct _mosquitto_packet *packet;

	if(!mosq) return MOSQ_ERR_INVAL;
	if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;

	pthread_mutex_lock(&mosq->current_out_packet_mutex);
	pthread_mutex_lock(&mosq->out_packet_mutex);
	if(mosq->out_packet && !mosq->current_out_packet){
		mosq->current_out_packet = mosq->out_packet;
		mosq->out_packet = mosq->out_packet->next;
		if(!mosq->out_packet){
			mosq->out_packet_last = NULL;
		}
	}
	pthread_mutex_unlock(&mosq->out_packet_mutex);

	while(mosq->current_out_packet){
		packet = mosq->current_out_packet;

		while(packet->to_process > 0){
			write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process);
			if(write_length > 0){
#if defined(WITH_BROKER) && defined(WITH_SYS_TREE)
				g_bytes_sent += write_length;
#endif
				packet->to_process -= write_length;
				packet->pos += write_length;
			}else{
#ifdef WIN32
				errno = WSAGetLastError();
#endif
				if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
					pthread_mutex_unlock(&mosq->current_out_packet_mutex);
					return MOSQ_ERR_SUCCESS;
				}else{
					pthread_mutex_unlock(&mosq->current_out_packet_mutex);
					switch(errno){
						case COMPAT_ECONNRESET:
							return MOSQ_ERR_CONN_LOST;
						default:
							return MOSQ_ERR_ERRNO;
					}
				}
			}
		}

#ifdef WITH_BROKER
#  ifdef WITH_SYS_TREE
		g_msgs_sent++;
		if(((packet->command)&0xF6) == PUBLISH){
			g_pub_msgs_sent++;
		}
#  endif
#else
		if(((packet->command)&0xF6) == PUBLISH){
			pthread_mutex_lock(&mosq->callback_mutex);
			if(mosq->on_publish){
				/* This is a QoS=0 message */
				mosq->in_callback = true;
				mosq->on_publish(mosq, mosq->userdata, packet->mid);
				mosq->in_callback = false;
			}
			pthread_mutex_unlock(&mosq->callback_mutex);
		}
#endif

		/* Free data and reset values */
		pthread_mutex_lock(&mosq->out_packet_mutex);
		mosq->current_out_packet = mosq->out_packet;
		if(mosq->out_packet){
			mosq->out_packet = mosq->out_packet->next;
			if(!mosq->out_packet){
				mosq->out_packet_last = NULL;
			}
		}
		pthread_mutex_unlock(&mosq->out_packet_mutex);

		_mosquitto_packet_cleanup(packet);
		_mosquitto_free(packet);

		pthread_mutex_lock(&mosq->msgtime_mutex);
		mosq->last_msg_out = mosquitto_time();
		pthread_mutex_unlock(&mosq->msgtime_mutex);
	}
	pthread_mutex_unlock(&mosq->current_out_packet_mutex);
	return MOSQ_ERR_SUCCESS;
}
Пример #4
0
int _mosquitto_packet_write(struct mosquitto *mosq)
{
    ssize_t write_length;
    struct _mosquitto_packet *packet;

    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;

    while(mosq->out_packet) {
        packet = mosq->out_packet;

        while(packet->to_process > 0) {
            write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process);
            if(write_length > 0) {
#ifdef WITH_BROKER
                bytes_sent += write_length;
#endif
                packet->to_process -= write_length;
                packet->pos += write_length;
            } else {
#ifndef WIN32
                if(errno == EAGAIN || errno == EWOULDBLOCK) {
#else
                if(WSAGetLastError() == WSAEWOULDBLOCK) {
#endif
                    return MOSQ_ERR_SUCCESS;
                } else {
                    switch(errno) {
                    case COMPAT_ECONNRESET:
                        return MOSQ_ERR_CONN_LOST;
                    default:
                        return MOSQ_ERR_UNKNOWN;
                    }
                }
            }
        }

#ifdef WITH_BROKER
        msgs_sent++;
#else
        if(((packet->command)&0xF6) == PUBLISH && mosq->on_publish) {
            /* This is a QoS=0 message */
            mosq->in_callback = true;
            mosq->on_publish(mosq->obj, packet->mid);
            mosq->in_callback = false;
        }
#endif

        /* Free data and reset values */
        mosq->out_packet = packet->next;
        _mosquitto_packet_cleanup(packet);
        _mosquitto_free(packet);

        mosq->last_msg_out = time(NULL);
    }
    return MOSQ_ERR_SUCCESS;
}

#ifdef WITH_BROKER
int _mosquitto_packet_read(mosquitto_db *db, int context_index)
#else
int _mosquitto_packet_read(struct mosquitto *mosq)
#endif
{
    uint8_t byte;
    ssize_t read_length;
    int rc = 0;
#ifdef WITH_BROKER
    struct mosquitto *mosq;

    if(context_index < 0 || context_index >= db->context_count) return MOSQ_ERR_INVAL;
    mosq = db->contexts[context_index];
#endif

    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
    /* This gets called if pselect() indicates that there is network data
     * available - ie. at least one byte.  What we do depends on what data we
     * already have.
     * If we've not got a command, attempt to read one and save it. This should
     * always work because it's only a single byte.
     * Then try to read the remaining length. This may fail because it is may
     * be more than one byte - will need to save data pending next read if it
     * does fail.
     * Then try to read the remaining payload, where 'payload' here means the
     * combined variable header and actual payload. This is the most likely to
     * fail due to longer length, so save current data and current position.
     * After all data is read, send to _mosquitto_handle_packet() to deal with.
     * Finally, free the memory and reset everything to starting conditions.
     */
    if(!mosq->in_packet.command) {
        read_length = _mosquitto_net_read(mosq, &byte, 1);
        if(read_length == 1) {
            mosq->in_packet.command = byte;
#ifdef WITH_BROKER
            bytes_received++;
            /* Clients must send CONNECT as their first command. */
            if(!(mosq->bridge) && mosq->state == mosq_cs_new && (byte&0xF0) != CONNECT) return MOSQ_ERR_PROTOCOL;
#endif
        } else {
            if(read_length == 0) return MOSQ_ERR_CONN_LOST; /* EOF */
#ifndef WIN32
            if(errno == EAGAIN || errno == EWOULDBLOCK) {
#else
            if(WSAGetLastError() == WSAEWOULDBLOCK) {
#endif
                return MOSQ_ERR_SUCCESS;
            } else {
                switch(errno) {
                case COMPAT_ECONNRESET:
                    return MOSQ_ERR_CONN_LOST;
                default:
                    return MOSQ_ERR_UNKNOWN;
                }
            }
        }
    }
    if(!mosq->in_packet.have_remaining) {
        /* Read remaining
         * Algorithm for decoding taken from pseudo code at
         * http://publib.boulder.ibm.com/infocenter/wmbhelp/v6r0m0/topic/com.ibm.etools.mft.doc/ac10870_.htm
         */
        do {
            read_length = _mosquitto_net_read(mosq, &byte, 1);
            if(read_length == 1) {
                mosq->in_packet.remaining_count++;
                /* Max 4 bytes length for remaining length as defined by protocol.
                 * Anything more likely means a broken/malicious client.
                 */
                if(mosq->in_packet.remaining_count > 4) return MOSQ_ERR_PROTOCOL;

#ifdef WITH_BROKER
                bytes_received++;
#endif
                mosq->in_packet.remaining_length += (byte & 127) * mosq->in_packet.remaining_mult;
                mosq->in_packet.remaining_mult *= 128;
            } else {
                if(read_length == 0) return MOSQ_ERR_CONN_LOST; /* EOF */
#ifndef WIN32
                if(errno == EAGAIN || errno == EWOULDBLOCK) {
#else
                if(WSAGetLastError() == WSAEWOULDBLOCK) {
#endif
                    return MOSQ_ERR_SUCCESS;
                } else {
                    switch(errno) {
                    case COMPAT_ECONNRESET:
                        return MOSQ_ERR_CONN_LOST;
                    default:
                        return MOSQ_ERR_UNKNOWN;
                    }
                }
            }
        }
        while((byte & 128) != 0);

        if(mosq->in_packet.remaining_length > 0) {
            mosq->in_packet.payload = _mosquitto_malloc(mosq->in_packet.remaining_length*sizeof(uint8_t));
            if(!mosq->in_packet.payload) return MOSQ_ERR_NOMEM;
            mosq->in_packet.to_process = mosq->in_packet.remaining_length;
        }
        mosq->in_packet.have_remaining = 1;
    }
    while(mosq->in_packet.to_process>0) {
        read_length = _mosquitto_net_read(mosq, &(mosq->in_packet.payload[mosq->in_packet.pos]), mosq->in_packet.to_process);
        if(read_length > 0) {
#ifdef WITH_BROKER
            bytes_received += read_length;
#endif
            mosq->in_packet.to_process -= read_length;
            mosq->in_packet.pos += read_length;
        } else {
#ifndef WIN32
            if(errno == EAGAIN || errno == EWOULDBLOCK) {
#else
            if(WSAGetLastError() == WSAEWOULDBLOCK) {
#endif
                return MOSQ_ERR_SUCCESS;
            } else {
                switch(errno) {
                case COMPAT_ECONNRESET:
                    return MOSQ_ERR_CONN_LOST;
                default:
                    return MOSQ_ERR_UNKNOWN;
                }
            }
        }
    }

    /* All data for this packet is read. */
    mosq->in_packet.pos = 0;
#ifdef WITH_BROKER
    msgs_received++;
    rc = mqtt3_packet_handle(db, context_index);
#else
    rc = _mosquitto_packet_handle(mosq);
#endif

    /* Free data and reset values */
    _mosquitto_packet_cleanup(&mosq->in_packet);

    mosq->last_msg_in = time(NULL);
    return rc;
}