OZ++ Class: AddressInfoList |
/****************************************************************************** * * Copyright (c) 2014 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer. * * 2. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * AddressInfoList.h * *****************************************************************************/ #pragma once #include <oz++/CommonObject.h> #include <oz++/Exception.h> #include <oz++/CharString.h> #include <oz++/AddressInfoHints.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> /* struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; */ namespace OZ { class AddressInfoList :public CommonObject { private: addrinfo* info; int count; CharString name; CharString service; public: AddressInfoList(const char* node, const char* service, const addrinfo* hints = NULL) :info(NULL), count(0), name(node), service(service) { /* Specifying hints as NULL is equivalent to setting ai_socktype and ai_protocol to 0; ai_family to AF_UNSPEC; and ai_flags to (AI_V4MAPPED | AI_ADDRCONFIG). */ int rc = getaddrinfo(node, service, hints, &(this->info)); if (rc < 0) { throw IException("Failed to getaddrinfo node=%s, service=%s; error=%s", node, service, gai_strerror(rc) ); } //How many entries does the info contain? count = 0; addrinfo* ptr = NULL;; for (ptr = this->info; ptr!=NULL; ptr=ptr->ai_next) { count++; } } public: ~AddressInfoList() { if (this->info) { freeaddrinfo(this->info); this->info = NULL; } } const addrinfo* getInfo() const { return this->info; } int getCount() const { return this->count; } const addrinfo* getNth(int n) { int i = 0; addrinfo* ptr = NULL; if (n < 0 || n >= this->count) { throw IException("Index is out of range"); } for(ptr = this->info; ptr!= NULL; ptr=ptr->ai_next) { if (i == n) { break; } i++; } return ptr; } public: void display() { printf("node =%s, service = %s \n", (const char*)name, (const char*)service); int i = 0; addrinfo* ptr = NULL;; for (ptr = this->info; ptr!=NULL; ptr=ptr->ai_next) { printf("flags [%d] = %d\n", i, ptr->ai_flags); printf("family [%d] = %d\n", i, ptr->ai_family); printf("socktype [%d] = %d\n", i, ptr->ai_socktype); printf("protocol [%d] = %d\n", i, ptr->ai_protocol); printf("addrlen [%d] = %d\n", i, ptr->ai_addrlen); /* printf("protocol = %d\n", struct sockaddr *ai_addr; */ printf("canonname[%d] = %s\n", i, ptr->ai_canonname); i++; } } }; }