示例#1
0
文件: network.c 项目: whilke/ColdC
void func_reassign_connection(void) {
    cData       * args;
    Conn * c;
    Obj     * obj;

    /* Accept a objnum. */
    if (!func_init_1(&args, OBJNUM))
        return;

    c = find_connection(cur_frame->object);
    if (c) {
        obj = cache_retrieve(args[0].u.objnum);
        if (!obj)
            THROW((objnf_id, "Object #%l does not exist.", args[0].u.objnum))
        else if (find_connection(obj)) {
            cthrow(perm_id, "Object %O already has a connection.", obj->objnum);
            cache_discard(obj);
            return;
        }
        c->objnum = obj->objnum;
        cache_discard(obj);
        cur_frame->object->conn = NULL;
        pop(1);
        push_int(1);
    } else {
示例#2
0
static void CheckIsConnected (const NODE * node1, const NODE * node2)
{
	int n1_to_n2;
	int n2_to_n1;
#ifdef NDEBUG
  return;
#endif

  n1_to_n2 = find_connection (node1, node2);
  n2_to_n1 = find_connection (node2, node1);

  assert (n1_to_n2 >= 0);
  assert (n2_to_n1 >= 0);

  assert (DBL_EQUALS (node1->blength[n1_to_n2], node2->blength[n2_to_n1]));
}
示例#3
0
uint32_t
remove_connection(iscsid_remove_connection_req_t * req)
{
	iscsi_remove_parameters_t removep;
	session_t *sess;
	connection_t *conn;
	int ret;

	LOCK_SESSIONS;
	sess = find_session(&req->session_id);
	if (sess == NULL) {
		UNLOCK_SESSIONS;
		return ISCSID_STATUS_INVALID_SESSION_ID;
	}
	conn = find_connection(sess, &req->connection_id);
	if (conn == NULL) {
		UNLOCK_SESSIONS;
		return ISCSID_STATUS_INVALID_CONNECTION_ID;
	}

	removep.session_id = sess->entry.sid.id;
	removep.connection_id = conn->entry.sid.id;
	UNLOCK_SESSIONS;

	ret = ioctl(driver, ISCSI_REMOVE_CONNECTION, &removep);
	DEB(9, ("Remove Connection returns %d, status=%d\n", ret, removep.status));

	return removep.status;
}
示例#4
0
int input_device_unregister(const char *path, const char *uuid)
{
	struct input_device *idev;
	struct input_conn *iconn;

	idev = find_device_by_path(devices, path);
	if (idev == NULL)
		return -EINVAL;

	iconn = find_connection(idev->connections, uuid);
	if (iconn == NULL)
		return -EINVAL;

	if (iconn->pending_connect) {
		/* Pending connection running */
		return -EBUSY;
	}

	idev->connections = g_slist_remove(idev->connections, iconn);
	input_conn_free(iconn);
	if (idev->connections)
		return 0;

	g_dbus_unregister_interface(idev->conn, path, INPUT_DEVICE_INTERFACE);

	return 0;
}
示例#5
0
文件: device.c 项目: blammit/bluez
int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst)
{
	struct input_device *idev = find_device(src, dst);
	struct input_conn *iconn;
	char sstr[18], dstr[18];

	ba2str(src, sstr);
	ba2str(dst, dstr);
	DBG("src %s, dst %s", sstr, dstr);

	DBG("idev %p", idev);

	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, HID_UUID);
	if (!iconn)
		return -ENOENT;

	if (iconn->intr_io)
		g_io_channel_shutdown(iconn->intr_io, TRUE, NULL);

	if (iconn->ctrl_io)
		g_io_channel_shutdown(iconn->ctrl_io, TRUE, NULL);

	return 0;
}
示例#6
0
文件: device.c 项目: blammit/bluez
/*
 * Input Device methods
 */
static DBusMessage *input_device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	struct input_conn *iconn;
	DBusMessage *reply;
	GError *err = NULL;

	DBG("idev %p", idev);

	iconn = find_connection(idev->connections, HID_UUID);
	if (!iconn)
		return btd_error_not_supported(msg);

	if (iconn->pending_connect)
		return btd_error_in_progress(msg);

	if (is_connected(iconn))
		return btd_error_already_connected(msg);

	iconn->pending_connect = dbus_message_ref(msg);

	dev_connect(idev, iconn, &err);

	if (err == NULL)
		return NULL;

	error("%s", err->message);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
	reply = btd_error_failed(msg, err->message);
	g_error_free(err);
	return reply;
}
示例#7
0
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
								GIOChannel *io)
{
	struct input_device *idev = find_device(src, dst);
	struct input_conn *iconn;

	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, "hid");
	if (!iconn)
		return -ENOENT;

	switch (psm) {
	case L2CAP_PSM_HIDP_CTRL:
		if (iconn->ctrl_io)
			return -EALREADY;
		iconn->ctrl_io = g_io_channel_ref(io);
		break;
	case L2CAP_PSM_HIDP_INTR:
		if (iconn->intr_io)
			return -EALREADY;
		iconn->intr_io = g_io_channel_ref(io);
		break;
	}

	if (iconn->intr_io && iconn->ctrl_io)
		input_device_connadd(idev, iconn);

	return 0;
}
示例#8
0
int connection_register(struct btd_device *device, const char *path,
			bdaddr_t *src, bdaddr_t *dst, uint16_t id)
{
	struct network_peer *peer;
	struct network_conn *nc;

	if (!path)
		return -EINVAL;

	peer = find_peer(peers, path);
	if (!peer) {
		peer = create_peer(device, path, src, dst);
		if (!peer)
			return -1;
		peers = g_slist_append(peers, peer);
	}

	nc = find_connection(peer->connections, id);
	if (nc)
		return 0;

	nc = g_new0(struct network_conn, 1);
	nc->id = id;
	memset(nc->dev, 0, sizeof(nc->dev));
	strcpy(nc->dev, "bnep%d");
	nc->state = DISCONNECTED;
	nc->peer = peer;

	peer->connections = g_slist_append(peer->connections, nc);

	return 0;
}
void reap_children()
{
    int status;
    int pid;
    int id;
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        id = find_connection(pid);
        if (id < 0)
            continue;
        release_connection(id);
    }
    child_exited = 0;
}
示例#10
0
void ApplicationManager::connection_close(connection_info_t cinfo)
{
    std::lock_guard<std::mutex> lck(this->lock);
    connection_info_t cinfo_orig = find_connection(cinfo->get_surface_id(),
                                                   cinfo->get_security_token());
    if (cinfo_orig == NULL)
    {
        mLOG_INFO("Cannot close specified connection (%S:%S)",
                  cinfo->get_surface_id(), cinfo->get_security_token());
        return false;
    }
    connections.remove(cinfo_orig);
    return true;
}
示例#11
0
static DBusMessage *input_device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	struct input_conn *iconn;
	struct fake_input *fake;
	DBusMessage *reply;
	GError *err = NULL;

	iconn = find_connection(idev->connections, "HID");
	if (!iconn)
		return not_supported(msg);

	if (iconn->pending_connect)
		return in_progress(msg);

	if (is_connected(iconn))
		return already_connected(msg);

	iconn->pending_connect = dbus_message_ref(msg);
	fake = iconn->fake;

	if (fake) {
		/* Fake input device */
		if (fake->connect(iconn, &err))
			fake->flags |= FI_FLAG_CONNECTED;
	} else {
		/* HID devices */
		GIOChannel *io;

		io = bt_io_connect(BT_IO_L2CAP, control_connect_cb, iconn,
					NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &idev->src,
					BT_IO_OPT_DEST_BDADDR, &idev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
		iconn->ctrl_io = io;
	}

	if (err == NULL)
		return NULL;

	error("%s", err->message);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
	reply = connection_attempt_failed(msg, err->message);
	g_error_free(err);
	return reply;
}
示例#12
0
/* Connect and initiate BNEP session */
static DBusMessage *connection_connect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	const char *svc;
	uint16_t id;
	GError *err = NULL;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
						DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	id = bnep_service_id(svc);
	nc = find_connection(peer->connections, id);
	if (!nc)
		return btd_error_not_supported(msg);

	if (nc->state != DISCONNECTED)
		return btd_error_already_connected(msg);

	nc->io = bt_io_connect(BT_IO_L2CAP, connect_cb, nc,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &peer->src,
				BT_IO_OPT_DEST_BDADDR, &peer->dst,
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_INVALID);
	if (!nc->io) {
		DBusMessage *reply;
		error("%s", err->message);
		reply = btd_error_failed(msg, err->message);
		g_error_free(err);
		return reply;
	}

	nc->state = CONNECTING;
	nc->msg = dbus_message_ref(msg);
	nc->watch = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						connection_destroy,
						nc, NULL);

	return NULL;
}
static void
connections_read (NMSettingsInterface *settings, gpointer user_data)
{
	GSList *connections;
	NMConnection *connection;
	NMDevice *dev;
	struct start_network_data *data = (struct start_network_data *)user_data;
	static int tries = 0;

	if(!NM_IS_REMOTE_SETTINGS_SYSTEM(settings))
	{
		network_status (data->client, "Not a settings_system object!  Huh?\n");
		g_main_loop_quit (loop);
		return;
	}

	connections = nm_settings_interface_list_connections (settings);
	connection = find_connection(connections, data->uuid);

	if (!connection) {
		if (tries++ >= 2) {
			network_status (data->client, "Unable to find connection from " NETWORK_CONFIG " in system configs file");
			g_main_loop_quit(loop);
			return;
		}
		return;
	}

	dev = get_device_for_connection (data->client, connection);
	if (!dev) {
		network_status (data->client, "Unable to find correct device for connection");
		g_main_loop_quit(loop);
		return;
	}
	data->should_quit = FALSE;

	nm_client_activate_connection (data->client,
					NM_DBUS_SERVICE_SYSTEM_SETTINGS,
					nm_connection_get_path (connection),//con_path,
					dev,//device,
					NULL,//spec_object,
					activate_connection_cb,
					data);
	return;
}
示例#14
0
int add_lengths_to_tree (TREE * tree, double *lengths)
{
  int a, b;

  CheckIsTree (tree);
  assert (NULL != lengths);

  for (a = 0; a < tree->n_br; a++) {
    (tree->branches[a])->blength[0] = lengths[a];
    b = find_connection (CHILD (tree->branches[a], 0), tree->branches[a]);

    CHILD (tree->branches[a], 0)->blength[b] = lengths[a];
  }

  CheckIsTree (tree);

  return 0;
}
示例#15
0
void ControllerServer::handle_http_post( const HttpServer::Request & request , HttpServer::Response & response )
{
    PostMap::iterator it = post_map.find( request.get_path() );

    if ( it == post_map.end() )
    {
        return;
    }

    ConnectionInfo * info = find_connection( it->second.connection );

    if ( ! info )
    {
        return;
    }

    const HttpServer::Request::Body & body( request.get_body() );

    if ( ! body.get_data() || ! body.get_length() )
    {
        response.set_status( HttpServer::HTTP_STATUS_BAD_REQUEST );

        return;
    }

    String ct( request.get_content_type() );

    const char * content_type = ct.empty() ? 0 : ct.c_str();

    switch ( it->second.type )
    {
        case PostInfo::AUDIO:
            tp_controller_submit_audio_clip( info->controller , body.get_data() , body.get_length() , content_type );
            break;

        case PostInfo::IMAGE:
            tp_controller_submit_image( info->controller , body.get_data() , body.get_length() , content_type );
            break;
    }

    response.set_status( HttpServer::HTTP_STATUS_OK );
}
示例#16
0
int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst)
{
	struct input_device *idev = find_device(src, dst);
	struct input_conn *iconn;

	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, "hid");
	if (!iconn)
		return -ENOENT;

	if (iconn->intr_io)
		g_io_channel_shutdown(iconn->intr_io, TRUE, NULL);

	if (iconn->ctrl_io)
		g_io_channel_shutdown(iconn->ctrl_io, TRUE, NULL);

	return 0;
}
示例#17
0
void connection_unregister(const char *path, uint16_t id)
{
	struct network_peer *peer;
	struct network_conn *nc;

	peer = find_peer(peers, path);
	if (!peer)
		return;

	nc = find_connection(peer->connections, id);
	if (!nc)
		return;

	peer->connections = g_slist_remove(peer->connections, nc);
	connection_free(nc);
	if (peer->connections)
		return;

	g_dbus_unregister_interface(connection, path, NETWORK_PEER_INTERFACE);
}
示例#18
0
文件: device.c 项目: blammit/bluez
static gboolean input_device_auto_reconnect(gpointer user_data)
{
	struct input_device *idev = user_data;
	struct input_conn *iconn;
	GError *err = NULL;

	DBG("idev %p", idev);

	DBG("path=%s, attempt=%d", idev->path, idev->reconnect_attempt);

	/* Stop the recurrent reconnection attempts if the device is reconnected
	 * or is marked for removal. */
	if (device_is_temporary(idev->device) ||
					device_is_connected(idev->device))
		return FALSE;

	/* Only attempt an auto-reconnect for at most 3 minutes (6 * 30s). */
	if (idev->reconnect_attempt >= 6)
		return FALSE;

	iconn = find_connection(idev->connections, HID_UUID);
	if (iconn == NULL)
		return FALSE;

	if (iconn->ctrl_io)
		return FALSE;

	if (is_connected(iconn))
		return FALSE;

	idev->reconnect_attempt++;

	dev_connect(idev, iconn, &err);
	if (err != NULL) {
		error("%s", err->message);
		g_error_free(err);
		return FALSE;
	}

	return TRUE;
}
示例#19
0
文件: device.c 项目: blammit/bluez
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
								GIOChannel *io)
{
	struct input_device *idev = find_device(src, dst);
	struct input_conn *iconn;
	char sstr[18], dstr[18];

	ba2str(src, sstr);
	ba2str(dst, dstr);
	DBG("src %s, dst %s", sstr, dstr);

	DBG("idev %p", idev);

	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, HID_UUID);
	if (!iconn)
		return -ENOENT;

	switch (psm) {
	case L2CAP_PSM_HIDP_CTRL:
		if (iconn->ctrl_io)
			return -EALREADY;
		iconn->ctrl_io = g_io_channel_ref(io);
		break;
	case L2CAP_PSM_HIDP_INTR:
		if (iconn->intr_io)
			return -EALREADY;
		iconn->intr_io = g_io_channel_ref(io);
		break;
	}

	if (iconn->intr_io && iconn->ctrl_io)
		input_device_connadd(idev, iconn);

	return 0;
}
示例#20
0
void ControllerServer::connection_closed( gpointer connection )
{
    ConnectionInfo * info = find_connection( connection );
    gpointer aui_connection = NULL;

    if ( info && info->controller )
    {
        tp_context_remove_controller( context, info->controller );
        aui_connection = info->aui_connection;
    }

    drop_resource_group( connection , String() );

    drop_post_endpoint( connection );

    connections.erase( connection );

    if ( aui_connection )
    {
        server->close_connection( aui_connection );
    }

    tplog( "CONNECTION CLOSED %p", connection );
}
示例#21
0
DWORD linux_proc_fill_program_name(struct connection_table * table_connection)
{
	char buffer[60];
	struct dirent *procent, *fdent;
	DIR * procfd, * pidfd;
	struct stat stat_buf;
	struct connection_entry * connection;

	procfd = opendir("/proc");
	if (procfd == NULL)
		return -1;
	while ((procent = readdir(procfd)) != NULL) {
		// not a pid directory
		if (!isdigit(*(procent->d_name)))
			continue;

		snprintf(buffer, sizeof(buffer), "/proc/%s/fd/", procent->d_name);
		if ((pidfd = opendir(buffer)) == NULL)
			continue;

		while((fdent = readdir(pidfd)) != NULL) {

			snprintf(buffer, sizeof(buffer), "/proc/%s/fd/%s", procent->d_name, fdent->d_name);
			if (stat(buffer, &stat_buf) < 0)
            			continue;
			if (!S_ISSOCK(stat_buf.st_mode))
				continue;
			// ok, FD is a socket, search if we have it in our list
			if ((connection = find_connection(table_connection, stat_buf.st_ino)) != NULL)
				linux_proc_get_program_name(connection, procent->d_name);
		}
		closedir(pidfd);
	}
	closedir(procfd);
	return 0;
}
示例#22
0
int
ldap_send_server_request(
	LDAP *ld,
	BerElement *ber,
	ber_int_t msgid,
	LDAPRequest *parentreq,
	LDAPURLDesc **srvlist,
	LDAPConn *lc,
	LDAPreqinfo *bind,
	int m_noconn,
	int m_res )
{
	LDAPRequest	*lr;
	int		incparent, rc;

	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex );
	Debug( LDAP_DEBUG_TRACE, "ldap_send_server_request\n", 0, 0, 0 );

	incparent = 0;
	ld->ld_errno = LDAP_SUCCESS;	/* optimistic */

	LDAP_CONN_LOCK_IF(m_noconn);
	if ( lc == NULL ) {
		if ( srvlist == NULL ) {
			lc = ld->ld_defconn;
		} else {
			lc = find_connection( ld, *srvlist, 1 );
			if ( lc == NULL ) {
				if ( (bind != NULL) && (parentreq != NULL) ) {
					/* Remember the bind in the parent */
					incparent = 1;
					++parentreq->lr_outrefcnt;
				}
				lc = ldap_new_connection( ld, srvlist, 0,
					1, bind, 1, m_res );
			}
		}
	}

	/* async connect... */
	if ( lc != NULL && lc->lconn_status == LDAP_CONNST_CONNECTING ) {
		ber_socket_t	sd = AC_SOCKET_ERROR;
		struct timeval	tv = { 0 };

		ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_GET_FD, &sd );

		/* poll ... */
		switch ( ldap_int_poll( ld, sd, &tv, 1 ) ) {
		case 0:
			/* go on! */
			lc->lconn_status = LDAP_CONNST_CONNECTED;
			break;

		case -2:
			/* async only occurs if a network timeout is set */

			/* honor network timeout */
			LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex );
			if ( time( NULL ) - lc->lconn_created <= ld->ld_options.ldo_tm_net.tv_sec )
			{
				/* caller will have to call again */
				ld->ld_errno = LDAP_X_CONNECTING;
			}
			LDAP_MUTEX_UNLOCK( &ld->ld_options.ldo_mutex );
			/* fallthru */

		default:
			/* error */
			break;
		}
	}

	if ( lc == NULL || lc->lconn_status != LDAP_CONNST_CONNECTED ) {
		if ( ld->ld_errno == LDAP_SUCCESS ) {
			ld->ld_errno = LDAP_SERVER_DOWN;
		}

		ber_free( ber, 1 );
		if ( incparent ) {
			/* Forget about the bind */
			--parentreq->lr_outrefcnt; 
		}
		LDAP_CONN_UNLOCK_IF(m_noconn);
		return( -1 );
	}

	use_connection( ld, lc );

#ifdef LDAP_CONNECTIONLESS
	if ( LDAP_IS_UDP( ld )) {
		BerElement tmpber = *ber;
		ber_rewind( &tmpber );
		LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex );
		rc = ber_write( &tmpber, ld->ld_options.ldo_peer,
			sizeof( struct sockaddr_storage ), 0 );
		LDAP_MUTEX_UNLOCK( &ld->ld_options.ldo_mutex );
		if ( rc == -1 ) {
			ld->ld_errno = LDAP_ENCODING_ERROR;
			LDAP_CONN_UNLOCK_IF(m_noconn);
			return rc;
		}
	}
#endif

	/* If we still have an incomplete write, try to finish it before
	 * dealing with the new request. If we don't finish here, return
	 * LDAP_BUSY and let the caller retry later. We only allow a single
	 * request to be in WRITING state.
	 */
	rc = 0;
	if ( ld->ld_requests &&
		ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
		ldap_int_flush_request( ld, ld->ld_requests ) < 0 )
	{
		rc = -1;
	}
	if ( rc ) {
		LDAP_CONN_UNLOCK_IF(m_noconn);
		return rc;
	}

	lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ) );
	if ( lr == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		ldap_free_connection( ld, lc, 0, 0 );
		ber_free( ber, 1 );
		if ( incparent ) {
			/* Forget about the bind */
			--parentreq->lr_outrefcnt; 
		}
		LDAP_CONN_UNLOCK_IF(m_noconn);
		return( -1 );
	} 
	lr->lr_msgid = msgid;
	lr->lr_status = LDAP_REQST_INPROGRESS;
	lr->lr_res_errno = LDAP_SUCCESS;	/* optimistic */
	lr->lr_ber = ber;
	lr->lr_conn = lc;
	if ( parentreq != NULL ) {	/* sub-request */
		if ( !incparent ) { 
			/* Increment if we didn't do it before the bind */
			++parentreq->lr_outrefcnt;
		}
		lr->lr_origid = parentreq->lr_origid;
		lr->lr_parentcnt = ++parentreq->lr_parentcnt;
		lr->lr_parent = parentreq;
		lr->lr_refnext = parentreq->lr_child;
		parentreq->lr_child = lr;
	} else {			/* original request */
		lr->lr_origid = lr->lr_msgid;
	}

	/* Extract requestDN for future reference */
#ifdef LDAP_CONNECTIONLESS
	if ( !LDAP_IS_UDP(ld) )
#endif
	{
		BerElement tmpber = *ber;
		ber_int_t	bint;
		ber_tag_t	tag, rtag;

		ber_reset( &tmpber, 1 );
		rtag = ber_scanf( &tmpber, "{it", /*}*/ &bint, &tag );
		switch ( tag ) {
		case LDAP_REQ_BIND:
			rtag = ber_scanf( &tmpber, "{i" /*}*/, &bint );
			break;
		case LDAP_REQ_DELETE:
			break;
		default:
			rtag = ber_scanf( &tmpber, "{" /*}*/ );
		case LDAP_REQ_ABANDON:
			break;
		}
		if ( tag != LDAP_REQ_ABANDON ) {
			ber_skip_tag( &tmpber, &lr->lr_dn.bv_len );
			lr->lr_dn.bv_val = tmpber.ber_ptr;
		}
	}

	lr->lr_prev = NULL;
	lr->lr_next = ld->ld_requests;
	if ( lr->lr_next != NULL ) {
		lr->lr_next->lr_prev = lr;
	}
	ld->ld_requests = lr;

	ld->ld_errno = LDAP_SUCCESS;
	if ( ldap_int_flush_request( ld, lr ) == -1 ) {
		msgid = -1;
	}

	LDAP_CONN_UNLOCK_IF(m_noconn);
	return( msgid );
}
示例#23
0
/*
 * XXX merging of errors in this routine needs to be improved
 * Protected by res_mutex, conn_mutex and req_mutex	(try_read1msg)
 */
int
ldap_chase_referrals( LDAP *ld,
	LDAPRequest *lr,
	char **errstrp,
	int sref,
	int *hadrefp )
{
	int		rc, count, id;
	unsigned	len;
	char		*p, *ref, *unfollowed;
	LDAPRequest	*origreq;
	LDAPURLDesc	*srv;
	BerElement	*ber;
	LDAPreqinfo  rinfo;
	LDAPConn	*lc;

	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex );
	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex );
	Debug( LDAP_DEBUG_TRACE, "ldap_chase_referrals\n", 0, 0, 0 );

	ld->ld_errno = LDAP_SUCCESS;	/* optimistic */
	*hadrefp = 0;

	if ( *errstrp == NULL ) {
		return( 0 );
	}

	len = strlen( *errstrp );
	for ( p = *errstrp; len >= LDAP_REF_STR_LEN; ++p, --len ) {
		if ( strncasecmp( p, LDAP_REF_STR, LDAP_REF_STR_LEN ) == 0 ) {
			*p = '\0';
			p += LDAP_REF_STR_LEN;
			break;
		}
	}

	if ( len < LDAP_REF_STR_LEN ) {
		return( 0 );
	}

	if ( lr->lr_parentcnt >= ld->ld_refhoplimit ) {
		Debug( LDAP_DEBUG_ANY,
		    "more than %d referral hops (dropping)\n",
		    ld->ld_refhoplimit, 0, 0 );
		    /* XXX report as error in ld->ld_errno? */
		    return( 0 );
	}

	/* find original request */
	for ( origreq = lr; origreq->lr_parent != NULL;
	     origreq = origreq->lr_parent ) {
		/* empty */;
	}

	unfollowed = NULL;
	rc = count = 0;

	/* parse out & follow referrals */
	for ( ref = p; rc == 0 && ref != NULL; ref = p ) {
		p = strchr( ref, '\n' );
		if ( p != NULL ) {
			*p++ = '\0';
		}

		rc = ldap_url_parse_ext( ref, &srv, LDAP_PVT_URL_PARSE_NOEMPTY_DN );
		if ( rc != LDAP_URL_SUCCESS ) {
			Debug( LDAP_DEBUG_TRACE,
				"ignoring %s referral <%s>\n",
				ref, rc == LDAP_URL_ERR_BADSCHEME ? "unknown" : "incorrect", 0 );
			rc = ldap_append_referral( ld, &unfollowed, ref );
			*hadrefp = 1;
			continue;
		}

		Debug( LDAP_DEBUG_TRACE,
		    "chasing LDAP referral: <%s>\n", ref, 0, 0 );

		*hadrefp = 1;

		/* See if we've already been here */
		if (( lc = find_connection( ld, srv, 1 )) != NULL ) {
			LDAPRequest *lp;
			int looped = 0;
			ber_len_t len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
			for ( lp = lr; lp; lp = lp->lr_parent ) {
				if ( lp->lr_conn == lc
					&& len == lp->lr_dn.bv_len )
				{
					if ( len && strncmp( srv->lud_dn, lp->lr_dn.bv_val, len ) )
							continue;
					looped = 1;
					break;
				}
			}
			if ( looped ) {
				ldap_free_urllist( srv );
				ld->ld_errno = LDAP_CLIENT_LOOP;
				rc = -1;
				continue;
			}
		}

		LDAP_NEXT_MSGID( ld, id );
		ber = re_encode_request( ld, origreq->lr_ber,
		    id, sref, srv, &rinfo.ri_request );

		if ( ber == NULL ) {
			return -1 ;
		}

		/* copy the complete referral for rebind process */
		rinfo.ri_url = LDAP_STRDUP( ref );

		rinfo.ri_msgid = origreq->lr_origid;

		rc = ldap_send_server_request( ld, ber, id,
			lr, &srv, NULL, &rinfo, 0, 1 );
		LDAP_FREE( rinfo.ri_url );

		if( rc >= 0 ) {
			++count;
		} else {
			Debug( LDAP_DEBUG_ANY,
				"Unable to chase referral \"%s\" (%d: %s)\n", 
				ref, ld->ld_errno, ldap_err2string( ld->ld_errno ) );
			rc = ldap_append_referral( ld, &unfollowed, ref );
		}

		ldap_free_urllist(srv);
	}

	LDAP_FREE( *errstrp );
	*errstrp = unfollowed;

	return(( rc == 0 ) ? count : rc );
}
示例#24
0
/*
 * Chase v3 referrals
 *
 * Parameters:
 *  (IN) ld = LDAP connection handle
 *  (IN) lr = LDAP Request structure
 *  (IN) refs = array of pointers to referral strings that we will chase
 *              The array will be free'd by this function when no longer needed
 *  (IN) sref != 0 if following search reference
 *  (OUT) errstrp = Place to return a string of referrals which could not be followed
 *  (OUT) hadrefp = 1 if sucessfully followed referral
 *
 * Return value - number of referrals followed
 *
 * Protected by res_mutex, conn_mutex and req_mutex	(try_read1msg)
 */
int
ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char **errstrp, int *hadrefp )
{
	char		*unfollowed;
	int		 unfollowedcnt = 0;
	LDAPRequest	*origreq;
	LDAPURLDesc	*srv = NULL;
	BerElement	*ber;
	char		**refarray = NULL;
	LDAPConn	*lc;
	int			 rc, count, i, j, id;
	LDAPreqinfo  rinfo;
	LDAP_NEXTREF_PROC	*nextref_proc = ld->ld_nextref_proc ? ld->ld_nextref_proc : ldap_int_nextref;

	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex );
	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex );
	Debug( LDAP_DEBUG_TRACE, "ldap_chase_v3referrals\n", 0, 0, 0 );

	ld->ld_errno = LDAP_SUCCESS;	/* optimistic */
	*hadrefp = 0;

	unfollowed = NULL;
	rc = count = 0;

	/* If no referrals in array, return */
	if ( (refs == NULL) || ( (refs)[0] == NULL) ) {
		rc = 0;
		goto done;
	}

	/* Check for hop limit exceeded */
	if ( lr->lr_parentcnt >= ld->ld_refhoplimit ) {
		Debug( LDAP_DEBUG_ANY,
		    "more than %d referral hops (dropping)\n", ld->ld_refhoplimit, 0, 0 );
		ld->ld_errno = LDAP_REFERRAL_LIMIT_EXCEEDED;
		rc = -1;
		goto done;
	}

	/* find original request */
	for ( origreq = lr;
		origreq->lr_parent != NULL;
		origreq = origreq->lr_parent )
	{
		/* empty */ ;
	}

	refarray = refs;
	refs = NULL;

	/* parse out & follow referrals */
	/* NOTE: if nextref_proc == ldap_int_nextref, params is ignored */
	i = -1;
	for ( nextref_proc( ld, &refarray, &i, ld->ld_nextref_params );
			i != -1;
			nextref_proc( ld, &refarray, &i, ld->ld_nextref_params ) )
	{

		/* Parse the referral URL */
		rc = ldap_url_parse_ext( refarray[i], &srv, LDAP_PVT_URL_PARSE_NOEMPTY_DN );
		if ( rc != LDAP_URL_SUCCESS ) {
			/* ldap_url_parse_ext() returns LDAP_URL_* errors
			 * which do not map on API errors */
			ld->ld_errno = LDAP_PARAM_ERROR;
			rc = -1;
			goto done;
		}

		if( srv->lud_crit_exts ) {
			int ok = 0;
#ifdef HAVE_TLS
			/* If StartTLS is the only critical ext, OK. */
			if ( find_tls_ext( srv ) == 2 && srv->lud_crit_exts == 1 )
				ok = 1;
#endif
			if ( !ok ) {
				/* we do not support any other extensions */
				ld->ld_errno = LDAP_NOT_SUPPORTED;
				rc = -1;
				goto done;
			}
		}

		/* check connection for re-bind in progress */
		if (( lc = find_connection( ld, srv, 1 )) != NULL ) {
			/* See if we've already requested this DN with this conn */
			LDAPRequest *lp;
			int looped = 0;
			ber_len_t len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
			for ( lp = origreq; lp; ) {
				if ( lp->lr_conn == lc
					&& len == lp->lr_dn.bv_len
					&& len
					&& strncmp( srv->lud_dn, lp->lr_dn.bv_val, len ) == 0 )
				{
					looped = 1;
					break;
				}
				if ( lp == origreq ) {
					lp = lp->lr_child;
				} else {
					lp = lp->lr_refnext;
				}
			}
			if ( looped ) {
				ldap_free_urllist( srv );
				srv = NULL;
				ld->ld_errno = LDAP_CLIENT_LOOP;
				rc = -1;
				continue;
			}

			if ( lc->lconn_rebind_inprogress ) {
				/* We are already chasing a referral or search reference and a
				 * bind on that connection is in progress.  We must queue
				 * referrals on that connection, so we don't get a request
				 * going out before the bind operation completes. This happens
				 * if two search references come in one behind the other
				 * for the same server with different contexts.
				 */
				Debug( LDAP_DEBUG_TRACE,
					"ldap_chase_v3referrals: queue referral \"%s\"\n",
					refarray[i], 0, 0);
				if( lc->lconn_rebind_queue == NULL ) {
					/* Create a referral list */
					lc->lconn_rebind_queue =
						(char ***) LDAP_MALLOC( sizeof(void *) * 2);

					if( lc->lconn_rebind_queue == NULL) {
						ld->ld_errno = LDAP_NO_MEMORY;
						rc = -1;
						goto done;
					}

					lc->lconn_rebind_queue[0] = refarray;
					lc->lconn_rebind_queue[1] = NULL;
					refarray = NULL;

				} else {
					/* Count how many referral arrays we already have */
					for( j = 0; lc->lconn_rebind_queue[j] != NULL; j++) {
						/* empty */;
					}

					/* Add the new referral to the list */
					lc->lconn_rebind_queue = (char ***) LDAP_REALLOC(
						lc->lconn_rebind_queue, sizeof(void *) * (j + 2));

					if( lc->lconn_rebind_queue == NULL ) {
						ld->ld_errno = LDAP_NO_MEMORY;
						rc = -1;
						goto done;
					}
					lc->lconn_rebind_queue[j] = refarray;
					lc->lconn_rebind_queue[j+1] = NULL;
					refarray = NULL;
				}

				/* We have queued the referral/reference, now just return */
				rc = 0;
				*hadrefp = 1;
				count = 1; /* Pretend we already followed referral */
				goto done;
			}
		} 
		/* Re-encode the request with the new starting point of the search.
		 * Note: In the future we also need to replace the filter if one
		 * was provided with the search reference
		 */

		/* For references we don't want old dn if new dn empty */
		if ( sref && srv->lud_dn == NULL ) {
			srv->lud_dn = LDAP_STRDUP( "" );
		}

		LDAP_NEXT_MSGID( ld, id );
		ber = re_encode_request( ld, origreq->lr_ber, id,
			sref, srv, &rinfo.ri_request );

		if( ber == NULL ) {
			ld->ld_errno = LDAP_ENCODING_ERROR;
			rc = -1;
			goto done;
		}

		Debug( LDAP_DEBUG_TRACE,
			"ldap_chase_v3referral: msgid %d, url \"%s\"\n",
			lr->lr_msgid, refarray[i], 0);

		/* Send the new request to the server - may require a bind */
		rinfo.ri_msgid = origreq->lr_origid;
		rinfo.ri_url = refarray[i];
		rc = ldap_send_server_request( ld, ber, id,
			origreq, &srv, NULL, &rinfo, 0, 1 );
		if ( rc < 0 ) {
			/* Failure, try next referral in the list */
			Debug( LDAP_DEBUG_ANY, "Unable to chase referral \"%s\" (%d: %s)\n", 
				refarray[i], ld->ld_errno, ldap_err2string( ld->ld_errno ) );
			unfollowedcnt += ldap_append_referral( ld, &unfollowed, refarray[i] );
			ldap_free_urllist( srv );
			srv = NULL;
			ld->ld_errno = LDAP_REFERRAL;
		} else {
			/* Success, no need to try this referral list further */
			rc = 0;
			++count;
			*hadrefp = 1;

			/* check if there is a queue of referrals that came in during bind */
			if ( lc == NULL) {
				lc = find_connection( ld, srv, 1 );
				if ( lc == NULL ) {
					ld->ld_errno = LDAP_OPERATIONS_ERROR;
					rc = -1;
					LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
					goto done;
				}
			}

			if ( lc->lconn_rebind_queue != NULL ) {
				/* Release resources of previous list */
				LDAP_VFREE( refarray );
				refarray = NULL;
				ldap_free_urllist( srv );
				srv = NULL;

				/* Pull entries off end of queue so list always null terminated */
				for( j = 0; lc->lconn_rebind_queue[j] != NULL; j++ )
					;
				refarray = lc->lconn_rebind_queue[j - 1];
				lc->lconn_rebind_queue[j-1] = NULL;
				/* we pulled off last entry from queue, free queue */
				if ( j == 1 ) {
					LDAP_FREE( lc->lconn_rebind_queue );
					lc->lconn_rebind_queue = NULL;
				}
				/* restart the loop the with new referral list */
				i = -1;
				continue;
			}
			break; /* referral followed, break out of for loop */
		}
	} /* end for loop */
done:
	LDAP_VFREE( refarray );
	ldap_free_urllist( srv );
	LDAP_FREE( *errstrp );
	
	if( rc == 0 ) {
		*errstrp = NULL;
		LDAP_FREE( unfollowed );
		return count;
	} else {
		*errstrp = unfollowed;
		return rc;
	}
}
示例#25
0
/* process_packet:
 * Callback which processes a packet captured by libpcap. */
void process_packet(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt)
{
    struct tcphdr tcp;
    int off, len, delta;
    connection *C, c;
    struct sockaddr_storage src, dst;
    struct sockaddr *s, *d;
    uint8_t proto;
    
    s = (struct sockaddr *)&src;
    d = (struct sockaddr *)&dst;

    if (handle_link_layer(&datalink_info, pkt, hdr->caplen, &proto, &off))
    	return;
	
    if (layer3_find_tcp(pkt, proto, &off, s, d, &tcp))
    	return;

    len = hdr->caplen - off;

    /* XXX fragmented packets and other nasties. */

    /* try to find the connection slot associated with this. */
    C = find_connection(s, d);

    /* no connection at all, so we need to allocate one. */
    if (!C) {
        log_msg(LOG_INFO, "new connection: %s", connection_string(s,d));
        C = alloc_connection();
        *C = connection_new(s, d);
        /* This might or might not be an entirely new connection (SYN flag
         * set). Either way we need a sequence number to start at. */
        (*C)->isn = ntohl(tcp.th_seq);
    }

    /* Now we need to process this segment. */
    c = *C;
    delta = 0;/*tcp.syn ? 1 : 0;*/

    /* NB (STD0007):
     *    SEG.LEN = the number of octets occupied by the data in the
     *    segment (counting SYN and FIN) */
#if 0
    if (tcp.syn)
        /* getting a new isn. */
        c->isn = htonl(tcp.seq);
#endif

    if (tcp.th_flags & TH_RST) {
        /* Looks like this connection is bogus, and so might be a
         * connection going the other way. */
        log_msg(LOG_INFO, "connection reset: %s", connection_string(s, d));

        connection_delete(c);
        *C = NULL;

        if ((C = find_connection(d, s))) {
            connection_delete(*C);
            *C = NULL;
        }

        return;
    }

    if (len > 0) {
        /* We have some data in the packet. If this data occurred after
         * the first data we collected for this connection, then save it
         * so that we can look for images. Otherwise, discard it. */
        unsigned int offset;

        offset = ntohl(tcp.th_seq);

        /* Modulo 2**32 arithmetic; offset = seq - isn + delta. */
        if (offset < (c->isn + delta))
            offset = 0xffffffff - (c->isn + delta - offset);
        else
            offset -= c->isn + delta;

        if (offset > c->len + WRAPLEN) {
            /* Out-of-order packet. */
            log_msg(LOG_INFO, "out of order packet: %s", connection_string(s, d));
        } else {
            connection_push(c, pkt + off, offset, len);
            extract_media(c);
        }
    }
    if (tcp.th_flags & TH_FIN) {
        /* Connection closing; mark it as closed, but let sweep_connections
         * free it if appropriate. */
        log_msg(LOG_INFO, "connection closing: %s, %d bytes transferred", connection_string(s, d), c->len);
        c->fin = 1;
    }

    /* sweep out old connections */
    sweep_connections();
}
示例#26
0
int
wait_for_events_and_walk(uber_state_t *uber_state) {
  struct timeval timeout;
  event_state_select_t *event_state = uber_state->event_state;

  fd_set loc_readfds;
  fd_set loc_writefds;

  connection_t *temp_connection;

  int ret;
  int i;
  int did_something;

  timeout.tv_sec = 2;
  timeout.tv_usec = 0;

  if (debug) {
    fprintf(stderr,"about to go into select\n");
  }

  /* rather blunt, but should be effective for now */
  memcpy(&loc_readfds, &(event_state->readfds),sizeof(fd_set));
  memcpy(&loc_writefds, &(event_state->writefds),sizeof(fd_set));

  ret = select(event_state->maxfd + 1,
	       &loc_readfds,
	       &loc_writefds,
	       NULL,   /* ignore exception for now */
	       &timeout);

  if (debug) {
    fprintf(stderr,
	    "select returned %d errno %d minfd %d maxfd %d\n",
	    ret,
	    errno,
	    event_state->minfd,
	    event_state->maxfd);
  }

  if (ret > 0) {
    /* first, the reads and accepts */
    for (i = event_state->minfd; i <= event_state->maxfd; i++) {
      if (FD_ISSET(i,&loc_readfds)) {
	temp_connection = find_connection(uber_state,i);
	if (debug) {
	  fprintf(stderr,
		  "fd %d is readable on connection %p\n",
		  i,
		  temp_connection);
	}
	/* is this our listen endpoint or something else? */
	if (temp_connection->flags & CONNECTION_LISTENING ) {
	  /* accept a connection */
	  SOCKET new_sock;
	  new_sock = accept_new_connection(uber_state,
					   temp_connection);
	  if (INVALID_SOCKET != new_sock) {
	    /* on the very good chance that this new connection is for
	       an FD higher than our listen endpoint, we set
	       loc_readfds so we go ahead and try to read from the new
	       connection when we get to that point in our walk of the
	       fdset returned from select(). */
	    FD_SET(new_sock,&loc_readfds);
	  }
	  /* if we got one connection, we should see about draining
	     the accept queue, eventually module some limit on the
	     number of concurrent connections we will allow */
	  while (new_sock >= 0) {
	    new_sock = accept_new_connection(uber_state,
					     temp_connection);
	    if (INVALID_SOCKET != new_sock) {
	      /* on the very good chance that this new connection is for
		 an FD higher than our listen endpoint, we set
		 loc_readfds so we go ahead and try to read from the new
		 connection when we get to that point in our walk of the
		 fdset returned from select(). */
	      FD_SET(new_sock,&loc_readfds);
	    }
	  }
	}
	else if (temp_connection->flags & CONNECTION_READING) {
	  /* read some bytes */
	}
	else {
	  /* something screwy happened */
	  fprintf(stderr,
		  "YO, we got readable on connection %p but we weren't reading\n",
		  temp_connection);
	}
      }
    }
    
    /* now the writes */
    for (i = event_state->minfd; i <= event_state->maxfd; i++) {
      if (FD_ISSET(i,&loc_writefds)) {
	temp_connection = find_connection(uber_state,i);
	fprintf(stderr,
		"fd %d is writable on connection %p\n",i,temp_connection);
      }
    }
  }

  return 0;
}
示例#27
0
void
test_define(iscsi_test_define_parameters_t *par)
{
	test_pars_t *tp;
	session_t *sess = NULL;
	connection_t *conn = NULL;

	if (!par->test_id) {
		par->status = ISCSI_STATUS_INVALID_ID;
		return;
	}
	if (find_test_id(par->test_id) != NULL) {
		par->status = ISCSI_STATUS_DUPLICATE_ID;
		return;
	}
	if (par->session_id &&
	    (sess = find_session(par->session_id)) == NULL) {
		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
		return;
	}
	if (sess != NULL) {
		if (par->connection_id &&
			(conn = find_connection(sess, par->connection_id)) == NULL) {
			par->status = ISCSI_STATUS_INVALID_CONNECTION_ID;
			return;
		} else if (!par->connection_id) {
			conn = TAILQ_FIRST(&sess->conn_list);
		}
		if (conn->test_pars != NULL) {
			par->status = ISCSI_STATUS_TEST_ALREADY_ASSIGNED;
			return;
		}
	}

	if ((tp = malloc(sizeof(*tp), M_TEMP, M_WAITOK | M_ZERO)) == NULL) {
		par->status = ISCSI_STATUS_NO_RESOURCES;
		return;
	}
	TAILQ_INIT(&tp->negs);
	TAILQ_INIT(&tp->mods);

	if (par->neg_descriptor_size &&
	    (par->status = add_neg(tp, par->neg_descriptor_ptr,
				par->neg_descriptor_size)) != 0) {
		free(tp, M_TEMP);
		return;
	}

	tp->test_id = par->test_id;
	tp->options = par->options;
	tp->lose_random[CNT_RX] = par->lose_random_rx;
	tp->lose_random[CNT_TX] = par->lose_random_tx;
	tp->connection = conn;
	tp->firstburst_val = par->firstburst_val;
	tp->maxburst_val = par->maxburst_val;
	tp->r2t_val = par->r2t_val;

	DEB(1, ("TestDefine: id=%d, opt=%x, negsize=%d, conn=%x\n",
		tp->test_id, tp->options, par->neg_descriptor_size, (int)conn));

	TAILQ_INSERT_TAIL(&test_list, tp, link);

	if (conn != NULL) {
		tp->connection = conn;
		conn->test_pars = tp;
		DEB(1, ("Assigning session %d, connection %d to test %d\n",
				conn->session->id, conn->id, tp->test_id));
	}

	par->status = ISCSI_STATUS_SUCCESS;
}
示例#28
0
文件: request.c 项目: andreiw/polaris
/* returns the message id of the request or -1 if an error occurs */
int
nsldapi_send_server_request(
    LDAP *ld,			/* session handle */
    BerElement *ber,		/* message to send */
    int msgid,			/* ID of message to send */
    LDAPRequest *parentreq,	/* non-NULL for referred requests */
    LDAPServer *srvlist,	/* servers to connect to (NULL for default) */
    LDAPConn *lc,		/* connection to use (NULL for default) */
    char *bindreqdn,		/* non-NULL for bind requests */
    int bind			/* perform a bind after opening new conn.? */
)
{
	LDAPRequest	*lr;
	int		err;
	int		incparent;	/* did we bump parent's ref count? */

	LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_send_server_request\n", 0, 0, 0 );

	incparent = 0;
	LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
	if ( lc == NULL ) {
		if ( srvlist == NULL ) {
			if ( ld->ld_defconn == NULL ) {
				LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
				if ( bindreqdn == NULL && ( ld->ld_options
				    & LDAP_BITOPT_RECONNECT ) != 0 ) {
					LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN,
					    NULL, NULL );
					ber_free( ber, 1 );
					LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
					LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
					return( -1 );
				}
				LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );

				if ( nsldapi_open_ldap_defconn( ld ) < 0 ) {
					ber_free( ber, 1 );
					LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
					return( -1 );
				}
			}
			lc = ld->ld_defconn;
		} else {
			if (( lc = find_connection( ld, srvlist, 1 )) ==
			    NULL ) {
				if ( bind && (parentreq != NULL) ) {
					/* Remember the bind in the parent */
					incparent = 1;
					++parentreq->lr_outrefcnt;
				}

				lc = nsldapi_new_connection( ld, &srvlist, 0,
					1, bind );
			}
			free_servers( srvlist );
		}
	}


    /*
     * the logic here is:
     * if 
     * 1. no connections exists, 
     * or 
     * 2. if the connection is either not in the connected 
     *     or connecting state in an async io model
     * or 
     * 3. the connection is notin a connected state with normal (non async io)
     */
	if (   lc == NULL
		|| (  (ld->ld_options & LDAP_BITOPT_ASYNC 
               && lc->lconn_status != LDAP_CONNST_CONNECTING
		    && lc->lconn_status != LDAP_CONNST_CONNECTED)
              || (!(ld->ld_options & LDAP_BITOPT_ASYNC )
		    && lc->lconn_status != LDAP_CONNST_CONNECTED) ) ) {

		ber_free( ber, 1 );
		if ( lc != NULL ) {
			LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
		}
		if ( incparent ) {
			/* Forget about the bind */
			--parentreq->lr_outrefcnt; 
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
		return( -1 );
	}

	use_connection( ld, lc );
	if (( lr = (LDAPRequest *)NSLDAPI_CALLOC( 1, sizeof( LDAPRequest ))) ==
	    NULL || ( bindreqdn != NULL && ( bindreqdn =
	    nsldapi_strdup( bindreqdn )) == NULL )) {
		if ( lr != NULL ) {
			NSLDAPI_FREE( lr );
		}
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		nsldapi_free_connection( ld, lc, NULL, NULL, 0, 0 );
		ber_free( ber, 1 );
		if ( incparent ) {
			/* Forget about the bind */
			--parentreq->lr_outrefcnt; 
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
		return( -1 );
	} 
	lr->lr_binddn = bindreqdn;
	lr->lr_msgid = msgid;
	lr->lr_status = LDAP_REQST_INPROGRESS;
	lr->lr_res_errno = LDAP_SUCCESS;	/* optimistic */
	lr->lr_ber = ber;
	lr->lr_conn = lc;

	if ( parentreq != NULL ) {	/* sub-request */
		if ( !incparent ) { 
			/* Increment if we didn't do it before the bind */
			++parentreq->lr_outrefcnt;
		}
		lr->lr_origid = parentreq->lr_origid;
		lr->lr_parentcnt = parentreq->lr_parentcnt + 1;
		lr->lr_parent = parentreq;
		if ( parentreq->lr_child != NULL ) {
			lr->lr_sibling = parentreq->lr_child;
		}
		parentreq->lr_child = lr;
	} else {			/* original request */
		lr->lr_origid = lr->lr_msgid;
	}

	LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
	if (( lr->lr_next = ld->ld_requests ) != NULL ) {
		lr->lr_next->lr_prev = lr;
	}
	ld->ld_requests = lr;
	lr->lr_prev = NULL;

	if (( err = nsldapi_ber_flush( ld, lc->lconn_sb, ber, 0, 1 )) != 0 ) {

		/* need to continue write later */
		if (ld->ld_options & LDAP_BITOPT_ASYNC && err == -2 ) {	
			lr->lr_status = LDAP_REQST_WRITING;
			nsldapi_iostatus_interest_write( ld, lc->lconn_sb );
		} else {

			LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
			nsldapi_free_request( ld, lr, 0 );
			nsldapi_free_connection( ld, lc, NULL, NULL, 0, 0 );
			LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
			LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
			return( -1 );
		}

	} else {
		if ( parentreq == NULL ) {
			ber->ber_end = ber->ber_ptr;
			ber->ber_ptr = ber->ber_buf;
		}

		/* sent -- waiting for a response */
		if (ld->ld_options & LDAP_BITOPT_ASYNC) {
			lc->lconn_status = LDAP_CONNST_CONNECTED;
		}

		nsldapi_iostatus_interest_read( ld, lc->lconn_sb );
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
	LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );

	LDAP_SET_LDERRNO( ld, LDAP_SUCCESS, NULL, NULL );
	return( msgid );
}
示例#29
0
/*
 * Input Device methods
 */
static DBusMessage *input_device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
//+++ BRCM
#ifdef BT_ALT_STACK
	struct input_device *idev = data;
	tDTUN_DEVICE_METHOD method;

	method.hh_open.hdr.id = DTUN_METHOD_HH_OPEN;
	method.hh_open.hdr.len = sizeof(tDTUN_METHOD_HH_OPEN) - sizeof(tDTUN_HDR);
	memcpy(&method.hh_open.bdaddr, &idev->dst, 6);
	read_remote_class(&idev->src, &idev->dst, &method.hh_open.cod);

	dtun_client_call_method(&method);
	return NULL;
#else
	struct input_device *idev = data;
	struct input_conn *iconn;
	struct fake_input *fake;
	DBusMessage *reply;
	GError *err = NULL;

	iconn = find_connection(idev->connections, "HID");
	if (!iconn)
		return btd_error_not_supported(msg);

	if (iconn->pending_connect)
		return btd_error_in_progress(msg);

	if (is_connected(iconn))
		return btd_error_already_connected(msg);

	iconn->pending_connect = dbus_message_ref(msg);
	fake = iconn->fake;

	if (fake) {
		/* Fake input device */
		if (fake->connect(iconn, &err))
			fake->flags |= FI_FLAG_CONNECTED;
	} else {
		/* HID devices */
		GIOChannel *io;

		io = bt_io_connect(BT_IO_L2CAP, control_connect_cb, iconn,
					NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &idev->src,
					BT_IO_OPT_DEST_BDADDR, &idev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_POWER_ACTIVE, 0,
					BT_IO_OPT_INVALID);
		iconn->ctrl_io = io;
	}

	if (err == NULL)
		return NULL;

	error("%s", err->message);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
	reply = btd_error_failed(msg, err->message);
	g_error_free(err);
	return reply;
#endif
//--- BRCM
}
示例#30
0
static int proc_master_connect(int fd, int token, rscntxt_t *cntxt) {
	Log("proc master connect\n");
	connection_t *conn = find_connection(cntxt, token);
	if (conn == NULL) {
		Log("Invalid token:%d from the master device\n", token);
		close (fd);
		return -1;
	} 

	int fd_slave = conn->conn_fd;
	struct sockaddr_in addr;
	int addr_len = sizeof(addr);
	if (getpeername(fd, (struct sockaddr *)&addr, &addr_len) < 0) {
		Log("Failed getsockname of master device");
		close (fd);	
		return -1;
	}

	uint32 ip = addr.sin_addr.s_addr;
	int port = addr.sin_port;
	msgheader_t header;
	memset(&header, 0, sizeof(header));
	header.message_type = htonl(REQ_RELAY);
	header.ip = ip;
	header.port = port;
	int nsize = sizeof(header);
	if(send(fd_slave, &header, nsize, 0) <= 0) {
		Log("Failed send resquest relay to slave device\n");
		return -1;
	}

	Log("sent req_relay to slave device\n");

	if (recv(fd_slave, &header, nsize, 0) <= 0) {
		Log("Failed recv slave device response reply\n");
		return -1;
	}

	if (header.message_type != RES_RELAY) {
		Log("Slave device response an invalid reply\n");
		return -1;
	}

	Log("recv res_relay from slave device\n");

	if (getpeername(fd_slave, (struct sockaddr *)&addr, &addr_len) < 0) {
		Log("Failed getsockname of slave device");
		close (fd);	
		return -1;
	}
	ip = addr.sin_addr.s_addr;
	port = addr.sin_port;
	header.ip = ip;
	header.port = port;
	header.token = htonl(token);
	if (send(fd, &header, nsize, 0) != nsize) {
		Log("Failed send master response message");
		close(fd);
		return -1;
	}

	return 0;
}