...

struct thread_func_args
{
 CTCPComm_Process pThis;
 unsigned int arg;
 
 thread_func_args (CTCPComm_Process t,unsigned int p)
  : pThis(t),arg(p){}
};

unsigned int socket_array[MAX_SOCKET];

...

 ....
 
 CTCPComm_Process tcp_proc;
 tcp_proc.m_nLsnSocketHandle=&m_nLsnSocketHandle;

 #ifndef WIN32
   pthread_mutex_lock(&mutex);
   socket_array[nConnection_Count++]=client_sockfd; //client_sockfd는 소켓통신시  accept로 받은 소켓 핸들 값 이게 뒤에 인자로 전달...

   thread_func_args pthread_args(tcp_proc,socket_array[nConnection_Count-1]);
   LOG4CPLUS_INFO(logger,"Current Thread Cnt " << socket_array[nConnection_Count-1]);
   pthread_mutex_unlock(&mutex);
 #endif
 

 LOG4CPLUS_INFO(logger,"Current Thread Cnt " << pthread_args.arg);
 status = pthread_create(&hThread,
                NULL,
      &CTCPComm::ValidateData_Client,
                &pthread_args);
                   
 if (status!=0){
     LOG4CPLUS_ERROR(logger, "CTCPComm::Client pthread_create 실패 nRtnValue = " << status);
     close(client_sockfd);  
     client_sockfd=-1;
 }
 pthread_detach( hThread ); //이걸 안하면 메모리 릭이 발생함
 
   ...




/*ValidateData_Client ==> static이어야 한다.*/
void* CTCPComm::ValidateData_Client(void* Parameter)
#endif
{

  thread_func_args* tf_args=static_cast<thread_func_args*>(Parameter);
  CTCPComm_Process pLocalThis=tf_args->pThis;
    
   pLocalThis.ValidateCall(tf_args->arg);

  delete tf_args;
  pthread_exit((void *)NULL);
  
}

AND

 
int stat=0;
 SSL_CTX* ctx;
    SSL*     ssl;
    X509*    server_cert;
 SSL_METHOD *meth;


 CTCPComm TCPComm;
 ByteString ip;
 int port;
 IPPortParsing(bsData,ip,port);
 stat=TCPComm.Connect((char*)ip,port);
 //stat=TCPComm.Connect("10.10.10.21",110);
 if (stat!=0) return -1;

 SSLeay_add_ssl_algorithms();
    //meth = SSLv2_client_method();
    meth = TLSv1_client_method();
    SSL_load_error_strings();
    ctx = SSL_CTX_new (meth);


 ssl = SSL_new (ctx);    
    //CHK_NULL(ssl);    

    // connect the SSL object with a file descriptor
    SSL_set_fd (ssl, TCPComm.m_nSocketHandle);

    // initiate the TLS/SSL handshake with an TLS/SSL server
    stat = SSL_connect (ssl);    
    //CHK_SSL(err);

    /* 
     * Following two steps are optional and not required for
     * data exchange to be successful. 
     */

    printf ("SSL connection using %s\n", SSL_get_cipher (ssl));

    // Get server's certificate (note: beware of dynamic allocation) - opt 
    server_cert = SSL_get_peer_certificate (ssl);    
    //CHK_NULL(server_cert);
    //print_x509(ssl);

    /*
    printf ("Server certificate:\n");
    str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
    CHK_NULL(str);
    printf ("\t subject: %s\n", str);
    free (str);

    str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
    CHK_NULL(str);
    printf ("\t issuer: %s\n", str);
    free (str);
    */

    /* 
     * We could do all sorts of certificate verification stuff here before
     * deallocating the certificate. 
     */
    X509_free (server_cert);

    ///////////////////////////////////////////////////////////////////////////////////////
    // DATA EXCHANGE - Send a message and receive a reply.
   
 ByteString temp;
 int idx=0;
 idx=bsData.find("$");
 if (idx<0 || idx>16) temp=bsData;
 else temp.setBuffer(bsData.getBuffer()+idx+1,bsData.getLength()-idx-1);

 bsData=temp;
    //err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));
 ByteString bsDataLast;
 //bsDataLast=bsData.getLength()+"$"+bsDataLast);
 
 //ByteString bsResult;
 //DSBase::base64Encode(bsData,&bsResult);

 bsDataLast.format2K("%d",bsData.getLength());
 bsDataLast+="$";
 bsDataLast+=bsData;
 //bsDataLast.format2K("%d$%uc",bsData.getLength(),bsData.getBuffer());
    //CHK_SSL(err);
 
 stat = SSL_write (ssl, bsDataLast.getBuffer(), bsDataLast.getLength());  
   // CHK_SSL(err);

    /*err = SSL_read (ssl, buf, sizeof(buf) - 1);    
    CHK_SSL(err);
    buf[err] = '\0';
    printf ("Got %d chars:'%s'\n", err, buf);*/

    // send SSL/TLS close_notify
    SSL_shutdown (ssl);  

    /* Clean up. */

    TCPComm.Close();
    SSL_free (ssl);
    SSL_CTX_free (ctx);

AND


SSL_CTX* ctx;
    SSL*     ssl;
    X509*    client_cert;

    char*    str;
 unsigned char  buf[100000]={0x00,};
 //memset(buf,0x00,100000);
 
 int stat=0;

    SSL_METHOD *meth;

 SOCKET client = (SOCKET)Parameter;

    /* SSL preliminaries. We keep the certificate and key with the context. */
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();
    meth = TLSv1_server_method();

    // create a new SSL_CTX object as framework for TLS/SSL enabled functions
    ctx = SSL_CTX_new (meth);
    if (!ctx) {
        ERR_print_errors_fp(stderr);
  return 0;
        //exit(2);
    }

    if (SSL_CTX_use_certificate_file(ctx, "./stunnel.pem", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
  return 0;
        //exit(3);
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, "./stunnel.pem", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
  return 0;
        //exit(4);
    }
    if (!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr,"Private key does not match the certificate public key\n");
  return 0;
        //exit(5);
    }

 
 
 

 ssl = SSL_new (ctx);                    
    //CHK_NULL(ssl);

    // connect the SSL object with a file descriptor
    SSL_set_fd (ssl, client);
    stat = SSL_accept (ssl);   
    //CHK_SSL(err);

    // Get the cipher - opt 
    printf ("SSL connection using %s\n", SSL_get_cipher (ssl));

    // Get client's certificate (note: beware of dynamic allocation) - opt
    client_cert = SSL_get_peer_certificate (ssl);
    if (client_cert != NULL) 
    {
        printf ("Client certificate:\n");

        str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
        //CHK_NULL(str);
        printf ("\t subject: %s\n", str);
        free (str);

        str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
        //CHK_NULL(str);
        printf ("\t issuer: %s\n", str);
        free (str);

        /* We could do all sorts of certificate verification stuff here before
           deallocating the certificate. */

        X509_free (client_cert);
    } 
    else
    {
        printf ("Client does not have certificate.\n");
    }
 int size=0;
 
    // DATA EXCHANGE - Receive message and send reply.
    stat = SSL_read (ssl, buf, sizeof(buf));
 int i=0;
 for(i=0;i<sizeof(buf);i++){
  if (buf[i]=='$') break;
 }
 
 char* buf1=new char[i-1];
 memset(buf1,0x00,sizeof(buf1));
 for (int j=0;j<=i-1;j++){
  buf1[j]=buf[j];
 }
    //CHK_SSL(err);
 size+=atoi((char*)buf1);
 buf1=0x00;
  

//    stat = SSL_write (ssl, "I hear you.", strlen("I hear you."));
    //CHK_SSL(err);
 
    /* Clean up. */
 closesocket(client);
 client = 0;
    //close (client);
    SSL_free (ssl);
    SSL_CTX_free (ctx);
 CTCPComm TCPComm;
 
 stat=TCPComm.Connect(gServerConfig.m_bsSVRDestIP,gServerConfig.m_nSVRDestPort);
 ByteString bsMsg;
 bsMsg.setBuffer(buf+i+1, size);

 //bsMsg=(char*)buf;
 /*std::string strMsg((char*)bsMsg);
 //str=(char*)bsMsg;
 size_t nSize = 0;
 std::string find_token="\\r\\n";
    while ((nSize = strMsg.find(find_token)) != std::string::npos)
       strMsg.replace(nSize, find_token.size(), "");
 
 ByteString bsResult((char*) strMsg.c_str());*/
 stat=TCPComm.Send(bsMsg);
 
 //UFilePlus::save("bsMsg.acr",bsMsg);
 TCPComm.Close();
 //Get the data form client
 //rVal = recv(client,buf,10000,0);
 //here we are performing simple check, the data came form client
 //is valid or not
 //at this point you can check your own data also, which needs some modification
 /*if(strcmp(buf,"Data On Socket"))
 {
  //Send back the data to the client
  //rVal = send(client,"YES",3,0);
 }
 else
 {
  //Send back the data to the client
  //rVal = send(client,"NO",2,0);
 }*/
 buf1=0x00;
 

AND


windows에서 설치하기. 다음의 파일을 참조. 아래에 설명 보충.



1. perl 설치
http://www.activestate.com/Products/ActivePerl/ 에서 activestate perl을 download한다.
특별한 이유가 없는 한 MSI 패키지를 download한다.
msi 파일은 더블클릭하면 설치가 시작된다. 특별히 건드릴 일은 없으니 default setting으로 설치.

2. compiler
windows에 cygwin이나 borland c 등을 설치해서 쓸 정도의 사람은 아마도 여기의 설명이
필요 없을 것이니, visuall c++을 사용한다고 가정한다. 설명서에도 나와 있다시피
MS의 MASM이라는 assembler가 아마도 visuall c++에 기본으로 포함돼 있을 것이다.

MASM이 없는 경우(ml.exe가 없는 경우) more...를 참조.

more..


암호 관련 라이브러리들은 대부분 극한의 속도를 목적으로 하기 때문에 assembler를 이용한
빠른 코드를 당근 사용해주는 게 좋겠다.

3. configure
1번의 perl 설치는 사실 configure script를 실행하기 위한 용도이다.
cmd창을 띄워서 다음과 같이 실행한다. (시작->실행->cmd.exe)

> cd <현재 소스 루트>
> perl Configure VC-WIN32 --prefix=D:/project/lib/ssl (반드시 \아닌 /로 해야됨)
사용자 삽입 이미지

이런 식으로 된다. prefix는 openssl library와 header file들이 설치될 위치이다.
다음으로 실제 compile할 때 사용될 Makefile과 assembly code들을 만든다.
위에서 MASM을 사용하기로 했으니 ms\do_masm을 실행한다.
사용자 삽입 이미지

원래의 설명서에 보면 VC++ environment에서 다음을 진행하라고 되어 있는데,
VC++의 명령행 프롬프트는 다음과 같이 띄운다.
사용자 삽입 이미지
사용하는 visual studio의 버젼에 따라서 조금 다를 수는 있다. VC++ 6.0 같은 경우는
일단 cmd 창을 띄운 후(시작->실행->cmd.exe)에 vcvars32.bat 를 실행하면 된다.
이제 library를 build한다.
사용자 삽입 이미지

그런데 visual studio 2005를 사용하는 경우는 cp949에서 특정 문자를 표시할 수 없다는
에러가 나온다. 그럴 경우는 아래 more... 를 참조. 그런 에러가 안 난다면 상관 없다.

less..

이것은 유니코드 어쩌구 저쩌구 하는 말이 나오는데 해당 파일을 code 949로
읽도록 돼 있으나 실제 파일에는 다룰 수 없는 유니코드 문자가 포함돼 있기 때문에 그런다.
사용자 삽입 이미지
유럽사람 이름이다. -.-;; 아마 umlaut 문자일 가능성이 높다.
해결하는 방법은 일단 두가지를 생각해 볼 수 있는데, 첫번째는 무식하지만 쉬운 방법이고,
두번째는 깔끔하지만 익숙하지 않은 사람은 찾기 힘든 방법이다. 그런데 방법을 찾아놨으니
그냥 쓰면 되겠다.

첫번째는 저런 에러가 나는 파일들을 모두 열어서 해당 라인을 삭제해 주면 된다. 또는
해당 파일을 unicode가 들어가지 않도록 저장할 수도 있다. 어느 방법이나, 소스코드에서
다룰 수 없는 유니코드를 없애는 방법이다. 문제가 되는 모든 파일을 건드려야 하니 무식한
방법이다.

두번째는 compiler에 옵션을 하나 주어서 해당 경고를 무시하도록 하는 것이다.
사용자 삽입 이미지

에러는 위와 같은데 C2220은 모든 경고를 오류로 간주해서 컴파일을 멈추도록 하는 것이기 때문에
실제 원인은 C4819이다. cl.exe 명령어의 명령행 옵션을 찾아보면 특정 경고를 무시하도록 하는
것이 있다. /wd<n> 옵션을 사용하는 것이다. 참고로 해당 도움말은
> cl.exe /?
로 볼 수 있다.
사용자 삽입 이미지

ms 디렉토리의 ntdll.mak 파일을 텍스트 에디터로 연다. (notepad로 열면 이상하게 보일 거다.
wordpad로 열든가. vim 같은 좋은 에디터를 쓰자. ^^) CFLAG 변수를 지정하는 부분을 찾아서
/wd4819 라는 옵션을 추가해서 소스 코드의 유니코드 관련한 경고를 무시하도록 고친다.
사용자 삽입 이미지

less..


컴파일이 정상적으로 끝났으면 이제 위에서 prefix로 정한 위치에 install을 해야 하는데
그전에 nmake test 를 통해서 library가 잘 만들어졌는지 확인해 볼 수 있다. 하지만 꼭 필요한
것은 아니고, 만족감을 얻고 싶거나, 정말 제대로 만들어졌는지 확인해 봐야 할 경우에만 한다.
마지막에 passed all tests라고 나오면 된다.
> nmake -f ms\ntdll.mak test

이제 install을 한다.
> nmake -f ms\ntdll.mak install
사용자 삽입 이미지
위와 같이 prefix로 정한 위치에 저런 디렉토리들이 만들어졌고 bin 디렉토리에
libeay32.dll, ssleay32.dll, openssl.exe 같은 파일들이 만들어졌는지 확인한다.
또 include\ssl 디렉토리에 각종 헤더파일들이 역시 존재하는지도 확인한다.

모두 다 제대로 들어 있다면 install은 ok.
AND


openssl 컴파일 및 설치를 위해선 active perl이 필요하다
http://www.activestate.com/activeperl/



2. the short way, using standard vs2005
create a new win32 project. make it an empty project!
now add almost all the files from the project:
which files to exclude?
env.c
nogui.c
pty.c

add includes and libs of ssl (C:\openssl\0.9.8j\include, C:\openssl\0.9.8j\lib)
add defines: USE_WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;VERSION="4.26"
that's more or less all
look in the mak file for additional stuff.
you may have to replace the VERSION with "4.26"....

라이브러리 참조 => libeay32.lib ssleay32.lib Ws2_32.lib
AND