smb_trantcp.c (76618) | smb_trantcp.c (87192) |
---|---|
1/* 2 * Copyright (c) 2000-2001 Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * | 1/* 2 * Copyright (c) 2000-2001 Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * |
32 * $FreeBSD: head/sys/netsmb/smb_trantcp.c 76618 2001-05-15 10:19:57Z tanimura $ | 32 * $FreeBSD: head/sys/netsmb/smb_trantcp.c 87192 2001-12-02 08:47:29Z bp $ |
33 */ 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/malloc.h> 38#include <sys/mbuf.h> 39#include <sys/proc.h> 40#include <sys/protosw.h> --- 24 unchanged lines hidden (view full) --- 65 66static int smb_tcpsndbuf = 10 * 1024; 67static int smb_tcprcvbuf = 10 * 1024; 68 69SYSCTL_DECL(_net_smb); 70SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &smb_tcpsndbuf, 0, ""); 71SYSCTL_INT(_net_smb, OID_AUTO, tcprcvbuf, CTLFLAG_RW, &smb_tcprcvbuf, 0, ""); 72 | 33 */ 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/malloc.h> 38#include <sys/mbuf.h> 39#include <sys/proc.h> 40#include <sys/protosw.h> --- 24 unchanged lines hidden (view full) --- 65 66static int smb_tcpsndbuf = 10 * 1024; 67static int smb_tcprcvbuf = 10 * 1024; 68 69SYSCTL_DECL(_net_smb); 70SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &smb_tcpsndbuf, 0, ""); 71SYSCTL_INT(_net_smb, OID_AUTO, tcprcvbuf, CTLFLAG_RW, &smb_tcprcvbuf, 0, ""); 72 |
73#define nb_sosend(so,m,flags,p) (so)->so_proto->pr_usrreqs->pru_sosend( \ 74 so, NULL, 0, m, 0, flags, p) | 73#define nb_sosend(so,m,flags,td) (so)->so_proto->pr_usrreqs->pru_sosend( \ 74 so, NULL, 0, m, 0, flags, td) |
75 76static int nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp, | 75 76static int nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp, |
77 u_int8_t *rpcodep, struct proc *p); 78static int smb_nbst_disconnect(struct smb_vc *vcp, struct proc *p); | 77 u_int8_t *rpcodep, struct thread *td); 78static int smb_nbst_disconnect(struct smb_vc *vcp, struct thread *td); |
79 80static int 81nb_setsockopt_int(struct socket *so, int level, int name, int val) 82{ 83 struct sockopt sopt; 84 85 bzero(&sopt, sizeof(sopt)); 86 sopt.sopt_level = level; 87 sopt.sopt_name = name; 88 sopt.sopt_val = &val; 89 sopt.sopt_valsize = sizeof(val); 90 return sosetopt(so, &sopt); 91} 92 93static __inline int | 79 80static int 81nb_setsockopt_int(struct socket *so, int level, int name, int val) 82{ 83 struct sockopt sopt; 84 85 bzero(&sopt, sizeof(sopt)); 86 sopt.sopt_level = level; 87 sopt.sopt_name = name; 88 sopt.sopt_val = &val; 89 sopt.sopt_valsize = sizeof(val); 90 return sosetopt(so, &sopt); 91} 92 93static __inline int |
94nb_poll(struct nbpcb *nbp, int events, struct proc *p) | 94nb_poll(struct nbpcb *nbp, int events, struct thread *td) |
95{ 96 return nbp->nbp_tso->so_proto->pr_usrreqs->pru_sopoll(nbp->nbp_tso, | 95{ 96 return nbp->nbp_tso->so_proto->pr_usrreqs->pru_sopoll(nbp->nbp_tso, |
97 events, NULL, p); | 97 events, NULL, td); |
98} 99 100static int | 98} 99 100static int |
101nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, struct proc *p) | 101nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, 102 struct thread *td) |
102{ 103 struct timeval atv, rtv, ttv; | 103{ 104 struct timeval atv, rtv, ttv; |
105 struct proc *p; |
|
104 int timo, error; 105 106 if (tv) { 107 atv = *tv; 108 if (itimerfix(&atv)) { 109 error = EINVAL; 110 goto done_noproclock; 111 } 112 getmicrouptime(&rtv); 113 timevaladd(&atv, &rtv); 114 } 115 timo = 0; | 106 int timo, error; 107 108 if (tv) { 109 atv = *tv; 110 if (itimerfix(&atv)) { 111 error = EINVAL; 112 goto done_noproclock; 113 } 114 getmicrouptime(&rtv); 115 timevaladd(&atv, &rtv); 116 } 117 timo = 0; |
118 p = td->td_proc; |
|
116 PROC_LOCK(p); | 119 PROC_LOCK(p); |
117 p->p_flag |= P_SELECT; | 120 mtx_lock_spin(&sched_lock); 121 td->td_flags |= TDF_SELECT; 122 mtx_unlock_spin(&sched_lock); |
118 PROC_UNLOCK(p); | 123 PROC_UNLOCK(p); |
119 error = nb_poll(nbp, events, p); | 124 error = nb_poll(nbp, events, td); |
120 PROC_LOCK(p); 121 if (error) { 122 error = 0; 123 goto done; 124 } 125 if (tv) { 126 getmicrouptime(&rtv); 127 if (timevalcmp(&rtv, &atv, >=)) { 128 /* 129 * An event of our interest may occur during locking a process. 130 * In order to avoid missing the event that occured during locking 131 * the process, test P_SELECT and rescan file descriptors if 132 * necessary. 133 */ | 125 PROC_LOCK(p); 126 if (error) { 127 error = 0; 128 goto done; 129 } 130 if (tv) { 131 getmicrouptime(&rtv); 132 if (timevalcmp(&rtv, &atv, >=)) { 133 /* 134 * An event of our interest may occur during locking a process. 135 * In order to avoid missing the event that occured during locking 136 * the process, test P_SELECT and rescan file descriptors if 137 * necessary. 138 */ |
134 if ((p->p_flag & P_SELECT) == 0) { 135 p->p_flag |= P_SELECT; | 139 mtx_lock_spin(&sched_lock); 140 if ((td->td_flags & TDF_SELECT) == 0) { 141 td->td_flags |= TDF_SELECT; 142 mtx_unlock_spin(&sched_lock); |
136 PROC_UNLOCK(p); | 143 PROC_UNLOCK(p); |
137 error = nb_poll(nbp, events, p); | 144 error = nb_poll(nbp, events, td); |
138 PROC_LOCK(p); | 145 PROC_LOCK(p); |
139 } | 146 } else 147 mtx_unlock_spin(&sched_lock); |
140 goto done; 141 } 142 ttv = atv; 143 timevalsub(&ttv, &rtv); 144 timo = tvtohz(&ttv); 145 } | 148 goto done; 149 } 150 ttv = atv; 151 timevalsub(&ttv, &rtv); 152 timo = tvtohz(&ttv); 153 } |
146 p->p_flag &= ~P_SELECT; | 154 mtx_lock_spin(&sched_lock); 155 td->td_flags &= ~TDF_SELECT; 156 mtx_unlock_spin(&sched_lock); |
147 if (timo > 0) 148 error = cv_timedwait(&selwait, &p->p_mtx, timo); 149 else { 150 cv_wait(&selwait, &p->p_mtx); 151 error = 0; 152 } 153 154done: | 157 if (timo > 0) 158 error = cv_timedwait(&selwait, &p->p_mtx, timo); 159 else { 160 cv_wait(&selwait, &p->p_mtx); 161 error = 0; 162 } 163 164done: |
165 mtx_lock_spin(&sched_lock); 166 td->td_flags &= ~TDF_SELECT; 167 mtx_unlock_spin(&sched_lock); |
|
155 PROC_UNLOCK(p); | 168 PROC_UNLOCK(p); |
156 p->p_flag &= ~P_SELECT; | 169 |
157done_noproclock: 158 if (error == ERESTART) 159 return 0; 160 return error; 161} 162 163static int 164nb_intr(struct nbpcb *nbp, struct proc *p) --- 38 unchanged lines hidden (view full) --- 203 if (seglen == 1) 204 break; 205 cp += seglen; 206 } 207 return 0; 208} 209 210static int | 170done_noproclock: 171 if (error == ERESTART) 172 return 0; 173 return error; 174} 175 176static int 177nb_intr(struct nbpcb *nbp, struct proc *p) --- 38 unchanged lines hidden (view full) --- 216 if (seglen == 1) 217 break; 218 cp += seglen; 219 } 220 return 0; 221} 222 223static int |
211nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct proc *p) | 224nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td) |
212{ 213 struct socket *so; 214 int error, s; 215 | 225{ 226 struct socket *so; 227 int error, s; 228 |
216 error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP, p); | 229 error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP, td); |
217 if (error) 218 return error; 219 nbp->nbp_tso = so; 220 so->so_upcallarg = (caddr_t)nbp; 221 so->so_upcall = nb_upcall; 222 so->so_rcv.sb_flags |= SB_UPCALL; 223 so->so_rcv.sb_timeo = (5 * hz); 224 so->so_snd.sb_timeo = (5 * hz); 225 error = soreserve(so, nbp->nbp_sndbuf, nbp->nbp_rcvbuf); 226 if (error) 227 goto bad; 228 nb_setsockopt_int(so, SOL_SOCKET, SO_KEEPALIVE, 1); 229 nb_setsockopt_int(so, IPPROTO_TCP, TCP_NODELAY, 1); 230 so->so_rcv.sb_flags &= ~SB_NOINTR; 231 so->so_snd.sb_flags &= ~SB_NOINTR; | 230 if (error) 231 return error; 232 nbp->nbp_tso = so; 233 so->so_upcallarg = (caddr_t)nbp; 234 so->so_upcall = nb_upcall; 235 so->so_rcv.sb_flags |= SB_UPCALL; 236 so->so_rcv.sb_timeo = (5 * hz); 237 so->so_snd.sb_timeo = (5 * hz); 238 error = soreserve(so, nbp->nbp_sndbuf, nbp->nbp_rcvbuf); 239 if (error) 240 goto bad; 241 nb_setsockopt_int(so, SOL_SOCKET, SO_KEEPALIVE, 1); 242 nb_setsockopt_int(so, IPPROTO_TCP, TCP_NODELAY, 1); 243 so->so_rcv.sb_flags &= ~SB_NOINTR; 244 so->so_snd.sb_flags &= ~SB_NOINTR; |
232 error = soconnect(so, (struct sockaddr*)to, p); | 245 error = soconnect(so, (struct sockaddr*)to, td); |
233 if (error) 234 goto bad; 235 s = splnet(); 236 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 237 tsleep(&so->so_timeo, PSOCK, "nbcon", 2 * hz); 238 if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0 && | 246 if (error) 247 goto bad; 248 s = splnet(); 249 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 250 tsleep(&so->so_timeo, PSOCK, "nbcon", 2 * hz); 251 if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0 && |
239 (error = nb_intr(nbp, p)) != 0) { | 252 (error = nb_intr(nbp, td->td_proc)) != 0) { |
240 so->so_state &= ~SS_ISCONNECTING; 241 splx(s); 242 goto bad; 243 } 244 } 245 if (so->so_error) { 246 error = so->so_error; 247 so->so_error = 0; 248 splx(s); 249 goto bad; 250 } 251 splx(s); 252 return 0; 253bad: | 253 so->so_state &= ~SS_ISCONNECTING; 254 splx(s); 255 goto bad; 256 } 257 } 258 if (so->so_error) { 259 error = so->so_error; 260 so->so_error = 0; 261 splx(s); 262 goto bad; 263 } 264 splx(s); 265 return 0; 266bad: |
254 smb_nbst_disconnect(nbp->nbp_vc, p); | 267 smb_nbst_disconnect(nbp->nbp_vc, td); |
255 return error; 256} 257 258static int | 268 return error; 269} 270 271static int |
259nbssn_rq_request(struct nbpcb *nbp, struct proc *p) | 272nbssn_rq_request(struct nbpcb *nbp, struct thread *td) |
260{ 261 struct mbchain mb, *mbp = &mb; 262 struct mdchain md, *mdp = &md; 263 struct mbuf *m0; 264 struct timeval tv; 265 struct sockaddr_in sin; 266 u_short port; 267 u_int8_t rpcode; 268 int error, rplen; 269 270 error = mb_init(mbp); 271 if (error) 272 return error; 273 mb_put_uint32le(mbp, 0); 274 nb_put_name(mbp, nbp->nbp_paddr); 275 nb_put_name(mbp, nbp->nbp_laddr); 276 nb_sethdr(mbp->mb_top, NB_SSN_REQUEST, mb_fixhdr(mbp) - 4); | 273{ 274 struct mbchain mb, *mbp = &mb; 275 struct mdchain md, *mdp = &md; 276 struct mbuf *m0; 277 struct timeval tv; 278 struct sockaddr_in sin; 279 u_short port; 280 u_int8_t rpcode; 281 int error, rplen; 282 283 error = mb_init(mbp); 284 if (error) 285 return error; 286 mb_put_uint32le(mbp, 0); 287 nb_put_name(mbp, nbp->nbp_paddr); 288 nb_put_name(mbp, nbp->nbp_laddr); 289 nb_sethdr(mbp->mb_top, NB_SSN_REQUEST, mb_fixhdr(mbp) - 4); |
277 error = nb_sosend(nbp->nbp_tso, mbp->mb_top, 0, p); | 290 error = nb_sosend(nbp->nbp_tso, mbp->mb_top, 0, td); |
278 if (!error) { 279 nbp->nbp_state = NBST_RQSENT; 280 } 281 mb_detach(mbp); 282 mb_done(mbp); 283 if (error) 284 return error; 285 TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo); | 291 if (!error) { 292 nbp->nbp_state = NBST_RQSENT; 293 } 294 mb_detach(mbp); 295 mb_done(mbp); 296 if (error) 297 return error; 298 TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo); |
286 error = nbssn_rselect(nbp, &tv, POLLIN, p); | 299 error = nbssn_rselect(nbp, &tv, POLLIN, td); |
287 if (error == EWOULDBLOCK) { /* Timeout */ 288 NBDEBUG("initial request timeout\n"); 289 return ETIMEDOUT; 290 } 291 if (error) /* restart or interrupt */ 292 return error; | 300 if (error == EWOULDBLOCK) { /* Timeout */ 301 NBDEBUG("initial request timeout\n"); 302 return ETIMEDOUT; 303 } 304 if (error) /* restart or interrupt */ 305 return error; |
293 error = nbssn_recv(nbp, &m0, &rplen, &rpcode, p); | 306 error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td); |
294 if (error) { 295 NBDEBUG("recv() error %d\n", error); 296 return error; 297 } 298 /* 299 * Process NETBIOS reply 300 */ 301 if (m0) --- 12 unchanged lines hidden (view full) --- 314 if (rplen != 6) { 315 error = ECONNABORTED; 316 break; 317 } 318 md_get_mem(mdp, (caddr_t)&sin.sin_addr, 4, MB_MSYSTEM); 319 md_get_uint16(mdp, &port); 320 sin.sin_port = port; 321 nbp->nbp_state = NBST_RETARGET; | 307 if (error) { 308 NBDEBUG("recv() error %d\n", error); 309 return error; 310 } 311 /* 312 * Process NETBIOS reply 313 */ 314 if (m0) --- 12 unchanged lines hidden (view full) --- 327 if (rplen != 6) { 328 error = ECONNABORTED; 329 break; 330 } 331 md_get_mem(mdp, (caddr_t)&sin.sin_addr, 4, MB_MSYSTEM); 332 md_get_uint16(mdp, &port); 333 sin.sin_port = port; 334 nbp->nbp_state = NBST_RETARGET; |
322 smb_nbst_disconnect(nbp->nbp_vc, p); 323 error = nb_connect_in(nbp, &sin, p); | 335 smb_nbst_disconnect(nbp->nbp_vc, td); 336 error = nb_connect_in(nbp, &sin, td); |
324 if (!error) | 337 if (!error) |
325 error = nbssn_rq_request(nbp, p); | 338 error = nbssn_rq_request(nbp, td); |
326 if (error) { | 339 if (error) { |
327 smb_nbst_disconnect(nbp->nbp_vc, p); | 340 smb_nbst_disconnect(nbp->nbp_vc, td); |
328 break; 329 } 330 } while(0); 331 if (m0) 332 md_done(mdp); 333 return error; 334} 335 336static int 337nbssn_recvhdr(struct nbpcb *nbp, int *lenp, | 341 break; 342 } 343 } while(0); 344 if (m0) 345 md_done(mdp); 346 return error; 347} 348 349static int 350nbssn_recvhdr(struct nbpcb *nbp, int *lenp, |
338 u_int8_t *rpcodep, int flags, struct proc *p) | 351 u_int8_t *rpcodep, int flags, struct thread *td) |
339{ 340 struct socket *so = nbp->nbp_tso; 341 struct uio auio; 342 struct iovec aio; 343 u_int32_t len; 344 int error; 345 346 aio.iov_base = (caddr_t)&len; 347 aio.iov_len = sizeof(len); 348 auio.uio_iov = &aio; 349 auio.uio_iovcnt = 1; 350 auio.uio_segflg = UIO_SYSSPACE; 351 auio.uio_rw = UIO_READ; 352 auio.uio_offset = 0; 353 auio.uio_resid = sizeof(len); | 352{ 353 struct socket *so = nbp->nbp_tso; 354 struct uio auio; 355 struct iovec aio; 356 u_int32_t len; 357 int error; 358 359 aio.iov_base = (caddr_t)&len; 360 aio.iov_len = sizeof(len); 361 auio.uio_iov = &aio; 362 auio.uio_iovcnt = 1; 363 auio.uio_segflg = UIO_SYSSPACE; 364 auio.uio_rw = UIO_READ; 365 auio.uio_offset = 0; 366 auio.uio_resid = sizeof(len); |
354 auio.uio_procp = p; | 367 auio.uio_td = td; |
355 error = so->so_proto->pr_usrreqs->pru_soreceive 356 (so, (struct sockaddr **)NULL, &auio, 357 (struct mbuf **)NULL, (struct mbuf **)NULL, &flags); 358 if (error) 359 return error; 360 if (auio.uio_resid > 0) { 361 SMBSDEBUG("short reply\n"); 362 return EPIPE; --- 6 unchanged lines hidden (view full) --- 369 return EFBIG; 370 } 371 *lenp = len; 372 return 0; 373} 374 375static int 376nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp, | 368 error = so->so_proto->pr_usrreqs->pru_soreceive 369 (so, (struct sockaddr **)NULL, &auio, 370 (struct mbuf **)NULL, (struct mbuf **)NULL, &flags); 371 if (error) 372 return error; 373 if (auio.uio_resid > 0) { 374 SMBSDEBUG("short reply\n"); 375 return EPIPE; --- 6 unchanged lines hidden (view full) --- 382 return EFBIG; 383 } 384 *lenp = len; 385 return 0; 386} 387 388static int 389nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp, |
377 u_int8_t *rpcodep, struct proc *p) | 390 u_int8_t *rpcodep, struct thread *td) |
378{ 379 struct socket *so = nbp->nbp_tso; 380 struct uio auio; 381 struct mbuf *m; 382 u_int8_t rpcode; 383 int len; 384 int error, rcvflg; 385 386 if (so == NULL) 387 return ENOTCONN; 388 389 if (mpp) 390 *mpp = NULL; 391 for(;;) { 392 m = NULL; | 391{ 392 struct socket *so = nbp->nbp_tso; 393 struct uio auio; 394 struct mbuf *m; 395 u_int8_t rpcode; 396 int len; 397 int error, rcvflg; 398 399 if (so == NULL) 400 return ENOTCONN; 401 402 if (mpp) 403 *mpp = NULL; 404 for(;;) { 405 m = NULL; |
393 error = nbssn_recvhdr(nbp, &len, &rpcode, MSG_DONTWAIT, p); | 406 error = nbssn_recvhdr(nbp, &len, &rpcode, MSG_DONTWAIT, td); |
394 if (so->so_state & 395 (SS_ISDISCONNECTING | SS_ISDISCONNECTED | SS_CANTRCVMORE)) { 396 nbp->nbp_state = NBST_CLOSED; 397 NBDEBUG("session closed by peer\n"); 398 return ECONNRESET; 399 } 400 if (error) 401 return error; 402 if (len == 0 && nbp->nbp_state != NBST_SESSION) 403 break; 404 if (rpcode == NB_SSN_KEEPALIVE) 405 continue; 406 bzero(&auio, sizeof(auio)); 407 auio.uio_resid = len; | 407 if (so->so_state & 408 (SS_ISDISCONNECTING | SS_ISDISCONNECTED | SS_CANTRCVMORE)) { 409 nbp->nbp_state = NBST_CLOSED; 410 NBDEBUG("session closed by peer\n"); 411 return ECONNRESET; 412 } 413 if (error) 414 return error; 415 if (len == 0 && nbp->nbp_state != NBST_SESSION) 416 break; 417 if (rpcode == NB_SSN_KEEPALIVE) 418 continue; 419 bzero(&auio, sizeof(auio)); 420 auio.uio_resid = len; |
408 auio.uio_procp = p; | 421 auio.uio_td = td; |
409 do { 410 rcvflg = MSG_WAITALL; 411 error = so->so_proto->pr_usrreqs->pru_soreceive 412 (so, (struct sockaddr **)NULL, 413 &auio, &m, (struct mbuf **)NULL, &rcvflg); 414 } while (error == EWOULDBLOCK || error == EINTR || 415 error == ERESTART); 416 if (error) --- 23 unchanged lines hidden (view full) --- 440 *rpcodep = rpcode; 441 return 0; 442} 443 444/* 445 * SMB transport interface 446 */ 447static int | 422 do { 423 rcvflg = MSG_WAITALL; 424 error = so->so_proto->pr_usrreqs->pru_soreceive 425 (so, (struct sockaddr **)NULL, 426 &auio, &m, (struct mbuf **)NULL, &rcvflg); 427 } while (error == EWOULDBLOCK || error == EINTR || 428 error == ERESTART); 429 if (error) --- 23 unchanged lines hidden (view full) --- 453 *rpcodep = rpcode; 454 return 0; 455} 456 457/* 458 * SMB transport interface 459 */ 460static int |
448smb_nbst_create(struct smb_vc *vcp, struct proc *p) | 461smb_nbst_create(struct smb_vc *vcp, struct thread *td) |
449{ 450 struct nbpcb *nbp; 451 452 MALLOC(nbp, struct nbpcb *, sizeof *nbp, M_NBDATA, M_WAITOK); 453 bzero(nbp, sizeof *nbp); 454 nbp->nbp_timo.tv_sec = 15; /* XXX: sysctl ? */ 455 nbp->nbp_state = NBST_CLOSED; 456 nbp->nbp_vc = vcp; 457 nbp->nbp_sndbuf = smb_tcpsndbuf; 458 nbp->nbp_rcvbuf = smb_tcprcvbuf; 459 vcp->vc_tdata = nbp; 460 return 0; 461} 462 463static int | 462{ 463 struct nbpcb *nbp; 464 465 MALLOC(nbp, struct nbpcb *, sizeof *nbp, M_NBDATA, M_WAITOK); 466 bzero(nbp, sizeof *nbp); 467 nbp->nbp_timo.tv_sec = 15; /* XXX: sysctl ? */ 468 nbp->nbp_state = NBST_CLOSED; 469 nbp->nbp_vc = vcp; 470 nbp->nbp_sndbuf = smb_tcpsndbuf; 471 nbp->nbp_rcvbuf = smb_tcprcvbuf; 472 vcp->vc_tdata = nbp; 473 return 0; 474} 475 476static int |
464smb_nbst_done(struct smb_vc *vcp, struct proc *p) | 477smb_nbst_done(struct smb_vc *vcp, struct thread *td) |
465{ 466 struct nbpcb *nbp = vcp->vc_tdata; 467 468 if (nbp == NULL) 469 return ENOTCONN; | 478{ 479 struct nbpcb *nbp = vcp->vc_tdata; 480 481 if (nbp == NULL) 482 return ENOTCONN; |
470 smb_nbst_disconnect(vcp, p); | 483 smb_nbst_disconnect(vcp, td); |
471 if (nbp->nbp_laddr) 472 free(nbp->nbp_laddr, M_SONAME); 473 if (nbp->nbp_paddr) 474 free(nbp->nbp_paddr, M_SONAME); 475 free(nbp, M_NBDATA); 476 return 0; 477} 478 479static int | 484 if (nbp->nbp_laddr) 485 free(nbp->nbp_laddr, M_SONAME); 486 if (nbp->nbp_paddr) 487 free(nbp->nbp_paddr, M_SONAME); 488 free(nbp, M_NBDATA); 489 return 0; 490} 491 492static int |
480smb_nbst_bind(struct smb_vc *vcp, struct sockaddr *sap, struct proc *p) | 493smb_nbst_bind(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td) |
481{ 482 struct nbpcb *nbp = vcp->vc_tdata; 483 struct sockaddr_nb *snb; 484 int error, slen; 485 486 NBDEBUG("\n"); 487 error = EINVAL; 488 do { --- 16 unchanged lines hidden (view full) --- 505 nbp->nbp_laddr = snb; 506 nbp->nbp_flags |= NBF_LOCADDR; 507 error = 0; 508 } while(0); 509 return error; 510} 511 512static int | 494{ 495 struct nbpcb *nbp = vcp->vc_tdata; 496 struct sockaddr_nb *snb; 497 int error, slen; 498 499 NBDEBUG("\n"); 500 error = EINVAL; 501 do { --- 16 unchanged lines hidden (view full) --- 518 nbp->nbp_laddr = snb; 519 nbp->nbp_flags |= NBF_LOCADDR; 520 error = 0; 521 } while(0); 522 return error; 523} 524 525static int |
513smb_nbst_connect(struct smb_vc *vcp, struct sockaddr *sap, struct proc *p) | 526smb_nbst_connect(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td) |
514{ 515 struct nbpcb *nbp = vcp->vc_tdata; 516 struct sockaddr_in sin; 517 struct sockaddr_nb *snb; 518 struct timespec ts1, ts2; 519 int error, slen; 520 521 NBDEBUG("\n"); --- 9 unchanged lines hidden (view full) --- 531 nbp->nbp_paddr = NULL; 532 } 533 snb = (struct sockaddr_nb*)dup_sockaddr(sap, 1); 534 if (snb == NULL) 535 return ENOMEM; 536 nbp->nbp_paddr = snb; 537 sin = snb->snb_addrin; 538 getnanotime(&ts1); | 527{ 528 struct nbpcb *nbp = vcp->vc_tdata; 529 struct sockaddr_in sin; 530 struct sockaddr_nb *snb; 531 struct timespec ts1, ts2; 532 int error, slen; 533 534 NBDEBUG("\n"); --- 9 unchanged lines hidden (view full) --- 544 nbp->nbp_paddr = NULL; 545 } 546 snb = (struct sockaddr_nb*)dup_sockaddr(sap, 1); 547 if (snb == NULL) 548 return ENOMEM; 549 nbp->nbp_paddr = snb; 550 sin = snb->snb_addrin; 551 getnanotime(&ts1); |
539 error = nb_connect_in(nbp, &sin, p); | 552 error = nb_connect_in(nbp, &sin, td); |
540 if (error) 541 return error; 542 getnanotime(&ts2); 543 timespecsub(&ts2, &ts1); 544 if (ts2.tv_sec == 0 && ts2.tv_sec == 0) 545 ts2.tv_sec = 1; 546 nbp->nbp_timo = ts2; 547 timespecadd(&nbp->nbp_timo, &ts2); 548 timespecadd(&nbp->nbp_timo, &ts2); 549 timespecadd(&nbp->nbp_timo, &ts2); /* * 4 */ | 553 if (error) 554 return error; 555 getnanotime(&ts2); 556 timespecsub(&ts2, &ts1); 557 if (ts2.tv_sec == 0 && ts2.tv_sec == 0) 558 ts2.tv_sec = 1; 559 nbp->nbp_timo = ts2; 560 timespecadd(&nbp->nbp_timo, &ts2); 561 timespecadd(&nbp->nbp_timo, &ts2); 562 timespecadd(&nbp->nbp_timo, &ts2); /* * 4 */ |
550 error = nbssn_rq_request(nbp, p); | 563 error = nbssn_rq_request(nbp, td); |
551 if (error) | 564 if (error) |
552 smb_nbst_disconnect(vcp, p); | 565 smb_nbst_disconnect(vcp, td); |
553 return error; 554} 555 556static int | 566 return error; 567} 568 569static int |
557smb_nbst_disconnect(struct smb_vc *vcp, struct proc *p) | 570smb_nbst_disconnect(struct smb_vc *vcp, struct thread *td) |
558{ 559 struct nbpcb *nbp = vcp->vc_tdata; 560 struct socket *so; 561 562 if (nbp == NULL || nbp->nbp_tso == NULL) 563 return ENOTCONN; 564 if ((so = nbp->nbp_tso) != NULL) { 565 nbp->nbp_flags &= ~NBF_CONNECTED; 566 nbp->nbp_tso = (struct socket *)NULL; 567 soshutdown(so, 2); 568 soclose(so); 569 } 570 if (nbp->nbp_state != NBST_RETARGET) { 571 nbp->nbp_state = NBST_CLOSED; 572 } 573 return 0; 574} 575 576static int | 571{ 572 struct nbpcb *nbp = vcp->vc_tdata; 573 struct socket *so; 574 575 if (nbp == NULL || nbp->nbp_tso == NULL) 576 return ENOTCONN; 577 if ((so = nbp->nbp_tso) != NULL) { 578 nbp->nbp_flags &= ~NBF_CONNECTED; 579 nbp->nbp_tso = (struct socket *)NULL; 580 soshutdown(so, 2); 581 soclose(so); 582 } 583 if (nbp->nbp_state != NBST_RETARGET) { 584 nbp->nbp_state = NBST_CLOSED; 585 } 586 return 0; 587} 588 589static int |
577smb_nbst_send(struct smb_vc *vcp, struct mbuf *m0, struct proc *p) | 590smb_nbst_send(struct smb_vc *vcp, struct mbuf *m0, struct thread *td) |
578{ 579 struct nbpcb *nbp = vcp->vc_tdata; 580 int error; 581 582 if (nbp->nbp_state != NBST_SESSION) { 583 error = ENOTCONN; 584 goto abort; 585 } 586 M_PREPEND(m0, 4, M_WAITOK); 587 if (m0 == NULL) 588 return ENOBUFS; 589 nb_sethdr(m0, NB_SSN_MESSAGE, m_fixhdr(m0) - 4); | 591{ 592 struct nbpcb *nbp = vcp->vc_tdata; 593 int error; 594 595 if (nbp->nbp_state != NBST_SESSION) { 596 error = ENOTCONN; 597 goto abort; 598 } 599 M_PREPEND(m0, 4, M_WAITOK); 600 if (m0 == NULL) 601 return ENOBUFS; 602 nb_sethdr(m0, NB_SSN_MESSAGE, m_fixhdr(m0) - 4); |
590 error = nb_sosend(nbp->nbp_tso, m0, 0, p); | 603 error = nb_sosend(nbp->nbp_tso, m0, 0, td); |
591 return error; 592abort: 593 if (m0) 594 m_freem(m0); 595 return error; 596} 597 598 599static int | 604 return error; 605abort: 606 if (m0) 607 m_freem(m0); 608 return error; 609} 610 611 612static int |
600smb_nbst_recv(struct smb_vc *vcp, struct mbuf **mpp, struct proc *p) | 613smb_nbst_recv(struct smb_vc *vcp, struct mbuf **mpp, struct thread *td) |
601{ 602 struct nbpcb *nbp = vcp->vc_tdata; 603 u_int8_t rpcode; 604 int error, rplen; 605 606 nbp->nbp_flags |= NBF_RECVLOCK; | 614{ 615 struct nbpcb *nbp = vcp->vc_tdata; 616 u_int8_t rpcode; 617 int error, rplen; 618 619 nbp->nbp_flags |= NBF_RECVLOCK; |
607 error = nbssn_recv(nbp, mpp, &rplen, &rpcode, p); | 620 error = nbssn_recv(nbp, mpp, &rplen, &rpcode, td); |
608 nbp->nbp_flags &= ~NBF_RECVLOCK; 609 return error; 610} 611 612static void 613smb_nbst_timo(struct smb_vc *vcp) 614{ 615 return; --- 75 unchanged lines hidden --- | 621 nbp->nbp_flags &= ~NBF_RECVLOCK; 622 return error; 623} 624 625static void 626smb_nbst_timo(struct smb_vc *vcp) 627{ 628 return; --- 75 unchanged lines hidden --- |