base
This commit is contained in:
@@ -0,0 +1,414 @@
|
||||
/***************************************************************************
|
||||
Socket Control Class (SocketControl.cpp)
|
||||
-----------------------------------------
|
||||
|
||||
begin : 2013/02/20
|
||||
copyright : (C) 2013 Solbox Inc.
|
||||
author : Development 1 Team
|
||||
- 2013/02/20 - 1st dadamin
|
||||
email : dev1@solbox.com
|
||||
version : 3.2.0
|
||||
|
||||
CopyRight(C) 2005 Solbox Inc. All Rights reserved.
|
||||
Redistribution and use in source and binary forms, with or with out
|
||||
modification, are not permitted in outside of Solbox Inc.
|
||||
***************************************************************************/
|
||||
#include "rc_mngd.h"
|
||||
#include "SocketControl.h"
|
||||
#include "Logger.h"
|
||||
#include "UtilFn.h"
|
||||
|
||||
#define SOCKET_TIMEOUT 5
|
||||
|
||||
CSocketControl::CSocketControl()
|
||||
: CBaseSocket( SOCKET_NOT_VALID ), m_ssl(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSocketControl::CSocketControl( const int & socket, SSL * ssl)
|
||||
: CBaseSocket( socket ), m_ssl(ssl)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSocketControl::~CSocketControl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CSocketControl::SetOption()
|
||||
{
|
||||
if( m_sock == SOCKET_NOT_VALID )
|
||||
return -1;
|
||||
|
||||
int result = 0;
|
||||
/* Time wait 방지 */
|
||||
struct linger ling;
|
||||
|
||||
ling.l_onoff = 1;
|
||||
ling.l_linger = 10; /* 0 for abortive disconnect */
|
||||
|
||||
result = setsockopt(m_sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
|
||||
if( result != 0 )
|
||||
{
|
||||
int errorNum = errno;
|
||||
LOG( LERR, "SO_LINGER set error.[%d][%s]", errorNum, strerror(errorNum));
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval tv_timeo = { SOCKET_TIMEOUT, 0 };
|
||||
/* Recv Timeout 설정. */
|
||||
result = setsockopt( m_sock, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo, sizeof(tv_timeo));
|
||||
if( result != 0 )
|
||||
{
|
||||
int errorNum = errno;
|
||||
LOG( LERR, "SO_RCVTIMEO set error.[%d][%s]", errorNum, strerror(errorNum));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send Timeout 설정. */
|
||||
result = setsockopt( m_sock, SOL_SOCKET, SO_SNDTIMEO, &tv_timeo, sizeof(tv_timeo));
|
||||
if( result != 0 )
|
||||
{
|
||||
int errorNum = errno;
|
||||
LOG( LERR, "SO_SNDTIMEO set error.[%d][%s]", errorNum, strerror(errorNum));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::ReadnSSL( void *vptr, size_t n )
|
||||
{
|
||||
ssize_t nread = 0;
|
||||
size_t nleft = n;
|
||||
char * ptr = (char *)vptr;
|
||||
|
||||
while(nleft > 0)
|
||||
{
|
||||
if((nread = SSL_read(m_ssl, ptr, nleft)) < 0)
|
||||
{
|
||||
int error_code = SSL_get_error(m_ssl, nread);
|
||||
LOG( LDBG, "SSL read error code [%d]", error_code);
|
||||
|
||||
switch( error_code)
|
||||
{
|
||||
char tempBuffer[1024];
|
||||
memset(tempBuffer, 0x00, sizeof(tempBuffer));
|
||||
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
nread = 0;
|
||||
LOG( LWAR, "SSL read sleep [%d]", error_code);
|
||||
solusleep(50000);
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
ERR_error_string_n(ERR_get_error(), tempBuffer, sizeof(tempBuffer));
|
||||
LOG( LERR, "SSL Read Error :[%s]", tempBuffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if(nread == 0)
|
||||
{
|
||||
LOG(LWAR, "SSL read return 0.[%zd]", nread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nleft -= nread;
|
||||
ptr += nread;
|
||||
}
|
||||
|
||||
return n;/* ?? */
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::WritenSSL(void *vptr, size_t n)
|
||||
{
|
||||
size_t nleft;
|
||||
ssize_t nwritten;
|
||||
|
||||
const char * ptr = (const char *)vptr;
|
||||
nleft = n;
|
||||
|
||||
int tryCount = 0;
|
||||
|
||||
while(nleft > 0)
|
||||
{
|
||||
//fprintf(stderr, "[%s] ssl write before nleft[%d]\n", __func__, nleft);
|
||||
nwritten = SSL_write( m_ssl, ptr, nleft);
|
||||
//fprintf(stderr, "[%s] ssl write after n[%d]\n", __func__, nwritten);
|
||||
|
||||
|
||||
if( nwritten < 0 )
|
||||
{
|
||||
int error_code = SSL_get_error(m_ssl, nwritten);
|
||||
LOG( LDBG, "SSL Write error code [%d]", error_code);
|
||||
|
||||
switch( error_code )
|
||||
{
|
||||
char tempBuffer[1024];
|
||||
|
||||
memset(tempBuffer, 0x00, sizeof(tempBuffer));
|
||||
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
nwritten = 0;
|
||||
++tryCount;
|
||||
LOG( LWAR, "SSL Write sleep [%d]", error_code);
|
||||
solusleep(50000);
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
ERR_error_string_n(ERR_get_error(), tempBuffer, sizeof(tempBuffer));
|
||||
LOG( LERR, "SSL Write Error [%s]", tempBuffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( nwritten == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( tryCount > 60 )
|
||||
{
|
||||
LOG( LERR, "SSL Write Try Count Over !!!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nleft -= nwritten;
|
||||
ptr += nwritten;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::ReadData(void *vptr, size_t n)
|
||||
{
|
||||
ssize_t nret = 0;
|
||||
|
||||
if(m_ssl)
|
||||
nret = ReadnSSL(vptr, n);
|
||||
else
|
||||
nret = ReadNTimeout(vptr, n);
|
||||
|
||||
ostringstream msg;
|
||||
msg << "Socket ReadData() result.[" << nret << "]";
|
||||
LOGACONSOLE( LDBG, msg);
|
||||
|
||||
return nret;
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::ReadDataEx(void *vptr, size_t n)
|
||||
{
|
||||
ssize_t nret = 0;
|
||||
|
||||
if (m_ssl)
|
||||
nret = ReadSSL(vptr, n);
|
||||
else
|
||||
nret = ReadTimeout(vptr, n);
|
||||
|
||||
ostringstream msg;
|
||||
msg << "Socket ReadDataEx() result.[" << nret << "]";
|
||||
LOGACONSOLE(LDBG, msg);
|
||||
|
||||
return nret;
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::ReadTimeout(void *vptr, size_t n, int timeout)
|
||||
{
|
||||
if (IsValidSocket() == false)
|
||||
return 0;
|
||||
|
||||
ssize_t nRead = 0;
|
||||
char * ptr = (char *)vptr;
|
||||
|
||||
struct timeval timeOver;
|
||||
int result;
|
||||
|
||||
fd_set selectFds;
|
||||
FD_ZERO(&selectFds);
|
||||
|
||||
|
||||
timeOver.tv_sec = timeout;
|
||||
timeOver.tv_usec = 0;
|
||||
FD_SET(m_sock, &selectFds);
|
||||
|
||||
do {
|
||||
result = select(m_sock + 1, &selectFds, (fd_set *)NULL, (fd_set *)NULL, &timeOver);
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
if (FD_ISSET(m_sock, &selectFds))
|
||||
{
|
||||
if ((nRead = read(m_sock, ptr, n)) < 0)
|
||||
{
|
||||
int errorNum = errno;
|
||||
if (errorNum == EINTR || errorNum == EAGAIN || errorNum == EWOULDBLOCK)
|
||||
{
|
||||
nRead = 0;
|
||||
continue;
|
||||
}
|
||||
else if (errorNum == ECONNRESET || errorNum == EPIPE)
|
||||
{
|
||||
// 2015-08-28 CHG huibong EPIPE(32) 오류 발생시.. 연결 종료로 처리되도록 수정
|
||||
m_bConnected = false;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LERR, "read func fail.[%d][%s]", errorNum, strerror(errorNum));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (nRead == 0)
|
||||
{
|
||||
m_bConnected = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (result == 0) // Timeout
|
||||
{
|
||||
//LOG( LDBG, "read timeout");
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int errorNum = errno;
|
||||
LOG(LERR, "select func error.[%d][%s]", errorNum, strerror(errorNum));
|
||||
|
||||
return -1;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
return nRead;
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::ReadSSL(void *vptr, size_t n)
|
||||
{
|
||||
ssize_t nread = 0;
|
||||
char * ptr = (char *)vptr;
|
||||
|
||||
if ((nread = SSL_read(m_ssl, ptr, n)) < 0)
|
||||
{
|
||||
int error_code = SSL_get_error(m_ssl, nread);
|
||||
LOG(LDBG, "SSL read error code [%d]", error_code);
|
||||
|
||||
switch (error_code)
|
||||
{
|
||||
char tempBuffer[1024];
|
||||
memset(tempBuffer, 0x00, sizeof(tempBuffer));
|
||||
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
nread = 0;
|
||||
LOG(LWAR, "SSL read sleep [%d]", error_code);
|
||||
solusleep(50000);
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
ERR_error_string_n(ERR_get_error(), tempBuffer, sizeof(tempBuffer));
|
||||
LOG(LERR, "SSL Read Error :[%s]", tempBuffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (nread == 0)
|
||||
{
|
||||
LOG(LWAR, "SSL read return 0.[%zd]", nread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nread;/* ?? */
|
||||
}
|
||||
|
||||
ssize_t CSocketControl::WriteData(void *vptr, size_t n)
|
||||
{
|
||||
ssize_t nret = 0;
|
||||
|
||||
if(m_ssl)
|
||||
nret = WritenSSL(vptr, n);
|
||||
else
|
||||
nret = WriteN(vptr, n);
|
||||
|
||||
ostringstream msg;
|
||||
msg << "Socket WriteData() result.[" << nret << "]";
|
||||
LOGACONSOLE( LDBG, msg);
|
||||
|
||||
return nret;
|
||||
}
|
||||
|
||||
string CSocketControl::GetMyIPString()
|
||||
{
|
||||
string r;
|
||||
union {
|
||||
struct sockaddr s;
|
||||
struct sockaddr_in v4;
|
||||
#ifdef AF_INET6
|
||||
struct sockaddr_in6 v6;
|
||||
#endif // AF_INET6
|
||||
} u;
|
||||
|
||||
if (m_sock == SOCKET_NOT_VALID) return r;
|
||||
|
||||
|
||||
socklen_t slen = sizeof(u);
|
||||
|
||||
|
||||
if (getsockname(m_sock, &u.s, &slen) == 0)
|
||||
{
|
||||
#ifdef AF_INET6
|
||||
if (u.s.sa_family == AF_INET6)
|
||||
{
|
||||
socklen_t clientSockLen;
|
||||
char tempBuffer[INET6_ADDRSTRLEN] = {0};
|
||||
|
||||
clientSockLen = sizeof(u.v6);
|
||||
|
||||
if (inet_ntop(AF_INET6, (void *)&u.v6.sin6_addr, tempBuffer, sizeof(tempBuffer)) != NULL)
|
||||
{
|
||||
r = tempBuffer;
|
||||
}
|
||||
|
||||
|
||||
} else
|
||||
#endif // AF_INET6
|
||||
if (u.s.sa_family == AF_INET)
|
||||
{
|
||||
socklen_t clientSockLen;
|
||||
char tempBuffer[INET_ADDRSTRLEN] = {0};
|
||||
|
||||
clientSockLen = sizeof(&u.v4);
|
||||
|
||||
if (inet_ntop(AF_INET, (void *)& u.v4.sin_addr, tempBuffer, sizeof(tempBuffer)) != NULL)
|
||||
{
|
||||
r = tempBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG( LERR, "My IP String : UNKNOWN??");
|
||||
}
|
||||
}
|
||||
|
||||
LOG( LDBG, "My IP String : %s",r.c_str());
|
||||
|
||||
return r;
|
||||
}
|
||||
Reference in New Issue
Block a user