--- /dev/null
+/*
+ * Copyright (C) 2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <udns.h>
+#include "sort_udns.h"
+
+int tcp_connect_a4 (struct in_addr addr, int port)
+{
+ int fd;
+ struct sockaddr_in in4;
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ return -1;
+ in4.sin_family = AF_INET;
+ in4.sin_port = htons (port);
+ in4.sin_addr = addr;
+ if (connect (fd, (struct sockaddr *) &in4, sizeof (in4)) < 0)
+ {
+ close (fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+tcp_connect_a6 (struct in6_addr addr, int port)
+{
+ int fd;
+ struct sockaddr_in6 in6;
+ fd = socket (PF_INET6, SOCK_STREAM, 0);
+ if (fd < 0)
+ return -1;
+ memset (&in6, sizeof (in6), 0);
+ in6.sin6_family = AF_INET6;
+ in6.sin6_port = htons (port);
+ in6.sin6_addr = addr;
+ if (connect (fd, (struct sockaddr *) &in6, sizeof (in6)) < 0)
+ {
+ close (fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+tcp_connect4 (struct dns_srv srv)
+{
+ struct dns_rr_a4 *a4;
+ int i;
+ int fd;
+ a4 = dns_resolve_a4 (NULL, srv.name, 0);
+ if (a4 == NULL)
+ return -1;
+ for (i = 0; i < a4->dnsa4_nrr; i++)
+ {
+ fd = tcp_connect_a4 (a4->dnsa4_addr[i], srv.port);
+ if (fd >= 0)
+ {
+ free (a4);
+ return fd;
+ }
+ }
+ free (a4);
+ return -1;
+}
+
+int
+tcp_connect6 (struct dns_srv srv)
+{
+ struct dns_rr_a6 *a6;
+ int i;
+ int fd;
+ a6 = dns_resolve_a6 (NULL, srv.name, 0);
+ if (a6 == NULL)
+ return -1;
+ for (i = 0; i < a6->dnsa6_nrr; i++)
+ {
+ fd = tcp_connect_a6 (a6->dnsa6_addr[i], srv.port);
+ if (fd >= 0)
+ {
+ free (a6);
+ return fd;
+ }
+ }
+ free (a6);
+ return -1;
+}
+
+int
+tcp_connect (char *server, char *service)
+{
+ struct dns_rr_srv *srv;
+ int i;
+ int fd;
+ srv = dns_resolve_srv (NULL, server, service, "tcp", 0);
+ if (srv == NULL)
+ return -1;
+ dns_srv_sort (srv->dnssrv_srv, srv->dnssrv_nrr);
+ for (i = 0; i < srv->dnssrv_nrr; i++)
+ {
+ fd = tcp_connect6 (srv->dnssrv_srv[i]);
+ if (fd < 0)
+ fd = tcp_connect4 (srv->dnssrv_srv[i]);
+ if (fd >= 0)
+ {
+ free (srv);
+ return fd;
+ }
+ }
+ free (srv);
+ return -1;
+}
+
+#ifdef TEST
+int
+main (int argc, char **argv)
+{
+ char *server;
+ char *service;
+ int fd;
+ dns_init (NULL, 1);
+ server = (argc >= 2) ? argv[1] : "holoscopio.com";
+ service = (argc >= 3) ? argv[2] : "xmpp-client";
+ fd = tcp_connect (server, service);
+ if (fd > 0)
+ close (fd);
+ return 0;
+}
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SORT_UDNS_H
+#define SORT_UDNS_H
+
+int tcp_connect (char *, char*);
+
+#endif