3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
32 * Server Cache Synchronization Protocol (SCSP) Support
33 * ----------------------------------------------------
35 * SCSP socket management routines
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <netatm/port.h>
45 #include <netatm/queue.h>
46 #include <netatm/atm.h>
47 #include <netatm/atm_if.h>
48 #include <netatm/atm_sap.h>
49 #include <netatm/atm_sys.h>
50 #include <netatm/atm_ioctl.h>
66 __RCSID("@(#) $FreeBSD$");
73 static struct t_atm_llc llc_scsp = {
76 {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x5e, 0x00, 0x05}
79 static struct t_atm_aal5 aal5 = {
80 0, /* forward_max_SDU_size */
81 0, /* backward_max_SDU_size */
85 static struct t_atm_traffic traffic = {
87 T_ATM_ABSENT, /* PCR_high_priority */
88 0, /* PCR_all_traffic */
89 T_ATM_ABSENT, /* SCR_high_priority */
90 T_ATM_ABSENT, /* SCR_all_traffic */
91 T_ATM_ABSENT, /* MBS_high_priority */
92 T_ATM_ABSENT, /* MBS_all_traffic */
96 T_ATM_ABSENT, /* PCR_high_priority */
97 0, /* PCR_all_traffic */
98 T_ATM_ABSENT, /* SCR_high_priority */
99 T_ATM_ABSENT, /* SCR_all_traffic */
100 T_ATM_ABSENT, /* MBS_high_priority */
101 T_ATM_ABSENT, /* MBS_all_traffic */
104 T_YES /* best_effort */
107 static struct t_atm_bearer bearer = {
108 T_ATM_CLASS_X, /* bearer_class */
109 T_ATM_NULL, /* traffic_type */
110 T_ATM_NULL, /* timing_requirements */
111 T_NO, /* clipping_susceptibility */
112 T_ATM_1_TO_1 /* connection_configuration */
115 static struct t_atm_qos qos = {
116 T_ATM_NETWORK_CODING, /* coding_standard */
118 T_ATM_QOS_CLASS_0 /* qos_class */
121 T_ATM_QOS_CLASS_0 /* qos_class */
125 static struct t_atm_app_name appname = {
131 * Find a DCS, given its socket
134 * sd socket descriptor
138 * address of DCS block corresponding to socket
146 Scsp_dcs *dcsp = NULL;
149 * Loop through the list of servers
151 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
153 * Check all the DCSs chained from each server
155 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
156 if (dcsp->sd_sock == sd)
166 * Find a server, given its socket
169 * sd socket descriptor
173 * address of server block corresponding to socket
183 * Loop through the list of servers
185 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
186 if (ssp->ss_sock == sd)
195 * Connect to a directly connected server
198 * dcsp pointer to DCS block for server
201 * 0 success (dcsp->sd_sock is set)
202 * else errno indicating reason for failure
206 scsp_dcs_connect(dcsp)
211 struct sockaddr_atm DCS_addr;
214 * If the DCS already has an open connection, just return
216 if (dcsp->sd_sock != -1) {
223 sd = socket(PF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5);
225 return(ESOCKTNOSUPPORT);
227 if (sd > scsp_max_socket) {
228 scsp_max_socket = sd;
232 * Set up connection parameters for SCSP connection
234 bzero(&DCS_addr, sizeof(DCS_addr));
235 #if (defined(BSD) && (BSD >= 199103))
236 DCS_addr.satm_len = sizeof(DCS_addr);
238 DCS_addr.satm_family = AF_ATM;
239 DCS_addr.satm_addr.t_atm_sap_addr.SVE_tag_addr =
241 DCS_addr.satm_addr.t_atm_sap_addr.SVE_tag_selector =
243 DCS_addr.satm_addr.t_atm_sap_addr.address_format =
244 dcsp->sd_addr.address_format;
245 DCS_addr.satm_addr.t_atm_sap_addr.address_length =
246 dcsp->sd_addr.address_length;
247 bcopy(dcsp->sd_addr.address,
248 DCS_addr.satm_addr.t_atm_sap_addr.address,
249 dcsp->sd_addr.address_length);
251 DCS_addr.satm_addr.t_atm_sap_layer2.SVE_tag =
253 DCS_addr.satm_addr.t_atm_sap_layer2.ID_type =
255 DCS_addr.satm_addr.t_atm_sap_layer2.ID.simple_ID =
258 DCS_addr.satm_addr.t_atm_sap_layer3.SVE_tag =
260 DCS_addr.satm_addr.t_atm_sap_appl.SVE_tag =
264 * Bind the socket to our address
266 if (bind(sd, (struct sockaddr *)&DCS_addr,
273 * Set non-blocking operation
276 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
278 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
281 scsp_log(LOG_ERR, "scsp_dcs_connect: fcntl failed");
289 aal5.forward_max_SDU_size = dcsp->sd_server->ss_mtu;
290 aal5.backward_max_SDU_size = dcsp->sd_server->ss_mtu;
291 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_AAL5, (caddr_t)&aal5,
298 * Set traffic options
300 switch(dcsp->sd_server->ss_media) {
302 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI100;
303 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI100;
306 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI140;
307 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI140;
311 traffic.forward.PCR_all_traffic = ATM_PCR_OC3C;
312 traffic.backward.PCR_all_traffic = ATM_PCR_OC3C;
315 traffic.forward.PCR_all_traffic = ATM_PCR_OC12C;
316 traffic.backward.PCR_all_traffic = ATM_PCR_OC12C;
322 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_TRAFFIC,
323 (caddr_t)&traffic, sizeof(traffic)) < 0) {
329 * Set bearer capability options
331 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_BEARER_CAP,
332 (caddr_t)&bearer, sizeof(bearer)) < 0) {
340 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_QOS,
341 (caddr_t)&qos, sizeof(qos)) < 0) {
349 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_LLC,
350 (caddr_t)&llc_scsp, sizeof(llc_scsp)) < 0) {
356 * Set application name
358 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_APP_NAME,
359 (caddr_t)&appname, sizeof(appname)) < 0) {
367 if (connect(sd, (struct sockaddr *)&DCS_addr,
368 sizeof(DCS_addr)) < 0 &&
369 errno != EINPROGRESS) {
382 * Close the socket if something didn't work
393 * Listen for ATM connections from DCSs
399 * sock socket which is listening (also set in
401 * -1 error encountered (reason in errno)
409 struct sockaddr_atm ls_addr;
414 sd = socket(PF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5);
419 if (sd > scsp_max_socket) {
420 scsp_max_socket = sd;
426 bzero(&ls_addr, sizeof(ls_addr));
427 #if (defined(BSD) && (BSD >= 199103))
428 ls_addr.satm_len = sizeof(ls_addr);
430 ls_addr.satm_family = AF_ATM;
431 ls_addr.satm_addr.t_atm_sap_addr.SVE_tag_addr = T_ATM_PRESENT;
432 ls_addr.satm_addr.t_atm_sap_addr.SVE_tag_selector =
434 ls_addr.satm_addr.t_atm_sap_addr.address_format =
435 ssp->ss_addr.address_format;
436 ls_addr.satm_addr.t_atm_sap_addr.address_length =
437 ssp->ss_addr.address_length;
438 bcopy(ssp->ss_addr.address,
439 ls_addr.satm_addr.t_atm_sap_addr.address,
440 ssp->ss_addr.address_length);
442 ls_addr.satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_PRESENT;
443 ls_addr.satm_addr.t_atm_sap_layer2.ID_type = T_ATM_SIMPLE_ID;
444 ls_addr.satm_addr.t_atm_sap_layer2.ID.simple_ID =
447 ls_addr.satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
448 ls_addr.satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
451 * Bind the socket to our address
453 rc = bind(sd, (struct sockaddr *)&ls_addr, sizeof(ls_addr));
460 * Set non-blocking I/O
463 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
465 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
468 scsp_log(LOG_ERR, "scsp_dcs_listen: fcntl failed");
476 aal5.forward_max_SDU_size = ssp->ss_mtu;
477 aal5.backward_max_SDU_size = ssp->ss_mtu;
478 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_AAL5, (caddr_t)&aal5,
485 * Set traffic options
487 switch(ssp->ss_media) {
489 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI100;
490 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI100;
493 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI140;
494 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI140;
498 traffic.forward.PCR_all_traffic = ATM_PCR_OC3C;
499 traffic.backward.PCR_all_traffic = ATM_PCR_OC3C;
502 traffic.forward.PCR_all_traffic = ATM_PCR_OC12C;
503 traffic.backward.PCR_all_traffic = ATM_PCR_OC12C;
509 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_TRAFFIC,
510 (caddr_t)&traffic, sizeof(traffic)) < 0) {
516 * Set bearer capability options
518 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_BEARER_CAP,
519 (caddr_t)&bearer, sizeof(bearer)) < 0) {
527 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_QOS,
528 (caddr_t)&qos, sizeof(qos)) < 0) {
536 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_LLC,
537 (caddr_t)&llc_scsp, sizeof(llc_scsp)) < 0) {
543 * Set application name
545 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_APP_NAME,
546 (caddr_t)&appname, sizeof(appname)) < 0) {
552 * Listen for new connections
554 if (listen(sd, 5) < 0) {
559 ssp->ss_dcs_lsock = sd;
564 * Close the socket if anything didn't work
571 ssp->ss_dcs_lsock = -1;
577 * Accept a connection from a DCS
580 * ssp pointer to server block
583 * address of DCS with new connection
584 * 0 failure (errno has reason)
592 struct sockaddr_atm dcs_sockaddr;
593 struct t_atm_sap_addr *dcs_addr = &dcs_sockaddr.satm_addr.t_atm_sap_addr;
594 Atm_addr dcs_atmaddr;
598 * Accept the new connection
600 len = sizeof(dcs_sockaddr);
601 sd = accept(ssp->ss_dcs_lsock,
602 (struct sockaddr *)&dcs_sockaddr, &len);
604 return((Scsp_dcs *)0);
606 if (sd > scsp_max_socket) {
607 scsp_max_socket = sd;
611 * Copy the DCS's address from the sockaddr to an Atm_addr
613 if (dcs_addr->SVE_tag_addr != T_ATM_PRESENT) {
614 dcs_atmaddr.address_format = T_ATM_ABSENT;
615 dcs_atmaddr.address_length = 0;
617 dcs_atmaddr.address_format = dcs_addr->address_format;
618 dcs_atmaddr.address_length = dcs_addr->address_length;
619 bcopy(dcs_addr->address, dcs_atmaddr.address,
620 dcs_addr->address_length);
624 * Find out which DCS this connection is for
626 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
628 * Compare DCS's address to address
631 if (ATM_ADDR_EQUAL(&dcsp->sd_addr,
637 * Make sure we have this DCS configured
641 goto dcs_accept_fail;
645 * Make sure we are in a state to accept the connection
647 if (ssp->ss_state != SCSP_SS_ACTIVE) {
649 goto dcs_accept_fail;
653 * Make sure we don't already have a connection to this DCS
655 if (dcsp->sd_sock != -1) {
657 goto dcs_accept_fail;
661 * Set application name
663 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_APP_NAME,
664 (caddr_t)&appname, sizeof(appname)) < 0) {
666 goto dcs_accept_fail;
670 * Set non-blocking I/O
673 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
675 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
678 goto dcs_accept_fail;
682 * Cancel the open retry timer
684 HARP_CANCEL(&dcsp->sd_open_t);
687 * Save the socket address and return the
695 * An error has occured--clean up and return
698 return((Scsp_dcs *)0);
703 * Read an SCSP message from a directly connected server
706 * dcsp pointer to DCS block that has data
710 * else errno indicating reason for failure
719 char *buff = (char *)0;
720 Scsp_server *ssp = dcsp->sd_server;
724 * Get a buffer to hold the entire message
727 buff = calloc(1, len);
729 scsp_mem_err("scsp_dcs_read: ssp->ss_mtu");
734 len = read(dcsp->sd_sock, buff, len);
740 * Parse the input message and pass it to the Hello FSM
742 msg = scsp_parse_msg(buff, len);
745 * Write the message to the trace file if
746 * it's of a type we're tracing
748 if (((scsp_trace_mode & SCSP_TRACE_HELLO_MSG) &&
749 msg->sc_msg_type == SCSP_HELLO_MSG) ||
750 ((scsp_trace_mode & SCSP_TRACE_CA_MSG) &&
751 msg->sc_msg_type != SCSP_HELLO_MSG)) {
752 scsp_trace_msg(dcsp, msg, 1);
757 * Pass the message to the Hello FSM
759 rc = scsp_hfsm(dcsp, SCSP_HFSM_RCVD, msg);
763 * Message was invalid. Write it to the trace file
764 * if we're tracing messages.
766 if (scsp_trace_mode & (SCSP_TRACE_HELLO_MSG &
767 SCSP_TRACE_CA_MSG)) {
769 scsp_trace("Invalid message received:\n");
771 for (i = 0; i < len; i++) {
772 scsp_trace("%02x ", (u_char)buff[i]);
783 * Error on read--check for special conditions
786 if (errno == ECONNRESET) {
788 * VCC has been closed--pass the event to
791 rc = scsp_hfsm(dcsp, SCSP_HFSM_VC_CLOSED,
794 if (errno == ECONNREFUSED) {
796 * VCC open failed--set a timer and try
797 * again when it fires
799 HARP_TIMER(&dcsp->sd_open_t,
812 * Listen for Unix connections from SCSP client servers
818 * sock socket which is listening
819 * -1 error (reason in errno)
827 static struct sockaddr scsp_addr = {
828 #if (defined(BSD) && (BSD >= 199103))
829 sizeof(struct sockaddr), /* sa_len */
831 AF_UNIX, /* sa_family */
832 SCSPD_SOCK_NAME /* sa_data */
836 * Unlink any old socket
838 rc = unlink(SCSPD_SOCK_NAME);
839 if (rc < 0 && errno != ENOENT)
845 sd = socket(PF_UNIX, SOCK_STREAM, 0);
849 if (sd > scsp_max_socket) {
850 scsp_max_socket = sd;
854 * Bind the socket's address
856 rc = bind(sd, &scsp_addr, sizeof(scsp_addr));
863 * Set non-blocking I/O
866 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
868 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
876 * Listen for new connections
878 if (listen(sd, 5) < 0) {
888 * Accept a connection from a server
890 * We accept a connection, but we won't know which server it is
891 * from until we get the configuration data from the server. We
892 * put the connection on a 'pending' queue and will assign it to
893 * a server when the config data arrives.
896 * ls listening socket to accept from
900 * errno reason for failure
904 scsp_server_accept(ls)
909 struct sockaddr server_addr;
913 * Accept the new connection
915 len = sizeof(server_addr);
916 sd = accept(ls, (struct sockaddr *)&server_addr, &len);
920 if (sd > scsp_max_socket) {
921 scsp_max_socket = sd;
925 * Set non-blocking operation
928 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
930 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
938 * Put the new socket on the 'pending' queue
940 psp = calloc(1, sizeof(Scsp_pending));
942 scsp_mem_err("scsp_server_accept: sizeof(Scsp_pending)");
944 LINK2TAIL(psp, Scsp_pending, scsp_pending_head, sp_next);
951 * Read a server interface message from a socket
954 * sd socket to read from
957 * msg pointer to message read
958 * 0 failure (errno has reason)
962 scsp_if_sock_read(sd)
967 char *buff = (char *)0;
969 Scsp_if_msg_hdr msg_hdr;
972 * Read the message header from the socket
974 len = read(sd, (char *)&msg_hdr, sizeof(msg_hdr));
975 if (len != sizeof(msg_hdr)) {
978 goto socket_read_fail;
982 * Get a buffer and read the rest of the message into it
984 buff = malloc(msg_hdr.sh_len);
986 scsp_mem_err("scsp_if_sock_read: msg_hdr.sh_len");
987 msg = (Scsp_if_msg *)buff;
988 msg->si_hdr = msg_hdr;
989 len = read(sd, &buff[sizeof(Scsp_if_msg_hdr)],
990 msg->si_len - sizeof(Scsp_if_msg_hdr));
991 if (len != msg->si_len - sizeof(Scsp_if_msg_hdr)) {
995 goto socket_read_fail;
1001 if (scsp_trace_mode & SCSP_TRACE_IF_MSG) {
1002 scsp_trace("Received server I/F message:\n");
1003 print_scsp_if_msg(scsp_trace_file, msg);
1012 return((Scsp_if_msg *)0);
1017 * Write a server interface message to a socket
1020 * sd socket to write to
1021 * msg pointer to message to write
1025 * errno reason for failure
1029 scsp_if_sock_write(sd, msg)
1038 if (scsp_trace_mode & SCSP_TRACE_IF_MSG) {
1039 scsp_trace("Writing server I/F message:\n");
1040 print_scsp_if_msg(scsp_trace_file, msg);
1045 * Write the message to the indicated socket
1047 len = write(sd, (char *)msg, msg->si_len);
1048 if (len != msg->si_len) {
1062 * Read data from a local server
1065 * ssp pointer to server block that has data
1069 * else errno indicating reason for failure
1073 scsp_server_read(ssp)
1083 msg = scsp_if_sock_read(ssp->ss_sock);
1085 if (errno == EWOULDBLOCK) {
1087 * Nothing to read--just return
1092 * Error--shut down the server entry
1094 scsp_server_shutdown(ssp);
1100 * Process the received message
1102 switch(msg->si_type) {
1108 case SCSP_CACHE_RSP:
1110 * Summarize the server's cache and try to open
1111 * connections to all of its DCSs
1113 scsp_process_cache_rsp(ssp, msg);
1114 ssp->ss_state = SCSP_SS_ACTIVE;
1115 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
1116 if (scsp_dcs_connect(dcsp)) {
1118 * Connect failed -- the DCS may not
1119 * be up yet, so we'll try again later
1121 HARP_TIMER(&dcsp->sd_open_t,
1126 ssp->ss_state = SCSP_SS_ACTIVE;
1128 case SCSP_SOLICIT_RSP:
1130 * The server has answered our request for a particular
1131 * entry from its cache
1133 dcsp = (Scsp_dcs *)msg->si_tok;
1134 rc = scsp_cfsm(dcsp, SCSP_CIFSM_SOL_RSP, (Scsp_msg *)0,
1137 case SCSP_UPDATE_REQ:
1139 * Pass the update request to the FSMs for all
1140 * DCSs associated with the server
1142 if (ssp->ss_state == SCSP_SS_ACTIVE) {
1143 for (dcsp = ssp->ss_dcs; dcsp;
1144 dcsp = dcsp->sd_next) {
1145 rc = scsp_cfsm(dcsp, SCSP_CIFSM_UPD_REQ,
1146 (Scsp_msg *)0, msg);
1150 case SCSP_UPDATE_RSP:
1152 * Pass the update response to the FSM for the
1153 * DCS associated with the request
1155 dcsp = (Scsp_dcs *)msg->si_tok;
1156 rc = scsp_cfsm(dcsp, SCSP_CIFSM_UPD_RSP,
1157 (Scsp_msg *)0, msg);
1160 scsp_log(LOG_ERR, "invalid message type %d from server",
1171 * Send a Cache Indication to a server
1174 * ssp pointer to server block block
1178 * else errno indicating reason for failure
1182 scsp_send_cache_ind(ssp)
1189 * Get storage for a server interface message
1191 msg = calloc(1, sizeof(Scsp_if_msg));
1193 scsp_mem_err("scsp_send_cache_ind: sizeof(Scsp_if_msg)");
1195 * Fill out the message
1197 msg->si_type = SCSP_CACHE_IND;
1198 msg->si_proto = ssp->ss_pid;
1199 msg->si_len = sizeof(Scsp_if_msg_hdr);
1200 msg->si_tok = (u_long)ssp;
1205 rc = scsp_if_sock_write(ssp->ss_sock, msg);
1212 * Read data from a pending server connection
1215 * psp pointer to pending block that has data
1219 * else errno indicating reason for failure
1223 scsp_pending_read(psp)
1232 * Read the message from the pending socket
1234 msg = scsp_if_sock_read(psp->sp_sock);
1237 goto pending_read_fail;
1241 * Make sure this is configuration data
1243 if (msg->si_type != SCSP_CFG_REQ) {
1244 scsp_log(LOG_ERR, "invalid message type %d from pending server",
1247 goto pending_read_fail;
1251 * Find the server this message is for
1253 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
1254 if (strcmp(ssp->ss_intf, msg->si_cfg.atmarp_netif) == 0)
1258 scsp_log(LOG_ERR, "refused connection from server for %s",
1259 msg->si_cfg.atmarp_netif);
1265 * Make sure the server is ready to go
1267 rc = scsp_get_server_info(ssp);
1275 ssp->ss_sock = psp->sp_sock;
1276 ssp->ss_state = SCSP_SS_CFG;
1277 UNLINK(psp, Scsp_pending, scsp_pending_head, sp_next);
1281 * Listen for connections from the server's DCSs
1283 rc = scsp_dcs_listen(ssp);
1290 * Respond to the configuration message
1292 msg->si_type = SCSP_CFG_RSP;
1293 msg->si_rc = SCSP_RSP_OK;
1294 msg->si_len = sizeof(Scsp_if_msg_hdr);
1295 rc = scsp_if_sock_write(ssp->ss_sock, msg);
1301 * Ask the server to send us its cache
1303 rc = scsp_send_cache_ind(ssp);
1313 * Respond to the configuration message
1315 msg->si_type = SCSP_CFG_RSP;
1316 msg->si_rc = SCSP_RSP_REJ;
1317 msg->si_len = sizeof(Scsp_if_msg_hdr);
1318 (void)scsp_if_sock_write(ssp->ss_sock, msg);
1321 if (ssp->ss_sock != -1) {
1322 (void)close(ssp->ss_sock);
1325 if (ssp->ss_dcs_lsock != -1) {
1326 (void)close(ssp->ss_dcs_lsock);
1329 ssp->ss_state = SCSP_SS_NULL;
1336 * Close the socket and free the pending read block
1338 (void)close(psp->sp_sock);
1339 UNLINK(psp, Scsp_pending, scsp_pending_head, sp_next);