struct sslbuffer_t *SSLBufferCreate(SSL_CTX *ctx, struct event_base *base) { struct sslbuffer_t *sslbuffer = NULL; SSL *ssl = NULL; struct buffer_t *write_buffer_1 = NULL; struct buffer_t *write_buffer_2 = NULL; sslbuffer = (struct sslbuffer_t *) malloc(sizeof(struct sslbuffer_t)); if (sslbuffer == NULL) goto Error; memset(sslbuffer, 0, sizeof(*sslbuffer)); sslbuffer->ctx = ctx; ssl = SSL_new(ctx); if (ssl == NULL) goto Error; SSL_set_cipher_list(ssl, CIPHER_LIST); sslbuffer->ssl = ssl; sslbuffer->base = base; write_buffer_1 = BufferCreate(256); if (write_buffer_1 == NULL) goto Error; sslbuffer->write_buffer_1 = write_buffer_1; write_buffer_2 = BufferCreate(256); if (write_buffer_2 == NULL) goto Error; sslbuffer->write_buffer_2 = write_buffer_2; sslbuffer->fl_connecting = 0; sslbuffer->fl_reading = 0; sslbuffer->fl_writing = 0; sslbuffer->fl_want_read = 0; sslbuffer->fl_want_write = 0; return sslbuffer; Error: if (write_buffer_2 != NULL) BufferDelete(write_buffer_2); if (write_buffer_1 != NULL) BufferDelete(write_buffer_1); if (ssl != NULL) SSL_free(ssl); free(sslbuffer); return NULL; }
int BufferReadline(Buffer b, FILE * f) { int c; int i = 0; /* count characters in buffer */ while ((c = fgetc(f)) != EOF) { b->buf[i] = c; i++; if (i >= b->cap - 1) { if (!b->ext) { b->ext = BufferCreate(SIZE_OF_BUFFER); if (!b->ext) return 1; } b->buf[i] = '\0'; b = b->ext; i = 0; } if (c == '\n') break; } b->buf[i] = '\0'; return 0; }
void TestCreateBuffer(CuTest* tc) { buffer_t *buf = BufferCreate(); CuAssertTrue(tc, buf != NULL); CuAssertIntEquals(tc, 0, BufferGetSize(buf)); BufferDestroy(&buf); CuAssertPtrEquals(tc, 0, buf); }
void TestAppend(CuTest* tc) { buffer_t *buf = BufferCreate(); uint8_t data[2] = { 1, 2 }; BufferAppend(buf, data, sizeof(data)); CuAssertIntEquals(tc, 2, BufferGetSize(buf)); CuAssertIntEquals(tc, 1, BufferGetByte(buf, 0)); CuAssertIntEquals(tc, 2, BufferGetByte(buf, 1)); BufferDestroy(&buf); }
zmtpreader_t *ZmtpReaderNew() { zmtpreader_t *reader = (zmtpreader_t *) malloc(sizeof(zmtpreader_t)); assert(reader); memset(reader, 0, sizeof(zmtpreader_t)); reader->state = ZMTP_STATE_INIT; reader->buffer = BufferCreate(); reader->error = 0; assert(reader->buffer); return reader; }
void TestAccessBufferData(CuTest* tc) { buffer_t *buf = BufferCreate(); uint8_t data1[4] = { 1, 2, 3, 4 }; BufferAppend(buf, data1, sizeof(data1)); uint8_t *buffer_data; size_t buffer_size; BufferGetData(buf, &buffer_data, &buffer_size); CuAssertTrue(tc, buffer_data != NULL); CuAssertIntEquals(tc, 4, buffer_size); BufferDestroy(&buf); }
void TestCopyBuffer(CuTest* tc) { buffer_t *buf = BufferCreate(); uint8_t data[4] = { 1, 2, 3, 4 }; BufferAppend(buf, data, sizeof(data)); uint8_t *data_out; size_t size_out; BufferCopy(buf, 2, &data_out, &size_out); CuAssertIntEquals(tc, 2, size_out); CuAssertIntEquals(tc, 0, memcmp(data, data_out, 2)); free(data_out); BufferDestroy(&buf); }
void TestExtractBuffer(CuTest* tc) { buffer_t *buf = BufferCreate(); uint8_t data[4] = { 1, 2, 3, 4 }; BufferAppend(buf, data, sizeof(data)); uint8_t *data_out; size_t size_out; BufferExtract(buf, 2, &data_out, &size_out); CuAssertIntEquals(tc, 2, size_out); CuAssertIntEquals(tc, 0, memcmp(data, data_out, 2)); free(data_out); CuAssertIntEquals(tc, 2, BufferGetSize(buf)); CuAssertIntEquals(tc, 3, BufferGetByte(buf, 0)); CuAssertIntEquals(tc, 4, BufferGetByte(buf, 1)); BufferDestroy(&buf); }
Line LineCreate(int n, int len) { Line l = (Line) malloc(sizeof(struct _Line)); if (!l) { perror("Line: Failed to allocate instance"); return NULL; } l->b = BufferCreate(len); if (!l->b) { perror("Line: Failed to allocate buffer"); free(l); return NULL; } l->n = n; l->next = NULL; return l; }
void TestGetBlock(CuTest* tc) { buffer_t *buf = BufferCreate(); uint8_t data1[4] = { 1, 2, 3, 4 }; BufferAppend(buf, data1, sizeof(data1)); uint8_t *block; // Test case when not enough data in the buffer. CuAssertIntEquals(tc, 0, BufferGetBlock(buf, &block, 0, 8)); // Add more data to the buffer. uint8_t data2[4] = { 5, 6, 7, 8 }; BufferAppend(buf, data2, sizeof(data2)); // Test case when enough data in the buffer. CuAssertIntEquals(tc, 1, BufferGetBlock(buf, &block, 0, 8)); uint8_t check_data[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; CuAssertIntEquals(tc, 0, memcmp(block, check_data, 8)); BufferDestroy(&buf); }
/** * @brief Handles all network connections * @param arg a pointer to a structure containing port number and timeout * @return never returns until shutdown * * @todo be sure this handles linkdead without removing all player structures * so the player can log back in and be where they were * * Brings up a TCP listener on the MUD's assigned port and accepts connections. * Also reads all data from connected clients and hands the data off to the * Input thread. When there is output to be sent, this thread handles writing * to the sockets after the first write has completed. This thread also * handles the disconnection of clients gracefully. */ void *ConnectionThread( void *arg ) { connectThreadArgs_t *argStruct; int portNum; char *port; struct sockaddr_in6 sa; int count; int fdCount; int newFd; socklen_t salen; struct timeval timeout; ConnectionItem_t *item; PlayerStruct_t *player; ConnInputItem_t *connItem; ConnDnsItem_t *dnsItem; uint32 i; int on; int retval; char ch; argStruct = (connectThreadArgs_t *)arg; portNum = argStruct->port; pthread_mutex_lock( startupMutex ); if( portNum == -1 ) { port = pb_get_setting( "listenPort" ); if( !port ) { portNum = 4000; } else { portNum = atoi(port); memfree(port); } } /* * Start listening */ listenFd = socket( AF_INET6, SOCK_STREAM, 0 ); if( listenFd < 0 ) { perror("Opening listener socket"); exit(1); } on = 1; if( setsockopt( listenFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) ) { perror("Setting socket to reuse"); exit(1); } memset(&sa, 0, sizeof(sa)); sa.sin6_family = AF_INET6; sa.sin6_port = htons(portNum); sa.sin6_addr = in6addr_any; if (bind(listenFd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("Binding listener socket"); close(listenFd); exit(1); } if (listen(listenFd, 10)) { perror("Listening to socket"); close(listenFd); exit(1); } FD_ZERO(&saveReadFds); FD_ZERO(&saveWriteFds); FD_ZERO(&saveExceptFds); connAddFd(listenFd, &saveReadFds); ConnectionList = LinkedListCreate(NULL); LogPrint( LOG_NOTICE, "Listening on port %d", portNum ); pthread_mutex_unlock( startupMutex ); while( !GlobalAbort ) { /* * Select on connected and listener */ readFds = saveReadFds; writeFds = saveWriteFds; exceptFds = saveExceptFds; timeout.tv_sec = argStruct->timeout_sec; timeout.tv_usec = argStruct->timeout_usec; fdCount = select(maxFd+1, &readFds, &writeFds, &exceptFds, &timeout); if( GlobalAbort ) { continue; } recalcMaxFd = FALSE; /* * Open a connection for listener */ if( FD_ISSET(listenFd, &readFds) ) { salen = sizeof(struct sockaddr_in6); newFd = accept(listenFd, (struct sockaddr *)&sa, &salen); connAddFd(newFd, &saveReadFds); connAddFd(newFd, &saveExceptFds); item = CREATE(ConnectionItem_t); if( !item ) { /* * No memory! */ LogPrintNoArg( LOG_EMERG, "Out of memory!" ); close(newFd); } else { item->fd = newFd; item->buffer = BufferCreate(MAX_BUFSIZE); item->hostName = ProtectedDataCreate(); ProtectedDataLock( item->hostName ); item->hostName->data = CREATEN(char, 50); inet_ntop(AF_INET6, &sa.sin6_addr, item->hostName->data, 50); if( !strncmp(item->hostName->data, "::ffff:", 7) ) { bcopy((char *)item->hostName->data + 7, item->hostName->data, 43); } ProtectedDataUnlock( item->hostName ); if (!IS_SET(SystemFlags, SYS_SKIPDNS)) { dnsItem = CREATE(ConnDnsItem_t); if( dnsItem ) { dnsItem->connection = item; memcpy(dnsItem->ipAddr, &sa.sin6_addr, 16); QueueEnqueueItem(ConnectDnsQ, dnsItem); } } player = CREATE(PlayerStruct_t); if( !player ) { /* * No memory! */ LogPrintNoArg( LOG_EMERG, "Out of memory!" ); BufferDestroy(item->buffer); close(newFd); memfree(item); } else { item->player = player; player->connection = item; player->in_buffer = item->buffer; LinkedListAdd( ConnectionList, (LinkedListItem_t *)item, UNLOCKED, AT_TAIL ); /* * Pass the info on to the other threads... */ #ifdef DEBUG_CONNECT LogPrint( LOG_INFO, "New connection: %p", player ); #endif connItem = CREATE(ConnInputItem_t); if( connItem ) { connItem->type = CONN_NEW_CONNECT; connItem->player = player; QueueEnqueueItem(ConnectInputQ, (QueueItem_t)connItem); } } } fdCount--; } if( fdCount ) { LinkedListLock( ConnectionList ); for( item = (ConnectionItem_t *)(ConnectionList->head); item && fdCount; item = (item ? (ConnectionItem_t *)item->link.next : (ConnectionItem_t *)ConnectionList->head) ) { if( FD_ISSET( item->fd, &exceptFds ) ) { /* * This connection's borked, close it, remove it, move on */ if( FD_ISSET( item->fd, &readFds ) ) { fdCount--; } if( FD_ISSET( item->fd, &writeFds ) ) { fdCount--; } BufferLock( item->buffer ); item = connRemove(item); fdCount--; continue; } if( item && FD_ISSET( item->fd, &readFds ) ) { /* * This connection has data ready */ count = BufferAvailWrite( item->buffer, TRUE ); if( !count ) { /* * No buffer space, the buffer's unlocked, move on */ LogPrint( LOG_INFO, "No buffer space: %p", item ); continue; } /* * The buffer's locked */ count = read( item->fd, BufferGetWrite( item->buffer ), count ); if( !count ) { LogPrint( LOG_DEBUG, "EOF on %d", item->fd ); /* * We hit EOF, close and remove */ if( FD_ISSET( item->fd, &writeFds ) ) { fdCount--; } item = connRemove(item); fdCount--; continue; } BufferWroteBytes( item->buffer, count ); BufferUnlock( item->buffer ); /* * Tell the input thread */ connItem = CREATE(ConnInputItem_t); if( connItem ) { #ifdef DEBUG_INPUT LogPrint( LOG_INFO, "New data: %p", item->player ); #endif connItem->type = CONN_INPUT_AVAIL; connItem->player = item->player; QueueEnqueueItem(ConnectInputQ, (QueueItem_t)connItem); } } if( item && FD_ISSET( item->fd, &writeFds ) ) { /* * We have space to output, so write if we have anything * to write */ #ifdef DEBUG_OUTPUT LogPrint( LOG_INFO, "Output sent to: %p", item ); #endif if( item->outBufDesc ) { /* TODO: deal with partial block writes */ retval = write( item->fd, item->outBufDesc->buf, item->outBufDesc->len ); memfree( item->outBufDesc->buf ); memfree( item->outBufDesc ); item->outBufDesc = NULL; } /* * Kick the next output */ connKickOutput( item ); fdCount--; } } LinkedListUnlock( ConnectionList ); } if( recalcMaxFd ) { LinkedListLock( ConnectionList ); maxFd = listenFd; for( item = (ConnectionItem_t *)(ConnectionList->head); item; item = (ConnectionItem_t *)item->link.next ) { if( item->fd > maxFd ) { maxFd = item->fd; } } LinkedListUnlock( ConnectionList ); } }