Esempio n. 1
0
int nagios() {

	struct uwsgi_header uh;
	char *buf = NULL;

	if (!use_nagios) {
		return 1;
	}

	if (!uwsgi.sockets) {
		fprintf(stdout, "UWSGI UNKNOWN: you have specified an invalid socket\n");
		exit(3);
	}


	int fd = uwsgi_connect(uwsgi.sockets->name, uwsgi.socket_timeout, 0);
	if (fd < 0) {
		fprintf(stdout, "UWSGI CRITICAL: could not connect() to workers %s\n", strerror(errno));
		if (errno == EPERM || errno == EACCES) {
			exit(3);
		}
		exit(2);
	}

	uh.modifier1 = UWSGI_MODIFIER_PING;
	uh.pktsize = 0;
	uh.modifier2 = 0;
	if (write(fd, &uh, 4) != 4) {
		uwsgi_error("write()");
		fprintf(stdout, "UWSGI CRITICAL: could not send ping packet to workers\n");
		exit(2);
	}


	int ret = uwsgi_read_response(fd, &uh, uwsgi.socket_timeout, &buf);

	if (ret == -2) {
		fprintf(stdout, "UWSGI CRITICAL: timed out waiting for response\n");
		exit(2);
	}
	else if (ret == -1) {
		fprintf(stdout, "UWSGI CRITICAL: error reading response\n");
		exit(2);
	}
	else {
		if (uh.pktsize > 0 && buf) {
			fprintf(stdout, "UWSGI WARNING: %.*s\n", uh.pktsize, buf);
			exit(1);
		}
		else {
			fprintf(stdout, "UWSGI OK: armed and ready\n");
			exit(0);
		}
	}

	// never here
	fprintf(stdout, "UWSGI UNKNOWN: probably you hit a bug of uWSGI !!!\n");
	exit(3);
}
Esempio n. 2
0
void uwsgi_opt_corerouter_zerg(char *opt, char *value, void *cr) {

        int j;
        int count = 8;
        struct uwsgi_gateway_socket *ugs;
	struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr;

        int zerg_fd = uwsgi_connect(value, 30, 0);
        if (zerg_fd < 0) {
                uwsgi_log("--- unable to connect to zerg server ---\n");
                exit(1);
        }

        int last_count = count;
        int *zerg = uwsgi_attach_fd(zerg_fd, &count, "uwsgi-zerg", 10);
        if (zerg == NULL) {
                if (last_count != count) {
                        close(zerg_fd);
                        zerg_fd = uwsgi_connect(value, 30, 0);
                        if (zerg_fd < 0) {
                                uwsgi_log("--- unable to connect to zerg server ---\n");
                                exit(1);
                        }
                        zerg = uwsgi_attach_fd(zerg_fd, &count, "uwsgi-zerg", 10);
                }
                else {
                        uwsgi_log("--- invalid data received from zerg-server ---\n");
                        exit(1);
                }
        }

        if (zerg == NULL) {
                uwsgi_log("--- invalid data received from zerg-server ---\n");
                exit(1);
        }


        close(zerg_fd);

        for(j=0;j<count;j++) {
                if (zerg[j] == -1) break;
                ugs = uwsgi_new_gateway_socket_from_fd(zerg[j], ucr->name);
                ugs->zerg = optarg;
        }
        free(zerg);
}
Esempio n. 3
0
int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {

	struct uwsgi_header *uh = (struct uwsgi_header *) ur->data;
	char *addr = ur->data + sizeof(struct uwsgi_header);
	
	// mark a route request
        wsgi_req->status = -17;

	// append appid
	if (ur->data2_len > 0) {
		uwsgi_req_append(wsgi_req, "UWSGI_APPID", 11, ur->data2, ur->data2_len);
	}

	// ok now if have offload threads, directly use them
        if (wsgi_req->socket->can_offload) {
		struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh.pktsize);
		if (ub) {
			uh->pktsize = wsgi_req->uh.pktsize;
			if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto bad;
			if (uwsgi_buffer_append(ub, wsgi_req->buffer, uh->pktsize)) goto bad;
                	if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) {
                        	wsgi_req->status = -30;
                        	return UWSGI_ROUTE_BREAK;
                	}
bad:
			uwsgi_buffer_destroy(ub);
		}
        }


	int uwsgi_fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
	if (uwsgi_fd < 0) {
		uwsgi_log("unable to connect to host %s\n", addr);
		return UWSGI_ROUTE_NEXT;
	}

	int post_fd = wsgi_req->poll.fd;
	if (wsgi_req->async_post) {
		post_fd = fileno((FILE*)wsgi_req->async_post);
	}

	if (uwsgi_send_message(uwsgi_fd, uh->modifier1, uh->modifier2, wsgi_req->buffer, wsgi_req->uh.pktsize, post_fd, wsgi_req->post_cl, 0) < 0) {
		uwsgi_log("unable to send uwsgi request to host %s", addr);
		return UWSGI_ROUTE_NEXT;
	}

	ssize_t ret = uwsgi_pipe(uwsgi_fd, wsgi_req->poll.fd, 0);
	if (ret > 0) {
		wsgi_req->response_size += ret;
	}
	else {
		uwsgi_log("unable to manage uwsgi route response for %s\n", addr);
	}

	close(uwsgi_fd);
	return UWSGI_ROUTE_BREAK;

}
Esempio n. 4
0
int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, size_t remains, int timeout) {

        int fd = uwsgi_connect(addr, 0, 1);
        if (fd < 0) {
		return -1;
        }

        int ret = uwsgi.wait_write_hook(fd, timeout);
        if (ret <= 0) {
		goto end;
        }

        // send the request (+ remaining data)
	if (ub) {
        	if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) {
			goto end;
        	}
	}

        // send the body
        while(remains > 0) {
                ssize_t rlen = 0;
                char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
                if (!buf) {
			goto end;
                }
                if (buf == uwsgi.empty) break;
                // write data to the node
                if (uwsgi_write_true_nb(fd, buf, rlen, timeout)) {
			goto end;
                }
                remains -= rlen;
        }

        // read the response
        for(;;) {
                char buf[8192];
                ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout);
                if (rlen > 0) {
                        if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
                                break;
                        }
                        continue;
                }
                break;
        }

	close(fd);
	return 0;
end:
	close(fd);
	return -1;
}
Esempio n. 5
0
static int u_offload_transfer_prepare(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor) {

	if (!uor->name) {
		return -1;
	}

	uor->fd = uwsgi_connect(uor->name, 0, 1);
	if (uor->fd < 0) {
		uwsgi_error("u_offload_transfer_prepare()/connect()");
		return -1;
	}

	return 0;
}
Esempio n. 6
0
int uwsgi_wstcp(struct wsgi_request *wsgi_req) {
    if (uwsgi_parse_vars(wsgi_req)) return -1;

    // handshake the websocket connection
    if (uwsgi_websocket_handshake(wsgi_req, NULL, 0, NULL, 0, NULL, 0)) return -1;

    // async connect to the tcp server
    int fd = uwsgi_connect("127.0.0.1:9090", 0, 1);
    if (fd < 0) return -1;

    // wait for connection
    int ret = uwsgi.wait_write_hook(fd, 30);
    if (ret <= 0) {
        close(fd);
        return -1;
    }

    // ok we are connected, enter the main loop
    for(;;) {
        int ready_fd = -1;
        // wait for both websockets and tcp
        int ret = uwsgi.wait_read2_hook(wsgi_req->fd, fd, 30, &ready_fd);
        if (ret <= 0) break;
        // websocket message
        if (ready_fd == wsgi_req->fd) {
            // read websocket message
            struct uwsgi_buffer *ub = uwsgi_websocket_recv_nb(wsgi_req);
            if (!ub) break;
            // send to tcp
            if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, 30)) break;
        }
        // packet from tcp
        else if (ready_fd == fd) {
            char buf[8192];
            // read from the tcp socket
            ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, 30);
            if (rlen <= 0) break;
            // send to the websocket
            if (uwsgi_websocket_send_binary(wsgi_req, buf, rlen)) break;
        }
    }

    // end of the session
    close(fd);
    return UWSGI_OK;
}
Esempio n. 7
0
static int fcgi_send(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, int timeout) {
	int fd = uwsgi_connect(addr, 0, 1);
	if (fd < 0)
		return -1;

	int ret = uwsgi.wait_write_hook(fd, timeout);
	if (ret <= 0)
		goto error;

	if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout))
		goto error;

	return fd;

error:
	close(fd);
	return -1;
}
Esempio n. 8
0
static void ping() {

	struct uwsgi_header uh;
	char *buf = NULL;

	// use a 3 secs timeout by default
	if (!uping.ping_timeout) uping.ping_timeout = 3;

	uwsgi_log("PING uwsgi host %s (timeout: %d)\n", uping.ping, uping.ping_timeout);

	int fd = uwsgi_connect(uping.ping, uping.ping_timeout, 0);
	if (fd < 0) {
		exit(1);
	}

	uh.modifier1 = UWSGI_MODIFIER_PING;
	uh.pktsize = 0;
	uh.modifier2 = 0;

	if (write(fd, &uh, 4) != 4) {
		uwsgi_error("write()");
		exit(2);
	}

	int ret = uwsgi_read_response(fd, &uh, uping.ping_timeout, &buf);
	if (ret < 0) {
		exit(1);
	}
	else {
		if (uh.pktsize > 0) {
			uwsgi_log("[WARNING] node %s message: %.*s\n", uping.ping, uh.pktsize, buf);
			exit(2);
		}
		else {
			exit(0);
		}
	}

}
Esempio n. 9
0
void uwsgi_imperial_monitor_amqp_init(struct uwsgi_emperor_scanner *ues) {

	char *vhost = "/";
	char *username = "******";
	char *password = "******";

        ues->fd = uwsgi_connect(ues->arg+7, -1, 0);
        if (ues->fd < 0) {
                uwsgi_log("unable to connect to AMQP server\n");
                return;
        }

        if (uwsgi_amqp_consume_queue(ues->fd, vhost, username, password, "", "uwsgi.emperor", "fanout") < 0) {
                close(ues->fd);
                ues->fd = -1;
                uwsgi_log("unable to subscribe to AMQP queue\n");
                return;
        }

	ues->event_func = uwsgi_imperial_monitor_amqp_event;

        event_queue_add_fd_read(uwsgi.emperor_queue, ues->fd);
}
Esempio n. 10
0
File: signal.c Progetto: rebx/uwsgi
int uwsgi_remote_signal_send(char *addr, uint8_t sig) {

	struct uwsgi_header uh;

	uh.modifier1 = 110;
	uh.pktsize = 0;
	uh.modifier2 = sig;
	
	int fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
        if (fd < 0) return -1;

	if (write(fd, (char *) &uh, 4) != 4) {
		uwsgi_error("uwsgi_remote_signal_send()");
		close(fd);
		return -1;
	}

	int ret = uwsgi_read_response(fd, &uh, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL);

	close(fd);
	return ret;

}
Esempio n. 11
0
void uwsgi_python_harakiri(int wid) {

	if (up.tracebacker) {

        	char buf[8192];
		char *address = uwsgi_concat2(up.tracebacker, uwsgi_num2str(wid));

        	int fd = uwsgi_connect(address, -1, 0);
        	for (;;) {
                	int ret = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
                	if (ret <= 0) {
				break;
                	}
                	ssize_t len = read(fd, buf, 8192);
                	if (len <= 0) {
				break;
                	}
                	uwsgi_log("%.*s", (int) len, buf);
        	}

		free(address);
	}

}
Esempio n. 12
0
static int uwsgi_routing_func_memcached(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
	// this is the buffer for the memcached response
	char buf[MEMCACHED_BUFSIZE];
	size_t i;
	char last_char = 0;

	struct uwsgi_router_memcached_conf *urmc = (struct uwsgi_router_memcached_conf *) ur->data2;

	char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
        uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);

	struct uwsgi_buffer *ub_key = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->key, urmc->key_len);
        if (!ub_key) return UWSGI_ROUTE_BREAK;

	int fd = uwsgi_connect(urmc->addr, 0, 1);
	if (fd < 0) { uwsgi_buffer_destroy(ub_key) ; goto end; }

        // wait for connection;
        int ret = uwsgi.wait_write_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
        if (ret <= 0) {
		uwsgi_buffer_destroy(ub_key) ;
		close(fd);
		goto end;
        }

	// build the request and send it
	char *cmd = uwsgi_concat3n("get ", 4, ub_key->buf, ub_key->pos, "\r\n", 2);
	if (uwsgi_write_true_nb(fd, cmd, 6+ub_key->pos, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
		uwsgi_buffer_destroy(ub_key);
		free(cmd);
		close(fd);
		goto end;
	}
	uwsgi_buffer_destroy(ub_key);
	free(cmd);

	// ok, start reading the response...
	// first we need to get a full line;
	size_t found = 0;
	size_t pos = 0;
	for(;;) {
		ssize_t len = read(fd, buf + pos, MEMCACHED_BUFSIZE - pos);
		if (len > 0) {
			pos += len;
			goto read;
		}
		if (len < 0) {
			if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait;
		}
		close(fd);
		goto end;
wait:
		ret = uwsgi.wait_read_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
		// when we have a chunk try to read the first line
		if (ret > 0) {
			len = read(fd, buf + pos, MEMCACHED_BUFSIZE - pos);
			if (len > 0) {
				pos += len;
				goto read;
			}
		}
		close(fd);
		goto end;
read:
		for(i=0;i<pos;i++) {
			if (last_char == '\r' && buf[i] == '\n') {
				found = i-1;
				break;
			}
			last_char = buf[i];
		}
		if (found) break;
	}

	// ok parse the first line
	size_t response_size = memcached_firstline_parse(buf, found);

	if (response_size == 0) {
		close(fd);
		goto end;
	}

	if (urmc->type_num == 1) {
		if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) { close(fd); goto end; }
		if (uwsgi_response_add_content_type(wsgi_req, urmc->content_type, urmc->content_type_len)) { close(fd); goto end; }
		if (uwsgi_response_add_content_length(wsgi_req, response_size)) { close(fd); goto end; }
	}
	size_t remains = pos-(found+2);
	if (remains >= response_size) {
		uwsgi_response_write_body_do(wsgi_req, buf+found+2, response_size);
		close(fd);
		goto end;
	}

	// send what we have
	if (uwsgi_response_write_body_do(wsgi_req, buf+found+2, remains)) {
		close(fd);
		goto end;
	}

	// and now start reading til the output is consumed
	response_size -= remains;
	while(response_size > 0) {
		ssize_t len = read(fd, buf, UMIN(MEMCACHED_BUFSIZE, response_size));
		if (len > 0) goto write;
		if (len < 0) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait2;
                }
		goto error;
wait2:
		ret = uwsgi.wait_read_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
		if (ret > 0) {
                        len = read(fd, buf, UMIN(MEMCACHED_BUFSIZE, response_size));
			if (len > 0) goto write;
		}
		goto error;
write:
		if (uwsgi_response_write_body_do(wsgi_req, buf, len)) {
			goto error;
        	}
		response_size -= len;
	}

	close(fd);
	return UWSGI_ROUTE_BREAK;

error:
	close(fd);
	
end:
	if (ur->custom)
        	return UWSGI_ROUTE_NEXT;

	return UWSGI_ROUTE_BREAK;
}
Esempio n. 13
0
static int uwsgi_init_ssh_session(
	struct uwsgi_ssh_mountpoint *usm,
	int* socket_fd,
	LIBSSH2_SESSION **session) {

	int sock = uwsgi_connect(usm->remote, ulibssh2.ssh_timeout, 1);
	if (sock < 0) {
		uwsgi_error("uwsgi_init_ssh_session()/uwsgi_connect()");
		return 1;
	}

	int rc = libssh2_init(0);
	if (rc) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_init()");
		goto shutdown;
	}

	*session = libssh2_session_init();
	if (!session) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_init()");
		goto shutdown;
	}

	libssh2_session_set_blocking(*session, 0);

	while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN) {
		uwsgi_ssh_waitsocket(sock, *session);
	}
	if (rc) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_handshake()");
		goto shutdown;
	}

	if (!ulibssh2.disable_remote_fingerprint_check) {
		LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(*session);
		if (!nh) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_init()");
			goto shutdown;
		}

		if (libssh2_knownhost_readfile(nh, ulibssh2.known_hosts_path, LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_readfile()");
		}

		size_t len;
		int type;
		const char *fingerprint = libssh2_session_hostkey(*session, &len, &type);
		if (!fingerprint) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_hostkey()");
			libssh2_knownhost_free(nh);
			goto shutdown;
		}

		char *remoteaddr_str = uwsgi_str(usm->remote);
		char *port_str = strchr(remoteaddr_str, ':');
		int port = SSH_DEFAULT_PORT;

		if (port_str) {
			port_str[0] = 0;
			port_str++;
			port = atoi(port_str);
		}

		struct libssh2_knownhost *host;
		int check = libssh2_knownhost_checkp(
			nh,
			remoteaddr_str,
			port,
			fingerprint,
			len,
			LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,
			&host
		);

		free(remoteaddr_str);

		if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
			uwsgi_log("[SSH] Remote fingerprint check failed!\n");
			libssh2_knownhost_free(nh);
			goto shutdown;
		}

		libssh2_knownhost_free(nh);
	}

	// If specified, username and password are honored
	if (usm->username && usm->password) {
		while ((rc = libssh2_userauth_password(
					*session,
					usm->username,
					usm->password)
			) == LIBSSH2_ERROR_EAGAIN) {
			uwsgi_ssh_waitsocket(sock, *session);
		}

		if (rc) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()");
			goto shutdown;
		} else {
			goto end;
		}

	// Else, let's try the fallback authentication methods:
	} else if (usm->username || ulibssh2.username) {

		// Let's choose which username to use
		char* auth_user = ulibssh2.username;
		if (usm->username) {
			auth_user = usm->username;
		}

		// Password authentication
		if (ulibssh2.auth_pw && ulibssh2.password) {
			while ((rc = libssh2_userauth_password(
						*session,
						auth_user,
						ulibssh2.password)
				) == LIBSSH2_ERROR_EAGAIN) {
				uwsgi_ssh_waitsocket(sock, *session);
			}
			if (rc) {
				uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()");
				// goto shutdown;
			} else {
				goto end;
			}
		}

		// SSH agent authentication
		if (usm->ssh_agent || ulibssh2.auth_ssh_agent) {
			if (uwsgi_ssh_agent_auth(*session, sock, auth_user)) {
				uwsgi_error("uwsgi_init_ssh_session()/uwsgi_ssh_agent_auth()");
				// goto shutdown;
			} else {
				goto end;
			}
		}

		// Public key authentication
		if ((ulibssh2.private_key_path && ulibssh2.private_key_passphrase) ||
			(usm->priv_key_path && usm->priv_key_passphrase)) {

			char *actual_pubk_path = ulibssh2.public_key_path;
			if (usm->pub_key_path) {
				actual_pubk_path = usm->pub_key_path;
			}

			char *actual_privk_path = ulibssh2.private_key_path;
			if (usm->priv_key_path) {
				actual_privk_path = usm->priv_key_path;
			}

			char *actual_passphrase = ulibssh2.private_key_passphrase;
			if (usm->priv_key_passphrase) {
				actual_passphrase = usm->priv_key_passphrase;
			}

			while ((rc = libssh2_userauth_publickey_fromfile(
						*session,
						auth_user,
						actual_pubk_path,
						actual_privk_path,
						actual_passphrase)
			) == LIBSSH2_ERROR_EAGAIN) {
				uwsgi_ssh_waitsocket(sock, *session);
			}

			if (rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
				uwsgi_log("[SSH] ssh authentication failed (bad passphrase)\n");
				// goto shutdown;
			} else if (rc) {
				uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_publickey_fromfile()");
				// goto shutdown;
			} else {
				goto end;
			}
		}
	}


	// If we arrive here, something went wrong.
	uwsgi_log("[SSH] session initialization failed (no authentication method worked)\n");
shutdown:
		close(sock);
		return 1;

end:
	// Otherwise, we're fine!
	*socket_fd = sock;
	return 0;

}
Esempio n. 14
0
void carbon_push_stats(int retry_cycle) {
	struct carbon_server_list *usl = u_carbon.servers_data;
	int i;
	int fd;
	int wok;

	for (i = 0; i < uwsgi.numproc; i++) {
		u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i];
		u_carbon.last_busyness_values[i] = uwsgi.workers[i+1].running_time;
	}

	u_carbon.need_retry = 0;
	while(usl) {
		if (retry_cycle && usl->healthy)
			// skip healthy servers during retry cycle
			goto nxt;
	  
		if (retry_cycle && usl->healthy == 0)
			uwsgi_log("[carbon] Retrying failed server at %s (%d)\n", usl->value, usl->errors);

		if (!retry_cycle) {
			usl->healthy = 1;
			usl->errors = 0;
		}
		
		fd = uwsgi_connect(usl->value, u_carbon.timeout, 0);
		if (fd < 0) {
			uwsgi_log("[carbon] Could not connect to carbon server at %s\n", usl->value);
			if (usl->errors < u_carbon.max_retries) {
				u_carbon.need_retry = 1;
				u_carbon.next_retry = uwsgi_now() + u_carbon.retry_delay;
			} else {
				uwsgi_log("[carbon] Maximum number of retries for %s (%d)\n",
					usl->value, u_carbon.max_retries);
				usl->healthy = 0;
				usl->errors = 0;
			}
			usl->healthy = 0;
			usl->errors++;
			goto nxt;
		}
		// put the socket in non-blocking mode
		uwsgi_socket_nb(fd);

		unsigned long long total_rss = 0;
		unsigned long long total_vsz = 0;
		unsigned long long total_tx = 0;
		unsigned long long total_avg_rt = 0; // total avg_rt
		unsigned long long avg_rt = 0; // per worker avg_rt reported to carbon
		unsigned long long active_workers = 0; // number of workers used to calculate total avg_rt
		unsigned long long total_busyness = 0;
		unsigned long long total_avg_busyness = 0;
		unsigned long long worker_busyness = 0;
		unsigned long long total_harakiri = 0;

		wok = carbon_write(&fd, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.workers[0].requests, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		for(i=1;i<=uwsgi.numproc;i++) {
			total_tx += uwsgi.workers[i].tx;
			if (uwsgi.workers[i].cheaped) {
				// also if worker is cheaped than we report its average response time as zero, sending last value might be confusing
				avg_rt = 0;
				worker_busyness = 0;
			}
			else {
				// global average response time is calculated from active/idle workers, cheaped workers are excluded, otherwise it is not accurate
				avg_rt = uwsgi.workers[i].avg_response_time;
				active_workers++;
				total_avg_rt += uwsgi.workers[i].avg_response_time;

				// calculate worker busyness
				worker_busyness = ((u_carbon.current_busyness_values[i-1]*100) / (u_carbon.freq*1000000));
				if (worker_busyness > 100) worker_busyness = 100;
				total_busyness += worker_busyness;

				// only running workers are counted in total memory stats
				total_rss += uwsgi.workers[i].rss_size;
				total_vsz += uwsgi.workers[i].vsz_size;

				total_harakiri += uwsgi.workers[i].harakiri_count;
			}

			//skip per worker metrics when disabled
			if (u_carbon.no_workers) continue;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].requests, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].rss_size, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].vsz_size, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) avg_rt, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].tx, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) worker_busyness, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

			wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].harakiri_count, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;

		}

		wok = carbon_write(&fd, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_rss, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		wok = carbon_write(&fd, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_vsz, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		wok = carbon_write(&fd, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) (active_workers ? total_avg_rt / active_workers : 0), (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		wok = carbon_write(&fd, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_tx, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		if (active_workers > 0) {
			total_avg_busyness = total_busyness / active_workers;
			if (total_avg_busyness > 100) total_avg_busyness = 100;
		} else {
			total_avg_busyness = 0;
		}
		wok = carbon_write(&fd, "uwsgi.%s.%s.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_avg_busyness, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		wok = carbon_write(&fd, "uwsgi.%s.%s.active_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) active_workers, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		if (uwsgi.cheaper) {
			wok = carbon_write(&fd, "uwsgi.%s.%s.cheaped_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.numproc - active_workers, (unsigned long long) uwsgi.current_time);
			if (!wok) goto clear;
		}

		wok = carbon_write(&fd, "uwsgi.%s.%s.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) uwsgi.current_time);
		if (!wok) goto clear;

		usl->healthy = 1;
		usl->errors = 0;

clear:
		close(fd);
nxt:
		usl = usl->next;
	}
	if (!retry_cycle) u_carbon.last_update = uwsgi_now();
	if (u_carbon.need_retry)
		// timeouts and retries might cause additional lags in carbon cycles, we will adjust timer to fix that
		u_carbon.last_update -= u_carbon.timeout;
}
Esempio n. 15
0
ssize_t uwsgi_redis_logger(struct uwsgi_logger *ul, char *message, size_t len) {

	ssize_t ret,ret2;
	struct uwsgi_redislog_state *uredislog = NULL;

	if (!ul->configured) {

		if (!ul->data) {
			ul->data = uwsgi_calloc(sizeof(struct uwsgi_redislog_state));
			uredislog = (struct uwsgi_redislog_state *) ul->data;
		}

		if (ul->arg != NULL) {
			char *logarg = uwsgi_str(ul->arg);
			char *comma1 = strchr(logarg, ',');
			if (!comma1) {
				uredislog->address = logarg;
				goto done;
			}
			*comma1 = 0;
			uredislog->address = logarg;
			comma1++;
			if (*comma1 == 0) goto done;

			char *comma2 = strchr(comma1,',');
			if (!comma2) {
				uredislog->command = uwsgi_redis_logger_build_command(comma1);
				goto done;
			}

			*comma2 = 0;
			uredislog->command = uwsgi_redis_logger_build_command(comma1);
			comma2++;
			if (*comma2 == 0) goto done;

			uredislog->prefix = comma2;
		}

done:

		if (!uredislog->address) uredislog->address = uwsgi_str("127.0.0.1:6379");
		if (!uredislog->command) uredislog->command = "*3\r\n$7\r\npublish\r\n$5\r\nuwsgi\r\n";
		if (!uredislog->prefix) uredislog->prefix = "";

		uredislog->fd = -1;

		uredislog->iovec[0].iov_base = uredislog->command;
		uredislog->iovec[0].iov_len = strlen(uredislog->command);
		uredislog->iovec[1].iov_base = "$";
		uredislog->iovec[1].iov_len = 1;

		uredislog->iovec[2].iov_base = uredislog->msgsize;

		uredislog->iovec[3].iov_base = "\r\n";
		uredislog->iovec[3].iov_len = 2;

		uredislog->iovec[4].iov_base = uredislog->prefix;
		uredislog->iovec[4].iov_len = strlen(uredislog->prefix);

		uredislog->iovec[6].iov_base = "\r\n";
		uredislog->iovec[6].iov_len = 2;

		ul->configured = 1;
	}

	uredislog = (struct uwsgi_redislog_state *) ul->data;
	if (uredislog->fd == -1) {
		uredislog->fd = uwsgi_connect(uredislog->address, uwsgi.socket_timeout, 0);
	}

	if (uredislog->fd == -1) return -1;

	// drop newline
        if (message[len-1] == '\n') len--;

	uwsgi_num2str2(len + uredislog->iovec[4].iov_len, uredislog->msgsize);
	uredislog->iovec[2].iov_len = strlen(uredislog->msgsize);

	uredislog->iovec[5].iov_base = message;
	uredislog->iovec[5].iov_len = len;
	
	ret = writev(uredislog->fd, uredislog->iovec, 7);
	if (ret <= 0) {
		close(uredislog->fd);
		uredislog->fd = -1;
		return -1;
	}

again:
	// read til a \n is found (ugly but fast)
	ret2 = read(uredislog->fd, uredislog->response, 8);
	if (ret2 <= 0) {
		close(uredislog->fd);
		uredislog->fd = -1;
		return -1;
	}

	if (!memchr(uredislog->response, '\n', ret2)) {
		goto again;
	}

	return ret;

}
Esempio n. 16
0
/*
	extremely complex function for reading resources (files, url...)
	need a lot of refactoring...
*/
char *uwsgi_open_and_read(char *url, size_t *size, int add_zero, char *magic_table[]) {

	int fd;
	struct stat sb;
	char *buffer = NULL;
	char byte;
	ssize_t len;
	char *uri, *colon;
	char *domain;
	char *ip;
	int body = 0;
	char *magic_buf;

	// stdin ?
	if (!strcmp(url, "-")) {
		buffer = uwsgi_read_fd(0, size, add_zero);
	}
	// fd ?
	else if (!strncmp("fd://", url, 5)) {
		fd = atoi(url + 5);
		buffer = uwsgi_read_fd(fd, size, add_zero);
	}
	// exec ?
	else if (!strncmp("exec://", url, 5)) {
		int cpipe[2];
		if (pipe(cpipe)) {
			uwsgi_error("pipe()");
			exit(1);
		}
		uwsgi_run_command(url + 7, NULL, cpipe[1]);
		buffer = uwsgi_read_fd(cpipe[0], size, add_zero);
		close(cpipe[0]);
		close(cpipe[1]);
	}
	// http url ?
	else if (!strncmp("http://", url, 7)) {
		domain = url + 7;
		uri = strchr(domain, '/');
		if (!uri) {
			uwsgi_log("invalid http url\n");
			exit(1);
		}
		uri[0] = 0;
		uwsgi_log("domain: %s\n", domain);

		colon = uwsgi_get_last_char(domain, ':');

		if (colon) {
			colon[0] = 0;
		}


		ip = uwsgi_resolve_ip(domain);
		if (!ip) {
			uwsgi_log("unable to resolve address %s\n", domain);
			exit(1);
		}

		if (colon) {
			colon[0] = ':';
			ip = uwsgi_concat2(ip, colon);
		}
		else {
			ip = uwsgi_concat2(ip, ":80");
		}

		fd = uwsgi_connect(ip, 0, 0);

		if (fd < 0) {
			exit(1);
		}

		free(ip);

		uri[0] = '/';

		len = write(fd, "GET ", 4);
		len = write(fd, uri, strlen(uri));
		len = write(fd, " HTTP/1.0\r\n", 11);
		len = write(fd, "Host: ", 6);

		uri[0] = 0;
		len = write(fd, domain, strlen(domain));
		uri[0] = '/';

		len = write(fd, "\r\nUser-Agent: uWSGI on ", 23);
		len = write(fd, uwsgi.hostname, uwsgi.hostname_len);
		len = write(fd, "\r\n\r\n", 4);

		int http_status_code_ptr = 0;

		while (read(fd, &byte, 1) == 1) {
			if (byte == '\r' && body == 0) {
				body = 1;
			}
			else if (byte == '\n' && body == 1) {
				body = 2;
			}
			else if (byte == '\r' && body == 2) {
				body = 3;
			}
			else if (byte == '\n' && body == 3) {
				body = 4;
			}
			else if (body == 4) {
				*size = *size + 1;
				char *tmp = realloc(buffer, *size);
				if (!tmp) {
					uwsgi_error("uwsgi_open_and_read()/realloc()");
					exit(1);
				}
				buffer = tmp;
				buffer[*size - 1] = byte;
			}
			else {
				body = 0;
				http_status_code_ptr++;
				if (http_status_code_ptr == 10) {
					if (byte != '2') {
						uwsgi_log("Not usable HTTP response: %cxx\n", byte);
						if (uwsgi.has_emperor) {
							exit(UWSGI_EXILE_CODE);
						}
						else {
							exit(1);
						}
					}
				}
			}
		}

		close(fd);

		if (add_zero) {
			*size = *size + 1;
			char *tmp = realloc(buffer, *size);
			if (!tmp) {
				uwsgi_error("uwsgi_open_and_read()/realloc()");
				exit(1);
			}
			buffer = tmp;
			buffer[*size - 1] = 0;
		}

	}
	else if (!strncmp("emperor://", url, 10)) {
		if (uwsgi.emperor_fd_config < 0) {
			uwsgi_log("this is not a vassal instance\n");
			exit(1);
		}
		ssize_t rlen;
		*size = 0;
		struct uwsgi_header uh;
		size_t remains = 4;
		char *ptr = (char *) &uh;
		while(remains) {
			int ret = uwsgi_waitfd(uwsgi.emperor_fd_config, 5);
			if (ret <= 0) {
				uwsgi_log("[uwsgi-vassal] error waiting for config header %s !!!\n", url);
				exit(1);
			}
			rlen = read(uwsgi.emperor_fd_config, ptr, remains);
			if (rlen <= 0) {
				uwsgi_log("[uwsgi-vassal] error reading config header from !!!\n", url);
				exit(1);
			}
			ptr+=rlen;
			remains-=rlen;
		}

		remains = uh.pktsize;
		if (!remains) {
			uwsgi_log("[uwsgi-vassal] invalid config from %s\n", url);
			exit(1);
		}

		buffer = uwsgi_calloc(remains + add_zero);
		ptr = buffer;
		while (remains) {
			int ret = uwsgi_waitfd(uwsgi.emperor_fd_config, 5);
                        if (ret <= 0) {
                                uwsgi_log("[uwsgi-vassal] error waiting for config %s !!!\n", url);
                                exit(1);
                        }
			rlen = read(uwsgi.emperor_fd_config, ptr, remains);
			if (rlen <= 0) {
                                uwsgi_log("[uwsgi-vassal] error reading config from !!!\n", url);
                                exit(1);
                        }
                        ptr+=rlen;
                        remains-=rlen;
		}

		*size = uh.pktsize + add_zero;
	}
#ifdef UWSGI_EMBED_CONFIG
	else if (url[0] == 0) {
		*size = &UWSGI_EMBED_CONFIG_END - &UWSGI_EMBED_CONFIG;
		if (add_zero) {
			*size += 1;
		}
		buffer = uwsgi_malloc(*size);
		memset(buffer, 0, *size);
		memcpy(buffer, &UWSGI_EMBED_CONFIG, &UWSGI_EMBED_CONFIG_END - &UWSGI_EMBED_CONFIG);
	}
#endif
	else if (!strncmp("data://", url, 7)) {
		fd = open(uwsgi.binary_path, O_RDONLY);
		if (fd < 0) {
			uwsgi_error_open(uwsgi.binary_path);
			exit(1);
		}
		int slot = atoi(url + 7);
		if (slot < 0) {
			uwsgi_log("invalid binary data slot requested\n");
			exit(1);
		}
		uwsgi_log("requesting binary data slot %d\n", slot);
		off_t fo = lseek(fd, 0, SEEK_END);
		if (fo < 0) {
			uwsgi_error("lseek()");
			uwsgi_log("invalid binary data slot requested\n");
			exit(1);
		}
		int i = 0;
		uint64_t datasize = 0;
		for (i = 0; i <= slot; i++) {
			fo = lseek(fd, -9, SEEK_CUR);
			if (fo < 0) {
				uwsgi_error("lseek()");
				uwsgi_log("invalid binary data slot requested\n");
				exit(1);
			}
			ssize_t len = read(fd, &datasize, 8);
			if (len != 8) {
				uwsgi_error("read()");
				uwsgi_log("invalid binary data slot requested\n");
				exit(1);
			}
			if (datasize == 0) {
				uwsgi_log("0 size binary data !!!\n");
				exit(1);
			}
			fo = lseek(fd, -(datasize + 9), SEEK_CUR);
			if (fo < 0) {
				uwsgi_error("lseek()");
				uwsgi_log("invalid binary data slot requested\n");
				exit(1);
			}

			if (i == slot) {
				*size = datasize;
				if (add_zero) {
					*size += 1;
				}
				buffer = uwsgi_malloc(*size);
				memset(buffer, 0, *size);
				len = read(fd, buffer, datasize);
				if (len != (ssize_t) datasize) {
					uwsgi_error("read()");
					uwsgi_log("invalid binary data slot requested\n");
					exit(1);
				}
			}
		}
	}
	else if (!strncmp("sym://", url, 6)) {
		char *symbol = uwsgi_concat3("_binary_", url + 6, "_start");
		void *sym_start_ptr = dlsym(RTLD_DEFAULT, symbol);
		if (!sym_start_ptr) {
			uwsgi_log("unable to find symbol %s\n", symbol);
			exit(1);
		}
		free(symbol);
		symbol = uwsgi_concat3("_binary_", url + 6, "_end");
		void *sym_end_ptr = dlsym(RTLD_DEFAULT, symbol);
		if (!sym_end_ptr) {
			uwsgi_log("unable to find symbol %s\n", symbol);
			exit(1);
		}
		free(symbol);

		*size = sym_end_ptr - sym_start_ptr;
		if (add_zero) {
			*size += 1;
		}
		buffer = uwsgi_malloc(*size);
		memset(buffer, 0, *size);
		memcpy(buffer, sym_start_ptr, sym_end_ptr - sym_start_ptr);

	}
#ifdef UWSGI_ELF
	else if (!strncmp("section://", url, 10)) {
		size_t s_len = 0;
		buffer = uwsgi_elf_section(uwsgi.binary_path, url + 10, &s_len);
		if (!buffer) {
			uwsgi_log("unable to find section %s in %s\n", url + 10, uwsgi.binary_path);
			exit(1);
		}
		*size = s_len;
		if (add_zero)
			*size += 1;
	}
#endif
	// fallback to file
	else {
		fd = open(url, O_RDONLY);
		if (fd < 0) {
			uwsgi_error_open(url);
			exit(1);
		}

		if (fstat(fd, &sb)) {
			uwsgi_error("fstat()");
			exit(1);
		}

		if (S_ISFIFO(sb.st_mode)) {
			buffer = uwsgi_read_fd(fd, size, add_zero);
			close(fd);
			goto end;
		}

		buffer = uwsgi_malloc(sb.st_size + add_zero);

		len = read(fd, buffer, sb.st_size);
		if (len != sb.st_size) {
			uwsgi_error("read()");
			exit(1);
		}

		close(fd);

		*size = sb.st_size + add_zero;

		if (add_zero)
			buffer[sb.st_size] = 0;
	}

end:

	if (magic_table) {

		magic_buf = magic_sub(buffer, *size, size, magic_table);
		free(buffer);
		return magic_buf;
	}

	return buffer;
}
Esempio n. 17
0
int bind_to_unix_dgram(char *socket_name) {

	int serverfd;
	struct sockaddr_un *uws_addr;
	socklen_t len;

	serverfd = socket(AF_UNIX, SOCK_DGRAM, 0);
	if (serverfd < 0) {
		uwsgi_error("socket()");
		uwsgi_nuclear_blast();
	}

	if (unlink(socket_name) != 0 && errno != ENOENT) {
		uwsgi_error("unlink()");
	}

	uws_addr = uwsgi_calloc(sizeof(struct sockaddr_un));
	uws_addr->sun_family = AF_UNIX;

	memcpy(uws_addr->sun_path, socket_name, UMIN(strlen(socket_name), 102));
	len = strlen(socket_name);

#ifdef __HAIKU__
	if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) {
#else
	if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
#endif
		uwsgi_error("bind()");
		uwsgi_nuclear_blast();
	}

	return serverfd;
}

int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abstract_socket) {

	int serverfd;
	struct sockaddr_un *uws_addr;
	socklen_t len;

	// leave 1 byte for abstract namespace (108 linux -> 104 bsd/mac)
	if (strlen(socket_name) > 102) {
		uwsgi_log("invalid socket name\n");
		uwsgi_nuclear_blast();
	}

	if (socket_name[0] == '@') {
		abstract_socket = 1;
	}
	else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
		abstract_socket = 1;
	}

	uws_addr = malloc(sizeof(struct sockaddr_un));
	if (uws_addr == NULL) {
		uwsgi_error("malloc()");
		uwsgi_nuclear_blast();
	}

	memset(uws_addr, 0, sizeof(struct sockaddr_un));
	serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (serverfd < 0) {
		uwsgi_error("socket()");
		uwsgi_nuclear_blast();
	}
	if (abstract_socket == 0) {
		if (unlink(socket_name) != 0 && errno != ENOENT) {
			uwsgi_error("unlink()");
		}
	}

	if (abstract_socket == 1) {
		uwsgi_log("setting abstract socket mode (warning: only Linux supports this)\n");
	}

	uws_addr->sun_family = AF_UNIX;
	if (socket_name[0] == '@') {
		memcpy(uws_addr->sun_path + abstract_socket, socket_name + 1, UMIN(strlen(socket_name + 1), 101));
		len = strlen(socket_name) + 1;
	}
	else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
		memcpy(uws_addr->sun_path + abstract_socket, socket_name + 2, UMIN(strlen(socket_name + 2), 101));
		len = strlen(socket_name + 1) + 1;

	}
	else if (abstract_socket) {
		memcpy(uws_addr->sun_path + 1, socket_name, UMIN(strlen(socket_name), 101));
		len = strlen(socket_name) + 1;
	}
	else {
		memcpy(uws_addr->sun_path + abstract_socket, socket_name, UMIN(strlen(socket_name), 102));
		len = strlen(socket_name);
	}

#ifdef __HAIKU__
	if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) {
#else
	if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
#endif
		uwsgi_error("bind()");
		uwsgi_nuclear_blast();
	}


	if (listen(serverfd, listen_queue) != 0) {
		uwsgi_error("listen()");
		uwsgi_nuclear_blast();
	}

	// chmod unix socket for lazy users
	if (chmod_socket == 1 && abstract_socket == 0) {
		if (uwsgi.chmod_socket_value) {
			if (chmod(socket_name, uwsgi.chmod_socket_value) != 0) {
				uwsgi_error("chmod()");
			}
		}
		else {
			uwsgi_log("chmod() socket to 666 for lazy and brave users\n");
			if (chmod(socket_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) != 0) {
				uwsgi_error("chmod()");
			}
		}
	}

	free(uws_addr);

	return serverfd;
}

#ifdef UWSGI_UDP
int bind_to_udp(char *socket_name, int multicast, int broadcast) {
	int serverfd;
	struct sockaddr_in uws_addr;
	char *udp_port;
	int bcast = 1;
	int reuse = 1;

#ifdef UWSGI_MULTICAST
	struct ip_mreq mc;
	uint8_t loop = 1;
#endif

	udp_port = strchr(socket_name, ':');
	if (udp_port == NULL) {
		return -1;
	}

	udp_port[0] = 0;

	if (socket_name[0] == 0 && multicast) {
		uwsgi_log("invalid multicast address\n");
		return -1;
	}
	memset(&uws_addr, 0, sizeof(struct sockaddr_in));
	uws_addr.sin_family = AF_INET;
	uws_addr.sin_port = htons(atoi(udp_port + 1));

#ifdef UWSGI_MULTICAST
	if (!broadcast && !multicast) {
		char quad[4];
		char *first_part = strchr(socket_name, '.');
		if (first_part && first_part - socket_name < 4) {
			memset(quad, 0, 4);
			memcpy(quad, socket_name, first_part - socket_name);
			if (atoi(quad) >= 224 && atoi(quad) <= 239) {
				multicast = 1;
			}
		}
#else
	if (!broadcast) {
#endif
		if (!strcmp(socket_name, "255.255.255.255")) {
			broadcast = 1;
		}
	}

	if (broadcast) {
		uws_addr.sin_addr.s_addr = INADDR_BROADCAST;
	}
	else if (socket_name[0] != 0) {
		uws_addr.sin_addr.s_addr = inet_addr(socket_name);
	}
	else {
		uws_addr.sin_addr.s_addr = INADDR_ANY;
	}


	serverfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (serverfd < 0) {
		uwsgi_error("socket()");
		return -1;
	}

	if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
		uwsgi_error("setsockopt()");
	}

#ifdef UWSGI_MULTICAST
	if (multicast) {
		// if multicast is enabled remember to bind to INADDR_ANY
		uws_addr.sin_addr.s_addr = INADDR_ANY;
		mc.imr_multiaddr.s_addr = inet_addr(socket_name);
		mc.imr_interface.s_addr = INADDR_ANY;
	}
#endif

	if (broadcast) {
		if (setsockopt(serverfd, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast))) {
			perror("setsockopt");
			close(serverfd);
			return -1;
		}
	}

	if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr)) != 0) {
		uwsgi_error("bind()");
		close(serverfd);
		return -1;
	}

#ifdef UWSGI_MULTICAST
	if (multicast) {
		uwsgi_log("[uWSGI] joining multicast group: %s:%d\n", socket_name, ntohs(uws_addr.sin_port));
		if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))) {
			uwsgi_error("setsockopt()");
		}

		if (setsockopt(serverfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mc, sizeof(mc))) {
			uwsgi_error("setsockopt()");
		}

		if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_TTL, &uwsgi.multicast_ttl, sizeof(uwsgi.multicast_ttl))) {
			uwsgi_error("setsockopt()");
		}

	}
#endif

	udp_port[0] = ':';
	return serverfd;

}
#endif

int uwsgi_connectn(char *socket_name, uint16_t len, int timeout, int async) {

	int fd;

	char *zeroed_socket_name = uwsgi_concat2n(socket_name, len, "", 0);
	fd = uwsgi_connect(zeroed_socket_name, timeout, async);

	free(zeroed_socket_name);
	return fd;
}
Esempio n. 18
0
void carbon_master_cycle() {

	static time_t last_update = 0;
	char ptr[4096];
	int rlen, i;
	int fd;
	struct uwsgi_string_list *usl = u_carbon.servers;

	if (!u_carbon.servers) return ;

	if (last_update == 0) last_update = time(NULL);

	// update
	if (uwsgi.current_time - last_update >= u_carbon.freq) {
		while(usl) {
			fd = uwsgi_connect(usl->value, u_carbon.timeout, 0);
			if (fd < 0) goto nxt;
			// put the socket in non-blocking mode
			uwsgi_socket_nb(fd);

			unsigned long long total_rss = 0;
			unsigned long long total_vsz = 0;
			unsigned long long total_tx = 0;
			unsigned long long total_avg_rt = 0; // total avg_rt
			unsigned long long avg_rt = 0; // per worker avg_rt reported to carbon
			unsigned long long avg_rt_workers = 0; // number of workers used to calculate total avg_rt

			rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) uwsgi.workers[0].requests, (unsigned long long ) uwsgi.current_time);
			if (rlen < 1) goto clear;
			if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
		
			if (u_carbon.no_workers) goto gmetrics;

			for(i=1;i<=uwsgi.numproc;i++) {
				rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].requests, (unsigned long long ) uwsgi.current_time);
				if (rlen < 1) goto clear;
				if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

				total_rss += uwsgi.workers[i].rss_size;
				rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].rss_size, (unsigned long long ) uwsgi.current_time);
				if (rlen < 1) goto clear;
				if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

				total_vsz += uwsgi.workers[i].vsz_size;
				rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].vsz_size, (unsigned long long ) uwsgi.current_time);
				if (rlen < 1) goto clear;
				if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

				if (uwsgi.workers[i].cheaped) {
					// also if worker is cheaped than we report its average response time as zero, sending last value might be confusing
					avg_rt = 0;
				}
				else {
					// global average response time is calcucalted from active/idle workers, cheaped workers are excluded, otherwise it is not accurate
					avg_rt = uwsgi.workers[i].avg_response_time;
					avg_rt_workers++;
					total_avg_rt += uwsgi.workers[i].avg_response_time;
				}
				rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) avg_rt, (unsigned long long ) uwsgi.current_time);
				if (rlen < 1) goto clear;
				if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

				total_tx += uwsgi.workers[i].tx;
				rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].tx, (unsigned long long ) uwsgi.current_time);
				if (rlen < 1) goto clear;
				if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
			}

gmetrics:

			rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_rss, (unsigned long long ) uwsgi.current_time);
			if (rlen < 1) goto clear;
			if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

			rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_vsz, (unsigned long long ) uwsgi.current_time);
			if (rlen < 1) goto clear;
			if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

			rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) (avg_rt_workers ? total_avg_rt / avg_rt_workers : 0), (unsigned long long ) uwsgi.current_time);
			if (rlen < 1) goto clear;
			if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

			rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_tx, (unsigned long long ) uwsgi.current_time);
			if (rlen < 1) goto clear;
			if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}

clear:
			close(fd);
nxt:
			usl = usl->next;
		}
		last_update = time(NULL);
	}
}
Esempio n. 19
0
int connect_prober_callback(int interesting_fd, struct uwsgi_signal_probe *up) {

	// is this a timeout event ?
	if (interesting_fd == -1) {
		// am i wating for something ?
		if (up->fd != -1) {
			if (up->cycles > (uint64_t) up->timeout) {
				// reset the cycle
				up->cycles = 0;
				close(up->fd);
				up->fd = -1;
				// state = NOOP
				up->state = 0;
				// avoid duplicated events
				if (!up->bad) {
					up->bad = 1;
					return 1;
				}
			}
		}
		// ok register a new event
		else {
			if ((up->cycles % up->freq) == 0) {
				up->fd = uwsgi_connect(up->args, -1, 1);
				if (up->fd != -1) {
					// status = CONNECTING
					up->state = 1;
					event_queue_add_fd_write(uwsgi.master_queue, up->fd);
					return 0;
				}
				// signal the bad event (if not already bad)
				if (!up->bad) {
					up->bad = 1;
					return 1;
				}

			}
		}
	}
	else if (up->fd != -1) {
		// is this event for me ?
		if (interesting_fd == up->fd) {
			// uselsess here (we have only one state), only to show a good practice
			// check the state
			if (up->state == 1) {
				if (uwsgi_is_bad_connection(up->fd)) {
					// signal the bad connection (if needed)
					up->cycles = 0;
					close(up->fd);
					up->fd = -1;
					// state = NOOP
					up->state = 0;
					if (!up->bad) {
						up->bad = 1;
						return 1;
					}
					return 0;
				}
				// this is a good connection
				up->cycles = 0;
				close(up->fd);
				up->fd = -1;
				// state = NOOP
				up->state = 0;
				if (up->bad) {
					up->bad = 0;
					return 1;
				}
			}
		}
	}

	// default action
	return 0;
}