Example #1
0
int uwsgi_is_a_keep_mount(char *mp) {
	struct uwsgi_string_list *usl = uwsgi.ns_keep_mount;
	while(usl) {
		char *colon = strchr(usl->value, ':');
		if (colon) {
			if (!strcmp(colon+1, mp)) {
				return 1;
			}
		}
		else {
			// slip first part
			if (!uwsgi_startswith(usl->value, uwsgi.ns, strlen(uwsgi.ns))) {
				char *skipped = usl->value + strlen(uwsgi.ns);
				if (uwsgi.ns[strlen(uwsgi.ns)-1] == '/') {
					skipped--;
				}	
				if (!strcmp(skipped, mp)) {
					return 1;
				}
			}
			else {
				if (!strcmp(usl->value, mp)) {
					return 1;
				}
			}
		}
		usl = usl->next;
	}

	return 0;
	
}
Example #2
0
void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *ues) {
	if (chdir(uwsgi.cwd)) {
		uwsgi_error("chdir()");
		exit(1);
	}

	uwsgi.emperor_absolute_dir = uwsgi.cwd;

	if (!uwsgi_startswith(ues->arg, "glob://", 7)) {
		ues->arg += 7;
	}
}
Example #3
0
void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *ues) {

	if (!uwsgi_startswith(ues->arg, "dir://", 6)) {
		ues->arg += 6;
	}

	if (chdir(ues->arg)) {
		uwsgi_error("chdir()");
		exit(1);
	}

	uwsgi.emperor_absolute_dir = uwsgi_malloc(PATH_MAX + 1);
	if (realpath(".", uwsgi.emperor_absolute_dir) == NULL) {
		uwsgi_error("realpath()");
		exit(1);
	}

}
Example #4
0
void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *ucr) {

	struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
	while (ugs) {
		if (!strcmp(ucr->name, ugs->owner)) {
			if (!ugs->subscription) {
				if (ugs->name[0] == '=') {
					int shared_socket = atoi(ugs->name+1);
                        		if (shared_socket >= 0) {
                                		ugs->fd = uwsgi_get_shared_socket_fd_by_num(shared_socket);
						ugs->shared = 1;
                                		if (ugs->fd == -1) {
                                        		uwsgi_log("unable to use shared socket %d\n", shared_socket);
							exit(1);
                                		}
						ugs->name = uwsgi_getsockname(ugs->fd);
                        		}
				}
				else if (!uwsgi_startswith("fd://", ugs->name, 5 )) {
					int fd_socket = atoi(ugs->name+5);
					if (fd_socket >= 0) {
						ugs->fd = fd_socket;
						ugs->name = uwsgi_getsockname(ugs->fd);
						if (!ugs->name) {
                                        		uwsgi_log("unable to use file descriptor %d as socket\n", fd_socket);
							exit(1);
						}
					}
				}
				else {
					ugs->port = strchr(ugs->name, ':');
					if (ugs->fd == -1) {
						if (ugs->port) {
							ugs->fd = bind_to_tcp(ugs->name, uwsgi.listen_queue, ugs->port);
							ugs->port++;
							ugs->port_len = strlen(ugs->port);
						}
						else {
							ugs->fd = bind_to_unix(ugs->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
						}
					}
				}
				// put socket in non-blocking mode
				uwsgi_socket_nb(ugs->fd);
				uwsgi_log("%s bound on %s fd %d\n", ucr->name, ugs->name, ugs->fd);
			}
			else if (ugs->subscription) {
				if (ugs->fd == -1) {
					if (strchr(ugs->name, ':')) {
						ugs->fd = bind_to_udp(ugs->name, 0, 0);
					}
					else {
						ugs->fd = bind_to_unix_dgram(ugs->name);
					}
					uwsgi_socket_nb(ugs->fd);
				}
				uwsgi_log("%s subscription server bound on %s fd %d\n", ucr->name, ugs->name, ugs->fd);
			}
		}
		ugs = ugs->next;
	}

}
char *uwsgi_format_airbrake_backtrace(struct uwsgi_thread *ut) {

	struct uwsgi_airbrake_config *uacc = (struct uwsgi_airbrake_config *) ut->data;

	xmlChar *xmlbuff;
	int buffersize;
	xmlDocPtr doc = NULL;
	xmlNodePtr notice_node = NULL, node = NULL, line_node = NULL, errnode = NULL;
	char *msg = NULL;

	doc = xmlNewDoc(BAD_CAST "1.0");
	notice_node = xmlNewNode(NULL, BAD_CAST "notice");
	xmlNewProp(notice_node, BAD_CAST "version", BAD_CAST "2.3");
	xmlDocSetRootElement(doc, notice_node);

	xmlNewChild(notice_node, NULL, BAD_CAST "api-key", BAD_CAST uacc->apikey);

	node = xmlNewChild(notice_node, NULL, BAD_CAST "notifier", NULL);
	xmlNewChild(node, NULL, BAD_CAST "name", BAD_CAST "uWSGI");
	xmlNewChild(node, NULL, BAD_CAST "version", BAD_CAST UWSGI_VERSION);
	xmlNewChild(node, NULL, BAD_CAST "url", BAD_CAST "https://github.com/unbit/uwsgi");

	// request env
	node = xmlNewChild(notice_node, NULL, BAD_CAST "request", NULL);
	node = xmlNewChild(node, NULL, BAD_CAST "cgi-data", NULL);

	line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST UWSGI_VERSION);
	xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "uwsgi_version");

	line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST __VERSION__);
	xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "compiled_with_version");

	struct utsname uuts;
#ifdef __sun__
	if (uname(&uuts) < 0) {
#else
	if (uname(&uuts)) {
#endif
		uwsgi_error("uname()");
	}
	else {
		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST uuts.sysname);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "os_sysname");

		char *os_version = uwsgi_concat3(uuts.release, "-", uuts.version);
		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST os_version);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "os_version");
		free(os_version);

		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST uuts.machine);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "machine");

		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST uuts.nodename);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "nodename");

	}
	// end request env

	node = xmlNewChild(notice_node, NULL, BAD_CAST "server-environment", NULL);
	xmlNewChild(node, NULL, BAD_CAST "app-version", BAD_CAST UWSGI_VERSION);
	if (uacc->env) {
		xmlNewChild(node, NULL, BAD_CAST "environment-name", BAD_CAST uacc->env);
	}
	else {
		xmlNewChild(node, NULL, BAD_CAST "environment-name", BAD_CAST UWSGI_VERSION);
	}

	errnode = xmlNewChild(notice_node, NULL, BAD_CAST "error", NULL);
	xmlNewChild(errnode, NULL, BAD_CAST "class", BAD_CAST "RuntimeError");
	node = xmlNewChild(errnode, NULL, BAD_CAST "backtrace", NULL);

	char *ctx = NULL;
	char *text = uwsgi_str(ut->buf);
	char *p = strtok_r(text, "\n", &ctx);
	while (p) {
		// skip log messages
		if (!uwsgi_startswith(p, "***", 3))
			goto next;
		// backtrace line looks like this: uwsgi(simple_loop_run+0xc5) [0x451555]
		// we take binary/lib as filename
		// and extract method name from remaining string
		char *n = strchr(p, '(');
		if (n) {
			*n = 0;

			char *pls = strchr(n+1, '+');
			if (pls) {
				*pls = 0;
			}

			if (!strcmp("uwsgi_backtrace", n+1) || !strcmp("what_i_am_doing", n+1)) {
				goto next;
			}
			else if (!strcmp("uwsgi_fpe", n+1)) {
				msg = uwsgi_concat4("uWSGI FPE at ", n+1, " in ", p);
				goto next;
			}

			if (!msg) {
				if (strlen(n+1)) {
					msg = uwsgi_concat4("uWSGI segfault at ", n+1, " in ", p);
				}
				else {
					// method name might be missing
					msg = uwsgi_concat2("uWSGI segfault in ", p);
				}
			}

			// skip empty lines
			if (!p)
				goto next;

			line_node = xmlNewChild(node, NULL, BAD_CAST "line", NULL);

			if ((n+1)[0] == ')') {
				xmlNewProp(line_node, BAD_CAST "method", BAD_CAST "()");
			}
			else {
				xmlNewProp(line_node, BAD_CAST "method", BAD_CAST n+1);
			}

			xmlNewProp(line_node, BAD_CAST "file", BAD_CAST p);

			//xmlNewProp(line_node, BAD_CAST "number", BAD_CAST "0");
		}
next:
		p = strtok_r(NULL, "\n", &ctx);
	}

	xmlNewChild(errnode, NULL, BAD_CAST "message", BAD_CAST msg);

	xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);

	xmlFreeDoc(doc);
	xmlCleanupParser();
	xmlMemoryDump();
	free(msg);
	free(text);

	return (char *) xmlbuff;
}


static void uwsgi_airbrake_loop(struct uwsgi_thread *ut) {
	int interesting_fd;
	ut->buf = uwsgi_malloc(uwsgi.log_master_bufsize);

	CURL *curl = curl_easy_init();
	// ARGH !!!
	if (!curl) return;

	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
	curl_easy_setopt(curl, CURLOPT_READDATA, ut);
	curl_easy_setopt(curl, CURLOPT_POST, 1L);
	struct curl_slist *expect = NULL; expect = curl_slist_append(expect, "Expect:");
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

	struct uwsgi_airbrake_config *uacc = (struct uwsgi_airbrake_config *) ut->data;
	char *opts = uwsgi_str(uacc->arg);

	// fill curl options
	char *ctx = NULL;
	char *p = strtok_r(opts, ";", &ctx);
	while(p) {
		uwsgi_airbrake_setopt(curl, uwsgi_str(p), uacc);
		p = strtok_r(NULL, ";", &ctx);
	}

	for(;;) {
		int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
		if (ret < 0) return;
		if (ret == 0) continue;
		if (interesting_fd != ut->pipe[1]) continue;
		ssize_t rlen = read(ut->pipe[1], ut->buf, uwsgi.log_master_bufsize);
		if (rlen <= 0) continue;
		ut->pos = 0;
		ut->len = (size_t) rlen;
		ut->custom0 = 0;

		char *notice = uwsgi_format_airbrake_backtrace(ut);

		curl_slist_append(expect, "Accept: */*");
		curl_slist_append(expect, "Content-Type: text/xml; charset=utf-8");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, notice);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(notice));

		curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) ut->len);
		CURLcode res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			uwsgi_log_alarm("-curl] curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
		}
		free(notice);
	}
}
Example #6
0
void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *ucr) {

	struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
	while (ugs) {
		if (!strcmp(ucr->name, ugs->owner)) {
#ifdef UWSGI_SCTP
			if (!ugs->subscription && !ugs->sctp) {
#else
			if (!ugs->subscription) {
#endif
				if (ugs->name[0] == '=') {
					int shared_socket = atoi(ugs->name+1);
                        		if (shared_socket >= 0) {
                                		ugs->fd = uwsgi_get_shared_socket_fd_by_num(shared_socket);
						ugs->shared = 1;
                                		if (ugs->fd == -1) {
                                        		uwsgi_log("unable to use shared socket %d\n", shared_socket);
							exit(1);
                                		}
						ugs->name = uwsgi_getsockname(ugs->fd);
                        		}
				}
				else if (!uwsgi_startswith("fd://", ugs->name, 5 )) {
					int fd_socket = atoi(ugs->name+5);
					if (fd_socket >= 0) {
						ugs->fd = fd_socket;
						ugs->name = uwsgi_getsockname(ugs->fd);
						if (!ugs->name) {
                                        		uwsgi_log("unable to use file descriptor %d as socket\n", fd_socket);
							exit(1);
						}
					}
				}
				else {
					ugs->port = strchr(ugs->name, ':');
					if (ugs->fd == -1) {
						if (ugs->port) {
							ugs->fd = bind_to_tcp(ugs->name, uwsgi.listen_queue, ugs->port);
							ugs->port++;
							ugs->port_len = strlen(ugs->port);
						}
						else {
							ugs->fd = bind_to_unix(ugs->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
						}
					}
				}
				// put socket in non-blocking mode
				uwsgi_socket_nb(ugs->fd);
				uwsgi_log("%s bound on %s fd %d\n", ucr->name, ugs->name, ugs->fd);
			}
			else if (ugs->subscription) {
				if (ugs->fd == -1) {
					if (strchr(ugs->name, ':')) {
						ugs->fd = bind_to_udp(ugs->name, 0, 0);
					}
					else {
						ugs->fd = bind_to_unix_dgram(ugs->name);
					}
					uwsgi_socket_nb(ugs->fd);
				}
				uwsgi_log("%s subscription server bound on %s fd %d\n", ucr->name, ugs->name, ugs->fd);
			}
#ifdef UWSGI_SCTP
			else if (ugs->sctp) {
				if (ugs->fd == -1) {
					ugs->fd = bind_to_sctp(ugs->name);
				}				
				uwsgi_log("%s SCTP server bound on %s fd %d\n", gw_id, ugs->name, ugs->fd);
			}
#endif
		}
		ugs = ugs->next;
	}

}

void *uwsgi_corerouter_setup_event_queue(struct uwsgi_corerouter *ucr, int id) {

	ucr->queue = event_queue_init();

	struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
	while (ugs) {
		if (!strcmp(ucr->name, ugs->owner)) {
			if (!ucr->cheap || ugs->subscription) {
				event_queue_add_fd_read(ucr->queue, ugs->fd);
			}
			ugs->gateway = &ushared->gateways[id];
		}
		ugs = ugs->next;
	}

	return event_queue_alloc(ucr->nevents);
}
Example #7
0
void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {

	socklen_t socket_type_len;
	union uwsgi_sockaddr_ptr gsa, isa;
	union uwsgi_sockaddr usa;
	int abstract = 0;

	socket_type_len = sizeof(struct sockaddr_un);
	gsa.sa = &usa.sa;
	if (!getsockname(fd, gsa.sa, &socket_type_len)) {
		if (socket_type_len <= 2) {
			// unbound socket
			return;
		}
		if (gsa.sa->sa_family == AF_UNIX) {
			if (usa.sa_un.sun_path[0] == 0)
				abstract = 1;
			// is it a zerg ?
			if (uwsgi_sock->name == NULL) {
				uwsgi_sock->fd = fd;
				uwsgi_sock->family = AF_UNIX;
				uwsgi_sock->bound = 1;
				uwsgi_sock->name = uwsgi_concat2(usa.sa_un.sun_path + abstract, "");
				if (uwsgi.zerg) {
					uwsgi_log("uwsgi zerg socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path + abstract, uwsgi_sock->fd);
				}
				else {
					uwsgi_log("uwsgi socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path + abstract, uwsgi_sock->fd);
				}
				return;
			}
			if (!uwsgi_startswith(uwsgi_sock->name, "fd://", 5)) {
				if (atoi(uwsgi_sock->name + 5) == fd) {
					uwsgi_sock->fd = fd;
					uwsgi_sock->family = AF_UNIX;
					uwsgi_sock->bound = 1;
					uwsgi_sock->name = uwsgi_str(usa.sa_un.sun_path + abstract);
					uwsgi_log("uwsgi socket %d inherited UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
				}
			}
			else if (!strcmp(usa.sa_un.sun_path + abstract, uwsgi_sock->name + abstract)) {
				uwsgi_sock->fd = fd;
				uwsgi_sock->family = AF_UNIX;
				uwsgi_sock->bound = 1;
				uwsgi_log("uwsgi socket %d inherited UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
			}
		}
		else if (gsa.sa->sa_family == AF_INET) {
			char *computed_addr;
			char computed_port[6];
			isa.sa_in = (struct sockaddr_in *) &usa;
			char ipv4a[INET_ADDRSTRLEN + 1];
			memset(ipv4a, 0, INET_ADDRSTRLEN + 1);
			memset(computed_port, 0, 6);


			if (snprintf(computed_port, 6, "%d", ntohs(isa.sa_in->sin_port)) > 0) {
				if (inet_ntop(AF_INET, (const void *) &isa.sa_in->sin_addr.s_addr, ipv4a, INET_ADDRSTRLEN)) {

					if (!strcmp("0.0.0.0", ipv4a)) {
						computed_addr = uwsgi_concat2(":", computed_port);
					}
					else {
						computed_addr = uwsgi_concat3(ipv4a, ":", computed_port);
					}

					// is it a zerg ?
					if (uwsgi_sock->name == NULL) {
						uwsgi_sock->fd = fd;
						uwsgi_sock->family = AF_INET;
						uwsgi_sock->bound = 1;
						uwsgi_sock->name = uwsgi_concat2(computed_addr, "");
						if (uwsgi.zerg) {
							uwsgi_log("uwsgi zerg socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
						}
						else {
							uwsgi_log("uwsgi socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
						}
						free(computed_addr);
						return;
					}
					char *asterisk = strchr(uwsgi_sock->name, '*');
					int match = 1;
					if (asterisk) {
						asterisk[0] = 0;
						match = strncmp(computed_addr, uwsgi_sock->name, strlen(uwsgi_sock->name));
						asterisk[0] = '*';
					}
					else {
						if (!uwsgi_startswith(uwsgi_sock->name, "fd://", 5)) {
							if (atoi(uwsgi_sock->name + 5) == fd) {
								uwsgi_sock->fd = fd;
								uwsgi_sock->family = AF_INET;
								uwsgi_sock->bound = 1;
								uwsgi_sock->name = uwsgi_str(computed_addr);
								uwsgi_log("uwsgi socket %d inherited INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
								match = 1;
							}
						}
						else {
							match = strcmp(computed_addr, uwsgi_sock->name);
						}
					}
					if (!match) {
						uwsgi_sock->fd = fd;
						uwsgi_sock->family = AF_INET;
						uwsgi_sock->bound = 1;
						uwsgi_log("uwsgi socket %d inherited INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
					}
					free(computed_addr);
				}
			}
		}
#ifdef UWSGI_IPV6
		else if (gsa.sa->sa_family == AF_INET6) {
			char *computed_addr;
			char computed_port[6];
			isa.sa_in6 = (struct sockaddr_in6 *) &usa;
			char ipv6a[INET6_ADDRSTRLEN + 1];
			memset(ipv6a, 0, INET_ADDRSTRLEN + 1);
			memset(computed_port, 0, 6);
			int match = 0;


			if (snprintf(computed_port, 6, "%d", ntohs(isa.sa_in6->sin6_port)) > 0) {
				if (inet_ntop(AF_INET6, (const void *) &isa.sa_in6->sin6_addr.s6_addr, ipv6a, INET6_ADDRSTRLEN)) {
					uwsgi_log("ipv6a = %s\n", ipv6a);
					if (!strcmp("::", ipv6a)) {
						computed_addr = uwsgi_concat2("[::]:", computed_port);
					}
					else {
						computed_addr = uwsgi_concat4("[", ipv6a, "]:", computed_port);
					}
					// is it a zerg ?
					if (uwsgi_sock->name == NULL) {
						uwsgi_sock->fd = fd;
						uwsgi_sock->family = AF_INET6;
						uwsgi_sock->bound = 1;
						uwsgi_sock->name = uwsgi_concat2(computed_addr, "");
						if (uwsgi.zerg) {
							uwsgi_log("uwsgi zerg socket %d attached to INET6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
						}
						else {
							uwsgi_log("uwsgi socket %d attached to INET6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
						}
						free(computed_addr);
						return;
					}

					if (!uwsgi_startswith(uwsgi_sock->name, "fd://", 5)) {
						if (atoi(uwsgi_sock->name + 5) == fd) {
							uwsgi_sock->fd = fd;
							uwsgi_sock->family = AF_INET6;
							uwsgi_sock->bound = 1;
							uwsgi_sock->name = uwsgi_str(computed_addr);
							uwsgi_log("uwsgi socket %d inherited INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
							match = 1;
						}
					}
					else {
						match = strcmp(computed_addr, uwsgi_sock->name);
					}

					if (!match) {
						uwsgi_sock->fd = fd;
						uwsgi_sock->family = AF_INET;
						uwsgi_sock->bound = 1;
						uwsgi_log("uwsgi socket %d inherited INET6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
					}
					free(computed_addr);
				}
			}
		}

#endif
	}

}
Example #8
0
struct uwsgi_socket *uwsgi_new_socket(char *name) {

	struct uwsgi_socket *uwsgi_sock = uwsgi.sockets, *old_uwsgi_sock;
	struct sockaddr_in sin;
	socklen_t socket_type_len;

	if (!uwsgi_sock) {
		uwsgi.sockets = uwsgi_malloc(sizeof(struct uwsgi_socket));
		uwsgi_sock = uwsgi.sockets;
	}
	else {
		while (uwsgi_sock) {
			old_uwsgi_sock = uwsgi_sock;
			uwsgi_sock = uwsgi_sock->next;
		}

		uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_socket));
		old_uwsgi_sock->next = uwsgi_sock;
	}

	memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
	uwsgi_sock->name = name;
	uwsgi_sock->fd = -1;

	if (!name)
		return uwsgi_sock;

	if (name[0] == '=') {
		int shared_socket = atoi(uwsgi_sock->name + 1);
		if (shared_socket >= 0) {
			struct uwsgi_socket *uss = uwsgi_get_shared_socket_by_num(shared_socket);
			if (!uss) {
				uwsgi_log("unable to use shared socket %d\n", shared_socket);
				exit(1);
			}
			uwsgi_sock->bound = 1;
			uwsgi_sock->shared = 1;
			uwsgi_sock->from_shared = shared_socket;
			return uwsgi_sock;
		}
	}

	if (!uwsgi_startswith(name, "fd://", 5)) {
		uwsgi_add_socket_from_fd(uwsgi_sock, atoi(name + 5));
		return uwsgi_sock;
	}

	char *tcp_port = strrchr(name, ':');
	if (tcp_port) {
		// INET socket, check for 0 port
		if (tcp_port[1] == 0 || tcp_port[1] == '0') {
			uwsgi_sock->fd = bind_to_tcp(name, uwsgi.listen_queue, tcp_port);
			uwsgi_sock->family = AF_INET;
			uwsgi_sock->bound = 1;

			uwsgi_sock->auto_port = 1;

			socket_type_len = sizeof(struct sockaddr_in);

			if (getsockname(uwsgi_sock->fd, (struct sockaddr *) &sin, &socket_type_len)) {
				uwsgi_error("getsockname()");
				exit(1);
			}


			char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
			uwsgi_sock->name = uwsgi_concat3n(name, tcp_port - name, ":", 1, auto_port, strlen(auto_port));
		}
		// is it fd 0 ?
		else if (tcp_port[1] == ':') {
			uwsgi_sock->fd = 0;
			uwsgi_sock->family = AF_INET;
			uwsgi_sock->bound = 1;

			socket_type_len = sizeof(struct sockaddr_in);

			if (getsockname(0, (struct sockaddr *) &sin, &socket_type_len)) {
				uwsgi_error("getsockname()");
				exit(1);
			}


			char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
			char *auto_ip = inet_ntoa(sin.sin_addr);
			uwsgi_sock->name = uwsgi_concat3n(auto_ip, strlen(auto_ip), ":", 1, auto_port, strlen(auto_port));
		}
	}

	return uwsgi_sock;
}
Example #9
0
void linux_namespace_jail() {

	char *ns_tmp_mountpoint = NULL, *ns_tmp_mountpoint2 = NULL;

	if (getpid() != 1) {
		uwsgi_log("your kernel does not support linux pid namespace\n");
		exit(1);
	}

	char *ns_hostname = strchr(uwsgi.ns, ':');
	if (ns_hostname) {
		ns_hostname[0] = 0;
		ns_hostname++;
		if (sethostname(ns_hostname, strlen(ns_hostname))) {
			uwsgi_error("sethostname()");
		}
	}

	FILE *procmounts;
	char line[1024];
	int unmounted = 1;
	char *delim0, *delim1;

	if (chdir(uwsgi.ns)) {
		uwsgi_error("chdir()");
		exit(1);
	}

	if (strcmp(uwsgi.ns, "/")) {
		ns_tmp_mountpoint = uwsgi_concat2(uwsgi.ns, "/.uwsgi_ns_tmp_mountpoint");
		mkdir(ns_tmp_mountpoint, S_IRWXU);

		ns_tmp_mountpoint2 = uwsgi_concat2(ns_tmp_mountpoint, "/.uwsgi_ns_tmp_mountpoint");
		mkdir(ns_tmp_mountpoint2, S_IRWXU);

		if (mount(uwsgi.ns, ns_tmp_mountpoint, "none", MS_BIND, NULL)) {
			uwsgi_error("mount()");
		}
		if (chdir(ns_tmp_mountpoint)) {
			uwsgi_error("chdir()");
		}

		if (pivot_root(".", ns_tmp_mountpoint2)) {
			uwsgi_error("pivot_root()");
			exit(1);
		}



		if (chdir("/")) {
			uwsgi_error("chdir()");
			exit(1);
		}

	}

	uwsgi_log("remounting /proc\n");
	if (mount("proc", "/proc", "proc", 0, NULL)) {
		uwsgi_error("mount()");
	}

	struct uwsgi_string_list *usl = uwsgi.ns_keep_mount;
	while(usl) {
		// bind mounting keep-mount items
		char *keep_mountpoint = usl->value;
		char *destination = strchr(usl->value, ':');
		if (destination) {
			keep_mountpoint = uwsgi_concat2n(usl->value, destination - usl->value, "", 0);
		}
		char *ks = uwsgi_concat2("/.uwsgi_ns_tmp_mountpoint", keep_mountpoint);
		if (!destination) {
			destination = usl->value;
			// skip first part of the name if under the jail
			if (!uwsgi_startswith(destination, uwsgi.ns, strlen(uwsgi.ns))) {
				if (uwsgi.ns[strlen(uwsgi.ns)-1] == '/') {
					destination += strlen(uwsgi.ns)-1;
				}
				else {
					destination += strlen(uwsgi.ns);
				}
			}
		}
		else {
			free(keep_mountpoint);
			destination++;
		}

		uwsgi_log("remounting %s to %s\n", ks+25, destination);
		if (mount(ks, destination, "none", MS_BIND, NULL)) {
			uwsgi_error("mount()");
		}
		free(ks);
		usl = usl->next;
	}

	while (unmounted) {

		unmounted = 0;
		procmounts = fopen("/proc/self/mounts", "r");
		while (fgets(line, 1024, procmounts) != NULL) {
			delim0 = strchr(line, ' ');
			delim0++;
			delim1 = strchr(delim0, ' ');
			*delim1 = 0;
			// and now check for keep-mounts
			if (uwsgi_is_a_keep_mount(delim0)) continue;
			if (!strcmp(delim0, "/") || !strcmp(delim0, "/proc"))
				continue;
			if (!umount(delim0)) {
				unmounted++;
			}
		}
		fclose(procmounts);
	}

	if (rmdir("/.uwsgi_ns_tmp_mountpoint/.uwsgi_ns_tmp_mountpoint")) {
		uwsgi_error("rmdir()");
	}
	if (rmdir("/.uwsgi_ns_tmp_mountpoint")) {
		uwsgi_error("rmdir()");
	}

	if (strcmp(uwsgi.ns, "/")) {
		free(ns_tmp_mountpoint2);
		free(ns_tmp_mountpoint);
	}



}
Example #10
0
ffi_type *uwsgi_libffi_get_type(char *what, size_t *skip) {
	if (!uwsgi_startswith(what, "int:", 4)) { *skip = 4; return &ffi_type_sint32;}
	if (!uwsgi_startswith(what, "sint:", 5)) { *skip = 5; return &ffi_type_sint32;}
	if (!uwsgi_startswith(what, "uint:", 5)) { *skip = 5;return &ffi_type_uint32;}
	return &ffi_type_pointer;
}
Example #11
0
void *uwsgi_request_subhandler_pump(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {

	PyObject *zero;

	int i;
        PyObject *pydictkey, *pydictvalue;

	char *port = memchr(wsgi_req->host, ':', wsgi_req->host_len);
	if (port) {

		zero = PyString_FromStringAndSize(wsgi_req->host, (port-wsgi_req->host));
		PyDict_SetItemString(wsgi_req->async_environ, "server_name", zero);
		Py_DECREF(zero);

		zero = PyString_FromStringAndSize(port, wsgi_req->host_len-((port+1)-wsgi_req->host));
		PyDict_SetItemString(wsgi_req->async_environ, "server_port", zero);
		Py_DECREF(zero);
	}
	else {

		zero = PyString_FromStringAndSize(wsgi_req->host, wsgi_req->host_len);
		PyDict_SetItemString(wsgi_req->async_environ, "server_name", zero);
		Py_DECREF(zero);

		zero = PyString_FromStringAndSize("80", 2);
		PyDict_SetItemString(wsgi_req->async_environ, "server_port", zero);
		Py_DECREF(zero);
	}

	zero = PyString_FromStringAndSize(wsgi_req->remote_addr, wsgi_req->remote_addr_len);
	PyDict_SetItemString(wsgi_req->async_environ, "remote_addr", zero);
	Py_DECREF(zero);

	zero = PyString_FromStringAndSize(wsgi_req->path_info, wsgi_req->path_info_len);
	PyDict_SetItemString(wsgi_req->async_environ, "uri", zero);
	Py_DECREF(zero);

	if (wsgi_req->query_string_len > 0) {
		zero = PyString_FromStringAndSize(wsgi_req->query_string, wsgi_req->query_string_len);
		PyDict_SetItemString(wsgi_req->async_environ, "query_string", zero);
		Py_DECREF(zero);
	}

	zero = PyString_FromStringAndSize(uwsgi_lower(wsgi_req->method, wsgi_req->method_len), wsgi_req->method_len);
	PyDict_SetItemString(wsgi_req->async_environ, "method", zero);
	Py_DECREF(zero);

	if (wsgi_req->post_cl > 0) {
		PyDict_SetItemString(wsgi_req->async_environ, "content_length", PyInt_FromLong(wsgi_req->post_cl));
		if (wsgi_req->content_type_len > 0) {
			zero = PyString_FromStringAndSize(wsgi_req->content_type, wsgi_req->content_type_len);
                	PyDict_SetItemString(wsgi_req->async_environ, "content_type", zero);
                	Py_DECREF(zero);
		}
	}



	PyObject *headers = PyDict_New();

        for (i = 0; i < wsgi_req->var_cnt; i += 2) {
#ifdef UWSGI_DEBUG
                uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
#endif
		if (wsgi_req->hvec[i].iov_len < 6) continue;
		if (!uwsgi_startswith(wsgi_req->hvec[i].iov_base, "HTTP_", 5)) {
			(void) uwsgi_lower(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
#ifdef PYTHREE
                	pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5, NULL);
                	pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
#else
                	pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
                	pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
#endif
			PyObject *old_value = PyDict_GetItem(headers, pydictkey);
			if (old_value) {
				if (PyString_Check(old_value)) {
					PyObject *new_value = PyList_New(0);
					PyList_Append(new_value, old_value);
					old_value = new_value;
                			PyDict_SetItem(headers, pydictkey, old_value);
					Py_DECREF(old_value);
				}
				PyList_Append(old_value, pydictvalue);
			}
			else {
                		PyDict_SetItem(headers, pydictkey, pydictvalue);
			}
                	Py_DECREF(pydictkey);
                	Py_DECREF(pydictvalue);
		}
        }

	PyDict_SetItemString(wsgi_req->async_environ, "headers", headers);
	Py_DECREF(headers);

        // create wsgi.input custom object
        wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
        ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;

        PyDict_SetItemString(wsgi_req->async_environ, "body", wsgi_req->async_input);

	if (wsgi_req->scheme_len > 0) {
		zero = PyString_FromStringAndSize(wsgi_req->scheme, wsgi_req->scheme_len);
	}
	else if (wsgi_req->https_len > 0) {
		if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') {
			zero = PyString_FromString("https");
		}
		else {
			zero = PyString_FromString("http");
		}
	}
	else {
		zero = PyString_FromString("http");
	}
	PyDict_SetItemString(wsgi_req->async_environ, "scheme", zero);
	Py_DECREF(zero);


	wsgi_req->async_app = wi->callable;

	// export .env only in non-threaded mode
        if (uwsgi.threads < 2) {
        	PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
        }

        PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);

        if (uwsgi.cores > 1) {
                PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id));
        }

        PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node);

	// call

	PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ);
	return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req);
}