#include <stdlib.h>#include <errno.h>#include "portability.h"#include "utility.h"#include "proxylib.h"
Go to the source code of this file.
Defines | |
| #define | INADDR_NONE ((unsigned int) 0xffffffff) |
| #define | MAXLEN 256 |
Functions | |
| int | proxy_get_fd_limit () |
| void | proxy_get_id (char *cp) |
| void | proxy_print_local_info () |
| void | proxy_print_componentID (FILE *f, char *id) |
| PROXY_COMPONENTADDR | proxy_get_local_addr () |
| ipaddr_t | proxy_get_proxy_ip () |
| int | proxy_set_cid_from_str (char *id) |
| in_port_t | proxy_get_proxy_port () |
| SOCKET | proxy_socket (int domain, int type, int protocol) |
| int | proxy_bind (SOCKET s, const struct sockaddr *name, int namelen) |
| int | proxy_getsockname (int s, struct sockaddr *name, socklen_t *namelen) |
| int | proxy_listen (SOCKET s, int backlog) |
| int | proxy_accept_x (SOCKET s, struct sockaddr *addr, socklen_t *addrlen) |
| int | proxy_accept (SOCKET s, struct sockaddr *addr, socklen_t *addrlen) |
| int | proxy_connect (SOCKET s, PROXY_COMPONENTADDR *name) |
| int | proxy_connect_nonb (SOCKET sockfd, const struct sockaddr *saptr, socklen_t salen, int nsec) |
| int | proxy_ip_to_str (ipaddr_t IP, char *dottedIP) |
| int | proxy_str_to_ip (ipaddr_t *IP, char *dottedIP) |
| int | proxy_do_auth (ipaddr_t proxy_ip, SOCKET s) |
| int | proxy_close (SOCKET fildes) |
| void | proxy_init (char *configFile) |
| int | proxy_str_to_cid (char *dest, char *src) |
| int | proxy_cid_to_str (char *dest, char *src) |
| int | proxy_cidcmp (char *src, char *dest) |
Variables | |
| PROXY_COMPONENTADDR | localInfo |
| PROXY_BINDING * | bindInfo |
| int | errno |
This file contains the implementation of a communications library that works in conjuction with a proxy server to allow NAT traversal. This API is meant to mimic the sockets API except that addressing is done based on globally unique component IDs rather than IP addresses, which are not unique in the presence of NATs.
Definition in file proxylib.c.
| #define INADDR_NONE ((unsigned int) 0xffffffff) |
Definition at line 37 of file proxylib.c.
| #define MAXLEN 256 |
| int proxy_accept | ( | SOCKET | s, | |
| struct sockaddr * | addr, | |||
| socklen_t * | addrlen | |||
| ) |
Proxy replacement for the accept() function, which accepts a connection on a socket.
| s | -- socket to accept the connection on | |
| addr | -- filled in with the address of the connecting entity | |
| addrlen | -- length of sockaddr structure |
Definition at line 720 of file proxylib.c.
{
int i, rv;
for(;;) {
rv = proxy_accept_x(s, addr, addrlen);
/* if successful, return now */
if(rv >= 0)
return rv;
/* if not successful, but not proxied, return now */
if(localInfo.proxyIP == 0)
return rv;
/* if not successful, not proxied, and EINTR, return now */
if((rv < 0) && ((errno=errno_socket()) == EINTR))
return rv;
/* If we reach here, then this server is proxied and
* proxy_accept() failed for some reason other than EINTR.
* Thus we need to try to reconnect to the proxy server.
* First close the old control socket descriptor so we don't
* build up a lot of unused descriptors.
*/
printf("proxy_accept failed, errno = %d\n", errno);
printf("trying to reconnect to the proxy\n");
i = 0;
while (bindInfo[i].sock != -1) {
if (s == bindInfo[i].sock) {
break;
}
i++;
}
if(bindInfo[i].control_sock >= 0) {
close(bindInfo[i].control_sock);
bindInfo[i].control_sock = -1;
}
while(proxy_listen(s, PROXY_MAX_CONNECTIONS) < 0) {
printf("Warning: failed to reconnect to the proxy!\n");
sleep(2);
}
}
}


| int proxy_accept_x | ( | SOCKET | s, | |
| struct sockaddr * | addr, | |||
| socklen_t * | addrlen | |||
| ) |
Proxy replacement for the accept() function, which accepts a connection on a socket.
| s | -- socket to accept the connection on | |
| addr | -- filled in with the address of the connecting entity | |
| addrlen | -- length of sockaddr structure |
Definition at line 386 of file proxylib.c.
{
struct timeval last_keepalive, tv_timeout;
int ret_val, maxfd;
SOCKET connfd;
int i = -1;
fd_set rset;
proxy_tag_t tag;
in_port_t clientPort;
char clientID[CID_LEN];
struct sockaddr_in proxyaddr;
char destID[CID_LEN];
in_port_t destPort;
SOCKET c = INVALID_SOCKET;
last_keepalive.tv_sec = 0;
last_keepalive.tv_usec = 0;
if (localInfo.proxyIP != 0) {
#ifdef WIN32
if (s == INVALID_SOCKET) {
#else
if (s < 0 || s > proxy_get_fd_limit()) {
#endif
errno = EBADF;
return -1;
}
i = 0;
while (bindInfo[i].sock != INVALID_SOCKET) {
if (s == bindInfo[i].sock) {
break;
}
i++;
}
if (bindInfo[i].sock == INVALID_SOCKET) {
errno = EINVAL;
return -1;
}
if (s > bindInfo[i].control_sock) {
maxfd = s;
} else {
maxfd = bindInfo[i].control_sock;
}
do {
FD_ZERO(&rset);
FD_SET(s, &rset);
FD_SET(bindInfo[i].control_sock, &rset);
tv_timeout.tv_sec = PROXY_KEEPALIVE_FREQ;
tv_timeout.tv_usec = 0;
ret_val = select(maxfd + 1, &rset, NULL, NULL, &tv_timeout);
if(ret_val == 0) {
/* check whether we've recently received a keepalive */
if(last_keepalive.tv_sec > 0) {
long time_since_keepalive;
gettimeofday(&tv_timeout, NULL);
time_since_keepalive = tv_timeout.tv_sec - last_keepalive.tv_sec;
if(time_since_keepalive > PROXY_KEEPALIVE_FREQ * 2) {
printf("have not received a keepalive from the proxy recently.\n");
errno = EIO;
return -1;
}
}
}
} while((ret_val == 0) || ((ret_val == -1) && (errno_socket() == EINTR)));
if(ret_val < 0) {
perror("proxy_accept_x: select");
errno = EIO;
return -1;
}
if(FD_ISSET(bindInfo[i].control_sock, &rset)) {
int flag = 1;
/* Need to go through proxy */
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: reading tag from proxy\n");
#endif
/* read message from proxy */
ret_val = proxy_tread(bindInfo[i].control_sock, (char *)&tag,
sizeof(tag), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
perror("proxy_accept_x: read5");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: tag = %d\n", tag);
#endif
if (tag == PROXY_KEEPALIVE) {
gettimeofday(&last_keepalive, NULL);
ret_val = write_socket(bindInfo[i].control_sock, &tag, sizeof(tag));
if (ret_val == SOCKET_ERROR)
perror("proxy_accept_x: write");
errno = EINTR;
return -1;
}
if (tag != PROXY_CONNECT_REQUEST) {
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: read client ID from proxy\n");
#endif
/* read client ID from proxy */
ret_val = proxy_tread(bindInfo[i].control_sock, clientID,
sizeof(clientID), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
perror("proxy_accept_x: read6");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: read client port from proxy\n");
#endif
/* read client port from proxy */
ret_val = proxy_tread(bindInfo[i].control_sock, (char *)&clientPort,
sizeof(clientPort), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
perror("proxy_accept_x: read7");
errno = EIO;
return -1;
}
/* connect to proxy */
memset(&proxyaddr, 0, sizeof(proxyaddr));
proxyaddr.sin_family = AF_INET;
proxyaddr.sin_port = clientPort;
proxyaddr.sin_addr.s_addr = localInfo.proxyIP;
connfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(bindInfo[i].control_sock, IPPROTO_TCP, TCP_NODELAY,
(char *) &flag, sizeof(int));
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: connect to proxy on 2nd port\n");
#endif
ret_val = proxy_connect_nonb(connfd, (struct sockaddr *) (&proxyaddr),
sizeof(proxyaddr), PROXY_CONN_TIMEOUT);
if (ret_val < 0) {
perror("proxy_accept_x: connect2");
errno = EIO;
return -1;
}
if (proxy_do_auth(localInfo.proxyIP, connfd) < 0) {
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: sending reply\n");
#endif
tag = PROXY_CONNECT_REPLY;
ret_val = write_socket(connfd, &tag, sizeof(tag));
if (ret_val == SOCKET_ERROR) {
perror("proxy_accept_x: write");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: send client's ID to proxy\n");
#endif
/* send client's ID to proxy */
ret_val = write_socket(connfd, clientID, sizeof(clientID));
if (ret_val == SOCKET_ERROR) {
perror("proxy_accept_x: write");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: write client port to proxy\n");
#endif
ret_val = write_socket(connfd, (char *)&clientPort, sizeof(clientPort));
if (ret_val == SOCKET_ERROR) {
perror("proxy_accept_x: write");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: going to read tag (%d bytes) from proxy\n", sizeof(tag));
#endif
ret_val = proxy_tread(connfd, (char *)&tag, sizeof(tag),
PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
perror("proxy_accept_x: read8");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: tag = %d\n", tag);
#endif
if (tag == PROXY_CONNECTION_REFUSED) {
errno = ECONNABORTED;
return -1;
}
return connfd;
}
else if(FD_ISSET(s, &rset)) {
/* else if it was not the control sock we got a connection on, then
* fall through and do a normal accept below.
*/
}
else {
/* neither of the descriptors are ready for reading, which seems like
* a bad thing.
*/
errno = ECONNABORTED;
return -1;
}
}
c = accept(s, addr, addrlen);
if (c == INVALID_SOCKET)
return c;
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: reading tag from proxy\n");
#endif
ret_val = proxy_tread(c, (char *) &tag, sizeof(tag), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
proxy_close(c);
perror("proxy_accept_x: read1");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: tag = %d\n", tag);
#endif
if (tag != PROXY_CONNECT) {
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: read client ID from proxy\n");
#endif
/* read client ID from proxy */
ret_val = proxy_tread(c, clientID, sizeof(clientID), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
proxy_close(c);
perror("proxy_accept_x: read2");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: read dest ID from proxy\n");
#endif
/* read dest ID from proxy */
ret_val = proxy_tread(c, destID, sizeof(destID), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
proxy_close(c);
perror("proxy_accept_x: read3");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: read dest port from proxy\n");
#endif
/* read dest port from proxy */
ret_val = proxy_tread(c, (char *)&destPort, sizeof(destPort),
PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
proxy_close(c);
perror("proxy_accept_x: read4");
errno = EIO;
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy_accept: checking IDs/sending reply\n");
fprintf(stderr,"local ID = ");
proxy_print_componentID(stdout, localInfo.ID);
fprintf(stderr,"\ndest ID = ");
proxy_print_componentID(stdout, destID);
fprintf(stderr,"\n");
#endif
if (proxy_cidcmp(localInfo.ID, destID)) {
fprintf(stderr,"proxy_accept: Dest ID does not match!\n");
tag = PROXY_CONNECTION_REFUSED;
write_socket(c, &tag, sizeof(tag));
proxy_close(c);
errno = EIO;
return -1;
}
tag = PROXY_CONNECTION_ACCEPTED;
ret_val = write_socket(c, &tag, sizeof(tag));
if (ret_val == SOCKET_ERROR) {
proxy_close(c);
perror("proxy_accept_x: write");
errno = EIO;
return -1;
}
return c;
}


| int proxy_bind | ( | SOCKET | s, | |
| const struct sockaddr * | name, | |||
| int | namelen | |||
| ) |
Proxy replacement for the bind() function, which binds a name to a socket.
| s | -- the socket to bind | |
| name | -- the local address for the socket | |
| namelen | -- length of the local address in bytes |
Definition at line 183 of file proxylib.c.
{
struct sockaddr_in *sockin;
int i;
int ret_val;
ret_val = bind(s, name, namelen);
if (localInfo.proxyIP != 0) {
#ifdef WIN32
if (s == INVALID_SOCKET) {
#else
if (s < 0 || s > proxy_get_fd_limit()) {
#endif
errno = EBADF;
return -1;
}
i = 0;
while (bindInfo[i].sock != INVALID_SOCKET) {
if (s == bindInfo[i].sock) {
errno = EINVAL;
return -1;
}
i++;
}
bindInfo[i].sock = s;
sockin = (struct sockaddr_in *) name;
if(sockin->sin_port == 0) {
struct sockaddr_in addr;
socklen_t addr_length;
addr_length = sizeof(addr);
if ((getsockname(s, (struct sockaddr *) &addr, &addr_length)) == -1) {
errno = EINVAL;
return -1;
}
bindInfo[i].port = addr.sin_port;
}
else
bindInfo[i].port = sockin->sin_port;
bindInfo[i + 1].sock = INVALID_SOCKET;
return 0;
}
return ret_val;
}


| int proxy_cid_to_str | ( | char * | dest, | |
| char * | src | |||
| ) |
Convert componentID (src CID_LEN) to a string (dest CID_LEN*2+1)
| dest | -- the string representation of the component ID (set on return) | |
| src | -- the binary component ID |
Definition at line 1281 of file proxylib.c.
{
char temp_string[CID_LEN*2+1];
int i;
for(i=0;i<CID_LEN;i++){
sprintf(temp_string, "%x%x", (src[i] >> 4) & 0x0F, src[i] & 0x0F);
if(i==0){
strcpy(dest, temp_string);
}
else{
strcat(dest, temp_string);
}
}
return 0;
}

| int proxy_cidcmp | ( | char * | src, | |
| char * | dest | |||
| ) |
Compares two component IDs.
| src | -- component ID to compare | |
| dest | -- component ID to compare |
Definition at line 1310 of file proxylib.c.
{
char any[CID_LEN];
/* all ones will match any component ID */
memset(any, 0xFF, CID_LEN);
if(memcmp(any, dest, CID_LEN) == 0)
return 0;
return memcmp(src,dest,CID_LEN);
}

| int proxy_close | ( | SOCKET | fildes | ) |
Proxy replacement for the close() function, which closes the specified socket.
| fildes | -- the socket to be closed |
Definition at line 1125 of file proxylib.c.
{
int i, found;
if (localInfo.proxyIP != 0) {
found = 0;
i = 0;
while (bindInfo[i].sock != -1) {
if (fildes == bindInfo[i].sock) {
found = 1;
break;
}
i++;
}
if (found == 1) {
close_socket(bindInfo[i].control_sock);
bindInfo[i].sock = -1;
}
}
return close_socket(fildes);
}

| int proxy_connect | ( | SOCKET | s, | |
| PROXY_COMPONENTADDR * | name | |||
| ) |
Proxy replacement for connect() function, which initiates a connection on a socket.
| s | -- socket to use to connect | |
| name | -- component address to connect to |
Definition at line 780 of file proxylib.c.
{
proxy_tag_t tag, connect_return;
int ret_val;
struct sockaddr_in addr;
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if (name->proxyIP != 0) {
addr.sin_addr.s_addr = name->proxyIP;
addr.sin_port = name->proxyPort;
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); fflush(NULL); */
ret_val = proxy_connect_nonb(s, (struct sockaddr *) (&addr),
sizeof(addr), PROXY_CONN_TIMEOUT);
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
if(ret_val < 0) {
perror("proxy_connect: connect");
return -1;
}
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
if(proxy_do_auth(name->proxyIP, s) < 0)
return -1;
}
else {
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
addr.sin_addr.s_addr = name->IP;
addr.sin_port = name->port;
ret_val = proxy_connect_nonb(s, (struct sockaddr *) (&addr),
sizeof(addr), PROXY_CONN_TIMEOUT);
if (ret_val < 0) {
fprintf(stderr, "connect failure\n");
return -1;
}
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
}
/* send some stuff over the connection */
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
tag = PROXY_CONNECT;
#ifdef PROXY_DEBUG
fprintf(stderr,"write tag %c %d %u sizeof(tag) %d \n", tag, tag, tag, sizeof(tag));
#endif
ret_val = write_socket(s, &tag, sizeof(tag));
if (ret_val == SOCKET_ERROR) {
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
perror("proxy_connect: write");
close_socket(s);
return -1;
}
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
#ifdef PROXY_DEBUG
fprintf(stderr,"write my id\n");
#endif
ret_val = write_socket(s, localInfo.ID, sizeof(localInfo.ID));
if (ret_val == SOCKET_ERROR) {
perror("proxy_connect: write");
close_socket(s);
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"write dest id\n");
#endif
ret_val = write_socket(s, name->ID, sizeof(name->ID));
if (ret_val == SOCKET_ERROR) {
perror("proxy_connect: write");
close_socket(s);
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"write dest port\n");
#endif
ret_val = write_socket(s, (char *)&(name->port), sizeof(name->port));
if (ret_val == SOCKET_ERROR) {
perror("proxy_connect: write");
close_socket(s);
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"wat for proxy reply\n");
#endif
/* wait for reply from proxy */
ret_val = proxy_tread(s, (char *)&connect_return, sizeof(connect_return),
PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
perror("proxy_connect: read");
close_socket(s);
return -1;
}
#ifdef PROXY_DEBUG
fprintf(stderr,"proxy reply = %d\n", ret_val);
#endif
if (connect_return == PROXY_CONNECTION_REFUSED) {
errno = ECONNREFUSED;
close_socket(s);
return -1;
}
/* fprintf(stderr, "%s:%d \n", __FILE__, __LINE__); */
return 0;
}


| int proxy_connect_nonb | ( | SOCKET | sockfd, | |
| const struct sockaddr * | saptr, | |||
| socklen_t | salen, | |||
| int | nsec | |||
| ) |
This is a replacement for connect that handles interruptions from signals. It also provides a timeout parameter for limiting the amount of time we block on a connection attempt. This code was adapted from Stevens' "UNIX Network Programming" page 411.
| sockfd | -- socket descriptor to use for connection | |
| saptr | -- pointer to address structure | |
| salen | -- length of address struct | |
| nsec | -- number of seconds to wait before timing out |
Definition at line 912 of file proxylib.c.
{
int n;
int error;
socklen_t len;
fd_set rset, wset;
struct timeval tval;
#ifndef WIN32
int flags;
#endif
#ifdef WIN32
{
ULONG NonBlock = 1;
if (ioctlsocket(sockfd, FIONBIO, &NonBlock) == SOCKET_ERROR) {
fprintf(stderr, "ioctlsocket() failed to set socket to non-blocking \n");
return -1;
}
}
#else
{
if (((flags = fcntl(sockfd, F_GETFL, 0)) < 0) ||
((fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0))) {
errno = EIO;
return -1;
}
}
#endif
error = 0;
if ( (n = connect(sockfd, saptr, salen)) == SOCKET_ERROR) {
errno = errno_socket();
/* The EWOULDBLOCK may be WIN32 specific */
if (errno != EINPROGRESS && errno != EWOULDBLOCK )
return -1;
}
/* Do whatever we want while the connect is taking place. */
if (n == 0)
goto done; /* connect completed immediately */
do {
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;
n = select(sockfd+1, &rset, &wset, NULL, nsec ? &tval : NULL);
if ( n == 0) {
close_socket(sockfd); /* timeout */
errno = ETIMEDOUT;
return -1;
}
else if ((n < 0) && ((errno=errno_socket()) != EINTR)) {
close_socket(sockfd);
return -1;
}
} while((n<0) && ((errno=errno_socket()) == EINTR));
if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&error, &len) < 0)
return -1; /* Solaris pending error */
} else {
fprintf(stderr,"select error: sockfd not set");
errno = EIO;
return -1;
}
done:
#ifdef WIN32
{
ULONG NonBlock = 0;
if (ioctlsocket(sockfd, FIONBIO, &NonBlock) == SOCKET_ERROR) {
fprintf(stderr, "ioctlsocket() failed to set socket to nonblocking \n");
return -1;
}
}
#else
if (fcntl(sockfd, F_SETFL, flags) < 0) { /* restore file status flags */
errno = EIO;
return -1;
}
#endif
if(error) {
close_socket(sockfd); /* just in case */
errno = error;
return -1;
}
return 0;
}


| int proxy_do_auth | ( | ipaddr_t | proxy_ip, | |
| SOCKET | s | |||
| ) |
Perform component-to-proxy authentication (if enabled).
| proxy_ip | -- proxy IP address | |
| s | -- the connected socket |
Definition at line 1063 of file proxylib.c.
{
proxy_tag_t tag;
int ret_val;
char proxy_host_ip[16];
proxy_ip_to_str(proxy_ip, proxy_host_ip);
ret_val = proxy_tread(s, (char *)&tag, sizeof(tag), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
errno = ECONNRESET;
return -1;
}
#ifdef KERBEROS5
if (tag == PROXY_KRB5_AUTH_REQUIRED) {
if (proxy_send_krb5_credentials(proxy_host_ip, s) < 0) {
errno = EACCES;
close_socket(s);
return -1;
}
ret_val = proxy_tread(s, (char *)&tag, sizeof(tag), PROXY_TIMEOUT_DEFAULT);
if (ret_val < 0) {
errno = ECONNRESET;
close_socket(s);
return -1;
}
}
/*
* check for authentication-specific error codes here
* before falling through to the problem-specific error codes
*/
if (tag == PROXY_AUTH_FAILED) {
errno = EACCES;
close_socket(s);
return -1;
}
#endif
if (tag == PROXY_KRB5_AUTH_REQUIRED) {
errno = EACCES;
close_socket(s);
return -1;
} else if (tag != PROXY_AUTH_ACCEPTED) {
errno = EACCES;
close_socket(s);
return -1;
}
return 0;
}


| int proxy_get_fd_limit | ( | ) |
Get the maximum number of descriptors we can use. This is used to allocate the table of bound connections. On some systems, the maximum number returned by getrlimit is pretty huge, so we use PROXY_BIND_MAXFD in that situation (to avoid trying to malloc an extremely large chunk of memory).
Definition at line 1334 of file proxylib.c.
{
#ifdef WIN32
return 256;
#else
struct rlimit rlp;
if(getrlimit(RLIMIT_NOFILE, &rlp) < 0)
return PROXY_BIND_MAXFD;
if((rlp.rlim_max <= 0) || (rlp.rlim_max > PROXY_BIND_MAXFD))
return PROXY_BIND_MAXFD;
return (int)rlp.rlim_max;
#endif
}

| void proxy_get_id | ( | char * | cp | ) |
Generates a random component ID.
| cp | -- on return contains the new component ID |
Definition at line 58 of file proxylib.c.
{
struct timeval tv;
int i;
if (!cp)
return;
gettimeofday(&tv, NULL);
srandom(tv.tv_usec);
for(i=0;i<CID_LEN;i++)
cp[i] = random() % 256;
}

| PROXY_COMPONENTADDR proxy_get_local_addr | ( | ) |
Gets this component's address.
Definition at line 111 of file proxylib.c.
{
return localInfo;
}

| ipaddr_t proxy_get_proxy_ip | ( | ) |
Gets the IP address of the proxy server.
Definition at line 123 of file proxylib.c.
{
return localInfo.proxyIP;
}

| in_port_t proxy_get_proxy_port | ( | ) |
Gets the proxy server port.
Definition at line 149 of file proxylib.c.
{
return localInfo.proxyPort;
}

| int proxy_getsockname | ( | int | s, | |
| struct sockaddr * | name, | |||
| socklen_t * | namelen | |||
| ) |
proxy replacement for the getsockname() function.
| s | -- | |
| name | -- | |
| namelen | -- |
Definition at line 246 of file proxylib.c.
{
int i;
if(getsockname(s, name, namelen) < 0)
return -1;
if (localInfo.proxyIP != 0) {
i = 0;
while(bindInfo[i].sock != INVALID_SOCKET) {
if(s == bindInfo[i].sock)
break;
i++;
}
if(bindInfo[i].sock == INVALID_SOCKET) {
errno = EINVAL;
return -1;
}
((struct sockaddr_in *)name)->sin_port = bindInfo[i].port;
}
return 0;
}

| void proxy_init | ( | char * | configFile | ) |
Initializes the proxy library.
| configFile | -- name of the configuration file, which specifies such things as the proxy IP address |
Definition at line 1154 of file proxylib.c.
{
#define MAXLEN 256
/* int const MAXLEN = 256; */
char line[MAXLEN];
char proxy_string[MAXLEN];
char proxy_port_string[MAXLEN];
FILE *fconfig;
struct hostent *hp;
/* generate an ID */
proxy_get_id(localInfo.ID);
/* default to no proxy */
strcpy(proxy_string, "0");
strcpy(proxy_port_string, "0");
if ((strlen(configFile) >= 1) &&
(fconfig = fopen(configFile, "r")) != NULL) {
/* get parameters from config file */
fgets(line, MAXLEN, fconfig);
while (!feof(fconfig)) {
if (strncmp(line, "proxyPort", strlen("proxyPort")) == 0) {
strtok(line, "=");
strcpy(proxy_port_string, (char *) strtok(NULL, " "));
proxy_port_string[strlen(proxy_port_string) - 1] = '\0';
} else if (strncmp(line, "proxy", strlen("proxy")) == 0) {
strtok(line, "=");
strcpy(proxy_string, strtok(NULL, " "));
proxy_string[strlen(proxy_string) - 1] = '\0';
}
fgets(line, MAXLEN, fconfig);
}
fclose(fconfig);
} else if ((getenv("GRIDSOLVE_PROXY")) != NULL) {
/* Get proxy from environment */
strncpy(line, getenv("GRIDSOLVE_PROXY"), MAXLEN);
fprintf(stderr,"Could not open proxy config file %s \n", configFile);
fprintf(stderr,"Trying environment variable GRIDSOLVE_PROXY=%s\n",line);
strcpy(proxy_string, strtok(line, ":"));
strcpy(proxy_port_string, strtok(NULL, ":"));
}
/* store proxy IP */
if (strcasecmp(proxy_string, "0") == 0) {
localInfo.proxyIP = 0;
} else {
if ((hp = gethostbyname(proxy_string)) == NULL) {
fprintf(stderr, "Could not gethostbyname for proxy %s\n", proxy_string);
perror("proxy_connect: gethostbyname()");
return;
}
memcpy((void *) &(localInfo.proxyIP), hp->h_addr_list[0], sizeof(ipaddr_t));
}
/* store proxy port */
if (strcasecmp(proxy_port_string, "0") == 0) {
localInfo.proxyPort = 0;
} else {
localInfo.proxyPort = htons(atoi((char *) strdup(proxy_port_string)));
}
/* get my IP */
localInfo.IP = proxy_get_my_ipaddr();
if (localInfo.proxyIP != 0) {
/* intialize bindinfo */
bindInfo =
(PROXY_BINDING *) malloc(sizeof(PROXY_BINDING) * proxy_get_fd_limit());
bindInfo[0].sock = INVALID_SOCKET;
}
}


| int proxy_ip_to_str | ( | ipaddr_t | IP, | |
| char * | dottedIP | |||
| ) |
Unparse the IP into string with dotted notation.
| IP | -- IP address to be converted to string representation | |
| dottedIP | -- string where the dotted version is stored |
Definition at line 1022 of file proxylib.c.
{
unsigned char *uptr = (unsigned char *)&IP;
if (IP == 0)
strcpy(dottedIP, "0.0.0.0");
else
sprintf(dottedIP, "%d.%d.%d.%d", uptr[0] & 0xff, uptr[1] & 0xff,
uptr[2] & 0xff, uptr[3] & 0xff);
return 0;
}

| int proxy_listen | ( | SOCKET | s, | |
| int | backlog | |||
| ) |
Proxy replacement for the listen() function, which specifies a willingness to accept incoming connections on the given socket.
| s | -- the socket to listen on | |
| backlog | -- maximum length the queue of pending connections may grow to |
Definition at line 285 of file proxylib.c.
{
proxy_tag_t tag;
int ret_val;
struct sockaddr_in proxyaddr;
ret_val = listen(s, backlog);
if (localInfo.proxyIP != 0) {
int i, flag = 1;
#ifdef WIN32
if (s == INVALID_SOCKET) {
#else
if (s < 0 || s > proxy_get_fd_limit()) {
#endif
errno = EBADF;
return -1;
}
i = 0;
while (bindInfo[i].sock != INVALID_SOCKET) {
if (s == bindInfo[i].sock) {
break;
}
i++;
}
if (bindInfo[i].sock == INVALID_SOCKET) {
errno = EINVAL;
return -1;
}
bindInfo[i].control_sock = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(bindInfo[i].control_sock, IPPROTO_TCP, TCP_NODELAY,
(char *) &flag, sizeof(int));
proxyaddr.sin_family = AF_INET;
proxyaddr.sin_addr.s_addr = localInfo.proxyIP;
proxyaddr.sin_port = localInfo.proxyPort;
#ifdef PROXY_DEBUG
fprintf(stderr,"listen: addr = %d\n", (int)localInfo.proxyIP);
fprintf(stderr,"listen: port = %d\n", (int)ntohs(localInfo.proxyPort));
#endif
/* Form control collection with proxy */
/* connect to proxy and form control connection */
ret_val = proxy_connect_nonb(bindInfo[i].control_sock,
(struct sockaddr *) (&proxyaddr), sizeof(proxyaddr), PROXY_CONN_TIMEOUT);
if (ret_val < 0) {
perror("proxy_listen: connect1");
return -1;
}
if (proxy_do_auth(localInfo.proxyIP, bindInfo[i].control_sock) < 0)
return -1;
tag = PROXY_CONTROL_CONNECTION;
ret_val = write_socket(bindInfo[i].control_sock, &tag, sizeof(tag));
if (ret_val == SOCKET_ERROR) {
perror("proxy_listen: write");
return -1;
}
/* send my ID to proxy */
ret_val = write_socket(bindInfo[i].control_sock, localInfo.ID, CID_LEN);
if (ret_val == SOCKET_ERROR) {
perror("proxy_listen: write");
return -1;
}
/* send the bind port to proxy */
ret_val = write_socket(bindInfo[i].control_sock, (char *)&(bindInfo[i].port),
sizeof(bindInfo[i].port));
if (ret_val == SOCKET_ERROR) {
perror("proxy_listen: write");
return -1;
}
return 0;
}
return ret_val;
}


| void proxy_print_componentID | ( | FILE * | f, | |
| char * | id | |||
| ) |
Prints the component ID to the specified file.
| f | -- the file to which the component ID should be printed | |
| id | -- the component id to print |
Definition at line 96 of file proxylib.c.


| void proxy_print_local_info | ( | ) |
Prints proxy IP address, proxy port, and component ID to stdout.
Definition at line 79 of file proxylib.c.
{
printf("Proxy IP port: %u %d\n",
(unsigned int)localInfo.proxyIP, ntohs(localInfo.proxyPort));
printf("My ID IP: ");
proxy_print_componentID(stdout, localInfo.ID);
printf(" %d\n", (int)localInfo.IP);
}


| int proxy_set_cid_from_str | ( | char * | id | ) |
Sets the component ID to the specified value.
| id | -- the ID to set (note this is the string form of the ID) |
Definition at line 137 of file proxylib.c.
{
return proxy_str_to_cid(localInfo.ID, id);
}


| SOCKET proxy_socket | ( | int | domain, | |
| int | type, | |||
| int | protocol | |||
| ) |
Proxy replacement for the socket() function, which creates an endpoint for communication.
| domain | -- the protocol family to use | |
| type | -- socket type (SOCK_STREAM, SOCK_DGRAM, etc) | |
| protocol | -- protocol to be used with the socket |
Definition at line 166 of file proxylib.c.
{
return socket(domain, type, protocol);
}

| int proxy_str_to_cid | ( | char * | dest, | |
| char * | src | |||
| ) |
Convert string (src CID_LEN*2+1) to a componentID (dest CID_LEN)
| dest | -- the binary component ID (set on return) | |
| src | -- the string representation of the component ID |
Definition at line 1241 of file proxylib.c.
{
int i,j;
if(!src || !dest)
return -1;
/* clear out destination */
memset(dest, 0, CID_LEN);
for(i=strlen(src)-1, j=CID_LEN-1;i>=0;i-=2, j--) {
char tmp[2];
if((src[i] == 'x') || (src[i] == 'X'))
break;
tmp[1] = 0;
tmp[0] = src[i];
dest[j] = (char)strtol(tmp,NULL,16);
if(i > 0) {
tmp[0] = src[i-1];
dest[j] |= (char)strtol(tmp,NULL,16) << 4;
}
}
return 0;
}

| int proxy_str_to_ip | ( | ipaddr_t * | IP, | |
| char * | dottedIP | |||
| ) |
Parse the string with dotted notation into an IP address.
| IP | -- the binary representation of the dotted IP string | |
| dottedIP | -- the dotted IP string to be converted |
Definition at line 1045 of file proxylib.c.
{
unsigned int b1,b2,b3,b4;
sscanf(dottedIP, "%u.%u.%u.%u", &b1,&b2,&b3,&b4);
*IP = htonl((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
return 0;
}

| PROXY_BINDING* bindInfo |
Definition at line 44 of file proxylib.c.
| int errno |
| PROXY_COMPONENTADDR localInfo |
Definition at line 41 of file proxylib.c.
1.6.3-20100507