* Allow binding of the SCGI socket to a specific address, and added

"scgi_dont_route" variable.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@908 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-05-23 21:47:11 +00:00
parent bebce18368
commit 13dc0c942a
6 changed files with 52 additions and 26 deletions
+20 -13
View File
@@ -178,7 +178,7 @@ apply_fast_cgi(const std::string& arg) {
void void
apply_scgi(const std::string& arg, int type) { apply_scgi(const std::string& arg, int type) {
if (control->fast_cgi() != NULL) if (control->scgi() != NULL)
throw torrent::input_error("SCGI already enabled."); throw torrent::input_error("SCGI already enabled.");
if (control->xmlrpc() == NULL) if (control->xmlrpc() == NULL)
@@ -187,35 +187,37 @@ apply_scgi(const std::string& arg, int type) {
// Fix this... // Fix this...
control->set_scgi(new rpc::SCgi); control->set_scgi(new rpc::SCgi);
rak::address_info* ai = NULL;
rak::socket_address sa;
rak::socket_address* saPtr;
try { try {
int port; int port, err;
char dummy; char dummy;
char address[1024]; char address[1024];
switch (type) { switch (type) {
case 1: case 1:
if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) { if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) {
if (port <= 0 || port >= (1 << 16)) sa.sa_inet()->clear();
throw torrent::input_error("Invalid port number."); saPtr = &sa;
control->scgi()->open_port(port);
} else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2) { } else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2) {
if (port <= 0 || port >= (1 << 16))
throw torrent::input_error("Invalid port number.");
int err;
rak::address_info* ai;
if ((err = rak::address_info::get_address_info(address, PF_INET, SOCK_STREAM, &ai)) != 0) if ((err = rak::address_info::get_address_info(address, PF_INET, SOCK_STREAM, &ai)) != 0)
throw torrent::input_error("Could not bind address: " + std::string(rak::address_info::strerror(err)) + "."); throw torrent::input_error("Could not bind address: " + std::string(rak::address_info::strerror(err)) + ".");
control->scgi()->open(ai->address()->c_sockaddr(), ai->address()->length()); saPtr = ai->address();
} else { } else {
throw torrent::input_error("Could not parse address."); throw torrent::input_error("Could not parse address.");
} }
if (port <= 0 || port >= (1 << 16))
throw torrent::input_error("Invalid port number.");
saPtr->set_port(port);
control->scgi()->open_port(saPtr, saPtr->length(), control->variable()->call_command_value("get_scgi_dont_route"));
break; break;
case 2: case 2:
@@ -224,7 +226,11 @@ apply_scgi(const std::string& arg, int type) {
break; break;
} }
rak::address_info::free_address_info(ai);
} catch (torrent::local_error& e) { } catch (torrent::local_error& e) {
rak::address_info::free_address_info(ai);
throw torrent::input_error(e.what()); throw torrent::input_error(e.what());
} }
@@ -289,6 +295,7 @@ initialize_command_network() {
ADD_COMMAND_STRING_UN("fast_cgi", std::ptr_fun(&apply_fast_cgi)); ADD_COMMAND_STRING_UN("fast_cgi", std::ptr_fun(&apply_fast_cgi));
ADD_COMMAND_STRING_UN("scgi_port", rak::bind2nd(std::ptr_fun(&apply_scgi), 1)); ADD_COMMAND_STRING_UN("scgi_port", rak::bind2nd(std::ptr_fun(&apply_scgi), 1));
ADD_COMMAND_STRING_UN("scgi_local", rak::bind2nd(std::ptr_fun(&apply_scgi), 2)); ADD_COMMAND_STRING_UN("scgi_local", rak::bind2nd(std::ptr_fun(&apply_scgi), 2));
ADD_VARIABLE_BOOL("scgi_dont_route", false);
ADD_COMMAND_VALUE_TRI("hash_read_ahead", std::ptr_fun(&apply_hash_read_ahead), rak::ptr_fun(torrent::hash_read_ahead)); ADD_COMMAND_VALUE_TRI("hash_read_ahead", std::ptr_fun(&apply_hash_read_ahead), rak::ptr_fun(torrent::hash_read_ahead));
ADD_COMMAND_VALUE_TRI("hash_interval", std::ptr_fun(&apply_hash_interval), rak::ptr_fun(torrent::hash_interval)); ADD_COMMAND_VALUE_TRI("hash_interval", std::ptr_fun(&apply_hash_interval), rak::ptr_fun(torrent::hash_interval));
+7 -9
View File
@@ -36,6 +36,7 @@
#include "config.h" #include "config.h"
#include <rak/error_number.h>
#include <rak/socket_address.h> #include <rak/socket_address.h>
#include <sys/un.h> #include <sys/un.h>
#include <torrent/connection_manager.h> #include <torrent/connection_manager.h>
@@ -71,15 +72,12 @@ SCgi::~SCgi() {
} }
void void
SCgi::open_port(uint16_t port) { SCgi::open_port(void* sa, unsigned int length, bool dontRoute) {
rak::socket_address sa; if (!get_fd().open_stream() ||
sa.sa_inet()->clear(); (dontRoute && !get_fd().set_dont_route(true)))
sa.sa_inet()->set_port(port); throw torrent::resource_error("Could not open socket for listening: " + std::string(rak::error_number::current().c_str()));
if (!get_fd().open_stream()) open(sa, length);
throw torrent::resource_error("Could not open socket for listening.");
open(sa.c_sockaddr(), sa.length());
} }
void void
@@ -107,7 +105,7 @@ SCgi::open(void* sa, unsigned int length) {
!get_fd().set_reuse_address(true) || !get_fd().set_reuse_address(true) ||
!get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) || !get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) ||
!get_fd().listen(max_tasks)) !get_fd().listen(max_tasks))
throw torrent::resource_error("Could not prepare socket for listening."); throw torrent::resource_error("Could not prepare socket for listening: " + std::string(rak::error_number::current().c_str()));
torrent::connection_manager()->inc_socket_count(); torrent::connection_manager()->inc_socket_count();
+3 -3
View File
@@ -59,9 +59,7 @@ public:
SCgi() {} SCgi() {}
virtual ~SCgi(); virtual ~SCgi();
void open(void* sa, unsigned int length); void open_port(void* sa, unsigned int length, bool dontRoute);
void open_port(uint16_t port);
void open_named(const std::string& filename); void open_named(const std::string& filename);
const std::string path() const { return m_path; } const std::string path() const { return m_path; }
@@ -77,6 +75,8 @@ public:
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); } utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
private: private:
void open(void* sa, unsigned int length);
std::string m_path; std::string m_path;
slot_process m_slotProcess; slot_process m_slotProcess;
SCgiTask m_task[max_tasks]; SCgiTask m_task[max_tasks];
+1 -1
View File
@@ -67,7 +67,7 @@ SCgiTask::open(SCgi* parent, int fd) {
control->poll()->insert_read(this); control->poll()->insert_read(this);
control->poll()->insert_error(this); control->poll()->insert_error(this);
scgiTimer = rak::timer::current(); // scgiTimer = rak::timer::current();
} }
void void
+18
View File
@@ -42,6 +42,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/ip.h> #include <netinet/ip.h>
@@ -81,6 +82,23 @@ SocketFd::set_reuse_address(bool state) {
return setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == 0; return setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == 0;
} }
bool
SocketFd::set_dont_route(bool state) {
check_valid();
int opt = state;
return setsockopt(m_fd, SOL_SOCKET, SO_DONTROUTE, &opt, sizeof(opt)) == 0;
}
// bool
// SocketFd::set_bind_to_device(const char* device) {
// check_valid();
// struct ifreq ifr;
// strncpy(ifr.ifr_name, device, IFNAMSIZ);
// return setsockopt(m_fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == 0;
// }
bool bool
SocketFd::set_send_buffer_size(uint32_t s) { SocketFd::set_send_buffer_size(uint32_t s) {
check_valid(); check_valid();
+3
View File
@@ -59,6 +59,9 @@ public:
bool set_nonblock(); bool set_nonblock();
bool set_reuse_address(bool state); bool set_reuse_address(bool state);
bool set_dont_route(bool state);
bool set_bind_to_device(const char* device);
bool set_priority(priority_type p); bool set_priority(priority_type p);