int libcfs_sock_listen (struct socket **sockp, __u32 local_ip, int local_port, int backlog) { int fatal; int rc; CFS_DECL_FUNNEL_DATA; rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port); if (rc != 0) { if (!fatal) CERROR("Can't create socket: port %d already in use\n", local_port); return rc; } CFS_NET_IN; rc = solisten(*sockp, backlog); CFS_NET_EX; if (rc == 0) return 0; CERROR("Can't set listen backlog %d: %d\n", backlog, rc); CFS_NET_IN; soclose(*sockp); CFS_NET_EX; return -rc; }
/* * Usage: * xprt = svc_vc_create(sock, send_buf_size, recv_buf_size); * * Creates, registers, and returns a (rpc) tcp based transporter. * Once *xprt is initialized, it is registered as a transporter * see (svc.h, xprt_register). This routine returns * a NULL if a problem occurred. * * The filedescriptor passed in is expected to refer to a bound, but * not yet connected socket. * * Since streams do buffered io similar to stdio, the caller can specify * how big the send and receive buffers are via the second and third parms; * 0 => use the system default. */ SVCXPRT * svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, size_t recvsize) { SVCXPRT *xprt = NULL; struct sockaddr* sa; int error; SOCK_LOCK(so); if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) { SOCK_UNLOCK(so); CURVNET_SET(so->so_vnet); error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa); CURVNET_RESTORE(); if (error) return (NULL); xprt = svc_vc_create_conn(pool, so, sa); free(sa, M_SONAME); return (xprt); } SOCK_UNLOCK(so); xprt = svc_xprt_alloc(); sx_init(&xprt->xp_lock, "xprt->xp_lock"); xprt->xp_pool = pool; xprt->xp_socket = so; xprt->xp_p1 = NULL; xprt->xp_p2 = NULL; xprt->xp_ops = &svc_vc_rendezvous_ops; CURVNET_SET(so->so_vnet); error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) { goto cleanup_svc_vc_create; } memcpy(&xprt->xp_ltaddr, sa, sa->sa_len); free(sa, M_SONAME); xprt_register(xprt); solisten(so, -1, curthread); SOCKBUF_LOCK(&so->so_rcv); xprt->xp_upcallset = 1; soupcall_set(so, SO_RCV, svc_vc_soupcall, xprt); SOCKBUF_UNLOCK(&so->so_rcv); return (xprt); cleanup_svc_vc_create: if (xprt) { sx_destroy(&xprt->xp_lock); svc_xprt_free(xprt); } return (NULL); }
int slirp_redir(int is_udp, int host_port, struct in_addr guest_addr, int guest_port) { if (is_udp) { if (!udp_listen(htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) return -1; } else { if (!solisten(htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) return -1; } return 0; }
int slirp_redir(int is_udp, int host_port, uint32_t guest_ip, int guest_port) { if (is_udp) { if (!udp_listen(host_port, guest_ip, guest_port, 0)) return -1; } else { if (!solisten(host_port, guest_ip, guest_port, 0)) return -1; } return 0; }
struct socket* listenon(unsigned short port) { struct socket* so = NULL; socreate(AF_INET, &so, SOCK_STREAM, 0); struct sockaddr_in addr; bzero(&addr, sizeof addr); addr.sin_len = sizeof addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); struct mbuf* nam = m_devget((caddr_t)&addr, sizeof addr, 0, NULL, NULL); sobind(so, nam); solisten(so, 5); return so; }
int sys_listen(struct lwp *l, const struct sys_listen_args *uap, register_t *retval) { /* { syscallarg(int) s; syscallarg(int) backlog; } */ struct socket *so; int error; if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) return (error); error = solisten(so, SCARG(uap, backlog), l); fd_putfile(SCARG(uap, s)); return error; }
/* ARGSUSED */ int sys_listen(struct proc *p, void *v, register_t *retval) { struct sys_listen_args /* { syscallarg(int) s; syscallarg(int) backlog; } */ *uap = v; struct file *fp; int error; if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); error = solisten(fp->f_data, SCARG(uap, backlog)); FRELE(fp, p); return (error); }
int listen (int s, int backlog) { int error; int ret = -1; struct socket *so; rtems_bsdnet_semaphore_obtain (); if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = solisten (so, backlog); if (error == 0) ret = 0; else errno = error; } rtems_bsdnet_semaphore_release (); return ret; }
/* * XXX Allow more than one X redirection? */ void redir_x(u_int32_t inaddr, int start_port, int display, int screen) { int i; if (x_port >= 0) { lprint("X Redir: X already being redirected.\r\n"); show_x(0, 0); } else { for (i = 6001 + (start_port-1); i <= 6100; i++) { if (solisten(htons(i), inaddr, htons(6000 + display), 0)) { /* Success */ x_port = i - 6000; x_display = display; x_screen = screen; show_x(0, 0); return; } } lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n"); } }
int sys_listen(struct thread *td, struct listen_args *uap) { struct socket *so; struct file *fp; cap_rights_t rights; int error; AUDIT_ARG_FD(uap->s); error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN), &fp, NULL, NULL); if (error == 0) { so = fp->f_data; #ifdef MAC error = mac_socket_check_listen(td->td_ucred, so); if (error == 0) #endif error = solisten(so, uap->backlog, td); fdrop(fp, td); } return(error); }
int t_listen(long s, int backlog) { struct socket * so; int err; so = LONG2SO(s); /* convert long to socket */ SOC_CHECK(so); so->so_error = 0; INET_TRACE (INETM_SOCKET, ("SOCK:listen:qlen %d\n", backlog)); LOCK_NET_RESOURCE(NET_RESID); err = solisten (so, backlog); UNLOCK_NET_RESOURCE(NET_RESID); if (err != 0) { so->so_error = err; return SOCKET_ERROR; } return 0; }
int waitForMessages(struct sockaddr_in *site_2, struct thread *td) { waiting_sockaddr = *site_2; struct sockaddr_in *site = &waiting_sockaddr; log_info("waiting for messages on %s:%d", inet_ntoa(site->sin_addr), ntohs(site->sin_port)); int error = 0; struct socket *so = NULL; error = socreate(AF_INET, &so, SOCK_STREAM, 0, td->td_ucred, td); if (error) { log_warn("error in socreate in waitForMessages"); goto bad; } error = sobind(so, (struct sockaddr *) site, td); if (error) { log_warn("error in sobind in waitForMessages"); goto bad; } error = solisten(so, 5, td); if (error) { log_warn("error in solisten in waitForMessages"); goto bad; } error = kthread_add(accept_loop, so, NULL, &accept_kthread, 0, 0, "raymond_accept_loop"); if (error) { log_warn("error creating thread: %d\n", error); goto bad; } return 0; bad: // on error if (so != NULL) soclose(so); return error; }
static void udp_emu(struct socket *so, struct mbuf *m) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); #ifdef EMULATE_TALK CTL_MSG_OLD *omsg; CTL_MSG *nmsg; char buff[sizeof(CTL_MSG)]; u_char type; struct talk_request { struct talk_request *next; struct socket *udp_so; struct socket *tcp_so; } *req; static struct talk_request *req_tbl = 0; #endif struct cu_header { uint16_t d_family; // destination family uint16_t d_port; // destination port uint32_t d_addr; // destination address uint16_t s_family; // source family uint16_t s_port; // source port uint32_t so_addr; // source address uint32_t seqn; // sequence number uint16_t message; // message uint16_t data_type; // data type uint16_t pkt_len; // packet length } *cu_head; switch(so->so_emu) { #ifdef EMULATE_TALK case EMU_TALK: case EMU_NTALK: /* * Talk emulation. We always change the ctl_addr to get * some answers from the daemon. When an ANNOUNCE comes, * we send LEAVE_INVITE to the local daemons. Also when a * DELETE comes, we send copies to the local daemons. */ if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) return; #define IS_OLD (so->so_emu == EMU_TALK) #define COPY_MSG(dest, src) { dest->type = src->type; \ dest->id_num = src->id_num; \ dest->pid = src->pid; \ dest->addr = src->addr; \ dest->ctl_addr = src->ctl_addr; \ memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); } #define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field) /* old_sockaddr to sockaddr_in */ if (IS_OLD) { /* old talk */ omsg = mtod(m, CTL_MSG_OLD*); nmsg = (CTL_MSG *) buff; type = omsg->type; OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; pstrcpy(omsg->l_name, NAME_SIZE_OLD, getlogin()); } else { /* new talk */ omsg = (CTL_MSG_OLD *) buff; nmsg = mtod(m, CTL_MSG *); type = nmsg->type; OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; pstrcpy(nmsg->l_name, NAME_SIZE_OLD, getlogin()); } if (type == LOOK_UP) return; /* for LOOK_UP this is enough */ if (IS_OLD) { /* make a copy of the message */ COPY_MSG(nmsg, omsg); nmsg->vers = 1; nmsg->answer = 0; } else COPY_MSG(omsg, nmsg); /* * If if is an ANNOUNCE message, we go through the * request table to see if a tcp port has already * been redirected for this socket. If not, we solisten() * a new socket and add this entry to the table. * The port number of the tcp socket and our IP * are put to the addr field of the message structures. * Then a LEAVE_INVITE is sent to both local daemon * ports, 517 and 518. This is why we have two copies * of the message, one in old talk and one in new talk * format. */ if (type == ANNOUNCE) { int s; u_short temp_port; for(req = req_tbl; req; req = req->next) if (so == req->udp_so) break; /* found it */ if (!req) { /* no entry for so, create new */ req = (struct talk_request *) malloc(sizeof(struct talk_request)); req->udp_so = so; req->tcp_so = solisten(0, OTOSIN(omsg, addr)->sin_addr.s_addr, OTOSIN(omsg, addr)->sin_port, SS_FACCEPTONCE); req->next = req_tbl; req_tbl = req; } /* replace port number in addr field */ addrlen = sizeof(addr); getsockname(req->tcp_so->s, (struct sockaddr *) &addr, &addrlen); OTOSIN(omsg, addr)->sin_port = addr.sin_port; OTOSIN(omsg, addr)->sin_addr = our_addr; OTOSIN(nmsg, addr)->sin_port = addr.sin_port; OTOSIN(nmsg, addr)->sin_addr = our_addr; /* send LEAVE_INVITEs */ temp_port = OTOSIN(omsg, ctl_addr)->sin_port; OTOSIN(omsg, ctl_addr)->sin_port = 0; OTOSIN(nmsg, ctl_addr)->sin_port = 0; omsg->type = nmsg->type = LEAVE_INVITE; s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); addr.sin_addr = our_addr; addr.sin_family = AF_INET; addr.sin_port = htons(517); sendto(s, (char *)omsg, sizeof(*omsg), 0, (struct sockaddr *)&addr, sizeof(addr)); addr.sin_port = htons(518); sendto(s, (char *)nmsg, sizeof(*nmsg), 0, (struct sockaddr *) &addr, sizeof(addr)); closesocket(s) ; omsg->type = nmsg->type = ANNOUNCE; OTOSIN(omsg, ctl_addr)->sin_port = temp_port; OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; } /* * If it is a DELETE message, we send a copy to the * local daemons. Then we delete the entry corresponding * to our socket from the request table. */ if (type == DELETE) { struct talk_request *temp_req, *req_next; int s; u_short temp_port; temp_port = OTOSIN(omsg, ctl_addr)->sin_port; OTOSIN(omsg, ctl_addr)->sin_port = 0; OTOSIN(nmsg, ctl_addr)->sin_port = 0; s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); addr.sin_addr = our_addr; addr.sin_family = AF_INET; addr.sin_port = htons(517); sendto(s, (char *)omsg, sizeof(*omsg), 0, (struct sockaddr *)&addr, sizeof(addr)); addr.sin_port = htons(518); sendto(s, (char *)nmsg, sizeof(*nmsg), 0, (struct sockaddr *)&addr, sizeof(addr)); closesocket(s); OTOSIN(omsg, ctl_addr)->sin_port = temp_port; OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; /* delete table entry */ if (so == req_tbl->udp_so) { temp_req = req_tbl; req_tbl = req_tbl->next; free(temp_req); } else { temp_req = req_tbl; for(req = req_tbl->next; req; req = req_next) { req_next = req->next; if (so == req->udp_so) { temp_req->next = req_next; free(req); break; } else { temp_req = req; } } } } return; #endif case EMU_CUSEEME: /* * Cu-SeeMe emulation. * Hopefully the packet is more that 16 bytes long. We don't * do any other tests, just replace the address and port * fields. */ if (m->m_len >= sizeof (*cu_head)) { if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) return; cu_head = mtod(m, struct cu_header *); cu_head->s_port = addr.sin_port; cu_head->so_addr = our_addr.s_addr; } return; }
static int icl_listen_add_tcp(struct icl_listen *il, int domain, int socktype, int protocol, struct sockaddr *sa, int portal_id) { struct icl_listen_sock *ils; struct socket *so; struct sockopt sopt; int error, one = 1; error = socreate(domain, &so, socktype, protocol, curthread->td_ucred, curthread); if (error != 0) { ICL_WARN("socreate failed with error %d", error); return (error); } sopt.sopt_dir = SOPT_SET; sopt.sopt_level = SOL_SOCKET; sopt.sopt_name = SO_REUSEADDR; sopt.sopt_val = &one; sopt.sopt_valsize = sizeof(one); sopt.sopt_td = NULL; error = sosetopt(so, &sopt); if (error != 0) { ICL_WARN("failed to set SO_REUSEADDR with error %d", error); soclose(so); return (error); } error = sobind(so, sa, curthread); if (error != 0) { ICL_WARN("sobind failed with error %d", error); soclose(so); return (error); } error = solisten(so, -1, curthread); if (error != 0) { ICL_WARN("solisten failed with error %d", error); soclose(so); return (error); } ils = malloc(sizeof(*ils), M_ICL_PROXY, M_ZERO | M_WAITOK); ils->ils_listen = il; ils->ils_socket = so; ils->ils_id = portal_id; error = kthread_add(icl_accept_thread, ils, NULL, NULL, 0, 0, "iclacc"); if (error != 0) { ICL_WARN("kthread_add failed with error %d", error); soclose(so); free(ils, M_ICL_PROXY); return (error); } sx_xlock(&il->il_lock); TAILQ_INSERT_TAIL(&il->il_sockets, ils, ils_next); sx_xunlock(&il->il_lock); return (0); }
/* * Receive a control message */ static int ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook) { struct thread *td = curthread; /* XXX broken */ const priv_p priv = NG_NODE_PRIVATE(node); struct socket *const so = priv->so; struct ng_mesg *resp = NULL; int error = 0; struct ng_mesg *msg; ng_ID_t raddr; NGI_GET_MSG(item, msg); switch (msg->header.typecookie) { case NGM_KSOCKET_COOKIE: switch (msg->header.cmd) { case NGM_KSOCKET_BIND: { struct sockaddr *const sa = (struct sockaddr *)msg->data; /* Sanity check */ if (msg->header.arglen < SADATA_OFFSET || msg->header.arglen < sa->sa_len) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Bind */ error = sobind(so, sa, td); break; } case NGM_KSOCKET_LISTEN: { /* Sanity check */ if (msg->header.arglen != sizeof(int32_t)) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Listen */ error = solisten(so, *((int32_t *)msg->data), td); break; } case NGM_KSOCKET_ACCEPT: { /* Sanity check */ if (msg->header.arglen != 0) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Make sure the socket is capable of accepting */ if (!(so->so_options & SO_ACCEPTCONN)) ERROUT(EINVAL); if (priv->flags & KSF_ACCEPTING) ERROUT(EALREADY); error = ng_ksocket_check_accept(priv); if (error != 0 && error != EWOULDBLOCK) ERROUT(error); /* * If a connection is already complete, take it. * Otherwise let the upcall function deal with * the connection when it comes in. */ priv->response_token = msg->header.token; raddr = priv->response_addr = NGI_RETADDR(item); if (error == 0) { ng_ksocket_finish_accept(priv); } else priv->flags |= KSF_ACCEPTING; break; } case NGM_KSOCKET_CONNECT: { struct sockaddr *const sa = (struct sockaddr *)msg->data; /* Sanity check */ if (msg->header.arglen < SADATA_OFFSET || msg->header.arglen < sa->sa_len) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Do connect */ if ((so->so_state & SS_ISCONNECTING) != 0) ERROUT(EALREADY); if ((error = soconnect(so, sa, td)) != 0) { soclrstate(so, SS_ISCONNECTING); ERROUT(error); } if ((so->so_state & SS_ISCONNECTING) != 0) { /* We will notify the sender when we connect */ priv->response_token = msg->header.token; raddr = priv->response_addr = NGI_RETADDR(item); priv->flags |= KSF_CONNECTING; ERROUT(EINPROGRESS); } break; } case NGM_KSOCKET_GETNAME: case NGM_KSOCKET_GETPEERNAME: { int (*func)(struct socket *so, struct sockaddr **nam); struct sockaddr *sa = NULL; int len; /* Sanity check */ if (msg->header.arglen != 0) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Get function */ if (msg->header.cmd == NGM_KSOCKET_GETPEERNAME) { if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) ERROUT(ENOTCONN); func = so->so_proto->pr_usrreqs->pru_peeraddr; } else func = so->so_proto->pr_usrreqs->pru_sockaddr; /* Get local or peer address */ if ((error = (*func)(so, &sa)) != 0) goto bail; len = (sa == NULL) ? 0 : sa->sa_len; /* Send it back in a response */ NG_MKRESPONSE(resp, msg, len, M_WAITOK | M_NULLOK); if (resp == NULL) { error = ENOMEM; goto bail; } bcopy(sa, resp->data, len); bail: /* Cleanup */ if (sa != NULL) kfree(sa, M_SONAME); break; } case NGM_KSOCKET_GETOPT: { struct ng_ksocket_sockopt *ksopt = (struct ng_ksocket_sockopt *)msg->data; struct sockopt sopt; /* Sanity check */ if (msg->header.arglen != sizeof(*ksopt)) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Get response with room for option value */ NG_MKRESPONSE(resp, msg, sizeof(*ksopt) + NG_KSOCKET_MAX_OPTLEN, M_WAITOK | M_NULLOK); if (resp == NULL) ERROUT(ENOMEM); /* Get socket option, and put value in the response */ sopt.sopt_dir = SOPT_GET; sopt.sopt_level = ksopt->level; sopt.sopt_name = ksopt->name; sopt.sopt_td = NULL; sopt.sopt_valsize = NG_KSOCKET_MAX_OPTLEN; ksopt = (struct ng_ksocket_sockopt *)resp->data; sopt.sopt_val = ksopt->value; if ((error = sogetopt(so, &sopt)) != 0) { NG_FREE_MSG(resp); break; } /* Set actual value length */ resp->header.arglen = sizeof(*ksopt) + sopt.sopt_valsize; break; } case NGM_KSOCKET_SETOPT: { struct ng_ksocket_sockopt *const ksopt = (struct ng_ksocket_sockopt *)msg->data; const int valsize = msg->header.arglen - sizeof(*ksopt); struct sockopt sopt; /* Sanity check */ if (valsize < 0) ERROUT(EINVAL); if (so == NULL) ERROUT(ENXIO); /* Set socket option */ sopt.sopt_dir = SOPT_SET; sopt.sopt_level = ksopt->level; sopt.sopt_name = ksopt->name; sopt.sopt_val = ksopt->value; sopt.sopt_valsize = valsize; sopt.sopt_td = NULL; error = sosetopt(so, &sopt); break; } default: error = EINVAL; break; } break; default: error = EINVAL; break; } done: NG_RESPOND_MSG(error, node, item, resp); NG_FREE_MSG(msg); return (error); }
static int bsd_listen(cyg_file *fp, int backlog) { return (solisten((struct socket *)fp->f_data, backlog, 0)); }