char * __mod_ssl_sni_common_handler (MyQttCtx * myqtt_ctx, MyQttConn * conn, const char * serverName, axlPointer user_data, const char * attr_name) { MyQttdCtx * ctx = user_data; axlNode * node; /* find certificate node by Name */ node = __mod_ssl_get_certificate_node_by_name (ctx, serverName); if (! node) { wrn ("No certificate was found for serverName=%s, requested by connecting ip=%s", serverName, myqtt_conn_get_host_ip (conn)); return NULL; /* no node certificate was found, finish * here */ } /* end if */ if (! HAS_ATTR (node, attr_name)) { wrn ("No certificate was found for serverName=%s, requested by connecting ip=%s, node %s attribute was not defined", serverName, myqtt_conn_get_host_ip (conn), attr_name); return NULL; /* no crt attr was found, finish here */ } /* end if */ /* ok, now report certificate location */ if (__mod_ssl_debug) msg ("Reporting certificate %s=%s for serverName=%s", attr_name, ATTR_VALUE (node, attr_name), serverName); /* report certificate */ return axl_strdup (ATTR_VALUE (node, attr_name)); }
void backTrack (void *v, int device, int mouseDown) { pWmj cW = (pWmj)v, pW = cW->prev; /* WmjAct *Ap = (device == LEFTMOUSE ? cW->lefMouse : cW->midMouse); */ pDmj cD = &cW->D; long bxA, byA, nxA, nyA, oxA,oyA, wx,ww,wy,wh; long widA = winget(); if (! mouseDown) return; getorigin(&wx,&wy); getsize( &ww,&wh); ww -= 1; wh -= 1; oxA = bxA = (getvaluator(MOUSEX) - wx); oyA = byA = (getvaluator(MOUSEY) - wy); cursoff(); drawmode(OVERDRAW); while(getbutton(device)) { nxA = getvaluator(MOUSEX) - wx; if (nxA < 0) nxA = 0; else if (nxA > ww) nxA = ww; nyA = getvaluator(MOUSEY) - wy; if (nyA < 0) nyA = 0; else if (nyA > wh) nyA = wh; if (nxA != oxA || nyA != oyA) { /* winset(widA); */ color(BLACK); /* black erases */ sboxi(bxA,byA,oxA,oyA); /* NB: sbox is faster than rect, but less flex */ color(RED); /* set color of new circle */ sboxi(bxA,byA,nxA,nyA); oxA = nxA, oyA = nyA; } } color(BLACK); sboxi(bxA,byA,oxA,oyA); drawmode(NORMALDRAW); cpack(FcGRN); sboxi(bxA,byA,nxA,nyA); if (pW) { pDmj pD = &pW->D; flt pzX = pW->zX, zX = pzX/cW->zX; flt pzY = pW->zY, zY = pzY/cW->zY; long L = cD->l*pzX, B = cD->b*pzY; wrn("bT: id: %d pD->lb: %3d %3d zXY: %.1f %.1f", pW->id, pD->l, pD->b, zX, zY); wrn("bT: id: %d cD->lb: %3d %3d czXY: %.1f %.1f", cW->id, cD->l, cD->b,cW->zX,cW->zY); winset(pW->id); drawmode(OVERDRAW); color(YELLOW); sboxi(L + bxA*zX, B + byA*zY, L + oxA*zX, B + oyA*zY); drawmode(NORMALDRAW); } winset(widA); curson(); }
/** * @internal * Function used to read content from the socket in the loop into the * connection proxied. * * Read Write * [ Loop socket ] --> [ Proxy connection ] */ axl_bool __myqttd_conn_proxy_reads_loop (MyQttdLoop * loop, MyQttdCtx * ctx, int descriptor, axlPointer ptr, axlPointer ptr2) { MyQttConn * conn = ptr; char buffer[4096]; int bytes_read; /* read content */ bytes_read = recv (descriptor, buffer, 4096, 0); /* msg ("PROXY: reading from socket=%d (bytes read=%d, errno=%d)", descriptor, bytes_read, errno); */ /* send content */ if (bytes_read <= 0 || ! myqtt_conn_is_ok (conn, axl_false) || ! myqtt_msg_send_raw (conn, (unsigned char *) buffer, bytes_read)) { /* close socket and unregister it and close associated conn */ wrn ("PROXY-fd: connection-id=%d is falling (wasn't able to send %d bytes, is zero?), closing associated socket=%d", myqtt_conn_get_id (conn), bytes_read, descriptor); /* check connection status to finish it */ if (myqtt_conn_is_ok (conn, axl_false)) myqtt_conn_shutdown (conn); return axl_false; } /* end if */ return axl_true; /* continue reading that socket */ }
void myqttd_conn_mgr_unref (axlPointer data) { /* get a reference to the state */ MyQttdConnMgrState * state = data; MyQttdCtx * ctx = state->ctx; /* check connection status */ if (state->conn) { /* uninstall on close full handler to avoid race conditions */ myqtt_conn_remove_on_close (state->conn, myqttd_conn_mgr_on_close, ctx); /* unref the connection */ msg ("Unregistering connection: %d (%p, socket: %d)", myqtt_conn_get_id ((MyQttConn*) state->conn), state->conn, myqtt_conn_get_socket (state->conn)); myqtt_conn_unref ((MyQttConn*) state->conn, "myqttd-conn-mgr"); } /* end if */ /* nullify and free */ memset (state, 0, sizeof (MyQttdConnMgrState)); axl_free (state); /* check if we have to initiate child process termination */ if (ctx->child && ctx->started) { /* msg ("CHILD: Checking for process termination, current connections are: %d", axl_hash_items (ctx->conn_mgr_hash)); */ if (axl_hash_items (ctx->conn_mgr_hash) == 0) { wrn ("CHILD: Starting finishing process, current connections are: 0"); myqttd_process_check_for_finish (ctx); } } /* end if */ return; }
void sgiWritFB(ppf rgb[4], int dX, int dY, unt dW, unt dH, unt dD, char *path) { IMAGE *sgim; int k,y,yI; flt *sr, *sg, *sb ; pus dr, dg, db, rr, gg, bb; mallocAss(rr,ush,dW); mallocAss(gg,ush,dW); mallocAss(bb,ush,dW); wrn("sgiWritFB dD: %u path: %s", dD,path); if (dD < 3 || rgb[1] == NULL) { sgiWritFlt(rgb[0],dX,dY,dW,dH,path); return; } sgim = iopen(path,"w",RLE(1),3,dW,dH,3); /* WHAT'S the 1st 3? */ for (y = 0, yI = dH+dY; yI > dY ; y++) { sr = &rgb[1][--yI][dX]; sg = &rgb[2][ yI][dX]; sb = &rgb[3][ yI][dX]; for (dr = rr, dg = gg, db = bb, k = dW; k; k--) { *dr++ = 0.5F + *sr++; *dg++ = 0.5F + *sg++; *db++ = 0.5F + *sb++; } putrow(sgim,rr,y,0); putrow(sgim,gg,y,1); putrow(sgim,bb,y,2); } iclose(sgim); free(rr); free(gg); free(bb); }
void rubberRectZoid (void *v, int device, int mouseDown) { static WmjAct backAct; pWmj cW = (pWmj)v; WmjAct *Ap = (device == LEFTMOUSE ? cW->lefMouse : cW->midMouse); /* Tetra *trp = Ap->data; */ flt zX = cW->zX, zY = cW->zY; long bxA, byA, nxA, nyA, oxA,oyA, wx,ww,wy,wh; long widA = winget(); if (! mouseDown) return; getorigin(&wx,&wy); getsize( &ww,&wh); ww -= 1; wh -= 1; oxA = bxA = (getvaluator(MOUSEX) - wx); oyA = byA = (getvaluator(MOUSEY) - wy); cursoff(); drawmode(OVERDRAW); while(getbutton(device)) { nxA = getvaluator(MOUSEX) - wx; if (nxA < 0) nxA = 0; else if (nxA > ww) nxA = ww; nyA = getvaluator(MOUSEY) - wy; if (nyA < 0) nyA = 0; else if (nyA > wh) nyA = wh; if (nxA != oxA || nyA != oyA) { winset(widA); color(BLACK); /* black erases */ sboxi(bxA,byA,oxA,oyA); color(RED); /* set color of new circle */ sboxi(bxA,byA,nxA,nyA); oxA = nxA, oyA = nyA; } } color(BLACK); sboxi(bxA,byA,oxA,oyA); drawmode(NORMALDRAW); cpack(FcGRN); sboxi(bxA,byA,nxA,nyA); if (bxA > nxA) nxA = bxA, bxA = oxA; if (byA > nyA) nyA = byA, byA = oyA; wrn("rubberRectZ B4 showSub: %4d %4d %4d %4d zX:%.2f zY:%.2f",bxA,byA,nxA,nyA, zX, zY); backAct = *Ap; backAct.func = &testChain; cW->next = showSub(cW, bxA/zX,byA/zY,nxA/zX,nyA/zY,"subA",zX*2.0,zY*2.0,5); cW->next->lefMouse = &backAct; cW->next->prev = cW; winset(widA); curson(); }
/** * @internal Creates a object that will represents a child object and * initialize internal data structures for its function. */ MyQttdChild * myqttd_child_new (MyQttdCtx * ctx) { MyQttdChild * result; char * temp_dir; struct timeval now; result = axl_new (MyQttdChild, 1); /* check allocation */ if (result == NULL) return NULL; /* get current time */ gettimeofday (&now, NULL); /* create socket path: socket used to transfer file descriptors from parent to child */ result->socket_control_path = axl_strdup_printf ("%s%s%s%s%p%d%d.myqttd", myqttd_runtime_datadir (ctx), MYQTT_FILE_SEPARATOR, "myqttd", MYQTT_FILE_SEPARATOR, result, now.tv_sec, now.tv_usec); /* check result */ if (result->socket_control_path == NULL) { axl_free (result); return NULL; } /* end if */ /* now check check base dir for socket control path exists */ temp_dir = myqttd_base_dir (result->socket_control_path); if (temp_dir && ! myqtt_support_file_test (temp_dir, FILE_EXISTS)) { /* base directory having child socket control do not exists */ wrn ("run time directory %s do not exists, creating..", temp_dir); if (! myqttd_create_dir (temp_dir)) { /* call to finish references */ myqttd_child_unref (result); error ("Unable to create directory to hold child socket connection, unable to create child process.."); axl_free (temp_dir); return NULL; } /* end if */ } /* end if */ /* free temporal directory */ axl_free (temp_dir); /* set context */ result->ctx = ctx; /* set default reference counting */ result->ref_count = 1; myqtt_mutex_create (&result->mutex); return result; }
static int initputvar() { if (!isatty(STDERR_FILENO)) return 0; if (putvarc) free(putvarc); if (!termsetup) { int status; if (! (termsetup = (setupterm(NULL, STDERR_FILENO, &status) == OK && status == 1))) { wrn( "Terminal doesn't support color (setupterm errno %d).\n", status ); return 0; } } putvarc=(char *)calloc(256, sizeof(char)); putvari=0; return 1; }
MyQttConn * __mod_ssl_start_listener (MyQttdCtx * ctx, MyQttCtx * my_ctx, axlNode * port_node, const char * bind_addr, const char * port, axlPointer user_data) { MyQttConn * listener; axlNode * node; const char * crt, * key, * chain; /* create listener on the port indicated */ listener = myqtt_tls_listener_new ( /* the context where the listener will * be started */ my_ctx, /* listener name */ bind_addr ? bind_addr : "0.0.0.0", /* port to use */ port, /* opts */ NULL, /* on ready callbacks */ NULL, NULL); /* configure default certificates from store */ node = __mod_ssl_get_default_certificate (ctx, my_ctx); if (node) { /* configure certificates */ crt = ATTR_VALUE (node, "crt"); key = ATTR_VALUE (node, "key"); chain = ATTR_VALUE (node, "chain"); msg ("mod-ssl: configuring default crt=%s, key=%s, chain=%s", crt, key, chain); if (! myqtt_tls_set_certificate (listener, crt, key, chain)) { error ("unable to configure certificates for TLS mqtt (myqtt_tls_set_certificate failed).."); return NULL; } /* end if */ } else { wrn ("Unable to configure any certificate. No default certificate was found. __mod_ssl_get_default_certificate() reported NULL"); } /* end if */ return listener; /* basic configuration done */ }
/** * @internal * Function used to read content from the connection and write that * content into the child socket. * * Read Write * [ Proxied connection ] --> [ Child socket ] */ void __myqttd_conn_mgr_proxy_reads (MyQttCtx * myqtt_ctx, MyQttConn * listener, MyQttConn * conn, MyQttConnOpts * opts, axlPointer user_data) { char buffer[4096]; int bytes_read; /* get socket associated */ int _socket = PTR_TO_INT (myqtt_conn_get_data (conn, "myqttd:proxy:fd")); MyQttdCtx * ctx = user_data; /* check connection status */ if (! myqtt_conn_is_ok (conn, axl_false)) return; /* check status and close the other connection if found that */ bytes_read = myqtt_msg_receive_raw (conn, (unsigned char *) buffer, 4096); /* msg ("PROXY-mqtt: Read %d bytes from conn-id=%d, sending them to child socket=%d (refs: %d, status: %d, errno=%d%s%s)", bytes_read, myqtt_conn_get_id (conn), _socket, myqtt_conn_ref_count (conn), myqtt_conn_is_ok (conn, axl_false), errno, errno != 0 ? " : " : "", errno != 0 ? strerror (errno) : ""); */ if (bytes_read > 0) { /* send content */ if (send (_socket, buffer, bytes_read, 0) != bytes_read) { wrn ("PROXY-mqtt: closing conn-id=%d because socket=%d isn't working", myqtt_conn_get_id (conn), _socket); /* remove preread handler and shutdown */ myqtt_conn_shutdown (conn); return; } /* end if */ /* buffer[bytes_read] = 0; msg ("PROXY-mqtt: sent content (mqtt conn-id=%d -> socket=%d): %s", myqtt_conn_get_id (conn), _socket, buffer); */ } /* end if */ return; }
/** * @internal Places current process identifier into the file provided * by the user. */ void valvulad_place_pidfile (ValvuladCtx * ctx) { FILE * pid_file = NULL; int pid = getpid (); char buffer[20]; int size; axlNode * node; int gid, uid; /* check if pid file exists */ if (! exarg_is_defined ("skip-pid-check")) { if (valvula_support_file_test (pid_file_path, FILE_EXISTS)) { abort_error ("Unable to start server, found pid file in place %s. There is a valvula server running. If not, remove file %s", pid_file_path, pid_file_path); exit (-1); return; } /* end if */ } else { wrn ("Skipping pid file checking.."); } /* end if */ /* open pid file or create it to place the pid file */ pid_file = fopen (pid_file_path, "w"); if (pid_file == NULL) { abort_error ("Unable to open pid file at: %s", pid_file_path); return; } /* end if */ /* stringfy pid */ size = axl_stream_printf_buffer (buffer, 20, NULL, "%d", pid); msg ("signaling PID %d at %s", pid, pid_file_path); if (fwrite (buffer, size, 1, pid_file) <= 0) { abort_error ("Unable to write pid file content at %s, error was: errno=%d : %s", pid_file, errno, strerror (errno)); return; } fclose (pid_file); pid_file = fopen (valvula_status, "w"); if (pid_file == NULL) { abort_error ("Unable to open valvula status file at: %s (errno=%d)", valvula_status, errno); return; } /* end if */ fprintf (pid_file, "<valvula-state>\n"); fprintf (pid_file, " <attr name='valvula pid' value='%d' />\n", getpid ()); fprintf (pid_file, "</valvula-state>\n"); fclose (pid_file); /* now change permissions (if required) */ node = axl_doc_get (ctx->config, "/valvula/global-settings/running"); if (node && ATTR_VALUE (node, "user") && ATTR_VALUE (node, "group") && HAS_ATTR_VALUE (node, "enabled", "yes")) { /* change group first */ gid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "group"), axl_false); uid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "user"), axl_true); msg ("Attempting to update pid ownership to %d:%d", uid, gid); if (gid > 0 && uid > 0) { if (chown (valvula_status, uid, gid) != 0) { error ("Unable to change permissions to file %s (%d:%d), error was errno=%d (%s)", valvula_status, uid, gid, errno, strerror (errno)); } /* end if */ /**** do no change pid file ownership is a security problem ****/ } /* end if */ } /* end if */ return; }
int hoghdd (long long forks, int clean, long long files, long long bytes) { long long i, j; int fd, pid, retval = 0; int chunk = (1024 * 1024) - 1; /* Minimize slow writing. */ char buff[chunk]; /* Make local copies of global variables. */ int ignore = global_ignore; int retry = global_retry; int timeout = global_timeout; long backoff = global_backoff * forks; /* Initialize buffer with some random ASCII data. */ dbg (stdout, "seeding buffer with random data\n"); for (i = 0; i < chunk - 1; i++) { j = rand (); j = (j < 0) ? -j : j; j %= 95; j += 32; buff[i] = j; } buff[i] = '\n'; dbg (stdout, "using backoff sleep of %lius for hoghdd\n", backoff); for (i = 0; forks == 0 || i < forks; i++) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); /* Use a backoff sleep to ensure we get good fork throughput. */ usleep (backoff); while (1) { for (i = 0; i < files; i++) { char name[] = "./stress.XXXXXX"; if ((fd = mkstemp (name)) < 0) { perror ("mkstemp"); err (stderr, "mkstemp failed\n"); exit (1); } if (clean == 0) { dbg (stdout, "unlinking %s\n", name); if (unlink (name)) { err (stderr, "unlink failed\n"); exit (1); } } dbg (stdout, "fast writing to %s\n", name); for (j = 0; bytes == 0 || j + chunk < bytes; j += chunk) { if (write (fd, buff, chunk) != chunk) { err (stderr, "write failed\n"); exit (1); } } dbg (stdout, "slow writing to %s\n", name); for (; bytes == 0 || j < bytes - 1; j++) { if (write (fd, "Z", 1) != 1) { err (stderr, "write failed\n"); exit (1); } } if (write (fd, "\n", 1) != 1) { err (stderr, "write failed\n"); exit (1); } ++j; dbg (stdout, "closing %s after writing %lli bytes\n", name, j); close (fd); if (clean == 1) { if (unlink (name)) { err (stderr, "unlink failed\n"); exit (1); } } } if (retval == 0) { dbg (stdout, "hoghdd worker starting over\n"); continue; } exit (retval); } /* This case never falls through; alarm signal can cause exit. */ case -1: /* error */ if (ignore) { ++retval; wrn (stderr, "hoghdd worker fork failed, continuing\n"); usleep (retry); continue; } err (stderr, "hoghdd worker fork failed\n"); return 1; default: /* parent */ dbg (stdout, "--> hoghdd worker forked (%i)\n", pid); } } /* Wait for our children to exit. */ while (i) { int status, ret; if ((pid = wait (&status)) > 0) { if ((WIFEXITED (status)) != 0) { if ((ret = WEXITSTATUS (status)) != 0) { err (stderr, "hoghdd worker %i exited %i\n", pid, ret); retval += ret; } else { dbg (stdout, "<-- hoghdd worker exited (%i)\n", pid); } } else { dbg (stdout, "<-- hoghdd worker signalled (%i)\n", pid); } --i; } else { dbg (stdout, "wait() returned error: %s\n", strerror (errno)); err (stderr, "detected missing hoghdd worker children\n"); ++retval; break; } } return retval; }
int hogvm (long long forks, long long chunks, long long bytes) { long long i, j, k; int pid, retval = 0; char *ptr; /* Make local copies of global variables. */ int ignore = global_ignore; int retry = global_retry; int timeout = global_timeout; long backoff = global_backoff * forks; dbg (stdout, "using backoff sleep of %lius for hogvm\n", backoff); if (bytes == 0) { /* 512MB is guess at the largest value can than be malloced at once. */ bytes = 512 * 1024 * 1024; } for (i = 0; forks == 0 || i < forks; i++) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); /* Use a backoff sleep to ensure we get good fork throughput. */ usleep (backoff); while (1) { for (j = 0; chunks == 0 || j < chunks; j++) { if ((ptr = (char *) malloc (bytes * sizeof (char)))) { for (k = 0; k < bytes; k++) ptr[k] = 'Z'; /* Ensure that COW happens. */ dbg (stdout, "hogvm worker malloced %lli bytes\n", k); } else if (ignore) { ++retval; wrn (stderr, "hogvm malloc failed, continuing\n"); usleep (retry); continue; } else { ++retval; err (stderr, "hogvm malloc failed\n"); break; } } if (global_vmhang && retval == 0) { dbg (stdout, "sleeping forever with allocated memory\n"); while (1) sleep (1024); } if (retval == 0) { dbg (stdout, "hogvm worker freeing memory and starting over\n"); free (ptr); continue; } exit (retval); } /* This case never falls through; alarm signal can cause exit. */ case -1: /* error */ if (ignore) { ++retval; wrn (stderr, "hogvm worker fork failed, continuing\n"); usleep (retry); continue; } err (stderr, "hogvm worker fork failed\n"); return 1; default: /* parent */ dbg (stdout, "--> hogvm worker forked (%i)\n", pid); } } /* Wait for our children to exit. */ while (i) { int status, ret; if ((pid = wait (&status)) > 0) { if ((WIFEXITED (status)) != 0) { if ((ret = WEXITSTATUS (status)) != 0) { err (stderr, "hogvm worker %i exited %i\n", pid, ret); retval += ret; } else { dbg (stdout, "<-- hogvm worker exited (%i)\n", pid); } } else { dbg (stdout, "<-- hogvm worker signalled (%i)\n", pid); } --i; } else { dbg (stdout, "wait() returned error: %s\n", strerror (errno)); err (stderr, "detected missing hogvm worker children\n"); ++retval; break; } } return retval; }
int hogio (long long forks) { long long i; int pid, retval = 0; /* Make local copies of global variables. */ int ignore = global_ignore; int retry = global_retry; int timeout = global_timeout; long backoff = global_backoff * forks; dbg (stdout, "using backoff sleep of %lius for hogio\n", backoff); for (i = 0; forks == 0 || i < forks; i++) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); /* Use a backoff sleep to ensure we get good fork throughput. */ usleep (backoff); while (1) sync (); /* This case never falls through; alarm signal can cause exit. */ case -1: /* error */ if (ignore) { ++retval; wrn (stderr, "hogio worker fork failed, continuing\n"); usleep (retry); continue; } err (stderr, "hogio worker fork failed\n"); return 1; default: /* parent */ dbg (stdout, "--> hogio worker forked (%i)\n", pid); } } /* Wait for our children to exit. */ while (i) { int status, ret; if ((pid = wait (&status)) > 0) { if ((WIFEXITED (status)) != 0) { if ((ret = WEXITSTATUS (status)) != 0) { err (stderr, "hogio worker %i exited %i\n", pid, ret); retval += ret; } else { dbg (stdout, "<-- hogio worker exited (%i)\n", pid); } } else { dbg (stdout, "<-- hogio worker signalled (%i)\n", pid); } --i; } else { dbg (stdout, "wait() returned error: %s\n", strerror (errno)); err (stderr, "detected missing hogio worker children\n"); ++retval; break; } } return retval; }
int main (int argc, char **argv) { int i, pid, children = 0, retval = 0; long starttime, stoptime, runtime, forks; /* Variables that indicate which options have been selected. */ int do_dryrun = 0; long long do_backoff = 3000; long long do_timeout = 0; long long do_cpu = 0; long long do_io = 0; long long do_vm = 0; long long do_vm_bytes = 256 * 1024 * 1024; long long do_vm_stride = 4096; long long do_vm_hang = -1; int do_vm_keep = 0; long long do_hdd = 0; int do_hdd_clean = 2; long long do_hdd_bytes = 1024 * 1024 * 1024; /* Record our start time. */ if ((starttime = time (NULL)) == -1) { err (stderr, "failed to acquire current time: %s\n", strerror (errno)); exit (1); } /* SuSv3 does not define any error conditions for this function. */ global_progname = basename (argv[0]); /* For portability, parse command line options without getopt_long. */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-?") == 0) { usage (0); } else if (strcmp (arg, "--version") == 0) { version (0); } else if (strcmp (arg, "--verbose") == 0 || strcmp (arg, "-v") == 0) { global_debug = 3; } else if (strcmp (arg, "--quiet") == 0 || strcmp (arg, "-q") == 0) { global_debug = 0; } else if (strcmp (arg, "--dry-run") == 0 || strcmp (arg, "-n") == 0) { do_dryrun = 1; } else if (strcmp (arg, "--backoff") == 0) { assert_arg ("--backoff"); if (sscanf (arg, "%lli", &do_backoff) != 1) { err (stderr, "invalid number: %s\n", arg); exit (1); } if (do_backoff < 0) { err (stderr, "invalid backoff factor: %lli\n", do_backoff); exit (1); } dbg (stdout, "setting backoff coeffient to %llius\n", do_backoff); } else if (strcmp (arg, "--timeout") == 0 || strcmp (arg, "-t") == 0) { assert_arg ("--timeout"); do_timeout = atoll_s (arg); if (do_timeout <= 0) { err (stderr, "invalid timeout value: %llis\n", do_timeout); exit (1); } } else if (strcmp (arg, "--cpu") == 0 || strcmp (arg, "-c") == 0) { assert_arg ("--cpu"); do_cpu = atoll_b (arg); if (do_cpu <= 0) { err (stderr, "invalid number of cpu hogs: %lli\n", do_cpu); exit (1); } } else if (strcmp (arg, "--io") == 0 || strcmp (arg, "-i") == 0) { assert_arg ("--io"); do_io = atoll_b (arg); if (do_io <= 0) { err (stderr, "invalid number of io hogs: %lli\n", do_io); exit (1); } } else if (strcmp (arg, "--vm") == 0 || strcmp (arg, "-m") == 0) { assert_arg ("--vm"); do_vm = atoll_b (arg); if (do_vm <= 0) { err (stderr, "invalid number of vm hogs: %lli\n", do_vm); exit (1); } } else if (strcmp (arg, "--vm-bytes") == 0) { assert_arg ("--vm-bytes"); do_vm_bytes = atoll_b (arg); if (do_vm_bytes <= 0) { err (stderr, "invalid vm byte value: %lli\n", do_vm_bytes); exit (1); } } else if (strcmp (arg, "--vm-stride") == 0) { assert_arg ("--vm-stride"); do_vm_stride = atoll_b (arg); if (do_vm_stride <= 0) { err (stderr, "invalid stride value: %lli\n", do_vm_stride); exit (1); } } else if (strcmp (arg, "--vm-hang") == 0) { assert_arg ("--vm-hang"); do_vm_hang = atoll_b (arg); if (do_vm_hang < 0) { err (stderr, "invalid value: %lli\n", do_vm_hang); exit (1); } } else if (strcmp (arg, "--vm-keep") == 0) { do_vm_keep = 1; } else if (strcmp (arg, "--hdd") == 0 || strcmp (arg, "-d") == 0) { assert_arg ("--hdd"); do_hdd = atoll_b (arg); if (do_hdd <= 0) { err (stderr, "invalid number of hdd hogs: %lli\n", do_hdd); exit (1); } } else if (strcmp (arg, "--hdd-noclean") == 0) { do_hdd_clean = 0; } else if (strcmp (arg, "--hdd-bytes") == 0) { assert_arg ("--hdd-bytes"); do_hdd_bytes = atoll_b (arg); if (do_hdd_bytes <= 0) { err (stderr, "invalid hdd byte value: %lli\n", do_hdd_bytes); exit (1); } } else { err (stderr, "unrecognized option: %s\n", arg); exit (1); } } /* Print startup message if we have work to do, bail otherwise. */ if (do_cpu + do_io + do_vm + do_hdd) { out (stdout, "dispatching hogs: %lli cpu, %lli io, %lli vm, %lli hdd\n", do_cpu, do_io, do_vm, do_hdd); } else usage (0); /* Round robin dispatch our worker processes. */ while ((forks = (do_cpu + do_io + do_vm + do_hdd))) { long long backoff, timeout = 0; /* Calculate the backoff value so we get good fork throughput. */ backoff = do_backoff * forks; dbg (stdout, "using backoff sleep of %llius\n", backoff); /* If we are supposed to respect a timeout, calculate it. */ if (do_timeout) { long long currenttime; /* Acquire current time. */ if ((currenttime = time (NULL)) == -1) { perror ("error acquiring current time"); exit (1); } /* Calculate timeout based on current time. */ timeout = do_timeout - (currenttime - starttime); if (timeout > 0) { dbg (stdout, "setting timeout to %llis\n", timeout); } else { wrn (stderr, "used up time before all workers dispatched\n"); break; } } if (do_cpu) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); usleep (backoff); if (do_dryrun) exit (0); exit (hogcpu ()); case -1: /* error */ err (stderr, "fork failed: %s\n", strerror (errno)); break; default: /* parent */ dbg (stdout, "--> hogcpu worker %lli [%i] forked\n", do_cpu, pid); ++children; } --do_cpu; } if (do_io) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); usleep (backoff); if (do_dryrun) exit (0); exit (hogio ()); case -1: /* error */ err (stderr, "fork failed: %s\n", strerror (errno)); break; default: /* parent */ dbg (stdout, "--> hogio worker %lli [%i] forked\n", do_io, pid); ++children; } --do_io; } if (do_vm) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); usleep (backoff); if (do_dryrun) exit (0); exit (hogvm (do_vm_bytes, do_vm_stride, do_vm_hang, do_vm_keep)); case -1: /* error */ err (stderr, "fork failed: %s\n", strerror (errno)); break; default: /* parent */ dbg (stdout, "--> hogvm worker %lli [%i] forked\n", do_vm, pid); ++children; } --do_vm; } if (do_hdd) { switch (pid = fork ()) { case 0: /* child */ alarm (timeout); usleep (backoff); if (do_dryrun) exit (0); exit (hoghdd (do_hdd_bytes, do_hdd_clean)); case -1: /* error */ err (stderr, "fork failed: %s\n", strerror (errno)); break; default: /* parent */ dbg (stdout, "--> hoghdd worker %lli [%i] forked\n", do_hdd, pid); ++children; } --do_hdd; } } /* Wait for our children to exit. */ while (children) { int status, ret; if ((pid = wait (&status)) > 0) { --children; if (WIFEXITED (status)) { if ((ret = WEXITSTATUS (status)) == 0) { dbg (stdout, "<-- worker %i returned normally\n", pid); } else { err (stderr, "<-- worker %i returned error %i\n", pid, ret); ++retval; wrn (stderr, "now reaping child worker processes\n"); if (signal (SIGUSR1, SIG_IGN) == SIG_ERR) err (stderr, "handler error: %s\n", strerror (errno)); if (kill (-1 * getpid (), SIGUSR1) == -1) err (stderr, "kill error: %s\n", strerror (errno)); } } else if (WIFSIGNALED (status)) { if ((ret = WTERMSIG (status)) == SIGALRM) { dbg (stdout, "<-- worker %i signalled normally\n", pid); } else if ((ret = WTERMSIG (status)) == SIGUSR1) { dbg (stdout, "<-- worker %i reaped\n", pid); } else { err (stderr, "<-- worker %i got signal %i\n", pid, ret); ++retval; wrn (stderr, "now reaping child worker processes\n"); if (signal (SIGUSR1, SIG_IGN) == SIG_ERR) err (stderr, "handler error: %s\n", strerror (errno)); if (kill (-1 * getpid (), SIGUSR1) == -1) err (stderr, "kill error: %s\n", strerror (errno)); } } else { err (stderr, "<-- worker %i exited abnormally\n", pid); ++retval; } } else { err (stderr, "error waiting for worker: %s\n", strerror (errno)); ++retval; break; } } /* Record our stop time. */ if ((stoptime = time (NULL)) == -1) { err (stderr, "failed to acquire current time\n"); exit (1); } /* Calculate our runtime. */ runtime = stoptime - starttime; /* Print final status message. */ if (retval) { err (stderr, "failed run completed in %lis\n", runtime); } else { out (stdout, "successful run completed in %lis\n", runtime); } exit (retval); }
ValvulaState bwl_check_status_rules (ValvulaCtx * _ctx, ValvulaRequest * request, ValvulaModBwlLevel level, const char * level_label, char ** message, ValvuladRes result, axl_bool first_specific) { ValvuladRow row; const char * status; const char * source; const char * destination; /* reset cursor */ valvulad_db_first_row (ctx, result); /* get row and then status */ row = GET_ROW (result); while (row) { /* get status */ status = GET_CELL (row, 0); source = GET_CELL (row, 1); destination = GET_CELL (row, 2); /* skip general rules first, look for specific rules where all attributes are defined */ if (first_specific && (!source || strlen (source) == 0 || !destination || strlen (destination) == 0)) { /* get next row */ row = GET_ROW (result); continue; } /* end if */ /* ensure source matches */ if (! valvula_address_rule_match (ctx->ctx, source, request->sender)) { if (__mod_bwl_enable_debug) wrn ("BWL: rule does not match(1) status=%s, source=%s, destination=%s", status, source, destination); /* get next row */ row = GET_ROW (result); continue; } /* end if */ if (! valvula_address_rule_match (ctx->ctx, destination, request->recipient)) { if (__mod_bwl_enable_debug) wrn ("BWL: rule does not match(2) status=%s, source=%s, destination=%s", status, source, destination); /* get next row */ row = GET_ROW (result); continue; } /* end if */ /* msg ("BWL: checking status=%s, source=%s, destination=%s", status, source, destination); msg ("BWL: with request source=%s, destination=%s", request->sender, request->recipient); */ /* now check values */ if (axl_stream_casecmp (status, "ok", 2)) { /* accept it if the sender or reception domain is local */ if (valvulad_run_is_local_delivery (ctx, request)) { /* so, reached this point we have that * the rule (whitelist) was added and * it matches with a local delivery */ return VALVULA_STATE_OK; } else { if (__mod_bwl_enable_debug) wrn ("Skipping rule because it is not a local delivery.."); } /* end if */ } if (axl_stream_casecmp (status, "reject", 6)) { valvulad_reject (ctx, VALVULA_STATE_REJECT, request, "Rejecting due to blacklist (%s)", level_label); return VALVULA_STATE_REJECT; } /* end if */ if (axl_stream_casecmp (status, "discard", 7)) { valvulad_reject (ctx, VALVULA_STATE_DISCARD, request, "Discard due to blacklist (%s)", level_label); return VALVULA_STATE_DISCARD; } /* end if */ if (axl_stream_casecmp (status, "filter-discard", 14)) { /* do a discard but instaed or returning DISCARD, use a filter to the transport discard: */ (*message) = axl_strdup ("discard:"); valvulad_reject (ctx, VALVULA_STATE_FILTER, request, "Discard (using filter-discard) due to blacklist (%s)", level_label); return VALVULA_STATE_FILTER; } /* end if */ /* get next row */ row = GET_ROW (result); } /* end while */ /* report dunno state */ return VALVULA_STATE_DUNNO; }