int mqtt3_handle_unsubscribe(struct mosquitto_db *db, struct mosquitto *context) { uint16_t mid; char *sub; if(!context) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBSCRIBE from %s", context->id); if(_mosquitto_read_uint16(&context->in_packet, &mid)) return 1; while(context->in_packet.pos < context->in_packet.remaining_length){ sub = NULL; if(_mosquitto_read_string(&context->in_packet, &sub)){ return 1; } if(sub){ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "\t%s", sub); mqtt3_sub_remove(db, context, sub, &db->subs); _mosquitto_log_printf(NULL, MOSQ_LOG_UNSUBSCRIBE, "%s %s", context->id, sub); _mosquitto_free(sub); } } #ifdef WITH_PERSISTENCE db->persistence_changes++; #endif return _mosquitto_send_command_with_mid(context, UNSUBACK, mid, false); }
int _mosquitto_handle_pubackcomp(struct mosquitto *mosq, const char *type) #endif { uint16_t mid; int rc; assert(mosq); rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); if(rc) return rc; #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received %s from %s (Mid: %d)", type, mosq->id, mid); if(mid){ rc = mqtt3_db_message_delete(db, mosq, mid, mosq_md_out); if(rc) return rc; } #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received %s (Mid: %d)", mosq->id, type, mid); if(!_mosquitto_message_delete(mosq, mid, mosq_md_out)){ /* Only inform the client the message has been sent once. */ pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_publish){ mosq->in_callback = true; mosq->on_publish(mosq, mosq->userdata, mid); mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); } #endif return MOSQ_ERR_SUCCESS; }
int _mosquitto_send_connack(struct mosquitto *context, int result) {//发送一个带2个数字的CONNACK回包给客户端,告诉他连接成功 struct _mosquitto_packet *packet = NULL; int rc; if(context){ if(context->id){ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending CONNACK to %s (%d)", context->id, result); }else{ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending CONNACK to %s (%d)", context->address, result); } } packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); if(!packet) return MOSQ_ERR_NOMEM; packet->command = CONNACK; packet->remaining_length = 2; rc = _mosquitto_packet_alloc(packet); if(rc){ _mosquitto_free(packet); return rc; } packet->payload[packet->pos+0] = 0; packet->payload[packet->pos+1] = result; return _mosquitto_packet_queue(context, packet); }
int _mosquitto_handle_pubrec(struct mosquitto *mosq) { uint16_t mid; int rc; assert(mosq); #ifdef WITH_STRICT_PROTOCOL if(mosq->in_packet.remaining_length != 2){ return MOSQ_ERR_PROTOCOL; } #endif rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); if(rc) return rc; #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREC from %s (Mid: %d)", mosq->id, mid); rc = mqtt3_db_message_update(mosq, mid, mosq_md_out, ms_wait_for_pubcomp); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREC (Mid: %d)", mosq->id, mid); rc = _mosquitto_message_update(mosq, mid, mosq_md_out, mosq_ms_wait_pubcomp); #endif if(rc) return rc; rc = _mosquitto_send_pubrel(mosq, mid, false); if(rc) return rc; return MOSQ_ERR_SUCCESS; }
int _mosquitto_handle_unsuback(struct mosquitto *mosq) { uint16_t mid; int rc; assert(mosq); #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received UNSUBACK", mosq->id); #endif rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); if(rc) return rc; #ifndef WITH_BROKER pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_unsubscribe){ mosq->in_callback = true; mosq->on_unsubscribe(mosq, mosq->userdata, mid); mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); #endif return MOSQ_ERR_SUCCESS; }
int _mosquitto_send_pingresp(struct mosquitto *mosq) { #ifdef WITH_BROKER if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PINGRESP to %s", mosq->id); #else if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PINGRESP", mosq->id); #endif return _mosquitto_send_simple_command(mosq, PINGRESP); }
int _mosquitto_send_pubrel(struct mosquitto *mosq, uint16_t mid, bool dup) { #ifdef WITH_BROKER if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBREL to %s (Mid: %d)", mosq->id, mid); #else if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBREL (Mid: %d)", mosq->id, mid); #endif return _mosquitto_send_command_with_mid(mosq, PUBREL|2, mid, dup); }
int _mosquitto_send_pubcomp(struct mosquitto *mosq, uint16_t mid) { #ifdef WITH_BROKER if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBCOMP to %s (Mid: %d)", mosq->id, mid); #else if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBCOMP (Mid: %d)", mosq->id, mid); #endif return _mosquitto_send_command_with_mid(mosq, PUBCOMP, mid, false); }
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); } } } }
int mqtt3_db_backup(mosquitto_db *db, bool cleanup, bool shutdown) { int rc = 0; FILE *db_fptr = NULL; uint32_t db_version = htonl(MOSQ_DB_VERSION); uint32_t crc = htonl(0); dbid_t i64temp; uint32_t i32temp; uint16_t i16temp; uint8_t i8temp; if(!db || !db->config || !db->config->persistence_filepath) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Saving in-memory database to %s.", db->config->persistence_filepath); if(cleanup){ mqtt3_db_store_clean(db); } db_fptr = fopen(db->config->persistence_filepath, "wb"); if(db_fptr == NULL){ goto error; } /* Header */ write_e(db_fptr, magic, 15); write_e(db_fptr, &crc, sizeof(uint32_t)); write_e(db_fptr, &db_version, sizeof(uint32_t)); /* DB config */ i16temp = htons(DB_CHUNK_CFG); write_e(db_fptr, &i16temp, sizeof(uint16_t)); /* chunk length */ i32temp = htonl(sizeof(dbid_t) + sizeof(uint8_t) + sizeof(uint8_t)); write_e(db_fptr, &i32temp, sizeof(uint32_t)); /* db written at broker shutdown or not */ i8temp = shutdown; write_e(db_fptr, &i8temp, sizeof(uint8_t)); i8temp = sizeof(dbid_t); write_e(db_fptr, &i8temp, sizeof(uint8_t)); /* last db mid */ i64temp = db->last_db_id; write_e(db_fptr, &i64temp, sizeof(dbid_t)); if(mqtt3_db_message_store_write(db, db_fptr)){ goto error; } mqtt3_db_client_write(db, db_fptr); mqtt3_db_subs_retain_write(db, db_fptr); fclose(db_fptr); return rc; error: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); if(db_fptr) fclose(db_fptr); return 1; }
int _mosquitto_handle_pingreq(struct mosquitto *mosq) { assert(mosq); #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGREQ from %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGREQ", mosq->id); #endif return _mosquitto_send_pingresp(mosq); }
static void do_disconnect(struct mosquitto_db *db, int context_index) { if (db->config->connection_messages == true) { if(db->contexts[context_index]->state != mosq_cs_disconnecting){ _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket error on client %s, disconnecting.", db->contexts[context_index]->id); }else{ _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[context_index]->id); } } mqtt3_context_disconnect(db, db->contexts[context_index]); }
int _mosquitto_handle_pingresp(struct mosquitto *mosq) { assert(mosq); mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */ #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGRESP", mosq->id); #endif return MOSQ_ERR_SUCCESS; }
int _mosquitto_send_disconnect(struct mosquitto *mosq) { assert(mosq); #ifdef WITH_BROKER # ifdef WITH_BRIDGE _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending DISCONNECT", mosq->id); # endif #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending DISCONNECT", mosq->id); #endif return _mosquitto_send_simple_command(mosq, DISCONNECT); }
static int _db_client_msg_restore(mosquitto_db *db, const char *client_id, uint16_t mid, uint8_t qos, uint8_t retain, uint8_t direction, uint8_t state, uint8_t dup, uint64_t store_id) { mosquitto_client_msg *cmsg, *tail; struct mosquitto_msg_store *store; struct mosquitto *context; cmsg = _mosquitto_calloc(1, sizeof(mosquitto_client_msg)); if(!cmsg){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } cmsg->store = NULL; cmsg->mid = mid; cmsg->qos = qos; cmsg->retain = retain; cmsg->direction = direction; cmsg->state = state; cmsg->dup = dup; store = db->msg_store; while(store){ if(store->db_id == store_id){ cmsg->store = store; cmsg->store->ref_count++; break; } store = store->next; } if(!cmsg->store){ _mosquitto_free(cmsg); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error restoring persistent database, message store corrupt."); return 1; } context = _db_find_or_add_context(db, client_id, 0); if(!context){ _mosquitto_free(cmsg); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error restoring persistent database, message store corrupt."); return 1; } if(context->msgs){ tail = context->msgs; while(tail->next){ tail = tail->next; } tail->next = cmsg; }else{ context->msgs = cmsg; } cmsg->next = NULL; return MOSQ_ERR_SUCCESS; }
int mqtt3_sub_add(struct mosquitto_db *db, struct mosquitto *context, const char *sub, int qos, struct _mosquitto_subhier *root) { int rc = 0; struct _mosquitto_subhier *subhier, *child; struct _sub_token *tokens = NULL, *tail; assert(root); assert(sub); if(_sub_topic_tokenise(sub, &tokens)) return 1; subhier = root->children; while(subhier){ if(!strcmp(subhier->topic, tokens->topic)){ rc = _sub_add(db, context, qos, subhier, tokens); break; } subhier = subhier->next; } if(!subhier){ child = _mosquitto_malloc(sizeof(struct _mosquitto_subhier)); if(!child){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } child->topic = _mosquitto_strdup(tokens->topic); if(!child->topic){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } child->subs = NULL; child->children = NULL; child->retained = NULL; if(db->subs.children){ child->next = db->subs.children; }else{ child->next = NULL; } db->subs.children = child; rc = _sub_add(db, context, qos, child, tokens); } while(tokens){ tail = tokens->next; _mosquitto_free(tokens->topic); _mosquitto_free(tokens); tokens = tail; } /* We aren't worried about -1 (already subscribed) return codes. */ if(rc == -1) rc = MOSQ_ERR_SUCCESS; return rc; }
int _mosquitto_send_pingreq(struct mosquitto *mosq) { int rc; assert(mosq); #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PINGREQ to %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PINGREQ", mosq->id); #endif rc = _mosquitto_send_simple_command(mosq, PINGREQ); if(rc == MOSQ_ERR_SUCCESS){ mosq->ping_t = mosquitto_time(); } return rc; }
int _mosquitto_handle_pingreq(struct mosquitto *mosq) { assert(mosq); #ifdef WITH_STRICT_PROTOCOL if(mosq->in_packet.remaining_length != 0){ return MOSQ_ERR_PROTOCOL; } #endif #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGREQ from %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGREQ", mosq->id); #endif return _mosquitto_send_pingresp(mosq); }
static int mqtt3_db_client_write(mosquitto_db *db, FILE *db_fptr) { int i; struct mosquitto *context; uint16_t i16temp, slen; uint32_t length; assert(db); assert(db_fptr); for(i=0; i<db->context_count; i++){ context = db->contexts[i]; if(context && context->clean_session == false){ length = htonl(2+strlen(context->id) + sizeof(uint16_t)); i16temp = htons(DB_CHUNK_CLIENT); write_e(db_fptr, &i16temp, sizeof(uint16_t)); write_e(db_fptr, &length, sizeof(uint32_t)); slen = strlen(context->id); i16temp = htons(slen); write_e(db_fptr, &i16temp, sizeof(uint16_t)); write_e(db_fptr, context->id, slen); i16temp = htons(context->last_mid); write_e(db_fptr, &i16temp, sizeof(uint16_t)); if(mqtt3_db_client_messages_write(db, db_fptr, context)) return 1; } } return MOSQ_ERR_SUCCESS; error: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); return 1; }
static void create_context_events( struct mosquitto_db* db, struct epoll_event* events, int* epollfd_index, int efd, time_t now, int i) { /* Local bridges never time out in this fashion. */ if (!(db->contexts[i]->keepalive) || db->contexts[i]->bridge || now - db->contexts[i]->last_msg_in < (time_t)(db->contexts[i]->keepalive) * 3 / 2) { if (mqtt3_db_message_write(db->contexts[i]) == MOSQ_ERR_SUCCESS) { nonblocking (db->contexts[i]->sock); events[*epollfd_index].data.fd = db->contexts[i]->sock; events[*epollfd_index].events = EPOLLIN | EPOLLRDHUP; if(db->contexts[i]->out_packet) { events[*epollfd_index].events |= EPOLLOUT; } epoll_ctl (efd, EPOLL_CTL_ADD, db->contexts[i]->sock, &events[*epollfd_index]); db->contexts[i]->pollfd_index = *epollfd_index; *epollfd_index = *epollfd_index + 1; } else { mqtt3_context_disconnect(db, db->contexts[i]); } } else{ if (db->config->connection_messages == true) { _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", db->contexts[i]->id); } /* Client has exceeded keepalive*1.5 */ mqtt3_context_disconnect(db, db->contexts[i]); } }
int mqtt3_handle_disconnect(struct mosquitto_db *db, struct mosquitto *context) { if(!context){ return MOSQ_ERR_INVAL; } if(context->in_packet.remaining_length != 0){ return MOSQ_ERR_PROTOCOL; } _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received DISCONNECT from %s", context->id); if(context->protocol == mosq_p_mqtt311){ if((context->in_packet.command&0x0F) != 0x00){ if(g_flag_epoll) { epoll_do_disconnect(db, context); } else { do_disconnect(db, context); } return MOSQ_ERR_PROTOCOL; } } context->state = mosq_cs_disconnecting; if(g_flag_epoll) { epoll_do_disconnect(db, context); } else { do_disconnect(db, context); } return MOSQ_ERR_SUCCESS; }
int _mosquitto_handle_pubrel(struct mosquitto *mosq) { uint16_t mid; struct mosquitto_message_all *message = NULL; int rc; assert(mosq); if(mosq->core.in_packet.remaining_length != 2){ return MOSQ_ERR_PROTOCOL; } rc = _mosquitto_read_uint16(&mosq->core.in_packet, &mid); if(rc) return rc; _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Received PUBREL (Mid: %d)", mid); if(!_mosquitto_message_remove(mosq, mid, mosq_md_in, &message)){ /* Only pass the message on if we have removed it from the queue - this * prevents multiple callbacks for the same message. */ if(mosq->on_message){ mosq->on_message(mosq->obj, &message->msg); }else{ _mosquitto_message_cleanup(&message); } } rc = _mosquitto_send_pubcomp(mosq, mid); if(rc) return rc; return MOSQ_ERR_SUCCESS; }
int _mosquitto_packet_handle(struct mosquitto *mosq) { assert(mosq); switch((mosq->in_packet.command)&0xF0){ case PINGREQ: return _mosquitto_handle_pingreq(mosq); case PINGRESP: return _mosquitto_handle_pingresp(mosq); case PUBACK: return _mosquitto_handle_pubackcomp(mosq, "PUBACK"); case PUBCOMP: return _mosquitto_handle_pubackcomp(mosq, "PUBCOMP"); case PUBLISH: return _mosquitto_handle_publish(mosq); case PUBREC: return _mosquitto_handle_pubrec(mosq); case PUBREL: return _mosquitto_handle_pubrel(NULL, mosq); case CONNACK: return _mosquitto_handle_connack(mosq); case SUBACK: return _mosquitto_handle_suback(mosq); case UNSUBACK: return _mosquitto_handle_unsuback(mosq); default: /* If we don't recognise the command, return an error straight away. */ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unrecognised command %d\n", (mosq->in_packet.command)&0xF0); return MOSQ_ERR_PROTOCOL; } }
int _mosquitto_handle_pingresp(struct mosquitto *mosq) { assert(mosq); #ifdef WITH_STRICT_PROTOCOL if(mosq->in_packet.remaining_length != 0){ return MOSQ_ERR_PROTOCOL; } #endif mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */ #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGRESP", mosq->id); #endif return MOSQ_ERR_SUCCESS; }
int _mosquitto_handle_connack(struct mosquitto *mosq) { uint8_t byte; uint8_t result; int rc; assert(mosq); if(mosq->core.in_packet.remaining_length != 2){ return MOSQ_ERR_PROTOCOL; } _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Received CONNACK"); rc = _mosquitto_read_byte(&mosq->core.in_packet, &byte); // Reserved byte, not used if(rc) return rc; rc = _mosquitto_read_byte(&mosq->core.in_packet, &result); if(rc) return rc; if(mosq->on_connect){ mosq->on_connect(mosq->obj, result); } switch(result){ case 0: mosq->core.state = mosq_cs_connected; return MOSQ_ERR_SUCCESS; case 1: case 2: case 3: case 4: case 5: return MOSQ_ERR_CONN_REFUSED; default: return MOSQ_ERR_PROTOCOL; } }
int _mosquitto_handle_suback(struct mosquitto *mosq) { uint16_t mid; uint8_t *granted_qos; int qos_count; int i = 0; int rc; assert(mosq); _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Received SUBACK"); rc = _mosquitto_read_uint16(&mosq->core.in_packet, &mid); if(rc) return rc; qos_count = mosq->core.in_packet.remaining_length - mosq->core.in_packet.pos; granted_qos = _mosquitto_malloc(qos_count*sizeof(uint8_t)); if(!granted_qos) return MOSQ_ERR_NOMEM; while(mosq->core.in_packet.pos < mosq->core.in_packet.remaining_length){ rc = _mosquitto_read_byte(&mosq->core.in_packet, &(granted_qos[i])); if(rc){ _mosquitto_free(granted_qos); return rc; } i++; } if(mosq->on_subscribe){ mosq->on_subscribe(mosq->obj, mid, qos_count, granted_qos); } _mosquitto_free(granted_qos); return MOSQ_ERR_SUCCESS; }
static int _mosquitto_connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address) { if(!mosq) return MOSQ_ERR_INVAL; if(!host || port <= 0) return MOSQ_ERR_INVAL; if(mosq->host) _mosquitto_free(mosq->host); mosq->host = _mosquitto_strdup(host); if(!mosq->host) return MOSQ_ERR_NOMEM; mosq->port = port; if(mosq->bind_address) _mosquitto_free(mosq->bind_address); if(bind_address){ mosq->bind_address = _mosquitto_strdup(bind_address); if(!mosq->bind_address) return MOSQ_ERR_NOMEM; } mosq->keepalive = keepalive; if(mosq->sockpairR != INVALID_SOCKET){ COMPAT_CLOSE(mosq->sockpairR); mosq->sockpairR = INVALID_SOCKET; } if(mosq->sockpairW != INVALID_SOCKET){ COMPAT_CLOSE(mosq->sockpairW); mosq->sockpairW = INVALID_SOCKET; } if(_mosquitto_socketpair(&mosq->sockpairR, &mosq->sockpairW)){ _mosquitto_log_printf(mosq, MOSQ_LOG_WARNING, "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); } return MOSQ_ERR_SUCCESS; }
int mqtt3_log_init(struct mqtt3_config *config) { int rc = 0; log_priorities = config->log_type; log_destinations = config->log_dest; if(log_destinations & MQTT3_LOG_SYSLOG){ #ifndef WIN32 openlog("mosquitto", LOG_PID|LOG_CONS, config->log_facility); #else syslog_h = OpenEventLog(NULL, "mosquitto"); #endif } if(log_destinations & MQTT3_LOG_FILE){ if(drop_privileges(config, true)){ return 1; } config->log_fptr = _mosquitto_fopen(config->log_file, "at"); if(!config->log_fptr){ log_destinations = MQTT3_LOG_STDERR; log_priorities = MOSQ_LOG_ERR; _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file); return MOSQ_ERR_INVAL; } restore_privileges(); } return rc; }
int mqtt3_handle_unsubscribe(struct mosquitto_db *db, struct mosquitto *context) { uint16_t mid; char *sub; if(!context) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBSCRIBE from %s", context->id); if(context->protocol == mosq_p_mqtt311){ if((context->in_packet.command&0x0F) != 0x02){ return MOSQ_ERR_PROTOCOL; } } if(_mosquitto_read_uint16(&context->in_packet, &mid)) return 1; g_epoll_unsubscribe_num++; while(context->in_packet.pos < context->in_packet.remaining_length){ sub = NULL; if(_mosquitto_read_string(&context->in_packet, &sub)){ return 1; } if(sub){ if(!strlen(sub)){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Empty unsubscription string from %s, disconnecting.", context->id); _mosquitto_free(sub); return 1; } if(mosquitto_sub_topic_check(sub)){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid unsubscription string from %s, disconnecting.", context->id); _mosquitto_free(sub); return 1; } _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "\t%s", sub); mqtt3_sub_remove(db, context, sub, &db->subs); _mosquitto_log_printf(NULL, MOSQ_LOG_UNSUBSCRIBE, "%s %s", context->id, sub); _mosquitto_free(sub); } } #ifdef WITH_PERSISTENCE db->persistence_changes++; #endif return _mosquitto_send_command_with_mid(context, UNSUBACK, mid, false); }
static int _db_client_msg_chunk_restore(mosquitto_db *db, FILE *db_fptr) { dbid_t i64temp, store_id; uint16_t i16temp, slen, mid; uint8_t qos, retain, direction, state, dup; char *client_id = NULL; int rc; read_e(db_fptr, &i16temp, sizeof(uint16_t)); slen = ntohs(i16temp); if(!slen){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Corrupt persistent database."); fclose(db_fptr); return 1; } client_id = _mosquitto_calloc(slen+1, sizeof(char)); if(!client_id){ fclose(db_fptr); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } read_e(db_fptr, client_id, slen); read_e(db_fptr, &i64temp, sizeof(dbid_t)); store_id = i64temp; read_e(db_fptr, &i16temp, sizeof(uint16_t)); mid = ntohs(i16temp); read_e(db_fptr, &qos, sizeof(uint8_t)); read_e(db_fptr, &retain, sizeof(uint8_t)); read_e(db_fptr, &direction, sizeof(uint8_t)); read_e(db_fptr, &state, sizeof(uint8_t)); read_e(db_fptr, &dup, sizeof(uint8_t)); rc = _db_client_msg_restore(db, client_id, mid, qos, retain, direction, state, dup, store_id); _mosquitto_free(client_id); return rc; error: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); if(db_fptr) fclose(db_fptr); if(client_id) _mosquitto_free(client_id); return 1; }