00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "config.h"
00025
00026 #include <cerrno>
00027 #include <cstring>
00028 #include <exception>
00029 #include <netdb.h>
00030 #include <sys/socket.h>
00031 #include <sys/types.h>
00032
00033 #include <scalestack/kernel/module.h>
00034 #include <scalestack/network/listener.h>
00035 #include <scalestack/network/stream_service.h>
00036
00037 using namespace std;
00038
00039 namespace scalestack
00040 {
00041 namespace network
00042 {
00043
00044
00045
00046
00047
00048 listener::listener(event::handler_service& handler_service,
00049 const struct addrinfo& local,
00050 int backlog,
00051 stream_service_provider& stream_service_provider):
00052 event::handler(handler_service),
00053 _stream_service_provider(stream_service_provider)
00054 {
00055 int file_descriptor = socket(local.ai_family,
00056 local.ai_socktype,
00057 local.ai_protocol);
00058 if (file_descriptor == -1)
00059 _module.log_fatal(_("Failed socket: %s:%d"), strerror(errno), errno);
00060
00061 int option = 1;
00062 int return_code = setsockopt(file_descriptor,
00063 SOL_SOCKET,
00064 SO_REUSEADDR,
00065 &option,
00066 sizeof(option));
00067 if (return_code == -1)
00068 {
00069 close(file_descriptor);
00070 _module.log_fatal(_("Failed setsockopt: %s:%d"), strerror(errno), errno);
00071 }
00072
00073 return_code = ::bind(file_descriptor, local.ai_addr, local.ai_addrlen);
00074 if (return_code == -1)
00075 {
00076 close(file_descriptor);
00077
00078 if (errno == EADDRINUSE)
00079 {
00080 _module.log_info(_("Failed bind, local address already in use"));
00081 throw exception();
00082 }
00083
00084 _module.log_fatal(_("Failed bind: %s:%d"), strerror(errno), errno);
00085 }
00086
00087 return_code = ::listen(file_descriptor, backlog);
00088 if (return_code == -1)
00089 {
00090 close(file_descriptor);
00091 _module.log_fatal(_("Failed listen: %s:%d"), strerror(errno), errno);
00092 }
00093
00094 set_file_descriptor(file_descriptor);
00095 watch_read();
00096 }
00097
00098 listener::~listener()
00099 {
00100 }
00101
00102 void listener::read_ready(int file_descriptor)
00103 {
00104 while (true)
00105 {
00106 struct sockaddr_storage peer_storage;
00107 struct sockaddr& peer = reinterpret_cast<struct sockaddr&>(peer_storage);
00108 socklen_t peer_size = sizeof(peer_storage);
00109
00110 int new_file_descriptor = ::accept(file_descriptor, &peer, &peer_size);
00111 if (new_file_descriptor == -1)
00112 {
00113 if (errno == EAGAIN)
00114 {
00115 watch_read();
00116 return;
00117 }
00118 else if (errno == EINTR)
00119 continue;
00120 else if (errno == EMFILE)
00121 {
00122 _module.log_error(_("Accept failed due to too many open files"));
00123 watch_read();
00124 return;
00125 }
00126
00127 _module.log_fatal(_("Failed accept: %s:%d"), strerror(errno), errno);
00128 }
00129
00130 try
00131 {
00132 _stream_service_provider.add_accepted(new_file_descriptor, peer,
00133 peer_size);
00134 }
00135 catch (exception& e)
00136 {
00137 _module.log_error(_("Accept failed: %s"), e.what());
00138 close(new_file_descriptor);
00139 }
00140 }
00141 }
00142
00143 }
00144 }