<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="security" content="public" />
<meta name="Robots" content="index,follow" />
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
<meta name="DC.Type" content="reference" />
<meta name="DC.Title" content="Example: GSKit secure server with asynchronous data receive" />
<meta name="abstract" content="This code example can be used to establish a secure server using Global Secure ToolKit (GSKit) APIs." />
<meta name="description" content="This code example can be used to establish a secure server using Global Secure ToolKit (GSKit) APIs." />
<meta name="DC.Relation" scheme="URI" content="x1ssl.htm" />
<meta name="DC.Relation" scheme="URI" content="cgskit.htm" />
<meta name="DC.Relation" scheme="URI" content="xgskclient.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/createiocompletionport.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/users_14.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/waitforiocompletion.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/destroyiocompletionport.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/bind.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/socket.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/listen.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/close.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/accept.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_open.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_buffer.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_enum.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_init.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_open.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_numeric_value.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_init.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gskstartrecv.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/users_25.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_close.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_close.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_get_numeric_value.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_write.htm" />
<meta name="DC.Relation" scheme="URI" content="xgskasynch.htm" />
<meta name="DC.Relation" scheme="URI" content="xgskclient.htm" />
<meta name="copyright" content="(C) Copyright IBM Corporation 2001, 2006" />
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2001, 2006" />
<meta name="DC.Format" content="XHTML" />
<meta name="DC.Identifier" content="xgskserver" />
<meta name="DC.Language" content="en-us" />
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
<link rel="stylesheet" type="text/css" href="./ic.css" />
<title>Example: GSKit secure server with asynchronous data receive</title>
</head>
<body id="xgskserver"><a name="xgskserver"><!-- --></a>
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
<h1 class="topictitle1">Example: GSKit secure server with asynchronous data receive</h1>
<div><p>This code example can be used to establish a secure server using
Global Secure ToolKit (GSKit) APIs.</p>
<div class="section"><p>The server opens the socket, prepares the secure environment,
accepts and processes connection requests, exchanges data with the client
and ends the session. The client also opens a socket, sets up the secure environment,
calls the server and requests a secure connection, exchanges data with the
server, and closes the session. The following diagram and description shows
the server/client flow of events.</p>
<div class="note"><span class="notetitle">Note:</span> The following example programs
use AF_INET address family, but they can be modified to also use the AF_INET6
address family.</div>
</div>
<div class="section"><h4 class="sectiontitle">Socket flow of events: Secure server that uses asynchronous
data receive</h4><p><br /><img src="rzab6512.gif" alt="GSKit secure server that uses asynchronous data receive" /><br /></p>
</div>
<div class="section"><p>The following sequence of the socket calls provides
a description of the graphic. It also describes the relationship between the
server and client examples.</p>
</div>
<div class="section"> <ol><li>The <span class="apiname">QsoCreateIOCompletionPort()</span> function creates an
I/O completion port.</li>
<li>The <span class="apiname">pthread_create</span> function creates a worker thread
to receive data and to echo it back to the client. The worker thread waits
for client requests to arrive on the I/O completion port just created. </li>
<li>A call to <span class="apiname">gsk_environment_open()</span> to obtain a handle
to an SSL environment.</li>
<li>One or more calls to gsk_attribute_set_xxxxx() to set attributes of the
SSL environment. At a minimum, either a call to <span class="apiname">gsk_attribute_set_buffer()</span> to
set the GSK_OS400_APPLICATION_ID value or to set the GSK_KEYRING_FILE value.
 Only one of these should be set.  It is preferred that you use the GSK_OS400_APPLICATION_ID
value.    Also ensure you set the type of application (client or server),
GSK_SESSION_TYPE, using <span class="apiname">gsk_attribute_set_enum()</span>.</li>
<li>A call to <span class="apiname">gsk_environment_init()</span> to initialize  this
environment for SSL processing and to establish the SSL security information
for all SSL sessions that run using this environment.</li>
<li>The <span class="apiname">socket</span> function creates a socket descriptor. The
server then issues the standard set of socket calls: <span class="apiname">bind()</span>, <span class="apiname">listen()</span>,
and <span class="apiname">accept()</span> to enable a server to accept incoming connection
requests.</li>
<li>The <span class="apiname">gsk_secure_soc_open()</span> function obtains storage
for a secure session, sets default values for attributes, and returns a handle
that must be saved and used on secure session-related function calls. </li>
<li>One or more calls to gsk_attribute_set_xxxxx() to set attributes of the
secure session. At a minimum, a call to <span class="apiname">gsk_attribute_set_numeric_value()</span> to
associate a specific socket with this secure session.</li>
<li>A call to <span class="apiname">gsk_secure_soc_init()</span>  to initiate the SSL
handshake negotiation of the cryptographic parameters.  <div class="note"><span class="notetitle">Note:</span> Typically, a
server program must provide a certificate for an SSL handshake to succeed.
A server must also have access to the private key that is associated with
the server certificate and the key database file where the certificate is
stored. In some cases, a client must also provide a certificate during the
SSL handshake processing. This occurs if the server to which the client is
connecting has enabled client authentication. The <span class="apiname">gsk_attribute_set_buffer</span>(GSK_OS400_APPLICATION_ID)
or <span class="apiname">gsk_attribute_set_buffer</span>(GSK_KEYRING_FILE)  API calls
identify (though in  dissimilar ways) the key database file from which the
certificate and private key that are used during the handshake are obtained.</div>
 
   </li>
<li>The <span class="apiname">gsk_secure_soc_startRecv()</span> function initiates an
asynchronous receive operation on a secure session. </li>
<li>The <span class="apiname">pthread_join</span> synchronizes the server
and worker programs. This function waits for the thread to end, detaches the
thread, and then returns the threads exit status to the server.</li>
<li>The <span class="apiname">gsk_secure_soc_close()</span> function ends the secure
session.</li>
<li>The <span class="apiname">gsk_environment_close()</span> function closes the SSL
environment. </li>
<li>The <span class="apiname">close()</span> function ends the listening socket.</li>
<li>The <span class="apiname">close()</span> ends the accepted (client connection) socket.</li>
<li>The <span class="apiname">QsoDestroyIOCompletionPort()</span> function destroys
the completion port.</li>
</ol>
</div>
<div class="section"><h4 class="sectiontitle">Socket flow of events: Worker thread that uses GSKit APIs</h4><ol><li>After the server application creates a worker thread, it waits for server
to send it the incoming client request to process client data with the <span class="apiname">gsk_secure_soc_startRecv()</span> call.
The <span class="apiname">QsoWaitForIOCompletionPort()</span> function waits on the
supplied IO completion port that was specified by the server.</li>
<li>As soon as the client request has been received, the <span class="apiname">gsk_attribute_get_numeric_value()</span> function
gets the socket descriptor associated with the secure session.</li>
<li>The <span class="apiname">gsk_secure_soc_write()</span> function sends the message
to the client using the secure session.</li>
</ol>
</div>
<div class="section"><div class="note"><span class="notetitle">Note:</span> By using the code examples, you agree to the terms of the <a href="codedisclaimer.htm">Code license and disclaimer information</a>.</div>
<pre>/* GSK Asynchronous Server Program using Application Id*/

/* "IBM grants you a nonexclusive copyright license   */
/* to use all programming code examples from which    */
/* you can generate similar function tailored to your */
/* own specific needs.                                */
/*                                                    */
/* All sample code is provided by IBM for illustrative*/
/* purposes only. These examples have not been        */
/* thoroughly tested under all conditions. IBM,       */
/* therefore, cannot guarantee or imply reliability,  */
/* serviceability, or function of these programs.     */
/*                                                    */
/* All programs contained herein are provided to you  */
/* "AS IS" without any warranties of any kind. The    */
/* implied warranties of non-infringement,            */
/* merchantability and fitness for a particular       */
/* purpose are expressly disclaimed.  "               */

/* Assummes that application id is already registered */
/* and a certificate has been associated with the     */
/* application id.                                    */
/* No parameters, some comments and many hardcoded    */
/* values to keep it short and simple                 */

/* use following command to create bound program:     */
/* CRTBNDC PGM(PROG/GSKSERVa)                         */
/*         SRCFILE(PROG/CSRC)                         */
/*         SRCMBR(GSKSERVa)                           */

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;gskssl.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;errno.h&gt;
#define _MULTI_THREADED
#include "pthread.h"
#include "qsoasync.h"
#define Failure 0
#define Success 1
#define TRUE 1
#define FALSE 0

void *workerThread(void *arg);
/********************************************************************/
/* Descriptive Name: Master thread will establish a client          */
/* connection and hand processing responsibility                    */
/* to a worker thread.                                              */
/* Note: Due to the thread attribute of this program, spawn() must  */
/* be used to invoke.                                               */
/********************************************************************/
int main(void)
{
  gsk_handle my_env_handle=NULL;    /* secure environment handle */
  gsk_handle my_session_handle=NULL;    /* secure session handle */

  struct sockaddr_in address;
  int buf_len, on = 1, rc = 0;
  int sd = -1, lsd = -1, al = -1, ioCompPort = -1;
  int successFlag = FALSE;
  char buff[1024];
  pthread_t thr;
  void *status;
  Qso_OverlappedIO_t ioStruct;

  /*********************************************/
  /* Issue all of the command in a do/while    */
  /* loop so that clean up can happen at end   */
  /*********************************************/
  do
  {
    /*********************************************/
    /* Create an I/O completion port for this    */
    /* process.                        */
    /*********************************************/
    if ((ioCompPort = QsoCreateIOCompletionPort()) &lt; 0)
    {
      perror("QsoCreateIOCompletionPort() failed");
      break;
    }
    /*********************************************/
    /* Create a worker thread                    */
    /* to process all client requests. The       */
    /* worker thread will wait for client        */
    /* requests to arrive on the I/O completion  */
    /* port just created.                        */
    /*********************************************/
    rc = pthread_create(&amp;thr, NULL, workerThread, &amp;ioCompPort);
    if (rc &lt; 0)
    {
      perror("pthread_create() failed");
      break;
    }

    /* open a gsk environment */
    rc = errno = 0;
    rc = gsk_environment_open(&amp;my_env_handle);
    if (rc != GSK_OK)
    {
      printf("gsk_environment_open() failed with rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* set the Application ID to use */
    rc = errno = 0;
    rc = gsk_attribute_set_buffer(my_env_handle,
                                  GSK_OS400_APPLICATION_ID,
                                  "MY_SERVER_APP",
                                  13);
    if (rc != GSK_OK)
    {
      printf("gsk_attribute_set_buffer() failed with rc = %d &amp; errno = %d.\n"
             ,rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* set this side as the server            */
    rc = errno = 0;
    rc = gsk_attribute_set_enum(my_env_handle,
                                GSK_SESSION_TYPE,
                                GSK_SERVER_SESSION);
    if (rc != GSK_OK)
    {
      printf("gsk_attribute_set_enum() failed with rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* by default SSL_V2, SSL_V3, and TLS_V1 are enabled  */
    /* We will disable SSL_V2 for this example.           */
    rc = errno = 0;
    rc = gsk_attribute_set_enum(my_env_handle,
                                GSK_PROTOCOL_SSLV2,
                                GSK_PROTOCOL_SSLV2_OFF);
    if (rc != GSK_OK)
    {
      printf("gsk_attribute_set_enum() failed with rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* set the cipher suite to use.  By default our default list     */
    /* of ciphers is enabled.  For this example we will just use one */
    rc = errno = 0;
    rc = gsk_attribute_set_buffer(my_env_handle,
                                  GSK_V3_CIPHER_SPECS,
                                  "05", /* SSL_RSA_WITH_RC4_128_SHA */
                                  2);
    if (rc != GSK_OK)
    {
      printf("gsk_attribute_set_buffer() failed with rc = %d &amp; errno = %d.\n"
             ,rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* Initialize the secure environment */
    rc = errno = 0;
    rc = gsk_environment_init(my_env_handle);
    if (rc != GSK_OK)
    {
      printf("gsk_environment_init() failed with rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* initialize a socket to be used for listening */
    lsd = socket(AF_INET, SOCK_STREAM, 0);
    if (lsd &lt; 0)
    {
      perror("socket() failed");
      break;
    }

    /* set socket so can be reused immediately */
    rc = setsockopt(lsd, SOL_SOCKET,
                    SO_REUSEADDR,
                    (char *)&amp;on,
                    sizeof(on));
    if (rc &lt; 0)
    {
      perror("setsockopt() failed");
      break;
    }

    /* bind to the local server address */
    memset((char *) &amp;address, 0, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_port = 13333;
    address.sin_addr.s_addr = 0;
    rc = bind(lsd, (struct sockaddr *) &amp;address, sizeof(address));
    if (rc &lt; 0)
    {
      perror("bind() failed");
      break;
    }

    /* enable the socket for incoming client connections */
    listen(lsd, 5);
    if (rc &lt; 0)
    {
      perror("listen() failed");
      break;
    }

    /* accept an incoming client connection */
    al = sizeof(address);
    sd = accept(lsd, (struct sockaddr *) &amp;address, &amp;al);
    if (sd &lt; 0)
    {
      perror("accept() failed");
      break;
    }

    /* open a secure session */
    rc = errno = 0;
    rc = gsk_secure_soc_open(my_env_handle, &amp;my_session_handle);
    if (rc != GSK_OK)
    {
      printf("gsk_secure_soc_open() failed with rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* associate our socket with the secure session */
    rc=errno=0;
    rc = gsk_attribute_set_numeric_value(my_session_handle,
                                         GSK_FD,
                                         sd);
    if (rc != GSK_OK)
    {
      printf("gsk_attribute_set_numeric_value() failed with rc = %d ", rc);
      printf("and errno = %d.\n", errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /* initiate the SSL handshake */
    rc = errno = 0;
    rc = gsk_secure_soc_init(my_session_handle);
    if (rc != GSK_OK)
    {
      printf("gsk_secure_soc_init() failed with rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /*********************************************/
    /* Issue gsk_secure_soc_startRecv() to       */
    /* receive client request.                   */
    /* Note:                                     */
    /* postFlag == on denoting request should    */
    /* posted to the I/O completion port, even   */
    /* if request is immediately available.      */
    /* Worker thread will process client request.*/
    /*********************************************/
    /*********************************************/
    /* initialize Qso_OverlappedIO_t structure - */
    /* reserved fields must be hex 00's.         */
    /*********************************************/
    memset(&amp;ioStruct, '\0', sizeof(ioStruct));
    memset((char *) buff, 0, sizeof(buff));
    ioStruct.buffer = buff;
    ioStruct.bufferLength = sizeof(buff);

    /*********************************************/
    /* Store the session handle in the           */
    /* Qso_OverlappedIO_t descriptorHandle field.*/
    /* This area is used to house information    */
    /* defining the state of the client          */
    /* connection. Field descriptorHandle is     */
    /* defined as a (void *) to allow the server */
    /* to address more extensive client          */
    /* connection state if needed.               */
    /*********************************************/
    ioStruct.descriptorHandle = my_session_handle;
    ioStruct.postFlag = 1;
    ioStruct.fillBuffer = 0;

    rc = gsk_secure_soc_startRecv(my_session_handle,
                                  ioCompPort,
                                  &amp;ioStruct);
    if (rc != GSK_AS400_ASYNCHRONOUS_RECV)
    {
      printf("gsk_secure_soc_startRecv() rc = %d &amp; errno = %d.\n",rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      break;
    }

    /*********************************************/
    /* This is where the server can loop back  */
    /* to accept a new connection.               */
    /*********************************************/

    /*********************************************/
    /* Wait for worker thread to finish          */
    /* processing client connection.             */
    /*********************************************/
    rc = pthread_join(thr, &amp;status);


    /* check status of the worker */
    if ( rc == 0 &amp;&amp; (rc = __INT(status)) == Success)
    {
      printf("Success.\n");
      successFlag = TRUE;
    }
    else
    {
      perror("pthread_join() reported failure");
    }
  } while(FALSE);

  /* disable the SSL session */
  if (my_session_handle != NULL)
    gsk_secure_soc_close(&amp;my_session_handle);

  /* disable the SSL environment */
  if (my_env_handle != NULL)
    gsk_environment_close(&amp;my_env_handle);

  /* close the listening socket */
  if (lsd &gt; -1)
    close(lsd);
  /* close the accepted socket */
  if (sd &gt; -1)
    close(sd);

  /* destroy the completion port */
  if (ioCompPort &gt; -1)
    QsoDestroyIOCompletionPort(ioCompPort);

  if (successFlag)
    exit(0);
  else
    exit(-1);
}


/********************************************************************/
/* Function Name: workerThread                                      */
/*                                                                  */
/* Descriptive Name: Process client connection.                     */
/*                                                                  */
/* Note:  To make the sample more straight forward the main routine */
/*        handles all of the clean up although this function can  */
/*        be made responsible for the clientfd and session_handle.  */
/********************************************************************/
void *workerThread(void *arg)
{
    struct timeval waitTime;
    int ioCompPort = -1, clientfd = -1;
    Qso_OverlappedIO_t ioStruct;
    int rc, tID;
    int amtWritten;
    gsk_handle client_session_handle = NULL;
    pthread_t thr;
    pthread_id_np_t t_id;
    t_id = pthread_getthreadid_np();
    tID = t_id.intId.lo;
    /*********************************************/
    /* I/O completion port is passed to this */
    /* routine. */
    /*********************************************/
    ioCompPort = *(int *)arg;
    /*********************************************/
    /* Wait on the supplied I/O completion port */
    /* for a client request. */
    /*********************************************/
    waitTime.tv_sec = 500;
    waitTime.tv_usec = 0;
    rc = QsoWaitForIOCompletion(ioCompPort, &amp;ioStruct, &amp;waitTime);
    if ((rc == 1) &amp;&amp;
        (ioStruct.returnValue == GSK_OK) &amp;&amp;
        (ioStruct.operationCompleted == GSKSECURESOCSTARTRECV))
    /*********************************************/
    /* Client request has been received. */
    /*********************************************/
    ;
    else
    {
      perror("QsoWaitForIOCompletion()/gsk_secure_soc_startRecv() failed");
      printf("ioStruct.returnValue = %d.\n", ioStruct.returnValue);
      return __VOID(Failure);
    }

    /* write results to screen */
    printf("gsk_secure_soc_startRecv() received %d bytes, here they are:\n",
           ioStruct.secureDataTransferSize);
    printf("%s\n",ioStruct.buffer);

    /*********************************************/
    /* Obtain the session handle associated      */
    /* with the client connection.               */
    /*********************************************/
    client_session_handle = ioStruct.descriptorHandle;

    /* get the socket associated with the secure session */
    rc=errno=0;
    rc = gsk_attribute_get_numeric_value(client_session_handle,
                                         GSK_FD,
                                         &amp;clientfd);
    if (rc != GSK_OK)
    {
      printf("gsk_attribute_get_numeric_value() rc = %d &amp; errno = %d.\n",
             rc,errno);
      printf("rc of %d means %s\n", rc, gsk_strerror(rc));
      return __VOID(Failure);
    }

    /* send the message to the client using the secure session */
    amtWritten = 0;
    rc = gsk_secure_soc_write(client_session_handle,
                              ioStruct.buffer,
                              ioStruct.secureDataTransferSize,
                              &amp;amtWritten);
    if (amtWritten != ioStruct.secureDataTransferSize)
    {
      if (rc != GSK_OK)
      {
        printf("gsk_secure_soc_write() rc = %d and errno = %d.\n",
               rc,errno);
        printf("rc of %d means %s\n", rc, gsk_strerror(rc));
        return __VOID(Failure);
      }
      else
      {
        printf("gsk_secure_soc_write() did not write all data.\n");
        return __VOID(Failure);
      }
    }

    /* write results to screen */
    printf("gsk_secure_soc_write() wrote %d bytes...\n", amtWritten);
    printf("%s\n",ioStruct.buffer);

    return __VOID(Success);
} /* end workerThread */</pre>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="x1ssl.htm" title="You can create secure server and clients using either the Global Secure ToolKit (GSKit) APIs or the Secure Sockets Layer (SSL_) APIs.">Examples: Establish secure connections</a></div>
</div>
<div class="relconcepts"><strong>Related concepts</strong><br />
<div><a href="cgskit.htm" title="Global Secure ToolKit (GSKit) is a set of programmable interfaces that allow an application to be SSL enabled.">Global Secure ToolKit (GSKit) APIs</a></div>
</div>
<div class="relref"><strong>Related reference</strong><br />
<div><a href="xgskclient.htm" title="This code sample provides an example of a client that uses the GSKit APIs.">Example: Establish a secure client with Global Secure ToolKit (GSKit) APIs</a></div>
<div><a href="xgskasynch.htm" title="The gsk_secure_soc_startInit() API allows you to create secure server applications that can handle request asynchronously.">Example: GSKit secure server with asynchronous handshake</a></div>
</div>
<div class="relinfo"><strong>Related information</strong><br />
<div><a href="../apis/createiocompletionport.htm">QsoCreateIOCompletionPort()</a></div>
<div><a href="../apis/users_14.htm">pthread_create</a></div>
<div><a href="../apis/waitforiocompletion.htm">QsoWaitForIoCompletionPort()</a></div>
<div><a href="../apis/destroyiocompletionport.htm">QsoDestroyIOCompletionPort()</a></div>
<div><a href="../apis/bind.htm">bind()</a></div>
<div><a href="../apis/socket.htm">socket()</a></div>
<div><a href="../apis/listen.htm">listen()</a></div>
<div><a href="../apis/close.htm">close()</a></div>
<div><a href="../apis/accept.htm">accept()</a></div>
<div><a href="../apis/gsk_environment_open.htm">gsk_environment_open()</a></div>
<div><a href="../apis/gsk_attribute_set_buffer.htm">gsk_attribute_set_buffer</a></div>
<div><a href="../apis/gsk_attribute_set_enum.htm">gsk_attribute_set_enum()</a></div>
<div><a href="../apis/gsk_environment_init.htm">gsk_environment_init()</a></div>
<div><a href="../apis/gsk_secure_soc_open.htm">gsk_secure_soc_open()</a></div>
<div><a href="../apis/gsk_attribute_set_numeric_value.htm">gsk_attribute_set_numeric_value()</a></div>
<div><a href="../apis/gsk_secure_soc_init.htm">gsk_secure_soc_init()</a></div>
<div><a href="../apis/gskstartrecv.htm">gsk_secure_soc_startRecv()</a></div>
<div><a href="../apis/users_25.htm">pthread_join</a></div>
<div><a href="../apis/gsk_secure_soc_close.htm">gsk_secure_soc_close()</a></div>
<div><a href="../apis/gsk_environment_close.htm">gsk_environment_close()</a></div>
<div><a href="../apis/gsk_attribute_get_numeric_value.htm">gsk_attribute_get_numeric_value()</a></div>
<div><a href="../apis/gsk_secure_soc_write.htm">gsk_secure_soc_write()</a></div>
</div>
</div>
</body>
</html>