void msg_event_handler( int fd, int msgid, int event ) { char buf[PACK_DATA_SIZE]; ssize_t n; // printf( "event 0x%03x for msg %d\n", event, msgid ); switch ( event ) { case MSG_EVT_ACCEPT_READY: if ( msg_accept( fd, msgid ) != 0 ) msg_set_read( fd, msgid ); // These are commands break; case MSG_EVT_READ_READY: msg_clr_read( fd, msgid ); n = msg_read( fd, msgid, buf, sizeof( buf ) ); if ( n <= 0 ) { cleanup_connection( msg_get_type( fd, msgid ) ); break; } if ( msg_get_type( fd, msgid ) < 0 ) { /* If the msgid is less than zero, it refers to a command and the message should not be routed to a file descriptor. */ // the entire command must fit inside one transport command_handler( fd, msgid, buf, n ); } else { zs_set_write( msg_get_type( fd, msgid ) ); /* if msgid is zero or greater it refers to a socket file descriptor that the message should be routed to. */ if ( zs_write( msg_get_type( fd, msgid ), buf, n ) == -1 ) cleanup_connection( msg_get_type( fd, msgid ) ); } break; case MSG_EVT_WRITE_READY: if ( msgid < 0 ) break; zs_set_read( msg_get_type( fd, msgid ) ); msg_clr_write( fd, msgid ); break; case MSG_SWITCH_EVT_IO_ERROR: //zclose( msg_switch->sockfd ); if ( website_get_by_sockfd( fd ) ) remove_website( fd ); else { for ( n = 0; n < FD_SETSIZE; n++ ) { if ( msg_exists( fd, n ) ) { if ( msg_get_type( fd, n ) > 0 ) cleanup_connection( msg_get_type( fd, n ) ); // else // msg_close( fd, n ); } } msg_switch_destroy( fd ); zs_close( fd ); } break; } }
int qdevice_net_socket_write(struct qdevice_net_instance *instance) { int res; struct send_buffer_list_entry *send_buffer; enum msg_type sent_msg_type; send_buffer = send_buffer_list_get_active(&instance->send_buffer_list); if (send_buffer == NULL) { qdevice_log(LOG_CRIT, "send_buffer_list_get_active returned NULL"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE; return (-1); } res = msgio_write(instance->socket, &send_buffer->buffer, &send_buffer->msg_already_sent_bytes); if (res == 1) { sent_msg_type = msg_get_type(&send_buffer->buffer); send_buffer_list_delete(&instance->send_buffer_list, send_buffer); if (sent_msg_type != MSG_TYPE_ECHO_REQUEST) { if (qdevice_net_socket_write_finished(instance) == -1) { return (-1); } } } if (res == -1) { qdevice_log_nss(LOG_CRIT, "PR_Send returned 0"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION; return (-1); } if (res == -2) { qdevice_log_nss(LOG_ERR, "Unhandled error when sending message to server"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE; return (-1); } return (0); }
void command_handler( int fd, int msgid, void* buf, size_t len ) { const char* ret_msg; switch ( msg_get_type( fd, msgid ) ) { case ZM_CMD_WS_START: ret_msg = start_website( fd, buf, buf + strlen( buf ) + 1 ); msg_write( fd, msgid, ret_msg, strlen( ret_msg ) + 1 ); msg_close( fd, msgid ); break; case ZM_CMD_WS_STOP: remove_website( fd ); break; /*case ZM_CMD_STATUS: message = get_status_message( buffer, sizeof( buffer ) ); ztransport_write( response, message, strlen( message ) ); break;*/ default: //status = MSG_PACK_RESP_FAIL; break; } }
/* * -1 means end of connection (EOF) or some other unhandled error. 0 = success */ int qdevice_net_socket_read(struct qdevice_net_instance *instance) { int res; int ret_val; int orig_skipping_msg; orig_skipping_msg = instance->skipping_msg; res = msgio_read(instance->socket, &instance->receive_buffer, &instance->msg_already_received_bytes, &instance->skipping_msg); if (!orig_skipping_msg && instance->skipping_msg) { qdevice_log(LOG_DEBUG, "msgio_read set skipping_msg"); } ret_val = 0; switch (res) { case 0: /* * Partial read */ break; case -1: qdevice_log(LOG_DEBUG, "Server closed connection"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION; ret_val = -1; break; case -2: qdevice_log(LOG_ERR, "Unhandled error when reading from server. " "Disconnecting from server"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE; ret_val = -1; break; case -3: qdevice_log(LOG_ERR, "Can't store message header from server. " "Disconnecting from server"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE; ret_val = -1; break; case -4: qdevice_log(LOG_ERR, "Can't store message from server. " "Disconnecting from server"); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE; ret_val = -1; break; case -5: qdevice_log(LOG_WARNING, "Server sent unsupported msg type %u. " "Disconnecting from server", msg_get_type(&instance->receive_buffer)); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_UNSUPPORTED_MSG; ret_val = -1; break; case -6: qdevice_log(LOG_WARNING, "Server wants to send too long message %u bytes. Disconnecting from server", msg_get_len(&instance->receive_buffer)); instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE; ret_val = -1; break; case 1: /* * Full message received / skipped */ if (!instance->skipping_msg) { if (qdevice_net_msg_received(instance) == -1) { ret_val = -1; } } else { qdevice_log(LOG_CRIT, "net_socket_read in skipping msg state"); exit(1); } instance->skipping_msg = 0; instance->msg_already_received_bytes = 0; dynar_clean(&instance->receive_buffer); break; default: qdevice_log(LOG_CRIT, "qdevice_net_socket_read unhandled error %d", res); exit(1); break; } return (ret_val); }