Browse Source

ipv6 support... WIP

test
nicolas-arnaud 2 years ago
parent
commit
ac3857755f
  1. 2
      Makefile
  2. 2
      default.json
  3. 11
      includes/Sock6.hpp
  4. 6
      includes/Socket.hpp
  5. 2
      includes/webserv.hpp
  6. 2
      srcs/load/Route.cpp
  7. 17
      srcs/load/Server.cpp
  8. 82
      srcs/load/Sock6.cpp
  9. 36
      srcs/load/Socket.cpp
  10. 11
      srcs/tools.cpp

2
Makefile

@ -1,6 +1,6 @@
NAME= server NAME= server
SRCS= srcs/webserv.cpp srcs/tools.cpp srcs/load/Env.cpp srcs/load/Server.cpp \ SRCS= srcs/webserv.cpp srcs/tools.cpp srcs/load/Env.cpp srcs/load/Server.cpp \
srcs/load/Socket.cpp srcs/load/Route.cpp \ srcs/load/Socket.cpp srcs/load/Sock6.cpp srcs/load/Route.cpp \
srcs/json/Nodes.cpp srcs/json/Token.cpp srcs/json/Parser.cpp srcs/json/Nodes.cpp srcs/json/Token.cpp srcs/json/Parser.cpp
OBJS= $(SRCS:.cpp=.o) OBJS= $(SRCS:.cpp=.o)
CXX=c++ CXX=c++

2
default.json

@ -4,7 +4,7 @@
"servers": [ "servers": [
{ {
"server_name": "localhost", "server_name": "localhost",
"listens": ["8080", "localhost:8080", "localhost", "[::]:443"], "listens": ["80", "localhost:80", "localhost", "[::]:5555"],
"return": "301 https://$host$uri" "return": "301 https://$host$uri"
}, },
{ {

11
includes/Sock6.hpp

@ -0,0 +1,11 @@
#pragma once
#include "webserv.hpp"
class Sock6: public Socket {
struct sockaddr_in6 _addr6;
public:
Sock6(listen_t listen);
~Sock6();
int launch();
void refresh(Env *env);
};

6
includes/Socket.hpp

@ -2,10 +2,12 @@
#include "webserv.hpp" #include "webserv.hpp"
class Socket { class Socket {
struct sockaddr_in _addr;
protected:
int _master_socket; int _master_socket;
struct sockaddr_in _address;
int _clients_amount; int _clients_amount;
std::vector<int> _clients; std::vector<int> _clients;
int _type;
public: public:
listen_t _listen; listen_t _listen;
@ -13,7 +15,7 @@ class Socket {
static int _max_fd; static int _max_fd;
static int _min_fd; static int _min_fd;
static int _amount; static int _amount;
Socket(string def); Socket(listen_t listen);
~Socket(); ~Socket();
int launch(); int launch();
void set_fds(); void set_fds();

2
includes/webserv.hpp

@ -44,6 +44,7 @@ typedef std::vector<JSONNode *> JSONList;
typedef struct listen_s { typedef struct listen_s {
string ip; string ip;
int port; int port;
int type;
} listen_t; } listen_t;
void *ft_memset(void *b, int c, size_t len); void *ft_memset(void *b, int c, size_t len);
@ -57,5 +58,6 @@ listen_t get_listen_t(string listen);
#include "Route.hpp" #include "Route.hpp"
#include "Socket.hpp" #include "Socket.hpp"
#include "Sock6.hpp"
#include "Server.hpp" #include "Server.hpp"
#include "Env.hpp" #include "Env.hpp"

2
srcs/load/Route.cpp

@ -33,7 +33,7 @@ string Route::getAutoindex(string uri) {
struct stat info; struct stat info;
if ((dir = opendir(path.c_str())) == NULL) if ((dir = opendir(path.c_str())) == NULL)
ret << " 19\n\nFolder unaccesible."; page << "Folder unaccesible.";
else { else {
page << path << " files :\n"; page << path << " files :\n";
while ((entry = readdir(dir)) != NULL) { while ((entry = readdir(dir)) != NULL) {

17
srcs/load/Server.cpp

@ -17,25 +17,30 @@ Server::Server(JSONNode *server) : Route(server) {
std::vector<Socket *> Server::get_sockets(JSONNode *server) { std::vector<Socket *> Server::get_sockets(JSONNode *server) {
JSONObject datas = server->obj(); JSONObject datas = server->obj();
std::vector<Socket *> ret; std::vector<Socket *> ret;
listen_t listen;
if (datas["listens"]) { if (datas["listens"]) {
JSONList listens = datas["listens"]->lst(); JSONList listens = datas["listens"]->lst();
for (JSONList::iterator it = listens.begin(); it < listens.end(); for (JSONList::iterator it = listens.begin(); it < listens.end();
it++) { it++) {
_listens.push_back(get_listen_t((*it)->str())); listen = get_listen_t((*it)->str());
Socket *sock = new Socket((*it)->str()); _listens.push_back(listen);
Socket *sock;
if (listen.type == AF_INET)
sock = new Socket(listen);
else
sock = new Sock6(listen);
if (sock->launch() == EXIT_SUCCESS) if (sock->launch() == EXIT_SUCCESS)
ret.push_back(sock); ret.push_back(sock);
else else
delete sock; delete sock;
} }
} else { } else {
Socket *sock = new Socket("localhost:80"); Socket *sock = new Socket(get_listen_t("localhost:80"));
if (sock->launch() == EXIT_SUCCESS) { if (sock->launch() == EXIT_SUCCESS) {
ret.push_back(sock); ret.push_back(sock);
} }
} }
return ret; return ret;
} }
Server::~Server(void) { cout << "Server destroyed!\n"; } Server::~Server(void) { cout << "Server destroyed!\n"; }
@ -49,8 +54,8 @@ Route *Server::get_route(string uri) {
root = split((*rit).first, '/'); root = split((*rit).first, '/');
std::vector<string>::iterator root_it = root.begin(); std::vector<string>::iterator root_it = root.begin();
for (std::vector<string>::iterator it = req.begin(); for (std::vector<string>::iterator it = req.begin(); it < req.end();
it < req.end(); it++) { it++) {
if (*it == "") if (*it == "")
continue; continue;
cout << *it << " - " << *root_it << "\n"; cout << *it << " - " << *root_it << "\n";

82
srcs/load/Sock6.cpp

@ -0,0 +1,82 @@
#include "webserv.hpp"
Sock6::Sock6(listen_t listen) : Socket(listen) { _type = AF_INET6; }
int Sock6::launch() {
int opt = 1;
string ip = _listen.ip;
int port = _listen.port;
_addr6.sin6_family = AF_INET6;
inet_pton(AF_INET6, ip.c_str(), (void *)&(_addr6.sin6_addr.s6_addr));
_addr6.sin6_port = htons(port);
_master_socket = socket(_addr6.sin6_family, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR,
(char *)&opt, sizeof(opt));
if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
if (bind(_master_socket, (struct sockaddr *)&_addr6, sizeof(_addr6)) < 0) {
cout << "Bind: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
cout << "Listener " << ip << " on port " << port << "\n";
if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
cout << "Socket::_master_socket: " << _master_socket << "\n";
if (_master_socket < _min_fd)
_min_fd = _master_socket;
_amount++;
return (EXIT_SUCCESS);
}
void Sock6::refresh(Env *env) {
std::vector<int>::iterator it;
int valread;
int addrlen = sizeof(_addr6);
char buffer[10000];
if (FD_ISSET(_master_socket, &_readfds)) {
int new_socket = accept(_master_socket, (struct sockaddr *)&_addr6,
(socklen_t *)&addrlen);
if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
#ifdef __APPLE__
fcntl(new_socket, F_GETNOSIGPIPE);
#endif
cout << "New connection, socket fd is "
<< new_socket
// << ", ip is : " << inet_ntoa(_addr6.sin6_addr)
<< ", port : " << ntohs(_addr6.sin6_port) << "\n";
_clients.push_back(new_socket);
}
for (it = _clients.begin(); it < _clients.end(); it++) {
if (FD_ISSET(*it, &_readfds)) {
valread = read(*it, buffer, 10000);
if (valread == 0) {
getpeername(*it, (struct sockaddr *)&_addr6,
(socklen_t *)&addrlen);
// cout << "Host disconnected, ip " <<
//inet_ntoa(_addr6.sin6_addr)
// << ", port " << ntohs(_addr6.sin6_port) << "\n";
close(*it);
_clients.erase(it);
} else {
buffer[valread] = '\0';
answer(env, *it, buffer);
}
}
}
}

36
srcs/load/Socket.cpp

@ -1,9 +1,9 @@
#include "webserv.hpp" #include "webserv.hpp"
Socket::Socket(string def) { Socket::Socket(listen_t listen) : _listen(listen) {
_listen = get_listen_t(def);
_clients_amount = 0; _clients_amount = 0;
_type = AF_INET;
} }
Socket::~Socket() { Socket::~Socket() {
close(_master_socket); close(_master_socket);
@ -14,7 +14,13 @@ int Socket::launch() {
int opt = 1; int opt = 1;
string ip = _listen.ip; string ip = _listen.ip;
int port = _listen.port; int port = _listen.port;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
_type = AF_INET;
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = inet_addr(ip.c_str());
_addr.sin_port = htons(port);
_master_socket = socket(_addr.sin_family, SOCK_STREAM, 0);
if (_master_socket == 0) { if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n"; cout << "Socket creation: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
@ -26,15 +32,7 @@ int Socket::launch() {
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
if (ip.at(0) == '[') if (bind(_master_socket, (struct sockaddr *)&_addr, sizeof(_addr)) < 0) {
_address.sin_family = AF_INET6;
else
_address.sin_family = AF_INET;
_address.sin_addr.s_addr = inet_addr(ip.c_str());
_address.sin_port = htons(port);
if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) <
0) {
cout << "Bind: " << strerror(errno) << "\n"; cout << "Bind: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
@ -65,10 +63,10 @@ void Socket::set_fds() {
void Socket::refresh(Env *env) { void Socket::refresh(Env *env) {
std::vector<int>::iterator it; std::vector<int>::iterator it;
int valread; int valread;
int addrlen = sizeof(_address); int addrlen = sizeof(_addr);
char buffer[10000]; char buffer[10000];
if (FD_ISSET(_master_socket, &_readfds)) { if (FD_ISSET(_master_socket, &_readfds)) {
int new_socket = accept(_master_socket, (struct sockaddr *)&_address, int new_socket = accept(_master_socket, (struct sockaddr *)&_addr,
(socklen_t *)&addrlen); (socklen_t *)&addrlen);
if (new_socket < 0) { if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n"; cout << "Accept: " << strerror(errno) << "\n";
@ -78,18 +76,18 @@ void Socket::refresh(Env *env) {
fcntl(new_socket, F_GETNOSIGPIPE); fcntl(new_socket, F_GETNOSIGPIPE);
#endif #endif
cout << "New connection, socket fd is " << new_socket cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(_address.sin_addr) << ", ip is : " << inet_ntoa(_addr.sin_addr)
<< ", port : " << ntohs(_address.sin_port) << "\n"; << ", port : " << ntohs(_addr.sin_port) << "\n";
_clients.push_back(new_socket); _clients.push_back(new_socket);
} }
for (it = _clients.begin(); it < _clients.end(); it++) { for (it = _clients.begin(); it < _clients.end(); it++) {
if (FD_ISSET(*it, &_readfds)) { if (FD_ISSET(*it, &_readfds)) {
valread = read(*it, buffer, 10000); valread = read(*it, buffer, 10000);
if (valread == 0) { if (valread == 0) {
getpeername(*it, (struct sockaddr *)&_address, getpeername(*it, (struct sockaddr *)&_addr,
(socklen_t *)&addrlen); (socklen_t *)&addrlen);
cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr) cout << "Host disconnected, ip " << inet_ntoa(_addr.sin_addr)
<< ", port " << ntohs(_address.sin_port) << "\n"; << ", port " << ntohs(_addr.sin_port) << "\n";
close(*it); close(*it);
_clients.erase(it); _clients.erase(it);
} else { } else {

11
srcs/tools.cpp

@ -36,8 +36,17 @@ listen_t get_listen_t(string listen) {
if (ip6_endpos > sep_pos) if (ip6_endpos > sep_pos)
ret.ip = listen; ret.ip = listen;
else else
ret.ip = isInt(tmp) || tmp == "localhost" ? "0.0.0.0" : tmp; ret.ip = isInt(tmp) ? "0.0.0.0" : \
(tmp == "localhost" ? "127.0.0.1" : \
(tmp == "[::]" ? "[0000:0000:0000:0000:0000:0000:0000:0000]" : tmp));
tmp = listen.substr(sep_pos + 1, listen.length() - sep_pos - 1).c_str(); tmp = listen.substr(sep_pos + 1, listen.length() - sep_pos - 1).c_str();
ret.port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str()); ret.port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str());
if (ret.ip.at(0) == '[') {
ret.type = AF_INET6;
ret.ip.erase(ret.ip.length() - 1, ret.ip.length());
ret.ip.erase(0, 1);
}
else
ret.type = AF_INET;
return ret; return ret;
} }

Loading…
Cancel
Save