📄 net.c
字号:
int timeout;
status = krnlSendMessage( iUserObject, IMESSAGE_GETATTRIBUTE,
&timeout, CRYPT_OPTION_NET_CONNECTTIMEOUT );
if( cryptStatusOK( status ) && timeout < fixedTimeout )
krnlSendMessage( stream->iTransportSession,
IMESSAGE_SETATTRIBUTE, ( void * ) &fixedTimeout,
CRYPT_OPTION_NET_CONNECTTIMEOUT );
status = krnlSendMessage( iUserObject, IMESSAGE_GETATTRIBUTE,
&timeout, CRYPT_OPTION_NET_READTIMEOUT );
if( cryptStatusOK( status ) && timeout < fixedTimeout )
krnlSendMessage( stream->iTransportSession, IMESSAGE_SETATTRIBUTE,
( void * ) &fixedTimeout,
CRYPT_OPTION_NET_READTIMEOUT );
status = krnlSendMessage( iUserObject, IMESSAGE_GETATTRIBUTE,
&timeout, CRYPT_OPTION_NET_WRITETIMEOUT );
if( cryptStatusOK( status ) && timeout < fixedTimeout )
krnlSendMessage( stream->iTransportSession, IMESSAGE_SETATTRIBUTE,
( void * ) &fixedTimeout,
CRYPT_OPTION_NET_WRITETIMEOUT );
status = CRYPT_OK; /* Reset status from above checks */
}
/* Wait for any async network driver binding to complete and make sure
that the network interface has been initialised */
if( !krnlWaitSemaphore( SEMAPHORE_DRIVERBIND ) || \
!stream->transportOKFunction() )
{
/* Provide more information on the nature of the problem */
strcpy( errorMessage, "Networking subsystem not available" );
/* Clean up */
cleanupStream( stream, FALSE, FALSE );
return( CRYPT_ERROR_NOTINITED );
}
/* Allocate room for the I/O buffers and error messages returned from the
lower-level networking code */
if( ( stream->errorMessage = clAlloc( "completeConnect", \
MAX_ERRMSG_SIZE + 1 ) ) == NULL )
{
cleanupStream( stream, FALSE, FALSE );
return( CRYPT_ERROR_MEMORY );
}
if( useTransportBuffering )
{
if( ( stream->buffer = clAlloc( "completeConnect", \
NETWORK_BUFFER_SIZE ) ) != NULL )
{
stream->bufSize = NETWORK_BUFFER_SIZE;
if( ( stream->writeBuffer = \
clAlloc( "completeConnect", NETWORK_BUFFER_SIZE ) ) != NULL )
stream->writeBufSize = NETWORK_BUFFER_SIZE;
}
if( stream->writeBufSize <= 0 )
{
cleanupStream( stream, FALSE, TRUE );
return( CRYPT_ERROR_MEMORY );
}
}
memset( stream->errorMessage, 0, MAX_ERRMSG_SIZE + 1 );
status = openConnection( stream, options, proxyURL );
if( cryptStatusError( status ) )
{
/* Copy back the error information to the caller */
*errorCode = stream->errorCode;
strcpy( errorMessage, stream->errorMessage );
/* Clean up */
cleanupStream( stream, FALSE, TRUE );
return( status );
}
/* If we're not going through a proxy, we're done */
if( proxyURL == NULL )
return( CRYPT_OK );
/* Complete the connect via the appropriate proxy type */
return( connectViaHttpProxy( stream, errorCode, errorMessage ) );
}
/* Open and close a network connection. This parses a location string
(usually a URL) into <scheme>://<host>[:<port>]/<path>[?<query>]
components and opens a connection to the host for non-stateless
protocols */
int sNetConnect( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
const NET_CONNECT_INFO *connectInfo, char *errorMessage,
int *errorCode )
{
URL_INFO urlInfo;
char proxyUrlBuffer[ MAX_DNS_SIZE + 1 ], *proxyURL = NULL;
int status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( protocol == STREAM_PROTOCOL_TCPIP || \
protocol == STREAM_PROTOCOL_HTTP || \
protocol == STREAM_PROTOCOL_HTTP_TRANSACTION || \
protocol == STREAM_PROTOCOL_CMP );
assert( isReadPtr( connectInfo, sizeof( NET_CONNECT_INFO ) ) );
assert( errorMessage != NULL && errorCode != NULL );
assert( ( connectInfo->options != NET_OPTION_HOSTNAME && \
connectInfo->options != NET_OPTION_HOSTNAME_TUNNEL ) || \
( ( connectInfo->options == NET_OPTION_HOSTNAME || \
connectInfo->options == NET_OPTION_HOSTNAME_TUNNEL ) && \
isReadPtr( connectInfo->name, connectInfo->nameLength ) && \
connectInfo->iCryptSession == CRYPT_ERROR && \
connectInfo->networkSocket == CRYPT_ERROR ) );
assert( connectInfo->options != NET_OPTION_TRANSPORTSESSION || \
( connectInfo->options == NET_OPTION_TRANSPORTSESSION && \
connectInfo->name == NULL && connectInfo->nameLength == 0 && \
connectInfo->iCryptSession != CRYPT_ERROR && \
connectInfo->networkSocket == CRYPT_ERROR ) );
assert( ( connectInfo->options != NET_OPTION_NETWORKSOCKET && \
connectInfo->options != NET_OPTION_NETWORKSOCKET_DUMMY ) || \
( ( connectInfo->options == NET_OPTION_NETWORKSOCKET || \
connectInfo->options == NET_OPTION_NETWORKSOCKET_DUMMY ) && \
connectInfo->name == NULL && connectInfo->nameLength == 0 && \
connectInfo->iCryptSession == CRYPT_ERROR && \
connectInfo->networkSocket != CRYPT_ERROR ) );
assert( connectInfo->iUserObject >= DEFAULTUSER_OBJECT_HANDLE &&
connectInfo->iUserObject < MAX_OBJECTS );
/* Clear the return values */
*errorMessage = '\0';
*errorCode = 0;
/* Initialise the network stream info */
initStream( stream, protocol, connectInfo, FALSE );
switch( connectInfo->options )
{
case NET_OPTION_HOSTNAME:
case NET_OPTION_HOSTNAME_TUNNEL:
/* If we're using standard HTTP then only an HTTP GET is
possible, use of POST requires the HTTP_TRANSACTION variant */
if( protocol == STREAM_PROTOCOL_HTTP )
stream->flags = STREAM_FLAG_READONLY;
/* Parse the URI into its various components */
status = parseURL( &urlInfo, connectInfo->name,
connectInfo->nameLength, connectInfo->port );
if( cryptStatusError( status ) )
{
/* There's an error in the URL format, provide more
information to the caller */
strcpy( errorMessage, "Invalid host name/URL" );
return( CRYPT_ERROR_OPEN );
}
status = copyUrlToStream( stream, &urlInfo );
if( cryptStatusError( status ) )
return( status );
/* Check for the use of a proxy to establish the connection */
if( checkForProxy( stream, protocol, connectInfo,
proxyUrlBuffer ) )
proxyURL = proxyUrlBuffer;
; break;
case NET_OPTION_TRANSPORTSESSION:
stream->iTransportSession = connectInfo->iCryptSession;
break;
case NET_OPTION_NETWORKSOCKET:
case NET_OPTION_NETWORKSOCKET_DUMMY:
stream->netSocket = connectInfo->networkSocket;
stream->flags |= STREAM_NFLAG_USERSOCKET;
break;
default:
assert( NOTREACHED );
return( CRYPT_ERROR );
}
/* Set up access mechanisms and complete the connection */
return( completeConnect( stream, protocol, connectInfo->options, proxyURL,
connectInfo->iUserObject, errorMessage, errorCode ) );
}
int sNetListen( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
const NET_CONNECT_INFO *connectInfo, char *errorMessage,
int *errorCode )
{
URL_INFO urlInfo;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( protocol == STREAM_PROTOCOL_TCPIP || \
protocol == STREAM_PROTOCOL_HTTP_TRANSACTION || \
protocol == STREAM_PROTOCOL_CMP );
assert( isReadPtr( connectInfo, sizeof( NET_CONNECT_INFO ) ) );
assert( errorMessage != NULL && errorCode != NULL );
assert( connectInfo->options != NET_OPTION_HOSTNAME || \
( connectInfo->options == NET_OPTION_HOSTNAME && \
connectInfo->iCryptSession == CRYPT_ERROR && \
connectInfo->networkSocket == CRYPT_ERROR ) );
assert( connectInfo->options != NET_OPTION_TRANSPORTSESSION || \
( connectInfo->options == NET_OPTION_TRANSPORTSESSION && \
connectInfo->name == NULL && connectInfo->nameLength == 0 && \
connectInfo->iCryptSession != CRYPT_ERROR && \
connectInfo->networkSocket == CRYPT_ERROR ) );
assert( ( connectInfo->options != NET_OPTION_NETWORKSOCKET && \
connectInfo->options != NET_OPTION_NETWORKSOCKET_DUMMY ) || \
( ( connectInfo->options == NET_OPTION_NETWORKSOCKET || \
connectInfo->options == NET_OPTION_NETWORKSOCKET_DUMMY ) || \
connectInfo->name == NULL && connectInfo->nameLength == 0 && \
connectInfo->iCryptSession == CRYPT_ERROR && \
connectInfo->networkSocket != CRYPT_ERROR ) );
assert( connectInfo->iUserObject >= DEFAULTUSER_OBJECT_HANDLE &&
connectInfo->iUserObject < MAX_OBJECTS );
/* Clear the return values */
*errorMessage = '\0';
*errorCode = 0;
/* Initialise the network stream info */
initStream( stream, protocol, connectInfo, TRUE );
switch( connectInfo->options )
{
case NET_OPTION_HOSTNAME:
if( connectInfo->name != NULL )
{
int status;
/* Parse the interface URI into its various components */
status = parseURL( &urlInfo, connectInfo->name,
connectInfo->nameLength,
connectInfo->port );
if( cryptStatusError( status ) )
{
/* There's an error in the format, provide more
information to the caller */
strcpy( errorMessage, "Invalid interface name" );
return( CRYPT_ERROR_OPEN );
}
status = copyUrlToStream( stream, &urlInfo );
if( cryptStatusError( status ) )
return( status );
}
break;
case NET_OPTION_TRANSPORTSESSION:
stream->iTransportSession = connectInfo->iCryptSession;
break;
case NET_OPTION_NETWORKSOCKET:
case NET_OPTION_NETWORKSOCKET_DUMMY:
stream->netSocket = connectInfo->networkSocket;
stream->flags |= STREAM_NFLAG_USERSOCKET;
break;
default:
assert( NOTREACHED );
return( CRYPT_ERROR );
}
/* Set up access mechanisms and complete the connection */
return( completeConnect( stream, protocol, connectInfo->options, NULL,
connectInfo->iUserObject, errorMessage, errorCode ) );
}
int sNetDisconnect( STREAM *stream )
{
cleanupStream( stream, TRUE, TRUE );
return( CRYPT_OK );
}
/* Parse a URL into its various components */
int sNetParseURL( URL_INFO *urlInfo, const char *url, const int urlLen )
{
return( parseURL( urlInfo, url, urlLen, CRYPT_UNUSED ) );
}
/* Get extended information about an error status on a network connection */
void sNetGetErrorInfo( STREAM *stream, char *errorString, int *errorCode )
{
assert( isReadPtr( stream, sizeof( STREAM ) ) );
assert( stream->type == STREAM_TYPE_NETWORK );
/* Remember the error code and message. If we're running over a
cryptlib transport session we have to first pull the info up from the
session */
if( stream->iTransportSession != CRYPT_ERROR )
getSessionErrorInfo( stream, CRYPT_OK );
*errorCode = stream->errorCode;
strcpy( errorString, stream->errorMessage );
}
#else
/****************************************************************************
* *
* Network Stream Stubs *
* *
****************************************************************************/
/* If there's no networking support present, we replace the network access
routines with dummy ones that always return an error */
int sNetConnect( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
const NET_CONNECT_INFO *connectInfo, char *errorMessage,
int *errorCode )
{
memset( stream, 0, sizeof( STREAM ) );
return( CRYPT_ERROR_OPEN );
}
int sNetListen( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
const NET_CONNECT_INFO *connectInfo, char *errorMessage,
int *errorCode )
{
memset( stream, 0, sizeof( STREAM ) );
return( CRYPT_ERROR_OPEN );
}
int sNetDisconnect( STREAM *stream )
{
UNUSED( stream );
return( CRYPT_OK );
}
int sNetParseURL( URL_INFO *urlInfo, const char *url, const int urlLen )
{
memset( urlInfo, 0, sizeof( URL_INFO ) );
return( CRYPT_ERROR_BADDATA );
}
void sNetGetErrorInfo( STREAM *stream, char *errorString, int *errorCode )
{
UNUSED( stream );
*errorString = '\0';
*errorCode = CRYPT_OK;
}
#endif /* USE_TCP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -