void LogWarning( const char* format, ... ) { va_list vl; va_start(vl, format); LogRaw(LogLevel_Warning, FormatV(format, vl).c_str()); va_end(vl); }
void LogError( const char* format, ... ) { va_list vl; va_start(vl, format); LogRaw(LogLevel_Error, FormatV(format, vl).c_str()); va_end(vl); }
/** * @param len is the number of bytes to send, or 0 if buffer is a * '\0'-terminated string so strlen(buffer) can used. */ int SendTransaction(const ConnectionInfo *conn_info, const char *buffer, int len, char status) { assert(status == CF_MORE || status == CF_DONE); char work[CF_BUFSIZE] = { 0 }; int ret; if (len == 0) { len = strlen(buffer); } if (len > CF_BUFSIZE - CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "SendTransaction: len (%d) > %d - %d", len, CF_BUFSIZE, CF_INBAND_OFFSET); return -1; } snprintf(work, CF_INBAND_OFFSET, "%c %d", status, len); memcpy(work + CF_INBAND_OFFSET, buffer, len); Log(LOG_LEVEL_DEBUG, "SendTransaction header: %s", work); LogRaw(LOG_LEVEL_DEBUG, "SendTransaction data: ", work + CF_INBAND_OFFSET, len); switch(ConnectionInfoProtocolVersion(conn_info)) { case CF_PROTOCOL_CLASSIC: ret = SendSocketStream(ConnectionInfoSocket(conn_info), work, len + CF_INBAND_OFFSET); break; case CF_PROTOCOL_TLS: ret = TLSSend(ConnectionInfoSSL(conn_info), work, len + CF_INBAND_OFFSET); break; default: UnexpectedError("SendTransaction: ProtocolVersion %d!", ConnectionInfoProtocolVersion(conn_info)); ret = -1; } if (ret == -1) return -1; else return 0; }
/** * @brief Set the connection type to CLASSIC or TLS. * It is performed by peeking into the TLS connection to read the first bytes, * and if it's a CAUTH protocol command use the old protocol loop, else use * the TLS protocol loop. * This must be the first thing we run on an accepted connection. * * @return -1 in case of error, 1 otherwise. */ int ServerTLSPeek(ConnectionInfo *conn_info) { assert(SSLSERVERCONTEXT != NULL && PRIVKEY != NULL && PUBKEY != NULL); assert(ConnectionInfoProtocolVersion(conn_info) == CF_PROTOCOL_UNDEFINED); const int peek_size = CF_INBAND_OFFSET + sizeof("CAUTH"); char buf[peek_size]; ssize_t got = recv(ConnectionInfoSocket(conn_info), buf, sizeof(buf), MSG_PEEK); assert(got <= peek_size); if (got < 0) { assert(got == -1); Log(LOG_LEVEL_ERR, "TCP receive error: %s", GetErrorStr()); return -1; } else if (got == 0) { Log(LOG_LEVEL_INFO, "Peer closed TCP connection without sending data!"); return -1; } else if (got < peek_size) { Log(LOG_LEVEL_INFO, "Peer sent only %zd bytes! Considering the protocol as Classic", got); ConnectionInfoSetProtocolVersion(conn_info, CF_PROTOCOL_CLASSIC); } else if (memcmp(&buf[CF_INBAND_OFFSET], "CAUTH", strlen("CAUTH")) == 0) { Log(LOG_LEVEL_VERBOSE, "Peeked CAUTH in TCP stream, considering the protocol as Classic"); ConnectionInfoSetProtocolVersion(conn_info, CF_PROTOCOL_CLASSIC); } else /* got==peek_size && not "CAUTH" */ { Log(LOG_LEVEL_VERBOSE, "Peeked nothing important in TCP stream, considering the protocol as TLS"); ConnectionInfoSetProtocolVersion(conn_info, CF_PROTOCOL_TLS); } LogRaw(LOG_LEVEL_DEBUG, "Peeked data: ", buf, got); return 1; }
/** * @brief Set the connection type to CLASSIC or TLS. * It is performed by peeking into the TLS connection to read the first bytes, * and if it's a CAUTH protocol command use the old protocol loop, else use * the TLS protocol loop. * * @return -1 in case of error, 1 otherwise. */ int ServerTLSPeek(ConnectionInfo *conn_info) { assert(SSLSERVERCONTEXT != NULL && PRIVKEY != NULL && PUBKEY != NULL); /* This must be the first thing we run on an accepted connection. */ assert(conn_info->type == CF_PROTOCOL_UNDEFINED); const int peek_size = CF_INBAND_OFFSET + sizeof("CAUTH"); char buf[peek_size]; ssize_t got = recv(conn_info->sd, buf, sizeof(buf), MSG_PEEK); if (got == -1) { Log(LOG_LEVEL_ERR, "TCP connection: %s", GetErrorStr()); return -1; } else if (got == 0) { Log(LOG_LEVEL_ERR, "Peer closed TCP connection without sending data!"); return -1; } else if (got < peek_size) { Log(LOG_LEVEL_WARNING, "Peer sent only %zd bytes! Considering the protocol as Classic", got); conn_info->type = CF_PROTOCOL_CLASSIC; } else if (got == peek_size && memcmp(&buf[CF_INBAND_OFFSET], "CAUTH", strlen("CAUTH")) == 0) { Log(LOG_LEVEL_VERBOSE, "Peeked CAUTH in TCP stream, considering the protocol as Classic"); conn_info->type = CF_PROTOCOL_CLASSIC; } else /* got==peek_size && not "CAUTH" */ { Log(LOG_LEVEL_VERBOSE, "Peeked nothing important in TCP stream, considering the protocol as TLS"); LogRaw(LOG_LEVEL_DEBUG, "Peeked data: ", buf, sizeof(buf)); conn_info->type = CF_PROTOCOL_TLS; } return 1; }
void OpenCLPrintExtendedGpuInfo(int device) { const char *data; cl_int status; ocl_context_t *cont = ocl_get_context(device); if (cont == NULL) return; if (cont->firstOnPlatform) { //Print platform info once LogRaw("\nPlatform info:\n"); LogRaw("--------------\n"); cl_char str[80]; status = clGetPlatformInfo(cont->platformID, CL_PLATFORM_NAME, sizeof(str), (void *)str, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Platform Name", str); status = clGetPlatformInfo(cont->platformID, CL_PLATFORM_VENDOR, sizeof(str), (void *)str, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Platform Vendor", str); status = clGetPlatformInfo(cont->platformID, CL_PLATFORM_VERSION, sizeof(str), (void *)str, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Platform Version", str); cl_char *str2; size_t sz; status = clGetPlatformInfo(cont->platformID, CL_PLATFORM_EXTENSIONS, 0, NULL, &sz); if (sz) { str2 = (cl_char*)malloc(sz+1); if (str2) { status = clGetPlatformInfo(cont->platformID, CL_PLATFORM_EXTENSIONS, sz+1, (void *)str2, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Platform extensions", str2); free(str2); } } /* Split platform and device info */ LogRaw("\nDevice info:\n"); LogRaw("--------------\n"); } cl_char device_name[1024] = {0}; cl_device_type type; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_TYPE, sizeof(type), &type, NULL); if (status == CL_SUCCESS) { if ( type & CL_DEVICE_TYPE_CPU ) data = "CPU"; else { if ( type & CL_DEVICE_TYPE_GPU ) data = "GPU"; else data = "UNKNOWN"; } LogRaw("%30s: %s\n", "Type", data); } status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_NAME, sizeof(device_name), device_name, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Name",device_name); cl_uint clockrate; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(clockrate), &clockrate, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %u\n", "Max clockrate", clockrate); cl_uint cunits; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cunits), &cunits, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %u\n", "Max compute units", cunits); cl_ulong gmemcache; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof(gmemcache), &gmemcache, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %" PRIu64 "\n", "Global memory cache size", gmemcache); cl_device_mem_cache_type ct; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, sizeof(ct), &ct, NULL); if (status == CL_SUCCESS) { switch(ct) { case CL_NONE: data = "NONE"; break; case CL_READ_ONLY_CACHE: data = "Read Only"; break; case CL_READ_WRITE_CACHE: data = "Read/Write"; break; default: data = "Not sure"; } LogRaw("%30s: %s\n", "Global memory cache type", data); } cl_bool um; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(um), &um, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Unified memory subsystem", (um ? "Yes" : "No")); status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_IMAGE_SUPPORT, sizeof(um), &um, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Image support", (um ? "Yes" : "No")); status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(gmemcache), &gmemcache, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %" PRIu64 "\n", "Local memory size", gmemcache); size_t mwgs; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(mwgs), &mwgs, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %lu\n", "Max workgroup size", (unsigned long)mwgs); cl_uint nvw; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, sizeof(nvw), &nvw, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %u\n", "native vector width (int)", nvw); status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, sizeof(nvw), &nvw, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %u\n", "native vector width (float)", nvw); status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_OPENCL_C_VERSION, sizeof(device_name), device_name, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "OpenCL C version",device_name); size_t ptres; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_PROFILING_TIMER_RESOLUTION, sizeof(ptres), &ptres, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %lu\n", "Device timer resolution (ns)", (unsigned long)ptres); status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_VENDOR, sizeof(device_name), device_name, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Device vendor",device_name); cl_uint vendor_id; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_VENDOR_ID, sizeof(vendor_id), &vendor_id, NULL); if (status == CL_SUCCESS) LogRaw("%30s: 0x%x\n", "Device vendor id",vendor_id); status = clGetDeviceInfo(cont->deviceID, CL_DRIVER_VERSION, sizeof(device_name), device_name, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %s\n", "Driver version",device_name); cl_uint devbits; status = clGetDeviceInfo(cont->deviceID, CL_DEVICE_ADDRESS_BITS, sizeof(devbits), &devbits, NULL); if (status == CL_SUCCESS) LogRaw("%30s: %u%s\n", "Device address bits", devbits, (devbits == sizeof(size_t) * 8 ? "" : " - NOT MATCHED -")); //TODO: device extensions }
int main(int argc, char **argv) { config.daemonize = 0; config.logserver = "minard"; config.dataserver = "192.168.80.100";//"192.168.80.1"; config.logfile = ""; config.loglevel = NOTICE; parseOptions(argc, argv); strcpy(logfile, config.logfile); verbosity = config.loglevel; if (config.daemonize) daemonize(); signal(SIGPIPE, SIG_IGN); signal(SIGINT, sigint_handler); Log(NOTICE, "tubii server started"); el = aeCreateEventLoop(100); if ((aeCreateTimeEvent(el, 0, printSkipped, NULL, NULL)) == AE_ERR) { LogRaw(WARNING, "failed to set up printSkipped()"); } startLogServer(config.logserver, "tubii"); initServer(el, 4001, commandTable, sizeof(commandTable)/sizeof(struct command)); /* set up the dispatch_connect event which will try to connect to the * data stream server. If it can't connect, it will retry every 10 * seconds. */ if (data_connect(config.dataserver)) { Log(WARNING, "failed to set up data stream"); return 1; } auto_init(); /* start tubii readout */ if (start_tubii_readout(1000)) { //Log(WARNING, tubii_err); return 1; } /* set up status event */ if (aeCreateTimeEvent(el, 0, tubii_status, NULL, NULL) == AE_ERR) { Log(WARNING, "failed to set up status tubii"); return 1; } /* enter the main event loop */ el->stop = 0; while (!el->stop) { if (el->beforesleep != NULL) el->beforesleep(el); aeProcessEvents(el, AE_ALL_EVENTS); } Log(NOTICE, "ctrl-c caught. flushing buffers..."); time_t now = time(NULL); while (time(NULL) < now + 1) { if (aeProcessEvents(el, AE_FILE_EVENTS | AE_DONT_WAIT) == 0) break; } aeDeleteEventLoop(el); return 0; }
/** * @return 0 in case of socket closed, -1 in case of other error, or * >0 the number of bytes read. */ int ReceiveTransaction(const ConnectionInfo *conn_info, char *buffer, int *more) { char proto[CF_INBAND_OFFSET + 1] = { 0 }; char status = 'x'; unsigned int len = 0; int ret; /* Get control channel. */ switch(ConnectionInfoProtocolVersion(conn_info)) { case CF_PROTOCOL_CLASSIC: ret = RecvSocketStream(ConnectionInfoSocket(conn_info), proto, CF_INBAND_OFFSET); break; case CF_PROTOCOL_TLS: ret = TLSRecv(ConnectionInfoSSL(conn_info), proto, CF_INBAND_OFFSET); break; default: UnexpectedError("ReceiveTransaction: ProtocolVersion %d!", ConnectionInfoProtocolVersion(conn_info)); ret = -1; } if (ret == -1 || ret == 0) return ret; LogRaw(LOG_LEVEL_DEBUG, "ReceiveTransaction header: ", proto, ret); ret = sscanf(proto, "%c %u", &status, &len); if (ret != 2) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: Bad packet -- bogus header: %s", proto); return -1; } if (len > CF_BUFSIZE - CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: Bad packet -- too long (len=%d)", len); return -1; } if (status != CF_MORE && status != CF_DONE) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: Bad packet -- bogus header (more='%c')", status); return -1; } if (more != NULL) { switch (status) { case CF_MORE: *more = true; break; case CF_DONE: *more = false; break; default: ProgrammingError("Unreachable, " "bogus headers have already been checked!"); } } /* Get data. */ switch(ConnectionInfoProtocolVersion(conn_info)) { case CF_PROTOCOL_CLASSIC: ret = RecvSocketStream(ConnectionInfoSocket(conn_info), buffer, len); break; case CF_PROTOCOL_TLS: ret = TLSRecv(ConnectionInfoSSL(conn_info), buffer, len); break; default: UnexpectedError("ReceiveTransaction: ProtocolVersion %d!", ConnectionInfoProtocolVersion(conn_info)); ret = -1; } LogRaw(LOG_LEVEL_DEBUG, "ReceiveTransaction data: ", buffer, ret); return ret; }
/** * @param len is the number of bytes to send, or 0 if buffer is a * '\0'-terminated string so strlen(buffer) can used. * @return -1 in case of error or connection closed * (also currently returns 0 for success but don't count on it) * @NOTE #buffer can't be of zero length, our protocol * does not allow empty transactions! The reason is that * ReceiveTransaction() can't differentiate between that * and connection closed. * @NOTE (len <= CF_BUFSIZE - CF_INBAND_OFFSET) */ int SendTransaction(const ConnectionInfo *conn_info, const char *buffer, int len, char status) { assert(status == CF_MORE || status == CF_DONE); char work[CF_BUFSIZE] = { 0 }; int ret; if (len == 0) { len = strlen(buffer); } /* Not allowed to send zero-payload packets, because (ReceiveTransaction() == 0) currently means connection closed. */ assert(len > 0); if (len > CF_BUFSIZE - CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "SendTransaction: len (%d) > %d - %d", len, CF_BUFSIZE, CF_INBAND_OFFSET); return -1; } snprintf(work, CF_INBAND_OFFSET, "%c %d", status, len); memcpy(work + CF_INBAND_OFFSET, buffer, len); Log(LOG_LEVEL_DEBUG, "SendTransaction header: %s", work); LogRaw(LOG_LEVEL_DEBUG, "SendTransaction data: ", work + CF_INBAND_OFFSET, len); switch(conn_info->protocol) { case CF_PROTOCOL_CLASSIC: ret = SendSocketStream(conn_info->sd, work, len + CF_INBAND_OFFSET); break; case CF_PROTOCOL_TLS: ret = TLSSend(conn_info->ssl, work, len + CF_INBAND_OFFSET); if (ret <= 0) { ret = -1; } break; default: UnexpectedError("SendTransaction: ProtocolVersion %d!", conn_info->protocol); ret = -1; } if (ret == -1) { return -1; /* error */ } else { /* SSL_MODE_AUTO_RETRY guarantees no partial writes. */ assert(ret == len + CF_INBAND_OFFSET); return 0; } }
/** * Receive a transaction packet of at most CF_BUFSIZE-1 bytes, and * NULL-terminate it. * * @return 0 in case of socket closed, -1 in case of other error, or * >0 the number of bytes read. */ int ReceiveTransaction(const ConnectionInfo *conn_info, char *buffer, int *more) { char proto[CF_INBAND_OFFSET + 1] = { 0 }; int ret; /* Get control channel. */ switch(conn_info->protocol) { case CF_PROTOCOL_CLASSIC: ret = RecvSocketStream(conn_info->sd, proto, CF_INBAND_OFFSET); break; case CF_PROTOCOL_TLS: ret = TLSRecv(conn_info->ssl, proto, CF_INBAND_OFFSET); break; default: UnexpectedError("ReceiveTransaction: ProtocolVersion %d!", conn_info->protocol); ret = -1; } if (ret == -1 || ret == 0) { return ret; } else if (ret != CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: bogus short header (%d bytes: '%s')", ret, proto); return -1; } LogRaw(LOG_LEVEL_DEBUG, "ReceiveTransaction header: ", proto, ret); char status = 'x'; int len = 0; ret = sscanf(proto, "%c %d", &status, &len); if (ret != 2) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: bogus header: %s", proto); return -1; } if (status != CF_MORE && status != CF_DONE) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: bogus header (more='%c')", status); return -1; } if (len > CF_BUFSIZE - CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: packet too long (len=%d)", len); return -1; } else if (len <= 0) { /* Zero-length packets are disallowed, because * ReceiveTransaction() == 0 currently means connection closed. */ Log(LOG_LEVEL_ERR, "ReceiveTransaction: packet too short (len=%d)", len); return -1; } if (more != NULL) { switch (status) { case CF_MORE: *more = true; break; case CF_DONE: *more = false; break; default: ProgrammingError("Unreachable, " "bogus headers have already been checked!"); } } /* Get data. */ switch(conn_info->protocol) { case CF_PROTOCOL_CLASSIC: ret = RecvSocketStream(conn_info->sd, buffer, len); break; case CF_PROTOCOL_TLS: ret = TLSRecv(conn_info->ssl, buffer, len); break; default: UnexpectedError("ReceiveTransaction: ProtocolVersion %d!", conn_info->protocol); ret = -1; } if (ret == -1 || ret == 0) { return ret; } else if (ret != len) { /* Should never happen given that we are using SSL_MODE_AUTO_RETRY and * that transaction payload < CF_BUFSIZE < TLS record size. */ Log(LOG_LEVEL_ERR, "Partial transaction read %d != %d bytes!", ret, len); return -1; } LogRaw(LOG_LEVEL_DEBUG, "ReceiveTransaction data: ", buffer, ret); return ret; }