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.
26 * @(#) $FreeBSD: src/usr.sbin/atm/scspd/scsp_socket.c,v 1.3 1999/08/28 01:15:34 peter Exp $
27 * @(#) $DragonFly: src/usr.sbin/atm/scspd/scsp_socket.c,v 1.2 2003/06/17 04:29:52 dillon Exp $
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>
68 static struct t_atm_llc llc_scsp = {
71 {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x5e, 0x00, 0x05}
74 static struct t_atm_aal5 aal5 = {
75 0, /* forward_max_SDU_size */
76 0, /* backward_max_SDU_size */
80 static struct t_atm_traffic traffic = {
82 T_ATM_ABSENT, /* PCR_high_priority */
83 0, /* PCR_all_traffic */
84 T_ATM_ABSENT, /* SCR_high_priority */
85 T_ATM_ABSENT, /* SCR_all_traffic */
86 T_ATM_ABSENT, /* MBS_high_priority */
87 T_ATM_ABSENT, /* MBS_all_traffic */
91 T_ATM_ABSENT, /* PCR_high_priority */
92 0, /* PCR_all_traffic */
93 T_ATM_ABSENT, /* SCR_high_priority */
94 T_ATM_ABSENT, /* SCR_all_traffic */
95 T_ATM_ABSENT, /* MBS_high_priority */
96 T_ATM_ABSENT, /* MBS_all_traffic */
99 T_YES /* best_effort */
102 static struct t_atm_bearer bearer = {
103 T_ATM_CLASS_X, /* bearer_class */
104 T_ATM_NULL, /* traffic_type */
105 T_ATM_NULL, /* timing_requirements */
106 T_NO, /* clipping_susceptibility */
107 T_ATM_1_TO_1 /* connection_configuration */
110 static struct t_atm_qos qos = {
111 T_ATM_NETWORK_CODING, /* coding_standard */
113 T_ATM_QOS_CLASS_0 /* qos_class */
116 T_ATM_QOS_CLASS_0 /* qos_class */
120 static struct t_atm_app_name appname = {
126 * Find a DCS, given its socket
129 * sd socket descriptor
133 * address of DCS block corresponding to socket
141 Scsp_dcs *dcsp = NULL;
144 * Loop through the list of servers
146 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
148 * Check all the DCSs chained from each server
150 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
151 if (dcsp->sd_sock == sd)
161 * Find a server, given its socket
164 * sd socket descriptor
168 * address of server block corresponding to socket
178 * Loop through the list of servers
180 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
181 if (ssp->ss_sock == sd)
190 * Connect to a directly connected server
193 * dcsp pointer to DCS block for server
196 * 0 success (dcsp->sd_sock is set)
197 * else errno indicating reason for failure
201 scsp_dcs_connect(dcsp)
206 struct sockaddr_atm DCS_addr;
209 * If the DCS already has an open connection, just return
211 if (dcsp->sd_sock != -1) {
218 sd = socket(PF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5);
220 return(ESOCKTNOSUPPORT);
222 if (sd > scsp_max_socket) {
223 scsp_max_socket = sd;
227 * Set up connection parameters for SCSP connection
229 UM_ZERO(&DCS_addr, sizeof(DCS_addr));
230 #if (defined(BSD) && (BSD >= 199103))
231 DCS_addr.satm_len = sizeof(DCS_addr);
233 DCS_addr.satm_family = AF_ATM;
234 DCS_addr.satm_addr.t_atm_sap_addr.SVE_tag_addr =
236 DCS_addr.satm_addr.t_atm_sap_addr.SVE_tag_selector =
238 DCS_addr.satm_addr.t_atm_sap_addr.address_format =
239 dcsp->sd_addr.address_format;
240 DCS_addr.satm_addr.t_atm_sap_addr.address_length =
241 dcsp->sd_addr.address_length;
242 UM_COPY(dcsp->sd_addr.address,
243 DCS_addr.satm_addr.t_atm_sap_addr.address,
244 dcsp->sd_addr.address_length);
246 DCS_addr.satm_addr.t_atm_sap_layer2.SVE_tag =
248 DCS_addr.satm_addr.t_atm_sap_layer2.ID_type =
250 DCS_addr.satm_addr.t_atm_sap_layer2.ID.simple_ID =
253 DCS_addr.satm_addr.t_atm_sap_layer3.SVE_tag =
255 DCS_addr.satm_addr.t_atm_sap_appl.SVE_tag =
259 * Bind the socket to our address
261 if (bind(sd, (struct sockaddr *)&DCS_addr,
268 * Set non-blocking operation
271 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
273 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
276 scsp_log(LOG_ERR, "scsp_dcs_connect: fcntl failed");
284 aal5.forward_max_SDU_size = dcsp->sd_server->ss_mtu;
285 aal5.backward_max_SDU_size = dcsp->sd_server->ss_mtu;
286 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_AAL5, (caddr_t)&aal5,
293 * Set traffic options
295 switch(dcsp->sd_server->ss_media) {
297 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI100;
298 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI100;
301 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI140;
302 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI140;
306 traffic.forward.PCR_all_traffic = ATM_PCR_OC3C;
307 traffic.backward.PCR_all_traffic = ATM_PCR_OC3C;
310 traffic.forward.PCR_all_traffic = ATM_PCR_OC12C;
311 traffic.backward.PCR_all_traffic = ATM_PCR_OC12C;
317 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_TRAFFIC,
318 (caddr_t)&traffic, sizeof(traffic)) < 0) {
324 * Set bearer capability options
326 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_BEARER_CAP,
327 (caddr_t)&bearer, sizeof(bearer)) < 0) {
335 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_QOS,
336 (caddr_t)&qos, sizeof(qos)) < 0) {
344 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_LLC,
345 (caddr_t)&llc_scsp, sizeof(llc_scsp)) < 0) {
351 * Set application name
353 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_APP_NAME,
354 (caddr_t)&appname, sizeof(appname)) < 0) {
362 if (connect(sd, (struct sockaddr *)&DCS_addr,
363 sizeof(DCS_addr)) < 0 &&
364 errno != EINPROGRESS) {
377 * Close the socket if something didn't work
388 * Listen for ATM connections from DCSs
394 * sock socket which is listening (also set in
396 * -1 error encountered (reason in errno)
404 struct sockaddr_atm ls_addr;
409 sd = socket(PF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5);
414 if (sd > scsp_max_socket) {
415 scsp_max_socket = sd;
421 UM_ZERO(&ls_addr, sizeof(ls_addr));
422 #if (defined(BSD) && (BSD >= 199103))
423 ls_addr.satm_len = sizeof(ls_addr);
425 ls_addr.satm_family = AF_ATM;
426 ls_addr.satm_addr.t_atm_sap_addr.SVE_tag_addr = T_ATM_PRESENT;
427 ls_addr.satm_addr.t_atm_sap_addr.SVE_tag_selector =
429 ls_addr.satm_addr.t_atm_sap_addr.address_format =
430 ssp->ss_addr.address_format;
431 ls_addr.satm_addr.t_atm_sap_addr.address_length =
432 ssp->ss_addr.address_length;
433 UM_COPY(ssp->ss_addr.address,
434 ls_addr.satm_addr.t_atm_sap_addr.address,
435 ssp->ss_addr.address_length);
437 ls_addr.satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_PRESENT;
438 ls_addr.satm_addr.t_atm_sap_layer2.ID_type = T_ATM_SIMPLE_ID;
439 ls_addr.satm_addr.t_atm_sap_layer2.ID.simple_ID =
442 ls_addr.satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
443 ls_addr.satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
446 * Bind the socket to our address
448 rc = bind(sd, (struct sockaddr *)&ls_addr, sizeof(ls_addr));
455 * Set non-blocking I/O
458 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
460 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
463 scsp_log(LOG_ERR, "scsp_dcs_listen: fcntl failed");
471 aal5.forward_max_SDU_size = ssp->ss_mtu;
472 aal5.backward_max_SDU_size = ssp->ss_mtu;
473 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_AAL5, (caddr_t)&aal5,
480 * Set traffic options
482 switch(ssp->ss_media) {
484 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI100;
485 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI100;
488 traffic.forward.PCR_all_traffic = ATM_PCR_TAXI140;
489 traffic.backward.PCR_all_traffic = ATM_PCR_TAXI140;
493 traffic.forward.PCR_all_traffic = ATM_PCR_OC3C;
494 traffic.backward.PCR_all_traffic = ATM_PCR_OC3C;
497 traffic.forward.PCR_all_traffic = ATM_PCR_OC12C;
498 traffic.backward.PCR_all_traffic = ATM_PCR_OC12C;
504 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_TRAFFIC,
505 (caddr_t)&traffic, sizeof(traffic)) < 0) {
511 * Set bearer capability options
513 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_BEARER_CAP,
514 (caddr_t)&bearer, sizeof(bearer)) < 0) {
522 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_QOS,
523 (caddr_t)&qos, sizeof(qos)) < 0) {
531 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_LLC,
532 (caddr_t)&llc_scsp, sizeof(llc_scsp)) < 0) {
538 * Set application name
540 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_APP_NAME,
541 (caddr_t)&appname, sizeof(appname)) < 0) {
547 * Listen for new connections
549 if (listen(sd, 5) < 0) {
554 ssp->ss_dcs_lsock = sd;
559 * Close the socket if anything didn't work
566 ssp->ss_dcs_lsock = -1;
572 * Accept a connection from a DCS
575 * ssp pointer to server block
578 * address of DCS with new connection
579 * 0 failure (errno has reason)
587 struct sockaddr_atm dcs_sockaddr;
588 struct t_atm_sap_addr *dcs_addr = &dcs_sockaddr.satm_addr.t_atm_sap_addr;
589 Atm_addr dcs_atmaddr;
593 * Accept the new connection
595 len = sizeof(dcs_sockaddr);
596 sd = accept(ssp->ss_dcs_lsock,
597 (struct sockaddr *)&dcs_sockaddr, &len);
599 return((Scsp_dcs *)0);
601 if (sd > scsp_max_socket) {
602 scsp_max_socket = sd;
606 * Copy the DCS's address from the sockaddr to an Atm_addr
608 if (dcs_addr->SVE_tag_addr != T_ATM_PRESENT) {
609 dcs_atmaddr.address_format = T_ATM_ABSENT;
610 dcs_atmaddr.address_length = 0;
612 dcs_atmaddr.address_format = dcs_addr->address_format;
613 dcs_atmaddr.address_length = dcs_addr->address_length;
614 UM_COPY(dcs_addr->address, dcs_atmaddr.address,
615 dcs_addr->address_length);
619 * Find out which DCS this connection is for
621 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
623 * Compare DCS's address to address
626 if (ATM_ADDR_EQUAL(&dcsp->sd_addr,
632 * Make sure we have this DCS configured
636 goto dcs_accept_fail;
640 * Make sure we are in a state to accept the connection
642 if (ssp->ss_state != SCSP_SS_ACTIVE) {
644 goto dcs_accept_fail;
648 * Make sure we don't already have a connection to this DCS
650 if (dcsp->sd_sock != -1) {
652 goto dcs_accept_fail;
656 * Set application name
658 if (setsockopt(sd, T_ATM_SIGNALING, T_ATM_APP_NAME,
659 (caddr_t)&appname, sizeof(appname)) < 0) {
661 goto dcs_accept_fail;
665 * Set non-blocking I/O
668 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
670 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
673 goto dcs_accept_fail;
677 * Cancel the open retry timer
679 HARP_CANCEL(&dcsp->sd_open_t);
682 * Save the socket address and return the
690 * An error has occured--clean up and return
693 return((Scsp_dcs *)0);
698 * Read an SCSP message from a directly connected server
701 * dcsp pointer to DCS block that has data
705 * else errno indicating reason for failure
714 char *buff = (char *)0;
715 Scsp_server *ssp = dcsp->sd_server;
719 * Get a buffer to hold the entire message
722 buff = (char *)UM_ALLOC(len);
724 scsp_mem_err("scsp_dcs_read: ssp->ss_mtu");
730 len = read(dcsp->sd_sock, buff, len);
736 * Parse the input message and pass it to the Hello FSM
738 msg = scsp_parse_msg(buff, len);
741 * Write the message to the trace file if
742 * it's of a type we're tracing
744 if (((scsp_trace_mode & SCSP_TRACE_HELLO_MSG) &&
745 msg->sc_msg_type == SCSP_HELLO_MSG) ||
746 ((scsp_trace_mode & SCSP_TRACE_CA_MSG) &&
747 msg->sc_msg_type != SCSP_HELLO_MSG)) {
748 scsp_trace_msg(dcsp, msg, 1);
753 * Pass the message to the Hello FSM
755 rc = scsp_hfsm(dcsp, SCSP_HFSM_RCVD, msg);
759 * Message was invalid. Write it to the trace file
760 * if we're tracing messages.
762 if (scsp_trace_mode & (SCSP_TRACE_HELLO_MSG &
763 SCSP_TRACE_CA_MSG)) {
765 scsp_trace("Invalid message received:\n");
767 for (i = 0; i < len; i++) {
768 scsp_trace("%02x ", (u_char)buff[i]);
779 * Error on read--check for special conditions
782 if (errno == ECONNRESET) {
784 * VCC has been closed--pass the event to
787 rc = scsp_hfsm(dcsp, SCSP_HFSM_VC_CLOSED,
790 if (errno == ECONNREFUSED) {
792 * VCC open failed--set a timer and try
793 * again when it fires
795 HARP_TIMER(&dcsp->sd_open_t,
808 * Listen for Unix connections from SCSP client servers
814 * sock socket which is listening
815 * -1 error (reason in errno)
823 static struct sockaddr scsp_addr = {
824 #if (defined(BSD) && (BSD >= 199103))
825 sizeof(struct sockaddr), /* sa_len */
827 AF_UNIX, /* sa_family */
828 SCSPD_SOCK_NAME /* sa_data */
832 * Unlink any old socket
834 rc = unlink(SCSPD_SOCK_NAME);
835 if (rc < 0 && errno != ENOENT)
841 sd = socket(PF_UNIX, SOCK_STREAM, 0);
845 if (sd > scsp_max_socket) {
846 scsp_max_socket = sd;
850 * Bind the socket's address
852 rc = bind(sd, &scsp_addr, sizeof(scsp_addr));
859 * Set non-blocking I/O
862 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
864 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
872 * Listen for new connections
874 if (listen(sd, 5) < 0) {
884 * Accept a connection from a server
886 * We accept a connection, but we won't know which server it is
887 * from until we get the configuration data from the server. We
888 * put the connection on a 'pending' queue and will assign it to
889 * a server when the config data arrives.
892 * ls listening socket to accept from
896 * errno reason for failure
900 scsp_server_accept(ls)
905 struct sockaddr server_addr;
909 * Accept the new connection
911 len = sizeof(server_addr);
912 sd = accept(ls, (struct sockaddr *)&server_addr, &len);
916 if (sd > scsp_max_socket) {
917 scsp_max_socket = sd;
921 * Set non-blocking operation
924 rc = fcntl(sd, F_SETFL, FNBIO + FNDELAY);
926 rc = fcntl(sd, F_SETFL, O_NONBLOCK);
934 * Put the new socket on the 'pending' queue
936 psp = (Scsp_pending *) UM_ALLOC(sizeof(Scsp_pending));
938 scsp_mem_err("scsp_server_accept: sizeof(Scsp_pending)");
941 LINK2TAIL(psp, Scsp_pending, scsp_pending_head, sp_next);
948 * Read a server interface message from a socket
951 * sd socket to read from
954 * msg pointer to message read
955 * 0 failure (errno has reason)
959 scsp_if_sock_read(sd)
964 char *buff = (char *)0;
966 Scsp_if_msg_hdr msg_hdr;
969 * Read the message header from the socket
971 len = read(sd, (char *)&msg_hdr, sizeof(msg_hdr));
972 if (len != sizeof(msg_hdr)) {
975 goto socket_read_fail;
979 * Get a buffer and read the rest of the message into it
981 buff = (char *)UM_ALLOC(msg_hdr.sh_len);
983 scsp_mem_err("scsp_if_sock_read: msg_hdr.sh_len");
985 msg = (Scsp_if_msg *)buff;
986 msg->si_hdr = msg_hdr;
987 len = read(sd, &buff[sizeof(Scsp_if_msg_hdr)],
988 msg->si_len - sizeof(Scsp_if_msg_hdr));
989 if (len != msg->si_len - sizeof(Scsp_if_msg_hdr)) {
993 goto socket_read_fail;
999 if (scsp_trace_mode & SCSP_TRACE_IF_MSG) {
1000 scsp_trace("Received server I/F message:\n");
1001 print_scsp_if_msg(scsp_trace_file, msg);
1010 return((Scsp_if_msg *)0);
1015 * Write a server interface message to a socket
1018 * sd socket to write to
1019 * msg pointer to message to write
1023 * errno reason for failure
1027 scsp_if_sock_write(sd, msg)
1036 if (scsp_trace_mode & SCSP_TRACE_IF_MSG) {
1037 scsp_trace("Writing server I/F message:\n");
1038 print_scsp_if_msg(scsp_trace_file, msg);
1043 * Write the message to the indicated socket
1045 len = write(sd, (char *)msg, msg->si_len);
1046 if (len != msg->si_len) {
1060 * Read data from a local server
1063 * ssp pointer to server block that has data
1067 * else errno indicating reason for failure
1071 scsp_server_read(ssp)
1081 msg = scsp_if_sock_read(ssp->ss_sock);
1083 if (errno == EWOULDBLOCK) {
1085 * Nothing to read--just return
1090 * Error--shut down the server entry
1092 scsp_server_shutdown(ssp);
1098 * Process the received message
1100 switch(msg->si_type) {
1106 case SCSP_CACHE_RSP:
1108 * Summarize the server's cache and try to open
1109 * connections to all of its DCSs
1111 scsp_process_cache_rsp(ssp, msg);
1112 ssp->ss_state = SCSP_SS_ACTIVE;
1113 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
1114 if (scsp_dcs_connect(dcsp)) {
1116 * Connect failed -- the DCS may not
1117 * be up yet, so we'll try again later
1119 HARP_TIMER(&dcsp->sd_open_t,
1124 ssp->ss_state = SCSP_SS_ACTIVE;
1126 case SCSP_SOLICIT_RSP:
1128 * The server has answered our request for a particular
1129 * entry from its cache
1131 dcsp = (Scsp_dcs *)msg->si_tok;
1132 rc = scsp_cfsm(dcsp, SCSP_CIFSM_SOL_RSP, (Scsp_msg *)0,
1135 case SCSP_UPDATE_REQ:
1137 * Pass the update request to the FSMs for all
1138 * DCSs associated with the server
1140 if (ssp->ss_state == SCSP_SS_ACTIVE) {
1141 for (dcsp = ssp->ss_dcs; dcsp;
1142 dcsp = dcsp->sd_next) {
1143 rc = scsp_cfsm(dcsp, SCSP_CIFSM_UPD_REQ,
1144 (Scsp_msg *)0, msg);
1148 case SCSP_UPDATE_RSP:
1150 * Pass the update response to the FSM for the
1151 * DCS associated with the request
1153 dcsp = (Scsp_dcs *)msg->si_tok;
1154 rc = scsp_cfsm(dcsp, SCSP_CIFSM_UPD_RSP,
1155 (Scsp_msg *)0, msg);
1158 scsp_log(LOG_ERR, "invalid message type %d from server",
1169 * Send a Cache Indication to a server
1172 * ssp pointer to server block block
1176 * else errno indicating reason for failure
1180 scsp_send_cache_ind(ssp)
1187 * Get storage for a server interface message
1189 msg = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg));
1191 scsp_mem_err("scsp_send_cache_ind: sizeof(Scsp_if_msg)");
1193 UM_ZERO(msg, sizeof(Scsp_if_msg));
1196 * Fill out the message
1198 msg->si_type = SCSP_CACHE_IND;
1200 msg->si_proto = ssp->ss_pid;
1201 msg->si_len = sizeof(Scsp_if_msg_hdr);
1202 msg->si_tok = (u_long)ssp;
1207 rc = scsp_if_sock_write(ssp->ss_sock, msg);
1214 * Read data from a pending server connection
1217 * psp pointer to pending block that has data
1221 * else errno indicating reason for failure
1225 scsp_pending_read(psp)
1234 * Read the message from the pending socket
1236 msg = scsp_if_sock_read(psp->sp_sock);
1239 goto pending_read_fail;
1243 * Make sure this is configuration data
1245 if (msg->si_type != SCSP_CFG_REQ) {
1246 scsp_log(LOG_ERR, "invalid message type %d from pending server",
1249 goto pending_read_fail;
1253 * Find the server this message is for
1255 for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
1256 if (strcmp(ssp->ss_intf, msg->si_cfg.atmarp_netif) == 0)
1260 scsp_log(LOG_ERR, "refused connection from server for %s",
1261 msg->si_cfg.atmarp_netif);
1267 * Make sure the server is ready to go
1269 rc = scsp_get_server_info(ssp);
1277 ssp->ss_sock = psp->sp_sock;
1278 ssp->ss_state = SCSP_SS_CFG;
1279 UNLINK(psp, Scsp_pending, scsp_pending_head, sp_next);
1283 * Listen for connections from the server's DCSs
1285 rc = scsp_dcs_listen(ssp);
1292 * Respond to the configuration message
1294 msg->si_type = SCSP_CFG_RSP;
1295 msg->si_rc = SCSP_RSP_OK;
1296 msg->si_len = sizeof(Scsp_if_msg_hdr);
1297 rc = scsp_if_sock_write(ssp->ss_sock, msg);
1303 * Ask the server to send us its cache
1305 rc = scsp_send_cache_ind(ssp);
1315 * Respond to the configuration message
1317 msg->si_type = SCSP_CFG_RSP;
1318 msg->si_rc = SCSP_RSP_REJ;
1319 msg->si_len = sizeof(Scsp_if_msg_hdr);
1320 (void)scsp_if_sock_write(ssp->ss_sock, msg);
1323 if (ssp->ss_sock != -1) {
1324 (void)close(ssp->ss_sock);
1327 if (ssp->ss_dcs_lsock != -1) {
1328 (void)close(ssp->ss_dcs_lsock);
1331 ssp->ss_state = SCSP_SS_NULL;
1338 * Close the socket and free the pending read block
1340 (void)close(psp->sp_sock);
1341 UNLINK(psp, Scsp_pending, scsp_pending_head, sp_next);