Beispiel #1
0
void *ProxyListSessions(struct mansession *s) {
	struct message m;
	struct mansession *c;
	char iabuf[INET_ADDRSTRLEN];

	memset(&m, 0, sizeof(struct message));
	AddHeader(&m, "ProxyResponse: Success");

	pthread_rwlock_rdlock(&sessionlock);
	c = sessions;
	while (c && (m.hdrcount < MAX_HEADERS - 4) ) {
		if (!c->server) {
			AddHeader(&m, "ProxyClientSession: %s", ast_inet_ntoa(iabuf, sizeof(iabuf), c->sin.sin_addr));
			AddHeader(&m, "ProxyClientActionID: %s", c->actionid);
			AddHeader(&m, "ProxyClientInputHandler: %s", c->input->formatname);
			AddHeader(&m, "ProxyClientOutputHandler: %s", c->output->formatname);
		} else 
			AddHeader(&m, "ProxyServerSession: %s", ast_inet_ntoa(iabuf, sizeof(iabuf), c->sin.sin_addr));
		c = c->next;
	}
	pthread_rwlock_unlock(&sessionlock);

	s->output->write(s, &m);
	FreeHeaders(&m);
	return 0;
}
Beispiel #2
0
int ooGetLocalIPAddress(char * pIPAddrs)
{
   int ret;
   struct hostent *hp;
   struct ast_hostent phost;
   char hostname[100];

   if(pIPAddrs == NULL)
      return -1; /* Need to find suitable return value */
   ret = gethostname(hostname, 100);
   if(ret == 0)
   {
      if ((hp = ast_gethostbyname(hostname, &phost))) {
			if (hp->h_addrtype == AF_INET6) {
				struct in6_addr i;
				memcpy(&i, hp->h_addr, sizeof(i));
				strcpy(pIPAddrs, (inet_ntop(AF_INET6, &i, 
				hostname, sizeof(hostname))) == NULL ? "::1" : 
				inet_ntop(AF_INET6, &i, hostname, sizeof(hostname)));
			} else {
	  			struct in_addr i;
				memcpy(&i, hp->h_addr, sizeof(i));
			  	strcpy(pIPAddrs, (ast_inet_ntoa(i) == NULL) ? "127.0.0.1" : ast_inet_ntoa(i));
			}
      } else {
         return -1;
      }
   }
   else{
      return -1;
   }
   return ASN_OK;
}
Beispiel #3
0
static void http_server_start(struct sockaddr_in *sin)
{
	char iabuf[INET_ADDRSTRLEN];
	int flags;
	int x = 1;
	
	/* Do nothing if nothing has changed */
	if (!memcmp(&oldsin, sin, sizeof(oldsin))) {
		ast_log(LOG_DEBUG, "Nothing changed in http\n");
		return;
	}
	
	memcpy(&oldsin, sin, sizeof(oldsin));
	
	/* Shutdown a running server if there is one */
	if (master != AST_PTHREADT_NULL) {
		pthread_cancel(master);
		pthread_kill(master, SIGURG);
		pthread_join(master, NULL);
	}
	
	if (httpfd != -1)
		close(httpfd);

	/* If there's no new server, stop here */
	if (!sin->sin_family)
		return;
	
	
	httpfd = socket(AF_INET, SOCK_STREAM, 0);
	if (httpfd < 0) {
		ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
		return;
	}
	
	setsockopt(httpfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
	if (bind(httpfd, (struct sockaddr *)sin, sizeof(*sin))) {
		ast_log(LOG_NOTICE, "Unable to bind http server to %s:%d: %s\n",
			ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port),
			strerror(errno));
		close(httpfd);
		httpfd = -1;
		return;
	}
	if (listen(httpfd, 10)) {
		ast_log(LOG_NOTICE, "Unable to listen!\n");
		close(httpfd);
		httpfd = -1;
		return;
	}
	flags = fcntl(httpfd, F_GETFL);
	fcntl(httpfd, F_SETFL, flags | O_NONBLOCK);
	if (ast_pthread_create(&master, NULL, http_root, NULL)) {
		ast_log(LOG_NOTICE, "Unable to launch http server on %s:%d: %s\n",
				ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port),
				strerror(errno));
		close(httpfd);
		httpfd = -1;
	}
}
Beispiel #4
0
int ooSocketRecvFrom (OOSOCKET socket, ASN1OCTET* pbuf, ASN1UINT bufsize,
                      char* remotehost, ASN1UINT hostBufLen, int * remoteport)
{
   struct sockaddr_in m_addr;
   int len, addrlen;
   const char * host=NULL;
   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
   addrlen = sizeof(m_addr);

   memset (&m_addr, 0, sizeof (m_addr));
      
   if ((len = recvfrom (socket, (char*) pbuf, bufsize, 0, 
                        (struct sockaddr*)&m_addr, (socklen_t *) &addrlen)) == -1)
      return ASN_E_INVSOCKET;

   if(remoteport)
      *remoteport = ntohs(m_addr.sin_port);
   if(remotehost)
   {
      host = ast_inet_ntoa(m_addr.sin_addr);
      if(strlen(host) < (hostBufLen-1))
         strcpy(remotehost, host);
      else
         return -1;
   }
   return len;
}
Beispiel #5
0
static int add_ipv4_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
		const struct ast_security_event_ipv4_addr *addr)
{
	struct ast_str *str = ast_str_alloca(64);

	ast_str_set(&str, 0, "IPV4/");

	switch (addr->transport) {
	case AST_SECURITY_EVENT_TRANSPORT_UDP:
		ast_str_append(&str, 0, "UDP/");
		break;
	case AST_SECURITY_EVENT_TRANSPORT_TCP:
		ast_str_append(&str, 0, "TCP/");
		break;
	case AST_SECURITY_EVENT_TRANSPORT_TLS:
		ast_str_append(&str, 0, "TLS/");
		break;
	}

	ast_str_append(&str, 0, "%s/%hu",
			ast_inet_ntoa(addr->sin->sin_addr),
			ntohs(addr->sin->sin_port));

	return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
}
Beispiel #6
0
 /** 
 * close a connection
 * @param	c: the connection which will be closed
 ************************************************************/
 void connection_close(connection_t *connection) {
	 assert(connection != NULL);
 
	 char iabuf[INET_ADDRSTRLEN];
	 LM_DBG("*** Disconnect from [%s]\n", ast_inet_ntoa(iabuf, sizeof(iabuf), connection->sin.sin_addr));
 
	 connection_remove_from_list(connection);
 
	 //if (!ret)
	//	 return;
 
	 event_del(&connection->event);
	 close(connection->sfd);
	 pthread_mutex_destroy(&connection->lock);
 /*
	 if (c->pair) {
		 close(c->pair->sfd);
		 pthread_mutex_destroy(&c->pair->lock);
		 free(c->pair);
	 }
 */
	 free(connection);
 
	 return;
 }
Beispiel #7
0
void *ProxyListServers(struct mansession *s) {
	struct message m;
	struct mansession *c;
	char iabuf[INET_ADDRSTRLEN];

	memset(&m, 0, sizeof(struct message));
	AddHeader(&m, "ProxyResponse: Success");

	pthread_rwlock_rdlock(&sessionlock);
	c = sessions;
	while (c) {
		if (c->server) {
			AddHeader(&m, "ProxyListServer I: %s H: %s U: %s P: %s E: %s ",
			ast_inet_ntoa(iabuf, sizeof(iabuf), c->sin.sin_addr),
			c->server->ast_host, c->server->ast_user,
			c->server->ast_port, c->server->ast_events);
		}

		c = c->next;
	}
	pthread_rwlock_unlock(&sessionlock);

	s->output->write(s, &m);
	FreeHeaders(&m);
	return 0;
}
static int handle_show_http(int fd, int argc, char *argv[])
{
	struct ast_http_uri *urih;

	if (argc != 3)
		return RESULT_SHOWUSAGE;

	ast_cli(fd, "HTTP Server Status:\n");
	ast_cli(fd, "Prefix: %s\n", prefix);
	if (oldsin.sin_family)
		ast_cli(fd, "Server Enabled and Bound to %s:%d\n\n",
			ast_inet_ntoa(oldsin.sin_addr),
			ntohs(oldsin.sin_port));
	else
		ast_cli(fd, "Server Disabled\n\n");
	ast_cli(fd, "Enabled URI's:\n");
	ast_rwlock_rdlock(&uris_lock);
	urih = uris;
	while(urih){
		ast_cli(fd, "%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
		urih = urih->next;
	}
	if (!uris)
		ast_cli(fd, "None.\n");
	ast_rwlock_unlock(&uris_lock);

	return RESULT_SUCCESS;
}
Beispiel #9
0
int ooSocketGetIpAndPort(OOSOCKET socket, char *ip, int len, int *port)
{
   int ret=ASN_OK;
   socklen_t size;
   struct sockaddr_in addr;
   const char *host=NULL;

   size = sizeof(addr);

   ret = ooSocketGetSockName(socket, &addr, &size);
   if(ret != 0)
      return ASN_E_INVSOCKET;

   host = ast_inet_ntoa(addr.sin_addr);

   if(host && strlen(host) < (unsigned)len)
      strcpy(ip, host);   
   else{
     OOTRACEERR1("Error:Insufficient buffer for ip address - "
                 "ooSocketGetIpAndPort\n");
      return -1;
   }
   
   *port = addr.sin_port;

   return ASN_OK;
}
Beispiel #10
0
/** 
* connect to as server 
* @param   s: the the connection 
************************************************************/
int emp_server_connect(connection_t *connection) {
	int r = 0, res = 0;
	char iabuf[INET_ADDRSTRLEN];
  	const char *ipaddr = (const char*)ast_inet_ntoa(iabuf, sizeof(iabuf), connection->sin.sin_addr);
  	if (ipaddr == NULL) 
   		 ipaddr = "n/a";
	
	for (;;) {
		if (connect(connection->sfd, (struct sockaddr *) &connection->sin, sizeof(connection->sin)) < 0) {
			++r;
			if (errno == EISCONN) {
				pthread_mutex_lock(&connection->lock);
				connection->sfd = socket(AF_INET, SOCK_STREAM, 0);

				// set socket to nonblock
			/*	
				int flags = 1;
				if ((flags = fcntl(s->sfd, F_GETFL, 0)) < 0 || fcntl(s->sfd, F_SETFL, flags | O_NONBLOCK) < 0) {
				                LM_ERR("setting O_NONBLOCK fail \n");
				                close(s->sfd);
				                continue;
				   }
			*/
				struct event_base *base = connection->event.ev_base;
				if (event_del(&connection->event) == -1) {
					pthread_mutex_unlock(&connection->lock);
					LM_ERR("event_del failed \n");
					continue;
				}
				
				event_assign(&connection->event, base, connection->sfd, EV_READ | EV_PERSIST, server_message_got, (void *)connection);
				
				if (event_add(&connection->event, 0) == -1) {
					pthread_mutex_unlock(&connection->lock);
					LM_ERR("event_del failed \n");
					continue;
				}
				
				pthread_mutex_unlock(&connection->lock);
			}

			LM_DBG("%d> emp_server@%s: Connect failed, Retrying (%04d) %s\n",
				connection->sfd, ipaddr, r, strerror(errno));

			if (proxy_config.maxretries && (r > proxy_config.maxretries)) {
				res = 1;
				break;
			} else
				sleep(proxy_config.retryinterval);
		} else {
			LM_DBG("%d> emp_server@%s connect to emp_server\n", connection->sfd, ipaddr);
			res = 0;
			break;
		}

	}

	return res;
}
Beispiel #11
0
static void score_address(const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
{
	const char *address;
	int score;

	address = ast_inet_ntoa(sin->sin_addr);

	/* RFC 1700 alias for the local network */
	if (address[0] == '0')
		score = -25;
	/* RFC 1700 localnet */
	else if (strncmp(address, "127", 3) == 0)
		score = -20;
	/* RFC 1918 non-public address space */
	else if (strncmp(address, "10.", 3) == 0)
		score = -5;
	/* RFC 1918 non-public address space */
	else if (strncmp(address, "172", 3) == 0) {
		/* 172.16.0.0 - 172.19.255.255, but not 172.160.0.0 - 172.169.255.255 */
		if (address[4] == '1' && address[5] >= '6' && address[6] == '.')
			score = -5;
		/* 172.20.0.0 - 172.29.255.255, but not 172.200.0.0 - 172.255.255.255 nor 172.2.0.0 - 172.2.255.255 */
		else if (address[4] == '2' && address[6] == '.')
			score = -5;
		/* 172.30.0.0 - 172.31.255.255 */
		else if (address[4] == '3' && address[5] <= '1')
			score = -5;
		/* All other 172 addresses are public */
		else
			score = 0;
	/* RFC 2544 Benchmark test range */
	} else if (strncmp(address, "198.1", 5) == 0 && address[5] >= '8' && address[6] == '.')
		score = -10;
	/* RFC 1918 non-public address space */
	else if (strncmp(address, "192.168", 7) == 0)
		score = -5;
	/* RFC 3330 Zeroconf network */
	else if (strncmp(address, "169.254", 7) == 0)
		/*!\note Better score than a test network, but not quite as good as RFC 1918
		 * address space.  The reason is that some Linux distributions automatically
		 * configure a Zeroconf address before trying DHCP, so we want to prefer a
		 * DHCP lease to a Zeroconf address.
		 */
		score = -10;
	/* RFC 3330 Test network */
	else if (strncmp(address, "192.0.2.", 8) == 0)
		score = -15;
	/* Every other address should be publically routable */
	else
		score = 0;

	if (score > *best_score) {
		*best_score = score;
		memcpy(best_addr, &sin->sin_addr, sizeof(*best_addr));
	}
}
Beispiel #12
0
static void dump_addr(char *output, int maxlen, void *value, int len)
{
	struct sockaddr_in sin;
	if (len == (int)sizeof(sin)) {
		memcpy(&sin, value, len);
		snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
	} else {
		ast_copy_string(output, "Invalid Address", maxlen);
	}
}
Beispiel #13
0
struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
{
	int x = 1;
	struct ast_tcptls_session_instance *tcptls_session = NULL;

	/* Do nothing if nothing has changed */
	if (!memcmp(&desc->old_address, &desc->remote_address, sizeof(desc->old_address))) {
		ast_debug(1, "Nothing changed in %s\n", desc->name);
		return NULL;
	}

	desc->old_address = desc->remote_address;

	if (desc->accept_fd != -1)
		close(desc->accept_fd);

	desc->accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (desc->accept_fd < 0) {
		ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
			desc->name, strerror(errno));
		return NULL;
	}

	/* if a local address was specified, bind to it so the connection will
	   originate from the desired address */
	if (desc->local_address.sin_family != 0) {
		setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
		if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) {
			ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n",
			desc->name,
				ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port),
				strerror(errno));
			goto error;
		}
	}

	if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
		goto error;

	ast_mutex_init(&tcptls_session->lock);
	tcptls_session->client = 1;
	tcptls_session->fd = desc->accept_fd;
	tcptls_session->parent = desc;
	tcptls_session->parent->worker_fn = NULL;
	memcpy(&tcptls_session->remote_address, &desc->remote_address, sizeof(tcptls_session->remote_address));

	return tcptls_session;

error:
	close(desc->accept_fd);
	desc->accept_fd = -1;
	if (tcptls_session)
		ao2_ref(tcptls_session, -1);
	return NULL;
}
Beispiel #14
0
int geo_acl_check(struct sockaddr_in *sin, char *allowed_countries, char *peername)
{
	GeoIP * gi;
        const char * returnedCountry;
        gi = GeoIP_open("/opt/GeoIP/share/GeoIP/GeoIP.dat", GEOIP_STANDARD | GEOIP_CHECK_CACHE);
	int retValue = 0;
	int j, i=0; // used to iterate through array
	char lookup[255];
    	char *token[86];
        if (gi == NULL) {
                ast_log(LOG_WARNING, "Failed to open GeoIP Lookup database - ignoring GeoACL");
        } else {
		if((allowed_countries == NULL) || (strlen(allowed_countries) == 0) ) {
			ast_log(LOG_NOTICE, "GeoACL - Peer %s does not have allowed/denied countries defined, ignoring check\n", peername);
		} else {
                	ast_log(LOG_DEBUG, "Using %s for allowed geo acl list\n", allowed_countries);
			returnedCountry = GeoIP_country_code_by_addr(gi,ast_inet_ntoa(sin->sin_addr));
	                if (returnedCountry == NULL) {
        	                ast_log(LOG_WARNING, "GeoACL Lookup failed for '%s' - ignoring GeoACL\n", ast_inet_ntoa(sin->sin_addr));
             	   	} else {
				// Now we default to deny since we know what they want and where the IP is from 
				strcpy(lookup, allowed_countries);
				retValue = 1;			
				//ast_log(LOG_NOTICE, "GeoACL - value of allowed_countries is %s", allowed_countries);						
				token[0] = strtok (lookup,",");
  				while(token[i]!= NULL) {   //ensure a pointer was found
        				i++;
        				token[i] = strtok(NULL, ","); //continue to tokenize the string
    				}
  				for(j = 0; j <= i-1; j++) {
			//		ast_log(LOG_DEBUG, "Checking token %s", token[j]);
					if (strncmp(returnedCountry, token[j], 2) == 0) {
						retValue = 0;
					}
				}
				if (retValue == 1)  {
					ast_log(LOG_NOTICE, "GeoACL - peer '%s' failed ACL check.  Allowed from %s but connected from %s\n", peername, allowed_countries, returnedCountry);
				} else {
                	       		 ast_log(LOG_NOTICE, "GeoACL passed for peer '%s' - connected from '%s'\n", peername, returnedCountry);
                		}
			}
		}
        }
        // Free resources
        GeoIP_delete(gi);
	return retValue;
}
Beispiel #15
0
static char *httpstatus_callback(struct sockaddr_in *req, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
{
	char result[4096];
	size_t reslen = sizeof(result);
	char *c=result;
	struct ast_variable *v;
	char iabuf[INET_ADDRSTRLEN];

	ast_build_string(&c, &reslen,
		"\r\n"
		"<title>Asterisk HTTP Status</title>\r\n"
		"<body bgcolor=\"#ffffff\">\r\n"
		"<table bgcolor=\"#f1f1f1\" align=\"center\"><tr><td bgcolor=\"#e0e0ff\" colspan=\"2\" width=\"500\">\r\n"
		"<h2>&nbsp;&nbsp;Asterisk&trade; HTTP Status</h2></td></tr>\r\n");

	ast_build_string(&c, &reslen, "<tr><td><i>Prefix</i></td><td><b>%s</b></td></tr>\r\n", prefix);
	ast_build_string(&c, &reslen, "<tr><td><i>Bind Address</i></td><td><b>%s</b></td></tr>\r\n",
			ast_inet_ntoa(iabuf, sizeof(iabuf), oldsin.sin_addr));
	ast_build_string(&c, &reslen, "<tr><td><i>Bind Port</i></td><td><b>%d</b></td></tr>\r\n",
			ntohs(oldsin.sin_port));
	ast_build_string(&c, &reslen, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
	v = vars;
	while(v) {
		if (strncasecmp(v->name, "cookie_", 7))
			ast_build_string(&c, &reslen, "<tr><td><i>Submitted Variable '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
		v = v->next;
	}
	ast_build_string(&c, &reslen, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
	v = vars;
	while(v) {
		if (!strncasecmp(v->name, "cookie_", 7))
			ast_build_string(&c, &reslen, "<tr><td><i>Cookie '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
		v = v->next;
	}
	ast_build_string(&c, &reslen, "</table><center><font size=\"-1\"><i>Asterisk and Digium are registered trademarks of Digium, Inc.</i></font></center></body>\r\n");
	return strdup(result);
}
Beispiel #16
0
struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
{
	struct ast_tcptls_session_args *desc;
	int flags;

	if (!(desc = tcptls_session->parent)) {
		goto client_start_error;
	}

	if (connect(desc->accept_fd, (const struct sockaddr *) &desc->remote_address, sizeof(desc->remote_address))) {
		ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n",
			desc->name,
			ast_inet_ntoa(desc->remote_address.sin_addr), ntohs(desc->remote_address.sin_port),
			strerror(errno));
		goto client_start_error;
	}

	flags = fcntl(desc->accept_fd, F_GETFL);
	fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);

	if (desc->tls_cfg) {
		desc->tls_cfg->enabled = 1;
		__ssl_setup(desc->tls_cfg, 1);
	}

	return handle_tcptls_connection(tcptls_session);

client_start_error:
	close(desc->accept_fd);
	desc->accept_fd = -1;
	if (tcptls_session) {
		ao2_ref(tcptls_session, -1);
	}
	return NULL;

}
Beispiel #17
0
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
{
	int flags;
	int x = 1;
	
	/* Do nothing if nothing has changed */
	if (!memcmp(&desc->old_address, &desc->local_address, sizeof(desc->old_address))) {
		ast_debug(1, "Nothing changed in %s\n", desc->name);
		return;
	}
	
	desc->old_address = desc->local_address;
	
	/* Shutdown a running server if there is one */
	if (desc->master != AST_PTHREADT_NULL) {
		pthread_cancel(desc->master);
		pthread_kill(desc->master, SIGURG);
		pthread_join(desc->master, NULL);
	}
	
	if (desc->accept_fd != -1)
		close(desc->accept_fd);

	/* If there's no new server, stop here */
	if (desc->local_address.sin_family == 0) {
		ast_debug(2, "Server disabled:  %s\n", desc->name);
		return;
	}

	desc->accept_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (desc->accept_fd < 0) {
		ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
		return;
	}
	
	setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
	if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) {
		ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n",
			desc->name,
			ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port),
			strerror(errno));
		goto error;
	}
	if (listen(desc->accept_fd, 10)) {
		ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
		goto error;
	}
	flags = fcntl(desc->accept_fd, F_GETFL);
	fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
	if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
		ast_log(LOG_ERROR, "Unable to launch thread for %s on %s:%d: %s\n",
			desc->name,
			ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port),
			strerror(errno));
		goto error;
	}
	return;

error:
	close(desc->accept_fd);
	desc->accept_fd = -1;
}
Beispiel #18
0
/* \brief called by scheduler to send STUN request */
static int stun_monitor_request(const void *blarg)
{
	int res;
	struct sockaddr_in answer;
	static const struct sockaddr_in no_addr = { 0, };

	ast_mutex_lock(&args.lock);
	if (!args.monitor_enabled) {
		goto monitor_request_cleanup;
	}

	if (args.stun_sock < 0) {
		struct ast_sockaddr stun_addr;

		/* STUN socket not open.  Refresh the server DNS address resolution. */
		if (!args.server_hostname) {
			/* No STUN hostname? */
			goto monitor_request_cleanup;
		}

		/* Lookup STUN address. */
		memset(&stun_addr, 0, sizeof(stun_addr));
		stun_addr.ss.ss_family = AF_INET;
		if (ast_get_ip(&stun_addr, args.server_hostname)) {
			/* Lookup failed. */
			ast_log(LOG_WARNING, "Unable to lookup STUN server '%s'\n",
				args.server_hostname);
			goto monitor_request_cleanup;
		}
		ast_sockaddr_set_port(&stun_addr, args.stun_port);

		/* open socket binding */
		args.stun_sock = socket(AF_INET, SOCK_DGRAM, 0);
		if (args.stun_sock < 0) {
			ast_log(LOG_WARNING, "Unable to create STUN socket: %s\n", strerror(errno));
			goto monitor_request_cleanup;
		}
		if (ast_connect(args.stun_sock, &stun_addr)) {
			ast_log(LOG_WARNING, "STUN Failed to connect to %s: %s\n",
				ast_sockaddr_stringify(&stun_addr), strerror(errno));
			stun_close_sock();
			goto monitor_request_cleanup;
		}
	}

	res = ast_stun_request(args.stun_sock, NULL, NULL, &answer);
	if (res) {
		/*
		 * STUN request timed out or errored.
		 *
		 * Refresh the server DNS address resolution next time around.
		 */
		if (!args.stun_poll_failed_gripe) {
			args.stun_poll_failed_gripe = 1;
			ast_log(LOG_WARNING, "STUN poll %s. Re-evaluating STUN server address.\n",
				res < 0 ? "failed" : "got no response");
		}
		stun_close_sock();
	} else {
		args.stun_poll_failed_gripe = 0;
		if (memcmp(&no_addr, &answer, sizeof(no_addr))
			&& memcmp(&args.external_addr, &answer, sizeof(args.external_addr))) {
			const char *newaddr = ast_strdupa(ast_inet_ntoa(answer.sin_addr));
			int newport = ntohs(answer.sin_port);

			ast_log(LOG_NOTICE, "Old external address/port %s:%d now seen as %s:%d.\n",
				ast_inet_ntoa(args.external_addr.sin_addr),
				ntohs(args.external_addr.sin_port), newaddr, newport);

			args.external_addr = answer;

			if (args.external_addr_known) {
				struct ast_event *event;

				/*
				 * The external address was already known, and has changed...
				 * generate event.
				 */
				event = ast_event_new(AST_EVENT_NETWORK_CHANGE, AST_EVENT_IE_END);
				if (!event) {
					ast_log(LOG_ERROR, "Could not create AST_EVENT_NETWORK_CHANGE event.\n");
				} else if (ast_event_queue(event)) {
					ast_event_destroy(event);
					ast_log(LOG_ERROR, "Could not queue AST_EVENT_NETWORK_CHANGE event.\n");
				}
			} else {
				/* this was the first external address we found, do not alert listeners
				 * until this address changes to something else. */
				args.external_addr_known = 1;
			}
		}
	}

monitor_request_cleanup:
	/* always refresh this scheduler item.  It will be removed elsewhere when
	 * it is supposed to go away */
	res = args.refresh * 1000;
	ast_mutex_unlock(&args.lock);

	return res;
}
Beispiel #19
0
static void vgsm_mesim_clnt_activate(struct vgsm_mesim_driver *driver)
{
	struct vgsm_mesim_clnt *mesim_clnt =
			container_of(driver, struct vgsm_mesim_clnt, driver);
	struct vgsm_mesim *mesim = mesim_clnt->mesim;

	assert(mesim_clnt->listen_fd == -1);
	assert(mesim_clnt->sock_fd == -1);

	if (ioctl(mesim->fd, VGSM_IOC_SET_SIM_ROUTE,
				VGSM_SIM_ROUTE_EXTERNAL) < 0) {
		ast_log(LOG_ERROR,
			"%s: ioctl(IOC_SET_SIM_ROUTE, EXTERN)"
			" failed: %s\n",
			mesim->name,
			strerror(errno));
		return;
	}

	mesim_clnt->bind_addr.sin_family = AF_INET;

	mesim_clnt->listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (mesim_clnt->listen_fd < 0) {
		ast_log(LOG_WARNING,
			"Unable to create MESIM socket: %s\n",
			strerror(errno));
		return;
	}

	int on = 1;
	if(setsockopt(mesim_clnt->listen_fd, SOL_SOCKET, SO_REUSEADDR,
					&on, sizeof(on)) == -1) {
		ast_log(LOG_ERROR,
			"Set Socket Options failed: %s\n",
			strerror(errno));
		return;
	}

	if (bind(mesim_clnt->listen_fd,
		(struct sockaddr *)&mesim_clnt->bind_addr,
		sizeof(mesim_clnt->bind_addr)) < 0) {
#if ASTERISK_VERSION_NUM < 010400 || (ASTERISK_VERSION_NUM >= 10200 && ASTERISK_VERSION_NUM < 10400)
		{
		char tmpstr[32];
		ast_inet_ntoa(tmpstr, sizeof(tmpstr),
			mesim_clnt->bind_addr.sin_addr);

			ast_log(LOG_WARNING,
				"Unable to bind MESIM socket to"
				" %s:%d: %s\n",
				tmpstr,
				ntohs(mesim_clnt->bind_addr.sin_port),
				strerror(errno));
		}
#else
			ast_log(LOG_WARNING,
				"Unable to bind MESIM socket to"
				" %s:%d: %s\n",
				ast_inet_ntoa(mesim_clnt->bind_addr.
						sin_addr),
				ntohs(mesim_clnt->bind_addr.sin_port),
				strerror(errno));
#endif

			return;
		}

	if (listen(mesim_clnt->listen_fd, 10)) {
#if ASTERISK_VERSION_NUM < 010400 || (ASTERISK_VERSION_NUM >= 10200 && ASTERISK_VERSION_NUM < 10400)
		{
		char tmpstr[32];
		ast_inet_ntoa(tmpstr, sizeof(tmpstr),
			mesim_clnt->bind_addr.sin_addr);

		ast_log(LOG_WARNING,
			"Unable to start listening on"
			" %s:%d: %s\n",
				tmpstr,
				ntohs(mesim_clnt->bind_addr.sin_port),
				strerror(errno));
		}
#else
		ast_log(LOG_WARNING,
			"Unable to start listening on"
			" %s:%d: %s\n",
				ast_inet_ntoa(mesim_clnt->bind_addr.
						sin_addr),
				ntohs(mesim_clnt->bind_addr.sin_port),
				strerror(errno));
#endif
		return;
	}

	vgsm_mesim_change_state(mesim, VGSM_MESIM_HOLDER_REMOVED, -1);
}
Beispiel #20
0
int ooSocketGetInterfaceList(OOCTXT *pctxt, OOInterface **ifList)
{
   OOSOCKET sock;
   struct ifconf ifc;
   int ifNum;
   OOInterface *pIf=NULL;
   struct sockaddr_in sin;

   OOTRACEDBGA1("Retrieving local interfaces\n");
   if(ooSocketCreateUDP(&sock, 4)!= ASN_OK)
   {
      OOTRACEERR1("Error:Failed to create udp socket - "
                  "ooSocketGetInterfaceList\n");   
      return -1;
   }
#ifdef SIOCGIFNUM
   if(ioctl(sock, SIOCGIFNUM, &ifNum) >= 0)
   {
      OOTRACEERR1("Error: ioctl for ifNum failed\n");
      return -1;
   }
#else
   ifNum = 50;
#endif
 
   ifc.ifc_len = ifNum * sizeof(struct ifreq);
   ifc.ifc_req = (struct ifreq *)memAlloc(pctxt, ifNum *sizeof(struct ifreq));
   if(!ifc.ifc_req)
   {
      OOTRACEERR1("Error:Memory - ooSocketGetInterfaceList - ifc.ifc_req\n");
      return -1;
   }

   if (ioctl(sock, SIOCGIFCONF, &ifc) >= 0) {
      void * ifEndList = (char *)ifc.ifc_req + ifc.ifc_len;
      struct ifreq *ifName;
      struct ifreq ifReq;
      int flags;
      for (ifName = ifc.ifc_req; (void*)ifName < ifEndList; ifName++) {
         char *pName=NULL;
         char addr[50];
#ifdef ifr_netmask
	char mask[50];
#endif
         
         pIf = (struct OOInterface*)memAlloc(pctxt, sizeof(struct OOInterface));
         pName = (char*)memAlloc(pctxt, strlen(ifName->ifr_name)+1);
         if(!pIf)
         {
            OOTRACEERR1("Error:Memory - ooSocketGetInterfaceList - "
                        "pIf/pName\n");
            return -1;
         }
         OOTRACEDBGA2("\tInterface name: %s\n", ifName->ifr_name);
         
         
         strcpy(ifReq.ifr_name, ifName->ifr_name);
         strcpy(pName, ifName->ifr_name);
         pIf->name = pName;

         /* Check whether the interface is up*/
         if (ioctl(sock, SIOCGIFFLAGS, &ifReq) < 0) {
            OOTRACEERR2("Error:Unable to determine status of interface %s\n", 
                        pName);
            memFreePtr(pctxt, pIf->name);
            memFreePtr(pctxt, pIf);
            continue;
         }
         flags = ifReq.ifr_flags;
         if (!(flags & IFF_UP)) {
            OOTRACEWARN2("Warn:Interface %s is not up\n", pName);
            memFreePtr(pctxt, pIf->name);
            memFreePtr(pctxt, pIf);
            continue;
         }

         /* Retrieve interface address */
         if (ioctl(sock, SIOCGIFADDR, &ifReq) < 0) 
         {
            OOTRACEWARN2("Warn:Unable to determine address of interface %s\n", 
                          pName);
            memFreePtr(pctxt, pIf->name);
            memFreePtr(pctxt, pIf);
            continue;
         }
	 memcpy(&sin, &ifReq.ifr_addr, sizeof(struct sockaddr_in));
	 strcpy(addr, ast_inet_ntoa(sin.sin_addr));
         OOTRACEDBGA2("\tIP address is %s\n", addr);
         pIf->addr = (char*)memAlloc(pctxt, strlen(addr)+1);
         if(!pIf->addr)
         {
            OOTRACEERR1("Error:Memory - ooSocketGetInterfaceList - "
                        "pIf->addr\n");
            memFreePtr(pctxt, pIf->name);
            memFreePtr(pctxt, pIf);
            return -1;
         }
         strcpy(pIf->addr, addr);
         
#ifdef ifr_netmask
         if (ioctl(sock, SIOCGIFNETMASK, &ifReq) < 0) 
         {
            OOTRACEWARN2("Warn:Unable to determine mask for interface %s\n", 
                          pName);
            memFreePtr(pctxt, pIf->name);
            memFreePtr(pctxt, pIf->addr);
            memFreePtr(pctxt, pIf);
            continue;
         }
	 memcpy(&sin, &ifReq.ifr_netmask, sizeof(struct sockaddr_in));
	 strcpy(mask, ast_inet_ntoa(sin.sin_addr));
         OOTRACEDBGA2("\tMask is %s\n", mask);
         pIf->mask = (char*)memAlloc(pctxt, strlen(mask)+1);
         if(!pIf->mask)
         {
            OOTRACEERR1("Error:Memory - ooSocketGetInterfaceList - "
                        "pIf->mask\n");
            memFreePtr(pctxt, pIf->name);
            memFreePtr(pctxt, pIf->addr);
            memFreePtr(pctxt, pIf);
            return -1;
         }
         strcpy(pIf->mask, mask);
#endif
         pIf->next = NULL;

         /* Add to the list */
         if(!*ifList)
         {
            *ifList = pIf;
            pIf = NULL;
         }
         else{
            pIf->next = *ifList;
            *ifList = pIf;
            pIf=NULL;
         }
/*
#if defined(OO_FREEBSD) || defined(OO_OPENBSD) || defined(OO_NETBSD) || defined(OO_MACOSX) || defined(OO_VXWORKS) || defined(OO_RTEMS) || defined(OO_QNX)
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ(ifr) \
        ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
         (sizeof(struct ifreq) - sizeof(struct sockaddr) + \
          (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))
#endif
      ifName = (struct ifreq *)((char *)ifName + _SIZEOF_ADDR_IFREQ(*ifName));
#else
      ifName++;
*/
      }

   }  
   return ASN_OK;
}
Beispiel #21
0
/** 
* This routine based on get_input from asterisk manager.c
* Good generic line-based input routine for \r\n\r\n terminated input 
* Used by standard.c and other input handlers
* @param   s: the connection 
* @param   output: the buffer save the message
************************************************************/
int get_input(connection_t *connection, char *output) {
  /* output must have at least sizeof(s->inbuf) space */
  int res;
  int x;
  struct pollfd fds[1];
  //char iabuf[INET_ADDRSTRLEN];
  
  //LM_DBG("s->inbuf = %s\n", s->inbuf);

  /* Look for \r\n from the front, our preferred end of line */
  for (x = 0; x < connection->inlen; x++) {
    int xtra = 0;
    if (connection->inbuf[x] == '\n') {
      if (x  && connection->inbuf[x-1] == '\r') {
        xtra = 1;
      }
      /* Copy output data not including \r\n */
      memcpy(output, connection->inbuf, x - xtra);
      /* Add trailing \0 */
      output[x-xtra] = '\0';
      /* Move remaining data back to the front */
      memmove(connection->inbuf, connection->inbuf + x + 1, connection->inlen - x);
      connection->inlen -= (x + 1);
      return 1;
    }
  }

  if ((unsigned int)connection->inlen >= sizeof(connection->inbuf) - 1) {
	char iabuf[INET_ADDRSTRLEN]; 
	const char *ipaddr = (const char*)ast_inet_ntoa(iabuf, sizeof(iabuf), connection->sin.sin_addr);

	if (ipaddr == NULL) 
		ipaddr = "n/a";
		
 	if (connection->server)	
      		LM_ERR("Warning: got wrong msg from server[%s]\n", ipaddr);
      else
		LM_ERR("Warning: got wrong msg from client[%s]\n", ipaddr);

	connection->inlen = 0;
	// return -1;
  }


  fds[0].fd = connection->sfd;
  fds[0].events = POLLIN;
  res = poll(fds, 1, -1);
  if (res < 0) {
    LM_ERR("Select returned error from fd[%d], error:%s\n", fds[0].fd, strerror(errno));
    return 0; 
  } else if (res > 0) {
    pthread_mutex_lock(&connection->lock);
   
    res = read(connection->sfd, connection->inbuf + connection->inlen, sizeof(connection->inbuf) - 1 - connection->inlen);
    pthread_mutex_unlock(&connection->lock);

    if (res < 1)
      return -1;

  }
  connection->inlen += res;
  connection->inbuf[connection->inlen] = '\0';

  //LM_DBG("s->inbuf = %s\n", s->inbuf);

  return 0;
  /* We have some input, but it's not ready for processing */
}