From owner-svn-src-stable@FreeBSD.ORG Tue Oct 29 07:33:54 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id D71BC6A5; Tue, 29 Oct 2013 07:33:54 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id B4215200E; Tue, 29 Oct 2013 07:33:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r9T7XsbC050897; Tue, 29 Oct 2013 07:33:54 GMT (envelope-from bapt@svn.freebsd.org) Received: (from bapt@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r9T7XsP4050893; Tue, 29 Oct 2013 07:33:54 GMT (envelope-from bapt@svn.freebsd.org) Message-Id: <201310290733.r9T7XsP4050893@svn.freebsd.org> From: Baptiste Daroussin Date: Tue, 29 Oct 2013 07:33:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r257309 - stable/10/usr.sbin/pkg X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Oct 2013 07:33:54 -0000 Author: bapt Date: Tue Oct 29 07:33:53 2013 New Revision: 257309 URL: http://svnweb.freebsd.org/changeset/base/257309 Log: MFC: r256968, r256971, r256978 Improve SRV records support for the pkg(8) bootstrap: - order srv records by priorities - for all entries of the same priority, order randomly respect the weight - select the port where to fetch from respect the port provided in the SRV record Allow to bootstrap by doing pkg add ./a/path/to/a/pkg_package.txz Approved by: re (glebius) Modified: stable/10/usr.sbin/pkg/dns_utils.c stable/10/usr.sbin/pkg/dns_utils.h stable/10/usr.sbin/pkg/pkg.c Directory Properties: stable/10/usr.sbin/pkg/ (props changed) Modified: stable/10/usr.sbin/pkg/dns_utils.c ============================================================================== --- stable/10/usr.sbin/pkg/dns_utils.c Tue Oct 29 07:25:54 2013 (r257308) +++ stable/10/usr.sbin/pkg/dns_utils.c Tue Oct 29 07:33:53 2013 (r257309) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Baptiste Daroussin + * Copyright (c) 2012-2013 Baptiste Daroussin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,77 @@ typedef union { unsigned char buf[1024]; } dns_query; +static int +srv_priority_cmp(const void *a, const void *b) +{ + const struct dns_srvinfo *da, *db; + unsigned int r, l; + + da = *(struct dns_srvinfo * const *)a; + db = *(struct dns_srvinfo * const *)b; + + l = da->priority; + r = db->priority; + + return ((l > r) - (l < r)); +} + +static int +srv_final_cmp(const void *a, const void *b) +{ + const struct dns_srvinfo *da, *db; + unsigned int r, l, wr, wl; + int res; + + da = *(struct dns_srvinfo * const *)a; + db = *(struct dns_srvinfo * const *)b; + + l = da->priority; + r = db->priority; + + res = ((l > r) - (l < r)); + + if (res == 0) { + wl = da->finalweight; + wr = db->finalweight; + res = ((wr > wl) - (wr < wl)); + } + + return (res); +} + +static void +compute_weight(struct dns_srvinfo **d, int first, int last) +{ + int i, j, totalweight; + int *chosen; + + chosen = malloc(sizeof(int) * (last - first + 1)); + totalweight = 0; + + for (i = 0; i <= last; i++) + totalweight += d[i]->weight; + + if (totalweight == 0) + return; + + for (i = 0; i <= last; i++) { + for (;;) { + chosen[i] = random() % (d[i]->weight * 100 / totalweight); + for (j = 0; j < i; j++) { + if (chosen[i] == chosen[j]) + break; + } + if (j == i) { + d[i]->finalweight = chosen[i]; + break; + } + } + } + + free(chosen); +} + struct dns_srvinfo * dns_getsrvinfo(const char *zone) { @@ -46,7 +117,7 @@ dns_getsrvinfo(const char *zone) unsigned char *end, *p; char host[MAXHOSTNAMELEN]; dns_query q; - int len, qdcount, ancount, n, i; + int len, qdcount, ancount, n, i, f, l; unsigned int type, class, ttl, priority, weight, port; if ((len = res_query(zone, C_IN, T_SRV, q.buf, sizeof(q.buf))) == -1 || @@ -125,6 +196,21 @@ dns_getsrvinfo(const char *zone) n++; } + qsort(res, n, sizeof(res[0]), srv_priority_cmp); + + priority = f = l = 0; + for (i = 0; i < n; i++) { + if (res[i]->priority != priority) { + if (f != l) + compute_weight(res, f, l); + f = i; + priority = res[i]->priority; + } + l = i; + } + + qsort(res, n, sizeof(res[0]), srv_final_cmp); + for (i = 0; i < n - 1; i++) res[i]->next = res[i + 1]; Modified: stable/10/usr.sbin/pkg/dns_utils.h ============================================================================== --- stable/10/usr.sbin/pkg/dns_utils.h Tue Oct 29 07:25:54 2013 (r257308) +++ stable/10/usr.sbin/pkg/dns_utils.h Tue Oct 29 07:33:53 2013 (r257309) @@ -35,6 +35,7 @@ struct dns_srvinfo { unsigned int priority; unsigned int weight; unsigned int port; + unsigned int finalweight; char host[MAXHOSTNAMELEN]; struct dns_srvinfo *next; }; Modified: stable/10/usr.sbin/pkg/pkg.c ============================================================================== --- stable/10/usr.sbin/pkg/pkg.c Tue Oct 29 07:25:54 2013 (r257308) +++ stable/10/usr.sbin/pkg/pkg.c Tue Oct 29 07:33:53 2013 (r257309) @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -191,8 +192,10 @@ bootstrap_pkg(void) } } - if (mirrors != NULL) + if (mirrors != NULL) { strlcpy(u->host, current->host, sizeof(u->host)); + u->port = current->port; + } remote = fetchXGet(u, &st, ""); if (remote == NULL) { @@ -295,7 +298,9 @@ int main(__unused int argc, char *argv[]) { char pkgpath[MAXPATHLEN]; + char pkgstatic[MAXPATHLEN]; bool yes = false; + int fd, ret; snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE); @@ -309,6 +314,19 @@ main(__unused int argc, char *argv[]) if (argv[1] != NULL && strcmp(argv[1], "-N") == 0) errx(EXIT_FAILURE, "pkg is not installed"); + if (argc > 2 && strcmp(argv[1], "add") == 0 && + access(argv[2], R_OK) == 0) { + fd = open(argv[2], O_RDONLY); + if (fd == -1) + err(EXIT_FAILURE, "Unable to open %s", argv[2]); + + if ((ret = extract_pkg_static(fd, pkgstatic, MAXPATHLEN)) == 0) + ret = install_pkg_static(pkgstatic, argv[2]); + close(fd); + if (ret != 0) + exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); + } /* * Do not ask for confirmation if either of stdin or stdout is * not tty. Check the environment to see if user has answer