/** * Bind an iSCSI connection to an iSCSI session. * (If an iSCSI session is not exist, create an iSCSI session) */ int iscsi_bind_connection( const char *target_name, union iscsi_sid sid, struct iscsi_conn *conn) { struct iscsi_target *target = NULL; struct iscsi_session *session = NULL; int rv = 0; ASSERT((conn != NULL), "conn == NULL\n"); ASSERT((conn->siso != NULL), "conn->siso == NULL\n"); ASSERT((conn->session == NULL), "conn->session != NULL\n"); ASSERT((conn->target == NULL), "conn->target != NULL\n"); log_dbg1("target_name=%s\n", target_name); target = siso_lookup_target(conn->siso, target_name); if (target == NULL) { return -ENOENT; } conn->target = target; LOCK_SESSIONS(target); { session = lookup_session(target, conn->sid); if (conn->sid.id.tsih[0] == 0x00 || conn->sid.id.tsih[1] == 0x00) { // Create session and attach connection to the session. ASSERT((session == NULL), "session != NULL\n"); log_dbg1("create iscsi session\n"); session = iscsi_create_session(target, sid, conn); if (session == NULL) { rv = -ENOMEM; goto done; } log_dbg1("conn->session=%p\n", conn->session); // Enlink this iSCSI session to iSCSI session list. list_add_elem(&(target->list_session), &(session->listelem)); } else { // Current implementation doesn't support multi-connection. log_err("Current implementation doesn't support multi-connection.\n"); rv = -EINVAL; } } done: UNLOCK_SESSIONS(target); if (!rv) { // detach iSCSI connection from tempolary list. siso_detach_connection(conn->siso, conn); } return rv; } // iscsi_bind_connection
/** * Creates a new outbound session the transport service will use to send data to the * peer * * @param cls the plugin * @param address the address * @return the session or NULL of max connections exceeded */ static struct Session * http_get_session (void *cls, const struct GNUNET_HELLO_Address *address) { struct Plugin *plugin = cls; struct Session * s = NULL; struct GNUNET_ATS_Information ats; size_t addrlen; GNUNET_assert (plugin != NULL); GNUNET_assert (address != NULL); GNUNET_assert (address->address != NULL); ats.type = htonl (GNUNET_ATS_ARRAY_TERMINATOR); ats.value = htonl (GNUNET_ATS_ARRAY_TERMINATOR); /* find existing session */ s = lookup_session (plugin, address); if (s != NULL) return s; if (plugin->max_connections <= plugin->cur_connections) { GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, "Maximum number of connections reached, " "cannot connect to peer `%s'\n", GNUNET_i2s (&address->peer)); return NULL; } /* create new session */ addrlen = address->address_length; GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || (addrlen == sizeof (struct IPv4HttpAddress))); s = create_session (plugin, &address->peer, address->address, address->address_length); /* Get ATS type */ if (addrlen == sizeof (struct IPv4HttpAddress)) { struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) address->address; struct sockaddr_in s4; s4.sin_family = AF_INET; s4.sin_addr.s_addr = a4->ipv4_addr; s4.sin_port = a4->u4_port; #if HAVE_SOCKADDR_IN_SIN_LEN s4.sin_len = sizeof (struct sockaddr_in); #endif ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s4, sizeof (struct sockaddr_in)); } if (addrlen == sizeof (struct IPv6HttpAddress)) { struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) address->address; struct sockaddr_in6 s6; s6.sin6_family = AF_INET6; s6.sin6_addr = a6->ipv6_addr; s6.sin6_port = a6->u6_port; #if HAVE_SOCKADDR_IN_SIN_LEN s6.sin6_len = sizeof (struct sockaddr_in6); #endif ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s6, sizeof (struct sockaddr_in6)); } s->ats_address_network_type = ats.value; /* add new session */ GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); /* initiate new connection */ if (GNUNET_SYSERR == client_connect (s)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "Cannot connect to peer `%s' address `%s''\n", http_plugin_address_to_string(NULL, s->addr, s->addrlen), GNUNET_i2s (&s->target)); GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); delete_session (s); return NULL; } return s; }