blob: 2667a57d9fa5b7e665189d1d2ed9ad27e5a50140 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* @version $Id$ */
#include "pr_warp.h"
wa_boolean n_recv(apr_socket_t *sock, warp_packet *pack) {
apr_size_t len=0;
char hdr[3];
int ptr=0;
if (sock==NULL) return(wa_false);
if (pack==NULL) return(wa_false);
p_reset(pack);
len=3;
while(1) {
if (apr_recv(sock,&hdr[ptr],&len)!=APR_SUCCESS) {
wa_debug(WA_MARK,"Cannot receive header");
return(wa_false);
}
ptr+=len;
len=3-ptr;
if (len==0) break;
}
pack->type=((int)hdr[0])&0x0ff;
pack->size=(hdr[1]&0x0ff)<<8;
pack->size=pack->size|(hdr[2]&0x0ff);
if (pack->size>0) {
len=pack->size;
ptr=0;
while(1) {
if (apr_recv(sock,&pack->buff[ptr],&len)!=APR_SUCCESS) {
wa_debug(WA_MARK,"Cannot receive payload");
return(wa_false);
}
ptr+=len;
len=pack->size-ptr;
if (len==0) break;
}
}
wa_debug(WA_MARK,"WARP <<< TYP=%02X LEN=%d",pack->type,pack->size);
return(wa_true);
}
wa_boolean n_send(apr_socket_t *sock, warp_packet *pack) {
apr_size_t len=0;
char hdr[3];
int ptr=0;
if (sock==NULL) return(wa_false);
if (pack==NULL) return(wa_false);
hdr[0]=(char)(pack->type&0x0ff);
hdr[1]=(char)((pack->size>>8)&0x0ff);
hdr[2]=(char)(pack->size&0x0ff);
len=3;
while(1) {
if (apr_send(sock,&hdr[ptr],&len)!=APR_SUCCESS) return(wa_false);
ptr+=len;
len=3-ptr;
if (len==0) break;
}
len=pack->size;
ptr=0;
while(1) {
if (apr_send(sock,&pack->buff[ptr],&len)!=APR_SUCCESS)
return(wa_false);
ptr+=len;
len=pack->size-ptr;
if (len==0) break;
}
wa_debug(WA_MARK,"WARP >>> TYP=%2X LEN=%d",pack->type,pack->size);
p_reset(pack);
return(wa_true);
}
/* Attempt to connect to the remote endpoint of the WARP connection (if not
done already). */
apr_socket_t *n_connect(wa_connection *conn) {
warp_config *conf=(warp_config *)conn->conf;
apr_status_t ret=APR_SUCCESS;
apr_socket_t *sock=NULL;
ret=apr_socket_create(&sock,AF_INET,SOCK_STREAM,wa_pool);
if (ret!=APR_SUCCESS) {
sock=NULL;
wa_log(WA_MARK,"Cannot create socket for conn. \"%s\"",conn->name);
return(sock);
}
/* Attempt to connect to the remote endpoint */
ret=apr_connect(sock, conf->addr);
if (ret!=APR_SUCCESS) {
apr_shutdown(sock,APR_SHUTDOWN_READWRITE);
sock=NULL;
wa_log(WA_MARK,"Connection \"%s\" cannot connect",conn->name);
return(sock);
}
#if APR_HAS_THREADS
apr_atomic_inc(&conf->open_socket_count);
#else
conf->open_socket_count++;
#endif
return(sock);
}
/* Attempt to disconnect a connection if connected. */
void n_disconnect(wa_connection *conn, apr_socket_t * sock) {
warp_config *conf=(warp_config *)conn->conf;
apr_status_t ret=APR_SUCCESS;
wa_debug(WA_MARK,"Disconnecting \"%s\"",conn->name);
/* Create the APR socket if that has not been yet created */
if (sock==NULL) return;
/* Shutdown and close the socket (ignoring errors) */
ret=apr_shutdown(sock,APR_SHUTDOWN_READWRITE);
if (ret!=APR_SUCCESS)
wa_log(WA_MARK,"Cannot shutdown \"%s\"",conn->name);
ret=apr_socket_close(sock);
if (ret!=APR_SUCCESS)
wa_log(WA_MARK,"Cannot close \"%s\"",conn->name);
#if APR_HAS_THREADS
apr_atomic_dec(&conf->open_socket_count);
#else
conf->open_socket_count--;
#endif
}