Back to index

im-sdk  12.3.91
Public Types | Public Member Functions | Private Member Functions | Private Attributes
IMSocketAddress Class Reference

#include <IMUtil.hh>

Collaboration diagram for IMSocketAddress:
Collaboration graph
[legend]

List of all members.

Public Types

enum  ADDRESS_TYPE { INET, UNIX_DOMAIN, UNIX_DOMAIN_PER_USER }
enum  TRANSPORT_TYPE { NORMAL, TLS }

Public Member Functions

int create_sockets (IMSocketVec &sockvec)
 IMSocketAddress (ADDRESS_TYPE type, const string &address, const string &service)
 IMSocketAddress (ADDRESS_TYPE type, TRANSPORT_TYPE trans_type, const string &address, const string &service)
 ~IMSocketAddress ()

Private Member Functions

void * get_addrinfo ()
void configure_socket (int fd)
void bind_fail (int fd)
int setup_inet (void *paddressinfo)
int setup_unix ()

Private Attributes

ADDRESS_TYPE type
TRANSPORT_TYPE trans_type
string address
string service
void * addrinfo
bool is_dir_created

Detailed Description

Definition at line 60 of file IMUtil.hh.


Member Enumeration Documentation

Enumerator:
INET 
UNIX_DOMAIN 
UNIX_DOMAIN_PER_USER 

Definition at line 63 of file IMUtil.hh.

Enumerator:
NORMAL 
TLS 

Definition at line 68 of file IMUtil.hh.

                        {
            NORMAL,
            TLS
    };

Constructor & Destructor Documentation

IMSocketAddress::IMSocketAddress ( ADDRESS_TYPE  type,
const string &  address,
const string &  service 
)

Definition at line 665 of file IMUtil.cpp.

  : trans_type(NORMAL), type(x_type), address(x_address), service(x_service)
{
    addrinfo = NULL;
    is_dir_created = false;
}
IMSocketAddress::IMSocketAddress ( ADDRESS_TYPE  type,
TRANSPORT_TYPE  trans_type,
const string &  address,
const string &  service 
)

Definition at line 676 of file IMUtil.cpp.

  : trans_type(x_trans), type(x_type), address(x_address), service(x_service)
{
    addrinfo = NULL;
    is_dir_created = false;
}

Definition at line 641 of file IMUtil.cpp.

{
    if (addrinfo) {
       freeaddrinfo((struct addrinfo*) addrinfo);
    }
#if defined(HAVE_UNIX_SOCKET)
    if (type == UNIX_DOMAIN || type == UNIX_DOMAIN_PER_USER) {
        sockaddr_un sun_addr;
       string dir = address.substr(0, address.find(".iiimp-unix", 0));

        snprintf(sun_addr.sun_path, sizeof(sun_addr.sun_path), "%s/%s",
            address.c_str(), service.c_str());
        sun_addr.sun_path[sizeof(sun_addr.sun_path) -1] = '\0';
        unlink (sun_addr.sun_path);
       if (is_dir_created || dir != address) {
           /* try to remove a socket directory which was made by iiimd itself
              or was expected for IIIMF */
           rmdir(address.c_str());
       }
    }
#endif
}

Member Function Documentation

void IMSocketAddress::bind_fail ( int  fd) [private]

Definition at line 441 of file IMUtil.cpp.

{
    int e = errno;

    LOG_ERROR("Fail to bind socket: %s:%s", address.c_str(), service.c_str());
#ifdef EADDRINUSE
    const int err_addr_in_use = EADDRINUSE;
#else
    const int err_addr_in_use = EINVAL;
#endif
    if (e == err_addr_in_use) {
       LOG_ERROR("Another IIIMP server might be running(address already in use).");
    }

    close(fd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void IMSocketAddress::configure_socket ( int  fd) [private]

Definition at line 461 of file IMUtil.cpp.

{
    int reuse = 1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
}

Here is the caller graph for this function:

Definition at line 585 of file IMUtil.cpp.

{
    if (type == INET) {
       int i = 0;
       int fd;
       struct addrinfo *pai = (struct addrinfo*) get_addrinfo();
       IMSocket *ps;

       for (; pai; pai = pai->ai_next) {
           fd = setup_inet(pai);
           if (fd < 0) continue;
           ps = new IMSocket(fd, trans_type);
           // it should be dealt with memory exception.
           if (!ps) {
              close(fd);
              return -1;
           }
           sockvec.push_back(ps);
           i++;
       }

       if (i == 0) {
           LOG_CRITICAL("Failed to create any sockets for %s:%s ... exit.",
                      address.c_str(), service.c_str());
           exit(255);
       }

       return i;
    } else if (type == UNIX_DOMAIN || type == UNIX_DOMAIN_PER_USER) {
       IMSocket *ps;
       int fd = setup_unix();

       if (fd >= 0) {
           ps = new IMSocket(fd, trans_type);
           if (!ps) {
              close(fd);
              return -1;
           }
       }
       if (fd < 0) {
           LOG_CRITICAL("Failed to create a unix domain socket for %s:%s ... exit.",
                      address.c_str(), service.c_str());
           exit(255);
       }

       sockvec.push_back(ps);
       return 1;
    }

    ERROR_INTERNAL("invalid IMSocketAddress type");

    return 0;
}

Here is the call graph for this function:

void * IMSocketAddress::get_addrinfo ( ) [private]

Definition at line 417 of file IMUtil.cpp.

{
    struct addrinfo hints, *pst;
    int st;

    if (addrinfo) return addrinfo;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    if (!address.c_str()) hints.ai_flags = AI_PASSIVE;
    st = getaddrinfo(address.c_str(), service.c_str(), &hints, &pst);
    if (st != 0) {
       LOG_ERROR("Fail to getaddrinfo:%s, %s",
                address.c_str(), service.c_str());
       return NULL;
    }

    addrinfo = pst;

    return pst;
}

Here is the caller graph for this function:

int IMSocketAddress::setup_inet ( void *  paddressinfo) [private]

Definition at line 470 of file IMUtil.cpp.

{
    struct addrinfo *pai = (struct addrinfo*) paddressinfo;

    int fd = socket(pai->ai_family, pai->ai_socktype, pai->ai_protocol);

    if (fd < 0) {
       LOG_ERROR("Cannot open socket for %s:%s",
                address.c_str(), service.c_str());
       return -1;
    }

    configure_socket(fd);

    if (bind(fd, pai->ai_addr, pai->ai_addrlen) < 0) {
       bind_fail(fd);
       return -1;
    }

    return fd;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMSocketAddress::setup_unix ( ) [private]

Definition at line 495 of file IMUtil.cpp.

{

#if defined(HAVE_UNIX_SOCKET)
    struct stat st;
    string srvc;

    srvc = service.c_str();
    if (srvc.size() != 0) {

       memset(&st, 0, sizeof(st));
       if (lstat(address.c_str(), &st) == 0) {
           if (S_ISDIR(st.st_mode) && (st.st_mode & (S_IXUSR | S_IWUSR))
              && !S_ISLNK(st.st_mode)) {
           } else {
              return -1;
           }
       } else {
           mode_t mode = (type == UNIX_DOMAIN) ? 0755 : 0700;
           string dir = address.substr(0, address.find(".iiimp-unix", 0));

           if (lstat(dir.c_str(), &st) == 0) {
              if (S_ISDIR(st.st_mode) && (st.st_mode & (S_IXUSR | S_IWUSR))
                  && !S_ISLNK(st.st_mode)) {
                  /* just try to make address directory */
                  if (mkdir(address.c_str(), mode) < 0) {
                     return -1;
                  }
              } else {
                  return -1;
              }
           } else {
              /* base directory like /var/run/iiim is missing. */
              if (!mkdir(dir.c_str(), mode)) {
                  if (mkdir(address.c_str(), mode) < 0) {
                     return -1;
                  }
              } else {
                  return -1;
              }
           }
       }
    }

    int fd = socket(AF_UNIX, SOCK_STREAM, 0);

    if (fd == -1) {
       LOG_ERROR("Cannot open socket. (%s)", address.c_str());
       return false;
    }

    configure_socket(fd);

    struct sockaddr_un sun_addr;

    if (srvc.size() != 0) {
       snprintf(sun_addr.sun_path, sizeof(sun_addr.sun_path), "%s/%s",
               address.c_str(), service.c_str());
    } else {
       strncpy(sun_addr.sun_path, address.c_str(), sizeof(sun_addr.sun_path));
    }
    sun_addr.sun_path[sizeof(sun_addr.sun_path) -1] = '\0';
    sun_addr.sun_family = AF_UNIX;

    size_t size = (offsetof(struct sockaddr_un, sun_path)
       + strlen (sun_addr.sun_path) + 1);

    if (unlink(sun_addr.sun_path) < 0) {
       if (errno != ENOENT) {
              bind_fail (fd);
              return -1;
       }
    }

    mode_t new_mask = (type == UNIX_DOMAIN) ? 0 : 077;
    mode_t old_mask = umask(new_mask);
    if (bind(fd, (struct sockaddr*) &sun_addr, size) < 0) {
       bind_fail(fd);
       unlink(sun_addr.sun_path);
       return -1;
    }
    umask(old_mask);

    return fd;
#else
    return -1;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

string IMSocketAddress::address [private]

Definition at line 76 of file IMUtil.hh.

void* IMSocketAddress::addrinfo [private]

Definition at line 78 of file IMUtil.hh.

Definition at line 79 of file IMUtil.hh.

string IMSocketAddress::service [private]

Definition at line 77 of file IMUtil.hh.

Definition at line 75 of file IMUtil.hh.

Definition at line 74 of file IMUtil.hh.


The documentation for this class was generated from the following files: