int ZmtpReader_Handshake(zmtpreader_t *self) { int res = ZmtpReader_Frame(self); if (self->error) return 0; if (res > 0) { BufferRemove(self->buffer, res); self->state= ZMTP_STATE_WAIT_PACKET; } return res; }
void SSLBufferTryWrite(struct sslbuffer_t *sslbuffer) { int res; unsigned long error; if (!sslbuffer->fl_writing) { if (BufferSize(sslbuffer->write_buffer_1) > 0) BufferCopy(sslbuffer->write_buffer_2, sslbuffer->write_buffer_1); } if (BufferSize(sslbuffer->write_buffer_2) > 0) { res = SSL_write( sslbuffer->ssl, BufferStart(sslbuffer->write_buffer_2), BufferSize(sslbuffer->write_buffer_2)); if (res <= 0) { error = SSL_get_error(sslbuffer->ssl, res); sslbuffer->fl_writing = 1; if (error == SSL_ERROR_WANT_READ) sslbuffer->fl_want_read = 1; else if (error == SSL_ERROR_WANT_WRITE) sslbuffer->fl_want_write = 1; else { printf("%s:%d: unknown error %lu\n", __FILE__, __LINE__, error); print_errors(); event_base_loopbreak(sslbuffer->base); } return; } BufferRemove(sslbuffer->write_buffer_2, (size_t) res); sslbuffer->fl_writing = 0; sslbuffer->fl_want_write = 0; sslbuffer->fl_want_read = 0; } if ( (BufferSize(sslbuffer->write_buffer_1) == 0) && (BufferSize(sslbuffer->write_buffer_2) == 0)) { event_del(sslbuffer->ev_write); } }
int ZmtpReader_Frame(zmtpreader_t *self) { assert(self); uint8_t *data; size_t len; size_t processed; BufferGetData(self->buffer, &data, &len); if (len < 1) { return 0; } int type = data[0]; // type of frame size_t payload_size; uint8_t *payload; if ((type == 4) || (type == 0) || (type == 1)) { // short size if (len < 2) return 0; payload_size = data[1]; if (len < 2 + payload_size) return 0; payload = data + 2; processed = 2 + payload_size; } else if ((type == 6) || (type == 3) || (type == 2)) { // long size if (len < 9) return 0; payload_size = LongLongToSize(&data[1]); if (len < 9 + payload_size) return 0; payload = data + 9; processed = 9 + payload_size; } else { // Wrong first byte self->error = 1; return 0; } if ((type == 4) || (type == 6)) { // command uint8_t *name; size_t name_len; uint8_t *after; size_t after_len; int res = ZmtpReaderGetKey(payload, payload_size, &name, &name_len, &after, &after_len); if (!res) { self->error = 1; goto End; } uint8_t *ready_check = (uint8_t *) "READY"; if ((name_len != 5) || (memcmp(name, ready_check, 5) != 0)) { char *name_ascii; char *name_binary; ZmtpReaderGenerateBinaryOutput(name, name_len, &name_ascii, &name_binary); ZmtpReaderReport(self, "command: \"%s\" %s\n", name_ascii, name_binary); free(name_ascii); free(name_binary); char *command_data_ascii; char *command_data_binary; ZmtpReaderGenerateBinaryOutput(after, after_len, &command_data_ascii, &command_data_binary); ZmtpReaderReport(self, "command data: \"%s\" %s\n", command_data_ascii, command_data_binary); free(command_data_ascii); free(command_data_binary); goto End; } ZmtpReaderReport(self, "READY command\n"); uint8_t *before; size_t before_len; uint8_t *property, *value; size_t property_len, value_len; before = after; before_len = after_len; while (before_len > 0) { res = ZmtpReaderGetKeyAndValue(before, before_len, &property, &property_len, &value, &value_len, &after, &after_len); if (!res || (property_len == 0)) { ZmtpReaderReport(self, "Bad property\n"); self->error = 1; goto End; } char *property_ascii; char *property_binary; char *value_ascii; char *value_binary; ZmtpReaderGenerateBinaryOutput(property, property_len, &property_ascii, &property_binary); ZmtpReaderGenerateBinaryOutput(value, value_len, &value_ascii, &value_binary); ZmtpReaderReport(self, "property: \"%s\" %s\n", property_ascii, property_binary); ZmtpReaderReport(self, "value: \"%s\" %s\n", value_ascii, value_binary); free(property_ascii); free(property_binary); free(value_ascii); free(value_binary); before = after; before_len = after_len; } } else { // message char *message_ascii; char *message_binary; ZmtpReaderGenerateBinaryOutput(payload, payload_size, &message_ascii, &message_binary); char *message; if ((type == 0) || (type == 2)) message = "message"; else message = "message-more"; ZmtpReaderReport(self, "%s: \"%s\" %s\n", message, message_ascii, message_binary); free(message_ascii); free(message_binary); } End: BufferRemove(self->buffer, processed); return processed; }