2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
SMB client transport context management functions
Copyright ( C ) Andrew Tridgell 1994 - 2003
Copyright ( C ) James Myers 2003 < myersjj @ samba . org >
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-09-25 15:18:04 +04:00
static void smbcli_transport_process_recv ( struct smbcli_transport * transport ) ;
static void smbcli_transport_process_send ( struct smbcli_transport * transport ) ;
2004-07-23 10:40:49 +04:00
/*
an event has happened on the socket
*/
2004-08-04 17:23:35 +04:00
static void smbcli_transport_event_handler ( struct event_context * ev , struct fd_event * fde ,
2004-07-23 10:40:49 +04:00
time_t t , uint16_t flags )
{
2004-08-04 17:23:35 +04:00
struct smbcli_transport * transport = fde - > private ;
2004-07-23 10:40:49 +04:00
2004-09-25 15:18:04 +04:00
if ( flags & EVENT_FD_READ ) {
smbcli_transport_process_recv ( transport ) ;
}
if ( flags & EVENT_FD_WRITE ) {
smbcli_transport_process_send ( transport ) ;
}
2004-07-23 10:40:49 +04:00
}
2003-08-13 05:53:07 +04:00
/*
create a transport structure based on an established socket
*/
2004-08-04 17:23:35 +04:00
struct smbcli_transport * smbcli_transport_init ( struct smbcli_socket * sock )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_transport * transport ;
2004-07-23 10:40:49 +04:00
struct fd_event fde ;
2003-08-13 05:53:07 +04:00
2004-09-26 10:44:08 +04:00
transport = talloc_p ( sock , struct smbcli_transport ) ;
2003-08-13 05:53:07 +04:00
if ( ! transport ) return NULL ;
2004-08-21 11:43:29 +04:00
ZERO_STRUCTP ( transport ) ;
2004-07-23 10:40:49 +04:00
transport - > event . ctx = event_context_init ( ) ;
if ( transport - > event . ctx = = NULL ) {
2004-09-08 04:00:56 +04:00
talloc_free ( transport ) ;
2004-07-23 10:40:49 +04:00
return NULL ;
}
2003-08-13 05:53:07 +04:00
transport - > socket = sock ;
transport - > negotiate . protocol = PROTOCOL_NT1 ;
2004-07-06 03:28:49 +04:00
transport - > options . use_spnego = lp_use_spnego ( ) ;
2003-08-13 05:53:07 +04:00
transport - > negotiate . max_xmit = ~ 0 ;
2004-07-12 13:11:13 +04:00
2004-08-04 17:23:35 +04:00
smbcli_init_signing ( transport ) ;
2004-07-12 13:11:13 +04:00
2003-08-13 05:53:07 +04:00
transport - > socket - > reference_count + + ;
2003-11-17 06:38:13 +03:00
ZERO_STRUCT ( transport - > called ) ;
2004-07-23 10:40:49 +04:00
fde . fd = sock - > fd ;
fde . flags = EVENT_FD_READ ;
2004-08-04 17:23:35 +04:00
fde . handler = smbcli_transport_event_handler ;
2004-07-23 10:40:49 +04:00
fde . private = transport ;
fde . ref_count = 1 ;
transport - > event . fde = event_add_fd ( transport - > event . ctx , & fde ) ;
2003-08-13 05:53:07 +04:00
return transport ;
}
/*
decrease reference count on a transport , and destroy if it becomes
zero
*/
2004-08-04 17:23:35 +04:00
void smbcli_transport_close ( struct smbcli_transport * transport )
2003-08-13 05:53:07 +04:00
{
transport - > reference_count - - ;
if ( transport - > reference_count < = 0 ) {
2004-07-23 10:40:49 +04:00
event_remove_fd ( transport - > event . ctx , transport - > event . fde ) ;
event_remove_timed ( transport - > event . ctx , transport - > event . te ) ;
event_context_destroy ( transport - > event . ctx ) ;
2004-09-26 11:04:35 +04:00
smbcli_sock_close ( transport - > socket ) ;
2003-08-13 05:53:07 +04:00
}
}
2004-04-23 08:21:22 +04:00
/*
mark the transport as dead
*/
2004-08-04 17:23:35 +04:00
void smbcli_transport_dead ( struct smbcli_transport * transport )
2004-04-23 08:21:22 +04:00
{
2004-08-04 17:23:35 +04:00
smbcli_sock_dead ( transport - > socket ) ;
2004-08-03 12:04:11 +04:00
/* all pending sends become errors */
while ( transport - > pending_send ) {
2004-08-04 17:23:35 +04:00
struct smbcli_request * req = transport - > pending_send ;
req - > state = SMBCLI_REQUEST_ERROR ;
2004-08-03 12:04:11 +04:00
req - > status = NT_STATUS_NET_WRITE_FAULT ;
DLIST_REMOVE ( transport - > pending_send , req ) ;
if ( req - > async . fn ) {
req - > async . fn ( req ) ;
}
}
/* as do all pending receives */
while ( transport - > pending_recv ) {
2004-08-04 17:23:35 +04:00
struct smbcli_request * req = transport - > pending_recv ;
req - > state = SMBCLI_REQUEST_ERROR ;
2004-08-03 12:04:11 +04:00
req - > status = NT_STATUS_NET_WRITE_FAULT ;
DLIST_REMOVE ( transport - > pending_recv , req ) ;
if ( req - > async . fn ) {
req - > async . fn ( req ) ;
}
}
2004-04-23 08:21:22 +04:00
}
2003-08-13 05:53:07 +04:00
2004-07-23 10:40:49 +04:00
/*
enable select for write on a transport
*/
2004-08-04 17:23:35 +04:00
static void smbcli_transport_write_enable ( struct smbcli_transport * transport )
2004-07-23 10:40:49 +04:00
{
transport - > event . fde - > flags | = EVENT_FD_WRITE ;
}
/*
disable select for write on a transport
*/
2004-08-04 17:23:35 +04:00
static void smbcli_transport_write_disable ( struct smbcli_transport * transport )
2004-07-23 10:40:49 +04:00
{
transport - > event . fde - > flags & = ~ EVENT_FD_WRITE ;
}
2003-08-13 05:53:07 +04:00
/****************************************************************************
send a session request ( if appropriate )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-08-04 17:23:35 +04:00
BOOL smbcli_transport_connect ( struct smbcli_transport * transport ,
2003-08-13 05:53:07 +04:00
struct nmb_name * calling ,
struct nmb_name * called )
{
char * p ;
int len = NBT_HDR_SIZE ;
2004-08-04 17:23:35 +04:00
struct smbcli_request * req ;
2003-08-13 05:53:07 +04:00
2003-11-17 06:38:13 +03:00
if ( called ) {
transport - > called = * called ;
}
2003-08-13 05:53:07 +04:00
/* 445 doesn't have session request */
if ( transport - > socket - > port = = 445 ) {
return True ;
}
/* allocate output buffer */
2004-08-04 17:23:35 +04:00
req = smbcli_request_setup_nonsmb ( transport , NBT_HDR_SIZE + 2 * nbt_mangled_name_len ( ) ) ;
2003-08-13 05:53:07 +04:00
/* put in the destination name */
p = req - > out . buffer + NBT_HDR_SIZE ;
name_mangle ( called - > name , p , called - > name_type ) ;
len + = name_len ( p ) ;
/* and my name */
p = req - > out . buffer + len ;
name_mangle ( calling - > name , p , calling - > name_type ) ;
len + = name_len ( p ) ;
_smb_setlen ( req - > out . buffer , len - 4 ) ;
SCVAL ( req - > out . buffer , 0 , 0x81 ) ;
2004-08-04 17:23:35 +04:00
if ( ! smbcli_request_send ( req ) | |
! smbcli_request_receive ( req ) ) {
smbcli_request_destroy ( req ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
if ( CVAL ( req - > in . buffer , 0 ) ! = 0x82 ) {
transport - > error . etype = ETYPE_NBT ;
transport - > error . e . nbt_error = CVAL ( req - > in . buffer , 4 ) ;
2004-08-04 17:23:35 +04:00
smbcli_request_destroy ( req ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_request_destroy ( req ) ;
2003-08-13 05:53:07 +04:00
return True ;
}
/****************************************************************************
get next mid in sequence
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-08-04 17:23:35 +04:00
uint16_t smbcli_transport_next_mid ( struct smbcli_transport * transport )
2003-08-13 05:53:07 +04:00
{
2004-05-25 21:24:24 +04:00
uint16_t mid ;
2004-08-04 17:23:35 +04:00
struct smbcli_request * req ;
2003-08-13 05:53:07 +04:00
mid = transport - > next_mid ;
again :
/* now check to see if this mid is being used by one of the
pending requests . This is quite efficient because the list is
usually very short */
/* the zero mid is reserved for requests that don't have a mid */
if ( mid = = 0 ) mid = 1 ;
2004-07-23 10:40:49 +04:00
for ( req = transport - > pending_recv ; req ; req = req - > next ) {
2003-08-13 05:53:07 +04:00
if ( req - > mid = = mid ) {
mid + + ;
goto again ;
}
}
transport - > next_mid = mid + 1 ;
return mid ;
}
2004-07-23 10:40:49 +04:00
static void idle_handler ( struct event_context * ev ,
struct timed_event * te , time_t t )
{
2004-08-04 17:23:35 +04:00
struct smbcli_transport * transport = te - > private ;
2004-07-23 10:40:49 +04:00
te - > next_event = t + transport - > idle . period ;
transport - > idle . func ( transport , transport - > idle . private ) ;
}
2003-08-13 05:53:07 +04:00
/*
setup the idle handler for a transport
2004-07-23 10:40:49 +04:00
the period is in seconds
2003-08-13 05:53:07 +04:00
*/
2004-08-04 17:23:35 +04:00
void smbcli_transport_idle_handler ( struct smbcli_transport * transport ,
void ( * idle_func ) ( struct smbcli_transport * , void * ) ,
2003-08-13 05:53:07 +04:00
uint_t period ,
void * private )
{
2004-07-23 10:40:49 +04:00
struct timed_event te ;
2003-08-13 05:53:07 +04:00
transport - > idle . func = idle_func ;
transport - > idle . private = private ;
transport - > idle . period = period ;
2004-07-23 10:40:49 +04:00
if ( transport - > event . te ! = NULL ) {
event_remove_timed ( transport - > event . ctx , transport - > event . te ) ;
}
te . next_event = time ( NULL ) + period ;
te . handler = idle_handler ;
te . private = transport ;
transport - > event . te = event_add_timed ( transport - > event . ctx , & te ) ;
}
2003-08-13 05:53:07 +04:00
/*
2004-07-23 10:40:49 +04:00
process some pending sends
2003-08-13 05:53:07 +04:00
*/
2004-08-04 17:23:35 +04:00
static void smbcli_transport_process_send ( struct smbcli_transport * transport )
2003-08-13 05:53:07 +04:00
{
2004-07-23 10:40:49 +04:00
while ( transport - > pending_send ) {
2004-08-04 17:23:35 +04:00
struct smbcli_request * req = transport - > pending_send ;
2004-07-23 10:40:49 +04:00
ssize_t ret ;
2004-08-04 17:23:35 +04:00
ret = smbcli_sock_write ( transport - > socket , req - > out . buffer , req - > out . size ) ;
2004-07-23 10:40:49 +04:00
if ( ret = = - 1 ) {
if ( errno = = EAGAIN | | errno = = EINTR ) {
return ;
}
2004-08-04 17:23:35 +04:00
smbcli_transport_dead ( transport ) ;
2004-09-25 15:18:04 +04:00
return ;
2004-07-23 10:40:49 +04:00
}
req - > out . buffer + = ret ;
req - > out . size - = ret ;
if ( req - > out . size = = 0 ) {
DLIST_REMOVE ( transport - > pending_send , req ) ;
2004-08-03 10:52:06 +04:00
if ( req - > one_way_request ) {
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_DONE ;
smbcli_request_destroy ( req ) ;
2004-08-03 10:52:06 +04:00
} else {
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_RECV ;
2004-08-03 10:52:06 +04:00
DLIST_ADD ( transport - > pending_recv , req ) ;
}
2004-07-23 10:40:49 +04:00
}
}
2003-08-13 05:53:07 +04:00
2004-07-23 10:40:49 +04:00
/* we're out of requests to send, so don't wait for write
events any more */
2004-08-04 17:23:35 +04:00
smbcli_transport_write_disable ( transport ) ;
2004-07-23 10:40:49 +04:00
}
2003-08-13 05:53:07 +04:00
/*
2004-07-23 10:40:49 +04:00
we have a full request in our receive buffer - match it to a pending request
and process
*/
2004-08-04 17:23:35 +04:00
static void smbcli_transport_finish_recv ( struct smbcli_transport * transport )
2003-08-13 05:53:07 +04:00
{
2004-07-23 10:40:49 +04:00
uint8_t * buffer , * hdr , * vwv ;
int len ;
2004-08-21 05:54:46 +04:00
uint16_t wct = 0 , mid = 0 ;
2004-08-04 17:23:35 +04:00
struct smbcli_request * req ;
2003-08-13 05:53:07 +04:00
2004-07-23 10:40:49 +04:00
buffer = transport - > recv_buffer . buffer ;
len = transport - > recv_buffer . req_size ;
2003-08-13 05:53:07 +04:00
2004-08-03 10:52:06 +04:00
ZERO_STRUCT ( transport - > recv_buffer ) ;
2004-07-23 10:40:49 +04:00
hdr = buffer + NBT_HDR_SIZE ;
vwv = hdr + HDR_VWV ;
/* see if it could be an oplock break request */
if ( handle_oplock_break ( transport , len , hdr , vwv ) ) {
2004-08-21 05:54:46 +04:00
talloc_free ( buffer ) ;
2004-07-23 10:40:49 +04:00
return ;
2003-08-13 05:53:07 +04:00
}
2004-07-23 10:40:49 +04:00
/* at this point we need to check for a readbraw reply, as
these can be any length */
if ( transport - > readbraw_pending ) {
transport - > readbraw_pending = 0 ;
/* it must match the first entry in the pending queue
as the client is not allowed to have outstanding
readbraw requests */
req = transport - > pending_recv ;
if ( ! req ) goto error ;
req - > in . buffer = buffer ;
2004-08-21 06:07:12 +04:00
talloc_steal ( req , buffer ) ;
2004-07-29 13:30:54 +04:00
req - > in . size = len ;
2004-07-23 10:40:49 +04:00
req - > in . allocated = req - > in . size ;
goto async ;
}
2003-08-13 05:53:07 +04:00
2004-07-23 10:40:49 +04:00
if ( len > = MIN_SMB_SIZE ) {
/* extract the mid for matching to pending requests */
mid = SVAL ( hdr , HDR_MID ) ;
wct = CVAL ( hdr , HDR_WCT ) ;
}
/* match the incoming request against the list of pending requests */
for ( req = transport - > pending_recv ; req ; req = req - > next ) {
if ( req - > mid = = mid ) break ;
}
if ( ! req ) {
DEBUG ( 1 , ( " Discarding unmatched reply with mid %d \n " , mid ) ) ;
goto error ;
}
/* fill in the 'in' portion of the matching request */
req - > in . buffer = buffer ;
2004-08-21 06:07:12 +04:00
talloc_steal ( req , buffer ) ;
2004-07-29 13:30:54 +04:00
req - > in . size = len ;
2004-07-23 10:40:49 +04:00
req - > in . allocated = req - > in . size ;
2004-08-14 22:24:33 +04:00
/* handle NBT session replies */
2004-08-19 00:07:44 +04:00
if ( req - > in . size > = 4 & & req - > in . buffer [ 0 ] ! = 0 ) {
2004-08-14 22:24:33 +04:00
req - > status = NT_STATUS_OK ;
goto async ;
}
2004-07-23 10:40:49 +04:00
/* handle non-SMB replies */
if ( req - > in . size < NBT_HDR_SIZE + MIN_SMB_SIZE ) {
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_ERROR ;
2004-07-23 10:40:49 +04:00
goto error ;
}
if ( req - > in . size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV ( wct ) ) {
DEBUG ( 2 , ( " bad reply size for mid %d \n " , mid ) ) ;
req - > status = NT_STATUS_UNSUCCESSFUL ;
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_ERROR ;
2004-07-23 10:40:49 +04:00
goto error ;
}
req - > in . hdr = hdr ;
req - > in . vwv = vwv ;
req - > in . wct = wct ;
if ( req - > in . size > = NBT_HDR_SIZE + MIN_SMB_SIZE + VWV ( wct ) ) {
req - > in . data = req - > in . vwv + VWV ( wct ) + 2 ;
req - > in . data_size = SVAL ( req - > in . vwv , VWV ( wct ) ) ;
if ( req - > in . size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV ( wct ) + req - > in . data_size ) {
DEBUG ( 3 , ( " bad data size for mid %d \n " , mid ) ) ;
/* blergh - w2k3 gives a bogus data size values in some
openX replies */
req - > in . data_size = req - > in . size - ( NBT_HDR_SIZE + MIN_SMB_SIZE + VWV ( wct ) ) ;
2003-08-13 05:53:07 +04:00
}
2004-07-23 10:40:49 +04:00
}
req - > in . ptr = req - > in . data ;
req - > flags2 = SVAL ( req - > in . hdr , HDR_FLG2 ) ;
if ( ! ( req - > flags2 & FLAGS2_32_BIT_ERROR_CODES ) ) {
transport - > error . etype = ETYPE_DOS ;
transport - > error . e . dos . eclass = CVAL ( req - > in . hdr , HDR_RCLS ) ;
transport - > error . e . dos . ecode = SVAL ( req - > in . hdr , HDR_ERR ) ;
req - > status = dos_to_ntstatus ( transport - > error . e . dos . eclass ,
transport - > error . e . dos . ecode ) ;
} else {
transport - > error . etype = ETYPE_NT ;
transport - > error . e . nt_status = NT_STATUS ( IVAL ( req - > in . hdr , HDR_RCLS ) ) ;
req - > status = transport - > error . e . nt_status ;
}
2004-08-04 17:23:35 +04:00
if ( ! smbcli_request_check_sign_mac ( req ) ) {
2004-07-23 10:40:49 +04:00
transport - > error . etype = ETYPE_SOCKET ;
transport - > error . e . socket_error = SOCKET_READ_BAD_SIG ;
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_ERROR ;
2004-07-23 10:40:49 +04:00
goto error ;
} ;
async :
/* if this request has an async handler then call that to
notify that the reply has been received . This might destroy
the request so it must happen last */
DLIST_REMOVE ( transport - > pending_recv , req ) ;
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_DONE ;
2004-07-23 10:40:49 +04:00
if ( req - > async . fn ) {
req - > async . fn ( req ) ;
}
return ;
error :
if ( req ) {
DLIST_REMOVE ( transport - > pending_recv , req ) ;
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_ERROR ;
2004-07-23 10:40:49 +04:00
}
}
2003-08-13 05:53:07 +04:00
2004-07-23 10:40:49 +04:00
/*
process some pending receives
*/
2004-08-04 17:23:35 +04:00
static void smbcli_transport_process_recv ( struct smbcli_transport * transport )
2004-07-23 10:40:49 +04:00
{
/* a incoming packet goes through 2 stages - first we read the
4 byte header , which tells us how much more is coming . Then
we read the rest */
if ( transport - > recv_buffer . received < NBT_HDR_SIZE ) {
ssize_t ret ;
2004-08-04 17:23:35 +04:00
ret = smbcli_sock_read ( transport - > socket ,
2004-07-23 10:40:49 +04:00
transport - > recv_buffer . header +
transport - > recv_buffer . received ,
NBT_HDR_SIZE - transport - > recv_buffer . received ) ;
2004-08-11 03:06:59 +04:00
if ( ret = = 0 ) {
smbcli_transport_dead ( transport ) ;
return ;
}
2004-07-23 10:40:49 +04:00
if ( ret = = - 1 ) {
if ( errno = = EINTR | | errno = = EAGAIN ) {
return ;
}
2004-08-04 17:23:35 +04:00
smbcli_transport_dead ( transport ) ;
2004-07-23 10:40:49 +04:00
return ;
2003-08-13 05:53:07 +04:00
}
2004-07-23 10:40:49 +04:00
transport - > recv_buffer . received + = ret ;
if ( transport - > recv_buffer . received = = NBT_HDR_SIZE ) {
/* we've got a full header */
transport - > recv_buffer . req_size = smb_len ( transport - > recv_buffer . header ) + NBT_HDR_SIZE ;
2004-08-21 11:43:29 +04:00
transport - > recv_buffer . buffer = talloc ( transport ,
2004-07-23 10:40:49 +04:00
NBT_HDR_SIZE + transport - > recv_buffer . req_size ) ;
if ( transport - > recv_buffer . buffer = = NULL ) {
2004-08-04 17:23:35 +04:00
smbcli_transport_dead ( transport ) ;
2004-07-23 10:40:49 +04:00
return ;
}
memcpy ( transport - > recv_buffer . buffer , transport - > recv_buffer . header , NBT_HDR_SIZE ) ;
2003-08-13 05:53:07 +04:00
}
2004-07-23 10:40:49 +04:00
}
if ( transport - > recv_buffer . received < transport - > recv_buffer . req_size ) {
ssize_t ret ;
2004-08-04 17:23:35 +04:00
ret = smbcli_sock_read ( transport - > socket ,
2004-07-23 10:40:49 +04:00
transport - > recv_buffer . buffer +
transport - > recv_buffer . received ,
transport - > recv_buffer . req_size -
transport - > recv_buffer . received ) ;
if ( ret = = - 1 ) {
if ( errno = = EINTR | | errno = = EAGAIN ) {
return ;
}
2004-08-04 17:23:35 +04:00
smbcli_transport_dead ( transport ) ;
2004-07-23 10:40:49 +04:00
return ;
2003-08-13 05:53:07 +04:00
}
2004-07-23 10:40:49 +04:00
transport - > recv_buffer . received + = ret ;
}
if ( transport - > recv_buffer . received ! = 0 & &
transport - > recv_buffer . received = = transport - > recv_buffer . req_size ) {
2004-08-04 17:23:35 +04:00
smbcli_transport_finish_recv ( transport ) ;
2004-07-23 10:40:49 +04:00
}
}
2003-08-13 05:53:07 +04:00
2004-07-23 10:40:49 +04:00
/*
process some read / write requests that are pending
return False if the socket is dead
*/
2004-08-04 17:23:35 +04:00
BOOL smbcli_transport_process ( struct smbcli_transport * transport )
2004-07-23 10:40:49 +04:00
{
2004-08-04 17:23:35 +04:00
smbcli_transport_process_send ( transport ) ;
smbcli_transport_process_recv ( transport ) ;
2004-07-23 10:40:49 +04:00
if ( transport - > socket - > fd = = - 1 ) {
return False ;
}
2003-08-13 05:53:07 +04:00
return True ;
}
2004-04-07 11:18:37 +04:00
2004-07-23 10:40:49 +04:00
/*
put a request into the send queue
*/
2004-08-04 17:23:35 +04:00
void smbcli_transport_send ( struct smbcli_request * req )
2004-07-23 10:40:49 +04:00
{
2004-08-03 12:04:11 +04:00
/* check if the transport is dead */
if ( req - > transport - > socket - > fd = = - 1 ) {
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_ERROR ;
2004-08-03 12:04:11 +04:00
req - > status = NT_STATUS_NET_WRITE_FAULT ;
return ;
}
2004-07-23 10:40:49 +04:00
/* put it on the outgoing socket queue */
2004-08-04 17:23:35 +04:00
req - > state = SMBCLI_REQUEST_SEND ;
DLIST_ADD_END ( req - > transport - > pending_send , req , struct smbcli_request * ) ;
2004-07-23 10:40:49 +04:00
/* make sure we look for write events */
2004-08-04 17:23:35 +04:00
smbcli_transport_write_enable ( req - > transport ) ;
2004-07-23 10:40:49 +04:00
}