Ejemplo n.º 1
0
struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
					struct event_context *ev,
					const struct sockaddr_storage *pss,
					uint16_t port,
					int timeout)
{
	char addr[INET6_ADDRSTRLEN];
	struct tevent_req *result, *subreq;
	struct open_socket_out_state *state;
	NTSTATUS status;

	result = tevent_req_create(mem_ctx, &state,
				   struct open_socket_out_state);
	if (result == NULL) {
		return NULL;
	}
	state->ev = ev;
	state->ss = *pss;
	state->port = port;
	state->wait_usec = 10000;
	state->salen = -1;

	state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
	if (state->fd == -1) {
		status = map_nt_error_from_unix(errno);
		goto post_status;
	}
	talloc_set_destructor(state, open_socket_out_state_destructor);

	if (!tevent_req_set_endtime(
		    result, ev, timeval_current_ofs_msec(timeout))) {
		goto fail;
	}

#if defined(HAVE_IPV6)
	if (pss->ss_family == AF_INET6) {
		struct sockaddr_in6 *psa6;
		psa6 = (struct sockaddr_in6 *)&state->ss;
		psa6->sin6_port = htons(port);
		if (psa6->sin6_scope_id == 0
		    && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
			setup_linklocal_scope_id(
				(struct sockaddr *)&(state->ss));
		}
		state->salen = sizeof(struct sockaddr_in6);
	}
#endif
	if (pss->ss_family == AF_INET) {
		struct sockaddr_in *psa;
		psa = (struct sockaddr_in *)&state->ss;
		psa->sin_port = htons(port);
		state->salen = sizeof(struct sockaddr_in);
	}

	if (pss->ss_family == AF_UNIX) {
		state->salen = sizeof(struct sockaddr_un);
	}

	print_sockaddr(addr, sizeof(addr), &state->ss);
	DEBUG(3,("Connecting to %s at port %u\n", addr,	(unsigned int)port));

	subreq = async_connect_send(state, state->ev, state->fd,
				    (struct sockaddr *)&state->ss,
				    state->salen);
	if ((subreq == NULL)
	    || !tevent_req_set_endtime(
		    subreq, state->ev,
		    timeval_current_ofs(0, state->wait_usec))) {
		goto fail;
	}
	tevent_req_set_callback(subreq, open_socket_out_connected, result);
	return result;

 post_status:
	tevent_req_nterror(result, status);
	return tevent_req_post(result, ev);
 fail:
	TALLOC_FREE(result);
	return NULL;
}
Ejemplo n.º 2
0
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
		struct smb_request *req,
		files_struct *fsp,
		int lock_timeout,
		int lock_num,
		uint64_t smblctx,
		enum brl_type lock_type,
		enum brl_flavour lock_flav,
		uint64_t offset,
		uint64_t count,
		uint64_t blocking_smblctx)
{
	struct smbd_server_connection *sconn = req->sconn;
	struct blocking_lock_record *blr;
	NTSTATUS status;

	if (req->smb2req) {
		return push_blocking_lock_request_smb2(br_lck,
				req,
				fsp,
				lock_timeout,
				lock_num,
				smblctx,
				lock_type,
				lock_flav,
				offset,
				count,
				blocking_smblctx);
	}

	if(req_is_in_chain(req)) {
		DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
		return False;
	}

	/*
	 * Now queue an entry on the blocking lock queue. We setup
	 * the expiration time here.
	 */

	blr = talloc(NULL, struct blocking_lock_record);
	if (blr == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
		return False;
	}

	blr->next = NULL;
	blr->prev = NULL;

	blr->fsp = fsp;
	if (lock_timeout == -1) {
		blr->expire_time.tv_sec = 0;
		blr->expire_time.tv_usec = 0; /* Never expire. */
	} else {
		blr->expire_time = timeval_current_ofs_msec(lock_timeout);
	}
	blr->lock_num = lock_num;
	blr->smblctx = smblctx;
	blr->blocking_smblctx = blocking_smblctx;
	blr->lock_flav = lock_flav;
	blr->lock_type = lock_type;
	blr->offset = offset;
	blr->count = count;

	/* Specific brl_lock() implementations can fill this in. */
	blr->blr_private = NULL;

	/* Add a pending lock record for this. */
	status = brl_lock(req->sconn->msg_ctx,
			br_lck,
			smblctx,
			messaging_server_id(req->sconn->msg_ctx),
			offset,
			count,
			lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
			blr->lock_flav,
			True,
			NULL,
			blr);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
		TALLOC_FREE(blr);
		return False;
	}

	SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd);
	blr->req = talloc_move(blr, &req);

	DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr, struct blocking_lock_record *);
	recalc_brl_timeout(sconn);

	/* Ensure we'll receive messages when this is unlocked. */
	if (!sconn->smb1.locks.blocking_lock_unlock_state) {
		messaging_register(sconn->msg_ctx, sconn,
				   MSG_SMB_UNLOCK, received_unlock_msg);
		sconn->smb1.locks.blocking_lock_unlock_state = true;
	}

	DEBUG(3,("push_blocking_lock_request: lock request blocked with "
		"expiry time (%u sec. %u usec) (+%d msec) for %s, name = %s\n",
		(unsigned int)blr->expire_time.tv_sec,
		(unsigned int)blr->expire_time.tv_usec, lock_timeout,
		fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp)));

	return True;
}