// Main server process that continuously runs until cntrl-c int main(int argc, char* argv[]) { pid_t spid, term_pid; /* pid_t is typedef for Linux process ID */ int chld_status; bool forever = true; if (argc < 2) { printf("No port specified\n"); return (-1); } /* create a "welcoming" socket at the specified port */ welcome_socket = ServerSocket_new(atoi(argv[1])); if (welcome_socket < 0) { printf("Failed new server socket\n"); return (-1); } /* The daemon infinite loop begins here; terminate with external action*/ while (forever) { /* accept an incoming client connection; blocks the * process until a connection attempt by a client. * creates a new data transfer socket. */ connect_socket = ServerSocket_accept(welcome_socket); if (connect_socket < 0) { printf("Failed accept on server socket\n"); exit (-1); } spid = fork(); /* create child == service process */ if (spid == -1) { perror("fork"); exit (-1); } if (spid == 0) {/* code for the service process */ ForkExecuteRedirect_service(); Socket_close(connect_socket); exit (0); } /* end service process */ else /* daemon process closes its connect socket */ { Socket_close(connect_socket); /* reap a zombie every time through the loop, avoid blocking*/ term_pid = waitpid(-1, &chld_status, WNOHANG); } } /* end of infinite loop for daemon process */ }
void MQTTClient_closeSession(Clients* client) { FUNC_ENTRY; client->good = 0; client->ping_outstanding = 0; if (client->net.socket > 0) { if (client->connected) MQTTPacket_send_disconnect(&client->net, client->clientID); Thread_lock_mutex(socket_mutex); #if defined(OPENSSL) SSLSocket_close(&client->net); #endif Socket_close(client->net.socket); Thread_unlock_mutex(socket_mutex); client->net.socket = 0; #if defined(OPENSSL) client->net.ssl = NULL; #endif } client->connected = 0; client->connect_state = 0; if (client->cleansession) MQTTClient_cleanSession(client); FUNC_EXIT; }
void MQTTProtocol_closeSession(Clients* client, int sendwill) { FUNC_ENTRY; client->good = 0; if (client->net.socket > 0) { if (client->connected || client->connect_state) { MQTTPacket_send_disconnect(&client->net, client->clientID); client->connected = 0; client->connect_state = 0; } #if defined(OPENSSL) SSLSocket_close(&client->net); #endif Socket_close(client->net.socket); client->net.socket = 0; #if defined(OPENSSL) client->net.ssl = NULL; #endif } if (client->cleansession) MQTTClient_cleanSession(client); FUNC_EXIT; }
// Sets up the service, ForkExecuteRedirect helper actually execs code void ForkExecuteRedirect_service(void) { int i, c, rc; int count = 0; bool forever = true; char input [INPUT_SIZE_MAX] = ""; int numArguments = 0; pid_t childPID; char** arguments = NULL; int input_index = 0; /* will not use the server socket */ Socket_close(welcome_socket); while (forever) /* actually, until EOF on connect socket */ { /* get a null-terminated string from the client on the data * transfer socket up to the maximim input line size. Continue * getting strings from the client until EOF on the socket. */ for (i = 0; i < MAX_LINE; i++) { c = Socket_getc(connect_socket); if (c == EOF) { printf("Socket_getc EOF or error\n"); return; /* assume socket EOF ends service for this client */ } else { if (c == '\n'){ // command entered input[input_index] = ' '; input[input_index + 1] = '\0'; // null-terminates string //printf("input: [%s]\n", input); arguments = getArgs(input, &numArguments); ForkExecuteRedirect_helper(numArguments, arguments); } else{ // command not entered, just continue filling input buffer if (input_index <= INPUT_SIZE_MAX){ input[input_index] = c; input[input_index + 1] = '\0'; input_index++; } else // if input size too large printf("max input size reached, no more input will be processed\n"); } } } } /* end while loop of the service process */ return; }
void check_put(int rc, void *p){ Socket *s = p; Socket connect_socket = *s; if (rc == EOF){ printf("Socket_putc EOF or error\n"); Socket_close(connect_socket); exit (ERROR); /* assume socket problem is fatal*/ } }
/* * Ftp_Connect - connect to remote server * * return 1 if connected, 0 if not */ int Ftp_Connect(const char *host, int port, netbuf **nControl) { int socket_d = 0; netbuf *ctrl; socket_d = Socket_Connect(host, port); if (socket_d > 0) { // allocate and fill in netbuf structure ctrl = calloc(1,sizeof(netbuf)); if (ctrl == NULL) { Socket_close(socket_d); return 0; } ctrl->buf = malloc(FTP_BUFSIZ); if (ctrl->buf == NULL) { Socket_close(socket_d); free(ctrl); return 0; } ctrl->handle = socket_d; ctrl->dir = FTP_CONTROL; if (readresp('2', ctrl) == 0) { Socket_close(socket_d); free(ctrl->buf); free(ctrl); return 0; } *nControl = ctrl; return 1; } else return 0; }
/* * Ftp_Quit - disconnect from remote * * return 1 if successful, 0 otherwise */ void Ftp_Quit(netbuf *nControl) { if (nControl->dir != FTP_CONTROL) return; Ftp_Send("QUIT",'2',nControl); Socket_close(nControl->handle); free(nControl->buf); free(nControl); #ifdef WIN32 // Clean up for windows WSACleanup (); #endif }
/*============================================================================== * Name : void Client_stop_cb(struct ev_loop* lp, ev_timer* wt, int ev) * Abstr : Time to close the connection and start the re-connect timer * Params : struct ev_loop* lp: inner event loop * ev_timer* wt: timer watcher * int ev: specific event * Return : * Modify : *=============================================================================*/ static void Client_stop_cb(struct ev_loop* lp, ev_timer* wt, int ev) { CONN_INFO* conn; /* connection with servant server */ conn = container_of(wt, CONN_INFO, t_wt); /* free socket resource */ Socket_shutdown(&conn->fd, &conn->name[0]); Socket_close (&conn->fd, &conn->name[0]); /* prepare reconnect msg */ memset(&conn->s_buf[0], 0x00, SEND_LEN_MAX); Client_start_prepare(conn); /* re-start the connection with servant server */ Client_switch_to_start(conn); }
static void connectHostNext(ConnectState *connectState) { Socket *sock; while (connectState->infoPtr != NULL) { sock = tryConnectHostNext(connectState); if (sock != Socket_noSocket) { // Connection succeeded or connection in progress connectState->nd = NetDescriptor_new(sock, (void *) connectState); if (connectState->nd == NULL) { ConnectError error; int savedErrno = errno; log_add(log_Error, "NetDescriptor_new() failed: %s.\n", strerror(errno)); Socket_close(sock); freeaddrinfo(connectState->info); connectState->info = NULL; connectState->infoPtr = NULL; connectState->state = Connect_closed; error.state = Connect_connecting; error.err = savedErrno; doConnectErrorCallback(connectState, &error); return; } NetDescriptor_setWriteCallback(connectState->nd, connectCallback); setConnectTimeout(connectState); return; } connectState->infoPtr = connectState->infoPtr->ai_next; } // Connect failed to all addresses. if (connectState->flags.retryDelayMs == Connect_noRetry) { connectHostReportAllFailed(connectState); return; } setConnectRetryAlarm(connectState); }
static int send_msg( char *dest_addr, char *return_addr, NodeMessage *msg ) { int dest_port, buflen = SENDBUF_LEN; char *colon, buf[SENDBUF_LEN], dest_host[16]; int sock; colon = strchr( (const char*)dest_addr, ':' ); if (colon == NULL) { Dbg_printf( NODE, ERROR, "send_msg, ':' not found in the dest_addr=%s\n", dest_addr ); return -1; } memcpy( dest_host, dest_addr, sizeof(char) * (colon - dest_addr) ); dest_host[colon - dest_addr] = '\0'; dest_port = atoi( colon + 1 ); if ((sock = Socket_create()) < 0 ) { Dbg_printf( NODE, ERROR, "send_msg, socket creation failed\n" ); return -1; } node_set_return_addr( msg, return_addr ); if (Socket_connect( sock, dest_host, dest_port ) < 0) { Dbg_printf( NODE, ERROR, "send_msg, socket connect failed\n" ); return -1; } if (node_stringify_msg( msg, buf, &buflen ) < 0 ) { Dbg_printf( NODE, ERROR, "send_msg, msg stringify failed\n" ); return -1; } Socket_send_data( sock, buf, buflen ); Socket_close( sock ); Dbg_printf( NODE, API, "%s message sent to %s\n", node_msgid2str( msg->msgid ), dest_addr ); return 0; }
void MQTTProtocol_closeSession(Clients* client, int sendwill) { FUNC_ENTRY; client->good = 0; if (client->socket > 0) { if (client->connected || client->connect_state) { MQTTPacket_send_disconnect(client->socket, client->clientID); client->connected = 0; client->connect_state = 0; } Socket_close(client->socket); client->socket = 0; } if (client->cleansession) MQTTClient_cleanSession(client); FUNC_EXIT; }
IoObject *IoSocket_close(IoSocket *self, IoObject *locals, IoMessage *m) { //doc Socket close Closes the socket and returns self. Returns nil on error. if (Socket_close(SOCKET(self))) { IoSocket_rawSetupEvents(self, locals, m); return self; } else { if (Socket_closeFailed()) { return SOCKETERROR("Failed to close socket"); } else { return IONIL(self); } } }
int main(int argc, char* argv[]) { int i, c, rc, fc; int count = 0; char line_data[MAX_LINE]; /* variable to hold socket descriptor */ Socket connect_socket; if (argc < 3) { printf("No host and port\n"); return (-1); } /* connect to the server at the specified host and port; * blocks the process until the connection is accepted * by the server; creates a new data transfer socket. */ connect_socket = Socket_new(argv[1], atoi(argv[2])); if (connect_socket < 0) { printf("Failed to connect to server\n"); return (-1); } printf("%% "); // print initial prompt /* get a string from stdin up to and including * a newline or to the maximim input line size. * Continue getting strings from stdin until EOF. */ while ((fgets(line_data, sizeof(line_data), stdin) != NULL)) { count = strlen(line_data) + 1; /* count includes '\0' */ /* send the characters of the input line to the server * using the data transfer socket. */ for (i = 0; i < count; i++) { c = line_data[i]; rc = Socket_putc(c, connect_socket); // if (rc == EOF) // { // printf("Socket_putc EOF or error\n"); // Socket_close(connect_socket); // exit (-1); /* assume socket problem is fatal, end client */ // } } /* receive the converted characters for the string from * the server using the data transfer socket. */ printf("boutta receive\n"); while (1) { fc = Socket_getc(connect_socket); printf("%c", fc); if (fc == '\0') { break; } } printf("%% "); // print prompt for next command } /* end of while loop; at EOF */ Socket_close(connect_socket); exit(0); }
int MQTTSProtocol_handleConnects(void* pack, int sock, char* clientAddr, Clients* client, uint8_t* wirelessNodeId , uint8_t wirelessNodeIdLen) { MQTTS_Connect* connect = (MQTTS_Connect*)pack; Listener* list = NULL; int terminate = 0; Node* elem = NULL; int rc = 0; int existingClient = 0; FUNC_ENTRY; Log(LOG_PROTOCOL, 39, NULL, sock, clientAddr, client ? client->clientID : "", connect->flags.cleanSession); if (bstate->clientid_prefixes->count > 0 && !ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare)) { Log(LOG_WARNING, 31, NULL, connect->clientID); terminate = 1; } else { list = Socket_getParentListener(sock); if (list->max_connections > -1 && list->connections->count > list->max_connections) { /* TODO: why is this commented out? delete if not needed //MQTTPacket_send_connack(3, sock); */ Log(LOG_WARNING, 141, NULL, connect->clientID, list->max_connections, list->port); terminate = 1; } else if (connect->protocolID != 1) { Log(LOG_WARNING, 32, NULL, "MQTT-S", connect->protocolID); /* TODO: why is this commented out? delete if not needed //MQTTPacket_send_connack(1, sock); */ terminate = 1; } } if (terminate) { /*TODO: process the terminate*/ MQTTSPacket_free_packet(pack); goto exit; } if (client != NULL && !strcmp(client->clientID, connect->clientID)) { /* Connect for a new client id on a used addr * TODO: clean out 'old' Client (that may be 'connected') */ } elem = TreeFindIndex(bstate->mqtts_clients, connect->clientID, 1); if (elem == NULL) { client = TreeRemoveKey(bstate->disconnected_mqtts_clients, connect->clientID); if (client == NULL) /* this is a totally new connection */ { /* Brand new client connection */ int i; client = malloc(sizeof(Clients)); memset(client, '\0', sizeof(Clients)); client->protocol = PROTOCOL_MQTTS; client->outboundMsgs = ListInitialize(); client->inboundMsgs = ListInitialize(); for (i = 0; i < PRIORITY_MAX; ++i) client->queuedMsgs[i] = ListInitialize(); client->registrations = ListInitialize(); client->noLocal = 0; /* (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0; */ client->clientID = connect->clientID; connect->clientID = NULL; /* don't want to free this space as it is being used in the clients tree below */ // Set Wireless Node ID if exists if ( wirelessNodeId == NULL) { client->wirelessNodeId = NULL ; client->wirelessNodeIdLen = 0 ; } else { client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ; memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ; client->wirelessNodeIdLen = wirelessNodeIdLen ; } } // // client == NULL else /* there is an existing disconnected client */ { /* Reconnect of a disconnected client */ free(client->addr); client->connect_state = 0; client->connected = 0; /* Do not connect until we know the connack has been sent */ // Delete Wireless Node ID if exists in existing client if ( wirelessNodeId == NULL) { if ( client->wirelessNodeId != NULL) free( client->wirelessNodeId ) ; client->wirelessNodeId = NULL ; client->wirelessNodeIdLen = 0 ; } else // Replace existing Wireless Node ID with value from current connect packet { if ( client->wirelessNodeId != NULL) free ( client->wirelessNodeId ) ; client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ; memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ; client->wirelessNodeIdLen = wirelessNodeIdLen ; } } // client != NULL client->good = 1; /* good is set to 0 in disconnect, so we need to reset it here */ client->keepAliveInterval = connect->keepAlive; client->cleansession = connect->flags.cleanSession; client->socket = sock; client->addr = malloc(strlen(clientAddr)+1); strcpy(client->addr, clientAddr); TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); if (client->cleansession) MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */ if (connect->flags.will) { client->connect_state = 1; rc = MQTTSPacket_send_willTopicReq(client); } else { client->connected = 1; rc = MQTTSPacket_send_connack(client, 0); /* send response */ } } else { /* Reconnect of a connected client */ client = (Clients*)(elem->content); if (client->connected) { Log(LOG_INFO, 34, NULL, connect->clientID, clientAddr); if (client->socket != sock) Socket_close(client->socket); } client->socket = sock; client->connected = 0; /* Do not connect until we know the connack has been sent */ client->connect_state = 0; // Delete Wireless Node ID if exists in existing client if ( wirelessNodeId == NULL) { if ( client->wirelessNodeId != NULL) free( client->wirelessNodeId ) ; client->wirelessNodeId = NULL ; client->wirelessNodeIdLen = 0 ; } else // Replace existing Wireless Node ID with value from current connect packet { if ( client->wirelessNodeId != NULL) free ( client->wirelessNodeId ) ; client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ; memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ; client->wirelessNodeIdLen = wirelessNodeIdLen ; } client->good = 1; if (client->addr != NULL) free(client->addr); client->addr = malloc(strlen(clientAddr)+1); strcpy(client->addr, clientAddr); client->cleansession = connect->flags.cleanSession; if (client->cleansession) { int i; MQTTProtocol_removeAllSubscriptions(client->clientID); /* empty pending message lists */ MQTTProtocol_emptyMessageList(client->outboundMsgs); MQTTProtocol_emptyMessageList(client->inboundMsgs); for (i = 0; i < PRIORITY_MAX; ++i) MQTTProtocol_emptyMessageList(client->queuedMsgs[i]); MQTTProtocol_clearWill(client); } /* registrations are always cleared */ MQTTSProtocol_emptyRegistrationList(client->registrations); /* have to remove and re-add client so it is in the right order for new socket */ if (client->socket != sock) { TreeRemoveNodeIndex(bstate->mqtts_clients, elem, 1); TreeRemoveKeyIndex(bstate->mqtts_clients, &client->socket, 0); client->socket = sock; TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } client->keepAliveInterval = connect->keepAlive; client->pendingRegistration = NULL; #if !defined(NO_BRIDGE) client->pendingSubscription = NULL; #endif if (connect->flags.will) { client->connect_state = 1; rc = MQTTSPacket_send_willTopicReq(client); } else { client->connected = 1; rc = MQTTSPacket_send_connack(client,0); /* send response */ } } if (existingClient) MQTTProtocol_processQueued(client); Log(LOG_INFO, 0, "Client connected to udp port %d from %s (%s)", list->port, client->clientID, clientAddr); MQTTSPacket_free_packet(pack); time( &(client->lastContact) ); exit: FUNC_EXIT_RC(rc); return rc; }
/** * Close any active session for a client and clean up. * @param client the client to clean up * @param send_will flag to indicate whether a will messsage should be sent if it has been set */ void MQTTProtocol_closeSession(Clients* client, int send_will) { FUNC_ENTRY; client->good = 0; if (in_MQTTPacket_Factory == client->socket || client->closing) goto exit; client->closing = 1; if (client->socket > 0) { if (client->connected) { if (client->outbound && client->will) { Publish pub; pub.payload = "0"; pub.payloadlen = 1; pub.topic = client->will->topic; #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) MQTTSProtocol_startPublishCommon(client, &pub, 0,0,1); if (client->protocol == PROTOCOL_MQTTS_DTLS) MQTTSProtocol_startPublishCommon(client, &pub, 0,0,1); //TODO LW else #endif MQTTPacket_send_publish(&pub, 0, 0, 1, client->socket, client->clientID); MQTTProtocol_sys_publish(client->will->topic, "0"); } #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS_MULTICAST) ; else if (client->protocol == PROTOCOL_MQTTS) MQTTSPacket_send_disconnect(client, 0); else if (client->protocol == PROTOCOL_MQTTS_DTLS) MQTTSPacket_send_disconnect(client, 0); else #endif if (client->outbound) MQTTPacket_send_disconnect(client->socket, client->clientID); } if (ListFindItem(&(state.pending_writes), &(client->socket), intcompare)) { pending_write* pw = (pending_write*)(state.pending_writes.current->content); MQTTProtocol_removePublication(pw->p); ListRemove(&(state.pending_writes), pw); } #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTT || client->outbound == 1) { if (client->protocol == PROTOCOL_MQTTS_MULTICAST) Socket_close_only(client->socket); else #endif Socket_close(client->socket); #if defined(MQTTS) } #endif } if (client->connected || client->connect_state) { client->connected = 0; client->connect_state = 0; } if (client->outbound == 0 && client->will != NULL && send_will) { Publish publish; publish.payload = client->will->msg; publish.payloadlen = strlen(client->will->msg); publish.topic = client->will->topic; publish.header.bits.qos = client->will->qos; publish.header.bits.retain = client->will->retained; Protocol_processPublication(&publish, client->clientID); } #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) MQTTSProtocol_emptyRegistrationList(client->registrations); else if (client->protocol == PROTOCOL_MQTTS_DTLS) MQTTSProtocol_emptyRegistrationList(client->registrations); #endif if (client->cleansession) { if (client->outbound && ((BridgeConnections*)(client->bridge_context))->state != CONNECTION_DELETE) { /* bridge outbound client structures are reused on reconnection */ int i; MQTTProtocol_removeAllSubscriptions(client->clientID); MQTTProtocol_emptyMessageList(client->inboundMsgs); MQTTProtocol_emptyMessageList(client->outboundMsgs); for (i = 0; i < PRIORITY_MAX; ++i) MQTTProtocol_emptyMessageList(client->queuedMsgs[i]); client->msgID = 0; } else { #if defined(MQTTS) if ((client->protocol == PROTOCOL_MQTTS && client->outbound == 0) || (client->protocol == PROTOCOL_MQTTS_DTLS && client->outbound == 0) || client->protocol == PROTOCOL_MQTTS_MULTICAST) { if (!TreeRemove(bstate->mqtts_clients, client) && !TreeRemove(bstate->disconnected_mqtts_clients, client)) Log(LOG_ERROR, 39, NULL); else Log(TRACE_MAX, 2, NULL, client->clientID, client->socket); } else { #endif if (!TreeRemove(bstate->clients, client) && !TreeRemove(bstate->disconnected_clients, client)) Log(LOG_ERROR, 39, NULL); else Log(TRACE_MAX, 2, NULL, client->clientID, client->socket); #if defined(MQTTS) } #endif MQTTProtocol_freeClient(client); } } else { int i; for (i = 0; i < PRIORITY_MAX; ++i) MQTTProtocol_removeQoS0Messages(client->queuedMsgs[i]); #if defined(MQTTS) if ((client->protocol == PROTOCOL_MQTTS && client->outbound == 0)||(client->protocol == PROTOCOL_MQTTS_DTLS && client->outbound == 0)) { if (TreeRemove(bstate->mqtts_clients, client)) { client->socket = 0; TreeAdd(bstate->disconnected_mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } } else { #endif if (TreeRemove(bstate->clients, client)) { client->socket = 0; TreeAdd(bstate->disconnected_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } #if defined(MQTTS) } #endif client->closing = 0; } exit: FUNC_EXIT; }
/** * MQTT protocol timeslice for one packet and client - must not take too long! * @param sock the socket which is ready for the packet to be read from * @param client the client structure which corresponds to the socket */ void MQTTProtocol_timeslice(int sock, Clients* client) { int error; MQTTPacket* pack; FUNC_ENTRY; Log(TRACE_MIN, -1, "%d %s About to read packet for peer address %s", sock, (client == NULL) ? "unknown" : client->clientID, Socket_getpeer(sock)); in_MQTTPacket_Factory = sock; pack = MQTTPacket_Factory(sock, &error); in_MQTTPacket_Factory = -1; if (pack == NULL) { /* there was an error on the socket, so clean it up */ if (error == SOCKET_ERROR || error == BAD_MQTT_PACKET) { if (client != NULL) { client->good = 0; /* make sure we don't try and send messages to ourselves */ if (error == SOCKET_ERROR) Log(LOG_WARNING, 18, NULL, client->clientID, sock, Socket_getpeer(sock)); else Log(LOG_WARNING, 19, NULL, client->clientID, sock, Socket_getpeer(sock)); MQTTProtocol_closeSession(client, 1); } else { if (error == SOCKET_ERROR) /* Don't do a Socket_getpeer in the case of SOCKET_ERROR - * otherwise another SOCKET_ERROR will be hit */ Log(LOG_WARNING, 20, NULL, sock, "unknown"); else Log(LOG_WARNING, 21, NULL, sock, Socket_getpeer(sock)); Socket_close(sock); } } } else if (handle_packets[pack->header.bits.type] == NULL) Log(LOG_WARNING, 22, NULL, pack->header.bits.type, sock); else { if (client == NULL && pack->header.bits.type != CONNECT) { Log(LOG_WARNING, 23, NULL, sock, Socket_getpeer(sock), MQTTPacket_name(pack->header.bits.type)); MQTTPacket_free_packet(pack); Socket_close(sock); } else { Node* elem = NULL; /* incoming publish at QoS 0 does not result in outgoing communication, so we don't want to count it as contact, for PING processing on outbound connections */ int update_time = (pack->header.bits.type == PUBLISH && pack->header.bits.qos == 0) ? 0 : 1; if (client && (update_time || (client->outbound == 0))) time(&(client->lastContact)); if ((*handle_packets[pack->header.bits.type])(pack, sock, client) == SOCKET_ERROR) { /* the client could have been closed during handle_packet, so check to see if it's still in the client list */ elem = TreeFind(bstate->clients, &sock); if (elem == NULL && client && client->clientID) elem = TreeFind(bstate->disconnected_clients, client->clientID); if (elem != NULL) { client = (Clients*)(elem->content); client->good = 0; /* make sure we don't try and send messages to ourselves */ Log(LOG_WARNING, 18, NULL, client->clientID, sock, Socket_getpeer(sock)); MQTTProtocol_closeSession(client, 1); } else { Log(LOG_WARNING, 20, NULL, sock, Socket_getpeer(sock)); Socket_close(sock); } } } } /*MQTTProtocol_housekeeping(); move to Protocol_timeslice*/ FUNC_EXIT; }
void shell_service(void){ int i = 0, c, character, rc, no_error; //MAX_LINE is the longest the stdin buffer can be, so we won't overflow it char line_data[MAX_LINE]; pid_t cpid, term_pid; /* pid_t is typedef for Linux process ID */ int chld_status; unsigned char new_line[MAX_LINE]; unsigned char tmp_name[MAX_TMP]; unsigned char id_str[MAX_TMP]; char response[MAX_LINE]; char temp[MAX_LINE]; int id; /* variable names for file "handles" */ FILE *tmpFP; FILE *fp; /* get the parent process ID and use it to create a file name for the * temporary file with the format "tmpxxxxx" where xxxxx is the ID */ id = (int) getpid(); sprintf(id_str, "%d", id); strcpy(tmp_name,"tmp"); strcat(tmp_name, id_str); /* will not use the server socket */ Socket_close(welcome_socket); while((c = Socket_getc(connect_socket)) != EOF){ if(c != NEWLINE){ line_data[i] = c; i ++; } else{ line_data[i] = STRING_END; i++; //make sure the string is terminated if(i == MAX_LINE){ line_data[MAX_LINE - 1] = STRING_END; } cpid = fork(); /* create child == service process */ if (cpid == ERROR){ perror("fork"); exit (ERROR); } if (cpid == NORMAL) {/* code for the service process */ /* dynamically redirect stdout to the named temporary * file open for writing */ fp = freopen(tmp_name, "w", stdout); parse_input(line_data, &connect_socket); } /* end service process */ else{ i = 0; term_pid = waitpid(cpid, &chld_status, 0); if (term_pid == ERROR) perror("waitpid"); else{ if (WIFEXITED(chld_status)) sprintf(response, "End of input: PID %d exited, status = %d\n", cpid, WEXITSTATUS(chld_status)); else sprintf(response, "End of Input: PID %d did not exit normally\n", cpid); } if ((tmpFP = fopen (tmp_name, "r")) == NULL) { fprintf (stderr, "error opening tmp file\n"); exit (ERROR); } no_error = 0; while (!feof (tmpFP)) { no_error = 1; /* Get line from file */ if (fgets (new_line, sizeof(new_line), tmpFP) == NULL) break; send(new_line, &connect_socket); } rc = Socket_putc(NEWLINE, connect_socket); check_put(rc, &connect_socket); if(no_error) send(response, &connect_socket); rc = Socket_putc(STRING_END, connect_socket); check_put(rc, &connect_socket); /* delete the temporary file */ remove(tmp_name); // } } } } }
static NetDescriptor * listenPortSingle(struct ListenState *listenState, struct addrinfo *info) { Socket *sock; int bindResult; int listenResult; NetDescriptor *nd; sock = Socket_openNative(info->ai_family, info->ai_socktype, info->ai_protocol); if (sock == Socket_noSocket) { int savedErrno = errno; log_add(log_Error, "socket() failed: %s.", strerror(errno)); errno = savedErrno; return NULL; } (void) Socket_setReuseAddr(sock); // Ignore errors; it's not a big deal. if (Socket_setNonBlocking(sock) == -1) { int savedErrno = errno; // Error message is already printed. Socket_close(sock); errno = savedErrno; return NULL; } bindResult = Socket_bind(sock, info->ai_addr, info->ai_addrlen); if (bindResult == -1) { int savedErrno = errno; if (errno == EADDRINUSE) { #ifdef DEBUG log_add(log_Warning, "bind() failed: %s.", strerror(errno)); #endif } else log_add(log_Error, "bind() failed: %s.", strerror(errno)); Socket_close(sock); errno = savedErrno; return NULL; } listenResult = Socket_listen(sock, listenState->flags.backlog); if (listenResult == -1) { int savedErrno = errno; log_add(log_Error, "listen() failed: %s.", strerror(errno)); Socket_close(sock); errno = savedErrno; return NULL; } nd = NetDescriptor_new(sock, (void *) listenState); if (nd == NULL) { int savedErrno = errno; log_add(log_Error, "NetDescriptor_new() failed: %s.", strerror(errno)); Socket_close(sock); errno = savedErrno; return NULL; } NetDescriptor_setReadCallback(nd, acceptCallback); return nd; }
static void acceptSingleConnection(ListenState *listenState, NetDescriptor *nd) { Socket *sock; Socket *acceptResult; struct sockaddr_storage addr; socklen_t addrLen; NetDescriptor *newNd; sock = NetDescriptor_getSocket(nd); addrLen = sizeof (addr); acceptResult = Socket_accept(sock, (struct sockaddr *) &addr, &addrLen); if (acceptResult == Socket_noSocket) { switch (errno) { case EWOULDBLOCK: case ECONNABORTED: // Nothing serious. Keep listening. return; case EMFILE: case ENFILE: case ENOBUFS: case ENOMEM: #ifdef ENOSR case ENOSR: #endif // Serious problems, but future connections may still // be possible. log_add(log_Warning, "accept() reported '%s'", strerror(errno)); return; default: // Should not happen. log_add(log_Fatal, "Internal error: accept() reported " "'%s'", strerror(errno)); explode(); } } (void) Socket_setReuseAddr(acceptResult); // Ignore errors; it's not a big deal. if (Socket_setNonBlocking(acceptResult) == -1) { int savedErrno = errno; log_add(log_Error, "Could not make socket non-blocking: %s.", strerror(errno)); Socket_close(acceptResult); errno = savedErrno; return; } (void) Socket_setInlineOOB(acceptResult); // Ignore errors; it's not a big deal as the other // party is not not supposed to send any OOB data. (void) Socket_setKeepAlive(sock); // Ignore errors; it's not a big deal. #ifdef DEBUG { char hostname[NI_MAXHOST]; int gniRes; gniRes = getnameinfo((struct sockaddr *) &addr, addrLen, hostname, sizeof hostname, NULL, 0, 0); if (gniRes != 0) { log_add(log_Error, "Error while performing hostname " "lookup for incoming connection: %s", (gniRes == EAI_SYSTEM) ? strerror(errno) : gai_strerror(gniRes)); } else { log_add(log_Debug, "Accepted incoming connection from '%s'.", hostname); } } #endif newNd = NetDescriptor_new(acceptResult, NULL); if (newNd == NULL) { int savedErrno = errno; log_add(log_Error, "NetDescriptor_new() failed: %s.", strerror(errno)); Socket_close(acceptResult); errno = savedErrno; return; } doListenConnectCallback(listenState, nd, newNd, (struct sockaddr *) &addr, addrLen); // NB: newNd is now handed over to the callback function, and should // no longer be referenced from here. }
int main(int argc, char* argv[]) { bool doneFlag = false; int i; int rc; int c; unsigned char tmp_name[MAX_TMP]; unsigned char id_str[MAX_TMP]; int id; int childPID, term_pid; int chld_status; char fc; char file_line[MAX_LINE]; char * args[MAX_ARGS]; /* variable names for file "handles" */ FILE *tmpFP; FILE *fp; if (argc < 2) { printf("No port specified\n"); return (-1); } /* create a "welcoming" socket at the specified port */ welcome_socket = ServerSocket_new(atoi(argv[1])); if (welcome_socket < 0) { printf("Failed new server socket\n"); return (-1); } id = (int) getpid(); sprintf(id_str, "%d", id); strcpy(tmp_name,"tmp"); strcat(tmp_name, id_str); /* accept an incoming client connection; blocks the * process until a connection attempt by a client. * creates a new data transfer socket. */ connect_socket = ServerSocket_accept(welcome_socket); if (connect_socket < 0) { printf("Failed accept on server socket\n"); exit (-1); } Socket_close(welcome_socket); char input[MAX_LINE]={'\0'}; memset(input,'\0',sizeof(char)*MAX_LINE); while(1){ for (i = 0; i < MAX_LINE; i++) { c = Socket_getc(connect_socket); if (c == EOF) { remove(tmp_name); doneFlag = true; for (i=0; i<=strlen(ERROR2); i++){ Socket_putc(ERROR2[i], connect_socket); } // printf("Socket_getc EOF or error\n"); return; /* assume socket EOF ends service for this client */ } else { if (c == '\0') { input[i] = '\0'; break; } if (c == '\n') { i--; } else{ input[i] = c; } } } /* be sure the string is terminated if max size reached */ if (i == MAX_LINE) input[i-1] = '\0'; fp = freopen(tmp_name, "w", stdout); childPID = fork(); if (childPID == 0){ //code for child: char * token = strtok(input, " \t"); args[0] = token; // set first "argument" to the command itself int count = 1; // loop to fill args[] with the remaining arguments (if any) while (token != NULL) { token = strtok(NULL, " "); args[count] = token; count++; if (count > (MAX_ARGS+2)){ // handle it } } args[count] = NULL; // the array must be null terminated for execvp() to work int execCode = execvp(args[0], args); if (execCode == -1) { for (i=0; i<=strlen(ERROR1); i++){ Socket_putc(ERROR1[i], connect_socket); } // exit(0); //goto end; // printf("Error: invalid command.\n"); } } else if (childPID == -1) { printf("Problem forking.\n"); } else { //parent code: term_pid = waitpid(childPID, &chld_status, 0); if (doneFlag == false){ char file_c; if ((tmpFP = fopen (tmp_name, "r")) == NULL) { fprintf (stderr, "error opening tmp file\n"); exit (-1); } while ((fc = fgetc(tmpFP)) != EOF) { Socket_putc(fc, connect_socket); } } if (term_pid == -1) perror("waitpid"); else { if (WIFEXITED(chld_status)) { char str[] = "PID %d exited, status = %d\n"; char str2[256]; sprintf(str2, str, childPID, WEXITSTATUS(chld_status)); for (i=0; i<=strlen(str2); i++){ Socket_putc(str2[i], connect_socket); } //printf("PID %d exited, status = %d\n", childPID, WEXITSTATUS(chld_status)); } else{ printf("PID %d did not exit normally\n", childPID); } } } end:; } Socket_close(connect_socket); exit (0); }
/** * Process an incoming connect packet for a socket * @param pack pointer to the connect packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handleConnects(void* pack, int sock, Clients* client) { Connect* connect = (Connect*)pack; Node* elem = NULL; int terminate = 0; int rc = TCPSOCKET_COMPLETE; #if !defined(SINGLE_LISTENER) Listener* listener = Socket_getParentListener(sock); #endif FUNC_ENTRY; Log(LOG_PROTOCOL, 26, NULL, sock, connect->clientID);/* connect->Protocol, connect->flags.bits.cleanstart, connect->keepAliveTimer, connect->version, connect->username, connect->password);*/ Socket_removeNew(sock); if (bstate->state != BROKER_RUNNING) terminate = 1; /* don't accept new connection requests when we are shutting down */ /* Now check the version. If we don't recognize it we will not have parsed the packet, * so nothing else in the packet structure will have been filled in. */ else if (!MQTTPacket_checkVersion(pack)) { Log(LOG_WARNING, 32, NULL, connect->Protocol, connect->version); rc = MQTTPacket_send_connack(CONNACK_UNACCEPTABLE_PROTOCOL_VERSION, sock, Socket_getpeer(sock)); /* send response */ terminate = 1; } else if (connect->clientID[0] == '\0' || (connect->version == 3 && strlen(connect->clientID) > 23)) { rc = MQTTPacket_send_connack(CONNACK_IDENTIFIER_REJECTED, sock, Socket_getpeer(sock)); /* send response */ terminate = 1; } else if (bstate->password_file != NULL) { if (connect->flags.bits.username && connect->flags.bits.password && (Users_authenticate(connect->username, connect->password) == false)) { Log(LOG_WARNING, 31, NULL, connect->clientID); rc = MQTTPacket_send_connack(CONNACK_BAD_USERNAME_OR_PASSWORD, sock, connect->clientID); /* send bad user/pass response */ terminate = 1; } else if ((!connect->flags.bits.username || !connect->flags.bits.password) && !bstate->allow_anonymous) { Log(LOG_WARNING, 31, NULL, connect->clientID); rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send broker unavailable response */ terminate = 1; } } if (terminate) ; else if (bstate->clientid_prefixes->count > 0 && !ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare)) { Log(LOG_WARNING, 31, NULL, connect->clientID); terminate = 1; } else { #if !defined(SINGLE_LISTENER) if (listener->max_connections > -1 && listener->connections->count > listener->max_connections) { Log(LOG_WARNING, 141, NULL, connect->clientID, listener->max_connections, listener->port); #else if (bstate->max_connections > -1 && MQTTProtocol_getNoConnectedClients() >= bstate->max_connections) { Log(LOG_WARNING, 141, NULL, connect->clientID, bstate->max_connections, bstate->port); #endif rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send response */ terminate = 1; } } if (terminate) { MQTTPacket_freeConnect(connect); Socket_close(sock); rc = TCPSOCKET_COMPLETE; goto exit; } if (bstate->connection_messages) Log(LOG_INFO, #if !defined(SINGLE_LISTENER) 33, NULL, listener->port, connect->clientID, Socket_getpeer(sock)); #else 33, NULL, bstate->port, connect->clientID, Socket_getpeer(sock)); #endif elem = TreeFindIndex(bstate->clients, connect->clientID, 1); if (elem == NULL) { client = TreeRemoveKey(bstate->disconnected_clients, connect->clientID); if (client == NULL) { int i; char* tmpAddr = NULL; client = malloc(sizeof(Clients)); memset(client, '\0', sizeof(Clients)); tmpAddr = Socket_getpeer(sock); client->addr = malloc(strlen(tmpAddr)+1); strcpy(client->addr, tmpAddr); #if defined(MQTTS) client->protocol = PROTOCOL_MQTT; #endif client->clientID = connect->clientID; client->outboundMsgs = ListInitialize(); client->inboundMsgs = ListInitialize(); for (i = 0; i < PRIORITY_MAX; ++i) client->queuedMsgs[i] = ListInitialize(); connect->clientID = NULL; /* don't want to free this space as it is being used in the client structure */ } client->socket = sock; TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } else { client = (Clients*)(elem->content); if (client->connected) { Log(LOG_INFO, 34, NULL, connect->clientID, Socket_getpeer(sock)); if (client->socket != sock) Socket_close(client->socket); } if (connect->flags.bits.cleanstart) { int i; /* empty pending message lists */ MQTTProtocol_emptyMessageList(client->outboundMsgs); MQTTProtocol_emptyMessageList(client->inboundMsgs); for (i = 0; i < PRIORITY_MAX; ++i) MQTTProtocol_emptyMessageList(client->queuedMsgs[i]); client->msgID = client->outbound = client->ping_outstanding = 0; } /* have to remove and re-add client so it is in the right order for new socket */ if (client->socket != sock) { TreeRemoveNodeIndex(bstate->clients, elem, 1); TreeRemoveKeyIndex(bstate->clients, &client->socket, 0); client->socket = sock; TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } } client->good = client->connected = 1; client->cleansession = connect->flags.bits.cleanstart; client->keepAliveInterval = connect->keepAliveTimer; client->noLocal = (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0; if (client->cleansession) MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */ #if !defined(SINGLE_LISTENER) if (listener && listener->mount_point && connect->flags.bits.will) { char* temp = malloc(strlen(connect->willTopic) + strlen(listener->mount_point) + 1); strcpy(temp, listener->mount_point); strcat(temp, connect->willTopic); free(connect->willTopic); connect->willTopic = temp; } #endif #if defined(MQTTS) if (connect->flags.bits.will) { MQTTProtocol_setWillTopic(client, connect->willTopic, connect->flags.bits.willRetain, connect->flags.bits.willQoS); MQTTProtocol_setWillMsg(client, connect->willMsg); connect->willTopic = NULL; connect->willMsg = NULL; } #else MQTTProtocol_setWill(connect, client); #endif if (connect->flags.bits.username) { client->user = Users_get_user(connect->username); } rc = MQTTPacket_send_connack(CONNACK_CONNECTION_ACCEPTED, sock, client->clientID); /* send response */ if (client->cleansession == 0) { ListElement* outcurrent = NULL; time_t now = 0; /* ensure that inflight messages are retried now by setting the last touched time * to very old (0) before calling the retry function */ time(&(now)); while (ListNextElement(client->outboundMsgs, &outcurrent)) { Messages* m = (Messages*)(outcurrent->content); m->lastTouch = 0; } MQTTProtocol_retries(now, client); MQTTProtocol_processQueued(client); } time(&(client->lastContact)); MQTTPacket_freeConnect(connect); exit: FUNC_EXIT_RC(rc); return rc; } /** * Process an incoming ping request packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePingreqs(void* pack, int sock, Clients* client) { int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; Log(LOG_PROTOCOL, 3, NULL, sock, client->clientID); rc = MQTTPacket_send_pingresp(sock, client->clientID); FUNC_EXIT_RC(rc); return rc; }
int main(int argc, char *argv[]) { int ID; char line[MAX_LINE]; FILE *tmp; FILE *output; //Argument 1: Welcoming port if (argc < 2) { printf("No port specified\n"); exit(-1); } /* Create a welcome socket at the specified port */ welcome_socket = ServerSocket_new(atoi(argv[1])); if (welcome_socket < 0) { printf("Failed new server socket\n"); exit(-1); } /* Open a connect socket through the welcom socket*/ connect_socket = ServerSocket_accept(welcome_socket); if (connect_socket < 0) { printf("Failed connect socket\n"); exit(-1); } Socket_close(welcome_socket); //Close the welcome socket as it is unused pid_t childPID; char *argcv[MAXARGSIZE]; int child_status; /* Run until exited*/ while ( 1 ) { ID = (int)getpid(); // Get PID of the Current Process sprintf(filename, "tmp%d", ID); // Make file name from the current pid tmp = freopen(filename, "w", stdout); // Redirect stdout to the tmp file read_line(line); childPID = fork(); //Child Process to read from client and execute if (childPID < 0) { printf("Fork error\n"); exit(-1); } if (childPID == 0) //Child process { tokenize(line, argv); //Tokenize the input line into arguments errno = 0; // Check if the file name is valid if (execvp(*argv, argv) == -1 ) //Run the command in the arguments list { printf("Execvp error: %d\n", errno); exit(-1); } } else if (childPID > 0) { int flag = 0; //Wait until the child process finishes if (waitpid(-1, &child_status, 0) == -1) { printf("Server: wait error\n"); } //Check signals for child process if (WIFSIGNALED(child_status)) { printf("Server: WIFSIGNALED ERROR: %d\n", WTERMSIG(child_status)); } else if (WIFSTOPPED(child_status)) { printf("Server: WIFSTOPPED ERROR: %d\n", WSTOPSIG(child_status)); } fclose(tmp); //Close the redirected temp file output_results(); //Ouput thte reuslts back into socket } } }
// actually does the execution and reports back to ForkExecuteRedirect void ForkExecuteRedirect_helper(int argc, char *argv[]){ pid_t cpid, term_pid; /* type for Linux process id */ int chld_status; int i; int execCheck; char *parms_array[NUM_PARMS]; /* arrary of pointers to strings */ unsigned char new_line[MAX_LINE]; unsigned char tmp_name[MAX_TMP]; unsigned char id_str[MAX_TMP]; int id; /* variable names for file "handles" */ FILE *tmpFP; FILE *fp; /* The positional parameters passed to this program as pointers to * strings can just be passed on to execvp which requires a * NULL-terminated array of pointers to strings. By convention, the * first entry in the array is the file name to be executed, and the * next non-null pointers are for positional parameters to that program. */ /* get the parent process ID and use it to create a file name for the * temporary file with the format "tmpxxxxx" where xxxxx is the ID */ id = (int) getpid(); sprintf(id_str, "%d", id); strcpy(tmp_name,"tmp"); strcat(tmp_name, id_str); /* create child process, report error if present and exit */ cpid = fork(); if (cpid == -1) { perror("fork"); /* perror creates description of OS error codes */ exit(ERR_RETURN); } /* conditional execution of statements depending on whether the code is * if running as the parent or child process. */ if (cpid == 0) { /* the child process */ /* dynamically redirect stdout to the named temporary * file open for writing */ fp = freopen(tmp_name, "w", stdout); /* do the OS execvp() call, if there is an error return, report it. Otherwise * this call will not return and the new image will execute as this process ID. */ execCheck = execvp(argv[0], argv); if (execCheck == -1) { perror("execvp, execCheck == -1"); exit(-1); } } /* end of code that can be executed by the child process */ else {/* code executed by the parent process */ /* wait for the child to terminate and determine its exit status */ /* this is necessary to prevent the accumulation of "Zombie" processes */ term_pid = waitpid(cpid, &chld_status, 0); if (term_pid == -1) perror("waitpid"); else { if (WIFEXITED(chld_status)) printf("PID %d exited, status = %d\n", cpid, WEXITSTATUS(chld_status)); else printf("PID %d did not exit normally\n", cpid); } if ((tmpFP = fopen (tmp_name, "r")) == NULL) { fprintf (stderr, "error opening tmp file\n"); exit (-1); } while (!feof (tmpFP)) { /* Get line from file */ if (fgets (new_line, sizeof(new_line), tmpFP) == NULL) break; int toClientCount = strlen(new_line); int new_index; char toClientChar; int new_rc; for (new_index = 0; new_index < toClientCount; new_index++){ toClientChar = new_line[new_index]; new_rc = Socket_putc(toClientChar, connect_socket); if (new_rc == EOF){ printf("Socket_putc EOF or error\n"); Socket_close(connect_socket); exit (-1); // assume socket problem is fatal, end client } } } // delete the temporary file remove(tmp_name); } // end of code that can be executed by the parent process exit(0); }
// Try connecting to the next address. static Socket * tryConnectHostNext(ConnectState *connectState) { struct addrinfo *info; Socket *sock; int connectResult; assert(connectState->nd == NULL); info = connectState->infoPtr; sock = Socket_openNative(info->ai_family, info->ai_socktype, info->ai_protocol); if (sock == Socket_noSocket) { int savedErrno = errno; log_add(log_Error, "socket() failed: %s.\n", strerror(errno)); errno = savedErrno; return Socket_noSocket; } if (Socket_setNonBlocking(sock) == -1) { int savedErrno = errno; log_add(log_Error, "Could not make socket non-blocking: %s.\n", strerror(errno)); errno = savedErrno; return Socket_noSocket; } (void) Socket_setReuseAddr(sock); // Ignore errors; it's not a big deal. (void) Socket_setInlineOOB(sock); // Ignore errors; it's not a big deal as the other party is not // not supposed to send any OOB data. (void) Socket_setKeepAlive(sock); // Ignore errors; it's not a big deal. connectResult = Socket_connect(sock, info->ai_addr, info->ai_addrlen); if (connectResult == 0) { // Connection has already succeeded. // We just wait for the writability callback anyhow, so that // we can use one code path. return sock; } switch (errno) { case EINPROGRESS: // Connection in progress; wait for the write callback. return sock; } // Connection failed immediately. This is just for one of the addresses, // so this does not have to be final. // Note that as the socket is non-blocking, most failed connection // errors will usually not be reported immediately. { int savedErrno = errno; Socket_close(sock); #ifdef DEBUG log_add(log_Debug, "connect() immediately failed for one address: " "%s.\n", strerror(errno)); // TODO: add the address in the status message. #endif errno = savedErrno; } return Socket_noSocket; }
static int closeSock(struct Allocator_OnFreeJob* j) { Socket_close((int)(uintptr_t)j->userData); return 0; }
int MQTTSProtocol_handleConnacks(void* pack, int sock, char* clientAddr) { MQTTS_Connack* connack = (MQTTS_Connack*)pack; int rc = 0; Clients* client = NULL; BridgeConnections* bc = Bridge_getBridgeConnection(sock); FUNC_ENTRY; if (bc == NULL) { rc = SOCKET_ERROR; goto exit; } if (bc->primary && bc->primary->socket == sock) client = bc->primary; else client = bc->backup; if (connack->returnCode != MQTTS_RC_ACCEPTED) { if (client) { if (client->noLocal == 1) client->noLocal = 0; else Log(LOG_WARNING, 132, NULL, connack->returnCode, client->clientID); MQTTProtocol_closeSession(client, 0); } else Socket_close(sock); } else if (client) { ListElement* addr = bc->cur_address; if (client == bc->primary && bc->round_robin == 0) addr = bc->addresses->first; Log(LOG_INFO, 133, NULL, bc->name, (char*)(addr->content)); client->connect_state = 3; //should have been 2 before bc->last_connect_result = connack->returnCode; (bc->no_successful_connections)++; client->connected = 1; client->good = 1; client->ping_outstanding = 0; time(&(client->lastContact)); if (client->will) { Publish pub; Messages* m = NULL; MQTTProtocol_sys_publish(client->will->topic, "1"); pub.payload = "1"; pub.payloadlen = 1; pub.topic = client->will->topic; MQTTProtocol_startOrQueuePublish(client, &pub, 0, client->will->retained, &m); } if (client == bc->primary && (bc->backup && (bc->backup->connected == 1 || bc->backup->connect_state != 0))) { Log(LOG_INFO, 134, NULL, (char*)(bc->cur_address->content)); MQTTProtocol_closeSession(bc->backup, 0); } //if (bc->addresses->count > 1 || bc->no_successful_connections == 1) Bridge_subscribe(bc, client); } //Clients* client = Protocol_getclientbyaddr(clientAddr); MQTTSPacket_free_packet(pack); exit: FUNC_EXIT_RC(rc); return rc; }