gethostbyname isn't reentrant, who knew...
authorMark Spencer <markster@digium.com>
Thu, 22 Apr 2004 00:20:34 +0000 (00:20 +0000)
committerMark Spencer <markster@digium.com>
Thu, 22 Apr 2004 00:20:34 +0000 (00:20 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2734 65c4cc65-6c06-0410-ace0-fbb531ad65f3

12 files changed:
acl.c
apps/app_festival.c
asterisk.c
astman/astman.c
channels/chan_h323.c
channels/chan_iax.c
channels/chan_iax2.c
channels/chan_mgcp.c
channels/chan_sip.c
channels/chan_skinny.c
include/asterisk/lock.h
utils/astman.c

diff --git a/acl.c b/acl.c
index 1ec629f..f698ec3 100755 (executable)
--- a/acl.c
+++ b/acl.c
@@ -139,7 +139,8 @@ int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
 int ast_get_ip(struct sockaddr_in *sin, char *value)
 {
        struct hostent *hp;
-       hp = gethostbyname(value);
+       struct ast_hostent ahp;
+       hp = ast_gethostbyname(value, &ahp);
        if (hp) {
                memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
        } else {
index fbe63cd..99b6226 100755 (executable)
@@ -250,6 +250,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
        struct localuser *u;
        struct sockaddr_in serv_addr;
        struct hostent *serverhost;
+       struct ast_hostent ahp;
        int fd;
        FILE *fs;
        char *host;
@@ -330,7 +331,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
         memset(&serv_addr, 0, sizeof(serv_addr));
         if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
                /* its a name rather than an ipnum */
-               serverhost = gethostbyname(host);
+               serverhost = ast_gethostbyname(host, &ahp);
                if (serverhost == (struct hostent *)0) {
                        ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n");
                        return -1;
index bc743be..eab37a8 100755 (executable)
@@ -46,6 +46,7 @@
 #include "editline/histedit.h"
 #include "asterisk.h"
 #include <asterisk/config.h>
+#include <asterisk/lock.h>
 
 #define AST_MAX_CONNECTS 128
 #define NUM_MSGS 64
@@ -1675,3 +1676,15 @@ int main(int argc, char *argv[])
        }
        return 0;
 }
+
+struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
+{
+       int res;
+       int h_errno;
+       struct hostent *result = NULL;
+       /* XXX Does BSD do this differently? XXX */
+       res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &h_errno);
+       if (res)
+               return NULL;
+       return &hp->hp;
+}
index 5ed3552..1b5cd50 100755 (executable)
@@ -23,6 +23,8 @@
 #include <asterisk/md5.h>
 #include <asterisk/manager.h>
 
+#undef gethostbyname
+
 #define MAX_HEADERS 80
 #define MAX_LEN 256
 
index 1dd16da..dc8b0ce 100755 (executable)
@@ -1437,7 +1437,7 @@ int reload_config(void)
        struct oh323_peer *peer   = NULL;
        struct oh323_user *user   = NULL;
        struct oh323_alias *alias = NULL;
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        char *cat;
        char *utype;
        
@@ -1464,7 +1464,7 @@ int reload_config(void)
                if (!strcasecmp(v->name, "port")) {
                        port = (int)strtol(v->value, NULL, 10);
                } else if (!strcasecmp(v->name, "bindaddr")) {
-                       if (!(hp = gethostbyname(v->value))) {
+                       if (!(hp = ast_gethostbyname(v->value, &ahp))) {
                                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
                        } else {
                                memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
index 6123a1c..962c6ea 100755 (executable)
@@ -1663,7 +1663,7 @@ static struct iax_user *mysql_user(char *user)
 
 static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, int *maxtime, char *peer, char *context)
 {
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        struct iax_peer *p;
        int found=0;
        if (sendani)
@@ -1710,7 +1710,7 @@ static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, i
        }
        ast_mutex_unlock(&peerl.lock);
        if (!p && !found) {
-               hp = gethostbyname(peer);
+               hp = ast_gethostbyname(peer, &ahp);
                if (hp) {
                        memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
                        sin->sin_port = htons(AST_DEFAULT_IAX_PORTNO);
@@ -3358,7 +3358,7 @@ static int iax_register(char *value, int lineno)
        char *porta;
        char *stringp=NULL;
        
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        if (!value)
                return -1;
        strncpy(copy, value, sizeof(copy)-1);
@@ -3380,7 +3380,7 @@ static int iax_register(char *value, int lineno)
                ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
                return -1;
        }
-       hp = gethostbyname(hostname);
+       hp = ast_gethostbyname(hostname, &ahp);
        if (!hp) {
                ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
                return -1;
index 42f0efc..bdf83c6 100755 (executable)
@@ -1925,7 +1925,7 @@ static struct iax2_user *mysql_user(char *user)
 
 static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, int *maxtime, char *peer, char *context, int *trunk, int *notransfer, char *secret, int seclen)
 {
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        struct iax2_peer *p;
        int found=0;
        if (sendani)
@@ -1980,7 +1980,7 @@ static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, i
                }
        }
        if (!p && !found) {
-               hp = gethostbyname(peer);
+               hp = ast_gethostbyname(peer, &ahp);
                if (hp) {
                        memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
                        sin->sin_port = htons(IAX_DEFAULT_PORTNO);
@@ -3860,7 +3860,7 @@ static int iax2_register(char *value, int lineno)
        char *porta;
        char *stringp=NULL;
        
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        if (!value)
                return -1;
        strncpy(copy, value, sizeof(copy)-1);
@@ -3882,7 +3882,7 @@ static int iax2_register(char *value, int lineno)
                ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
                return -1;
        }
-       hp = gethostbyname(hostname);
+       hp = ast_gethostbyname(hostname, &ahp);
        if (!hp) {
                ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
                return -1;
index e2cf8e4..34344ba 100755 (executable)
@@ -1573,7 +1573,7 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
        int peercapability, peerNonCodecCapability;
        struct sockaddr_in sin;
        char *codecs;
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        int codec;
        int iterator;
     struct mgcp_endpoint *p = sub->parent;
@@ -1590,7 +1590,7 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
                return -1;
        }
        /* XXX This could block for a long time, and block the main thread! XXX */
-       hp = gethostbyname(host);
+       hp = ast_gethostbyname(host, &ahp);
        if (!hp) {
                ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
                return -1;
@@ -1772,7 +1772,7 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
        struct sockaddr_in dest;
     struct mgcp_endpoint *p = sub->parent;
        /* XXX We break with the "recommendation" and send our IP, in order that our
-              peer doesn't have to gethostbyname() us XXX */
+              peer doesn't have to ast_gethostbyname() us XXX */
        len = 0;
        if (!sub->rtp) {
                ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
@@ -3651,7 +3651,7 @@ static int reload_config(void)
        struct mgcp_gateway *g;
        struct mgcp_endpoint *e;
        char *cat;
-       struct hostent *hp;
+       struct ast_hostent ahp; struct hostent *hp;
        int format;
        
        if (gethostname(ourhost, sizeof(ourhost))) {
@@ -3670,7 +3670,7 @@ static int reload_config(void)
        while(v) {
                /* Create the interface list */
                if (!strcasecmp(v->name, "bindaddr")) {
-                       if (!(hp = gethostbyname(v->value))) {
+                       if (!(hp = ast_gethostbyname(v->value, &ahp))) {
                                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
                        } else {
                                memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
@@ -3749,7 +3749,7 @@ static int reload_config(void)
        if (ntohl(bindaddr.sin_addr.s_addr)) {
                memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
        } else {
-               hp = gethostbyname(ourhost);
+               hp = ast_gethostbyname(ourhost, &ahp);
                if (!hp) {
                        ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n");
             ast_destroy(cfg);
index a264aac..ddf8088 100755 (executable)
@@ -808,6 +808,7 @@ static struct sip_peer *mysql_peer(char *peer, struct sockaddr_in *sin)
 static int create_addr(struct sip_pvt *r, char *peer)
 {
        struct hostent *hp;
+       struct ast_hostent ahp;
        struct sip_peer *p;
        int found=0;
        char *port;
@@ -905,7 +906,7 @@ static int create_addr(struct sip_pvt *r, char *peer)
                                portno = tportno;
                        }
                }
-               hp = gethostbyname(hostn);
+               hp = ast_gethostbyname(hostn, &ahp);
                if (hp) {
                        strncpy(r->tohost, peer, sizeof(r->tohost) - 1);
                        memcpy(&r->sa.sin_addr, hp->h_addr, sizeof(r->sa.sin_addr));
@@ -1858,6 +1859,7 @@ static int sip_register(char *value, int lineno)
        char *stringp=NULL;
        
        struct hostent *hp;
+       struct ast_hostent ahp;
        if (!value)
                return -1;
        strncpy(copy, value, sizeof(copy)-1);
@@ -1893,7 +1895,7 @@ static int sip_register(char *value, int lineno)
                ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
                return -1;
        }
-       hp = gethostbyname(hostname);
+       hp = ast_gethostbyname(hostname, &ahp);
        if (!hp) {
                ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
                return -1;
@@ -2011,6 +2013,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
        struct sockaddr_in sin;
        char *codecs;
        struct hostent *hp;
+       struct ast_hostent ahp;
        int codec;
        int iterator;
        int sendonly = 0;
@@ -2032,7 +2035,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
                return -1;
        }
        /* XXX This could block for a long time, and block the main thread! XXX */
-       hp = gethostbyname(host);
+       hp = ast_gethostbyname(host, &ahp);
        if (!hp) {
                ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
                return -1;
@@ -2315,6 +2318,7 @@ static void set_destination(struct sip_pvt *p, char *uri)
        char *h, *maddr, hostname[256];
        int port, hn;
        struct hostent *hp;
+       struct ast_hostent ahp;
 
        /* Parse uri to h (host) and port - uri is already just the part inside the <> */
        /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
@@ -2356,7 +2360,7 @@ static void set_destination(struct sip_pvt *p, char *uri)
                strncpy(hostname, maddr, hn);  hostname[hn] = '\0';
        }
        
-       hp = gethostbyname(hostname);
+       hp = ast_gethostbyname(hostname, &ahp);
        if (hp == NULL)  {
                ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
                return;
@@ -2646,7 +2650,7 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
        struct sockaddr_in dest;
        struct sockaddr_in vdest = { 0, };
        /* XXX We break with the "recommendation" and send our IP, in order that our
-              peer doesn't have to gethostbyname() us XXX */
+              peer doesn't have to ast_gethostbyname() us XXX */
        len = 0;
        if (!p->rtp) {
                ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
@@ -3220,6 +3224,7 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth, char
        char via[80];
        char addr[80];
        struct sip_pvt *p;
+       struct ast_hostent ahp;
        struct hostent *hp;
 
        /* exit if we are already in process with this registrar ?*/
@@ -3261,7 +3266,7 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth, char
                  based on whether the remote host is on the external or
                  internal network so we can register through nat
                 */
-               if ((hp = gethostbyname(r->hostname))) {
+               if ((hp = ast_gethostbyname(r->hostname, &ahp))) {
                        if (ast_sip_ouraddrfor((struct in_addr *)hp->h_addr, &p->ourip))
                                memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip));
                }
@@ -3468,6 +3473,7 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
        char *c, *n, *pt;
        int port;
        struct hostent *hp;
+       struct ast_hostent ahp;
        struct sockaddr_in oldsin;
        if (!strlen(expires)) {
                expires = strstr(get_header(req, "Contact"), "expires=");
@@ -3529,7 +3535,7 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
        memcpy(&oldsin, &p->addr, sizeof(oldsin));
        if (!p->nat) {
                /* XXX This could block for a long time XXX */
-               hp = gethostbyname(n);
+               hp = ast_gethostbyname(n, &ahp);
                if (!hp)  {
                        ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
                        return -1;
@@ -4162,6 +4168,7 @@ static int check_via(struct sip_pvt *p, struct sip_request *req)
        char via[256] = "";
        char *c, *pt;
        struct hostent *hp;
+       struct ast_hostent ahp;
 
        memset(via, 0, sizeof(via));
        strncpy(via, get_header(req, "Via"), sizeof(via) - 1);
@@ -4183,7 +4190,7 @@ static int check_via(struct sip_pvt *p, struct sip_request *req)
                        *pt = '\0';
                        pt++;
                }
-               hp = gethostbyname(c);
+               hp = ast_gethostbyname(c, &ahp);
                if (!hp) {
                        ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
                        return -1;
@@ -6025,6 +6032,7 @@ static int sip_devicestate(void *data)
        char *dest = data;
 
        struct hostent *hp;
+       struct ast_hostent ahp;
        struct sip_peer *p;
        int found = 0;
 
@@ -6058,7 +6066,7 @@ static int sip_devicestate(void *data)
        }
        ast_mutex_unlock(&peerl.lock);
        if (!p && !found) {
-               hp = gethostbyname(host);
+               hp = ast_gethostbyname(host, &ahp);
                if (hp)
                        res = AST_DEVICE_UNKNOWN;
        }
@@ -6439,6 +6447,7 @@ static int reload_config(void)
        struct ast_variable *v;
        struct sip_peer *peer;
        struct sip_user *user;
+       struct ast_hostent ahp;
        char *cat;
     char *utype;
        struct hostent *hp;
@@ -6523,23 +6532,23 @@ static int reload_config(void)
                        if (default_expiry < 1)
                                default_expiry = DEFAULT_DEFAULT_EXPIRY;
                } else if (!strcasecmp(v->name, "bindaddr")) {
-                       if (!(hp = gethostbyname(v->value))) {
+                       if (!(hp = ast_gethostbyname(v->value, &ahp))) {
                                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
                        } else {
                                memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
                        }
                } else if (!strcasecmp(v->name, "localnet")) {
-                       if (!(hp = gethostbyname(v->value)))
+                       if (!(hp = ast_gethostbyname(v->value, &ahp)))
                                ast_log(LOG_WARNING, "Invalid localnet keyword: %s\n", v->value);
                        else 
                                memcpy(&localnet.sin_addr, hp->h_addr, sizeof(localnet.sin_addr));
                } else if (!strcasecmp(v->name, "localmask")) {
-                       if (!(hp = gethostbyname(v->value)))
+                       if (!(hp = ast_gethostbyname(v->value, &ahp)))
                                ast_log(LOG_WARNING, "Invalid localmask keyword: %s\n", v->value);
                        else
                                memcpy(&localmask.sin_addr, hp->h_addr, sizeof(localmask.sin_addr));
                } else if (!strcasecmp(v->name, "externip")) {
-                       if (!(hp = gethostbyname(v->value))) 
+                       if (!(hp = ast_gethostbyname(v->value, &ahp))) 
                                ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
                        else
                                memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
@@ -6631,7 +6640,7 @@ static int reload_config(void)
        if (ntohl(bindaddr.sin_addr.s_addr)) {
                memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
        } else {
-               hp = gethostbyname(ourhost);
+               hp = ast_gethostbyname(ourhost, &ahp);
                if (!hp) {
                        ast_log(LOG_WARNING, "Unable to get IP address for %s, SIP disabled\n", ourhost);
                        return 0;
index ceb2d66..e473f23 100755 (executable)
@@ -482,7 +482,7 @@ static struct sockaddr_in bindaddr;
 static char ourhost[256];
 static int ourport;
 static struct in_addr __ourip;
-struct hostent *hp;
+struct ast_hostent ahp; struct hostent *hp;
 static int skinnysock  = -1;
 static pthread_t tcp_thread;
 static pthread_t accept_t;
@@ -2511,7 +2511,7 @@ static int reload_config(void)
        while(v) {
                /* Create the interface list */
                if (!strcasecmp(v->name, "bindaddr")) {
-                       if (!(hp = gethostbyname(v->value))) {
+                       if (!(hp = ast_gethostbyname(v->value, &ahp))) {
                                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
                        } else {
                                memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
@@ -2545,7 +2545,7 @@ static int reload_config(void)
        if (ntohl(bindaddr.sin_addr.s_addr)) {
                memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
        } else {
-               hp = gethostbyname(ourhost);
+               hp = ast_gethostbyname(ourhost, &ahp);
                if (!hp) {
                        ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n");
                        return 0;
index 9542dbe..0352379 100755 (executable)
@@ -15,6 +15,7 @@
 #define _ASTERISK_LOCK_H
 
 #include <pthread.h>
+#include <netdb.h>
 
 #define AST_PTHREADT_NULL (pthread_t) -1
 #define AST_PTHREADT_STOP (pthread_t) -2
@@ -177,5 +178,12 @@ static inline int ast_mutex_init(ast_mutex_t *t)
 
 #endif /* DEBUG_THREADS */
 
+#define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
+struct ast_hostent {
+       struct hostent hp;
+       char buf[1024];
+};
+
+extern struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
 
 #endif
index 5ed3552..1b5cd50 100755 (executable)
@@ -23,6 +23,8 @@
 #include <asterisk/md5.h>
 #include <asterisk/manager.h>
 
+#undef gethostbyname
+
 #define MAX_HEADERS 80
 #define MAX_LEN 256