示例#1
0
/* Coprocess functionality */
void dnsrv_child_process_xstream_io(int type, xmlnode x, void* args)
{
     dns_io di = (dns_io)args;
     char*  hostname;
     char*  str = NULL;
     dns_resend_list iternode = NULL;

     if (type == XSTREAM_NODE)
     {
          /* Get the hostname out... */
          hostname = xmlnode_get_data(x);
          log_debug(ZONE, "dnsrv: Recv'd lookup request for %s", hostname);
          if (hostname != NULL)
          {
               /* For each entry in the svclist, try and resolve using
                  the specified service and resend it to the specified host */
               iternode = di->svclist;
               while (iternode != NULL)
               {
                    str = srv_lookup(x->p, iternode->service, hostname);
                    if (str != NULL)
                    {
                         log_debug(ZONE, "Resolved %s(%s): %s\tresend to:%s", hostname, iternode->service, str, iternode->host);
                         xmlnode_put_attrib(x, "ip", str);
                         xmlnode_put_attrib(x, "to", iternode->host);
                         break;
                    }
                    iternode = iternode->next;
               }
               str = xmlnode2str(x);
               write(di->out, str, strlen(str));
          }
     }
     xmlnode_free(x);
}
示例#2
0
static void srv_handler(int err, const struct dnshdr *hdr, struct list *ansl,
			 struct list *authl, struct list *addl, void *arg)
{
	struct sip_request *req = arg;
	(void)hdr;
	(void)authl;

	dns_rrlist_sort(ansl, DNS_TYPE_SRV);

	dns_rrlist_apply(ansl, NULL, DNS_TYPE_SRV, DNS_CLASS_IN, false,
			 rr_append_handler, &req->srvl);

	if (!req->srvl.head) {
		if (!req->tp_selected) {
			if (transp_next(req->sip, &req->tp)) {

				err = srv_lookup(req, req->host);
				if (err)
					goto fail;

				return;
			}

			req->tp = SIP_TRANSP_NONE;
			if (!transp_next(req->sip, &req->tp)) {
				err = EPROTONOSUPPORT;
				goto fail;
			}
		}

		req->port = sip_transp_port(req->tp, 0);

		err = addr_lookup(req, req->host);
		if (err)
			goto fail;

		return;
	}

	dns_rrlist_apply(addl, NULL, DNS_QTYPE_ANY, DNS_CLASS_IN, false,
			 rr_cache_handler, req);

	err = request_next(req);
	if (err)
		goto fail;

	if (!req->stateful) {
		req->resph = NULL;
		terminate(req, 0, NULL);
		mem_deref(req);
	}

	return;

 fail:
	terminate(req, err, NULL);
	mem_deref(req);
}
示例#3
0
static void naptr_handler(int err, const struct dnshdr *hdr, struct list *ansl,
			  struct list *authl, struct list *addl, void *arg)
{
	struct sip_request *req = arg;
	struct dnsrr *rr;
	(void)hdr;
	(void)authl;

	dns_rrlist_sort(ansl, DNS_TYPE_NAPTR);

	rr = dns_rrlist_apply(ansl, NULL, DNS_TYPE_NAPTR, DNS_CLASS_IN, false,
			      rr_naptr_handler, req);
	if (!rr) {
		err = srv_lookup(req, req->host);
		if (err)
			goto fail;

		return;
	}

	dns_rrlist_sort(addl, DNS_TYPE_SRV);

	dns_rrlist_apply(addl, rr->rdata.naptr.replace, DNS_TYPE_SRV,
			 DNS_CLASS_IN, true, rr_append_handler, &req->srvl);

	if (!req->srvl.head) {
		err = dnsc_query(&req->dnsq, req->sip->dnsc,
				 rr->rdata.naptr.replace, DNS_TYPE_SRV,
				 DNS_CLASS_IN, true, srv_handler, req);
		if (err)
			goto fail;

		return;
	}

	dns_rrlist_apply(addl, NULL, DNS_QTYPE_ANY, DNS_CLASS_IN, false,
			 rr_cache_handler, req);

	err = request_next(req);
	if (err)
		goto fail;

	if (!req->stateful) {
		req->resph = NULL;
		terminate(req, 0, NULL);
		mem_deref(req);
	}

	return;

 fail:
	terminate(req, err, NULL);
	mem_deref(req);
}
示例#4
0
/**
 * Send a SIP request
 *
 * @param reqp     Pointer to allocated SIP request object
 * @param sip      SIP Stack
 * @param stateful Stateful client transaction
 * @param met      SIP Method string
 * @param metl     Length of SIP Method string
 * @param uri      Request URI
 * @param uril     Length of Request URI string
 * @param route    Next hop route URI
 * @param mb       Buffer containing SIP request
 * @param sendh    Send handler
 * @param resph    Response handler
 * @param arg      Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful,
		const char *met, int metl, const char *uri, int uril,
		const struct uri *route, struct mbuf *mb,
		sip_send_h *sendh, sip_resp_h *resph, void *arg)
{
	struct sip_request *req;
	struct sa dst;
	struct pl pl;
	int err;

	if (!sip || !met || !uri || !route || !mb)
		return EINVAL;

	if (pl_strcasecmp(&route->scheme, "sip"))
		return ENOSYS;

	req = mem_zalloc(sizeof(*req), destructor);
	if (!req)
		return ENOMEM;

	list_append(&sip->reql, &req->le, req);

	err = str_ldup(&req->met, met, metl);
	if (err)
		goto out;

	err = str_ldup(&req->uri, uri, uril);
	if (err)
		goto out;

	if (sip_param_decode(&route->params, "maddr", &pl))
		pl = route->host;

	err = pl_strdup(&req->host, &pl);
	if (err)
		goto out;

	req->stateful = stateful;
	req->mb    = mem_ref(mb);
	req->sip   = sip;
	req->sendh = sendh;
	req->resph = resph;
	req->arg   = arg;

	if (!sip_param_decode(&route->params, "transport", &pl)) {

		if (!pl_strcasecmp(&pl, "udp"))
			req->tp = SIP_TRANSP_UDP;
		else if (!pl_strcasecmp(&pl, "tcp"))
			req->tp = SIP_TRANSP_TCP;
		else if (!pl_strcasecmp(&pl, "tls"))
			req->tp = SIP_TRANSP_TLS;
		else {
			err = EPROTONOSUPPORT;
			goto out;
		}

		if (!sip_transp_supported(sip, req->tp, AF_UNSPEC)) {
			err = EPROTONOSUPPORT;
			goto out;
		}

		req->tp_selected = true;
	}
	else {
		req->tp = SIP_TRANSP_NONE;
		if (!transp_next(sip, &req->tp)) {
			err = EPROTONOSUPPORT;
			goto out;
		}

		req->tp_selected = false;
	}

	if (!sa_set_str(&dst, req->host,
			sip_transp_port(req->tp, route->port))) {

		err = request(req, req->tp, &dst);
		if (!req->stateful) {
			mem_deref(req);
			return err;
		}
	}
	else if (route->port) {

		req->port = sip_transp_port(req->tp, route->port);
		err = addr_lookup(req, req->host);
	}
	else if (req->tp_selected) {

		err = srv_lookup(req, req->host);
	}
	else {
	        err = dnsc_query(&req->dnsq, sip->dnsc, req->host,
				 DNS_TYPE_NAPTR, DNS_CLASS_IN, true,
				 naptr_handler, req);
	}

 out:
	if (err)
		mem_deref(req);
	else if (reqp) {
		req->reqp = reqp;
		*reqp = req;
	}

	return err;
}
示例#5
0
文件: jabber.c 项目: AlD/bitlbee
/* Separate this from jabber_login() so we can do OAuth first if necessary.
   Putting this in io.c would probably be more correct. */
void jabber_connect( struct im_connection *ic )
{
	account_t *acc = ic->acc;
	struct jabber_data *jd = ic->proto_data;
	int i;
	char *connect_to;
	struct ns_srv_reply **srvl = NULL, *srv = NULL;
	
	/* Figure out the hostname to connect to. */
	if( acc->server && *acc->server )
		connect_to = acc->server;
	else if( ( srvl = srv_lookup( "xmpp-client", "tcp", jd->server ) ) ||
	         ( srvl = srv_lookup( "jabber-client", "tcp", jd->server ) ) )
	{
		/* Find the lowest-priority one. These usually come
		   back in random/shuffled order. Not looking at
		   weights etc for now. */
		srv = *srvl;
		for( i = 1; srvl[i]; i ++ )
			if( srvl[i]->prio < srv->prio )
				srv = srvl[i];
		
		connect_to = srv->name;
	}
	else
		connect_to = jd->server;
	
	imcb_log( ic, "Connecting" );
	
	for( i = 0; jabber_port_list[i] > 0; i ++ )
		if( set_getint( &acc->set, "port" ) == jabber_port_list[i] )
			break;

	if( jabber_port_list[i] == 0 )
	{
		imcb_log( ic, "Illegal port number" );
		imc_logout( ic, FALSE );
		return;
	}
	
	/* For non-SSL connections we can try to use the port # from the SRV
	   reply, but let's not do that when using SSL, SSL usually runs on
	   non-standard ports... */
	if( set_getbool( &acc->set, "ssl" ) )
	{
		jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), FALSE, jabber_connected_ssl, ic );
		jd->fd = jd->ssl ? ssl_getfd( jd->ssl ) : -1;
	}
	else
	{
		jd->fd = proxy_connect( connect_to, srv ? srv->port : set_getint( &acc->set, "port" ), jabber_connected_plain, ic );
	}
	srv_free( srvl );
	
	if( jd->fd == -1 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		
		return;
	}
	
	if( set_getbool( &acc->set, "xmlconsole" ) )
	{
		jd->flags |= JFLAG_XMLCONSOLE;
		/* Shouldn't really do this at this stage already, maybe. But
		   I think this shouldn't break anything. */
		imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
	}
	
	jabber_generate_id_hash( jd );
}
示例#6
0
文件: jabber.c 项目: luka-n/bitlbee
/* Separate this from jabber_login() so we can do OAuth first if necessary.
   Putting this in io.c would probably be more correct. */
void jabber_connect(struct im_connection *ic)
{
	account_t *acc = ic->acc;
	struct jabber_data *jd = ic->proto_data;
	int i;
	char *connect_to;
	struct ns_srv_reply **srvl = NULL, *srv = NULL;

	/* Figure out the hostname to connect to. */
	if (acc->server && *acc->server) {
		connect_to = acc->server;
	} else if ((srvl = srv_lookup("xmpp-client", "tcp", jd->server)) ||
	           (srvl = srv_lookup("jabber-client", "tcp", jd->server))) {
		/* Find the lowest-priority one. These usually come
		   back in random/shuffled order. Not looking at
		   weights etc for now. */
		srv = *srvl;
		for (i = 1; srvl[i]; i++) {
			if (srvl[i]->prio < srv->prio) {
				srv = srvl[i];
			}
		}

		connect_to = srv->name;
	} else {
		connect_to = jd->server;
	}

	imcb_log(ic, "Connecting");

	for (i = 0; jabber_port_list[i] > 0; i++) {
		if (set_getint(&acc->set, "port") == jabber_port_list[i]) {
			break;
		}
	}

	if (jabber_port_list[i] == 0) {
		imcb_log(ic, "Illegal port number");
		imc_logout(ic, FALSE);
		return;
	}

	/* For non-SSL connections we can try to use the port # from the SRV
	   reply, but let's not do that when using SSL, SSL usually runs on
	   non-standard ports... */
	if (set_getbool(&acc->set, "ssl")) {
		jd->ssl = ssl_connect(connect_to, set_getint(&acc->set, "port"), set_getbool(&acc->set,
		                                                                             "tls_verify"), jabber_connected_ssl,
		                      ic);
		jd->fd = jd->ssl ? ssl_getfd(jd->ssl) : -1;
	} else {
		jd->fd = proxy_connect(connect_to, srv ? srv->port : set_getint(&acc->set,
		                                                                "port"), jabber_connected_plain, ic);
	}
	srv_free(srvl);

	if (jd->fd == -1) {
		imcb_error(ic, "Could not connect to server");
		imc_logout(ic, TRUE);

		return;
	}

	if (set_getbool(&acc->set, "xmlconsole")) {
		jabber_xmlconsole_enable(ic);
	}

	if (set_getbool(&acc->set, "mail_notifications")) {
		/* It's gmail specific, but it checks for server support before enabling it */
		jd->flags |= JFLAG_GMAILNOTIFY;
		if (set_getstr(&acc->set, "mail_notifications_handle")) {
			imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
		}
	}

	jabber_generate_id_hash(jd);
}