30 #define MCS_SOCKET_START "DATA-START %d (%d)" 31 #define MCS_SOCKET_SENDING "DATA-CHUNK %d" 32 #define MCS_SOCKET_STOP "DATA-STOP" 40 struct if_nameindex* ni;
45 while (ni[i].if_index) {
46 names.push_back(
string(ni[i].if_name));
52 for (i=0; i<names.size(); i++)
53 if (name == names[i]) {
59 throw MCS_FATAL(MSG_NET_INTERFACE_NAME_NOT_EXISTS, name.csz);
62 throw MCS_FATAL(MSG_NET_INTERFACE_NOT_ACTIVE, name.csz);
75 if ((
unsigned int) index >= names.size())
76 throw MCS_FATAL(MSG_NET_INTERFACE_ID_NOT_EXISTS, index, names.size());
93 int mcs::NetInterface::req(
int ioctl_num,
struct ifreq *ifr)
97 sock = socket(AF_INET, SOCK_STREAM, 0);
98 strncpy(ifr->ifr_name, names[lindex].c_str(), IFNAMSIZ-1);
99 ifr->ifr_name[IFNAMSIZ-1] = 0;
101 ret = ioctl(sock, ioctl_num, ifr);
104 throw MCS_FATAL(MSG_RETRIEVING_INTERFACE_FLAGS, names[lindex].
csz);
110 int mcs::NetInterface::getflags()
113 req(SIOCGIFFLAGS, &ifr);
114 return ifr.ifr_flags;
118 bool mcs::NetInterface::isup()
120 return ((getflags() & IFF_UP) ?
true :
false);
124 void mcs::NetInterface::str_sockaddr(
struct sockaddr* sa)
128 ifr.ifr_addr.sa_family = AF_INET;
129 req(SIOCGIFADDR, &ifr);
131 sa->sa_family = ifr.ifr_addr.sa_family;
132 memcpy(sa->sa_data, ifr.ifr_addr.sa_data, 14);
136 void mcs::NetInterface::str_sockaddr_in(
struct sockaddr_in* sin)
140 memcpy(sin, &sa,
sizeof(
struct sockaddr_in));
147 struct sockaddr_in sin;
149 int actIndex = lindex;
151 if ((
unsigned int) index >= names.size())
152 throw MCS_FATAL(MSG_NET_INTERFACE_ID_NOT_EXISTS, index, names.size());
157 s =
"(not available)";
159 str_sockaddr_in(&sin);
160 s = inet_ntoa(sin.sin_addr);
181 he = gethostbyname(host.c_str());
183 throw MCS_FATAL(MSG_RETRIEVING_HOSTNAME, hstrerror(h_errno));
186 ipaddr = inet_ntoa(*(
struct in_addr*)he->h_addr);
187 populate_sockaddr_in();
197 ret = getpeername(sockfd, (
struct sockaddr*)&sin, &len);
199 throw MCS_FATAL(MSG_RETRIEVING_PEERNAME, strerror(errno));
202 he = gethostbyaddr(&(sin.sin_addr),
sizeof(
struct in_addr), AF_INET);
209 ipaddr = inet_ntoa(*(
struct in_addr*)he->h_addr);
210 populate_sockaddr_in();
218 void mcs::HostInfo::populate_sockaddr_in()
221 inet_aton(ipaddr.c_str(), &addr);
223 sin.sin_family = AF_INET;
224 sin.sin_port = htons(0);
225 sin.sin_addr.s_addr = addr.s_addr;
226 memset(&(sin.sin_zero),
'\0', 8);
243 unsigned int readTimeout,
unsigned int writeTimeout,
246 MCS_DEBUG_SETUP(0,
"Socket");
250 #ifdef HAVE_OPENSSL_SSL_H 251 this->ssl_ctx = NULL;
252 #endif //HAVE_OPENSSL_SSL_H 259 #ifdef HAVE_OPENSSL_SSL_H 262 ERR_load_crypto_strings();
263 SSL_load_error_strings();
265 ssl_ctx = SSL_CTX_new(SSLv23_method());
267 ssl=SSL_new(ssl_ctx);
268 sbio=BIO_new_socket(
sockfd, BIO_NOCLOSE);
269 SSL_set_bio(ssl, sbio, sbio);
271 int ret = SSL_connect(ssl);
273 throw MCS_ERROR( MSG_SSL_CONNECT_ERROR );
293 #endif //HAVE_OPENSSL_SSL_H 298 unsigned int readTimeout,
299 unsigned int writeTimeout,
302 MCS_DEBUG_SETUP(0,
"Socket");
305 this->
use_ssl = (ssl_ctx != NULL);
306 #ifdef HAVE_OPENSSL_SSL_H 307 this->ssl_ctx = NULL;
308 #endif //HAVE_OPENSSL_SSL_H 316 #ifdef HAVE_OPENSSL_SSL_H 318 SSL_CTX* ctx = (SSL_CTX*) ssl_ctx;
320 sbio=BIO_new_socket(sockfd, BIO_NOCLOSE);
322 SSL_set_bio(ssl, sbio, sbio);
324 if(SSL_accept(ssl) <= 0)
327 #endif //HAVE_OPENSSL_SSL_H 338 sockfd = socket(PF_INET, SOCK_STREAM, 0);
340 sin.sin_port = htons(port);
343 socketflags = fcntl(
sockfd, F_GETFL, NULL);
344 fcntl(
sockfd, F_SETFL, socketflags | O_NONBLOCK);
346 ret = connect(
sockfd, (
struct sockaddr *)&sin,
sizeof(
struct sockaddr));
349 if (errno == EINPROGRESS)
352 throw MCS_FATAL(MSG_CANT_CONNECT_TO_HOST, strerror(errno));
356 fcntl(
sockfd, F_SETFL, socketflags);
371 #ifdef HAVE_OPENSSL_SSL_H 377 SSL_CTX_free (ssl_ctx);
379 #endif //HAVE_OPENSSL_SSL_H 391 struct timeval timeout;
392 timeout.tv_sec =
writeto.tv_sec;
393 timeout.tv_usec =
writeto.tv_usec;
398 ret = select(
sockfd+1, NULL, &
fds, NULL, &timeout);
401 throw MCS_FATAL(MSG_CALLING_SELECT, strerror(errno));
403 }
else if (ret == 0) {
423 struct timeval timeout;
425 if (chkDataAvailable) {
430 timeout.tv_sec =
readto.tv_sec;
431 timeout.tv_usec =
readto.tv_usec;
437 #ifdef HAVE_OPENSSL_SSL_H 439 ret = SSL_pending(ssl);
443 #endif //HAVE_OPENSSL_SSL_H 445 ret = select(
sockfd+1, &
fds, NULL, NULL, &timeout);
448 throw MCS_FATAL(MSG_CALLING_SELECT, strerror(errno));
457 ret = recv(
sockfd, &a, 1, MSG_PEEK);
460 throw MCS_FATAL(MSG_CALLING_RECV, strerror(errno));
484 sprintf(buf, MCS_SOCKET_SENDING, size);
488 if ((sscanf(s.c_str(),
"%d", &resp) == 1) && (resp == size) ) {
492 throw MCS_WARN(MSG_SEND_ABORT_BY_RECEIVER);
500 unsigned int chunksize;
503 if (s == MCS_SOCKET_STOP)
506 if (sscanf(s.c_str(), MCS_SOCKET_SENDING, &chunksize) != 1)
507 throw MCS_FATAL(MSG_PROTOCOL, s.c_str());
509 if (chunksize > maxsize)
510 throw MCS_FATAL(MSG_NOT_ENOUGH_SPACE, chunksize, maxsize);
512 sprintf(buf,
"%d", chunksize);
524 unsigned int chunksize;
527 if (s == MCS_SOCKET_STOP)
530 if (sscanf(s.c_str(), MCS_SOCKET_SENDING, &chunksize) != 1)
531 throw MCS_FATAL(MSG_PROTOCOL, s.c_str());
534 char* p = (*abuf)[0];
536 sprintf(buf,
"%d", chunksize);
548 unsigned int ret, lcount;
549 char* p = (
char*) buf;
555 #ifdef HAVE_OPENSSL_SSL_H 557 ret = SSL_read(ssl, p ,count);
558 switch(SSL_get_error(ssl, ret)) {
573 #endif //HAVE_OPENSSL_SSL_H 574 ret = recv(
sockfd, (
void*) p, count, 0);
594 #ifdef HAVE_OPENSSL_SSL_H 596 ret = SSL_write(ssl, buf, count);
597 switch(SSL_get_error(ssl, ret)) {
601 throw MCS_FATAL(MSG_CALLING_SEND,
"SSL write problem");
605 #endif //HAVE_OPENSSL_SSL_H 606 ret = send(
sockfd, buf, count, 0);
609 throw MCS_FATAL(MSG_CALLING_SEND, strerror(errno));
633 write((
void*) s.c_str(), s.length());
641 unsigned int chunksize;
643 MCS_DEBUG_ENTER(NOARGS);
648 sprintf(buf, MCS_SOCKET_START, 0, from->
maxChunkSize());
651 while ((p = from->
nextChunk(chunksize))) {
656 sprintf(buf, MCS_SOCKET_STOP);
658 MCS_DEBUG_LEAVE(NOARGS);
664 unsigned int size, chunksize, accum, tmp;
668 if (sscanf(s.c_str(), MCS_SOCKET_START, &size, &chunksize) != 2)
669 throw MCS_FATAL(MSG_PROTOCOL, s.c_str());
673 abuf =
new Buffer(*buffer, maxsize);
682 *buffer = (*abuf)[0];
725 ofstream out(filename.c_str(), ios::binary);
727 throw MCS_ERROR(MSG_CANT_OPEN_FILE, filename.c_str());
735 unsigned int size, chunksize, accum, tmp;
740 if (sscanf(s.c_str(), MCS_SOCKET_START, &size, &chunksize) != 2)
741 throw MCS_FATAL(MSG_PROTOCOL, s.c_str());
743 p = (
char*) malloc (chunksize);
745 while ((tmp =
recvChunk(p, chunksize))) {
759 unsigned int size, chunksize, accum, tmp;
764 if (sscanf(s.c_str(), MCS_SOCKET_START, &size, &chunksize) != 2)
765 throw MCS_FATAL(MSG_PROTOCOL, s.c_str());
767 p = (
char*) malloc (chunksize);
769 while ((tmp =
recvChunk(p, chunksize))) {
784 float fsec = ((float) millisec) / 1000.0;
785 int isec = (int) rintf(fsec);
800 bool use_ssl,
string sslcert,
string sslpriv) :
804 struct sockaddr_in sin;
808 sockfd = socket(PF_INET, SOCK_STREAM, 0);
809 str_sockaddr_in(&sin);
810 sin.sin_port = htons(port);
813 ret = setsockopt(
sockfd, SOL_SOCKET, SO_REUSEADDR, &ret,
sizeof(
int));
814 ret = bind(
sockfd, (
struct sockaddr *)&sin,
sizeof(
struct sockaddr));
817 throw MCS_FATAL(MSG_CALLING_BIND, strerror(errno));
821 throw MCS_FATAL(MSG_CALLING_LISTEN, strerror(errno));
825 #ifdef HAVE_OPENSSL_SSL_H 830 SSL_load_error_strings();
831 ERR_load_crypto_strings();
833 ssl_ctx=SSL_CTX_new(SSLv23_server_method());
836 if (! SSL_CTX_use_certificate_file(ssl_ctx, sslcert.c_str(),
840 if (! SSL_CTX_use_PrivateKey_file(ssl_ctx, sslpriv.c_str(),
844 if (! SSL_CTX_check_private_key(ssl_ctx))
847 #endif //HAVE_OPENSSL_SSL_H 855 #ifdef HAVE_OPENSSL_SSL_H 858 SSL_CTX_free (ssl_ctx);
859 #endif //HAVE_OPENSSL_SSL_H 864 void* mcs::ServerSocket::getSSLContext()
866 #ifdef HAVE_OPENSSL_SSL_H 873 #endif //HAVE_OPENSSL_SSL_H 880 struct sockaddr_in sin;
881 socklen_t sin_size =
sizeof(
struct sockaddr_in);
887 struct timeval timeout;
890 int ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
892 throw MCS_FATAL(MSG_CALLING_SELECT, strerror(errno));
898 if (FD_ISSET(
sockfd, &fds))
899 newsock = accept(
sockfd, (
struct sockaddr *)&sin, &sin_size);
Retrieve informations about network interfaces.
string ipaddress()
Return the host IP address.
~ServerSocket()
Destructor.
Serialize memory buffers or files into chunks.
Socket(const Socket &)
Declared to avoid using of default copy constructor.
ServerSocket(const ServerSocket &)
Declared to avoid using of default copy constructor.
Hold informations about an event.
#define csz
Macro to extract a C-style, null terminated string from a string object.
void print(string s)
Writes a string in the socket adding a newline.
bool acceptConnection(int &newsock, unsigned int millisec)
Wait for an incoming connection.
unsigned int write(void *buf, unsigned int count)
Reads data from a buffer and write in the socket.
int sockfd
C socket file descriptor.
unsigned int count()
Return how many network interfaces are present in the system.
#define MCS_ERROR(A, rest...)
Facility to easily pass all necessary parameter to an Event constructor.
bool use_ssl
True if the connection should be encrypted.
bool knowSize()
Reinitialize internal data.
unsigned int size()
If knowSize() is true, return the size of the entire block of data.
string remTrailing(string &s, const char *p)
Remove any trailing character "p".
int socketToHost(unsigned short port)
Connect to the host.
void resize(unsigned int size)
Check size, and eventually enlarge allocated memory.
bool use_ssl
True if the connection should be encrypted.
unsigned int read(void *buf, unsigned int count)
Reads data from the socket and write in a buffer.
string ipaddress(int index=-1)
Return the IP address of an interface.
unsigned int index()
Return the index of the actual interface.
HostInfo(const HostInfo &)
Declared to avoid using of default copy constructor.
void * nextChunk(unsigned int &chunksize)
Fills a buffer with next chunk to be sent.
void sendChunk(void *buf, unsigned int size)
Send a chunk of binary data through the socket.
Main include file for all MCS based applications.
void sendData(Serializable *from)
Send a block of data through the socket.
bool chkRecv(bool chkDataAvailable=false, enum ThrowExceptions throwexc=THROW)
Check if you can read data from this socket.
#define MCS_WARN(A, rest...)
Facility to easily pass all necessary parameter to an Event constructor.
unsigned short int port
Port on which this socket will connect.
ThrowExceptions
Values to be used with throwexc parameters.
bool chkSend(enum ThrowExceptions throwexc=THROW)
Check if you can send data through this socket.
static void set_struct_timeval(unsigned int millisec, struct timeval *time)
Fill a "struct timeval" with the given interval.
struct timeval readto
Timeout interval for read operations.
NetInterface(string name="lo")
Constructor.
void Close()
Close the socket.
unsigned int maxChunkSize()
Return the max size allowed for a chunk.
#define MCS_FATAL(A, rest...)
Facility to easily pass all necessary parameter to an Event constructor.
unsigned int recvData(char **buffer, unsigned int maxsize)
Receive data and store in a buffer.
int sockfd
Server socket descriptor.
string name(int index=-1)
Return the name of an interface.
string getline()
Reads from a socket until a newline is encountered.
~NetInterface()
Destructor.
fd_set fds
Set of socket file descriptors, used with select().
Retrieve informations about a network host.
string hostname()
Return the host name.
struct timeval writeto
Timeout interval fro write operations.
unsigned int recvChunk(void *buf, unsigned int size)
Receive a chunk of binary data from the socket.
Namespace for MCS library.