Esempio n. 1
0
// called after receaving the uwsgi header (read vars)
static ssize_t fr_recv_uwsgi_vars(struct corerouter_peer *main_peer) {
	struct uwsgi_header *uh = (struct uwsgi_header *) main_peer->in->buf;
	// better to store it as the original buf address could change
	uint16_t pktsize = uh->_pktsize;
	// increase buffer if needed
	if (uwsgi_buffer_fix(main_peer->in, pktsize+4))
		return -1;
	ssize_t len = cr_read_exact(main_peer, pktsize+4, "fr_recv_uwsgi_vars()");
	if (!len) return 0;

	// headers received, ready to choose the instance
	if (main_peer->in->pos == (size_t)(pktsize+4)) {
		struct uwsgi_corerouter *ucr = main_peer->session->corerouter;

		struct corerouter_peer *new_peer = uwsgi_cr_peer_add(main_peer->session);
		new_peer->last_hook_read = fr_instance_read;

		if (!ufr.force_key) {
			// find the hostname
			if (uwsgi_hooked_parse(main_peer->in->buf+4, pktsize, fr_get_hostname, (void *) new_peer)) {
				return -1;
			}
		}
		else {
			new_peer->key_len = strlen(ufr.force_key);
			memcpy(new_peer->key, ufr.force_key, new_peer->key_len);
		}

		// check the hostname;
		if (new_peer->key_len == 0)
			return -1;

		// find an instance using the key
		if (ucr->mapper(ucr, new_peer))
			return -1;

		// check instance
		if (new_peer->instance_address_len == 0) {
			if (ufr.cr.fallback_on_no_key) {
				new_peer->failed = 1;
				new_peer->can_retry = 1;
				corerouter_close_peer(&ufr.cr, new_peer);
				return len;
			}
			return -1;
		}

		new_peer->can_retry = 1;

		cr_connect(new_peer, fr_instance_connected);
	}

	return len;
}
Esempio n. 2
0
// allocate a new session
static int rawrouter_alloc_session(struct uwsgi_corerouter *ucr, struct uwsgi_gateway_socket *ugs, struct corerouter_session *cs, struct sockaddr *sa, socklen_t s_len) {

	// set default read hook
	cs->main_peer->last_hook_read = rr_read;
	// set close hook
	cs->close = rr_session_close;
	// set retry hook
	cs->retry = rr_retry;

	if (sa && sa->sa_family == AF_INET) {
		if (urr.xclient) {
			struct rawrouter_session *rr = (struct rawrouter_session *) cs;
			rr->xclient = uwsgi_buffer_new(13+sizeof(cs->client_address)+2);
			if (uwsgi_buffer_append(rr->xclient, "XCLIENT ADDR=", 13)) return -1;
			if (uwsgi_buffer_append(rr->xclient, cs->client_address, strlen(cs->client_address))) return -1;
			if (uwsgi_buffer_append(rr->xclient, "\r\n", 2)) return -1;
		}
        }

	// add a new peer
	struct corerouter_peer *peer = uwsgi_cr_peer_add(cs);

	// set default peer hook
	peer->last_hook_read = rr_instance_read;

	// use the address as hostname
        memcpy(peer->key, cs->ugs->name, cs->ugs->name_len);
        peer->key_len = cs->ugs->name_len;

        // the mapper hook
        if (ucr->mapper(ucr, peer)) {
		return -1;
	}

        if (peer->instance_address_len == 0) {
		return -1;
        }

	peer->can_retry = 1;
	cr_connect(peer, rr_instance_connected);
	return 0;
}
Esempio n. 3
0
// called after receaving the uwsgi header (read vars)
ssize_t fr_recv_uwsgi_vars(struct corerouter_peer *main_peer) {
	struct uwsgi_header *uh = (struct uwsgi_header *) main_peer->in->buf;
	// increase buffer if needed
	if (uwsgi_buffer_fix(main_peer->in, uh->pktsize+4))
		return -1;
	ssize_t len = cr_read_exact(main_peer, uh->pktsize+4, "fr_recv_uwsgi_vars()");
	if (!len) return 0;

	// headers received, ready to choose the instance
	if (main_peer->in->pos == (size_t)(uh->pktsize+4)) {
		struct uwsgi_corerouter *ucr = main_peer->session->corerouter;

		struct corerouter_peer *new_peer = uwsgi_cr_peer_add(main_peer->session);
		new_peer->last_hook_read = fr_instance_read;

		// find the hostname
		if (uwsgi_hooked_parse(main_peer->in->buf+4, uh->pktsize, fr_get_hostname, (void *) new_peer)) {
			return -1;
		}

		// check the hostname;
		if (new_peer->key_len == 0)
			return -1;

		// find an instance using the key
		if (ucr->mapper(ucr, new_peer))
			return -1;

		// check instance
		if (new_peer->instance_address_len == 0)
			return -1;

		cr_connect(new_peer, fr_instance_connected);
	}

	return len;
}
Esempio n. 4
0
static ssize_t sr_read(struct corerouter_peer *main_peer) {
        struct corerouter_session *cs = main_peer->session;
        struct sslrouter_session *sr = (struct sslrouter_session *) cs;

        int ret = SSL_read(sr->ssl, main_peer->in->buf + main_peer->in->pos, main_peer->in->len - main_peer->in->pos);
        if (ret > 0) {
                // fix the buffer
                main_peer->in->pos += ret;
                // check for pending data
                int ret2 = SSL_pending(sr->ssl);
                if (ret2 > 0) {
                        if (uwsgi_buffer_fix(main_peer->in, main_peer->in->len + ret2 )) {
                                uwsgi_cr_log(main_peer, "cannot fix the buffer to %d\n", main_peer->in->len + ret2);
                                return -1;
                        }
                        if (SSL_read(sr->ssl, main_peer->in->buf + main_peer->in->pos, ret2) != ret2) {
                                uwsgi_cr_log(main_peer, "SSL_read() on %d bytes of pending data failed\n", ret2);
                                return -1;
                        }
                        // fix the buffer
                        main_peer->in->pos += ret2;
                }
		if (!main_peer->session->peers) {
			// add a new peer
        		struct corerouter_peer *peer = uwsgi_cr_peer_add(cs);
        		// set default peer hook
        		peer->last_hook_read = sr_instance_read;
        		// use the address as hostname
        		peer->key = cs->ugs->name;
        		peer->key_len = cs->ugs->name_len;

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
			if (usr.sni) {
				const char *servername = SSL_get_servername(sr->ssl, TLSEXT_NAMETYPE_host_name);
				if (servername) {
        				peer->key = (char *) servername;
        				peer->key_len = strlen(servername);
				}
			}
#endif
        		// the mapper hook
        		if (cs->corerouter->mapper(cs->corerouter, peer)) {
                		return -1;
        		}

        		if (peer->instance_address_len == 0) {
                		return -1;
        		}

			peer->can_retry = 1;
        		cr_connect(peer, sr_instance_connected);
			return 1;
		}
		main_peer->session->peers->out = main_peer->in;
        	main_peer->session->peers->out_pos = 0;
		cr_write_to_backend(main_peer, sr_instance_write);
		return ret;
        }
        if (ret == 0) return 0;
        int err = SSL_get_error(sr->ssl, ret);

        if (err == SSL_ERROR_WANT_READ) {
                cr_reset_hooks_and_read(main_peer, sr_read);
                return 1;
        }

        else if (err == SSL_ERROR_WANT_WRITE) {
                cr_write_to_main(main_peer, sr_read);
                return 1;
        }

        else if (err == SSL_ERROR_SYSCALL) {
                uwsgi_cr_error(main_peer, "sr_ssl_read()");
        }

        else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
                ERR_print_errors_fp(stderr);
        }

        return -1;
}