costin      01/11/16 14:48:55

  Modified:    jk/native/common jk_channel_socket.c
  Log:
  Working impl. for a socket channel, using cut&paste from jk_connect.c.
  
  The code is almost identical.
  
  I just changed a bit the if()s, as I'm just a confused java programmer -
  I'll probably continue to change to java-style if( foo != NULL ) and
  move the function calls before the if - sorry, but my C is not that good,
  it takes me some time to read C-style ifs...
  
  Revision  Changes    Path
  1.2       +312 -38   jakarta-tomcat-connectors/jk/native/common/jk_channel_socket.c
  
  Index: jk_channel_socket.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_channel_socket.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- jk_channel_socket.c       2001/11/07 21:38:39     1.1
  +++ jk_channel_socket.c       2001/11/16 22:48:55     1.2
  @@ -56,7 +56,8 @@
    * ========================================================================= */
   
   /**
  - * Channel using 'plain' TCP sockets. Based on jk_sockbuf.
  + * Channel using 'plain' TCP sockets. Based on jk_sockbuf. Will be replaced by
  + * an APR-based mechanism.
    * 
    * Properties:
    *  - host
  @@ -73,7 +74,29 @@
   #include "jk_channel.h"
   #include "jk_global.h"
   
  +#include <string.h>
   
  +#ifndef WIN32
  +     #define closesocket                     close
  +#endif
  +
  +/** Information specific for the socket channel
  + */
  +struct jk_channel_socket_private {
  +    int ndelay;
  +    struct sockaddr_in addr;    
  +    char *host;
  +    short port;
  +};
  +
  +/** Informations for each connection
  + */
  +typedef struct jk_channel_socket_data {
  +    int sock;
  +} jk_channel_socket_data_t;
  +
  +typedef struct jk_channel_socket_private jk_channel_socket_private_t;
  +
   /*
     We use the _privateInt field directly. Long term we can define our own
     jk_channel_socket_t structure and use the _private field, etc - but we 
  @@ -84,7 +107,231 @@
   
   int JK_METHOD jk_channel_socket_factory(jk_env_t *env, void **result,
                                        char *type, char *name);
  +static int jk_channel_socket_resolve(char *host, short port,
  +                                  struct sockaddr_in *rc);
  +
  +static int jk_channel_socket_getProperty(jk_channel_t *_this, 
  +                                      char *name, char **value)
  +{
  +    return JK_FALSE;
  +}
  +
  +static int jk_channel_socket_setProperty(jk_channel_t *_this, 
  +                                      char *name, char *value)
  +{
  +    jk_channel_socket_private_t *socketInfo=
  +     (jk_channel_socket_private_t *)(_this->_privatePtr);
  +
  +    if( strcmp( "host", name ) != 0 ) {
  +     socketInfo->host=value;
  +    } else if( strcmp( "defaultPort", name ) != 0 ) {
  +    } else if( strcmp( "port", name ) != 0 ) {
  +    } else {
  +     return JK_FALSE;
  +    }
  +    return JK_TRUE;
  +}
  +
  +/** resolve the host IP ( jk_resolve ) and initialize the channel.
  + */
  +static int jk_channel_socket_init(jk_channel_t *_this, 
  +                               jk_map_t *props,
  +                               char *worker_name, 
  +                               jk_worker_t *worker, 
  +                               jk_logger_t *l )
  +{
  +    int err=jk_log(l, JK_LOG_DEBUG, "Into jk_channel_socket_init\n");
  +    jk_channel_socket_private_t *socketInfo=
  +     (jk_channel_socket_private_t *)(_this->_privatePtr);
  +
  +    char *host=socketInfo->host;
  +    short port=socketInfo->port;
  +    struct sockaddr_in *rc=&socketInfo->addr;
  +
  +    port = jk_get_worker_port(props, worker_name, port);
  +    host = jk_get_worker_host(props, worker_name, host);
  +
  +    _this->worker=worker;
  +    _this->logger=l;
  +    _this->properties=props;
  +    
  +    err=jk_channel_socket_resolve( host, port, rc );
  +    if( err!= JK_TRUE ) {
  +     jk_log(l, JK_LOG_ERROR, "jk_channel_socket_init: "
  +            "can't resolve %s:%d errno=%d\n", host, port, errno );
  +    }
  +    jk_log(l, JK_LOG_DEBUG, "jk_channel_socket_init: ok "
  +        " %s:%d\n", host, port );
  +
  +    return err;
  +}
  +
  +/** private: resolve the address on init
  + */
  +static int jk_channel_socket_resolve(char *host, short port,
  +                                  struct sockaddr_in *rc)
  +{
  +    int x;
  +    u_long laddr;
  +    
  +    rc->sin_port   = htons((short)port);
  +    rc->sin_family = AF_INET;
  +
  +    /* Check if we only have digits in the string */
  +    for(x = 0 ; '\0' != host[x] ; x++) {
  +        if(!isdigit(host[x]) && host[x] != '.') {
  +            break;
  +        }
  +    }
   
  +    if(host[x] != '\0') {
  +        /* If we found also characters we use gethostbyname()*/
  +        struct hostent *hoste = gethostbyname(host);
  +        if(!hoste) {
  +            return JK_FALSE;
  +        }
  +
  +        laddr = ((struct in_addr *)hoste->h_addr_list[0])->s_addr;
  +    } else {
  +        /* If we found only digits we use inet_addr() */
  +        laddr = inet_addr(host);        
  +    }
  +    memcpy(&(rc->sin_addr), &laddr , sizeof(laddr));
  +
  +    return JK_TRUE;
  +}
  +
  +/** connect to Tomcat (jk_open_socket)
  + */
  +static int jk_channel_socket_open(jk_channel_t *_this, jk_endpoint_t *endpoint)
  +{
  +    jk_logger_t *l=_this->logger;
  +    int err=jk_log(l, JK_LOG_DEBUG, "Into jk_channel_socket_open\n");
  +    jk_channel_socket_private_t *socketInfo=
  +     (jk_channel_socket_private_t *)(_this->_privatePtr);
  +
  +    struct sockaddr_in *addr=&socketInfo->addr;
  +    int ndelay=socketInfo->ndelay;
  +
  +    int sock;
  +
  +    sock = socket(AF_INET, SOCK_STREAM, 0);
  +    if(sock > -1) {
  +        int ret;
  +        /* Tries to connect to JServ (continues trying while error is EINTR) */
  +        do {
  +            jk_log(l, JK_LOG_DEBUG, "jk_open_socket, try to connect socket = %d\n", 
sock);
  +            ret = connect(sock,
  +                          (struct sockaddr *)addr,
  +                          sizeof(struct sockaddr_in));
  +#ifdef WIN32
  +            if(SOCKET_ERROR == ret) { 
  +                errno = WSAGetLastError() - WSABASEERR;
  +            }
  +#endif /* WIN32 */
  +            jk_log(l, JK_LOG_DEBUG, "jk_open_socket, after connect ret = %d\n", 
ret);
  +        } while (-1 == ret && EINTR == errno);
  +
  +        /* Check if we connected */
  +        if(0 == ret) {
  +            if(ndelay) {
  +                int set = 1;
  +
  +                jk_log(l, JK_LOG_DEBUG, "jk_open_socket, set TCP_NODELAY to on\n");
  +                setsockopt(sock, 
  +                           IPPROTO_TCP, 
  +                           TCP_NODELAY, 
  +                           (char *)&set, 
  +                           sizeof(set));
  +            }   
  +
  +            jk_log(l, JK_LOG_DEBUG, "jk_open_socket, return, sd = %d\n", sock);
  +         {
  +             jk_channel_socket_data_t *sd=endpoint->channelData;
  +             if( sd==NULL ) {
  +                 sd=(jk_channel_socket_data_t *)
  +                     malloc( sizeof( jk_channel_socket_data_t ));
  +                 endpoint->channelData=sd;
  +             }
  +             sd->sock=sock;
  +         }
  +            return JK_TRUE;
  +        }   
  +        jk_close_socket(sock);
  +    } else {
  +#ifdef WIN32
  +        errno = WSAGetLastError() - WSABASEERR;
  +#endif /* WIN32 */
  +    }    
  +
  +    jk_log(l, JK_LOG_ERROR, "jk_open_socket, connect() failed errno = %d %s\n",
  +        errno, strerror( errno ) ); 
  +
  +    return -1;
  +}
  +
  +
  +/** close the socket  ( was: jk_close_socket )
  +*/
  +int jk_channel_socket_close(jk_channel_t *_this, jk_endpoint_t *endpoint)
  +{
  +    int sd;
  +    jk_channel_socket_data_t *chD=endpoint->channelData;
  +    if( chD==NULL ) 
  +     return JK_FALSE;
  +    sd=chD->sock;
  +
  +#ifdef WIN32
  +    if(INVALID_SOCKET  != sd) {
  +        return closesocket(sd) ? JK_FALSE : JK_TRUE;; 
  +    }
  +#else 
  +    if(-1 != sd) {
  +        return close(sd);
  +    }
  +#endif
  +    return JK_FALSE;
  +}
  +
  +/** send a long message
  + * @param sd  opened socket.
  + * @param b   buffer containing the data.
  + * @param len length to send.
  + * @return    -2: send returned 0 ? what this that ?
  + *            -3: send failed.
  + *            >0: total size send.
  + * @bug       this fails on Unixes if len is too big for the underlying
  + *             protocol.
  + * @was: jk_tcp_socket_sendfull
  + */
  +static int jk_channel_socket_send(jk_channel_t *_this,
  +                               jk_endpoint_t *endpoint,
  +                               char *b, int len) 
  +{
  +    int sd;
  +    int  sent=0;
  +
  +    jk_channel_socket_data_t *chD=endpoint->channelData;
  +    if( chD==NULL ) 
  +     return JK_FALSE;
  +    sd=chD->sock;
  +
  +    while(sent < len) {
  +        int this_time = send(sd, (char *)b + sent , len - sent,  0);
  +         
  +     if(0 == this_time) {
  +         return -2;
  +     }
  +     if(this_time < 0) {
  +         return -3;
  +     }
  +     sent += this_time;
  +    }
  +    /*     return sent; */
  +    return JK_TRUE;
  +}
  +
  +
   /** receive len bytes.
    * @param sd  opened socket.
    * @param b   buffer to store the data.
  @@ -94,49 +341,76 @@
    * Was: tcp_socket_recvfull
    */
   static int jk_channel_socket_recv( jk_channel_t *_this,
  -                                jk_msg_buf_t *mb ) 
  +                                jk_endpoint_t *endpoint,
  +                                char *b, int len ) 
   {
  -  int sd=_this->_privateInt;
  -  unsigned char *b=jk_b_get_buff( mb );
  -  int len=jk_b_get_len( mb );
  -
  -  int rdlen = 0;
  -
  -  while(rdlen < len) {
  -    int this_time = recv(sd, 
  -                      (char *)b + rdlen, 
  -                      len - rdlen, 
  -                      0);    
  -    if(-1 == this_time) {
  +    jk_channel_socket_data_t *chD=endpoint->channelData;
  +    int sd;
  +    int rdlen;
  +
  +    if( chD==NULL ) 
  +     return JK_FALSE;
  +    sd=chD->sock;
  +    rdlen = 0;
  +    
  +    while(rdlen < len) {
  +     int this_time = recv(sd, 
  +                          (char *)b + rdlen, 
  +                          len - rdlen, 
  +                          0);        
  +     if(-1 == this_time) {
   #ifdef WIN32
  -      if(SOCKET_ERROR == this_time) { 
  -     errno = WSAGetLastError() - WSABASEERR;
  -      }
  +         if(SOCKET_ERROR == this_time) { 
  +             errno = WSAGetLastError() - WSABASEERR;
  +         }
   #endif /* WIN32 */
  -      
  -      if(EAGAIN == errno) {
  -     continue;
  -      } 
  -      return -1;
  -    }
  -    if(0 == this_time) {
  -      return -1; 
  -    }
  -    rdlen += this_time;
  -  }
  -  return rdlen;
  +         
  +         if(EAGAIN == errno) {
  +             continue;
  +         } 
  +         return -1;
  +     }
  +     if(0 == this_time) {
  +         return -1; 
  +     }
  +     rdlen += this_time;
  +    }
  +    return rdlen; 
   }
   
  +
  +
   int JK_METHOD jk_channel_socket_factory(jk_env_t *env, void **result,
                                        char *type, char *name)
   {
  -  jk_channel_t *channel;
  -
  -  channel=(jk_channel_t *)malloc( sizeof( jk_channel_t));
  -  /* channel->send= &jk_channel_socket_send; */
  -
  -
  -  *result= & channel;
  -  
  -  return JK_TRUE;
  +    jk_channel_t *channel;
  +    
  +    if( strcmp( "channel", type ) != 0 ) {
  +     /* Wrong type  XXX throw */
  +     *result=NULL;
  +     return JK_FALSE;
  +    }
  +    channel=(jk_channel_t *)malloc( sizeof( jk_channel_t));
  +    channel->_privatePtr= (jk_channel_socket_private_t *)
  +     malloc( sizeof( jk_channel_socket_private_t));
  +
  +    channel->recv= &jk_channel_socket_recv; 
  +    channel->send= &jk_channel_socket_send; 
  +    channel->init= &jk_channel_socket_init; 
  +    channel->open= &jk_channel_socket_open; 
  +    channel->close= &jk_channel_socket_close; 
  +    channel->getProperty= &jk_channel_socket_getProperty; 
  +    channel->setProperty= &jk_channel_socket_setProperty; 
  +
  +    channel->supportedProperties=( char ** )malloc( 4 * sizeof( char * ));
  +    channel->supportedProperties[0]="host";
  +    channel->supportedProperties[1]="port";
  +    channel->supportedProperties[2]="defaultPort";
  +    channel->supportedProperties[3]="\0";
  +
  +    channel->name="file";
  +    
  +    *result= channel;
  +    
  +    return JK_TRUE;
   }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to