* First try to compute an unique ID for each vhost with minimal criteria, * that is the first Host/IP:port and ServerName. For most cases this should * be enough and avoids changing the ID unnecessarily across restart (or * stop/start w.r.t. persisted files) for things that this module does not * care about. * * But if it's not enough (collisions) do a second pass for the full monty, * that
| 813 | * solely on this ID and resets them if the sizes don't match. |
| 814 | */ |
| 815 | static apr_array_header_t *make_servers_ids(server_rec *main_s, apr_pool_t *p) |
| 816 | { |
| 817 | server_rec *s = main_s; |
| 818 | apr_array_header_t *ids = apr_array_make(p, 10, sizeof(const char *)); |
| 819 | apr_hash_t *dups = apr_hash_make(p); |
| 820 | int idx, *dup, full_monty = 0; |
| 821 | const char *id; |
| 822 | |
| 823 | for (idx = 0, s = main_s; s; s = s->next, ++idx) { |
| 824 | id = make_server_id(s, p, 0); |
| 825 | dup = apr_hash_get(dups, id, APR_HASH_KEY_STRING); |
| 826 | apr_hash_set(dups, id, APR_HASH_KEY_STRING, |
| 827 | apr_pmemdup(p, &idx, sizeof(int))); |
| 828 | if (dup) { |
| 829 | full_monty = 1; |
| 830 | APR_ARRAY_IDX(ids, *dup, const char *) = NULL; |
| 831 | APR_ARRAY_PUSH(ids, const char *) = NULL; |
| 832 | } |
| 833 | else { |
| 834 | APR_ARRAY_PUSH(ids, const char *) = id; |
| 835 | } |
| 836 | } |
| 837 | if (full_monty) { |
| 838 | apr_hash_clear(dups); |
| 839 | for (idx = 0, s = main_s; s; s = s->next, ++idx) { |
| 840 | id = APR_ARRAY_IDX(ids, idx, const char *); |
| 841 | if (id) { |
| 842 | /* Preserve non-duplicates */ |
| 843 | continue; |
| 844 | } |
| 845 | id = make_server_id(s, p, 1); |
| 846 | if (apr_hash_get(dups, id, APR_HASH_KEY_STRING)) { |
| 847 | id = apr_psprintf(p, "%s_%x", id, idx); |
| 848 | } |
| 849 | else { |
| 850 | apr_hash_set(dups, id, APR_HASH_KEY_STRING, (void *)-1); |
| 851 | } |
| 852 | APR_ARRAY_IDX(ids, idx, const char *) = id; |
| 853 | } |
| 854 | } |
| 855 | |
| 856 | return ids; |
| 857 | } |
| 858 | |
| 859 | /* post_config hook: */ |
| 860 | static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, |
no test coverage detected