This prepares the structures for multi-channel support.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
enum protocol_types protocol;
struct {
+ int sock;
+
struct {
bool got_session;
} nbt;
struct smbd_server_connection {
NTSTATUS status;
- int sock;
const struct tsocket_address *local_address;
const struct tsocket_address *remote_address;
const char *remote_hostname;
sconn->ev_ctx = ev;
sconn->msg_ctx = msg;
- sconn->sock = -1;
smbd_echo_init(sconn);
conn = conn_new(sconn);
len = smb_len_large(buf_out) + 4;
- ret = write_data(sconn->sock, buf_out, len);
+ ret = write_data(xconn->transport.sock, buf_out, len);
if (ret <= 0) {
int saved_errno = errno;
/*
static void smbd_server_connection_read_handler(
struct smbd_server_connection *sconn, int fd)
{
+ struct smbXsrv_connection *xconn = sconn->conn;
uint8_t *inbuf = NULL;
size_t inbuf_len = 0;
size_t unread_bytes = 0;
}
}
- from_client = (sconn->sock == fd);
+ from_client = (xconn->transport.sock == fd);
if (async_echo && from_client) {
smbd_lock_socket(sconn);
{
struct smbd_server_connection *conn = talloc_get_type(private_data,
struct smbd_server_connection);
+ struct smbXsrv_connection *xconn = conn->conn;
if (!NT_STATUS_IS_OK(conn->status)) {
/*
return;
}
if (flags & TEVENT_FD_READ) {
- smbd_server_connection_read_handler(conn, conn->sock);
+ smbd_server_connection_read_handler(conn, xconn->transport.sock);
return;
}
}
}
smbd_lock_socket(sconn);
- ret = send_keepalive(sconn->sock);
+ ret = send_keepalive(xconn->transport.sock);
smbd_unlock_socket(sconn);
if (!ret) {
{
struct tevent_req *req, *subreq;
struct smbd_echo_read_state *state;
+ struct smbXsrv_connection *xconn = sconn->conn;
req = tevent_req_create(mem_ctx, &state,
struct smbd_echo_read_state);
state->ev = ev;
state->sconn = sconn;
- subreq = wait_for_read_send(state, ev, sconn->sock);
+ subreq = wait_for_read_send(state, ev, xconn->transport.sock);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
struct smbd_echo_read_state *state = tevent_req_data(
req, struct smbd_echo_read_state);
struct smbd_server_connection *sconn = state->sconn;
+ struct smbXsrv_connection *xconn = sconn->conn;
bool ok;
NTSTATUS status;
size_t unread = 0;
return;
}
- if (!fd_is_readable(sconn->sock)) {
+ if (!fd_is_readable(xconn->transport.sock)) {
DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
(int)getpid()));
return;
}
- subreq = wait_for_read_send(state, state->ev, sconn->sock);
+ subreq = wait_for_read_send(state, state->ev,
+ xconn->transport.sock);
if (tevent_req_nomem(subreq, req)) {
return;
}
return;
}
- status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
+ status = receive_smb_talloc(state, sconn,
+ xconn->transport.sock,
+ &state->buf,
0 /* timeout */,
&unread,
&encrypted,
conn->ev_ctx = ev_ctx;
conn->msg_ctx = msg_ctx;
+ conn->transport.sock = sock_fd;
sconn = talloc_zero(conn, struct smbd_server_connection);
if (!sconn) {
sconn->ev_ctx = ev_ctx;
sconn->msg_ctx = msg_ctx;
- sconn->sock = sock_fd;
smbd_echo_init(sconn);
if (!interactive) {
}
/* Ensure child is set to blocking mode */
- set_blocking(sconn->sock,True);
+ set_blocking(sock_fd,True);
- set_socket_options(sconn->sock, "SO_KEEPALIVE");
- set_socket_options(sconn->sock, lp_socket_options());
+ set_socket_options(sock_fd, "SO_KEEPALIVE");
+ set_socket_options(sock_fd, lp_socket_options());
sa_socklen = sizeof(ss_clnt);
ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
}
sconn->smb1.fde = tevent_add_fd(ev_ctx,
- sconn,
- sconn->sock,
- TEVENT_FD_READ,
- smbd_server_connection_handler,
- sconn);
+ sconn,
+ sock_fd,
+ TEVENT_FD_READ,
+ smbd_server_connection_handler,
+ sconn);
if (!sconn->smb1.fde) {
exit_server("failed to create smbd_server_connection fde");
}
static bool netbios_session_retarget(struct smbd_server_connection *sconn,
const char *name, int name_type)
{
+ struct smbXsrv_connection *xconn = sconn->conn;
char *trim_name;
char *trim_name_type;
const char *retarget_parm;
bool ret = false;
uint8_t outbuf[10];
- if (get_socket_port(sconn->sock) != NBT_SMB_PORT) {
+ if (get_socket_port(xconn->transport.sock) != NBT_SMB_PORT) {
return false;
}
memset(buf + ret, '\0', cur_read - ret);
}
- ret = write_data(xconn->sconn->sock, buf, cur_read);
+ ret = write_data(xconn->transport.sock, buf, cur_read);
if (ret != cur_read) {
int saved_errno = errno;
/*
ssize_t ret;
to_write = MIN(SHORT_SEND_BUFSIZE, smb_maxcnt - nread);
- ret = write_data(xconn->sconn->sock, buf, to_write);
+ ret = write_data(xconn->transport.sock, buf, to_write);
if (ret != to_write) {
int saved_errno = errno;
/*
SIVAL(header,0,0);
smbd_lock_socket(sconn);
- if (write_data(sconn->sock,header,4) != 4) {
+ if (write_data(xconn->transport.sock,header,4) != 4) {
int saved_errno = errno;
/*
* Try and give an error message saying what
_smb_setlen(header,nread);
header_blob = data_blob_const(header, 4);
- sendfile_read = SMB_VFS_SENDFILE(sconn->sock, fsp,
+ sendfile_read = SMB_VFS_SENDFILE(xconn->transport.sock, fsp,
&header_blob, startpos,
nread);
if (sendfile_read == -1) {
}
_smb_setlen(outbuf,ret);
- if (write_data(sconn->sock, outbuf, 4+ret) != 4+ret) {
+ if (write_data(xconn->transport.sock, outbuf, 4+ret) != 4+ret) {
int saved_errno = errno;
/*
* Try and give an error message saying what
construct_reply_common_req(req, (char *)headerbuf);
setup_readX_header(req, (char *)headerbuf, smb_maxcnt);
- nread = SMB_VFS_SENDFILE(req->sconn->sock, fsp, &header,
+ nread = SMB_VFS_SENDFILE(xconn->transport.sock, fsp, &header,
startpos, smb_maxcnt);
if (nread == -1) {
saved_errno = errno;
setup_readX_header(req, (char *)headerbuf, smb_maxcnt);
/* Send out the header. */
- ret = write_data(req->sconn->sock, (char *)headerbuf,
+ ret = write_data(xconn->transport.sock, (char *)headerbuf,
sizeof(headerbuf));
if (ret != sizeof(headerbuf)) {
saved_errno = errno;
}
/* Now read the raw data into the buffer and write it */
- status = read_smb_length(req->sconn->sock, buf, SMB_SECONDARY_WAIT,
+ status = read_smb_length(xconn->transport.sock, buf, SMB_SECONDARY_WAIT,
&numtowrite);
if (!NT_STATUS_IS_OK(status)) {
exit_server_cleanly("secondary writebraw failed");
(int)tcount,(int)nwritten,(int)numtowrite));
}
- status = read_data(req->sconn->sock, buf+4, numtowrite);
+ status = read_data(xconn->transport.sock, buf+4, numtowrite);
if (!NT_STATUS_IS_OK(status)) {
/* Try and give an error message
* sending a NBSSkeepalive. Thanks to DaveCB at Sun for this.
* JRA.
*/
- if (!send_keepalive(req->sconn->sock)) {
+ if (!send_keepalive(xconn->transport.sock)) {
exit_server_cleanly("reply_writebraw: send of "
"keepalive failed");
}
void reply_write_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smbXsrv_connection *xconn = req->sconn->conn;
files_struct *fsp;
struct lock_struct lock;
off_t startpos;
out:
if (req->unread_bytes) {
/* writeX failed. drain socket. */
- if (drain_socket(req->sconn->sock, req->unread_bytes) !=
+ if (drain_socket(xconn->transport.sock, req->unread_bytes) !=
req->unread_bytes) {
smb_panic("failed to drain pending bytes");
}
bool (*snumused) (struct smbd_server_connection *, int),
bool test)
{
+ struct smbXsrv_connection *xconn = NULL;
bool ret;
+ if (sconn != NULL) {
+ xconn = sconn->conn;
+ }
+
if (lp_loaded()) {
char *fname = lp_next_configfile(talloc_tos());
if (file_exist(fname) &&
load_interfaces();
- if (sconn != NULL) {
- set_socket_options(sconn->sock, "SO_KEEPALIVE");
- set_socket_options(sconn->sock, lp_socket_options());
+ if (xconn != NULL) {
+ set_socket_options(xconn->transport.sock, "SO_KEEPALIVE");
+ set_socket_options(xconn->transport.sock, lp_socket_options());
}
mangle_reset_cache();
ssize_t ret;
int saved_errno;
- nread = SMB_VFS_SENDFILE(fsp->conn->sconn->sock,
+ nread = SMB_VFS_SENDFILE(xconn->transport.sock,
fsp,
hdr,
in_offset,
normal_read:
/* Send out the header. */
- ret = write_data(fsp->conn->sconn->sock,
+ ret = write_data(xconn->transport.sock,
(const char *)hdr->data, hdr->length);
if (ret != hdr->length) {
saved_errno = errno;
static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *sconn)
{
+ struct smbXsrv_connection *xconn = sconn->conn;
+
TALLOC_FREE(sconn->smb1.fde);
sconn->smb2.send_queue = NULL;
sconn->smb2.fde = tevent_add_fd(sconn->ev_ctx,
sconn,
- sconn->sock,
+ xconn->transport.sock,
TEVENT_FD_READ,
smbd_smb2_connection_handler,
sconn);
}
/* Ensure child is set to non-blocking mode */
- set_blocking(sconn->sock, false);
+ set_blocking(xconn->transport.sock, false);
return NT_STATUS_OK;
}
DATA_BLOB *info,
const char *location)
{
+ struct smbXsrv_connection *xconn = req->sconn->conn;
DATA_BLOB body;
DATA_BLOB _dyn;
uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
size_t ret;
errno = 0;
- ret = drain_socket(req->sconn->sock, unread_bytes);
+ ret = drain_socket(xconn->transport.sock, unread_bytes);
if (ret != unread_bytes) {
NTSTATUS error;
static NTSTATUS smbd_smb2_flush_send_queue(struct smbd_server_connection *sconn)
{
+ struct smbXsrv_connection *xconn = sconn->conn;
int ret;
int err;
bool retry;
continue;
}
- ret = writev(sconn->sock, e->vector, e->count);
+ ret = writev(xconn->transport.sock, e->vector, e->count);
if (ret == 0) {
/* propagate end of file */
return NT_STATUS_INTERNAL_ERROR;
static NTSTATUS smbd_smb2_io_handler(struct smbd_server_connection *sconn,
uint16_t fde_flags)
{
+ struct smbXsrv_connection *xconn = sconn->conn;
struct smbd_smb2_request_read_state *state = &sconn->smb2.request_read_state;
struct smbd_smb2_request *req = NULL;
size_t min_recvfile_size = UINT32_MAX;
state->vector.iov_len = NBT_HDR_SIZE;
}
- ret = readv(sconn->sock, &state->vector, 1);
+ ret = readv(xconn->transport.sock, &state->vector, 1);
if (ret == 0) {
/* propagate end of file */
return NT_STATUS_END_OF_FILE;
ssize_t ret;
if (req && req->unread_bytes) {
- int sockfd = req->sconn->sock;
+ int sockfd = req->sconn->conn->transport.sock;
int old_flags;
SMB_ASSERT(req->unread_bytes == N);
/* VFS_RECVFILE must drain the socket
ssize_t ret;
if (req && req->unread_bytes) {
- int sockfd = req->sconn->sock;
+ int sockfd = req->sconn->conn->transport.sock;
SMB_ASSERT(req->unread_bytes == N);
/* VFS_RECVFILE must drain the socket
* before returning. */