fis-gtm/sr_port/iosocket_bind.c

176 lines
5.5 KiB
C
Raw Normal View History

/****************************************************************
* *
* Copyright 2001, 2009 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
/* iosocket_bind.c */
#include "mdef.h"
#include <errno.h>
#include "gtm_time.h"
#include "gtm_socket.h"
#include "gtm_inet.h"
#include <netinet/tcp.h>
#include "gtm_stdio.h"
#include "gtm_string.h"
#include "gt_timer.h"
#include "io.h"
#include "iotimer.h"
#include "iotcpdef.h"
#include "iosocketdef.h"
#include "iotcproutine.h"
#define BOUND "BOUND"
GBLREF tcp_library_struct tcp_routines;
boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update_bufsiz)
{
int temp_1 = 1;
char *errptr;
int4 errlen, msec_timeout, real_errno;
short len;
in_port_t actual_port;
boolean_t no_time_left = FALSE;
d_socket_struct *dsocketptr;
ABS_TIME cur_time, end_time;
GTM_SOCKLEN_TYPE addrlen;
GTM_SOCKLEN_TYPE sockbuflen;
error_def(ERR_SOCKINIT);
error_def(ERR_GETSOCKOPTERR);
error_def(ERR_SETSOCKOPTERR);
error_def(ERR_GETSOCKNAMERR);
dsocketptr = socketptr->dev;
assert(NULL != dsocketptr);
dsocketptr->dollar_key[0] = '\0';
if (timepar != NO_M_TIMEOUT)
{
msec_timeout = timeout2msec(timepar);
sys_get_curr_time(&cur_time);
add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
}
do
{
if (1 != temp_1)
tcp_routines.aa_close(socketptr->sd);
if (-1 == (socketptr->sd = tcp_routines.aa_socket(AF_INET, SOCK_STREAM, 0)))
{
real_errno = errno;
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(5) ERR_SOCKINIT, 3, real_errno, errlen, errptr);
return FALSE;
}
temp_1 = 1;
if (-1 == tcp_routines.aa_setsockopt(socketptr->sd,
SOL_SOCKET, SO_REUSEADDR, &temp_1, SIZEOF(temp_1)))
{
real_errno = errno;
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
RTS_ERROR_LITERAL("SO_REUSEADDR"), real_errno, errlen, errptr);
return FALSE;
}
#ifdef TCP_NODELAY
temp_1 = socketptr->nodelay ? 1 : 0;
if (-1 == tcp_routines.aa_setsockopt(socketptr->sd,
IPPROTO_TCP, TCP_NODELAY, &temp_1, SIZEOF(temp_1)))
{
real_errno = errno;
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
RTS_ERROR_LITERAL("TCP_NODELAY"), real_errno, errlen, errptr);
return FALSE;
}
#endif
if (update_bufsiz)
{
if (-1 == tcp_routines.aa_setsockopt(socketptr->sd,
SOL_SOCKET, SO_RCVBUF, &socketptr->bufsiz, SIZEOF(socketptr->bufsiz)))
{
real_errno = errno;
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
RTS_ERROR_LITERAL("SO_RCVBUF"), real_errno, errlen, errptr);
return FALSE;
}
} else
{
sockbuflen = SIZEOF(socketptr->bufsiz);
if (-1 == tcp_routines.aa_getsockopt(socketptr->sd,
SOL_SOCKET, SO_RCVBUF, &socketptr->bufsiz, &sockbuflen))
{
real_errno = errno;
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(7) ERR_GETSOCKOPTERR, 5,
RTS_ERROR_LITERAL("SO_RCVBUF"), real_errno, errlen, errptr);
return FALSE;
}
}
temp_1 = tcp_routines.aa_bind(socketptr->sd,
(struct sockaddr *)&socketptr->local.sin, SIZEOF(struct sockaddr));
if (temp_1 < 0)
{
real_errno = errno;
no_time_left = TRUE;
switch (real_errno)
{
case EADDRINUSE:
if (NO_M_TIMEOUT != timepar)
{
sys_get_curr_time(&cur_time);
cur_time = sub_abs_time(&end_time, &cur_time);
if (cur_time.at_sec > 0)
no_time_left = FALSE;
}
break;
case EINTR:
break;
default:
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(5) ERR_SOCKINIT, 3, real_errno, errlen, errptr);
break;
}
if (no_time_left)
return FALSE;
hiber_start(100);
}
} while (temp_1 < 0);
addrlen = SIZEOF(socketptr->local.sin);
if (-1 == tcp_routines.aa_getsockname(socketptr->sd, (struct sockaddr *)&socketptr->local.sin, &addrlen))
{
real_errno = errno;
errptr = (char *)STRERROR(real_errno);
errlen = STRLEN(errptr);
rts_error(VARLSTCNT(5) ERR_GETSOCKNAMERR, 3, real_errno, errlen, errptr);
return FALSE;
}
actual_port = GTM_NTOHS(socketptr->local.sin.sin_port);
if (0 == socketptr->local.port)
socketptr->local.port = actual_port;
assert(socketptr->local.port == actual_port);
socketptr->state = socket_bound;
len = SIZEOF(BOUND) - 1;
memcpy(&dsocketptr->dollar_key[0], BOUND, len);
dsocketptr->dollar_key[len++] = '|';
memcpy(&dsocketptr->dollar_key[len], socketptr->handle, socketptr->handle_len);
len += socketptr->handle_len;
dsocketptr->dollar_key[len++] = '|';
SPRINTF(&dsocketptr->dollar_key[len], "%d", socketptr->local.port);
return TRUE;
}