mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
6.4 KiB
271 lines
6.4 KiB
/******************************************************************************
|
|
**
|
|
** socket.c
|
|
**
|
|
** This file is part of the ABYSS Web server project.
|
|
**
|
|
** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.
|
|
** All rights reserved.
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions
|
|
** are met:
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
** notice, this list of conditions and the following disclaimer.
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
** documentation and/or other materials provided with the distribution.
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
** derived from this software without specific prior written permission.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
** SUCH DAMAGE.
|
|
**
|
|
*******************************************************************************/
|
|
|
|
/*============================================================================
|
|
socket.c
|
|
==============================================================================
|
|
Implementation of TSocket class: A generic socket over which one can
|
|
transport an HTTP stream or manage HTTP connections
|
|
============================================================================*/
|
|
|
|
#include <sys/types.h>
|
|
#include <assert.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "abyss_mallocvar.h"
|
|
#include "abyss_xmlrpc_int.h"
|
|
#include <xmlrpc-c/abyss.h>
|
|
#ifdef WIN32
|
|
#include "socket_win.h"
|
|
#else
|
|
#include "abyss_socket_unix.h"
|
|
#endif
|
|
#include "abyss_socket.h"
|
|
|
|
|
|
#ifdef WIN32
|
|
#include "socket_win.h"
|
|
#else
|
|
#include "abyss_socket_unix.h"
|
|
#endif
|
|
|
|
#include "abyss_socket.h"
|
|
|
|
|
|
static void
|
|
socketOsInit(abyss_bool * const succeededP) {
|
|
|
|
#ifdef WIN32
|
|
SocketWinInit(succeededP);
|
|
#else
|
|
SocketUnixInit(succeededP);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
socketOsTerm(void) {
|
|
|
|
#ifdef WIN32
|
|
SocketWinTerm();
|
|
#else
|
|
SocketUnixTerm();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
abyss_bool SocketTraceIsActive;
|
|
|
|
abyss_bool
|
|
SocketInit(void) {
|
|
abyss_bool retval;
|
|
|
|
socketOsInit(&retval);
|
|
|
|
SocketTraceIsActive = (getenv("ABYSS_TRACE_SOCKET") != NULL);
|
|
if (SocketTraceIsActive)
|
|
fprintf(stderr, "Abyss socket layer will trace socket traffic "
|
|
"due to ABYSS_TRACE_SOCKET environment variable\n");
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SocketTerm(void) {
|
|
|
|
socketOsTerm();
|
|
}
|
|
|
|
|
|
|
|
/* SocketCreate() is not exported to the Abyss user. It is meant to
|
|
be used by an implementation-specific TSocket generator which is
|
|
exported to the Abyss user, e.g. SocketCreateUnix() in
|
|
socket_unix.c
|
|
|
|
The TSocket generator functions are the _only_ user-accessible
|
|
functions that are particular to an implementation.
|
|
*/
|
|
|
|
static uint const socketSignature = 0x060609;
|
|
|
|
void
|
|
SocketCreate(const struct TSocketVtbl * const vtblP,
|
|
void * const implP,
|
|
TSocket ** const socketPP) {
|
|
|
|
TSocket * socketP;
|
|
|
|
MALLOCVAR(socketP);
|
|
|
|
if (socketP) {
|
|
socketP->implP = implP;
|
|
socketP->vtbl = *vtblP;
|
|
socketP->signature = socketSignature;
|
|
*socketPP = socketP;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SocketClose(TSocket * const socketP) {
|
|
socketP->vtbl.close(socketP);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SocketDestroy(TSocket * const socketP) {
|
|
|
|
assert(socketP->signature == socketSignature);
|
|
|
|
socketP->vtbl.destroy(socketP);
|
|
|
|
socketP->signature = 0; /* For debuggability */
|
|
|
|
free(socketP);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SocketWrite(TSocket * const socketP,
|
|
const unsigned char * const buffer,
|
|
uint32_t const len,
|
|
abyss_bool * const failedP) {
|
|
|
|
(*socketP->vtbl.write)(socketP, buffer, len, failedP );
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
SocketRead(TSocket * const socketP,
|
|
unsigned char * const buffer,
|
|
uint32_t const len) {
|
|
|
|
return (*socketP->vtbl.read)(socketP, (char*)buffer, len);
|
|
}
|
|
|
|
|
|
|
|
abyss_bool
|
|
SocketConnect(TSocket * const socketP,
|
|
TIPAddr * const addrP,
|
|
uint16_t const portNumber) {
|
|
|
|
return (*socketP->vtbl.connect)(socketP, addrP, portNumber);
|
|
}
|
|
|
|
|
|
|
|
abyss_bool
|
|
SocketBind(TSocket * const socketP,
|
|
TIPAddr * const addrP,
|
|
uint16_t const portNumber) {
|
|
|
|
return (*socketP->vtbl.bind)(socketP, addrP, portNumber);
|
|
}
|
|
|
|
|
|
|
|
abyss_bool
|
|
SocketListen(TSocket * const socketP,
|
|
uint32_t const backlog) {
|
|
|
|
return (*socketP->vtbl.listen)(socketP, backlog);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SocketAccept(TSocket * const listenSocketP,
|
|
abyss_bool * const connectedP,
|
|
abyss_bool * const failedP,
|
|
TSocket ** const acceptedSocketPP,
|
|
TIPAddr * const ipAddrP) {
|
|
|
|
(*listenSocketP->vtbl.accept)(listenSocketP,
|
|
connectedP,
|
|
failedP,
|
|
acceptedSocketPP,
|
|
ipAddrP);
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
SocketWait(TSocket * const socketP,
|
|
abyss_bool const rd,
|
|
abyss_bool const wr,
|
|
uint32_t const timems) {
|
|
|
|
return (*socketP->vtbl.wait)(socketP, rd, wr, timems);
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
SocketAvailableReadBytes(TSocket * const socketP) {
|
|
|
|
return (*socketP->vtbl.availableReadBytes)(socketP);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SocketGetPeerName(TSocket * const socketP,
|
|
TIPAddr * const ipAddrP,
|
|
uint16_t * const portNumberP,
|
|
abyss_bool * const successP) {
|
|
|
|
(*socketP->vtbl.getPeerName)(socketP, ipAddrP, portNumberP, successP);
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
SocketError(TSocket * const socketP) {
|
|
|
|
return (*socketP->vtbl.error)(socketP);
|
|
}
|