diff options
| author | Garrett D'Amore <garrett@damore.org> | 2022-07-03 19:05:50 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2022-07-11 18:59:59 -0400 |
| commit | 15f90b02bdacbf0ae47fa105944f15b6596f9748 (patch) | |
| tree | 998c2fb60e1c6a117e55985b8d94631e5cc95ea8 /usr/src/uts | |
| parent | 174513368dec739adb93c76e5d47aed84797d1ad (diff) | |
| download | illumos-joyent-15f90b02bdacbf0ae47fa105944f15b6596f9748.tar.gz | |
14768 retire nca
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Reviewed by: Andy Fiddaman <andy@omnios.org>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Approved by: Robert Mustacchi <rm@fingolfin.org>
Diffstat (limited to 'usr/src/uts')
36 files changed, 22 insertions, 7530 deletions
diff --git a/usr/src/uts/Makefile b/usr/src/uts/Makefile index b21c920fce..2cc0dce6f0 100644 --- a/usr/src/uts/Makefile +++ b/usr/src/uts/Makefile @@ -22,6 +22,7 @@ # # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2018 Nexenta Systems, Inc. +# Copyright 2022 Garrett D'Amore # include ../Makefile.master @@ -138,7 +139,6 @@ COMMON_HDRDIRS= common/c2 \ common/klm \ common/inet \ common/inet/ipf/netinet \ - common/inet/nca \ common/inet/sockmods/netpacket \ common/io/bpf/net \ common/io/fibre-channel/fca/qlc \ diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 8e7d5f0e06..1e9d9774b7 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -621,8 +621,6 @@ TCP_OBJS += tcpddi.o TCP6_OBJS += tcp6ddi.o -NCA_OBJS += ncaddi.o - SDP_SOCK_MOD_OBJS += sockmod_sdp.o socksdp.o socksdpsubr.o SCTP_SOCK_MOD_OBJS += sockmod_sctp.o socksctp.o socksctpsubr.o @@ -1282,8 +1280,7 @@ SOCK_OBJS += socksubr.o sockvfsops.o sockparams.o \ sockcommon_vnops.o sockcommon_subr.o \ sockcommon_sops.o sockcommon.o \ sock_notsupp.o socknotify.o \ - nl7c.o nl7curi.o nl7chttp.o nl7clogd.o \ - nl7cnca.o sodirect.o sockfilter.o + sodirect.o sockfilter.o TMPFS_OBJS += tmp_dir.o tmp_subr.o tmp_tnode.o tmp_vfsops.o \ tmp_vnops.o diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules index df000b61cb..ba70c5d688 100644 --- a/usr/src/uts/common/Makefile.rules +++ b/usr/src/uts/common/Makefile.rules @@ -530,10 +530,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/udp/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) -$(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/nca/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - $(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/sockmods/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) diff --git a/usr/src/uts/common/fs/sockfs/nl7c.c b/usr/src/uts/common/fs/sockfs/nl7c.c deleted file mode 100644 index a71572cbd4..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7c.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. - */ - -/* - * NL7C (Network Layer 7 Cache) as part of SOCKFS provides an in-kernel - * gateway cache for the request/response message based L7 protocol HTTP - * (Hypertext Transfer Protocol, see HTTP/1.1 RFC2616) in a semantically - * transparent manner. - * - * Neither the requesting user agent (client, e.g. web browser) nor the - * origin server (e.g. webserver) that provided the response cached by - * NL7C are impacted in any way. - * - * Note, currently NL7C only processes HTTP messages via the embedded - * URI of scheme http (not https nor any other), additional scheme are - * intended to be supported as is practical such that much of the NL7C - * framework may appear more general purpose then would be needed just - * for an HTTP gateway cache. - * - * NL7C replaces NCA (Network Cache and Accelerator) and in the future - * NCAS (NCA/SSL). - * - * Further, NL7C uses all NCA configuration files, see "/etc/nca/", the - * NCA socket API, "AF_NCA", and "ndd /dev/nca" for backwards compatibility. - */ - -#include <sys/systm.h> -#include <sys/strsun.h> -#include <sys/strsubr.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <inet/common.h> -#include <inet/ip.h> -#include <inet/led.h> -#include <inet/mi.h> -#include <netinet/in.h> -#include <fs/sockfs/nl7c.h> -#include <fs/sockfs/nl7curi.h> -#include <fs/sockfs/socktpi.h> - -#include <inet/nca/ncadoorhdr.h> -#include <inet/nca/ncalogd.h> -#include <inet/nca/ncandd.h> - -#include <sys/promif.h> - -/* - * NL7C, NCA, NL7C logger enabled: - */ - -boolean_t nl7c_enabled = B_FALSE; - -boolean_t nl7c_logd_enabled = B_FALSE; -boolean_t nl7c_logd_started = B_FALSE; -boolean_t nl7c_logd_cycle = B_TRUE; - -/* - * Some externs: - */ -extern void nl7c_uri_init(void); -extern boolean_t nl7c_logd_init(int, caddr_t *); -extern void nl7c_nca_init(void); - -/* - * nl7c_addr_t - a singly linked grounded list, pointed to by *nl7caddrs, - * constructed at init time by parsing "/etc/nca/ncaport.conf". - * - * This list is searched at bind(3SOCKET) time when an application doesn't - * explicitly set AF_NCA but instead uses AF_INET, if a match is found then - * the underlying socket is marked sti_nl7c_flags NL7C_ENABLED. - */ - -typedef struct nl7c_addr_s { - struct nl7c_addr_s *next; /* next entry */ - sa_family_t family; /* addr type, only INET and INET6 */ - uint16_t port; /* port */ - union { - ipaddr_t v4; /* IPv4 address */ - in6_addr_t v6; /* IPv6 address */ - void *align; /* foce alignment */ - } addr; /* address */ - - struct sonode *listener; /* listen()er's sonode */ - boolean_t temp; /* temporary addr via add_addr() ? */ -} nl7c_addr_t; - -nl7c_addr_t *nl7caddrs = NULL; - -/* - * Called for an NL7C_ENABLED listen()er socket for the nl7c_addr_t - * previously returned by nl7c_lookup_addr(). - */ - -void -nl7c_listener_addr(void *arg, struct sonode *so) -{ - nl7c_addr_t *p = (nl7c_addr_t *)arg; - - if (p->listener == NULL) - p->listener = so; - SOTOTPI(so)->sti_nl7c_addr = arg; -} - -struct sonode * -nl7c_addr2portso(void *arg) -{ - nl7c_addr_t *p = (nl7c_addr_t *)arg; - - return (p->listener); -} - -void * -nl7c_lookup_addr(void *addr, t_uscalar_t addrlen) -{ - struct sockaddr *sap = addr; - struct sockaddr_in *v4p = addr; - nl7c_addr_t *p = nl7caddrs; - - if (sap->sa_family != AF_INET || addrlen != sizeof (*v4p)) { - /* Only support IPv4 */ - return (B_FALSE); - } - while (p) { - if (sap->sa_family == p->family && - v4p->sin_port == p->port && - (v4p->sin_addr.s_addr == p->addr.v4 || - p->addr.v4 == INADDR_ANY)) { - /* Match */ - return (p); - } - p = p->next; - } - return (NULL); -} - -void * -nl7c_add_addr(void *addr, t_uscalar_t addrlen) -{ - struct sockaddr *sap = addr; - struct sockaddr_in *v4p = addr; - nl7c_addr_t *new = NULL; - nl7c_addr_t *old; - nl7c_addr_t *p; - boolean_t alloced; - - if (sap->sa_family != AF_INET || addrlen != sizeof (*v4p)) { - /* Only support IPv4 */ - return (NULL); - } -again: - p = nl7caddrs; - while (p) { - if (new == NULL && p->port == 0) - new = p; - if (sap->sa_family == p->family && - v4p->sin_port == p->port && - (v4p->sin_addr.s_addr == p->addr.v4 || - p->addr.v4 == INADDR_ANY)) { - /* Match */ - return (p); - } - p = p->next; - } - if (new == NULL) { - new = kmem_zalloc(sizeof (*new), KM_SLEEP); - alloced = B_TRUE; - } else - alloced = B_FALSE; - - new->family = sap->sa_family; - new->port = v4p->sin_port; - new->addr.v4 = v4p->sin_addr.s_addr; - new->temp = B_TRUE; - - if (alloced) { - old = nl7caddrs; - new->next = old; - if (atomic_cas_ptr(&nl7caddrs, old, new) != old) { - kmem_free(new, sizeof (*new)); - goto again; - } - } - - return (new); -} - -boolean_t -nl7c_close_addr(struct sonode *so) -{ - nl7c_addr_t *p = nl7caddrs; - - while (p) { - if (p->listener == so) { - if (p->temp) - p->port = (uint16_t)-1; - p->listener = NULL; - return (B_TRUE); - } - p = p->next; - } - return (B_FALSE); -} - -static void -nl7c_addr_add(nl7c_addr_t *p) -{ - p->next = nl7caddrs; - nl7caddrs = p; -} - -void -nl7c_mi_report_addr(mblk_t *mp) -{ - ipaddr_t ip; - uint16_t port; - nl7c_addr_t *p = nl7caddrs; - struct sonode *so; - char addr[32]; - - (void) mi_mpprintf(mp, "Door Up-Call-Queue IPaddr:TCPport Listenning"); - while (p) { - if (p->port != (uint16_t)-1) { - /* Don't report freed slots */ - ip = ntohl(p->addr.v4); - port = ntohs(p->port); - - if (ip == INADDR_ANY) { - (void) strcpy(addr, "*"); - } else { - int a1 = (ip >> 24) & 0xFF; - int a2 = (ip >> 16) & 0xFF; - int a3 = (ip >> 8) & 0xFF; - int a4 = ip & 0xFF; - - (void) mi_sprintf(addr, "%d.%d.%d.%d", - a1, a2, a3, a4); - } - so = p->listener; - (void) mi_mpprintf(mp, "%p %s:%d %d", - so ? (void *)strvp2wq(SOTOV(so)) : NULL, - addr, port, p->listener ? 1 : 0); - } - p = p->next; - } -} - -/* - * Inet ASCII to binary. - * - * Note, it's assumed that *s is a valid zero byte terminated string, and - * that *p is a zero initialized struct (this is important as the value of - * INADDR_ANY and IN6ADDR_ANY is zero). - */ - -static int -inet_atob(char *s, nl7c_addr_t *p) -{ - if (strcmp(s, "*") == 0) { - /* INADDR_ANY */ - p->family = AF_INET; - return (0); - } - if (strcmp(s, "::") == 0) { - /* IN6ADDR_ANY */ - p->family = AF_INET6; - return (0); - } - /* IPv4 address ? */ - if (inet_pton(AF_INET, s, &p->addr.v4) != 1) { - /* Nop, IPv6 address ? */ - if (inet_pton(AF_INET6, s, &p->addr.v6) != 1) { - /* Nop, return error */ - return (1); - } - p->family = AF_INET6; - } else { - p->family = AF_INET; - } - return (0); -} - -/* - * Open and read each line from "/etc/nca/ncaport.conf", the syntax of a - * ncaport.conf file line is: - * - * ncaport=IPaddr/Port[/Proxy] - * - * Where: - * - * ncaport - the only token recognized. - * - * IPaddr - an IPv4 numeric dot address (e.g. 192.168.84.71) or '*' for - * INADDR_ANY, or an IPv6 numeric address or "::" for IN6ADDR_ANY. - * - * / - IPaddr/Port separator. - * - * Port - a TCP decimal port number. - * - * Note, all other lines will be ignored. - */ - -static void -ncaportconf_read(void) -{ - int ret; - struct vnode *vp; - char c; - ssize_t resid; - char buf[1024]; - char *ebp = &buf[sizeof (buf)]; - char *bp = ebp; - offset_t off = 0; - enum parse_e {START, TOK, ADDR, PORT, EOL} parse = START; - nl7c_addr_t *addrp = NULL; - char *ncaport = "ncaport"; - char string[] = "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX"; - char *stringp; - char *tok; - char *portconf = "/etc/nca/ncaport.conf"; - - ret = vn_open(portconf, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0); - if (ret == ENOENT) { - /* No portconf file, nothing to do */ - return; - } - if (ret != 0) { - /* Error of some sort, tell'm about it */ - cmn_err(CE_WARN, "%s: open error %d", portconf, ret); - return; - } - /* - * Read portconf one buf[] at a time, parse one char at a time. - */ - for (;;) { - if (bp == ebp) { - /* Nothing left in buf[], read another */ - ret = vn_rdwr(UIO_READ, vp, buf, sizeof (buf), off, - UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid); - if (ret != 0) { - /* Error of some sort, tell'm about it */ - cmn_err(CE_WARN, "%s: read error %d", - portconf, ret); - break; - } - if (resid == sizeof (buf)) { - /* EOF, done */ - break; - } - /* Initilize per buf[] state */ - bp = buf; - ebp = &buf[sizeof (buf) - resid]; - off += sizeof (buf) - resid; - } - c = *bp++; - switch (parse) { - case START: - /* Initilize all per file line state */ - if (addrp == NULL) { - addrp = kmem_zalloc(sizeof (*addrp), - KM_NOSLEEP); - } - tok = ncaport; - stringp = string; - parse = TOK; - /*FALLTHROUGH*/ - case TOK: - if (c == '#') { - /* Comment through end of line */ - parse = EOL; - break; - } - if (isalpha(c)) { - if (c != *tok++) { - /* Only know one token, skip */ - parse = EOL; - } - } else if (c == '=') { - if (*tok != '\0') { - /* Only know one token, skip */ - parse = EOL; - break; - } - parse = ADDR; - } else if (c == '\n') { - /* Found EOL, empty line, next line */ - parse = START; - } else { - /* Unexpected char, skip */ - parse = EOL; - } - break; - - case ADDR: - if (c == '/') { - /* addr/port separator, end of addr */ - *stringp = 0; - if (inet_atob(string, addrp)) { - /* Bad addr, skip */ - parse = EOL; - } else { - stringp = string; - parse = PORT; - } - } else { - /* Save char to string */ - if (stringp == - &string[sizeof (string) - 1]) { - /* Would overflow, skip */ - parse = EOL; - } else { - /* Copy IP addr char */ - *stringp++ = c; - } - } - break; - - case PORT: - if (isdigit(c)) { - /* Save char to string */ - if (stringp == - &string[sizeof (string) - 1]) { - /* Would overflow, skip */ - parse = EOL; - } else { - /* Copy port digit char */ - *stringp++ = c; - } - break; - } else if (c == '#' || isspace(c)) { - unsigned long result = 0; - - /* End of port number, convert */ - *stringp = '\0'; - if (ddi_strtoul(string, NULL, 10, &result) - != 0) { - parse = EOL; - break; - } - addrp->port = ntohs(result); - - /* End of parse, add entry */ - nl7c_addr_add(addrp); - addrp = NULL; - parse = EOL; - } else { - /* Unrecognized char, skip */ - parse = EOL; - break; - } - if (c == '\n') { - /* Found EOL, start on next line */ - parse = START; - } - break; - - case EOL: - if (c == '\n') { - /* Found EOL, start on next line */ - parse = START; - } - break; - } - - } - if (addrp != NULL) { - kmem_free(addrp, sizeof (*addrp)); - } - (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL); - VN_RELE(vp); -} - -/* - * Open and read each line from "/etc/nca/ncakmod.conf" and parse looking - * for the NCA enabled, the syntax is: status=enabled, all other lines will - * be ignored. - */ - -static void -ncakmodconf_read(void) -{ - int ret; - struct vnode *vp; - char c; - ssize_t resid; - char buf[1024]; - char *ebp = &buf[sizeof (buf)]; - char *bp = ebp; - offset_t off = 0; - enum parse_e {START, TOK, EOL} parse = START; - char *status = "status=enabled"; - char *tok; - char *ncakmod = "/etc/nca/ncakmod.conf"; - - ret = vn_open(ncakmod, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0); - if (ret == ENOENT) { - /* No ncakmod file, nothing to do */ - return; - } - if (ret != 0) { - /* Error of some sort, tell'm about it */ - cmn_err(CE_WARN, "%s: open error %d", status, ret); - return; - } - /* - * Read ncakmod one buf[] at a time, parse one char at a time. - */ - for (;;) { - if (bp == ebp) { - /* Nothing left in buf[], read another */ - ret = vn_rdwr(UIO_READ, vp, buf, sizeof (buf), off, - UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid); - if (ret != 0) { - /* Error of some sort, tell'm about it */ - cmn_err(CE_WARN, "%s: read error %d", - status, ret); - break; - } - if (resid == sizeof (buf)) { - /* EOF, done */ - break; - } - /* Initilize per buf[] state */ - bp = buf; - ebp = &buf[sizeof (buf) - resid]; - off += sizeof (buf) - resid; - } - c = *bp++; - switch (parse) { - case START: - /* Initilize all per file line state */ - tok = status; - parse = TOK; - /*FALLTHROUGH*/ - case TOK: - if (c == '#') { - /* Comment through end of line */ - parse = EOL; - break; - } - if (isalpha(c) || c == '=') { - if (c != *tok++) { - /* Only know one token, skip */ - parse = EOL; - } - } else if (c == '\n') { - /* - * Found EOL, if tok found done, - * else start on next-line. - */ - if (*tok == '\0') { - nl7c_enabled = B_TRUE; - goto done; - } - parse = START; - } else { - /* Unexpected char, skip */ - parse = EOL; - } - break; - - case EOL: - if (c == '\n') { - /* Found EOL, start on next line */ - parse = START; - } - break; - } - - } -done: - (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL); - VN_RELE(vp); -} - -/* - * Open and read each line from "/etc/nca/ncalogd.conf" and parse for - * the tokens and token text (i.e. key and value ncalogd.conf(5)): - * - * status=enabled - * - * logd_file_size=[0-9]+ - * - * logd_file_name=["]filename( filename)*["] - */ - -static int file_size = 1000000; -static caddr_t fnv[NCA_FIOV_SZ]; - -static void -ncalogdconf_read(void) -{ - int ret; - struct vnode *vp; - char c; - int sz; - ssize_t resid; - char buf[1024]; - char *ebp = &buf[sizeof (buf)]; - char *bp = ebp; - offset_t off = 0; - enum parse_e {START, TOK, TEXT, EOL} parse = START; - char *tokstatus = "status\0enabled"; - char *toksize = "logd_file_size"; - char *tokfile = "logd_path_name"; - char *tokstatusp; - char *toksizep; - char *tokfilep; - char *tok; - int tokdelim = 0; - char *ncalogd = "/etc/nca/ncalogd.conf"; - char *ncadeflog = "/var/nca/log"; - char file[TYPICALMAXPATHLEN] = {0}; - char *fp = file; - caddr_t *fnvp = fnv; - - ret = vn_open(ncalogd, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0); - if (ret == ENOENT) { - /* No ncalogd file, nothing to do */ - return; - } - if (ret != 0) { - /* Error of some sort, tell'm about it */ - cmn_err(CE_WARN, "ncalogdconf_read: %s: open error(%d).", - ncalogd, ret); - return; - } - /* - * Read ncalogd.conf one buf[] at a time, parse one char at a time. - */ - for (;;) { - if (bp == ebp) { - /* Nothing left in buf[], read another */ - ret = vn_rdwr(UIO_READ, vp, buf, sizeof (buf), off, - UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid); - if (ret != 0) { - /* Error of some sort, tell'm about it */ - cmn_err(CE_WARN, "%s: read error %d", - ncalogd, ret); - break; - } - if (resid == sizeof (buf)) { - /* EOF, done */ - break; - } - /* Initilize per buf[] state */ - bp = buf; - ebp = &buf[sizeof (buf) - resid]; - off += sizeof (buf) - resid; - } - c = *bp++; - switch (parse) { - case START: - /* Initilize all per file line state */ - tokstatusp = tokstatus; - toksizep = toksize; - tokfilep = tokfile; - tok = NULL; - parse = TOK; - sz = 0; - /*FALLTHROUGH*/ - case TOK: - if (isalpha(c) || c == '_') { - /* - * Found a valid tok char, if matches - * any of the tokens continue else NULL - * then string pointer. - */ - if (tokstatusp != NULL && c != *tokstatusp++) - tokstatusp = NULL; - if (toksizep != NULL && c != *toksizep++) - toksizep = NULL; - if (tokfilep != NULL && c != *tokfilep++) - tokfilep = NULL; - - if (tokstatusp == NULL && - toksizep == NULL && - tokfilep == NULL) { - /* - * All tok string pointers are NULL - * so skip rest of line. - */ - parse = EOL; - } - } else if (c == '=') { - /* - * Found tok separator, if tok found get - * tok text, else skip rest of line. - */ - if (tokstatusp != NULL && *tokstatusp == '\0') - tok = tokstatus; - else if (toksizep != NULL && *toksizep == '\0') - tok = toksize; - else if (tokfilep != NULL && *tokfilep == '\0') - tok = tokfile; - if (tok != NULL) - parse = TEXT; - else - parse = EOL; - } else if (c == '\n') { - /* Found EOL, start on next line */ - parse = START; - } else { - /* Comment or unknown char, skip rest of line */ - parse = EOL; - } - break; - case TEXT: - if (c == '\n') { - /* - * Found EOL, finish up tok text processing - * (if any) and start on next line. - */ - if (tok == tokstatus) { - if (*++tokstatusp == '\0') - nl7c_logd_enabled = B_TRUE; - } else if (tok == toksize) { - file_size = sz; - } else if (tok == tokfile) { - if (tokdelim == 0) { - /* Non delimited path name */ - *fnvp++ = strdup(file); - } else if (fp != file) { - /* No closing delimiter */ - /*EMPTY*/; - } - } - parse = START; - } else if (tok == tokstatus) { - if (! isalpha(c) || *++tokstatusp == '\0' || - c != *tokstatusp) { - /* Not enabled, skip line */ - parse = EOL; - } - } else if (tok == toksize) { - if (isdigit(c)) { - sz *= 10; - sz += c - '0'; - } else { - /* Not a decimal digit, skip line */ - parse = EOL; - } - } else { - /* File name */ - if (c == '"' && tokdelim++ == 0) { - /* Opening delimiter, skip */ - /*EMPTY*/; - } else if (c == '"' || c == ' ') { - /* List delim or filename separator */ - *fnvp++ = strdup(file); - fp = file; - } else if (fp < &file[sizeof (file) - 1]) { - /* Filename char */ - *fp++ = c; - } else { - /* Filename to long, skip line */ - parse = EOL; - } - } - break; - - case EOL: - if (c == '\n') { - /* Found EOL, start on next line */ - parse = START; - } - break; - } - - } -done: - (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL); - VN_RELE(vp); - - if (nl7c_logd_enabled) { - if (fnvp == fnv) { - /* - * No logfile was specified and found so - * so use defualt NCA log file path. - */ - *fnvp++ = strdup(ncadeflog); - } - if (fnvp < &fnv[NCA_FIOV_SZ]) { - /* NULL terminate list */ - *fnvp = NULL; - } - } -} - -void -nl7clogd_startup(void) -{ - static kmutex_t startup; - - /* - * Called on the first log() attempt, have to wait until then to - * initialize logd as at logdconf_read() the root fs is read-only. - */ - mutex_enter(&startup); - if (nl7c_logd_started) { - /* Lost the race, nothing todo */ - mutex_exit(&startup); - return; - } - nl7c_logd_started = B_TRUE; - if (! nl7c_logd_init(file_size, fnv)) { - /* Failure, disable logging */ - nl7c_logd_enabled = B_FALSE; - cmn_err(CE_WARN, "nl7clogd_startup: failed, disabling loggin"); - mutex_exit(&startup); - return; - } - mutex_exit(&startup); -} - - -void -nl7c_startup() -{ - /* - * Open, read, and parse the NCA logd configuration file, - * then initialize URI processing and NCA compat. - */ - ncalogdconf_read(); - nl7c_uri_init(); - nl7c_nca_init(); -} - -void -nl7c_init() -{ - /* Open, read, and parse the NCA kmod configuration file */ - ncakmodconf_read(); - - if (nl7c_enabled) { - /* - * NL7C is enabled so open, read, and parse - * the NCA address/port configuration file - * and call startup() to finish config/init. - */ - ncaportconf_read(); - nl7c_startup(); - } -} - -/* - * The main processing function called by accept() on a newly created - * socket prior to returning it to the caller of accept(). - * - * Here data is read from the socket until a completed L7 request parse - * is completed. Data will be read in the context of the user thread - * which called accept(), when parse has been completed either B_TRUE - * or B_FALSE will be returned. - * - * If NL7C successfully process the L7 protocol request, i.e. generates - * a response, B_TRUE will be returned. - * - * Else, B_FALSE will be returned if NL7C can't process the request: - * - * 1) Couldn't locate a URI within the request. - * - * 2) URI scheme not reqcognized. - * - * 3) A request which can't be processed. - * - * 4) A request which could be processed but NL7C dosen't currently have - * the response data. In which case NL7C will parse the returned response - * from the application for possible caching for subsequent request(s). - */ - -volatile uint64_t nl7c_proc_cnt = 0; -volatile uint64_t nl7c_proc_error = 0; -volatile uint64_t nl7c_proc_ETIME = 0; -volatile uint64_t nl7c_proc_again = 0; -volatile uint64_t nl7c_proc_next = 0; -volatile uint64_t nl7c_proc_rcv = 0; -volatile uint64_t nl7c_proc_noLRI = 0; -volatile uint64_t nl7c_proc_nodata = 0; -volatile uint64_t nl7c_proc_parse = 0; - -boolean_t -nl7c_process(struct sonode *so, boolean_t nonblocking) -{ - vnode_t *vp = SOTOV(so); - sotpi_info_t *sti = SOTOTPI(so); - mblk_t *rmp = sti->sti_nl7c_rcv_mp; - clock_t timout; - rval_t rval; - uchar_t pri; - int pflag; - int error; - boolean_t more; - boolean_t ret = B_FALSE; - boolean_t first = B_TRUE; - boolean_t pollin = (sti->sti_nl7c_flags & NL7C_POLLIN); - - nl7c_proc_cnt++; - - /* Caller has so_lock enter()ed */ - error = so_lock_read_intr(so, nonblocking ? FNDELAY|FNONBLOCK : 0); - if (error) { - /* Couldn't read lock, pass on this socket */ - sti->sti_nl7c_flags = 0; - nl7c_proc_noLRI++; - return (B_FALSE); - } - /* Exit so_lock for now, will be reenter()ed prior to return */ - mutex_exit(&so->so_lock); - - if (pollin) - sti->sti_nl7c_flags &= ~NL7C_POLLIN; - - /* Initialize some kstrgetmsg() constants */ - pflag = MSG_ANY | MSG_DELAYERROR; - pri = 0; - if (nonblocking) { - /* Non blocking so don't block */ - timout = 0; - } else if (sti->sti_nl7c_flags & NL7C_SOPERSIST) { - /* 2nd or more time(s) here so use keep-alive value */ - timout = nca_http_keep_alive_timeout; - } else { - /* 1st time here so use connection value */ - timout = nca_http_timeout; - } - - rval.r_vals = 0; - do { - /* - * First time through, if no data left over from a previous - * kstrgetmsg() then try to get some, else just process it. - * - * Thereafter, rmp = NULL after the successful kstrgetmsg() - * so try to get some new data and append to list (i.e. until - * enough fragments are collected for a successful parse). - */ - if (rmp == NULL) { - - error = kstrgetmsg(vp, &rmp, NULL, &pri, &pflag, - timout, &rval); - if (error) { - if (error == ETIME) { - /* Timeout */ - nl7c_proc_ETIME++; - } else if (error != EWOULDBLOCK) { - /* Error of some sort */ - nl7c_proc_error++; - rval.r_v.r_v2 = error; - sti->sti_nl7c_flags = 0; - break; - } - error = 0; - } - if (rmp != NULL) { - mblk_t *mp = sti->sti_nl7c_rcv_mp; - - - if (mp == NULL) { - /* Just new data, common case */ - sti->sti_nl7c_rcv_mp = rmp; - } else { - /* Add new data to tail */ - while (mp->b_cont != NULL) - mp = mp->b_cont; - mp->b_cont = rmp; - } - } - if (sti->sti_nl7c_rcv_mp == NULL) { - /* No data */ - nl7c_proc_nodata++; - if (timout > 0 || (first && pollin)) { - /* Expected data so EOF */ - ret = B_TRUE; - } else if (sti->sti_nl7c_flags & - NL7C_SOPERSIST) { - /* Persistent so just checking */ - ret = B_FALSE; - } - break; - } - rmp = NULL; - } - first = B_FALSE; - again: - nl7c_proc_parse++; - - more = nl7c_parse(so, nonblocking, &ret); - - if (ret == B_TRUE && (sti->sti_nl7c_flags & NL7C_SOPERSIST)) { - /* - * Parse complete, cache hit, response on its way, - * socket is persistent so try to process the next - * request. - */ - if (nonblocking) { - ret = B_FALSE; - break; - } - if (sti->sti_nl7c_rcv_mp) { - /* More recv-side data, pipelined */ - nl7c_proc_again++; - goto again; - } - nl7c_proc_next++; - if (nonblocking) - timout = 0; - else - timout = nca_http_keep_alive_timeout; - - more = B_TRUE; - } - - } while (more); - - if (sti->sti_nl7c_rcv_mp) { - nl7c_proc_rcv++; - } - sti->sti_nl7c_rcv_rval = rval.r_vals; - /* Renter so_lock, caller called with it enter()ed */ - mutex_enter(&so->so_lock); - so_unlock_read(so); - - return (ret); -} diff --git a/usr/src/uts/common/fs/sockfs/nl7c.h b/usr/src/uts/common/fs/sockfs/nl7c.h deleted file mode 100644 index 6cd27c5efd..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7c.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_SOCKFS_NL7C_H -#define _SYS_SOCKFS_NL7C_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <sys/atomic.h> -#include <sys/cmn_err.h> -#include <sys/stropts.h> -#include <sys/socket.h> -#include <sys/socketvar.h> - - -/* - * NCA_DEV NCA device - * - * NCA_INET_DEV TPI device for the INET based transport that NCA will use. - */ -#define NCA_DEV "/dev/nca" -#define NCA_INET_DEV "/dev/tcp" - -/* - * NL7C (uint64_t)(sotpi_info_t).sti_nl7c_flags: - */ - -#define NL7C_ENABLED 0x00000001 /* NL7C enabled socket */ -#define NL7C_SOPERSIST 0x00000002 /* NL7C socket is persistent */ -#define NL7C_WAITWRITE 0x00000004 /* NL7C waiting first write */ -#define NL7C_AF_NCA 0x00000008 /* NL7C enabled socket via AF_NCA */ -#define NL7C_POLLIN 0x00000010 /* poll() POLLIN prior to read */ -#define NL7C_CLOSE 0x00000020 /* NL7C close needed */ - -#define NL7C_SCHEMEPRIV 0xFFFF0000 /* NL7C scheme private state */ - -#define NL7C_UNUSED 0xFFFFFFFF00000000 /* Unused bits */ - -/* - * Globals ... - */ - -extern boolean_t nl7c_enabled; -extern clock_t nl7c_uri_ttl; - -/* - * Function prototypes ... - */ - -boolean_t nl7c_process(struct sonode *, boolean_t); -int nl7c_data(struct sonode *, uio_t *); -void nl7c_urifree(struct sonode *); -void nl7c_close(struct sonode *); -boolean_t nl7c_parse(struct sonode *, boolean_t, boolean_t *); - -extern void *nl7c_lookup_addr(void *, t_uscalar_t); -extern void *nl7c_add_addr(void *, t_uscalar_t); -extern void nl7c_listener_addr(void *, struct sonode *); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_SOCKFS_NL7C_H */ diff --git a/usr/src/uts/common/fs/sockfs/nl7chttp.c b/usr/src/uts/common/fs/sockfs/nl7chttp.c deleted file mode 100644 index e22c9d300c..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7chttp.c +++ /dev/null @@ -1,1948 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/sysmacros.h> -#include <sys/strsubr.h> -#include <fs/sockfs/nl7c.h> -#include <fs/sockfs/nl7curi.h> -#include <fs/sockfs/socktpi.h> - -#include <inet/nca/ncadoorhdr.h> -#include <inet/nca/ncalogd.h> - - -volatile uint64_t nl7c_http_response_chunked = 0; -volatile uint64_t nl7c_http_response_chunkparse = 0; - -volatile uint64_t nl7c_http_response_pass1 = 0; -volatile uint64_t nl7c_http_response_pass2 = 0; -volatile uint64_t nl7c_http_response_304 = 0; -volatile uint64_t nl7c_http_response_307 = 0; -volatile uint64_t nl7c_http_response_400 = 0; - -volatile uint64_t nl7c_http_cond_304 = 0; -volatile uint64_t nl7c_http_cond_412 = 0; - -/* - * Some externs: - */ - -extern uint64_t nl7c_uri_bytes; -extern kmem_cache_t *nl7c_uri_kmc; -extern kmem_cache_t *nl7c_uri_rd_kmc; -extern void nl7c_uri_inactive(uri_desc_t *); -extern uint32_t nca_major_version; -extern uint32_t nca_minor_version; - -/* - * HTTP connection persistent headers, mblk_t's, and state values stored in - * (struct sonode *).so_nl7c_flags & NL7C_SCHEMEPRIV. - */ - -char Shttp_conn_cl[] = "Connection: close\r\n"; -char Shttp_conn_ka[] = "Connection: Keep-Alive\r\n"; - -mblk_t *http_conn_cl; -mblk_t *http_conn_ka; - -#define HTTP_CONN_CL 0x00010000 -#define HTTP_CONN_KA 0x00020000 - -/* - * Hex ascii Digit to Integer accumulate, if (char)c is a valid ascii - * hex digit then the contents of (int32_t)n will be left shifted and - * the new digit added in, else n will be set to -1. - */ - -#define hd2i(c, n) { \ - (n) *= 16; \ - if (isdigit(c)) \ - (n) += (c) - '0'; \ - else if ((c) >= 'a' && (c) <= 'f') \ - (n) += (c) - 'W'; \ - else if ((c) >= 'A' && (c) <= 'F') \ - (n) += (c) - '7'; \ - else \ - (n) = -1; \ -} - -/* - * HTTP parser action values: - */ - -typedef enum act_e { - REQUEST = 0x0001, - NUMERIC = 0x0002, - QUALIFIER = 0x0004, - PASS = 0x0008, - FILTER = 0x0010, - NOCACHE = 0x0020, - HASH = 0x0040, - DATE = 0x0080, - ETAG = 0x0100, - RESPONSE = 0x0200, - URIABS = 0x0400, - URIREL = 0x0800, - HEX = 0x1000 -} act_t; - -#define UNDEF PASS - -/* - * HTTP parser token: - */ - -typedef struct token_s { - int tokid; /* Token ident */ - char *text; /* Token text */ - act_t act; /* Action to take */ -} token_t; - -/* - * The ttree_t (or token tree) is an ascending ordered binary tree - * built by ttree_build() from an array of tokens and subsequently - * used by ttree_line_parse() to parse multiline text data. - */ -typedef struct ttree_s { - token_t *tok; /* Token */ - struct ttree_s *lt, *gt; /* < and > next node */ -} ttree_t; - -/* - * Note: req_tree[] and res_tree[] must be in ascending case insensitive - * order of the char[] strings used to initialize each element. - * - * See "nl7ctokreq.txt" and "nl7ctokres.txt" which are processed by - * "nl7ctokgen" to produce "nl7ctokgen.h" and included here. - */ - -#define INIT(s, t) {s, S##s, t} - -#include "nl7ctokgen.h" -static ttree_t *req_tree; -static ttree_t *res_tree; - -/* - * HTTP scheme private state: - */ - -typedef struct http_s { - boolean_t parsed; /* Response parsed */ - uint32_t major, minor; /* HTTP/major.minor */ - uint32_t headlen; /* HTTP header length */ - clock_t date; /* Response Date: */ - clock_t expire; /* Response Expire: */ - clock_t moddate; /* Request *Modified-Since date */ - enum tokid_e modtokid; /* Request *Modified-Since tokid */ - time_t lastmod; /* Response Last-Modified: */ - str_t accept; /* Request Accept: */ - str_t acceptchar; /* Request Accept-Charset: */ - str_t acceptenco; /* Request Accept-Encoding: */ - str_t acceptlang; /* Request Accept-Language: */ - str_t etag; /* Request/Response ETag: */ - str_t uagent; /* Request User-Agent: */ -} http_t; - -static kmem_cache_t *http_kmc; - -/* - * HTTP date routines, dow[] for day of the week, Dow[] for day of the - * week for the Unix epoch (i.e. day 0 is a Thu), months[] for the months - * of the year, and dom[] for day number of the year for the first day - * of each month (non leap year). - */ - -static char *dow[] = {"sunday", "monday", "tuesday", "wednesday", "thursday", - "friday", "saturday", 0}; - -static char *Dow[] = {"Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", 0}; - -static char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", - "Aug", "Sep", "Oct", "Nov", "Dec", 0}; - -static int dom[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - -/* - * http_date2time_t(const char *) - returns the time(2) value (i.e. - * the value 0 is Thu, 01 Jan 1970 00:00:00 GMT) for the following - * time formats used by HTTP request and response headers: - * - * 1) Sun, 07 Dec 1998 14:49:37 GMT ; RFC 822, updated by RFC 1123 - * 2) Sunday, 07-Dec-98 14:49:37 GMT ; RFC 850, obsoleted by RFC 1036 - * 3) Sun Nov 7 14:49:37 1998 ; ANSI C's asctime() format - * 4) 60 ; Time delta of N seconds - * - * On error a time_t value of -1 is returned. - * - * All dates are GMT (must be part of the date string for types - * 1 and 2 and not for type 1). - * - * Note, the given mstr_t pointed to by *sp will be modified. - */ - -static time_t -http_date2time_t(char *cp, char *ep) -{ - char *scp = cp; - time_t secs; - char **tpp; - char *tp; - char c, sc; - ssize_t n; - - ssize_t zeroleap = 1970 / 4 - 1970 / 100 + 1970 / 400; - ssize_t leap; - ssize_t year; - ssize_t month; - ssize_t day; - ssize_t hour; - ssize_t min; - ssize_t sec; - - /* Parse and skip day-of-week (we don't use it) */ - tpp = dow; - tp = *tpp; - n = 0; - while (cp < ep) { - c = *cp++; - if (c == ',' || c == ' ') - break; - c = tolower(c); - if (*tp == 0 || *tp != c) { - cp = scp; - if ((tp = *++tpp) == NULL) - break; - continue; - } - tp++; - } - if (cp == NULL) { - /* Not case 1-3, try 4 */ - while (cp < ep) { - c = *cp; - if (isdigit(c)) { - cp++; - n *= 10; - n += c - '0'; - continue; - } - /* An invalid date sytax */ - return (-1); - } - /* Case 4, delta from current time */ - return (gethrestime_sec() + n); - } - if (c == ',') { - /* Case 1 or 2, skip <SP> */ - if (cp == ep) - return (-1); - c = *cp++; - if (c != ' ') - return (-1); - /* Get day of the month */ - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - day = n; - /* Get day/month/year seperator */ - if (cp == ep) - return (-1); - sc = *cp++; - if (sc != ' ' && sc != '-') - return (-1); - /* Parse month */ - tpp = months; - tp = *tpp++; - scp = cp; - n = 0; - while (cp < ep) { - c = *cp; - if (c == sc) { - cp++; - break; - } - c = tolower(c); - if (*tp == 0 || tolower(*tp) != c) { - if ((tp = *tpp++) == NULL) - break; - cp = scp; - n++; - continue; - } - cp++; - tp++; - } - if (cp == NULL) - return (-1); - month = n; - /* Get year */ - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (sc == ' ') { - /* Case 1, get 2 more year digits */ - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - /* Get seperator char */ - if (cp == ep) - return (-1); - c = *cp; - if (c != ' ') - return (-1); - cp++; - } else { - /* - * Case 2, 2 digit year and as this is a so-called - * Unix date format and the begining of time was - * 1970 so we can extend this obsoleted date syntax - * past the year 1999 into the year 2038 for 32 bit - * machines and through 2069 for 64 bit machines. - */ - if (n > 69) - n += 1900; - else - n += 2000; - } - year = n; - /* Get GMT time */ - if (c != ' ') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - hour = n; - if (cp == ep) - return (-1); - c = *cp++; - if (c != ':') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - min = n; - if (cp == ep) - return (-1); - c = *cp++; - if (c != ':') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - sec = n; - if (cp == ep) - return (-1); - c = *cp++; - if (c != ' ') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (c != 'G') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (c != 'M') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (c != 'T') - return (-1); - } else { - /* case 3, parse month */ - sc = c; - tpp = months; - tp = *tpp++; - scp = cp; - n = 0; - while (cp < ep) { - c = *cp; - if (c == sc) { - cp++; - break; - } - c = tolower(c); - if (*tp == 0 || tolower(*tp) != c) { - if ((tp = *tpp++) == NULL) - break; - cp = scp; - n++; - continue; - } - cp++; - tp++; - } - if (cp == NULL) - return (-1); - month = n; - /* Get day of the month */ - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - day = n; - /* Skip <SP> */ - if (cp == ep) - return (-1); - c = *cp++; - if (c != ' ') - return (-1); - /* Get time */ - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - hour = n; - if (cp == ep) - return (-1); - c = *cp++; - if (c != ':') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - min = n; - if (cp == ep) - return (-1); - c = *cp++; - if (c != ':') - return (-1); - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - sec = n; - /* Skip <SP> */ - if (cp == ep) - return (-1); - c = *cp++; - if (c != ' ') - return (-1); - /* Get year */ - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n = c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - if (cp == ep) - return (-1); - c = *cp++; - if (! isdigit(c)) - return (-1); - n *= 10; - n += c - '0'; - year = n; - } - - /* Last, caclulate seconds since Unix day zero */ - leap = year; - if (month < 2) - leap--; - leap = leap / 4 - leap / 100 + leap / 400 - zeroleap; - secs = ((((year - 1970) * 365 + dom[month] + day - 1 + leap) * 24 - + hour) * 60 + min) * 60 + sec; - - return (secs); -} - -/* - * http_today(char *) - returns in the given char* pointer the current - * date in ascii with a format of (char [29]): - * - * Sun, 07 Dec 1998 14:49:37 GMT ; RFC 822, updated by RFC 1123 - */ - -static void -http_today(char *cp) -{ - ssize_t i; - char *fp; - - ssize_t leap; - ssize_t year; - ssize_t month; - ssize_t dow; - ssize_t day; - ssize_t hour; - ssize_t min; - ssize_t sec; - - /* Secs since Thu, 01 Jan 1970 00:00:00 GMT */ - time_t now = gethrestime_sec(); - - sec = now % 60; - now /= 60; - min = now % 60; - now /= 60; - hour = now % 24; - now /= 24; - dow = now % 7; - - year = 1970; - for (;;) { - if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) - day = 366; - else - day = 365; - if (now < day) - break; - now -= day; - year++; - } - - now++; - if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) - leap = 1; - else - leap = 0; - month = 11; - for (i = 11; i; i--) { - if (i < 2) - leap = 0; - if (now > dom[i] + leap) - break; - month--; - } - day = now - dom[i] - leap; - - fp = Dow[dow]; - *cp++ = *fp++; - *cp++ = *fp++; - *cp++ = *fp++; - *cp++ = ','; - *cp++ = ' '; - - i = day / 10; - *cp++ = '0' + i; - *cp++ = '0' + (day - i * 10); - *cp++ = ' '; - - fp = months[month]; - *cp++ = *fp++; - *cp++ = *fp++; - *cp++ = *fp++; - *cp++ = ' '; - - i = year / 1000; - *cp++ = '0' + i; - year -= i * 1000; - i = year / 100; - *cp++ = '0' + i; - year -= i * 100; - i = year / 10; - *cp++ = '0' + i; - year -= i * 10; - *cp++ = '0' + year; - *cp++ = ' '; - - i = hour / 10; - *cp++ = '0' + i; - *cp++ = '0' + (hour - i * 10); - *cp++ = ':'; - - i = min / 10; - *cp++ = '0' + i; - *cp++ = '0' + (min - i * 10); - *cp++ = ':'; - - i = sec / 10; - *cp++ = '0' + i; - *cp++ = '0' + (sec - i * 10); - *cp++ = ' '; - - *cp++ = 'G'; - *cp++ = 'M'; - *cp = 'T'; -} - -/* - * Given the ttree_t pointer "*t", parse the char buffer pointed to - * by "**cpp" of multiline text data up to the pointer "**epp", the - * pointer "*hash" points to the current text hash. - * - * If a match is found a pointer to the ttree_t token will be returned, - * "**cpp" will point to the next line, "**epp" will point to the first - * EOL char, "**hpp" will point to remainder of the parse data (if none, - * **hpp == **epp), and "*hash" will be updated. - * - * If no match, as above except "**hpp" points to the begining of the - * line and "*hash" wont be updated. - * - * If no EOL is found NULL is returned, "**epp" is set to NULL, no further - * calls can be made until additional data is ready and all arguments are - * reset. - * - * If EOH (i.e. an empty line) NULL is returned, "**hpp" is set to NULL, - * *cpp points to past EOH, no further calls can be made. - */ - -static token_t * -ttree_line_parse(ttree_t *t, char **cpp, char **epp, char **hpp, uint32_t *hash) -{ - char ca, cb; /* current line <=> parse node */ - - char *cp = *cpp; - char *ep = *epp; - - char *tp = t->tok->text; /* current parse text */ - char *sp = cp; /* saved *cp */ - - int parse; /* parse state */ - - uint32_t hv; /* hash value */ - - if (hash != NULL) - hv = *hash; - - /* Special case, check for EOH (i.e. empty line) */ - if (cp < ep) { - ca = *cp; - if (ca == '\n') { - /* End of header */ - *cpp = ++cp; - *hpp = NULL; - return (NULL); - } else if (ca == '\r') { - cp++; - if (cp < ep) { - ca = *cp; - if (ca == '\n') { - /* End of header */ - *cpp = ++cp; - *hpp = NULL; - return (NULL); - } - } - cp = *cpp; - } - } - while (cp < ep) { - /* Get next parse text char */ - cb = *tp; - if (cb != 0) { - /* Get next current line char */ - ca = *cp++; - /* Case insensitive */ - cb = tolower(cb); - ca = tolower(ca); - if (ca == cb) { - /* - * Char match, next char. - * - * Note, parse text can contain EOL chars. - */ - tp++; - continue; - } - if (ca == '\r' || ca == '\n') { - /* EOL, always go less than */ - t = t->lt; - } else if (ca < cb) { - /* Go less than */ - t = t->lt; - } else { - /* Go greater than */ - t = t->gt; - } - while (t != NULL && t->tok == NULL) { - /* Null node, so descend to < node */ - t = t->lt; - } - if (t != NULL) { - /* Initialize for next node compare */ - tp = t->tok->text; - cp = sp; - continue; - } - /* - * End of tree walk, no match, return pointer - * to the start of line then below find EOL. - */ - *hpp = *cpp; - } else { - /* - * End of token text, match, return pointer to - * the rest of header text then below find EOL. - */ - *hpp = cp; - } - /* - * Find end of line. Note, the HTTP line syntax supports - * implicit multi-line if the next line starts with a <SP> - * or <HT>. - */ - parse = 0; - while (cp < ep) { - ca = *cp; - if (parse == 0 && ca == '\r') { - *epp = cp; - parse = 1; - } else if (parse == 0 && ca == '\n') { - *epp = cp; - parse = 2; - } else if (parse == 1 && ca == '\n') { - parse = 2; - } else if (parse >= 2 && (ca == ' ' || ca == '\t')) { - parse++; - } else if (parse > 2) { - parse = 0; - } else if (parse == 2) { - break; - } else if (t != NULL && (t->tok->act & HASH) && - hash != NULL) { - CHASH(hv, ca); - } - cp++; - } - if (parse < 2) { - /* No EOL, not enough data */ - *epp = NULL; - return (t != NULL ? t->tok : NULL); - } - /* - * Return updated hash value (if any), update parse current - * pointer for next call (i.e. begin of next line), and last - * return pointer to the matching token_t. - */ - if (t != NULL && (t->tok->act & HASH) && hash != NULL) - *hash = hv; - *cpp = cp; - return (t != NULL ? t->tok : NULL); - } - /* - * End of parse text, ... - */ - *epp = NULL; - return (NULL); -} - -/* - * Given a NULL terminated array of token_t(s) ordered in ascending - * case insensitive order a binary tree is allocated and populated with - * pointers into the array and a pointer to the root node is returned. - * - * Todo, for maximum ttree parse efficiency needs to be path compressed, - * the function ttree_line_parse() handles the empty nodes correctly. - */ -static ttree_t * -ttree_build(token_t *list, int sz) -{ - ttree_t *treev; - int max, lvl, inc, ix; - - /* calc the size of the tree */ - for (max = 1; max < sz; max <<= 1) - ; - /* allocate the tree */ - treev = kmem_alloc(sizeof (*treev) * (max - 1), KM_SLEEP); - - /* walk the tree and populate from list vector */ - lvl = max; - while (lvl >>= 1) { - inc = lvl >> 1; - for (ix = lvl; ix < max; ix += lvl << 1) { - if (ix <= sz) { - treev[ix - 1].tok = &list[ix - 1]; - } else { - treev[ix - 1].tok = 0; - } - if (inc) { - treev[ix - 1].lt = &treev[ix - inc - 1]; - treev[ix - 1].gt = &treev[ix + inc - 1]; - } else { - treev[ix - 1].lt = 0; - treev[ix - 1].gt = 0; - } - } - } - - return (&treev[(max >> 1) - 1]); -} - -void -nl7c_http_init(void) -{ - int n; - - http_kmc = kmem_cache_create("NL7C_http_kmc", - sizeof (http_t), 0, NULL, NULL, NULL, NULL, NULL, 0); - - req_tree = ttree_build(tokreq, tokreq_cnt - 1); - res_tree = ttree_build(tokres, tokres_cnt - 1); - - n = sizeof (Shttp_conn_cl) - 1; - http_conn_cl = allocb_wait(n, BPRI_HI, STR_NOSIG, NULL); - bcopy(Shttp_conn_cl, http_conn_cl->b_rptr, n); - http_conn_cl->b_wptr += n; - - n = sizeof (Shttp_conn_ka) - 1; - http_conn_ka = allocb_wait(n, BPRI_HI, STR_NOSIG, NULL); - bcopy(Shttp_conn_ka, http_conn_ka->b_rptr, n); - http_conn_ka->b_wptr += n; -} - -void -nl7c_http_free(void *arg) -{ - http_t *http = arg; - - kmem_cache_free(http_kmc, http); -} - -#define STR_T_NOTCMP_OPT(a, b, m) ( \ - a->m.cp && b->m.cp && \ - ((a->m.ep - a->m.cp) != (b->m.ep - b->m.cp) || \ - strncmp(a->m.cp, b->m.cp, (b->m.ep - b->m.cp)))) - -#define STR_T_NOTCMP(a, b, m) ( \ - a->m.cp && ! b->m.cp || \ - b->m.cp && ! a->m.cp || \ - STR_T_NOTCMP_OPT(a, b, m)) - -boolean_t -nl7c_http_cmp(void *arg1, void *arg2) -{ - http_t *httpa = arg1; /* Response */ - http_t *httpb = arg2; /* Request */ - - if (httpa->major != httpb->major || - httpa->minor != httpb->minor || - STR_T_NOTCMP(httpa, httpb, accept) || - STR_T_NOTCMP(httpa, httpb, acceptchar) || - STR_T_NOTCMP(httpa, httpb, acceptenco) || - STR_T_NOTCMP(httpa, httpb, acceptlang) || - STR_T_NOTCMP_OPT(httpa, httpb, etag)) - return (B_FALSE); - return (B_TRUE); -} - -/* - * In-line HTTP responses: - */ - -static char http_resp_304[] = - "HTTP/#.# 304 Not Modified\r\n" - "Date: #############################\r\n" - "Server: NCA/#.# (Solaris)\r\n"; - -static char http_resp_412[] = - "HTTP/#.# 412 Precondition Failed\r\n" - "Date: #############################\r\n" - "Server: NCA/#.# (Solaris)\r\n"; - -static uri_desc_t * -http_mkresponse(uri_desc_t *req, uri_desc_t *res, char *proto, int sz) -{ - http_t *qhttp = req->scheme; - http_t *shttp = res->scheme; - uri_desc_t *uri = kmem_cache_alloc(nl7c_uri_kmc, KM_SLEEP); - char *alloc; - char *cp; - char *ep = &proto[sz]; - uri_rd_t *rdp; - int cnt; - - char hdr_etag[] = "ETag: "; - - /* Any optional header(s) */ - if (shttp->etag.cp != NULL) { - /* Response has an ETag:, count it */ - sz += sizeof (hdr_etag) - 1 + - (shttp->etag.ep - shttp->etag.cp) + 2; - } - sz += 2; - alloc = kmem_alloc(sz, KM_SLEEP); - - /* Minimum temp uri initialization as needed by uri_response() */ - REF_INIT(uri, 1, nl7c_uri_inactive, nl7c_uri_kmc); - uri->hash = URI_TEMP; - uri->tail = NULL; - uri->scheme = NULL; - uri->reqmp = NULL; - uri->count = 0; - cv_init(&uri->waiting, NULL, CV_DEFAULT, NULL); - mutex_init(&uri->proclock, NULL, MUTEX_DEFAULT, NULL); - - URI_RD_ADD(uri, rdp, sz, -1); - rdp->data.kmem = alloc; - atomic_add_64(&nl7c_uri_bytes, sz); - - cp = alloc; - if (qhttp->major == 1) { - /* - * Full response format. - * - * Copy to first sub char '#'. - */ - while (proto < ep) { - if (*proto == '#') - break; - *cp++ = *proto++; - } - - /* Process the HTTP version substitutions */ - if (*proto != '#') goto bad; - *cp++ = '0' + qhttp->major; - proto++; - while (proto < ep) { - if (*proto == '#') - break; - *cp++ = *proto++; - } - if (*proto != '#') goto bad; - *cp++ = '0' + qhttp->minor; - proto++; - - /* Copy to the next sub char '#' */ - while (proto < ep) { - if (*proto == '#') - break; - *cp++ = *proto++; - } - - /* Process the "Date: " substitution */ - if (*proto != '#') goto bad; - http_today(cp); - - /* Skip to the next nonsub char '#' */ - while (proto < ep) { - if (*proto != '#') - break; - cp++; - proto++; - } - - /* Copy to the next sub char '#' */ - while (proto < ep) { - if (*proto == '#') - break; - *cp++ = *proto++; - } - - /* Process the NCA version substitutions */ - if (*proto != '#') goto bad; - *cp++ = '0' + nca_major_version; - proto++; - while (proto < ep) { - if (*proto == '#') - break; - *cp++ = *proto++; - } - if (*proto != '#') goto bad; - *cp++ = '0' + nca_minor_version; - proto++; - - /* Copy remainder of HTTP header */ - while (proto < ep) { - *cp++ = *proto++; - } - } else { - goto bad; - } - /* Any optional header(s) */ - if (shttp->etag.cp != NULL) { - /* Response has an ETag:, add it */ - cnt = sizeof (hdr_etag) - 1; - bcopy(hdr_etag, cp, cnt); - cp += cnt; - cnt = (shttp->etag.ep - shttp->etag.cp); - bcopy(shttp->etag.cp, cp, cnt); - cp += cnt; - *cp++ = '\r'; - *cp++ = '\n'; - } - /* Last, add empty line */ - uri->eoh = cp; - *cp++ = '\r'; - *cp = '\n'; - - return (uri); - -bad: - /* - * Free any resources allocated here, note that while we could - * use the uri_inactive() to free the uri by doing a REF_RELE() - * we instead free it here as the URI may be in less then a fully - * initialized state. - */ - kmem_free(alloc, sz); - kmem_cache_free(nl7c_uri_kmc, uri); - return (NULL); -} - -uri_desc_t * -nl7c_http_cond(uri_desc_t *req, uri_desc_t *res) -{ - http_t *qhttp = req->scheme; - time_t qdate = qhttp->moddate; - http_t *shttp = res->scheme; - time_t sdate = shttp->lastmod == -1 ? shttp->date : shttp->lastmod; - uri_desc_t *uri; - - if (qhttp->modtokid == Qhdr_If_Modified_Since && - sdate != -1 && qdate != -1 && sdate <= qdate) { - /* - * Request is If-Modified-Since: and both response - * and request dates are valid and response is the - * same age as request so return a 304 response uri - * instead of the cached response. - */ - nl7c_http_cond_304++; - uri = http_mkresponse(req, res, http_resp_304, - sizeof (http_resp_304) - 1); - if (uri != NULL) { - /* New response uri */ - REF_RELE(res); - return (uri); - } - return (res); - } else if (qhttp->modtokid == Qhdr_If_Unmodified_Since && - sdate != -1 && qdate != -1 && sdate >= qdate) { - /* - * Request is If-Unmodified-Since: and both response - * and request dates are valid and response is not the - * same age as the request so return a 412 response - * uri instead of the cached response. - */ - nl7c_http_cond_412++; - uri = http_mkresponse(req, res, http_resp_412, - sizeof (http_resp_412) - 1); - if (uri != NULL) { - /* New response uri */ - REF_RELE(res); - return (uri); - } - return (res); - } - /* - * No conditional response meet or unknown type or no - * valid dates so just return the original uri response. - */ - return (res); -} - -/* - * Return the appropriate HTTP connection persist header - * based on the request HTTP persistent header state. - */ - -mblk_t * -nl7c_http_persist(struct sonode *so) -{ - uint64_t flags = SOTOTPI(so)->sti_nl7c_flags & NL7C_SCHEMEPRIV; - mblk_t *mp; - - if (flags & HTTP_CONN_CL) - mp = dupb(http_conn_cl); - else if (flags & HTTP_CONN_KA) - mp = dupb(http_conn_ka); - else - mp = NULL; - return (mp); -} - -/* - * Parse the buffer *p of size len and update the uri_desc_t *uri and our - * http_t *http with the results. - */ - -boolean_t -nl7c_http_request(char **cpp, char *ep, uri_desc_t *uri, struct sonode *so) -{ - sotpi_info_t *sti = SOTOTPI(so); - http_t *http = kmem_cache_alloc(http_kmc, KM_SLEEP); - char *cp = *cpp; - char *hp; - char *scp, *sep; - char *HTTP = "HTTP/"; - token_t *match; - boolean_t persist = B_FALSE; - - ASSERT(cp <= ep); - - if (cp == ep) { - goto bad; - } - /* - * Initialize any uri_desc_t and/or http_t members. - */ - uri->scheme = (void *)http; - uri->auth.cp = NULL; - uri->auth.ep = NULL; - uri->resplen = URI_LEN_NOVALUE; - uri->respclen = URI_LEN_NOVALUE; - uri->eoh = NULL; - uri->nocache = B_FALSE; - uri->conditional = B_FALSE; - http->parsed = B_FALSE; - http->accept.cp = NULL; - http->acceptchar.cp = NULL; - http->acceptenco.cp = NULL; - http->acceptlang.cp = NULL; - http->etag.cp = NULL; - http->uagent.cp = NULL; - http->date = -1; - http->expire = -1; - http->lastmod = -1; - if (*cp == '\r') { - /* - * Special case for a Request-Line without an HTTP version, - * assume it's an old style, i.e. HTTP version 0.9 request. - */ - http->major = 0; - http->minor = 9; - goto got_version; - } - /* - * Skip URI path delimiter, must be a <SP>. - */ - if (*cp++ != ' ') - /* Unkown or bad Request-Line format, just punt */ - goto bad; - /* - * The URI parser has parsed through the URI and the <SP> - * delimiter, parse the HTTP/N.N version - */ - while (cp < ep && *HTTP == *cp) { - HTTP++; - cp++; - } - if (*HTTP != 0) { - if (cp == ep) - goto more; - goto bad; - } - if (cp == ep) - goto more; - if (*cp < '0' || *cp > '9') - goto bad; - http->major = *cp++ - '0'; - if (cp == ep) - goto more; - if (*cp++ != '.') - goto bad; - if (cp == ep) - goto more; - if (*cp < '0' || *cp > '9') - goto bad; - http->minor = *cp++ - '0'; - if (cp == ep) - goto more; - -got_version: - - if (*cp++ != '\r') - goto bad; - if (cp == ep) - goto more; - if (*cp++ != '\n') - goto bad; - /* - * Initialize persistent state based on HTTP version. - */ - if (http->major == 1) { - if (http->minor >= 1) { - /* 1.1 persistent by default */ - persist = B_TRUE; - } else { - /* 1.0 isn't persistent by default */ - persist = B_FALSE; - } - } else if (http->major == 0) { - /* Before 1.0 no persistent connections */ - persist = B_FALSE; - } else { - /* >= 2.0 not supported (yet) */ - goto bad; - } - /* - * Parse HTTP headers through the EOH - * (End Of Header, i.e. an empty line). - */ - for (sep = ep; cp < ep; ep = sep) { - /* Get the next line */ - scp = cp; - match = ttree_line_parse(req_tree, &cp, &ep, &hp, &uri->hvalue); - if (match != NULL) { - if (match->act & QUALIFIER) { - /* - * Header field text is used to qualify this - * request/response, based on qualifier type - * optionally convert and store *http. - */ - char c; - int n = 0; - time_t secs; - - ASSERT(hp != NULL && ep != NULL); - - if (match->act & NUMERIC) { - while (hp < ep) { - c = *hp++; - if (! isdigit(c)) - goto bad; - n *= 10; - n += c - '0'; - } - } else if (match->act & DATE) { - secs = http_date2time_t(hp, ep); - } - switch (match->tokid) { - - case Qhdr_Accept_Charset: - http->acceptchar.cp = hp; - http->acceptchar.ep = ep; - break; - - case Qhdr_Accept_Encoding: - http->acceptenco.cp = hp; - http->acceptenco.ep = ep; - break; - - case Qhdr_Accept_Language: - http->acceptlang.cp = hp; - http->acceptlang.ep = ep; - break; - - case Qhdr_Accept: - http->accept.cp = hp; - http->accept.ep = ep; - break; - - case Qhdr_Authorization: - goto pass; - - case Qhdr_Connection_close: - persist = B_FALSE; - break; - - case Qhdr_Connection_Keep_Alive: - persist = B_TRUE; - break; - - case Qhdr_Date: - http->date = secs; - break; - - case Qhdr_ETag: - http->etag.cp = hp; - http->etag.ep = ep; - break; - - case Qhdr_Host: - uri->auth.cp = hp; - uri->auth.ep = ep; - break; - - case Qhdr_If_Modified_Since: - case Qhdr_If_Unmodified_Since: - http->moddate = secs; - http->modtokid = match->tokid; - uri->conditional = B_TRUE; - break; - - case Qhdr_Keep_Alive: - persist = B_TRUE; - break; - - case Qhdr_User_Agent: - http->uagent.cp = hp; - http->uagent.ep = ep; - break; - - default: - break; - - }; - } - if (match->act & FILTER) { - /* - * Filter header, do a copyover the header - * text, guarenteed to be at least 1 byte. - */ - char *cop = scp; - int n = (ep - cop) - 1; - char filter[] = "NL7C-Filtered"; - - n = MIN(n, sizeof (filter) - 1); - if (n > 0) - bcopy(filter, cop, n); - cop += n; - ASSERT(cop < ep); - *cop++ = ':'; - while (cop < ep) - *cop++ = ' '; - } - if (match->act & NOCACHE) { - uri->nocache = B_TRUE; - } - } else if (hp == NULL) { - goto done; - } else if (ep == NULL) { - goto more; - } - } - /* No EOH found */ - goto more; - -done: - /* - * Initialize socket persist state and response persist type - * flag based on the persist state of the request headers. - * - */ - if (persist) - sti->sti_nl7c_flags |= NL7C_SOPERSIST; - else - sti->sti_nl7c_flags &= ~NL7C_SOPERSIST; - - if (http->major == 1) { - sti->sti_nl7c_flags &= ~NL7C_SCHEMEPRIV; - if (http->minor >= 1) { - if (! persist) - sti->sti_nl7c_flags |= HTTP_CONN_CL; - } else { - if (persist) - sti->sti_nl7c_flags |= HTTP_CONN_KA; - else - sti->sti_nl7c_flags |= HTTP_CONN_CL; - } - } - /* - * Last, update parse consumed text pointer. - */ - *cpp = cp; - return (B_TRUE); - -pass: - *cpp = NULL; - return (B_TRUE); - -bad: - *cpp = NULL; -more: - return (B_FALSE); -} - -boolean_t -nl7c_http_response(char **cpp, char *ep, uri_desc_t *uri, struct sonode *so) -{ - sotpi_info_t *sti = SOTOTPI(so); - http_t *http = uri->scheme; - char *cp = *cpp; - char *hp; - char *scp, *sep; - char *HTTP = "HTTP/"; - int status = 0; - token_t *match; -#ifdef NOT_YET - uint32_t major, minor; -#endif - boolean_t nocache = B_FALSE; - boolean_t persist = B_FALSE; - - ASSERT(http != NULL); - - if (http->parsed) { - if (uri->respclen != URI_LEN_NOVALUE) { - /* Chunked response */ - sep = ep; - goto chunked; - } - /* Already parsed, nothing todo */ - return (B_TRUE); - } - - /* - * Parse the HTTP/N.N version. Note, there's currently no use - * for the actual response major nor minor values as only the - * request values are used. - */ - while (cp < ep && *HTTP == *cp) { - HTTP++; - cp++; - } - if (*HTTP != 0) { - if (cp == ep) - goto more; - goto bad; - } - if (cp == ep) - goto more; - - if (*cp < '0' || *cp > '9') - goto bad; -#ifdef NOT_YET - major = *cp++ - '0'; -#else - cp++; -#endif - - if (cp == ep) - goto more; - if (*cp++ != '.') - goto bad; - if (cp == ep) - goto more; - if (*cp < '0' || *cp > '9') - goto bad; -#ifdef NOT_YET - minor = *cp++ - '0'; -#else - cp++; -#endif - - if (cp == ep) - goto more; - -got_version: - - /* - * Get the response code. - */ - if (*cp++ != ' ') - goto bad; - if (cp == ep) - goto more; - - do { - if (*cp == ' ') - break; - if (*cp < '0' || *cp > '9') - goto bad; - if (status) - status *= 10; - status += *cp++ - '0'; - } while (cp < ep); - - switch (status) { - case 200: - /* - * The only response status we continue to process. - */ - break; - case 304: - nl7c_http_response_304++; - nocache = B_TRUE; - uri->resplen = 0; - goto pass; - case 307: - nl7c_http_response_307++; - nocache = B_TRUE; - uri->resplen = 0; - goto pass; - case 400: - nl7c_http_response_400++; - /* - * Special case some response status codes, just mark - * as nocache and no response length and pass on the - * request/connection. - */ - nocache = B_TRUE; - uri->resplen = 0; - goto pass; - default: - /* - * All other response codes result in a parse failure. - */ - goto bad; - } - - /* - * Initialize persistent state based on request HTTP version. - */ - if (http->major == 1) { - if (http->minor >= 1) { - /* 1.1 persistent by default */ - persist = B_TRUE; - } else { - /* 1.0 isn't persistent by default */ - persist = B_FALSE; - } - } else if (http->major == 0) { - /* Before 1.0 no persistent connections */ - persist = B_FALSE; - } else { - /* >= 2.0 not supported (yet) */ - goto bad; - } - - /* - * Parse HTTP headers through the EOH - * (End Of Header, i.e. an empty line). - */ - for (sep = ep; cp < ep; ep = sep) { - /* Get the next line */ - scp = cp; - match = ttree_line_parse(res_tree, &cp, &ep, &hp, NULL); - if (match != NULL) { - if (match->act & QUALIFIER) { - /* - * Header field text is used to qualify this - * request/response, based on qualifier type - * optionally convert and store *http. - */ - char c; - int n = 0; - time_t secs; - - ASSERT(hp != NULL && ep != NULL); - - if (match->act & NUMERIC) { - while (hp < ep) { - c = *hp++; - if (match->act & HEX) { - hd2i(c, n); - if (n == -1) - goto bad; - } else { - if (! isdigit(c)) - goto bad; - n *= 10; - n += c - '0'; - } - } - } else if (match->act & DATE) { - secs = http_date2time_t(hp, ep); - } - switch (match->tokid) { - - case Shdr_Cache_Control_Max_Age: - break; - - case Shdr_Cache_Control_No_Cache: - nocache = B_TRUE; - break; - - case Shdr_Cache_Control_No_Store: - nocache = B_TRUE; - break; - - case Shdr_Connection_close: - persist = B_FALSE; - break; - - case Shdr_Connection_Keep_Alive: - persist = B_TRUE; - break; - - case Shdr_Chunked: - uri->respclen = 0; - uri->resplen = 0; - nl7c_http_response_chunked++; - break; - - case Shdr_Content_Length: - if (uri->respclen == URI_LEN_NOVALUE) - uri->resplen = n; - break; - - case Shdr_Date: - http->date = secs; - break; - - case Shdr_ETag: - http->etag.cp = hp; - http->etag.ep = ep; - break; - - case Shdr_Expires: - http->expire = secs; - break; - - case Shdr_Keep_Alive: - persist = B_TRUE; - break; - - case Shdr_Last_Modified: - http->lastmod = secs; - break; - - case Shdr_Set_Cookie: - nocache = B_TRUE; - break; - - case Shdr_Server: - break; - - default: - nocache = B_TRUE; - break; - }; - } - if (match->act & FILTER) { - /* - * Filter header, do a copyover the header - * text, guarenteed to be at least 1 byte. - */ - char *cop = scp; - int n = (ep - cop) - 1; - char filter[] = "NL7C-Filtered"; - - n = MIN(n, sizeof (filter) - 1); - if (n > 0) - bcopy(filter, cop, n); - cop += n; - ASSERT(cop < ep); - *cop++ = ':'; - while (cop < ep) - *cop++ = ' '; - } - if (match->act & NOCACHE) { - nocache = B_TRUE; - } - } else if (hp == NULL) { - uri->eoh = scp; - goto done; - } else if (ep == NULL) { - goto more; - } - } - /* No EOH found */ - goto more; - -done: - /* Parse completed */ - http->parsed = B_TRUE; - /* Save the HTTP header length */ - http->headlen = (cp - *cpp); - if (uri->respclen == URI_LEN_NOVALUE) { - if (uri->resplen == URI_LEN_NOVALUE) { - nl7c_http_response_pass1++; - goto pass; - } - } - /* Add header length to URI response length */ - uri->resplen += http->headlen; - - /* Set socket persist state */ - if (persist) - sti->sti_nl7c_flags |= NL7C_SOPERSIST; - else - sti->sti_nl7c_flags &= ~NL7C_SOPERSIST; - - if (http->major == 1) { - sti->sti_nl7c_flags &= ~NL7C_SCHEMEPRIV; - if (http->minor >= 1) { - if (! persist) - sti->sti_nl7c_flags |= HTTP_CONN_CL; - } else { - if (persist) - sti->sti_nl7c_flags |= HTTP_CONN_KA; - else - sti->sti_nl7c_flags |= HTTP_CONN_CL; - } - } - - if (nocache) { - /* - * Response not to be cached, only post response - * processing code common to both non and cached - * cases above here and code for the cached case - * below. - * - * Note, chunked transfer processing is the last - * to be done. - */ - uri->nocache = B_TRUE; - if (uri->respclen != URI_LEN_NOVALUE) { - /* Chunked response */ - goto chunked; - } - /* Nothing more todo */ - goto parsed; - } - - if (http->expire != -1 && http->date != -1) { - if (http->expire <= http->date) { - /* ??? just pass */ - nl7c_http_response_pass2++; - goto pass; - } - /* Have a valid expire and date so calc an lbolt expire */ - uri->expire = ddi_get_lbolt() + SEC_TO_TICK(http->expire - - http->date); - } else if (nl7c_uri_ttl != -1) { - /* No valid expire speced and we have a TTL */ - uri->expire = ddi_get_lbolt() + SEC_TO_TICK(nl7c_uri_ttl); - } - -chunked: - /* - * Chunk transfer parser and processing, a very simple parser - * is implemented here for the common case were one, or more, - * complete chunk(s) are passed in (i.e. length header + body). - * - * All other cases are passed. - */ - scp = cp; - while (uri->respclen != URI_LEN_NOVALUE && cp < sep) { - if (uri->respclen == URI_LEN_CONSUMED) { - /* Skip trailing "\r\n" */ - if (cp == sep) - goto more; - if (*cp++ != '\r') - goto bad; - if (cp == sep) - goto more; - if (*cp++ != '\n') - goto bad; - uri->respclen = 0; - } - if (uri->respclen == 0) { - /* Parse a chunklen "[0-9A-Fa-f]+" */ - char c; - int n = 0; - - if (cp == sep) - goto more; - nl7c_http_response_chunkparse++; - while (cp < sep && (c = *cp++) != '\r') { - hd2i(c, n); - if (n == -1) - goto bad; - } - if (cp == sep) - goto more; - if (*cp++ != '\n') - goto bad; - uri->respclen = n; - if (n == 0) { - /* Last chunk, skip trailing "\r\n" */ - if (cp == sep) - goto more; - if (*cp++ != '\r') - goto bad; - if (cp == sep) - goto more; - if (*cp++ != '\n') - goto bad; - uri->respclen = URI_LEN_NOVALUE; - break; - } - } - if (uri->respclen > 0) { - /* Consume some bytes for the current chunk */ - uint32_t sz = (sep - cp); - - if (sz > uri->respclen) - sz = uri->respclen; - uri->respclen -= sz; - cp += sz; - if (uri->respclen == 0) { - /* End of chunk, skip trailing "\r\n" */ - if (cp == sep) { - uri->respclen = URI_LEN_CONSUMED; - goto more; - } - if (*cp++ != '\r') - goto bad; - if (cp == sep) - goto more; - if (*cp++ != '\n') - goto bad; - if (cp == sep) - goto more; - } - } - } - uri->resplen += (cp - scp); - -parsed: - *cpp = cp; - return (B_TRUE); - -pass: - *cpp = NULL; - return (B_TRUE); - -bad: - *cpp = NULL; - return (B_FALSE); - -more: - uri->resplen += (cp - scp); - *cpp = cp; - return (B_FALSE); -} - -boolean_t -nl7c_http_log(uri_desc_t *quri, uri_desc_t *suri, nca_request_log_t *req, - char **wp, char **pep, uint32_t *off) -{ - http_t *qhttp = quri->scheme; - http_t *shttp = suri->scheme; - int sz; - - if (qhttp->uagent.cp != NULL) { - sz = (qhttp->uagent.ep - qhttp->uagent.cp); - if ((*wp + sz + 1) >= *pep) goto full; - bcopy(qhttp->uagent.cp, *wp, sz); - *wp += sz; - *(*wp)++ = 0; - sz++; - req->useragent_len = sz; - req->useragent = *off; - *off += sz; - } - - req->response_len -= (uint_t)shttp->headlen; - - req->method = NCA_GET; - - if (qhttp->major == 1) { - if (qhttp->minor == 0) { - req->version = HTTP_1_0; - } else if (qhttp->minor == 1) { - req->version = HTTP_1_1; - } else { - req->version = HTTP_0_0; - } - } else if (qhttp->major == 0) { - req->version = HTTP_0_9; - } else { - req->version = HTTP_0_0; - } - - return (B_FALSE); - -full: - return (B_TRUE); -} diff --git a/usr/src/uts/common/fs/sockfs/nl7clogd.c b/usr/src/uts/common/fs/sockfs/nl7clogd.c deleted file mode 100644 index 4dd40abf2d..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7clogd.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/sysmacros.h> -#include <sys/callb.h> -#include <sys/fcntl.h> -#include <sys/filio.h> -#include <sys/pathname.h> -#include <sys/cpuvar.h> -#include <sys/promif.h> -#include <fs/sockfs/nl7c.h> -#include <fs/sockfs/nl7curi.h> - -#include <inet/nca/ncadoorhdr.h> -#include <inet/nca/ncalogd.h> - -extern boolean_t nl7c_logd_enabled; -extern boolean_t nl7c_logd_started; -extern boolean_t nl7c_logd_cycle; - -extern void nl7clogd_startup(void); - -extern boolean_t nl7c_http_log(uri_desc_t *, uri_desc_t *, - nca_request_log_t *, char **, char **, uint32_t *); - -static void logit_flush(void *); - -/* - * NL7C reuses the NCA logging scheme, the directory "/var/nca" contains - * the symlink "current" to 1 of up to 16 NCA BLF logging files, by default - * a single logging file "log", optionally paths of up to 16 log files can - * be specified via ncalogd.conf(5), note that these log files need not be - * in the "/var/nca" directory. - * - * NL7C reuses the NCA logging APIs defined in <inet/nca/ncalogd.h>, at - * some future date (when NCA is deprecated or improvements are needed) - * these need to be moved into NL7C. - * - * NL7C implements logging differently in 2 ways, 1st the initialization - * is handled completely in the kernel by NL7C when it's enabled vs NCA - * when the kmod was loaded, 2nd a simple worker thread with a FIFO queue - * is used to process log_buf_t's instead of a squeue_t (this is done as - * squeue_t's are private to NCA and IP at some future date we may us an - * IP squeue_t): - * - * logd_t - used by various functions to manage a singly linked - * grounded list of log_buf_t's and it's worker thread. - */ - -typedef struct logd_s { - log_buf_t *head; - log_buf_t *tail; - kthread_t *worker; - kcondvar_t wait; - kmutex_t lock; -} logd_t; - -/* - * In-kernel logging: - * - * nl7c_logbuf_max - tunable for the number of preallocated next - * log_buf_t(s) for use by log_buf_alloc(), note if the value is - * 0 (the default) then max_cpus worth will be allocated. - * - * logd - global logd_t used to post log_buf_t's too. - * - * log - global current log_buf_t that logit() logs too. - * - * logv[] - vector of available next logbuf(s) such that when - * logbuf is filled another can be used while being processed by - * the logger() and kmem_cache_alloc() of a replacement is done. - * - * logvcnt - count of logv[] vector element(s) and the index - * plus 1 of the next logbuf. - * - * log_buf_kmc - the kmem_cache to alloc/free log_buf_t's from/to. - * - * fio - the global nca_fio_t used to manage file i/o to a logfile. - * - * dir - path to the directory where the current logfile symlink - * is created and the default directory for logfile(s). - * - * symlink - name of the logfile symlink. - * - * symlink_path - path to the logfile symlink. - * - * log_lock - the kmutex_t used to guarantee atomic access of - * all of the above. - * - * flush_tid - logit_flush() timeout id. - * - * LOGBUFV_ALLOC() - macro used to add log_buf_t(s) to logv[]. - */ - -int nl7c_logbuf_max = 0; -static logd_t logd; -static log_buf_t *log = NULL; -static log_buf_t **logv = NULL; -static int logvcnt = 0; -static kmem_cache_t *log_buf_kmc; -static nca_fio_t fio; -static caddr_t dir = "/var/nca/"; -static caddr_t symlink = "current"; -static caddr_t symlink_dir = "/var/nca"; -static caddr_t symlink_path = "/var/nca/current"; - -static kmutex_t log_lock; - -static timeout_id_t flush_tid; - -#define LOGBUFV_ALLOC(kmflag) { \ - log_buf_t *_p; \ - \ - ASSERT(mutex_owned(&log_lock)); \ - while (logvcnt < nl7c_logbuf_max) { \ - /*CONSTCOND*/ \ - if (kmflag == KM_SLEEP) \ - mutex_exit(&log_lock); \ - _p = kmem_cache_alloc(log_buf_kmc, kmflag); \ - /*CONSTCOND*/ \ - if (kmflag == KM_SLEEP) { \ - mutex_enter(&log_lock); \ - if (logvcnt == nl7c_logbuf_max) { \ - mutex_exit(&log_lock); \ - kmem_cache_free(log_buf_kmc, _p); \ - mutex_enter(&log_lock); \ - break; \ - } \ - } else { \ - if (_p == NULL) { \ - break; \ - } \ - } \ - logv[logvcnt++] = _p; \ - } \ -} - -/* - * Exports for inet/nca/ncaddi.c: - */ - -nca_fio_t *nl7c_logd_fio = &fio; - -static void -log_buf_alloc(int kmflag) -{ - nca_log_buf_hdr_t *hdr; - static ulong_t seq = 0; - - ASSERT(mutex_owned(&log_lock)); - - if (logvcnt == 0) { - /* - * No logv[] to use for the new log global logbuf, - * try to allocate one or more before giving up. - */ - LOGBUFV_ALLOC(kmflag); - if (logvcnt == 0) { - /* No joy, just give up. */ - log = NULL; - return; - } - } - log = logv[--logvcnt]; - - log->size = NCA_DEFAULT_LOG_BUF_SIZE; - log->cur_pos = sizeof (*hdr); - - hdr = (nca_log_buf_hdr_t *)&log->buffer; - hdr->nca_loghdr.nca_version = NCA_LOG_VERSION1; - hdr->nca_loghdr.nca_op = log_op; - hdr->nca_logstats.n_log_size = NCA_DEFAULT_LOG_BUF_SIZE - sizeof (*hdr); - hdr->nca_logstats.n_log_recs = 0; - hdr->nca_logstats.n_log_upcall = seq++; - - /* Try to allocate for at least the one we just used */ - LOGBUFV_ALLOC(kmflag); -} - -static void -logd_off() -{ - ; -} - -static void -logd_log_write(kmutex_t *lock, log_buf_t *lbp) -{ - nca_log_buf_hdr_t *hdr = (nca_log_buf_hdr_t *)lbp->buffer; - nca_log_stat_t *sts = &hdr->nca_logstats; - int size = sts->n_log_size + sizeof (*hdr); - vnode_t *vp; - uio_t uio; - iovec_t iov; - int ret; - boolean_t noretry = B_FALSE; - vattr_t attr; - - if (size & (DEV_BSIZE - 1)) { - /* - * Not appropriately sized for directio(), - * add some filler so it is. - */ - sts->n_log_size += DEV_BSIZE - (size & (DEV_BSIZE - 1)); - size = sts->n_log_size + sizeof (*hdr); - } -retry: - if (nca_fio_offset(&fio) + size <= nca_fio_size(&fio)) { - /* - * Room in the current log file so write the logbuf out, - * exit the logd lock while doing the i/o as to not block - * queuing. - */ - mutex_exit(lock); - - vp = nca_fio_vp(&fio); - (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); - iov.iov_base = lbp->buffer; - iov.iov_len = size; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_fmode = 0; - uio.uio_loffset = (u_offset_t)nca_fio_offset(&fio); - uio.uio_llimit = curproc->p_fsz_ctl; - uio.uio_resid = size; - ret = VOP_WRITE(vp, &uio, 0, kcred, NULL); - VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); - if (ret != 0) { - if (ret == EFBIG) { - /* - * Out of space for this file, - * retry with the next. - */ - nca_fio_size(&fio) = nca_fio_offset(&fio); - if (noretry) { - nl7c_logd_enabled = B_FALSE; - goto done; - } else - goto next; - } - } - nca_fio_offset(&fio) = uio.uio_loffset; - - mutex_enter(lock); - goto done; - } - - /* - * Current logfile doesn't have sufficient space - * so move on to next file (if any). - */ -next: - mutex_exit(lock); - /* Close current file */ - ret = VOP_CLOSE(nca_fio_vp(&fio), FCREAT|FWRITE|FAPPEND|FTRUNC, - 1, (offset_t)0, kcred, NULL); - nca_fio_vp(&fio) = NULL; - if (ret) { - cmn_err(CE_WARN, "nl7c_logd: close of %s failed (error %d)", - nca_fio_name(&fio), ret); - nl7c_logd_enabled = B_FALSE; - logd_off(); - return; - } - - /* Go to next file */ - nca_fio_ix(&fio)++; - if (nca_fio_ix(&fio) == nca_fio_cnt(&fio)) { - /* - * We have reached the last file. If cycling - * is not on, disable logging and bailout. - */ - if (nl7c_logd_cycle) { - /* Start from the first file */ - nca_fio_ix(&fio) = 0; - } else { - nca_fio_ix(&fio)--; - nl7c_logd_enabled = B_FALSE; - logd_off(); - return; - } - } - - /* Open the next log file */ - ret = vn_open(nca_fio_name(&fio), UIO_SYSSPACE, FCREAT|FWRITE|FTRUNC, - 0600, &nca_fio_vp(&fio), 0, 0); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd: vn_open of %s failed (error %d)", - nca_fio_name(&fio), ret); - nl7c_logd_enabled = B_FALSE; - logd_off(); - return; - } - - /* Turn on directio */ - (void) VOP_IOCTL(nca_fio_vp(&fio), _FIODIRECTIO, - DIRECTIO_ON, 0, kcred, NULL, NULL); - - /* Start writing from the begining of the file */ - nca_fio_offset(&fio) = 0; - - /* Remove the current symlink */ - (void) VOP_REMOVE(nca_fio_dvp(&fio), symlink, kcred, NULL, 0); - - attr.va_mask = AT_MODE | AT_TYPE; - attr.va_mode = 0777; - attr.va_type = VLNK; - - /* Create symlink to the new log file */ - ret = VOP_SYMLINK(nca_fio_dvp(&fio), symlink, - &attr, nca_fio_name(&fio), kcred, NULL, 0); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd: symlink of %s to %s failed", - symlink, nca_fio_name(&fio)); - nl7c_logd_enabled = B_FALSE; - logd_off(); - return; - } - mutex_enter(lock); - goto retry; - -done: - if (logvcnt < nl7c_logbuf_max) { - /* May need to allocate some logbuf(s) for logv[] */ - mutex_enter(&log_lock); - if (logvcnt < nl7c_logbuf_max) { - /* - * After acquiring the lock still need logbuf(s), - * if the global logbuf pointer is NULL then call - * log_buf_alloc() as it will fill up logbugv[] - * and initialize a new logbuf else fill up just - * the logv[] here. - */ - if (log == NULL) { - log_buf_alloc(KM_SLEEP); - } else { - /*LINTED*/ - LOGBUFV_ALLOC(KM_SLEEP); - } - } - mutex_exit(&log_lock); - } -} - -static void -logd_worker(logd_t *logdp) -{ - log_buf_t *lbp; - kmutex_t *lock = &logdp->lock; - kcondvar_t *wait = &logdp->wait; - callb_cpr_t cprinfo; - - CALLB_CPR_INIT(&cprinfo, lock, callb_generic_cpr, "nl7c"); - mutex_enter(lock); - - for (;;) { - /* Wait for something to do */ - while ((lbp = logdp->head) == NULL) { - CALLB_CPR_SAFE_BEGIN(&cprinfo); - cv_wait(wait, lock); - CALLB_CPR_SAFE_END(&cprinfo, lock); - } - if ((logdp->head = lbp->next) == NULL) - logdp->tail = NULL; - /* Got a logbuf to write out */ - if (nl7c_logd_enabled) - logd_log_write(lock, lbp); - kmem_cache_free(log_buf_kmc, lbp); - } -} - -boolean_t -nl7c_logd_init(int fsz, caddr_t *fnv) -{ - vnode_t *dvp; - vnode_t *svp; - vnode_t *vp; - int ret; - caddr_t *fnp; - vattr_t attr; - uio_t uio; - iovec_t iov; - char fbuf[TYPICALMAXPATHLEN + 1]; - - /* - * Initialize the global logfio. - */ - nca_fio_cnt(&fio) = 0; - nca_fio_ix(&fio) = 0; - fnp = fnv; - while (*fnp != NULL) { - nca_fio_cnt(&fio)++; - nca_fio_name(&fio) = *fnp; - nca_fio_size(&fio) = fsz; - nca_fio_offset(&fio) = 0; - nca_fio_file(&fio) = nca_fio_ix(&fio); - nca_fio_vp(&fio) = NULL; - - if (++fnp == &fnv[NCA_FIOV_SZ]) - break; - - nca_fio_ix(&fio)++; - } - /* - * See if we can start logging from where we left off last time, - * first check if the symlink exists. - */ - dvp = NULL; - ret = lookupname(symlink_path, UIO_SYSSPACE, NO_FOLLOW, &dvp, &svp); - if (ret || dvp == NULL || svp == NULL) { - if (dvp == NULL) { - /* No NCA symlink directory, create one */ - attr.va_mask = AT_MODE | AT_TYPE; - attr.va_mode = 0755; - attr.va_type = VDIR; - ret = vn_create(symlink_dir, UIO_SYSSPACE, &attr, - EXCL, 0, &dvp, CRMKDIR, 0, 0); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd_init: create" - " symlink dir of %s failed(%d).", - symlink_dir, ret); - goto error; - } - } - nca_fio_dvp(&fio) = dvp; - /* No symlink so don't know were to start from */ - goto fresh_start; - } - /* Save the symlink dir vnode */ - nca_fio_dvp(&fio) = dvp; - - /* Check if the file pointed by the symlink exists */ - ret = lookupname(symlink_path, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp); - if (ret || vp == NULL) - goto fresh_start; - VN_RELE(vp); - - /* Read the symlink and find it in fnv[], else fresh start */ - iov.iov_len = TYPICALMAXPATHLEN; - iov.iov_base = fbuf; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = iov.iov_len; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_loffset = 0; - uio.uio_fmode = 0; - ret = VOP_READLINK(svp, &uio, kcred, NULL); - if (ret) { - (void) VOP_REMOVE(dvp, symlink, kcred, NULL, 0); - goto fresh_start; - } - - /* Null terminate the buf */ - fbuf[TYPICALMAXPATHLEN - (int)uio.uio_resid] = '\0'; - fnp = fnv; - nca_fio_ix(&fio) = 0; - while (*fnp != NULL) { - if (strcmp(*fnp, fbuf) == 0) - break; - if (++fnp == &fnv[NCA_FIOV_SZ]) - goto fresh_start; - nca_fio_ix(&fio)++; - } - if (*fnp == NULL) - goto fresh_start; - - /* Start writing to the end of the file */ - ret = vn_open(*fnp, UIO_SYSSPACE, - FCREAT|FWRITE|FAPPEND, 0600, &vp, 0, 0); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd_init: vn_open of " - "%s failed (error %d)", *fnp, ret); - goto error; - } - nca_fio_vp(&fio) = vp; - (void) VOP_IOCTL(vp, _FIODIRECTIO, DIRECTIO_ON, 0, kcred, NULL, NULL); - attr.va_mask = AT_SIZE; - ret = VOP_GETATTR(nca_fio_vp(&fio), &attr, 0, NULL, NULL); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd_init: getattr of %s failed", *fnp); - goto error; - } - nca_fio_offset(&fio) = (off64_t)attr.va_size; - - goto finish; - -fresh_start: - /* - * Here if no previous logging environment found or if the previous - * logging environment isn't usable or isn't consistent with the new - * fnv[]. Remove the existing symlink (if any) then create the new - * symlink to point to the first logfile. - */ - nca_fio_ix(&fio) = 0; - attr.va_mask = AT_MODE | AT_TYPE; - attr.va_mode = 0777; - attr.va_type = VLNK; - (void) VOP_REMOVE(dvp, symlink, kcred, NULL, 0); - ret = VOP_SYMLINK(dvp, symlink, &attr, nca_fio_name(&fio), kcred, NULL, - 0); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd_init: symlink of %s to %s failed", - symlink_path, nca_fio_name(&fio)); - goto error; - } - ret = vn_open(nca_fio_name(&fio), UIO_SYSSPACE, - FCREAT|FWRITE|FTRUNC, 0600, &nca_fio_vp(&fio), 0, 0); - if (ret) { - cmn_err(CE_WARN, "nl7c_logd_init: vn_open of " - "%s failed (error %d)", nca_fio_name(&fio), ret); - goto error; - } - - /* Turn on directio */ - (void) VOP_IOCTL(nca_fio_vp(&fio), _FIODIRECTIO, - DIRECTIO_ON, 0, kcred, NULL, NULL); - -finish: - log_buf_kmc = kmem_cache_create("NL7C_log_buf_kmc", sizeof (log_buf_t), - 0, NULL, NULL, NULL, NULL, NULL, 0); - - mutex_init(&log_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_enter(&log_lock); - - if (nl7c_logbuf_max == 0) - nl7c_logbuf_max = max_ncpus; - logv = kmem_alloc(nl7c_logbuf_max * sizeof (*logv), KM_SLEEP); - for (logvcnt = 0; logvcnt < nl7c_logbuf_max; logvcnt++) { - logv[logvcnt] = kmem_cache_alloc(log_buf_kmc, KM_SLEEP); - } - - log_buf_alloc(KM_SLEEP); - - mutex_init(&logd.lock, NULL, MUTEX_DEFAULT, NULL); - cv_init(&logd.wait, NULL, CV_DEFAULT, NULL); - logd.head = NULL; - logd.tail = NULL; - logd.worker = thread_create(NULL, 0, logd_worker, &logd, - 0, &p0, TS_RUN, maxclsyspri); - - mutex_exit(&log_lock); - - /* Last, start logger timeout flush */ - logit_flush(NULL); - - return (B_TRUE); - - /* - * Error of some sort, free any resources in reverse order. - */ -error: - nca_fio_ix(&fio) = 0; - while (nca_fio_ix(&fio) < nca_fio_cnt(&fio)) { - char *name = nca_fio_name(&fio); - - if ((vp = nca_fio_vp(&fio)) != NULL) - VN_RELE(vp); - kmem_free(name, (strlen(name) + 1)); - nca_fio_ix(&fio)++; - } - nca_fio_cnt(&fio) = 0; - - if (svp) - VN_RELE(svp); - - if (dvp) - VN_RELE(dvp); - - return (B_FALSE); -} - -/*ARGSUSED*/ -static void -logit_flush(void *arg) -{ - static log_buf_t *lastlbp = NULL; - static int lastpos; - log_buf_t *lbp = log; - - flush_tid = 0; - - mutex_enter(&log_lock); - if (log == NULL) { - /* No global logbuf ? Nothing to flush. */ - goto out; - } - if (lbp != NULL && lbp->cur_pos > (sizeof (nca_log_buf_hdr_t)) && - lastlbp == lbp && lastpos == lbp->cur_pos) { - /* - * We have a logbuf and it has log data and it's the - * same logbuf and pos as last time and after lock - * still true, so flush. - */ - nca_log_stat_t *sp; - - sp = &(((nca_log_buf_hdr_t *)lbp)->nca_logstats); - sp->n_log_size = lbp->cur_pos; - - /* Link new logbuf onto end of logd and wake logd up */ - mutex_enter(&logd.lock); - log->next = NULL; - if (logd.tail == NULL) - logd.head = log; - else - logd.tail->next = log; - logd.tail = log; - cv_signal(&logd.wait); - - mutex_exit(&logd.lock); - - log_buf_alloc(KM_NOSLEEP); - } - - if ((lastlbp = lbp) != NULL) - lastpos = lbp->cur_pos; - - mutex_exit(&log_lock); -out: - /* Check again in 1 second */ - flush_tid = timeout(&logit_flush, NULL, hz); -} - -void -nl7c_logd_log(uri_desc_t *quri, uri_desc_t *suri, time_t rtime, ipaddr_t faddr) -{ - nca_request_log_t *req; - char *wp; - char *pep; - int sz; - uint32_t off = 0; - int kmflag = servicing_interrupt() ? KM_NOSLEEP : KM_SLEEP; - - if (! nl7c_logd_enabled) - return; - - if (! nl7c_logd_started) { - /* Startup logging */ - nl7clogd_startup(); - } - mutex_enter(&log_lock); -again: - if (log == NULL) { - /* No global logbuf, try to allocate one before giving up. */ - log_buf_alloc(kmflag); - if (log == NULL) { - /* No joy, just give up. */ - mutex_exit(&log_lock); - return; - } - } - /* - * Get a pointer to an aligned write position, a pointer to past - * the end of the logbuf, and a pointer to the request header. - * - * As the request header is filled in field by field addtional - * storage is allcated following the request header. - * - * If at any point an allocation from the logbuf overflows (i.e. - * resulting in a pointer > pep) the current request logging is - * aborted, the current logbuf is posted for write, a new logbuf - * is allocated, and start all over. - */ - pep = &((char *)log)[log->size]; - wp = (log->buffer + log->cur_pos); - wp = NCA_LOG_ALIGN(wp); - req = (nca_request_log_t *)wp; - if ((wp + sizeof (*req)) >= pep) goto full; - bzero(wp, sizeof (*req)); - wp += sizeof (*req); - - sz = MIN((quri->path.ep - quri->path.cp), MAX_URL_LEN); - if ((wp + sz + 1) >= pep) goto full; - bcopy(quri->path.cp, wp, sz); - wp += sz; - *wp++ = 0; - sz++; - req->request_url_len = sz; - req->request_url = off; - off += sz; - - /* - * Set response length now as the scheme log function will - * subtract out any header length as we want the entity body - * length returned for the response_len. - */ - req->response_len = (uint_t)suri->resplen; - - /* Call scheme log */ - if (nl7c_http_log(quri, suri, req, &wp, &pep, &off)) goto full; - - /* Update logbuf */ - log->cur_pos = (wp - log->buffer); - - req->response_status = HS_OK; - - req->start_process_time = (time32_t)rtime; - req->end_process_time = (time32_t)gethrestime_sec(); - - req->remote_host = faddr; - - ((nca_log_buf_hdr_t *)log)->nca_logstats.n_log_recs++; - mutex_exit(&log_lock); - return; - -full: - /* - * The logbuf is full, zero fill from current - * write pointer through the end of the buf. - */ - wp = (log->buffer + log->cur_pos); - sz = pep - wp; - bzero(wp, sz); - /* - * Link new logbuf onto end of logd and wake logd up. - */ - mutex_enter(&logd.lock); - log->next = NULL; - if (logd.tail == NULL) - logd.head = log; - else - logd.tail->next = log; - logd.tail = log; - cv_signal(&logd.wait); - mutex_exit(&logd.lock); - /* - * Try to allocate a new global logbuf. - */ - log_buf_alloc(kmflag); - - goto again; -} diff --git a/usr/src/uts/common/fs/sockfs/nl7cnca.c b/usr/src/uts/common/fs/sockfs/nl7cnca.c deleted file mode 100644 index 3e1b494fee..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7cnca.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/stream.h> -#include <sys/strsubr.h> -#include <sys/stropts.h> -#define _SUN_TPI_VERSION 2 -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/cmn_err.h> -#include <sys/debug.h> -#include <sys/vtrace.h> -#include <sys/errno.h> -#include <inet/common.h> -#include <inet/led.h> -#include <inet/mi.h> -#include <inet/nd.h> -#include <sys/strsun.h> - -#include <fs/sockfs/nl7c.h> -#include <fs/sockfs/nl7curi.h> - -#include <inet/nca/nca.h> -#include <inet/nca/ncalogd.h> - -/* - * This file is for NCA compatability, specifically it provides ndd - * support for existing NCA ndd ... - */ - -extern boolean_t nl7c_logd_enabled; -extern nca_fio_t *nl7c_logd_fio; -extern clock_t nl7c_uri_ttl; -extern boolean_t nl7c_use_kmem; -extern uint64_t nl7c_file_prefetch; -extern uint64_t nl7c_uri_max; -extern uint64_t nl7c_uri_bytes; - -extern void nl7c_mi_report_addr(mblk_t *); - -#define MS 1L -#define SECONDS (1000 * MS) -#define MINUTES (60 * SECONDS) -#define HOURS (60 * MINUTES) -#define DAYS (24 * HOURS) - -#define PARAM_MAX UINT_MAX -#define PARAML_MAX ULONG_MAX - -#include <inet/nca/ncandd.h> - -uint32_t nca_major_version = 1; -uint32_t nca_minor_version = 3; -uint32_t nca_httpd_version = NCA_HTTP_VERSION1; -uint32_t nca_logd_version = NCA_LOG_VERSION1; - -caddr_t nca_g_nd; /* Head of 'named dispatch' variable list */ - -/* - * min, max, and value are int64_t's, addr is the optional address of an - * external int64_t to be updated at init/set, name is the ndd name used - * to access. Note, if min == max then only get is allowed, i.e. RO. - */ - -/* BEGIN CSTYLED */ -ncaparam_t nca_param_arr[] = { - /*min max value name */ - { 0, 1, 1, "nca_log_cycle"}, - { 0, 1, 0, "no_caching"}, - { 0, PARAML_MAX, 0, "nca_log_size"}, - { 0, PARAM_MAX, 10000000, "nca_max_cache_size"}, - { 0, PARAM_MAX, 300*SECONDS, "nca_http_timeout"}, - { 0, PARAM_MAX, 15*SECONDS, "nca_http_keep_alive_timeout"}, - { 0, PARAM_MAX, 100, "nca_http_keep_alive_max"}, - { 0, 1, 1, "nca_inq_nointr"}, - { 0, 1, 1, "nca_use_hwcksum"}, - { 0, PARAM_MAX, 0, "nca_segmap_min_size"}, -}; - -/* - * Obsolete ip variables, use "/dev/ip" instead. - */ - -ncaparam_t nca_ip_obsolete_arr[] = { - { 0, 0, 0, "ip_forwarding"}, - { 0, 0, 0, "ip_respond_to_address_mask_broadcast"}, - { 0, 0, 0, "ip_respond_to_echo_broadcast"}, - { 0, 0, 0, "ip_respond_to_timestamp"}, - { 0, 0, 0, "ip_respond_to_timestamp_broadcast"}, - { 0, 0, 0, "ip_send_redirects"}, - { 0, 0, 0, "ip_forward_directed_broadcasts"}, - { 0, 0, 0, "ip_debug"}, - { 0, 0, 0, "ip_mrtdebug"}, - { 0, 0, 0, "ip_ire_cleanup_interval" }, - { 0, 0, 0, "ip_ire_flush_interval" }, - { 0, 0, 0, "ip_ire_redirect_interval" }, - { 0, 0, 0, "ip_def_ttl" }, - { 0, 0, 0, "ip_forward_src_routed"}, - { 0, 0, 0, "ip_wroff_extra" }, - { 0, 0, 0, "ip_ire_pathmtu_interval" }, - { 0, 0, 0, "ip_icmp_return_data_bytes" }, - { 0, 0, 0, "ip_send_source_quench" }, - { 0, 0, 0, "ip_path_mtu_discovery" }, - { 0, 0, 0, "ip_ignore_delete_time" }, - { 0, 0, 0, "ip_ignore_redirect" }, - { 0, 0, 0, "ip_output_queue" }, - { 0, 0, 0, "ip_broadcast_ttl" }, - { 0, 0, 0, "ip_icmp_err_interval" }, - { 0, 0, 0, "ip_reass_queue_bytes" }, - { 0, 0, 0, "ip_strict_dst_multihoming" }, - { 0, 0, 0, "ip_addrs_per_if"}, -}; - -/* - * Obsolete tcp variables, use "/dev/tcp" instead. - */ - -ncaparam_t nca_tcp_obsolete_arr[] = { - { 0, 0, 0, "tcp_time_wait_interval"}, - { 0, 0, 0, "tcp_conn_req_max_q" }, - { 0, 0, 0, "tcp_conn_req_max_q0" }, - { 0, 0, 0, "tcp_conn_req_min" }, - { 0, 0, 0, "tcp_conn_grace_period" }, - { 0, 0, 0, "tcp_cwnd_max" }, - { 0, 0, 0, "tcp_debug" }, - { 0, 0, 0, "tcp_smallest_nonpriv_port"}, - { 0, 0, 0, "tcp_ip_abort_cinterval"}, - { 0, 0, 0, "tcp_ip_abort_linterval"}, - { 0, 0, 0, "tcp_ip_abort_interval"}, - { 0, 0, 0, "tcp_ip_notify_cinterval"}, - { 0, 0, 0, "tcp_ip_notify_interval"}, - { 0, 0, 0, "tcp_ip_ttl"}, - { 0, 0, 0, "tcp_keepalive_interval"}, - { 0, 0, 0, "tcp_maxpsz_multiplier" }, - { 0, 0, 0, "tcp_mss_def"}, - { 0, 0, 0, "tcp_mss_max"}, - { 0, 0, 0, "tcp_mss_min"}, - { 0, 0, 0, "tcp_naglim_def"}, - { 0, 0, 0, "tcp_rexmit_interval_initial"}, - { 0, 0, 0, "tcp_rexmit_interval_max"}, - { 0, 0, 0, "tcp_rexmit_interval_min"}, - { 0, 0, 0, "tcp_wroff_xtra" }, - { 0, 0, 0, "tcp_deferred_ack_interval" }, - { 0, 0, 0, "tcp_snd_lowat_fraction" }, - { 0, 0, 0, "tcp_sth_rcv_hiwat" }, - { 0, 0, 0, "tcp_sth_rcv_lowat" }, - { 0, 0, 0, "tcp_dupack_fast_retransmit" }, - { 0, 0, 0, "tcp_ignore_path_mtu" }, - { 0, 0, 0, "tcp_rcv_push_wait" }, - { 0, 0, 0, "tcp_smallest_anon_port"}, - { 0, 0, 0, "tcp_largest_anon_port"}, - { 0, 0, 0, "tcp_xmit_hiwat"}, - { 0, 0, 0, "tcp_xmit_lowat"}, - { 0, 0, 0, "tcp_recv_hiwat"}, - { 0, 0, 0, "tcp_recv_hiwat_minmss"}, - { 0, 0, 0, "tcp_fin_wait_2_flush_interval"}, - { 0, 0, 0, "tcp_max_buf"}, - { 0, 0, 0, "tcp_strong_iss"}, - { 0, 0, 0, "tcp_rtt_updates"}, - { 0, 0, 0, "tcp_wscale_always"}, - { 0, 0, 0, "tcp_tstamp_always"}, - { 0, 0, 0, "tcp_tstamp_if_wscale"}, - { 0, 0, 0, "tcp_rexmit_interval_extra"}, - { 0, 0, 0, "tcp_deferred_acks_max"}, - { 0, 0, 0, "tcp_slow_start_after_idle"}, - { 0, 0, 0, "tcp_slow_start_initial"}, - { 0, 0, 0, "tcp_sack_permitted"}, -#ifdef DEBUG - { 0, 0, 0, "tcp_drop_oob"}, -#endif -}; - -/* - * Obsolete nca variables, just warn. - */ - -ncaparam_t nca_nca_obsolete_arr[] = { - { 0, 0, 0, "nca_ipport_table_bucket"}, - { 0, 0, 0, "nca_ipport_table_size"}, - { 0, 0, 0, "nca_ipport_table_expand"}, - { 0, 0, 0, "nca_ipport_table_shrink"}, - { 0, 0, 0, "nca_ip_virtual_hosting"}, - { 0, 0, 0, "httpd_door_address"}, - { 0, 0, 0, "httpd_door_path"}, - { 0, 0, 0, "httpd_downdoor_path"}, - { 0, 0, 0, "nca_ppmax"}, - { 0, 0, 0, "nca_vpmax"}, - { 0, 0, 0, "nca_use_segmap"}, - { 0, 0, 0, "nca_availrmem"}, - { 0, 0, 0, "nca_maxkmem"}, - { 0, 0, 0, "nca_log_file"}, - { 0, 0, 0, "conn_status"}, - { 0, 0, 0, "conn_status_all"}, - { 0, 0, 0, "nca_conn_req_max_q"}, - { 0, 0, 0, "nca_conn_req_max_q0"}, - { 0, 0, 0, "cache_clear"}, - { 0, 0, 0, "nca_node_hash"}, - { 0, 0, 0, "node_status"}, -#ifdef DEBUG - { 0, 0, 0, "nca_debug_counter"}, -#endif -}; -/* END CSTYLED */ - -static int -/*ARGSUSED*/ -nl7c_uri_ttl_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "%ld", nl7c_uri_ttl); - return (0); -} - -static int -/*ARGSUSED*/ -nl7c_uri_ttl_set(queue_t *q, mblk_t *mp, char *value, caddr_t nu, cred_t *cr) -{ - if (ddi_strtol(value, NULL, 10, &nl7c_uri_ttl) != 0) - return (EINVAL); - return (0); -} - -static int -/*ARGSUSED*/ -nca_logging_on_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "%d", nl7c_logd_enabled); - return (0); -} - -static int -/*ARGSUSED*/ -nca_logging_on_set(queue_t *q, mblk_t *mp, char *value, caddr_t nu, cred_t *cr) -{ - long new_value; - - if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value < 0 || - new_value > 1) { - return (EINVAL); - } - if (nca_fio_cnt(nl7c_logd_fio) == 0) - return (EINVAL); - nl7c_logd_enabled = new_value; - - return (0); -} - -static int -/*ARGSUSED*/ -nca_version_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "%d.%d", nca_major_version, nca_minor_version); - return (0); -} - -static int -/*ARGSUSED*/ -nca_httpd_version_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "%d", nca_httpd_version); - return (0); -} - -static int -/*ARGSUSED*/ -nca_logd_version_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "%d", nca_logd_version); - return (0); -} - -static int -/*ARGSUSED*/ -nca_httpd_door_inst_get(queue_t *q, mblk_t *mp, caddr_t nu, cred_t *cr) -{ - nl7c_mi_report_addr(mp); - return (0); -} - -static int -/*ARGSUSED*/ -nca_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - ncaparam_t *ncapa = (ncaparam_t *)cp; - - (void) mi_mpprintf(mp, "%ld", ncapa->param_val); - return (0); -} - -static int -/*ARGSUSED*/ -nca_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr) -{ - ulong_t new_value; - ncaparam_t *ncapa = (ncaparam_t *)cp; - - if (ddi_strtoul(value, NULL, 10, &new_value) != 0 || - new_value < ncapa->param_min || new_value > ncapa->param_max) { - return (EINVAL); - } - ncapa->param_val = new_value; - return (0); -} - -static int -/*ARGSUSED*/ -nca_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "obsolete"); - return (0); -} - -static int -/*ARGSUSED*/ -nca_ip_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "obsolete for /dev/nca, use /dev/ip"); - return (0); -} - -static int -/*ARGSUSED*/ -nca_tcp_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "obsolete for /dev/nca, use /dev/tcp"); - return (0); -} - -static int -/*ARGSUSED*/ -nca_nca_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr) -{ - (void) mi_mpprintf(mp, "obsolete for /dev/nca"); - return (0); -} - -static boolean_t -nca_param_register(ncaparam_t *ncapa, int cnt) -{ - for (; cnt-- > 0; ncapa++) { - if (ncapa->param_name && ncapa->param_name[0]) { - if (!nd_load(&nca_g_nd, ncapa->param_name, - nca_param_get, nca_param_set, - (caddr_t)ncapa)) { - goto error; - } - } - - } - if (!nd_load(&nca_g_nd, "nca_version", nca_version_get, nil(pfi_t), - nil(caddr_t))) { - goto error; - } - if (!nd_load(&nca_g_nd, "nca_logd_version", nca_logd_version_get, - nil(pfi_t), nil(caddr_t))) { - goto error; - } - if (!nd_load(&nca_g_nd, "nca_logging_on", nca_logging_on_get, - nca_logging_on_set, nil(caddr_t))) { - goto error; - } - - if (!nd_load(&nca_g_nd, "uri_time_to_live", nl7c_uri_ttl_get, - nl7c_uri_ttl_set, nil(caddr_t))) { - goto error; - } - if (!nd_load(&nca_g_nd, "nca_httpd_version", nca_httpd_version_get, - nil(pfi_t), nil(caddr_t))) { - goto error; - } - if (!nd_load(&nca_g_nd, "httpd_door_instance", nca_httpd_door_inst_get, - nil(pfi_t), nil(caddr_t))) { - nd_free(&nca_g_nd); - return (B_FALSE); - } - - ncapa = nca_ip_obsolete_arr; - cnt = A_CNT(nca_ip_obsolete_arr); - for (; cnt-- > 0; ncapa++) { - if (ncapa->param_name && ncapa->param_name[0]) { - if (!nd_load(&nca_g_nd, ncapa->param_name, - nca_ip_obsolete, NULL, (caddr_t)ncapa)) { - goto error; - } - } - - } - - ncapa = nca_tcp_obsolete_arr; - cnt = A_CNT(nca_tcp_obsolete_arr); - for (; cnt-- > 0; ncapa++) { - if (ncapa->param_name && ncapa->param_name[0]) { - if (!nd_load(&nca_g_nd, ncapa->param_name, - nca_tcp_obsolete, NULL, (caddr_t)ncapa)) { - goto error; - } - } - - } - - ncapa = nca_nca_obsolete_arr; - cnt = A_CNT(nca_nca_obsolete_arr); - for (; cnt-- > 0; ncapa++) { - if (ncapa->param_name && ncapa->param_name[0]) { - if (!nd_load(&nca_g_nd, ncapa->param_name, - nca_nca_obsolete, NULL, (caddr_t)ncapa)) { - goto error; - } - } - - } - - return (B_TRUE); - -error: - nd_free(&nca_g_nd); - return (B_FALSE); -} - -void -nl7c_nca_init(void) -{ - if (! nca_g_nd) { - if (! nca_param_register(nca_param_arr, A_CNT(nca_param_arr))) - cmn_err(CE_WARN, - "nl7c: /dev/nca ndd initialization failed."); - } -} diff --git a/usr/src/uts/common/fs/sockfs/nl7ctokgen b/usr/src/uts/common/fs/sockfs/nl7ctokgen deleted file mode 100755 index 1cdf1d2d1f..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7ctokgen +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/ksh -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Executed from appropriate arch build directory, e.g. {intel,sparc}/sockfs, -# to generate the nl7ctokgen.h file from nl7ctok*.txt file(s). -# - -EXIT=0 -IFS="," -while [ "$1" != "" ] -do -NAME=$1 -shift -<$NAME sort -f +1 |{ - -while read IDN STR FLG BAD -do - if [ "$IDN" != "${IDN#\#}" ] - then - continue - fi - if [ -n "$BAD" ] - then - echo "$IDN: ${BAD## }: too many arguments" - EXIT=1 - fi - echo "static char S$IDN[] = ${STR## };" - ELE="$ELE - INIT($IDN, ${FLG## })," - ENU="$ENU - $IDN," -done -NAME=${NAME##*nl7c} -NAME=${NAME%.txt} -TOKEN="$TOKEN -token_t $NAME[] = { -$ELE - {0} -}; - -#define ${NAME}_cnt (sizeof ($NAME) / sizeof (*$NAME)) -" -ELE="" - -} -done - -echo " -enum tokid_e { - _Hdr_First_, -$ENU - _Hdr_Last_ -}; -$TOKEN -" - -exit $EXIT diff --git a/usr/src/uts/common/fs/sockfs/nl7ctokreq.txt b/usr/src/uts/common/fs/sockfs/nl7ctokreq.txt deleted file mode 100644 index 4924ce0e32..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7ctokreq.txt +++ /dev/null @@ -1,44 +0,0 @@ -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Executed from appropriate arch build directory, e.g. {intel,sparc}/sockfs, -# to generate the nl7ctokgen.h file from nl7ctok*.txt file(s). -# -Qhdr_Accept, "Accept: ", PASS | QUALIFIER -Qhdr_Accept_Charset, "Accept-Charset: ", PASS | QUALIFIER -Qhdr_Accept_Encoding, "Accept-Encoding: ", PASS | QUALIFIER -Qhdr_Accept_Language, "Accept-Language: ", PASS | QUALIFIER -Qhdr_Authorization, "Authorization: ", PASS | QUALIFIER | NOCACHE -Qhdr_Host, "Host: ", PASS | QUALIFIER | HASH -Qhdr_If_Modified_Since, "If-Modified-Since: ", FILTER | QUALIFIER | DATE -Qhdr_If_Unmodified_Since, "If-Unmodified-Since: ", FILTER | QUALIFIER | DATE -Qhdr_User_Agent, "User-Agent: ", PASS | QUALIFIER -Qhdr_Connection_close, "Connection: close", QUALIFIER -Qhdr_Connection_Keep_Alive, "Connection: Keep-Alive", QUALIFIER -Qhdr_Keep_Alive, "Keep-Alive: ", FILTER | QUALIFIER -Qhdr_Date, "Date: ", PASS | QUALIFIER | DATE -Qhdr_ETagW, "ETag: W/", PASS | NOCACHE -Qhdr_ETag, "ETag: ", PASS | QUALIFIER -Qhdr_Pragma_no_cache, "Pragma: no-cache", PASS | NOCACHE diff --git a/usr/src/uts/common/fs/sockfs/nl7ctokres.txt b/usr/src/uts/common/fs/sockfs/nl7ctokres.txt deleted file mode 100644 index 12307d7d37..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7ctokres.txt +++ /dev/null @@ -1,43 +0,0 @@ -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Executed from appropriate arch build directory, e.g. {intel,sparc}/sockfs, -# to generate the nl7ctokgen.h file from nl7ctok*.txt file(s). -# -Shdr_Connection_close, "Connection: close", FILTER | QUALIFIER -Shdr_Connection_Keep_Alive, "Connection: Keep-Alive", FILTER | QUALIFIER -Shdr_Content_Length, "Content-Length: ", PASS | QUALIFIER | NUMERIC -Shdr_Date, "Date: ", PASS | QUALIFIER | DATE -Shdr_Expires, "Expires: ", PASS | QUALIFIER | DATE -Shdr_Keep_Alive, "Keep-Alive: ", FILTER | QUALIFIER -Shdr_Last_Modified, "Last-Modified: ", PASS | QUALIFIER | QUALIFIER | DATE -Shdr_Set_Cookie, "Set-Cookie: ", PASS | NOCACHE -Shdr_Cache_Control_No_Cache, "Cache-Control: no-cache", PASS | NOCACHE -Shdr_Cache_Control_No_Store, "Cache-Control: no-store", PASS | NOCACHE -Shdr_Cache_Control_Max_Age, "Cache-Control: max-age", PASS | NUMERIC -Shdr_ETagW, "ETag: W/", PASS | NOCACHE -Shdr_ETag, "ETag: ", PASS | QUALIFIER -Shdr_Chunked, "Transfer-Encoding: chunked", PASS | QUALIFIER -Shdr_Server, "Server: ", PASS | QUALIFIER diff --git a/usr/src/uts/common/fs/sockfs/nl7curi.c b/usr/src/uts/common/fs/sockfs/nl7curi.c deleted file mode 100644 index 0c8276d227..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7curi.c +++ /dev/null @@ -1,2145 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <sys/strsubr.h> -#include <sys/strsun.h> -#include <sys/param.h> -#include <sys/sysmacros.h> -#include <vm/seg_map.h> -#include <vm/seg_kpm.h> -#include <sys/condvar_impl.h> -#include <sys/sendfile.h> -#include <fs/sockfs/nl7c.h> -#include <fs/sockfs/nl7curi.h> -#include <fs/sockfs/socktpi_impl.h> - -#include <inet/common.h> -#include <inet/ip.h> -#include <inet/ip6.h> -#include <inet/tcp.h> -#include <inet/led.h> -#include <inet/mi.h> - -#include <inet/nca/ncadoorhdr.h> -#include <inet/nca/ncalogd.h> -#include <inet/nca/ncandd.h> - -#include <sys/promif.h> - -/* - * Some externs: - */ - -extern boolean_t nl7c_logd_enabled; -extern void nl7c_logd_log(uri_desc_t *, uri_desc_t *, - time_t, ipaddr_t); -extern boolean_t nl7c_close_addr(struct sonode *); -extern struct sonode *nl7c_addr2portso(void *); -extern uri_desc_t *nl7c_http_cond(uri_desc_t *, uri_desc_t *); - -/* - * Various global tuneables: - */ - -clock_t nl7c_uri_ttl = -1; /* TTL in seconds (-1 == infinite) */ - -boolean_t nl7c_use_kmem = B_FALSE; /* Force use of kmem (no segmap) */ - -uint64_t nl7c_file_prefetch = 1; /* File cache prefetch pages */ - -uint64_t nl7c_uri_max = 0; /* Maximum bytes (0 == infinite) */ -uint64_t nl7c_uri_bytes = 0; /* Bytes of kmem used by URIs */ - -/* - * Locals: - */ - -static int uri_rd_response(struct sonode *, uri_desc_t *, - uri_rd_t *, boolean_t); -static int uri_response(struct sonode *, uri_desc_t *); - -/* - * HTTP scheme functions called from nl7chttp.c: - */ - -boolean_t nl7c_http_request(char **, char *, uri_desc_t *, struct sonode *); -boolean_t nl7c_http_response(char **, char *, uri_desc_t *, struct sonode *); -boolean_t nl7c_http_cmp(void *, void *); -mblk_t *nl7c_http_persist(struct sonode *); -void nl7c_http_free(void *arg); -void nl7c_http_init(void); - -/* - * Counters that need to move to kstat and/or be removed: - */ - -volatile uint64_t nl7c_uri_request = 0; -volatile uint64_t nl7c_uri_hit = 0; -volatile uint64_t nl7c_uri_pass = 0; -volatile uint64_t nl7c_uri_miss = 0; -volatile uint64_t nl7c_uri_temp = 0; -volatile uint64_t nl7c_uri_more = 0; -volatile uint64_t nl7c_uri_data = 0; -volatile uint64_t nl7c_uri_sendfilev = 0; -volatile uint64_t nl7c_uri_reclaim_calls = 0; -volatile uint64_t nl7c_uri_reclaim_cnt = 0; -volatile uint64_t nl7c_uri_pass_urifail = 0; -volatile uint64_t nl7c_uri_pass_dupbfail = 0; -volatile uint64_t nl7c_uri_more_get = 0; -volatile uint64_t nl7c_uri_pass_method = 0; -volatile uint64_t nl7c_uri_pass_option = 0; -volatile uint64_t nl7c_uri_more_eol = 0; -volatile uint64_t nl7c_uri_more_http = 0; -volatile uint64_t nl7c_uri_pass_http = 0; -volatile uint64_t nl7c_uri_pass_addfail = 0; -volatile uint64_t nl7c_uri_pass_temp = 0; -volatile uint64_t nl7c_uri_expire = 0; -volatile uint64_t nl7c_uri_purge = 0; -volatile uint64_t nl7c_uri_NULL1 = 0; -volatile uint64_t nl7c_uri_NULL2 = 0; -volatile uint64_t nl7c_uri_close = 0; -volatile uint64_t nl7c_uri_temp_close = 0; -volatile uint64_t nl7c_uri_free = 0; -volatile uint64_t nl7c_uri_temp_free = 0; -volatile uint64_t nl7c_uri_temp_mk = 0; -volatile uint64_t nl7c_uri_rd_EAGAIN = 0; - -/* - * Various kmem_cache_t's: - */ - -kmem_cache_t *nl7c_uri_kmc; -kmem_cache_t *nl7c_uri_rd_kmc; -static kmem_cache_t *uri_desb_kmc; -static kmem_cache_t *uri_segmap_kmc; - -static void uri_kmc_reclaim(void *); - -static void nl7c_uri_reclaim(void); - -/* - * The URI hash is a dynamically sized A/B bucket hash, when the current - * hash's average bucket chain length exceeds URI_HASH_AVRG a new hash of - * the next P2Ps[] size is created. - * - * All lookups are done in the current hash then the new hash (if any), - * if there is a new has then when a current hash bucket chain is examined - * any uri_desc_t members will be migrated to the new hash and when the - * last uri_desc_t has been migrated then the new hash will become the - * current and the previous current hash will be freed leaving a single - * hash. - * - * uri_hash_t - hash bucket (chain) type, contained in the uri_hash_ab[] - * and can be accessed only after aquiring the uri_hash_access lock (for - * READER or WRITER) then acquiring the lock uri_hash_t.lock, the uri_hash_t - * and all linked uri_desc_t.hash members are protected. Note, a REF_HOLD() - * is placed on all uri_desc_t uri_hash_t list members. - * - * uri_hash_access - rwlock for all uri_hash_* variables, READER for read - * access and WRITER for write access. Note, WRITER is only required for - * hash geometry changes. - * - * uri_hash_which - which uri_hash_ab[] is the current hash. - * - * uri_hash_n[] - the P2Ps[] index for each uri_hash_ab[]. - * - * uri_hash_sz[] - the size for each uri_hash_ab[]. - * - * uri_hash_cnt[] - the total uri_desc_t members for each uri_hash_ab[]. - * - * uri_hash_overflow[] - the uri_hash_cnt[] for each uri_hash_ab[] when - * a new uri_hash_ab[] needs to be created. - * - * uri_hash_ab[] - the uri_hash_t entries. - * - * uri_hash_lru[] - the last uri_hash_ab[] walked for lru reclaim. - */ - -typedef struct uri_hash_s { - struct uri_desc_s *list; /* List of uri_t(s) */ - kmutex_t lock; -} uri_hash_t; - -#define URI_HASH_AVRG 5 /* Desired average hash chain length */ -#define URI_HASH_N_INIT 9 /* P2Ps[] initial index */ - -static krwlock_t uri_hash_access; -static uint32_t uri_hash_which = 0; -static uint32_t uri_hash_n[2] = {URI_HASH_N_INIT, 0}; -static uint32_t uri_hash_sz[2] = {0, 0}; -static uint32_t uri_hash_cnt[2] = {0, 0}; -static uint32_t uri_hash_overflow[2] = {0, 0}; -static uri_hash_t *uri_hash_ab[2] = {NULL, NULL}; -static uri_hash_t *uri_hash_lru[2] = {NULL, NULL}; - -/* - * Primes for N of 3 - 24 where P is first prime less then (2^(N-1))+(2^(N-2)) - * these primes have been foud to be useful for prime sized hash tables. - */ - -static const int P2Ps[] = { - 0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 761, 1531, 3067, - 6143, 12281, 24571, 49139, 98299, 196597, 393209, - 786431, 1572853, 3145721, 6291449, 12582893, 0}; - -/* - * Hash macros: - * - * H2A(char *cp, char *ep, char c) - convert the escaped octet (ASCII) - * hex multichar of the format "%HH" pointeded to by *cp to a char and - * return in c, *ep points to past end of (char *), on return *cp will - * point to the last char consumed. - * - * URI_HASH(unsigned hix, char *cp, char *ep) - hash the char(s) from - * *cp to *ep to the unsigned hix, cp nor ep are modified. - * - * URI_HASH_IX(unsigned hix, int which) - convert the hash value hix to - * a hash index 0 - (uri_hash_sz[which] - 1). - * - * URI_HASH_MIGRATE(from, hp, to) - migrate the uri_hash_t *hp list - * uri_desc_t members from hash from to hash to. - * - * URI_HASH_UNLINK(cur, new, hp, puri, uri) - unlink the uri_desc_t - * *uri which is a member of the uri_hash_t *hp list with a previous - * list member of *puri for the uri_hash_ab[] cur. After unlinking - * check for cur hash empty, if so make new cur. Note, as this macro - * can change a hash chain it needs to be run under hash_access as - * RW_WRITER, futher as it can change the new hash to cur any access - * to the hash state must be done after either dropping locks and - * starting over or making sure the global state is consistent after - * as before. - */ - -#define H2A(cp, ep, c) { \ - int _h = 2; \ - int _n = 0; \ - char _hc; \ - \ - while (_h > 0 && ++(cp) < (ep)) { \ - if (_h == 1) \ - _n *= 0x10; \ - _hc = *(cp); \ - if (_hc >= '0' && _hc <= '9') \ - _n += _hc - '0'; \ - else if (_hc >= 'a' || _hc <= 'f') \ - _n += _hc - 'W'; \ - else if (_hc >= 'A' || _hc <= 'F') \ - _n += _hc - '7'; \ - _h--; \ - } \ - (c) = _n; \ -} - -#define URI_HASH(hv, cp, ep) { \ - char *_s = (cp); \ - char _c; \ - \ - while (_s < (ep)) { \ - if ((_c = *_s) == '%') { \ - H2A(_s, (ep), _c); \ - } \ - CHASH(hv, _c); \ - _s++; \ - } \ -} - -#define URI_HASH_IX(hix, which) (hix) = (hix) % (uri_hash_sz[(which)]) - -#define URI_HASH_MIGRATE(from, hp, to) { \ - uri_desc_t *_nuri; \ - uint32_t _nhix; \ - uri_hash_t *_nhp; \ - \ - mutex_enter(&(hp)->lock); \ - while ((_nuri = (hp)->list) != NULL) { \ - (hp)->list = _nuri->hash; \ - atomic_dec_32(&uri_hash_cnt[(from)]); \ - atomic_inc_32(&uri_hash_cnt[(to)]); \ - _nhix = _nuri->hvalue; \ - URI_HASH_IX(_nhix, to); \ - _nhp = &uri_hash_ab[(to)][_nhix]; \ - mutex_enter(&_nhp->lock); \ - _nuri->hash = _nhp->list; \ - _nhp->list = _nuri; \ - _nuri->hit = 0; \ - mutex_exit(&_nhp->lock); \ - } \ - mutex_exit(&(hp)->lock); \ -} - -#define URI_HASH_UNLINK(cur, new, hp, puri, uri) { \ - if ((puri) != NULL) { \ - (puri)->hash = (uri)->hash; \ - } else { \ - (hp)->list = (uri)->hash; \ - } \ - if (atomic_dec_32_nv(&uri_hash_cnt[(cur)]) == 0 && \ - uri_hash_ab[(new)] != NULL) { \ - kmem_free(uri_hash_ab[cur], \ - sizeof (uri_hash_t) * uri_hash_sz[cur]); \ - uri_hash_ab[(cur)] = NULL; \ - uri_hash_lru[(cur)] = NULL; \ - uri_hash_which = (new); \ - } else { \ - uri_hash_lru[(cur)] = (hp); \ - } \ -} - -void -nl7c_uri_init(void) -{ - uint32_t cur = uri_hash_which; - - rw_init(&uri_hash_access, NULL, RW_DEFAULT, NULL); - - uri_hash_sz[cur] = P2Ps[URI_HASH_N_INIT]; - uri_hash_overflow[cur] = P2Ps[URI_HASH_N_INIT] * URI_HASH_AVRG; - uri_hash_ab[cur] = kmem_zalloc(sizeof (uri_hash_t) * uri_hash_sz[cur], - KM_SLEEP); - uri_hash_lru[cur] = uri_hash_ab[cur]; - - nl7c_uri_kmc = kmem_cache_create("NL7C_uri_kmc", sizeof (uri_desc_t), - 0, NULL, NULL, uri_kmc_reclaim, NULL, NULL, 0); - - nl7c_uri_rd_kmc = kmem_cache_create("NL7C_uri_rd_kmc", - sizeof (uri_rd_t), 0, NULL, NULL, NULL, NULL, NULL, 0); - - uri_desb_kmc = kmem_cache_create("NL7C_uri_desb_kmc", - sizeof (uri_desb_t), 0, NULL, NULL, NULL, NULL, NULL, 0); - - uri_segmap_kmc = kmem_cache_create("NL7C_uri_segmap_kmc", - sizeof (uri_segmap_t), 0, NULL, NULL, NULL, NULL, NULL, 0); - - nl7c_http_init(); -} - -#define CV_SZ 16 - -void -nl7c_mi_report_hash(mblk_t *mp) -{ - uri_hash_t *hp, *pend; - uri_desc_t *uri; - uint32_t cur; - uint32_t new; - int n, nz, tot; - uint32_t cv[CV_SZ + 1]; - - rw_enter(&uri_hash_access, RW_READER); - cur = uri_hash_which; - new = cur ? 0 : 1; -next: - for (n = 0; n <= CV_SZ; n++) - cv[n] = 0; - nz = 0; - tot = 0; - hp = &uri_hash_ab[cur][0]; - pend = &uri_hash_ab[cur][uri_hash_sz[cur]]; - while (hp < pend) { - n = 0; - for (uri = hp->list; uri != NULL; uri = uri->hash) { - n++; - } - tot += n; - if (n > 0) - nz++; - if (n > CV_SZ) - n = CV_SZ; - cv[n]++; - hp++; - } - - (void) mi_mpprintf(mp, "\nHash=%s, Buckets=%d, " - "Avrg=%d\nCount by bucket:", cur != new ? "CUR" : "NEW", - uri_hash_sz[cur], nz != 0 ? ((tot * 10 + 5) / nz) / 10 : 0); - (void) mi_mpprintf(mp, "Free=%d", cv[0]); - for (n = 1; n < CV_SZ; n++) { - int pn = 0; - char pv[5]; - char *pp = pv; - - for (pn = n; pn < 1000; pn *= 10) - *pp++ = ' '; - *pp = 0; - (void) mi_mpprintf(mp, "%s%d=%d", pv, n, cv[n]); - } - (void) mi_mpprintf(mp, "Long=%d", cv[CV_SZ]); - - if (cur != new && uri_hash_ab[new] != NULL) { - cur = new; - goto next; - } - rw_exit(&uri_hash_access); -} - -void -nl7c_mi_report_uri(mblk_t *mp) -{ - uri_hash_t *hp; - uri_desc_t *uri; - uint32_t cur; - uint32_t new; - int ix; - int ret; - char sc; - - rw_enter(&uri_hash_access, RW_READER); - cur = uri_hash_which; - new = cur ? 0 : 1; -next: - for (ix = 0; ix < uri_hash_sz[cur]; ix++) { - hp = &uri_hash_ab[cur][ix]; - mutex_enter(&hp->lock); - uri = hp->list; - while (uri != NULL) { - sc = *(uri->path.ep); - *(uri->path.ep) = 0; - ret = mi_mpprintf(mp, "%s: %d %d %d", - uri->path.cp, (int)uri->resplen, - (int)uri->respclen, (int)uri->count); - *(uri->path.ep) = sc; - if (ret == -1) break; - uri = uri->hash; - } - mutex_exit(&hp->lock); - if (ret == -1) break; - } - if (ret != -1 && cur != new && uri_hash_ab[new] != NULL) { - cur = new; - goto next; - } - rw_exit(&uri_hash_access); -} - -/* - * The uri_desc_t ref_t inactive function called on the last REF_RELE(), - * free all resources contained in the uri_desc_t. Note, the uri_desc_t - * will be freed by REF_RELE() on return. - */ - -void -nl7c_uri_inactive(uri_desc_t *uri) -{ - int64_t bytes = 0; - - if (uri->tail) { - uri_rd_t *rdp = &uri->response; - uri_rd_t *free = NULL; - - while (rdp) { - if (rdp->off == -1) { - bytes += rdp->sz; - kmem_free(rdp->data.kmem, rdp->sz); - } else { - VN_RELE(rdp->data.vnode); - } - rdp = rdp->next; - if (free != NULL) { - kmem_cache_free(nl7c_uri_rd_kmc, free); - } - free = rdp; - } - } - if (bytes) { - atomic_add_64(&nl7c_uri_bytes, -bytes); - } - if (uri->scheme != NULL) { - nl7c_http_free(uri->scheme); - } - if (uri->reqmp) { - freeb(uri->reqmp); - } -} - -/* - * The reclaim is called by the kmem subsystem when kmem is running - * low. More work is needed to determine the best reclaim policy, for - * now we just manipulate the nl7c_uri_max global maximum bytes threshold - * value using a simple arithmetic backoff of the value every time this - * function is called then call uri_reclaim() to enforce it. - * - * Note, this value remains in place and enforced for all subsequent - * URI request/response processing. - * - * Note, nl7c_uri_max is currently initialized to 0 or infinite such that - * the first call here set it to the current uri_bytes value then backoff - * from there. - * - * XXX how do we determine when to increase nl7c_uri_max ??? - */ - -/*ARGSUSED*/ -static void -uri_kmc_reclaim(void *arg) -{ - uint64_t new_max; - - if ((new_max = nl7c_uri_max) == 0) { - /* Currently infinite, initialize to current bytes used */ - nl7c_uri_max = nl7c_uri_bytes; - new_max = nl7c_uri_bytes; - } - if (new_max > 1) { - /* Lower max_bytes to 93% of current value */ - new_max >>= 1; /* 50% */ - new_max += (new_max >> 1); /* 75% */ - new_max += (new_max >> 2); /* 93% */ - if (new_max < nl7c_uri_max) - nl7c_uri_max = new_max; - else - nl7c_uri_max = 1; - } - nl7c_uri_reclaim(); -} - -/* - * Delete a uri_desc_t from the URI hash. - */ - -static void -uri_delete(uri_desc_t *del) -{ - uint32_t hix; - uri_hash_t *hp; - uri_desc_t *uri; - uri_desc_t *puri; - uint32_t cur; - uint32_t new; - - ASSERT(del->hash != URI_TEMP); - rw_enter(&uri_hash_access, RW_WRITER); - cur = uri_hash_which; - new = cur ? 0 : 1; -next: - puri = NULL; - hix = del->hvalue; - URI_HASH_IX(hix, cur); - hp = &uri_hash_ab[cur][hix]; - for (uri = hp->list; uri != NULL; uri = uri->hash) { - if (uri != del) { - puri = uri; - continue; - } - /* - * Found the URI, unlink from the hash chain, - * drop locks, ref release it. - */ - URI_HASH_UNLINK(cur, new, hp, puri, uri); - rw_exit(&uri_hash_access); - REF_RELE(uri); - return; - } - if (cur != new && uri_hash_ab[new] != NULL) { - /* - * Not found in current hash and have a new hash so - * check the new hash next. - */ - cur = new; - goto next; - } - rw_exit(&uri_hash_access); -} - -/* - * Add a uri_desc_t to the URI hash. - */ - -static void -uri_add(uri_desc_t *uri, krw_t rwlock, boolean_t nonblocking) -{ - uint32_t hix; - uri_hash_t *hp; - uint32_t cur = uri_hash_which; - uint32_t new = cur ? 0 : 1; - - /* - * Caller of uri_add() must hold the uri_hash_access rwlock. - */ - ASSERT((rwlock == RW_READER && RW_READ_HELD(&uri_hash_access)) || - (rwlock == RW_WRITER && RW_WRITE_HELD(&uri_hash_access))); - /* - * uri_add() always succeeds so add a hash ref to the URI now. - */ - REF_HOLD(uri); -again: - hix = uri->hvalue; - URI_HASH_IX(hix, cur); - if (uri_hash_ab[new] == NULL && - uri_hash_cnt[cur] < uri_hash_overflow[cur]) { - /* - * Easy case, no new hash and current hasn't overflowed, - * add URI to current hash and return. - * - * Note, the check for uri_hash_cnt[] above aren't done - * atomictally, i.e. multiple threads can be in this code - * as RW_READER and update the cnt[], this isn't a problem - * as the check is only advisory. - */ - fast: - atomic_inc_32(&uri_hash_cnt[cur]); - hp = &uri_hash_ab[cur][hix]; - mutex_enter(&hp->lock); - uri->hash = hp->list; - hp->list = uri; - mutex_exit(&hp->lock); - rw_exit(&uri_hash_access); - return; - } - if (uri_hash_ab[new] == NULL) { - /* - * Need a new a or b hash, if not already RW_WRITER - * try to upgrade our lock to writer. - */ - if (rwlock != RW_WRITER && ! rw_tryupgrade(&uri_hash_access)) { - /* - * Upgrade failed, we can't simple exit and reenter - * the lock as after the exit and before the reenter - * the whole world can change so just wait for writer - * then do everything again. - */ - if (nonblocking) { - /* - * Can't block, use fast-path above. - * - * XXX should have a background thread to - * handle new ab[] in this case so as to - * not overflow the cur hash to much. - */ - goto fast; - } - rw_exit(&uri_hash_access); - rwlock = RW_WRITER; - rw_enter(&uri_hash_access, rwlock); - cur = uri_hash_which; - new = cur ? 0 : 1; - goto again; - } - rwlock = RW_WRITER; - if (uri_hash_ab[new] == NULL) { - /* - * Still need a new hash, allocate and initialize - * the new hash. - */ - uri_hash_n[new] = uri_hash_n[cur] + 1; - if (uri_hash_n[new] == 0) { - /* - * No larger P2Ps[] value so use current, - * i.e. 2 of the largest are better than 1 ? - */ - uri_hash_n[new] = uri_hash_n[cur]; - cmn_err(CE_NOTE, "NL7C: hash index overflow"); - } - uri_hash_sz[new] = P2Ps[uri_hash_n[new]]; - ASSERT(uri_hash_cnt[new] == 0); - uri_hash_overflow[new] = uri_hash_sz[new] * - URI_HASH_AVRG; - uri_hash_ab[new] = kmem_zalloc(sizeof (uri_hash_t) * - uri_hash_sz[new], nonblocking ? KM_NOSLEEP : - KM_SLEEP); - if (uri_hash_ab[new] == NULL) { - /* - * Alloc failed, use fast-path above. - * - * XXX should have a background thread to - * handle new ab[] in this case so as to - * not overflow the cur hash to much. - */ - goto fast; - } - uri_hash_lru[new] = uri_hash_ab[new]; - } - } - /* - * Hashed against current hash so migrate any current hash chain - * members, if any. - * - * Note, the hash chain list can be checked for a non empty list - * outside of the hash chain list lock as the hash chain struct - * can't be destroyed while in the uri_hash_access rwlock, worst - * case is that a non empty list is found and after acquiring the - * lock another thread beats us to it (i.e. migrated the list). - */ - hp = &uri_hash_ab[cur][hix]; - if (hp->list != NULL) { - URI_HASH_MIGRATE(cur, hp, new); - } - /* - * If new hash has overflowed before current hash has been - * completely migrated then walk all current hash chains and - * migrate list members now. - */ - if (atomic_inc_32_nv(&uri_hash_cnt[new]) >= uri_hash_overflow[new]) { - for (hix = 0; hix < uri_hash_sz[cur]; hix++) { - hp = &uri_hash_ab[cur][hix]; - if (hp->list != NULL) { - URI_HASH_MIGRATE(cur, hp, new); - } - } - } - /* - * Add URI to new hash. - */ - hix = uri->hvalue; - URI_HASH_IX(hix, new); - hp = &uri_hash_ab[new][hix]; - mutex_enter(&hp->lock); - uri->hash = hp->list; - hp->list = uri; - mutex_exit(&hp->lock); - /* - * Last, check to see if last cur hash chain has been - * migrated, if so free cur hash and make new hash cur. - */ - if (uri_hash_cnt[cur] == 0) { - /* - * If we don't already hold the uri_hash_access rwlock for - * RW_WRITE try to upgrade to RW_WRITE and if successful - * check again and to see if still need to do the free. - */ - if ((rwlock == RW_WRITER || rw_tryupgrade(&uri_hash_access)) && - uri_hash_cnt[cur] == 0 && uri_hash_ab[new] != 0) { - kmem_free(uri_hash_ab[cur], - sizeof (uri_hash_t) * uri_hash_sz[cur]); - uri_hash_ab[cur] = NULL; - uri_hash_lru[cur] = NULL; - uri_hash_which = new; - } - } - rw_exit(&uri_hash_access); -} - -/* - * Lookup a uri_desc_t in the URI hash, if found free the request uri_desc_t - * and return the found uri_desc_t with a REF_HOLD() placed on it. Else, if - * add B_TRUE use the request URI to create a new hash entry. Else if add - * B_FALSE ... - */ - -static uri_desc_t * -uri_lookup(uri_desc_t *ruri, boolean_t add, boolean_t nonblocking) -{ - uint32_t hix; - uri_hash_t *hp; - uri_desc_t *uri; - uri_desc_t *puri; - uint32_t cur; - uint32_t new; - char *rcp = ruri->path.cp; - char *rep = ruri->path.ep; - -again: - rw_enter(&uri_hash_access, RW_READER); - cur = uri_hash_which; - new = cur ? 0 : 1; -nexthash: - puri = NULL; - hix = ruri->hvalue; - URI_HASH_IX(hix, cur); - hp = &uri_hash_ab[cur][hix]; - mutex_enter(&hp->lock); - for (uri = hp->list; uri != NULL; uri = uri->hash) { - char *ap = uri->path.cp; - char *bp = rcp; - char a, b; - - /* Compare paths */ - while (bp < rep && ap < uri->path.ep) { - if ((a = *ap) == '%') { - /* Escaped hex multichar, convert it */ - H2A(ap, uri->path.ep, a); - } - if ((b = *bp) == '%') { - /* Escaped hex multichar, convert it */ - H2A(bp, rep, b); - } - if (a != b) { - /* Char's don't match */ - goto nexturi; - } - ap++; - bp++; - } - if (bp != rep || ap != uri->path.ep) { - /* Not same length */ - goto nexturi; - } - ap = uri->auth.cp; - bp = ruri->auth.cp; - if (ap != NULL) { - if (bp == NULL) { - /* URI has auth request URI doesn't */ - goto nexturi; - } - while (bp < ruri->auth.ep && ap < uri->auth.ep) { - if ((a = *ap) == '%') { - /* Escaped hex multichar, convert it */ - H2A(ap, uri->path.ep, a); - } - if ((b = *bp) == '%') { - /* Escaped hex multichar, convert it */ - H2A(bp, rep, b); - } - if (a != b) { - /* Char's don't match */ - goto nexturi; - } - ap++; - bp++; - } - if (bp != ruri->auth.ep || ap != uri->auth.ep) { - /* Not same length */ - goto nexturi; - } - } else if (bp != NULL) { - /* URI doesn't have auth and request URI does */ - goto nexturi; - } - /* - * Have a path/auth match so before any other processing - * of requested URI, check for expire or request no cache - * purge. - */ - if (uri->expire >= 0 && uri->expire <= ddi_get_lbolt() || - ruri->nocache) { - /* - * URI has expired or request specified to not use - * the cached version, unlink the URI from the hash - * chain, release all locks, release the hash ref - * on the URI, and last look it up again. - * - * Note, this will cause all variants of the named - * URI to be purged. - */ - if (puri != NULL) { - puri->hash = uri->hash; - } else { - hp->list = uri->hash; - } - mutex_exit(&hp->lock); - atomic_dec_32(&uri_hash_cnt[cur]); - rw_exit(&uri_hash_access); - if (ruri->nocache) - nl7c_uri_purge++; - else - nl7c_uri_expire++; - REF_RELE(uri); - goto again; - } - if (uri->scheme != NULL) { - /* - * URI has scheme private qualifier(s), if request - * URI doesn't or if no match skip this URI. - */ - if (ruri->scheme == NULL || - ! nl7c_http_cmp(uri->scheme, ruri->scheme)) - goto nexturi; - } else if (ruri->scheme != NULL) { - /* - * URI doesn't have scheme private qualifiers but - * request URI does, no match, skip this URI. - */ - goto nexturi; - } - /* - * Have a match, ready URI for return, first put a reference - * hold on the URI, if this URI is currently being processed - * then have to wait for the processing to be completed and - * redo the lookup, else return it. - */ - REF_HOLD(uri); - mutex_enter(&uri->proclock); - if (uri->proc != NULL) { - /* The URI is being processed, wait for completion */ - mutex_exit(&hp->lock); - rw_exit(&uri_hash_access); - if (! nonblocking && - cv_wait_sig(&uri->waiting, &uri->proclock)) { - /* - * URI has been processed but things may - * have changed while we were away so do - * most everything again. - */ - mutex_exit(&uri->proclock); - REF_RELE(uri); - goto again; - } else { - /* - * A nonblocking socket or an interrupted - * cv_wait_sig() in the first case can't - * block waiting for the processing of the - * uri hash hit uri to complete, in both - * cases just return failure to lookup. - */ - mutex_exit(&uri->proclock); - REF_RELE(uri); - return (NULL); - } - } - mutex_exit(&uri->proclock); - uri->hit++; - mutex_exit(&hp->lock); - rw_exit(&uri_hash_access); - return (uri); - nexturi: - puri = uri; - } - mutex_exit(&hp->lock); - if (cur != new && uri_hash_ab[new] != NULL) { - /* - * Not found in current hash and have a new hash so - * check the new hash next. - */ - cur = new; - goto nexthash; - } -add: - if (! add) { - /* Lookup only so return failure */ - rw_exit(&uri_hash_access); - return (NULL); - } - /* - * URI not hashed, finish intialization of the - * request URI, add it to the hash, return it. - */ - ruri->hit = 0; - ruri->expire = -1; - ruri->response.sz = 0; - ruri->proc = (struct sonode *)~0; - cv_init(&ruri->waiting, NULL, CV_DEFAULT, NULL); - mutex_init(&ruri->proclock, NULL, MUTEX_DEFAULT, NULL); - uri_add(ruri, RW_READER, nonblocking); - /* uri_add() has done rw_exit(&uri_hash_access) */ - return (ruri); -} - -/* - * Reclaim URIs until max cache size threshold has been reached. - * - * A CLOCK based reclaim modified with a history (hit counter) counter. - */ - -static void -nl7c_uri_reclaim(void) -{ - uri_hash_t *hp, *start, *pend; - uri_desc_t *uri; - uri_desc_t *puri; - uint32_t cur; - uint32_t new; - - nl7c_uri_reclaim_calls++; -again: - rw_enter(&uri_hash_access, RW_WRITER); - cur = uri_hash_which; - new = cur ? 0 : 1; -next: - hp = uri_hash_lru[cur]; - start = hp; - pend = &uri_hash_ab[cur][uri_hash_sz[cur]]; - while (nl7c_uri_bytes > nl7c_uri_max) { - puri = NULL; - for (uri = hp->list; uri != NULL; uri = uri->hash) { - if (uri->hit != 0) { - /* - * Decrement URI activity counter and skip. - */ - uri->hit--; - puri = uri; - continue; - } - if (uri->proc != NULL) { - /* - * Currently being processed by a socket, skip. - */ - continue; - } - /* - * Found a candidate, no hit(s) since added or last - * reclaim pass, unlink from it's hash chain, update - * lru scan pointer, drop lock, ref release it. - */ - URI_HASH_UNLINK(cur, new, hp, puri, uri); - if (cur == uri_hash_which) { - if (++hp == pend) { - /* Wrap pointer */ - hp = uri_hash_ab[cur]; - } - uri_hash_lru[cur] = hp; - } - rw_exit(&uri_hash_access); - REF_RELE(uri); - nl7c_uri_reclaim_cnt++; - goto again; - } - if (++hp == pend) { - /* Wrap pointer */ - hp = uri_hash_ab[cur]; - } - if (hp == start) { - if (cur != new && uri_hash_ab[new] != NULL) { - /* - * Done with the current hash and have a - * new hash so check the new hash next. - */ - cur = new; - goto next; - } - } - } - rw_exit(&uri_hash_access); -} - -/* - * Called for a socket which is being freed prior to close, e.g. errored. - */ - -void -nl7c_urifree(struct sonode *so) -{ - sotpi_info_t *sti = SOTOTPI(so); - uri_desc_t *uri = (uri_desc_t *)sti->sti_nl7c_uri; - - sti->sti_nl7c_uri = NULL; - if (uri->hash != URI_TEMP) { - uri_delete(uri); - mutex_enter(&uri->proclock); - uri->proc = NULL; - if (CV_HAS_WAITERS(&uri->waiting)) { - cv_broadcast(&uri->waiting); - } - mutex_exit(&uri->proclock); - nl7c_uri_free++; - } else { - /* No proclock as uri exclusively owned by so */ - uri->proc = NULL; - nl7c_uri_temp_free++; - } - REF_RELE(uri); -} - -/* - * ... - * - * < 0 need more data - * - * 0 parse complete - * - * > 0 parse error - */ - -volatile uint64_t nl7c_resp_pfail = 0; -volatile uint64_t nl7c_resp_ntemp = 0; -volatile uint64_t nl7c_resp_pass = 0; - -static int -nl7c_resp_parse(struct sonode *so, uri_desc_t *uri, char *data, int sz) -{ - if (! nl7c_http_response(&data, &data[sz], uri, so)) { - if (data == NULL) { - /* Parse fail */ - goto pfail; - } - /* More data */ - data = NULL; - } else if (data == NULL) { - goto pass; - } - if (uri->hash != URI_TEMP && uri->nocache) { - /* - * After response parse now no cache, - * delete it from cache, wakeup any - * waiters on this URI, make URI_TEMP. - */ - uri_delete(uri); - mutex_enter(&uri->proclock); - if (CV_HAS_WAITERS(&uri->waiting)) { - cv_broadcast(&uri->waiting); - } - mutex_exit(&uri->proclock); - uri->hash = URI_TEMP; - nl7c_uri_temp_mk++; - } - if (data == NULL) { - /* More data needed */ - return (-1); - } - /* Success */ - return (0); - -pfail: - nl7c_resp_pfail++; - return (EINVAL); - -pass: - nl7c_resp_pass++; - return (ENOTSUP); -} - -/* - * Called to sink application response data, the processing of the data - * is the same for a cached or temp URI (i.e. a URI for which we aren't - * going to cache the URI but want to parse it for detecting response - * data end such that for a persistent connection we can parse the next - * request). - * - * On return 0 is returned for sink success, > 0 on error, and < 0 on - * no so URI (note, data not sinked). - */ - -int -nl7c_data(struct sonode *so, uio_t *uio) -{ - sotpi_info_t *sti = SOTOTPI(so); - uri_desc_t *uri = (uri_desc_t *)sti->sti_nl7c_uri; - iovec_t *iov; - int cnt; - int sz = uio->uio_resid; - char *data, *alloc; - char *bp; - uri_rd_t *rdp; - boolean_t first; - int error, perror; - - nl7c_uri_data++; - - if (uri == NULL) { - /* Socket & NL7C out of sync, disable NL7C */ - sti->sti_nl7c_flags = 0; - nl7c_uri_NULL1++; - return (-1); - } - - if (sti->sti_nl7c_flags & NL7C_WAITWRITE) { - sti->sti_nl7c_flags &= ~NL7C_WAITWRITE; - first = B_TRUE; - } else { - first = B_FALSE; - } - - alloc = kmem_alloc(sz, KM_SLEEP); - URI_RD_ADD(uri, rdp, sz, -1); - - if (uri->hash != URI_TEMP && uri->count > nca_max_cache_size) { - uri_delete(uri); - uri->hash = URI_TEMP; - } - data = alloc; - alloc = NULL; - rdp->data.kmem = data; - atomic_add_64(&nl7c_uri_bytes, sz); - - bp = data; - while (uio->uio_resid > 0) { - iov = uio->uio_iov; - if ((cnt = iov->iov_len) == 0) { - goto next; - } - cnt = MIN(cnt, uio->uio_resid); - error = xcopyin(iov->iov_base, bp, cnt); - if (error) - goto fail; - - iov->iov_base += cnt; - iov->iov_len -= cnt; - uio->uio_resid -= cnt; - uio->uio_loffset += cnt; - bp += cnt; - next: - uio->uio_iov++; - uio->uio_iovcnt--; - } - - /* Successfull sink of data, response parse the data */ - perror = nl7c_resp_parse(so, uri, data, sz); - - /* Send the data out the connection */ - error = uri_rd_response(so, uri, rdp, first); - if (error) - goto fail; - - /* Success */ - if (perror == 0 && - ((uri->respclen == URI_LEN_NOVALUE && - uri->resplen == URI_LEN_NOVALUE) || - uri->count >= uri->resplen)) { - /* - * No more data needed and no pending response - * data or current data count >= response length - * so close the URI processing for this so. - */ - nl7c_close(so); - if (! (sti->sti_nl7c_flags & NL7C_SOPERSIST)) { - /* Not a persistent connection */ - sti->sti_nl7c_flags = 0; - } - } - - return (0); - -fail: - if (alloc != NULL) { - kmem_free(alloc, sz); - } - sti->sti_nl7c_flags = 0; - nl7c_urifree(so); - - return (error); -} - -/* - * Called to read data from file "*fp" at offset "*off" of length "*len" - * for a maximum of "*max_rem" bytes. - * - * On success a pointer to the kmem_alloc()ed file data is returned, "*off" - * and "*len" are updated for the acutal number of bytes read and "*max_rem" - * is updated with the number of bytes remaining to be read. - * - * Else, "NULL" is returned. - */ - -static char * -nl7c_readfile(file_t *fp, u_offset_t *off, int *len, int max, int *ret) -{ - vnode_t *vp = fp->f_vnode; - int flg = 0; - size_t size = MIN(*len, max); - char *data; - int error; - uio_t uio; - iovec_t iov; - - (void) VOP_RWLOCK(vp, flg, NULL); - - if (*off > MAXOFFSET_T) { - VOP_RWUNLOCK(vp, flg, NULL); - *ret = EFBIG; - return (NULL); - } - - if (*off + size > MAXOFFSET_T) - size = (ssize32_t)(MAXOFFSET_T - *off); - - data = kmem_alloc(size, KM_SLEEP); - - iov.iov_base = data; - iov.iov_len = size; - uio.uio_loffset = *off; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = size; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_llimit = MAXOFFSET_T; - uio.uio_fmode = fp->f_flag; - - error = VOP_READ(vp, &uio, fp->f_flag, fp->f_cred, NULL); - VOP_RWUNLOCK(vp, flg, NULL); - *ret = error; - if (error) { - kmem_free(data, size); - return (NULL); - } - *len = size; - *off += size; - return (data); -} - -/* - * Called to sink application response sendfilev, as with nl7c_data() above - * all the data will be processed by NL7C unless there's an error. - */ - -int -nl7c_sendfilev(struct sonode *so, u_offset_t *fileoff, sendfilevec_t *sfvp, - int sfvc, ssize_t *xfer) -{ - sotpi_info_t *sti = SOTOTPI(so); - uri_desc_t *uri = (uri_desc_t *)sti->sti_nl7c_uri; - file_t *fp = NULL; - vnode_t *vp = NULL; - char *data = NULL; - u_offset_t off; - int len; - int cnt; - int total_count = 0; - char *alloc; - uri_rd_t *rdp; - int max; - int perror; - int error = 0; - boolean_t first = B_TRUE; - - nl7c_uri_sendfilev++; - - if (uri == NULL) { - /* Socket & NL7C out of sync, disable NL7C */ - sti->sti_nl7c_flags = 0; - nl7c_uri_NULL2++; - return (0); - } - - if (sti->sti_nl7c_flags & NL7C_WAITWRITE) - sti->sti_nl7c_flags &= ~NL7C_WAITWRITE; - - while (sfvc-- > 0) { - /* - * off - the current sfv read file offset or user address. - * - * len - the current sfv length in bytes. - * - * cnt - number of bytes kmem_alloc()ed. - * - * alloc - the kmem_alloc()ed buffer of size "cnt". - * - * data - copy of "alloc" used for post alloc references. - * - * fp - the current sfv file_t pointer. - * - * vp - the current "*vp" vnode_t pointer. - * - * Note, for "data" and "fp" and "vp" a NULL value is used - * when not allocated such that the common failure path "fail" - * is used. - */ - off = sfvp->sfv_off; - len = sfvp->sfv_len; - cnt = len; - - if (len == 0) { - sfvp++; - continue; - } - - if (sfvp->sfv_fd == SFV_FD_SELF) { - /* - * User memory, copyin() all the bytes. - */ - alloc = kmem_alloc(cnt, KM_SLEEP); - error = xcopyin((caddr_t)(uintptr_t)off, alloc, cnt); - if (error) - goto fail; - } else { - /* - * File descriptor, prefetch some bytes. - */ - if ((fp = getf(sfvp->sfv_fd)) == NULL) { - error = EBADF; - goto fail; - } - if ((fp->f_flag & FREAD) == 0) { - error = EACCES; - goto fail; - } - vp = fp->f_vnode; - if (vp->v_type != VREG) { - error = EINVAL; - goto fail; - } - VN_HOLD(vp); - - /* Read max_rem bytes from file for prefetch */ - if (nl7c_use_kmem) { - max = cnt; - } else { - max = MAXBSIZE * nl7c_file_prefetch; - } - alloc = nl7c_readfile(fp, &off, &cnt, max, &error); - if (alloc == NULL) - goto fail; - - releasef(sfvp->sfv_fd); - fp = NULL; - } - URI_RD_ADD(uri, rdp, cnt, -1); - data = alloc; - alloc = NULL; - rdp->data.kmem = data; - total_count += cnt; - if (uri->hash != URI_TEMP && total_count > nca_max_cache_size) { - uri_delete(uri); - uri->hash = URI_TEMP; - } - - /* Response parse */ - perror = nl7c_resp_parse(so, uri, data, len); - - /* Send kmem data out the connection */ - error = uri_rd_response(so, uri, rdp, first); - - if (error) - goto fail; - - if (sfvp->sfv_fd != SFV_FD_SELF) { - /* - * File descriptor, if any bytes left save vnode_t. - */ - if (len > cnt) { - /* More file data so add it */ - URI_RD_ADD(uri, rdp, len - cnt, off); - rdp->data.vnode = vp; - - /* Send vnode data out the connection */ - error = uri_rd_response(so, uri, rdp, first); - } else { - /* All file data fit in the prefetch */ - VN_RELE(vp); - } - *fileoff += len; - vp = NULL; - } - *xfer += len; - sfvp++; - - if (first) - first = B_FALSE; - } - if (total_count > 0) { - atomic_add_64(&nl7c_uri_bytes, total_count); - } - if (perror == 0 && - ((uri->respclen == URI_LEN_NOVALUE && - uri->resplen == URI_LEN_NOVALUE) || - uri->count >= uri->resplen)) { - /* - * No more data needed and no pending response - * data or current data count >= response length - * so close the URI processing for this so. - */ - nl7c_close(so); - if (! (sti->sti_nl7c_flags & NL7C_SOPERSIST)) { - /* Not a persistent connection */ - sti->sti_nl7c_flags = 0; - } - } - - return (0); - -fail: - if (error == EPIPE) - tsignal(curthread, SIGPIPE); - - if (alloc != NULL) - kmem_free(data, len); - - if (vp != NULL) - VN_RELE(vp); - - if (fp != NULL) - releasef(sfvp->sfv_fd); - - if (total_count > 0) { - atomic_add_64(&nl7c_uri_bytes, total_count); - } - - sti->sti_nl7c_flags = 0; - nl7c_urifree(so); - - return (error); -} - -/* - * Called for a socket which is closing or when an application has - * completed sending all the response data (i.e. for a persistent - * connection called once for each completed application response). - */ - -void -nl7c_close(struct sonode *so) -{ - sotpi_info_t *sti = SOTOTPI(so); - uri_desc_t *uri = (uri_desc_t *)sti->sti_nl7c_uri; - - if (uri == NULL) { - /* - * No URI being processed so might be a listen()er - * if so do any cleanup, else nothing more to do. - */ - if (so->so_state & SS_ACCEPTCONN) { - (void) nl7c_close_addr(so); - } - return; - } - sti->sti_nl7c_uri = NULL; - if (uri->hash != URI_TEMP) { - mutex_enter(&uri->proclock); - uri->proc = NULL; - if (CV_HAS_WAITERS(&uri->waiting)) { - cv_broadcast(&uri->waiting); - } - mutex_exit(&uri->proclock); - nl7c_uri_close++; - } else { - /* No proclock as uri exclusively owned by so */ - uri->proc = NULL; - nl7c_uri_temp_close++; - } - REF_RELE(uri); - if (nl7c_uri_max > 0 && nl7c_uri_bytes > nl7c_uri_max) { - nl7c_uri_reclaim(); - } -} - -/* - * The uri_segmap_t ref_t inactive function called on the last REF_RELE(), - * release the segmap mapping. Note, the uri_segmap_t will be freed by - * REF_RELE() on return. - */ - -void -uri_segmap_inactive(uri_segmap_t *smp) -{ - if (!segmap_kpm) { - (void) segmap_fault(kas.a_hat, segkmap, smp->base, - smp->len, F_SOFTUNLOCK, S_OTHER); - } - (void) segmap_release(segkmap, smp->base, SM_DONTNEED); - VN_RELE(smp->vp); -} - -/* - * The call-back for desballoc()ed mblk_t's, if a segmap mapped mblk_t - * release the reference, one per desballoc() of a segmap page, if a rd_t - * mapped mblk_t release the reference, one per desballoc() of a uri_desc_t, - * last kmem free the uri_desb_t. - */ - -static void -uri_desb_free(uri_desb_t *desb) -{ - if (desb->segmap != NULL) { - REF_RELE(desb->segmap); - } - REF_RELE(desb->uri); - kmem_cache_free(uri_desb_kmc, desb); -} - -/* - * Segmap map up to a page of a uri_rd_t file descriptor. - */ - -uri_segmap_t * -uri_segmap_map(uri_rd_t *rdp, int bytes) -{ - uri_segmap_t *segmap = kmem_cache_alloc(uri_segmap_kmc, KM_SLEEP); - int len = MIN(rdp->sz, MAXBSIZE); - - if (len > bytes) - len = bytes; - - REF_INIT(segmap, 1, uri_segmap_inactive, uri_segmap_kmc); - segmap->len = len; - VN_HOLD(rdp->data.vnode); - segmap->vp = rdp->data.vnode; - - segmap->base = segmap_getmapflt(segkmap, segmap->vp, rdp->off, len, - segmap_kpm ? SM_FAULT : 0, S_READ); - - if (segmap_fault(kas.a_hat, segkmap, segmap->base, len, - F_SOFTLOCK, S_READ) != 0) { - REF_RELE(segmap); - return (NULL); - } - return (segmap); -} - -/* - * Chop up the kernel virtual memory area *data of size *sz bytes for - * a maximum of *bytes bytes into an besballoc()ed mblk_t chain using - * the given template uri_desb_t *temp of max_mblk bytes per. - * - * The values of *data, *sz, and *bytes are updated on return, the - * mblk_t chain is returned. - */ - -static mblk_t * -uri_desb_chop(char **data, size_t *sz, int *bytes, uri_desb_t *temp, - int max_mblk, char *eoh, mblk_t *persist) -{ - char *ldata = *data; - size_t lsz = *sz; - int lbytes = bytes ? *bytes : lsz; - uri_desb_t *desb; - mblk_t *mp = NULL; - mblk_t *nmp, *pmp = NULL; - int msz; - - if (lbytes == 0 && lsz == 0) - return (NULL); - - while (lbytes > 0 && lsz > 0) { - msz = MIN(lbytes, max_mblk); - msz = MIN(msz, lsz); - if (persist && eoh >= ldata && eoh < &ldata[msz]) { - msz = (eoh - ldata); - pmp = persist; - persist = NULL; - if (msz == 0) { - nmp = pmp; - pmp = NULL; - goto zero; - } - } - desb = kmem_cache_alloc(uri_desb_kmc, KM_SLEEP); - REF_HOLD(temp->uri); - if (temp->segmap) { - REF_HOLD(temp->segmap); - } - bcopy(temp, desb, sizeof (*desb)); - desb->frtn.free_arg = (caddr_t)desb; - nmp = desballoc((uchar_t *)ldata, msz, BPRI_HI, &desb->frtn); - if (nmp == NULL) { - if (temp->segmap) { - REF_RELE(temp->segmap); - } - REF_RELE(temp->uri); - if (mp != NULL) { - mp->b_next = NULL; - freemsg(mp); - } - if (persist != NULL) { - freeb(persist); - } - return (NULL); - } - nmp->b_wptr += msz; - zero: - if (mp != NULL) { - mp->b_next->b_cont = nmp; - } else { - mp = nmp; - } - if (pmp != NULL) { - nmp->b_cont = pmp; - nmp = pmp; - pmp = NULL; - } - mp->b_next = nmp; - ldata += msz; - lsz -= msz; - lbytes -= msz; - } - *data = ldata; - *sz = lsz; - if (bytes) - *bytes = lbytes; - return (mp); -} - -/* - * Experimential noqwait (i.e. no canput()/qwait() checks), just send - * the entire mblk_t chain down without flow-control checks. - */ - -static int -kstrwritempnoqwait(struct vnode *vp, mblk_t *mp) -{ - struct stdata *stp; - int error = 0; - - ASSERT(vp->v_stream); - stp = vp->v_stream; - - /* Fast check of flags before acquiring the lock */ - if (stp->sd_flag & (STWRERR|STRHUP|STPLEX)) { - mutex_enter(&stp->sd_lock); - error = strgeterr(stp, STWRERR|STRHUP|STPLEX, 0); - mutex_exit(&stp->sd_lock); - if (error != 0) { - if (!(stp->sd_flag & STPLEX) && - (stp->sd_wput_opt & SW_SIGPIPE)) { - error = EPIPE; - } - return (error); - } - } - putnext(stp->sd_wrq, mp); - return (0); -} - -/* - * Send the URI uri_desc_t *uri response uri_rd_t *rdp out the socket_t *so. - */ - -static int -uri_rd_response(struct sonode *so, - uri_desc_t *uri, - uri_rd_t *rdp, - boolean_t first) -{ - vnode_t *vp = SOTOV(so); - int max_mblk = (int)vp->v_stream->sd_maxblk; - int wsz; - mblk_t *mp, *wmp, *persist; - int write_bytes; - uri_rd_t rd; - uri_desb_t desb; - uri_segmap_t *segmap = NULL; - char *segmap_data; - size_t segmap_sz; - int error; - int fflg = ((so->so_state & SS_NDELAY) ? FNDELAY : 0) | - ((so->so_state & SS_NONBLOCK) ? FNONBLOCK : 0); - - - /* Initialize template uri_desb_t */ - desb.frtn.free_func = uri_desb_free; - desb.frtn.free_arg = NULL; - desb.uri = uri; - - /* Get a local copy of the rd_t */ - bcopy(rdp, &rd, sizeof (rd)); - do { - if (first) { - /* - * For first kstrwrite() enough data to get - * things going, note non blocking version of - * kstrwrite() will be used below. - */ - write_bytes = P2ROUNDUP((max_mblk * 4), - MAXBSIZE * nl7c_file_prefetch); - } else { - if ((write_bytes = so->so_sndbuf) == 0) - write_bytes = vp->v_stream->sd_qn_maxpsz; - ASSERT(write_bytes > 0); - write_bytes = P2ROUNDUP(write_bytes, MAXBSIZE); - } - /* - * Chop up to a write_bytes worth of data. - */ - wmp = NULL; - wsz = write_bytes; - do { - if (rd.sz == 0) - break; - if (rd.off == -1) { - if (uri->eoh >= rd.data.kmem && - uri->eoh < &rd.data.kmem[rd.sz]) { - persist = nl7c_http_persist(so); - } else { - persist = NULL; - } - desb.segmap = NULL; - mp = uri_desb_chop(&rd.data.kmem, &rd.sz, - &wsz, &desb, max_mblk, uri->eoh, persist); - if (mp == NULL) { - error = ENOMEM; - goto invalidate; - } - } else { - if (segmap == NULL) { - segmap = uri_segmap_map(&rd, - write_bytes); - if (segmap == NULL) { - error = ENOMEM; - goto invalidate; - } - desb.segmap = segmap; - segmap_data = segmap->base; - segmap_sz = segmap->len; - } - mp = uri_desb_chop(&segmap_data, &segmap_sz, - &wsz, &desb, max_mblk, NULL, NULL); - if (mp == NULL) { - error = ENOMEM; - goto invalidate; - } - if (segmap_sz == 0) { - rd.sz -= segmap->len; - rd.off += segmap->len; - REF_RELE(segmap); - segmap = NULL; - } - } - if (wmp == NULL) { - wmp = mp; - } else { - wmp->b_next->b_cont = mp; - wmp->b_next = mp->b_next; - mp->b_next = NULL; - } - } while (wsz > 0 && rd.sz > 0); - - wmp->b_next = NULL; - if (first) { - /* First kstrwrite(), use noqwait */ - if ((error = kstrwritempnoqwait(vp, wmp)) != 0) - goto invalidate; - /* - * For the rest of the kstrwrite()s use SO_SNDBUF - * worth of data at a time, note these kstrwrite()s - * may (will) block one or more times. - */ - first = B_FALSE; - } else { - if ((error = kstrwritemp(vp, wmp, fflg)) != 0) { - if (error == EAGAIN) { - nl7c_uri_rd_EAGAIN++; - if ((error = - kstrwritempnoqwait(vp, wmp)) != 0) - goto invalidate; - } else - goto invalidate; - } - } - } while (rd.sz > 0); - - return (0); - -invalidate: - if (segmap) { - REF_RELE(segmap); - } - if (wmp) - freemsg(wmp); - - return (error); -} - -/* - * Send the URI uri_desc_t *uri response out the socket_t *so. - */ - -static int -uri_response(struct sonode *so, uri_desc_t *uri) -{ - uri_rd_t *rdp = &uri->response; - boolean_t first = B_TRUE; - int error; - - while (rdp != NULL) { - error = uri_rd_response(so, uri, rdp, first); - if (error != 0) { - goto invalidate; - } - first = B_FALSE; - rdp = rdp->next; - } - return (0); - -invalidate: - if (uri->hash != URI_TEMP) - uri_delete(uri); - return (error); -} - -/* - * The pchars[] array is indexed by a char to determine if it's a - * valid URI path component chararcter where: - * - * pchar = unreserved | escaped | - * ":" | "@" | "&" | "=" | "+" | "$" | "," - * - * unreserved = alphanum | mark - * - * alphanum = alpha | digit - * - * alpha = lowalpha | upalpha - * - * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | - * "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | - * "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | - * "y" | "z" - * - * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | - * "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | - * "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | - * "Y" | "Z" - * - * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | - * "8" | "9" - * - * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" - * - * escaped = "%" hex hex - * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | - * "a" | "b" | "c" | "d" | "e" | "f" - */ - -static char pchars[] = { - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x07 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08 - 0x0F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x17 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x18 - 0x1F */ - 0, 1, 0, 0, 1, 1, 1, 1, /* 0x20 - 0x27 */ - 0, 0, 1, 1, 1, 1, 1, 1, /* 0x28 - 0x2F */ - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x30 - 0x37 */ - 1, 1, 1, 0, 0, 1, 0, 0, /* 0x38 - 0x3F */ - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x47 */ - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x48 - 0x4F */ - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x57 */ - 1, 1, 1, 0, 0, 0, 0, 1, /* 0x58 - 0x5F */ - 0, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x67 */ - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x68 - 0x6F */ - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x77 */ - 1, 1, 1, 0, 0, 0, 1, 0 /* 0x78 - 0x7F */ -}; - -#define PCHARS_MASK 0x7F - -/* - * This is the main L7 request message parse, we are called each time - * new data is availble for a socket, each time a single buffer of the - * entire message to date is given. - * - * Here we parse the request looking for the URI, parse it, and if a - * supported scheme call the scheme parser to commplete the parse of any - * headers which may further qualify the identity of the requested object - * then lookup it up in the URI hash. - * - * Return B_TRUE for more processing. - * - * Note, at this time the parser supports the generic message format as - * specified in RFC 822 with potentional limitations as specified in RFC - * 2616 for HTTP messages. - * - * Note, the caller supports an mblk_t chain, for now the parser(s) - * require the complete header in a single mblk_t. This is the common - * case and certainly for high performance environments, if at a future - * date mblk_t chains are important the parse can be reved to process - * mblk_t chains. - */ - -boolean_t -nl7c_parse(struct sonode *so, boolean_t nonblocking, boolean_t *ret) -{ - sotpi_info_t *sti = SOTOTPI(so); - char *cp = (char *)sti->sti_nl7c_rcv_mp->b_rptr; - char *ep = (char *)sti->sti_nl7c_rcv_mp->b_wptr; - char *get = "GET "; - char *post = "POST "; - char c; - char *uris; - uri_desc_t *uri = NULL; - uri_desc_t *ruri = NULL; - mblk_t *reqmp; - uint32_t hv = 0; - - if ((reqmp = dupb(sti->sti_nl7c_rcv_mp)) == NULL) { - nl7c_uri_pass_dupbfail++; - goto pass; - } - /* - * Allocate and initialize minimumal state for the request - * uri_desc_t, in the cache hit case this uri_desc_t will - * be freed. - */ - uri = kmem_cache_alloc(nl7c_uri_kmc, KM_SLEEP); - REF_INIT(uri, 1, nl7c_uri_inactive, nl7c_uri_kmc); - uri->hash = NULL; - uri->tail = NULL; - uri->scheme = NULL; - uri->count = 0; - uri->reqmp = reqmp; - - /* - * Set request time to current time. - */ - sti->sti_nl7c_rtime = gethrestime_sec(); - - /* - * Parse the Request-Line for the URI. - * - * For backwards HTTP version compatable reasons skip any leading - * CRLF (or CR or LF) line terminator(s) preceding Request-Line. - */ - while (cp < ep && (*cp == '\r' || *cp == '\n')) { - cp++; - } - while (cp < ep && *get == *cp) { - get++; - cp++; - } - if (*get != 0) { - /* Note a "GET", check for "POST" */ - while (cp < ep && *post == *cp) { - post++; - cp++; - } - if (*post != 0) { - if (cp == ep) { - nl7c_uri_more_get++; - goto more; - } - /* Not a "GET" or a "POST", just pass */ - nl7c_uri_pass_method++; - goto pass; - } - /* "POST", don't cache but still may want to parse */ - uri->hash = URI_TEMP; - } - /* - * Skip over URI path char(s) and save start and past end pointers. - */ - uris = cp; - while (cp < ep && (c = *cp) != ' ' && c != '\r') { - if (c == '?') { - /* Don't cache but still may want to parse */ - uri->hash = URI_TEMP; - } - CHASH(hv, c); - cp++; - } - if (c != '\r' && cp == ep) { - nl7c_uri_more_eol++; - goto more; - } - /* - * Request-Line URI parsed, pass the rest of the request on - * to the the http scheme parse. - */ - uri->path.cp = uris; - uri->path.ep = cp; - uri->hvalue = hv; - if (! nl7c_http_request(&cp, ep, uri, so) || cp == NULL) { - /* - * Parse not successful or pass on request, the pointer - * to the parse pointer "cp" is overloaded such that ! NULL - * for more data and NULL for bad parse of request or pass. - */ - if (cp != NULL) { - nl7c_uri_more_http++; - goto more; - } - nl7c_uri_pass_http++; - goto pass; - } - if (uri->nocache) { - uri->hash = URI_TEMP; - (void) uri_lookup(uri, B_FALSE, nonblocking); - } else if (uri->hash == URI_TEMP) { - uri->nocache = B_TRUE; - (void) uri_lookup(uri, B_FALSE, nonblocking); - } - - if (uri->hash == URI_TEMP) { - if (sti->sti_nl7c_flags & NL7C_SOPERSIST) { - /* Temporary URI so skip hash processing */ - nl7c_uri_request++; - nl7c_uri_temp++; - goto temp; - } - /* Not persistent so not interested in the response */ - nl7c_uri_pass_temp++; - goto pass; - } - /* - * Check the URI hash for a cached response, save the request - * uri in case we need it below. - */ - ruri = uri; - if ((uri = uri_lookup(uri, B_TRUE, nonblocking)) == NULL) { - /* - * Failed to lookup due to nonblocking wait required, - * interrupted cv_wait_sig(), KM_NOSLEEP memory alloc - * failure, ... Just pass on this request. - */ - nl7c_uri_pass_addfail++; - goto pass; - } - nl7c_uri_request++; - if (uri->response.sz > 0) { - /* - * We have the response cached, update recv mblk rptr - * to reflect the data consumed in parse. - */ - mblk_t *mp = sti->sti_nl7c_rcv_mp; - - if (cp == (char *)mp->b_wptr) { - sti->sti_nl7c_rcv_mp = mp->b_cont; - mp->b_cont = NULL; - freeb(mp); - } else { - mp->b_rptr = (unsigned char *)cp; - } - nl7c_uri_hit++; - /* If logging enabled log request */ - if (nl7c_logd_enabled) { - ipaddr_t faddr; - - if (so->so_family == AF_INET) { - /* Only support IPv4 addrs */ - faddr = ((struct sockaddr_in *) - sti->sti_faddr_sa) ->sin_addr.s_addr; - } else { - faddr = 0; - } - /* XXX need to pass response type, e.g. 200, 304 */ - nl7c_logd_log(ruri, uri, sti->sti_nl7c_rtime, faddr); - } - - /* If conditional request check for substitute response */ - if (ruri->conditional) { - uri = nl7c_http_cond(ruri, uri); - } - - /* - * Release reference on request URI, send the response out - * the socket, release reference on response uri, set the - * *ret value to B_TRUE to indicate request was consumed - * then return B_FALSE to indcate no more data needed. - */ - REF_RELE(ruri); - (void) uri_response(so, uri); - REF_RELE(uri); - *ret = B_TRUE; - return (B_FALSE); - } - /* - * Miss the cache, the request URI is in the cache waiting for - * application write-side data to fill it. - */ - nl7c_uri_miss++; -temp: - /* - * A miss or temp URI for which response data is needed, link - * uri to so and so to uri, set WAITWRITE in the so such that - * read-side processing is suspended (so the next read() gets - * the request data) until a write() is processed by NL7C. - * - * Note, sti->sti_nl7c_uri now owns the REF_INIT() ref. - */ - uri->proc = so; - sti->sti_nl7c_uri = uri; - sti->sti_nl7c_flags |= NL7C_WAITWRITE; - *ret = B_FALSE; - return (B_FALSE); - -more: - /* More data is needed, note fragmented recv not supported */ - nl7c_uri_more++; - -pass: - /* Pass on this request */ - nl7c_uri_pass++; - nl7c_uri_request++; - if (ruri != NULL) { - REF_RELE(ruri); - } - if (uri) { - REF_RELE(uri); - } - sti->sti_nl7c_flags = 0; - *ret = B_FALSE; - return (B_FALSE); -} diff --git a/usr/src/uts/common/fs/sockfs/nl7curi.h b/usr/src/uts/common/fs/sockfs/nl7curi.h deleted file mode 100644 index d002a0e5f9..0000000000 --- a/usr/src/uts/common/fs/sockfs/nl7curi.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_SOCKFS_NL7CURI_H -#define _SYS_SOCKFS_NL7CURI_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <sys/atomic.h> -#include <sys/cmn_err.h> -#include <sys/stropts.h> -#include <sys/socket.h> -#include <sys/socketvar.h> - -#undef PROMIF_DEBUG - -/* - * Some usefull chararcter macros: - */ - -#ifndef tolower -#define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) | 0x20 : (c)) -#endif - -#ifndef isdigit -#define isdigit(c) ((c) >= '0' && (c) <= '9') -#endif - -#ifndef isalpha -#define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) -#endif - -#ifndef isspace -#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || \ - (c) == '\r' || (c) == '\f' || (c) == '\013') -#endif - -/* - * ref_t - reference type, ... - * - * Note, all struct's must contain a single ref_t, all must use - * kmem_cache, all must use the REF_* macros for free. - */ - -typedef struct ref_s { - uint32_t cnt; /* Reference count */ - void (*last)(void *); /* Call-back for last ref */ - kmem_cache_t *kmc; /* Container allocator cache */ -} ref_t; - -#define REF_INIT(container, count, inactive, kmem) { \ - (container)->ref.cnt = (count); \ - (container)->ref.last = (void (*)(void *))((inactive)); \ - (container)->ref.kmc = (kmem); \ -} - -#define REF_HOLD(container) { \ - atomic_inc_32(&(container)->ref.cnt); \ - ASSERT((container)->ref.cnt != 0); \ -} - -#define REF_RELE(container) { \ - if (atomic_dec_32_nv(&(container)->ref.cnt) == 0) { \ - (container)->ref.last((container)); \ - kmem_cache_free((container)->ref.kmc, (container)); \ - } \ -} - -#define REF_COUNT(container) (container)->ref.cnt - -#define REF_ASSERT(container, count) \ - ASSERT((container)->ref.cnt == (count)); - -/* - * str_t - string type, used to access a an arbitrary span of a char[]. - */ - -typedef struct str_s { - char *cp; /* Char pointer current char */ - char *ep; /* Char pointer past end of string */ -} str_t; - -/* - * uri_*_t - URI descriptor, used to describe a cached URI object. - */ - -typedef struct uri_rd_s { - size_t sz; /* Size of data */ - offset_t off; /* Offset into file or -1 for kmem */ - union { /* Response data */ - char *kmem; /* Data in kmem */ - vnode_t *vnode; /* Data in vnode */ - } data; - struct uri_rd_s *next; /* Next response descriptor */ -} uri_rd_t; - -typedef struct uri_desc_s { - struct uri_desc_s *hash; /* Hash *next */ - uint64_t hit; /* Hit counter */ - clock_t expire; /* URI lbolt expires on (-1 = NEVER) */ -#ifdef notyet - void *sslctx; /* SSL context */ -#endif - boolean_t nocache; /* URI no cache */ - boolean_t conditional; /* Conditional response */ - uint32_t hvalue; /* Hashed value */ - - mblk_t *reqmp; /* Request mblk_t */ - str_t path; /* Path name of response */ - str_t auth; /* Authority for response */ - ssize_t resplen; /* Response length */ - ssize_t respclen; /* Response chunk length */ - char *eoh; /* End of header pointer */ - void *scheme; /* Scheme private state */ - - ref_t ref; /* Reference stuff */ - - size_t count; /* rd_t chain byte count */ - uri_rd_t *tail; /* Last response descriptor */ - uri_rd_t response; /* First response descriptor */ - - struct sonode *proc; /* Socket processing this uri */ - kcondvar_t waiting; /* Socket(s) waiting for processing */ - kmutex_t proclock; /* Lock for proc and waiting */ -} uri_desc_t; - -/* Hash the (char)c to the hash accumulator (uint32_t)hv */ -#define CHASH(hv, c) (hv) = ((hv) << 5) + (hv) + c; (hv) &= 0x7FFFFFFF - -#define URI_TEMP (uri_desc_t *)-1 /* Temp (nocache) uri_t.hash pointer */ - -#define URI_LEN_NOVALUE -1 /* Length (int) counter no value yet */ -#define URI_LEN_CONSUMED -2 /* Length (int) counter consumed */ - -typedef struct uri_segmap_s { - ref_t ref; /* Reference, one per uri_desb_t */ - caddr_t base; /* Base addr of segmap mapping */ - size_t len; /* Length of segmap mapping */ - vnode_t *vp; /* Vnode mapped */ -} uri_segmap_t; - -typedef struct uri_desb_s { - frtn_t frtn; /* For use by esballoc() and freinds */ - uri_desc_t *uri; /* Containing URI of REF_HOLD() */ - uri_segmap_t *segmap; /* If segmap mapped else NULL */ -} uri_desb_t; - -/* - * Add (and create if need be) a new uri_rd_t to a uri. - * - * Note, macro can block, must be called from a blockable context. - */ -#define URI_RD_ADD(uri, rdp, size, offset) { \ - if ((uri)->tail == NULL) { \ - (rdp) = &(uri)->response; \ - } else { \ - (rdp) = kmem_cache_alloc(nl7c_uri_rd_kmc, KM_SLEEP); \ - (uri)->tail->next = (rdp); \ - } \ - (rdp)->sz = size; \ - (rdp)->off = offset; \ - (rdp)->next = NULL; \ - (uri)->tail = rdp; \ - (uri)->count += size; \ -} - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_SOCKFS_NL7CURI_H */ diff --git a/usr/src/uts/common/fs/sockfs/sockcommon.c b/usr/src/uts/common/fs/sockfs/sockcommon.c index edcb41951c..27b1b3cf26 100644 --- a/usr/src/uts/common/fs/sockfs/sockcommon.c +++ b/usr/src/uts/common/fs/sockfs/sockcommon.c @@ -23,6 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015, Joyent, Inc. * Copyright 2017 Sebastian Wiedenroth + * Copyright 2022 Garrett D'Amore */ #include <sys/types.h> @@ -47,7 +48,6 @@ #include <inet/ipclassifier.h> #include <fs/sockfs/sockcommon.h> #include <fs/sockfs/sockfilter_impl.h> -#include <fs/sockfs/nl7c.h> #include <fs/sockfs/socktpi.h> #include <fs/sockfs/sodirect.h> #include <inet/ip.h> diff --git a/usr/src/uts/common/fs/sockfs/sockcommon_sops.c b/usr/src/uts/common/fs/sockfs/sockcommon_sops.c index 4c8784e974..b1f74b993b 100644 --- a/usr/src/uts/common/fs/sockfs/sockcommon_sops.c +++ b/usr/src/uts/common/fs/sockfs/sockcommon_sops.c @@ -26,6 +26,7 @@ /* * Copyright (c) 2015, Joyent, Inc. All rights reserved. * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Garrett D'Amore */ #include <sys/types.h> @@ -58,7 +59,6 @@ #include <fs/sockfs/socktpi_impl.h> #include <fs/sockfs/sodirect.h> #include <sys/tihdr.h> -#include <fs/sockfs/nl7c.h> extern int xnet_skip_checks; extern int xnet_check_print; @@ -233,33 +233,6 @@ so_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen, goto dobind; } - /* - * First we check if either NCA or KSSL has been enabled for - * the requested address, and if so, we fall back to TPI. - * If neither of those two services are enabled, then we just - * pass the request to the protocol. - * - * Note that KSSL can only be enabled on a socket if NCA is NOT - * enabled for that socket, hence the else-statement below. - */ - if (nl7c_enabled && ((so->so_family == AF_INET || - so->so_family == AF_INET6) && - nl7c_lookup_addr(name, namelen) != NULL)) { - /* - * NL7C is not supported in non-global zones, - * we enforce this restriction here. - */ - if (so->so_zoneid == GLOBAL_ZONEID) { - /* NCA should be used, so fall back to TPI */ - error = so_tpi_fallback(so, cr); - SO_UNBLOCK_FALLBACK(so); - if (error) - return (error); - else - return (SOP_BIND(so, name, namelen, flags, cr)); - } - } - dobind: if (so->so_filter_active == 0 || (error = sof_filter_bind(so, name, &namelen, cr)) < 0) { diff --git a/usr/src/uts/common/fs/sockfs/socksubr.c b/usr/src/uts/common/fs/sockfs/socksubr.c index 73c36ce0d4..3262150f79 100644 --- a/usr/src/uts/common/fs/sockfs/socksubr.c +++ b/usr/src/uts/common/fs/sockfs/socksubr.c @@ -24,6 +24,7 @@ * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright 2015, Joyent, Inc. All rights reserved. * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Garrett D'Amore */ #include <sys/types.h> @@ -72,7 +73,6 @@ #include <c2/audit.h> -#include <fs/sockfs/nl7c.h> #include <fs/sockfs/sockcommon.h> #include <fs/sockfs/sockfilter_impl.h> #include <fs/sockfs/socktpi.h> @@ -94,7 +94,6 @@ #define SO_LOCK_WAKEUP_TIME 3000 /* Wakeup time in milliseconds */ dev_t sockdev; /* For fsid in getattr */ -int sockfs_defer_nl7c_init = 0; struct socklist socklist; @@ -112,8 +111,6 @@ extern smod_info_t *sotpi_smod_create(void); extern void sendfile_init(); -extern void nl7c_init(void); - extern int modrootloaded; /* @@ -282,11 +279,6 @@ sockinit(int fstype, char *name) mutex_init(&socklist.sl_lock, NULL, MUTEX_DEFAULT, NULL); sendfile_init(); - if (!modrootloaded) { - sockfs_defer_nl7c_init = 1; - } else { - nl7c_init(); - } /* Initialize socket filters */ sof_init(); diff --git a/usr/src/uts/common/fs/sockfs/socksyscalls.c b/usr/src/uts/common/fs/sockfs/socksyscalls.c index 30666f73ca..b9eec810e3 100644 --- a/usr/src/uts/common/fs/sockfs/socksyscalls.c +++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c @@ -25,6 +25,7 @@ * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Garrett D'Amore */ #include <sys/types.h> @@ -69,7 +70,6 @@ #include <vm/seg_map.h> #include <vm/seg_kpm.h> -#include <fs/sockfs/nl7c.h> #include <fs/sockfs/sockcommon.h> #include <fs/sockfs/sockfilter_impl.h> #include <fs/sockfs/socktpi.h> @@ -82,9 +82,6 @@ int do_useracc = 1; /* Controlled by setting SO_DEBUG to 4 */ extern int xnet_truncate_print; -extern void nl7c_init(void); -extern int sockfs_defer_nl7c_init; - /* * Kernel component of socket creation. * @@ -1699,37 +1696,9 @@ sockconf_add_sock(int family, int type, int protocol, char *name) } if (strncmp(buf, "/dev", strlen("/dev")) == 0) { /* For device */ - - /* - * Special handling for NCA: - * - * DEV_NCA is never opened even if an application - * requests for AF_NCA. The device opened is instead a - * predefined AF_INET transport (NCA_INET_DEV). - * - * Prior to Volo (PSARC/2007/587) NCA would determine - * the device using a lookup, which worked then because - * all protocols were based on TPI. Since TPI is no - * longer the default, we have to explicitly state - * which device to use. - */ - if (strcmp(buf, NCA_DEV) == 0) { - /* only support entry <28, 2, 0> */ - if (family != AF_NCA || type != SOCK_STREAM || - protocol != 0) { - kmem_free(buf, MAXPATHLEN); - return (EINVAL); - } - - pathlen = strlen(NCA_INET_DEV) + 1; - kdevpath = kmem_alloc(pathlen, KM_SLEEP); - bcopy(NCA_INET_DEV, kdevpath, pathlen); - kdevpath[pathlen - 1] = '\0'; - } else { - kdevpath = kmem_alloc(pathlen, KM_SLEEP); - bcopy(buf, kdevpath, pathlen); - kdevpath[pathlen - 1] = '\0'; - } + kdevpath = kmem_alloc(pathlen, KM_SLEEP); + bcopy(buf, kdevpath, pathlen); + kdevpath[pathlen - 1] = '\0'; } else { /* For socket module */ kmodule = kmem_alloc(pathlen, KM_SLEEP); @@ -1929,11 +1898,6 @@ sockconfig(int cmd, void *arg1, void *arg2, void *arg3, void *arg4) if (secpolicy_net_config(CRED(), B_FALSE) != 0) return (set_errno(EPERM)); - if (sockfs_defer_nl7c_init) { - nl7c_init(); - sockfs_defer_nl7c_init = 0; - } - switch (cmd) { case SOCKCONFIG_ADD_SOCK: error = sockconf_add_sock((int)(uintptr_t)arg1, diff --git a/usr/src/uts/common/fs/sockfs/socktpi.c b/usr/src/uts/common/fs/sockfs/socktpi.c index 0e9883498b..678dce986a 100644 --- a/usr/src/uts/common/fs/sockfs/socktpi.c +++ b/usr/src/uts/common/fs/sockfs/socktpi.c @@ -23,6 +23,7 @@ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015, Joyent, Inc. * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright 2022 Garrett D'Amore */ #include <sys/types.h> @@ -78,9 +79,6 @@ #include <sys/zone.h> -#include <fs/sockfs/nl7c.h> -#include <fs/sockfs/nl7curi.h> - #include <fs/sockfs/sockcommon.h> #include <fs/sockfs/socktpi.h> #include <fs/sockfs/socktpi_impl.h> @@ -314,10 +312,6 @@ sotpi_create(struct sockparams *sp, int family, int type, int protocol, sonode_init(so, sp, family, type, protocol, &sotpi_sonodeops); sotpi_info_init(so); - if (sfamily == AF_NCA) { - SOTOTPI(so)->sti_nl7c_flags = NL7C_AF_NCA; - } - if (version == SOV_DEFAULT) version = so_default_version; @@ -646,7 +640,6 @@ sotpi_bindlisten(struct sonode *so, struct sockaddr *name, int save_so_backlog; t_scalar_t PRIM_type = O_T_BIND_REQ; boolean_t tcp_udp_xport; - void *nl7c = NULL; sotpi_info_t *sti = SOTOTPI(so); dprintso(so, 1, ("sotpi_bindlisten(%p, %p, %d, %d, 0x%x) %s\n", @@ -1043,35 +1036,6 @@ sotpi_bindlisten(struct sonode *so, struct sockaddr *name, } /* - * If NL7C addr(s) have been configured check for addr/port match, - * or if an implicit NL7C socket via AF_NCA mark socket as NL7C. - * - * NL7C supports the TCP transport only so check AF_INET and AF_INET6 - * family sockets only. If match mark as such. - */ - if (nl7c_enabled && ((addr != NULL && - (so->so_family == AF_INET || so->so_family == AF_INET6) && - (nl7c = nl7c_lookup_addr(addr, addrlen))) || - sti->sti_nl7c_flags == NL7C_AF_NCA)) { - /* - * NL7C is not supported in non-global zones, - * we enforce this restriction here. - */ - if (so->so_zoneid == GLOBAL_ZONEID) { - /* An NL7C socket, mark it */ - sti->sti_nl7c_flags |= NL7C_ENABLED; - if (nl7c == NULL) { - /* - * Was an AF_NCA bind() so add it to the - * addr list for reporting purposes. - */ - nl7c = nl7c_add_addr(addr, addrlen); - } - } else - nl7c = NULL; - } - - /* * We send a T_BIND_REQ for TCP/UDP since we know it supports it, * for other transports we will send in a O_T_BIND_REQ. */ @@ -1351,11 +1315,6 @@ sotpi_bindlisten(struct sonode *so, struct sockaddr *name, } } - if (nl7c != NULL) { - /* Register listen()er sonode pointer with NL7C */ - nl7c_listener_addr(nl7c, so); - } - freemsg(mp); done: @@ -1965,39 +1924,6 @@ again: nso->so_proto_handle = (sock_lower_handle_t)opt; nsti->sti_laddr_valid = 1; - if (sti->sti_nl7c_flags & NL7C_ENABLED) { - /* - * A NL7C marked listen()er so the new socket - * inherits the listen()er's NL7C state, except - * for NL7C_POLLIN. - * - * Only call NL7C to process the new socket if - * the listen socket allows blocking i/o. - */ - nsti->sti_nl7c_flags = - sti->sti_nl7c_flags & (~NL7C_POLLIN); - if (so->so_state & (SS_NONBLOCK|SS_NDELAY)) { - /* - * Nonblocking accept() just make it - * persist to defer processing to the - * read-side syscall (e.g. read). - */ - nsti->sti_nl7c_flags |= NL7C_SOPERSIST; - } else if (nl7c_process(nso, B_FALSE)) { - /* - * NL7C has completed processing on the - * socket, close the socket and back to - * the top to await the next T_CONN_IND. - */ - mutex_exit(&nso->so_lock); - (void) VOP_CLOSE(nvp, 0, 1, (offset_t)0, - cr, NULL); - VN_RELE(nvp); - goto again; - } - /* Pass the new socket out */ - } - mutex_exit(&nso->so_lock); /* @@ -2981,75 +2907,6 @@ sorecv_update_oobstate(struct sonode *so) } /* - * Handle recv* calls for an so which has NL7C saved recv mblk_t(s). - */ -static int -nl7c_sorecv(struct sonode *so, mblk_t **rmp, uio_t *uiop, rval_t *rp) -{ - sotpi_info_t *sti = SOTOTPI(so); - int error = 0; - mblk_t *tmp = NULL; - mblk_t *pmp = NULL; - mblk_t *nmp = sti->sti_nl7c_rcv_mp; - - ASSERT(nmp != NULL); - - while (nmp != NULL && uiop->uio_resid > 0) { - ssize_t n; - - if (DB_TYPE(nmp) == M_DATA) { - /* - * We have some data, uiomove up to resid bytes. - */ - n = MIN(MBLKL(nmp), uiop->uio_resid); - if (n > 0) - error = uiomove(nmp->b_rptr, n, UIO_READ, uiop); - nmp->b_rptr += n; - if (nmp->b_rptr == nmp->b_wptr) { - pmp = nmp; - nmp = nmp->b_cont; - } - if (error) - break; - } else { - /* - * We only handle data, save for caller to handle. - */ - if (pmp != NULL) { - pmp->b_cont = nmp->b_cont; - } - nmp->b_cont = NULL; - if (*rmp == NULL) { - *rmp = nmp; - } else { - tmp->b_cont = nmp; - } - nmp = nmp->b_cont; - tmp = nmp; - } - } - if (pmp != NULL) { - /* Free any mblk_t(s) which we have consumed */ - pmp->b_cont = NULL; - freemsg(sti->sti_nl7c_rcv_mp); - } - if ((sti->sti_nl7c_rcv_mp = nmp) == NULL) { - /* Last mblk_t so return the saved kstrgetmsg() rval/error */ - if (error == 0) { - rval_t *p = (rval_t *)&sti->sti_nl7c_rcv_rval; - - error = p->r_v.r_v2; - p->r_v.r_v2 = 0; - } - rp->r_vals = sti->sti_nl7c_rcv_rval; - sti->sti_nl7c_rcv_rval = 0; - } else { - /* More mblk_t(s) to process so no rval to return */ - rp->r_vals = 0; - } - return (error); -} -/* * Receive the next message on the queue. * If msg_controllen is non-zero when called the caller is interested in * any received control info (options). @@ -3138,55 +2995,6 @@ sotpi_recvmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop, mutex_enter(&so->so_lock); /* - * If an NL7C enabled socket and not waiting for write data. - */ - if ((sti->sti_nl7c_flags & (NL7C_ENABLED | NL7C_WAITWRITE)) == - NL7C_ENABLED) { - if (sti->sti_nl7c_uri) { - /* Close uri processing for a previous request */ - nl7c_close(so); - } - if ((so_state & SS_CANTRCVMORE) && - sti->sti_nl7c_rcv_mp == NULL) { - /* Nothing to process, EOF */ - mutex_exit(&so->so_lock); - return (0); - } else if (sti->sti_nl7c_flags & NL7C_SOPERSIST) { - /* Persistent NL7C socket, try to process request */ - boolean_t ret; - - ret = nl7c_process(so, - (so->so_state & (SS_NONBLOCK|SS_NDELAY))); - rval.r_vals = sti->sti_nl7c_rcv_rval; - error = rval.r_v.r_v2; - if (error) { - /* Error of some sort, return it */ - mutex_exit(&so->so_lock); - return (error); - } - if (sti->sti_nl7c_flags && - ! (sti->sti_nl7c_flags & NL7C_WAITWRITE)) { - /* - * Still an NL7C socket and no data - * to pass up to the caller. - */ - mutex_exit(&so->so_lock); - if (ret) { - /* EOF */ - return (0); - } else { - /* Need more data */ - return (EAGAIN); - } - } - } else { - /* - * Not persistent so no further NL7C processing. - */ - sti->sti_nl7c_flags = 0; - } - } - /* * Only one reader is allowed at any given time. This is needed * for T_EXDATA handling and, in the future, MSG_WAITALL. * @@ -3239,13 +3047,8 @@ retry: saved_resid = uiop->uio_resid; pri = 0; mp = NULL; - if (sti->sti_nl7c_rcv_mp != NULL) { - /* Already kstrgetmsg()ed saved mblk(s) from NL7C */ - error = nl7c_sorecv(so, &mp, uiop, &rval); - } else { - error = kstrgetmsg(SOTOV(so), &mp, uiop, &pri, &pflag, - timout, &rval); - } + error = kstrgetmsg(SOTOV(so), &mp, uiop, &pri, &pflag, + timout, &rval); if (error != 0) { /* kstrgetmsg returns ETIME when timeout expires */ if (error == ETIME) @@ -4555,11 +4358,6 @@ sotpi_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop, dprintso(so, 1, ("sotpi_sendmsg: write\n")); /* Send M_DATA messages */ - if ((sti->sti_nl7c_flags & NL7C_ENABLED) && - (error = nl7c_data(so, uiop)) >= 0) { - /* NL7C consumed the data */ - return (error); - } /* * If there is no SO_DONTROUTE to turn off, * sti_direct is on, and there is no flow @@ -5837,11 +5635,6 @@ sotpi_close(struct sonode *so, int flag, struct cred *cr) ASSERT(so_verify_oobstate(so)); - if (sti->sti_nl7c_flags & NL7C_ENABLED) { - sti->sti_nl7c_flags = 0; - nl7c_close(so); - } - if (vp->v_stream != NULL) { vnode_t *ux_vp; @@ -6426,14 +6219,6 @@ sotpi_poll( if (so->so_state & SS_OOBPEND) *reventsp |= POLLRDBAND & events; - if (sti->sti_nl7c_rcv_mp != NULL) { - *reventsp |= (POLLIN|POLLRDNORM) & events; - } - if ((sti->sti_nl7c_flags & NL7C_ENABLED) && - ((POLLIN|POLLRDNORM) & *reventsp)) { - sti->sti_nl7c_flags |= NL7C_POLLIN; - } - return (0); } @@ -6734,10 +6519,6 @@ i_sotpi_info_constructor(sotpi_info_t *sti) sti->sti_laddr_sa = NULL; sti->sti_faddr_sa = NULL; - sti->sti_nl7c_flags = 0; - sti->sti_nl7c_uri = NULL; - sti->sti_nl7c_rcv_mp = NULL; - mutex_init(&sti->sti_plumb_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&sti->sti_ack_cv, NULL, CV_DEFAULT, NULL); @@ -6759,10 +6540,6 @@ i_sotpi_info_destructor(sotpi_info_t *sti) ASSERT(sti->sti_laddr_sa == NULL); ASSERT(sti->sti_faddr_sa == NULL); - ASSERT(sti->sti_nl7c_flags == 0); - ASSERT(sti->sti_nl7c_uri == NULL); - ASSERT(sti->sti_nl7c_rcv_mp == NULL); - mutex_destroy(&sti->sti_plumb_lock); cv_destroy(&sti->sti_ack_cv); } @@ -6895,19 +6672,6 @@ sotpi_info_fini(struct sonode *so) sti->sti_ack_mp = NULL; } - if ((mp = sti->sti_nl7c_rcv_mp) != NULL) { - sti->sti_nl7c_rcv_mp = NULL; - freemsg(mp); - } - sti->sti_nl7c_rcv_rval = 0; - if (sti->sti_nl7c_uri != NULL) { - nl7c_urifree(so); - /* urifree() cleared nl7c_uri */ - } - if (sti->sti_nl7c_flags) { - sti->sti_nl7c_flags = 0; - } - ASSERT(sti->sti_ux_bound_vp == NULL); if ((mp = sti->sti_unbind_mp) != NULL) { freemsg(mp); diff --git a/usr/src/uts/common/fs/sockfs/socktpi.h b/usr/src/uts/common/fs/sockfs/socktpi.h index 8da8392a68..15d128afb5 100644 --- a/usr/src/uts/common/fs/sockfs/socktpi.h +++ b/usr/src/uts/common/fs/sockfs/socktpi.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Garrett D'Amore */ #ifndef _SOCKFS_SOCKTPI_H @@ -224,30 +225,6 @@ typedef struct sotpi_info { struct sonode *sti_next_so; /* next sonode on socklist */ struct sonode *sti_prev_so; /* previous sonode on socklist */ mblk_t *sti_discon_ind_mp; /* T_DISCON_IND received from below */ - - /* - * For NL7C sockets: - * - * sti_nl7c_flags the NL7C state of URL processing. - * - * sti_nl7c_rcv_mp mblk_t chain of already received data to be - * passed up to the app after NL7C gives up on - * a socket. - * - * sti_nl7c_rcv_rval returned rval for last mblk_t from above. - * - * sti_nl7c_uri the URI currently being processed. - * - * sti_nl7c_rtime URI request gethrestime_sec(). - * - * sti_nl7c_addr pointer returned by nl7c_addr_lookup(). - */ - uint64_t sti_nl7c_flags; - mblk_t *sti_nl7c_rcv_mp; - int64_t sti_nl7c_rcv_rval; - void *sti_nl7c_uri; - time_t sti_nl7c_rtime; - void *sti_nl7c_addr; } sotpi_info_t; struct T_capability_ack; @@ -262,7 +239,7 @@ extern void sotpi_update_state(struct sonode *, struct T_capability_ack *, struct sockaddr *, socklen_t, struct sockaddr *, socklen_t, short); -extern sotpi_info_t *sotpi_sototpi(struct sonode *); +extern sotpi_info_t *sotpi_sototpi(struct sonode *); #ifdef DEBUG #define SOTOTPI(so) (sotpi_sototpi(so)) #else diff --git a/usr/src/uts/common/inet/nca/ncaddi.c b/usr/src/uts/common/inet/nca/ncaddi.c deleted file mode 100644 index f02924d131..0000000000 --- a/usr/src/uts/common/inet/nca/ncaddi.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * Copyright (c) 2011 Bayard G. Bell. All rights reserved. - */ - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/stream.h> -#include <sys/strsubr.h> -#include <sys/strsun.h> -#include <sys/zone.h> -#include <inet/common.h> -#include <inet/led.h> -#include <inet/nd.h> -#include <netinet/in.h> - -#include "ncaconf.h" - -extern caddr_t nca_g_nd; /* Head of 'named dispatch' variable list */ - -#define INET_NAME "nca" -#define INET_MODSTRTAB ncainfo -#define INET_DEVSTRTAB ncainfo -#define INET_MODDESC "NCA STREAMS module 1.6" -#define INET_DEVDESC "NCA STREAMS driver 1.6" -#define INET_DEVMINOR 0 -#define INET_DEVMTFLAGS D_MP -#define INET_MODMTFLAGS D_MP - -#include "../inetddi.c" - -/*ARGSUSED*/ -static int -nca_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) -{ - /* Reopen supported */ - if (q->q_ptr != NULL) - return (0); - - /* - * NCA is not supported in non-global zones; we enforce this restriction - * here. - */ - if (credp != NULL && crgetzoneid(credp) != GLOBAL_ZONEID) { - return (ENOTSUP); - } - - if (! (sflag & MODOPEN)) { - /* Device instance */ - RD(q)->q_ptr = (void *)B_TRUE; - WR(q)->q_ptr = (void *)B_TRUE; - } else { - /* Modopen just pass through */ - RD(q)->q_ptr = (void *)B_FALSE; - WR(q)->q_ptr = (void *)B_FALSE; - } - qprocson(q); - return (0); -} - -/* ARGSUSED */ -static int -nca_close(queue_t *q, int flags __unused, cred_t *credp __unused) -{ - qprocsoff(q); - RD(q)->q_ptr = NULL; - WR(q)->q_ptr = NULL; - return (0); -} - -static int -nca_rput(queue_t *q, mblk_t *mp) -{ - /* Passthrough */ - putnext(q, mp); - return (0); -} - -static int -nca_wput(queue_t *q, mblk_t *mp) -{ - struct iocblk *iocp; - - if (! (boolean_t)q->q_ptr) { - iocp = (struct iocblk *)mp->b_rptr; - if (DB_TYPE(mp) == M_IOCTL && iocp->ioc_cmd == NCA_SET_IF) { - miocnak(q, mp, 0, ENOTSUP); - return (0); - } - /* Module, passthrough */ - putnext(q, mp); - return (0); - } - - switch (DB_TYPE(mp)) { - case M_IOCTL: - iocp = (struct iocblk *)mp->b_rptr; - switch (iocp->ioc_cmd) { - case ND_SET: - case ND_GET: - if (! nd_getset(q, nca_g_nd, mp)) { - miocnak(q, mp, 0, ENOENT); - return (0); - } - qreply(q, mp); - break; - default: - miocnak(q, mp, 0, ENOTSUP); - break; - } - break; - default: - freemsg(mp); - break; - } - return (0); -} - -static struct module_info info = { - 0, "nca", 1, INFPSZ, 65536, 1024 -}; - -static struct qinit rinit = { - nca_rput, NULL, nca_open, nca_close, NULL, &info -}; - -static struct qinit winit = { - nca_wput, NULL, nca_open, nca_close, NULL, &info -}; - -struct streamtab ncainfo = { - &rinit, &winit -}; - -int -_init(void) -{ - return (mod_install(&modlinkage)); -} - -int -_fini(void) -{ - return (EBUSY); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} diff --git a/usr/src/uts/common/io/ksocket/ksocket.c b/usr/src/uts/common/io/ksocket/ksocket.c index 3ce44cce55..3eb23f1dbe 100644 --- a/usr/src/uts/common/io/ksocket/ksocket.c +++ b/usr/src/uts/common/io/ksocket/ksocket.c @@ -23,6 +23,7 @@ * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015, Joyent, Inc. + * Copyright 2022 Garrett D'Amore */ #include <sys/file.h> @@ -57,9 +58,6 @@ ksocket_socket(ksocket_t *ksp, int domain, int type, int protocol, int flags, /* All Solaris components should pass a cred for this operation. */ ASSERT(cr != NULL); - if (domain == AF_NCA) - return (EAFNOSUPPORT); - ASSERT(flags == KSOCKET_SLEEP || flags == KSOCKET_NOSLEEP); so = socket_create(domain, type, protocol, NULL, NULL, version, flags, cr, &error); diff --git a/usr/src/uts/common/sys/socket.h b/usr/src/uts/common/sys/socket.h index 30f7367bcd..9e61bc7bb0 100644 --- a/usr/src/uts/common/sys/socket.h +++ b/usr/src/uts/common/sys/socket.h @@ -19,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2014 Garrett D'Amore <garrett@damore.org> - * * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015, Joyent, Inc. All rights reserved. + * Copyright 2022 Garrett D'Amore + * */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -160,7 +160,7 @@ typedef void *_RESTRICT_KYWD Psocklen_t; /* when doing zero-copy */ struct so_snd_bufinfo { - ushort_t sbi_wroff; /* Write offset */ + ushort_t sbi_wroff; /* Write offset */ ssize_t sbi_maxblk; /* Max size of a single mblk */ ssize_t sbi_maxpsz; /* Max total size of a mblk chain */ ushort_t sbi_tail; /* Extra space available at the end */ @@ -299,7 +299,7 @@ struct linger { #define AF_LINK 25 /* Link-layer interface */ #define AF_INET6 26 /* Internet Protocol, Version 6 */ #define AF_KEY 27 /* Security Association DB socket */ -#define AF_NCA 28 /* NCA socket */ +#define AF_NCA 28 /* NCA socket (obsolete) */ #define AF_POLICY 29 /* Security Policy DB socket */ #define AF_INET_OFFLOAD 30 /* Sun private; do not use */ #define AF_TRILL 31 /* TRILL interface */ diff --git a/usr/src/uts/common/syscall/sendfile.c b/usr/src/uts/common/syscall/sendfile.c index 7cfd5bc188..d0667061d3 100644 --- a/usr/src/uts/common/syscall/sendfile.c +++ b/usr/src/uts/common/syscall/sendfile.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Garrett D'Amore */ #include <sys/types.h> @@ -68,8 +69,6 @@ extern int sosendfile64(file_t *, file_t *, const struct ksendfilevec64 *, ssize32_t *); -extern int nl7c_sendfilev(struct sonode *, u_offset_t *, struct sendfilevec *, - int, ssize_t *); extern int snf_segmap(file_t *, vnode_t *, u_offset_t, u_offset_t, ssize_t *, boolean_t); extern sotpi_info_t *sotpi_sototpi(struct sonode *); @@ -1319,16 +1318,9 @@ sendfilev(int opcode, int fildes, const struct sendfilevec *vec, int sfvcnt, * Future zero copy code will plugin into sendvec_chunk * only because doing zero copy for files smaller then * pagesize is useless. - * - * Note, if socket has NL7C enabled then call NL7C's - * senfilev() function to consume the sfv[]. */ if (is_sock) { - if (!SOCK_IS_NONSTR(so) && - _SOTOTPI(so)->sti_nl7c_flags != 0) { - error = nl7c_sendfilev(so, &fileoff, - sfv, copy_cnt, &count); - } else if ((total_size <= (4 * maxblk)) && + if ((total_size <= (4 * maxblk)) && error == 0) { error = sendvec_small_chunk(fp, &fileoff, sfv, copy_cnt, diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index a3708e086a..ac4d9a0548 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -279,7 +279,6 @@ DRV_KMODS += mouse8042 DRV_KMODS += mpt_sas DRV_KMODS += mr_sas DRV_KMODS += mwl -DRV_KMODS += nca DRV_KMODS += nsmb DRV_KMODS += nulldriver DRV_KMODS += nv_sata diff --git a/usr/src/uts/intel/ml/modstubs.s b/usr/src/uts/intel/ml/modstubs.s index 0f97c21ac6..ec0eefd9f7 100644 --- a/usr/src/uts/intel/ml/modstubs.s +++ b/usr/src/uts/intel/ml/modstubs.s @@ -364,7 +364,6 @@ fcnname/**/_info: \ NO_UNLOAD_STUB(sockfs, sosendfile64, nomod_zero); NO_UNLOAD_STUB(sockfs, snf_segmap, nomod_einval); NO_UNLOAD_STUB(sockfs, sock_getfasync, nomod_zero); - NO_UNLOAD_STUB(sockfs, nl7c_sendfilev, nomod_zero); NO_UNLOAD_STUB(sockfs, sotpi_sototpi, nomod_zero); NO_UNLOAD_STUB(sockfs, socket_sendmblk, nomod_zero); NO_UNLOAD_STUB(sockfs, socket_setsockopt, nomod_zero); diff --git a/usr/src/uts/intel/nca/Makefile b/usr/src/uts/intel/nca/Makefile deleted file mode 100644 index afdba0d636..0000000000 --- a/usr/src/uts/intel/nca/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# uts/intel/nca/Makefile -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Copyright (c) 2018, Joyent, Inc. - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = nca -OBJECTS = $(NCA_OBJS:%=$(OBJS_DIR)/%) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/common/inet/nca - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) - -# -# Overrides -# -LDFLAGS += -Nfs/sockfs -Ndrv/ip - -# needs work -$(OBJS_DIR)/ncaddi.o := SMOFF += index_overflow - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -install: $(INSTALL_DEPS) - -$(ROOTLINK): $(ROOT_STRMOD_DIR) $(ROOTMODULE) - -$(RM) $@; ln $(ROOTMODULE) $@ - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ diff --git a/usr/src/uts/intel/sockrds/Makefile b/usr/src/uts/intel/sockrds/Makefile index bf78373d38..80a2d0d145 100644 --- a/usr/src/uts/intel/sockrds/Makefile +++ b/usr/src/uts/intel/sockrds/Makefile @@ -21,9 +21,6 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # -# This makefile drives the production of the nca driver -# kernel module. -# # intel architecture dependent # diff --git a/usr/src/uts/intel/socksctp/Makefile b/usr/src/uts/intel/socksctp/Makefile index fa43835eae..bba3ad9bbe 100644 --- a/usr/src/uts/intel/socksctp/Makefile +++ b/usr/src/uts/intel/socksctp/Makefile @@ -22,9 +22,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# This makefile drives the production of the nca driver -# kernel module. -# # intel architecture dependent # diff --git a/usr/src/uts/intel/socksdp/Makefile b/usr/src/uts/intel/socksdp/Makefile index 6c4029ba03..b9b9da1c90 100644 --- a/usr/src/uts/intel/socksdp/Makefile +++ b/usr/src/uts/intel/socksdp/Makefile @@ -22,9 +22,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# This makefile drives the production of the nca driver -# kernel module. -# # intel architecture dependent # diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc index 8c8ca81e30..19dc78dea0 100644 --- a/usr/src/uts/sparc/Makefile.sparc +++ b/usr/src/uts/sparc/Makefile.sparc @@ -207,7 +207,7 @@ DRV_KMODS += dtrace fasttrap fbt lockstat profile sdt systrace dcpc DRV_KMODS += fssnap icmp icmp6 ip ip6 ipnet ipsecah DRV_KMODS += ipsecesp iptun iwscn keysock kmdb kstat ksyms llc1 DRV_KMODS += lofi -DRV_KMODS += log logindmux mm nca physmem pm poll pool +DRV_KMODS += log logindmux mm physmem pm poll pool DRV_KMODS += pseudo ptc ptm pts ptsl ramdisk random rsm rts sad DRV_KMODS += simnet softmac sppp sppptun sy sysevent sysmsg DRV_KMODS += spdsock diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s index f43346fd48..07aff93702 100644 --- a/usr/src/uts/sparc/ml/modstubs.s +++ b/usr/src/uts/sparc/ml/modstubs.s @@ -377,7 +377,6 @@ stubs_base: NO_UNLOAD_STUB(sockfs, sosendfile64, nomod_zero); NO_UNLOAD_STUB(sockfs, snf_segmap, nomod_einval); NO_UNLOAD_STUB(sockfs, sock_getfasync, nomod_zero); - NO_UNLOAD_STUB(sockfs, nl7c_sendfilev, nomod_zero); NO_UNLOAD_STUB(sockfs, sotpi_sototpi, nomod_zero); NO_UNLOAD_STUB(sockfs, socket_sendmblk, nomod_zero); NO_UNLOAD_STUB(sockfs, socket_setsockopt, nomod_zero); diff --git a/usr/src/uts/sparc/nca/Makefile b/usr/src/uts/sparc/nca/Makefile deleted file mode 100644 index e44ddf4c8d..0000000000 --- a/usr/src/uts/sparc/nca/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# -# This makefile drives the production of the nca driver -# kernel module. -# -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = nca -OBJECTS = $(NCA_OBJS:%=$(OBJS_DIR)/%) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/common/inet/nca - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# Define targets -# -ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) - -CFLAGS += $(CCVERBOSE) - -LDFLAGS += -Nfs/sockfs -Ndrv/ip - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -install: $(INSTALL_DEPS) - -$(ROOTLINK): $(ROOT_STRMOD_DIR) $(ROOTMODULE) - -$(RM) $@; ln $(ROOTMODULE) $@ - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ diff --git a/usr/src/uts/sparc/sockpfp/Makefile b/usr/src/uts/sparc/sockpfp/Makefile index 3f90a0acd1..647b37dfcc 100644 --- a/usr/src/uts/sparc/sockpfp/Makefile +++ b/usr/src/uts/sparc/sockpfp/Makefile @@ -22,9 +22,6 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# This makefile drives the production of the nca driver -# kernel module. -# # sparc architecture dependent # diff --git a/usr/src/uts/sparc/sockrds/Makefile b/usr/src/uts/sparc/sockrds/Makefile index 526b6e7a81..74fd11f083 100644 --- a/usr/src/uts/sparc/sockrds/Makefile +++ b/usr/src/uts/sparc/sockrds/Makefile @@ -23,9 +23,6 @@ # # -# This makefile drives the production of the nca driver -# kernel module. -# # sparc architecture dependent # diff --git a/usr/src/uts/sparc/socksctp/Makefile b/usr/src/uts/sparc/socksctp/Makefile index bece5cb8db..f59aaa0e00 100644 --- a/usr/src/uts/sparc/socksctp/Makefile +++ b/usr/src/uts/sparc/socksctp/Makefile @@ -23,9 +23,6 @@ # Use is subject to license terms. # -# This makefile drives the production of the nca driver -# kernel module. -# # sparc architecture dependent # diff --git a/usr/src/uts/sparc/socksdp/Makefile b/usr/src/uts/sparc/socksdp/Makefile index e69985523b..34817b87a8 100644 --- a/usr/src/uts/sparc/socksdp/Makefile +++ b/usr/src/uts/sparc/socksdp/Makefile @@ -23,9 +23,6 @@ # Use is subject to license terms. # -# This makefile drives the production of the nca driver -# kernel module. -# # sparc architecture dependent # |
