ReactOS  0.4.14-dev-323-g6fe6a88
svc_generic.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2009, Sun Microsystems, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * - Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * - Neither the name of Sun Microsystems, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * Copyright (c) 1986-1991 by Sun Microsystems Inc.
32  */
33 
34 /*
35  * svc_generic.c, Server side for RPC.
36  *
37  */
38 #include <wintirpc.h>
39 //#include <pthread.h>
40 #include <reentrant.h>
41 #include <sys/types.h>
42 //#include <sys/socket.h>
43 //#include <netinet/in.h>
44 #include <rpc/rpc.h>
45 #include <rpc/nettype.h>
46 #include <stdio.h>
47 #include <errno.h>
48 #include <stdlib.h>
49 #include <string.h>
50 //#include <unistd.h>
51 //#include <err.h>
52 
53 #include "rpc_com.h"
54 #include <rpc/svc.h>
55 
56 extern int __svc_vc_setflag(SVCXPRT *, int);
57 
58 /*
59  * The highest level interface for server creation.
60  * It tries for all the nettokens in that particular class of token
61  * and returns the number of handles it can create and/or find.
62  *
63  * It creates a link list of all the handles it could create.
64  * If svc_create() is called multiple times, it uses the handle
65  * created earlier instead of creating a new handle every time.
66  */
67 int
68 svc_create(dispatch, prognum, versnum, nettype)
69  void (*dispatch)(struct svc_req *, SVCXPRT *);
70  rpcprog_t prognum; /* Program number */
71  rpcvers_t versnum; /* Version number */
72  const char *nettype; /* Networktype token */
73 {
74  struct xlist {
75  SVCXPRT *xprt; /* Server handle */
76  struct xlist *next; /* Next item */
77  } *l;
78  static struct xlist *xprtlist; /* A link list of all the handles */
79  int num = 0;
80  SVCXPRT *xprt;
81  struct netconfig *nconf;
82  void *handle;
83  extern mutex_t xprtlist_lock;
84 
85 /* VARIABLES PROTECTED BY xprtlist_lock: xprtlist */
86 
87  if ((handle = __rpc_setconf(nettype)) == NULL) {
88  // XXX warnx("svc_create: unknown protocol");
89  return (0);
90  }
91  while ((nconf = __rpc_getconf(handle)) != NULL) {
93  for (l = xprtlist; l; l = l->next) {
94  if (strcmp(l->xprt->xp_netid, nconf->nc_netid) == 0) {
95  /* Found an old one, use it */
96  (void) rpcb_unset(prognum, versnum, nconf);
97  if (svc_reg(l->xprt, prognum, versnum,
98  dispatch, nconf) == FALSE) {
99  // XXX warnx(
100 // "svc_create: could not register prog %u vers %u on %s",
101 // (unsigned)prognum, (unsigned)versnum,
102 // nconf->nc_netid);
103  } else {
104  num++;
105  }
106  break;
107  }
108  }
109  if (l == NULL) {
110  /* It was not found. Now create a new one */
111  xprt = svc_tp_create(dispatch, prognum, versnum, nconf);
112  if (xprt) {
113  l = (struct xlist *)malloc(sizeof (*l));
114  if (l == NULL) {
115  // XXX warnx("svc_create: no memory");
117  return (0);
118  }
119  l->xprt = xprt;
120  l->next = xprtlist;
121  xprtlist = l;
122  num++;
123  }
124  }
126  }
128  /*
129  * In case of num == 0; the error messages are generated by the
130  * underlying layers; and hence not needed here.
131  */
132  return (num);
133 }
134 
135 /*
136  * The high level interface to svc_tli_create().
137  * It tries to create a server for "nconf" and registers the service
138  * with the rpcbind. It calls svc_tli_create();
139  */
140 SVCXPRT *
141 svc_tp_create(dispatch, prognum, versnum, nconf)
142  void (*dispatch)(struct svc_req *, SVCXPRT *);
143  rpcprog_t prognum; /* Program number */
144  rpcvers_t versnum; /* Version number */
145  const struct netconfig *nconf; /* Netconfig structure for the network */
146 {
147  SVCXPRT *xprt;
148 
149  if (nconf == NULL) {
150  // XXX warnx(
151 // "svc_tp_create: invalid netconfig structure for prog %u vers %u",
152 // (unsigned)prognum, (unsigned)versnum);
153  return (NULL);
154  }
155  xprt = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0);
156  if (xprt == NULL) {
157  return (NULL);
158  }
159  /*LINTED const castaway*/
160  (void) rpcb_unset(prognum, versnum, (struct netconfig *) nconf);
161  if (svc_reg(xprt, prognum, versnum, dispatch, nconf) == FALSE) {
162  // XXX warnx(
163 // "svc_tp_create: Could not register prog %u vers %u on %s",
164 // (unsigned)prognum, (unsigned)versnum,
165 // nconf->nc_netid);
166  SVC_DESTROY(xprt);
167  return (NULL);
168  }
169  return (xprt);
170 }
171 
172  /*
173  * If fd is RPC_ANYFD, then it opens a fd for the given transport
174  * provider (nconf cannot be NULL then). If the t_state is T_UNBND and
175  * bindaddr is NON-NULL, it performs a t_bind using the bindaddr. For
176  * NULL bindadr and Connection oriented transports, the value of qlen
177  * is set to 8.
178  *
179  * If sendsz or recvsz are zero, their default values are chosen.
180  */
181 SVCXPRT *
182 svc_tli_create(fd, nconf, bindaddr, sendsz, recvsz)
183  SOCKET fd; /* Connection end point */
184  const struct netconfig *nconf; /* Netconfig struct for nettoken */
185  const struct t_bind *bindaddr; /* Local bind address */
186  u_int sendsz; /* Max sendsize */
187  u_int recvsz; /* Max recvsize */
188 {
189  SVCXPRT *xprt = NULL; /* service handle */
190  bool_t madefd = FALSE; /* whether fd opened here */
191  struct __rpc_sockinfo si;
192  struct sockaddr_storage ss;
193  socklen_t slen;
194 
195  if (fd == RPC_ANYFD) {
196  if (nconf == NULL) {
197  // XXX warnx("svc_tli_create: invalid netconfig");
198  return (NULL);
199  }
200  fd = __rpc_nconf2fd(nconf);
201  if (fd == -1) {
202  // XXX warnx(
203 // "svc_tli_create: could not open connection for %s",
204 // nconf->nc_netid);
205  return (NULL);
206  }
207  __rpc_nconf2sockinfo(nconf, &si);
208  madefd = TRUE;
209  } else {
210  /*
211  * It is an open descriptor. Get the transport info.
212  */
213  if (!__rpc_fd2sockinfo(fd, &si)) {
214  // XXX warnx(
215 // "svc_tli_create: could not get transport information");
216  return (NULL);
217  }
218  }
219 
220  /*
221  * If the fd is unbound, try to bind it.
222  */
223  if (madefd || !__rpc_sockisbound(fd)) {
224  if (bindaddr == NULL) {
225  if (bindresvport(fd, NULL) < 0) {
226  memset(&ss, 0, sizeof ss);
227  ss.ss_family = si.si_af;
228  if (bind(fd, (struct sockaddr *)(void *)&ss,
229  (socklen_t)si.si_alen) == SOCKET_ERROR) {
230  // XXX warnx(
231 // "svc_tli_create: could not bind to anonymous port");
232  goto freedata;
233  }
234  }
235  listen(fd, SOMAXCONN);
236  } else {
237  if (bind(fd,
238  (struct sockaddr *)bindaddr->addr.buf,
239  (socklen_t)si.si_alen) == SOCKET_ERROR) {
240  // XXX warnx(
241 // "svc_tli_create: could not bind to requested address");
242  goto freedata;
243  }
244  listen(fd, (int)bindaddr->qlen);
245  }
246 
247  }
248  /*
249  * call transport specific function.
250  */
251  switch (si.si_socktype) {
252  case SOCK_STREAM:
253  slen = sizeof ss;
254  if (getpeername(fd, (struct sockaddr *)(void *)&ss, &slen)
255  == 0) {
256  /* accepted socket */
257  xprt = svc_fd_create(fd, sendsz, recvsz);
258  } else
259  xprt = svc_vc_create(fd, sendsz, recvsz);
260  if (!nconf || !xprt)
261  break;
262 #if 0
263  /* XXX fvdl */
264  if (strcmp(nconf->nc_protofmly, "inet") == 0 ||
265  strcmp(nconf->nc_protofmly, "inet6") == 0)
266  (void) __svc_vc_setflag(xprt, TRUE);
267 #endif
268  break;
269  case SOCK_DGRAM:
270  xprt = svc_dg_create(fd, sendsz, recvsz);
271  break;
272  default:
273  // XXX warnx("svc_tli_create: bad service type");
274  goto freedata;
275  }
276 
277  if (xprt == NULL)
278  /*
279  * The error messages here are spitted out by the lower layers:
280  * svc_vc_create(), svc_fd_create() and svc_dg_create().
281  */
282  goto freedata;
283 
284  /* Fill in type of service */
286 
287  if (nconf) {
288  xprt->xp_netid = strdup(nconf->nc_netid);
289  xprt->xp_tp = strdup(nconf->nc_device);
290  }
291  return (xprt);
292 
293 freedata:
294  if (madefd)
295  (void)closesocket(fd);
296  if (xprt) {
297  if (!madefd) /* so that svc_destroy doesnt close fd */
298  xprt->xp_fd = RPC_ANYFD;
299  SVC_DESTROY(xprt);
300  }
301  return (NULL);
302 }
#define SOCKET_ERROR
Definition: winsock.h:333
struct netbuf addr
Definition: types.h:156
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
u_int32_t rpcvers_t
Definition: types.h:105
ADDRESS_FAMILY si_af
Definition: types.h:165
#define closesocket
int32_t bool_t
Definition: types.h:101
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define RPC_ANYFD
Definition: svc.h:328
SVCXPRT * svc_tli_create(SOCKET fd, const struct netconfig *nconf, const struct t_bind *bindaddr, u_int sendsz, u_int recvsz)
Definition: svc_generic.c:182
SVCXPRT * svc_dg_create(int fd, u_int sendsize, u_int recvsize)
Definition: svc_dg.c:95
int __rpc_sockisbound(SOCKET)
Definition: rpc_generic.c:909
int __rpc_socktype2seman(int)
Definition: rpc_generic.c:859
static int fd
Definition: io.c:51
SVCXPRT * svc_tp_create(void *dispatch, rpcprog_t prognum, rpcvers_t versnum, const struct netconfig *nconf)
Definition: svc_generic.c:141
struct netconfig * __rpc_getconf(void *vhandle)
Definition: rpc_generic.c:348
#define mutex_lock(m)
Definition: reentrant.h:128
#define mutex_unlock(m)
Definition: reentrant.h:129
int __svc_vc_setflag(SVCXPRT *, int)
mutex_t xprtlist_lock
Definition: mt_misc.c:97
#define SOMAXCONN
Definition: winsock.h:399
int __rpc_fd2sockinfo(SOCKET fd, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:481
int si_socktype
Definition: types.h:167
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
char * nc_protofmly
Definition: netconfig.h:14
int bindresvport(SOCKET sd, struct sockaddr_in *sin)
Definition: bindresvport.c:53
char * xp_tp
Definition: svc.h:117
smooth NULL
Definition: ftsmooth.c:416
INT WSAAPI getpeername(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:167
r l[0]
Definition: byte_order.h:167
SOCKET xp_fd
Definition: svc.h:91
int si_alen
Definition: types.h:168
#define SVC_DESTROY(xprt)
Definition: svc.h:184
bool_t rpcb_unset(rpcprog_t program, rpcvers_t version, const struct netconfig *nconf)
Definition: rpcb_clnt.c:581
GLuint GLuint num
Definition: glext.h:9618
int socklen_t
Definition: tcp.c:35
u_int32_t rpcprog_t
Definition: types.h:104
char * nc_netid
Definition: netconfig.h:11
int xp_type
Definition: svc.h:126
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:66
char * nc_device
Definition: netconfig.h:16
SOCKET __rpc_nconf2fd(const struct netconfig *nconf)
Definition: rpc_generic.c:562
static unsigned __int64 next
Definition: rand_nt.c:6
void * __rpc_setconf(char *nettype) const
Definition: rpc_generic.c:305
UINT32 u_int
Definition: types.h:82
bool_t svc_reg(SVCXPRT *xprt, const rpcprog_t prog, const rpcvers_t vers, void *dispatch, const struct netconfig *nconf)
Definition: svc.c:178
Definition: svc.h:132
Definition: types.h:155
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define malloc
Definition: debug_ros.c:4
void __rpc_endconf(void *vhandle)
Definition: rpc_generic.c:425
int __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:540
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCK_STREAM
Definition: tcpip.h:118
#define ss
Definition: i386-dis.c:432
Definition: module.h:446
#define SOCK_DGRAM
Definition: winsock.h:336
SVCXPRT * svc_fd_create(SOCKET fd, u_int sendsize, u_int recvsize)
Definition: svc_vc.c:204
#define memset(x, y, z)
Definition: compat.h:39
char * xp_netid
Definition: svc.h:118
int svc_create(void *dispatch, rpcprog_t prognum, rpcvers_t versnum, const char *nettype)
Definition: svc_generic.c:68
SVCXPRT * svc_vc_create(int fd, u_int sendsize, u_int recvsize)
Definition: svc_vc.c:146
unsigned int qlen
Definition: types.h:157