static void find_another_host (ACE_TCHAR other_host[]) { static ACE_TCHAR cached_other_host[MAXHOSTNAMELEN] = {'\0'}; if (cached_other_host[0] == '\0') { ACE_OS::strcpy (other_host, ACE_DEFAULT_SERVER_HOST); // If all else fails #if !defined (ACE_LACKS_GETHOSTENT) // These gethost-type things don't work everywhere. struct hostent *h = 0; ACE_utsname un; ACE_OS::uname (&un); h = ACE_OS::gethostbyname (un.nodename); if (h == 0) ACE_OS::strcpy (other_host, ACE_LOCALHOST); else // Use me if can't find another ACE_OS::strcpy (other_host, ACE_TEXT_CHAR_TO_TCHAR (h->h_name)); // @@ We really need to add wrappers for these hostent methods. // Optimize for sequential access of DNS or hosts file. sethostent (1); int candidate_count = 0; // Accumulate candidates first. There is some interaction on // Linux systems between <gethostent> and <gethostbyname_r> // (called by ACE_INET_Addr in host_is_up) This otherwise causes // an infinite loop on Linux --mas 03-08-2001 while ((h = gethostent ()) != 0) { if (ACE_OS::strcmp (h->h_name, ACE_TEXT_ALWAYS_CHAR (ACE_DEFAULT_SERVER_HOST)) == 0) continue; // AIX just _has_ to be different if (ACE_OS::strcmp (h->h_name, "loopback") == 0) continue; // If not me. if (ACE_OS::strcmp (h->h_name, ACE_TEXT_ALWAYS_CHAR (other_host)) != 0 && ACE_OS::strcmp (h->h_name, un.nodename) != 0) { ACE_OS::strcpy (candidate[candidate_count].host_name, ACE_TEXT_CHAR_TO_TCHAR (h->h_name)); if (++candidate_count >= MAX_CANDIDATES) break; } } // Now try to connect to candidates for (int i = 0; i < candidate_count; i++) if (host_is_up (candidate[i].host_name)) { ACE_OS::strcpy (other_host, candidate[i].host_name); break; } sethostent (0); endhostent (); #endif /* ! ACE_LACKS_GETHOSTENT */ ACE_OS::strcpy (cached_other_host, other_host); } else ACE_OS::strcpy (other_host, cached_other_host); }
static gfarm_error_t gfm_server_switch_back_channel_common( struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep, int from_client, int version, const char *diag, struct relayed_request *relay) { gfarm_error_t e = GFARM_ERR_NO_ERROR, e2; struct host *host; gfp_xdr_async_peer_t async = NULL; struct local_peer *local_peer = NULL; int is_direct_connection; int i = 0; #ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */ host = NULL; #endif is_direct_connection = (peer_get_parent(peer) == NULL); giant_lock(); if (from_client) { gflog_debug(GFARM_MSG_1001995, "Operation not permitted: from_client"); e = GFARM_ERR_OPERATION_NOT_PERMITTED; } else if ((host = peer_get_host(peer)) == NULL) { gflog_debug(GFARM_MSG_1001996, "Operation not permitted: peer_get_host() failed"); e = GFARM_ERR_OPERATION_NOT_PERMITTED; } else if (is_direct_connection && (e = gfp_xdr_async_peer_new(&async)) != GFARM_ERR_NO_ERROR) { gflog_error(GFARM_MSG_1002288, "%s: gfp_xdr_async_peer_new(): %s", diag, gfarm_error_string(e)); } giant_unlock(); e2 = gfm_server_relay_put_reply(peer, xid, sizep, relay, diag, &e, "i", &i/*XXX FIXME*/); if (e2 != GFARM_ERR_NO_ERROR) return (e2); if (debug_mode) gflog_debug(GFARM_MSG_1000404, "gfp_xdr_flush"); e2 = gfp_xdr_flush(peer_get_conn(peer)); if (e2 != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000405, "%s: protocol flush: %s", diag, gfarm_error_string(e2)); return (e2); } else if (e != GFARM_ERR_NO_ERROR) return (e2); if (is_direct_connection) { local_peer = peer_to_local_peer(peer); local_peer_set_async(local_peer, async); /* XXXRELAY */ local_peer_set_readable_watcher(local_peer, back_channel_recv_watcher); } if (host_is_up(host)) /* throw away old connetion */ { gflog_warning(GFARM_MSG_1002440, "back_channel(%s): switching to new connection", host_name(host)); host_disconnect_request(host, NULL); } giant_lock(); peer_set_peer_type(peer, peer_type_back_channel); abstract_host_set_peer(host_to_abstract_host(host), peer, version); giant_unlock(); if (is_direct_connection) { local_peer_watch_readable(local_peer); gfarm_thr_statewait_signal( local_peer_get_statewait(local_peer), e2, diag); } callout_setfunc(host_status_callout(host), NULL /* or, use back_channel_send_manager thread pool? */, gfs_client_status_callout, host); gfs_client_status_schedule(host, 1); gflog_info(GFARM_MSG_1004035, "back_channel(%s): started", host_name(host)); return (e2); }