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.5 2006/08/03 16:40:48 swildner 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
137 scsp_find_dcs(int sd
)
140 Scsp_dcs
*dcsp
= NULL
;
143 * Loop through the list of servers
145 for (ssp
= scsp_server_head
; ssp
; ssp
= ssp
->ss_next
) {
147 * Check all the DCSs chained from each server
149 for (dcsp
= ssp
->ss_dcs
; dcsp
; dcsp
= dcsp
->sd_next
) {
150 if (dcsp
->sd_sock
== sd
)
160 * Find a server, given its socket
163 * sd socket descriptor
167 * address of server block corresponding to socket
171 scsp_find_server(int sd
)
176 * Loop through the list of servers
178 for (ssp
= scsp_server_head
; ssp
; ssp
= ssp
->ss_next
) {
179 if (ssp
->ss_sock
== sd
)
188 * Connect to a directly connected server
191 * dcsp pointer to DCS block for server
194 * 0 success (dcsp->sd_sock is set)
195 * else errno indicating reason for failure
199 scsp_dcs_connect(Scsp_dcs
*dcsp
)
203 struct sockaddr_atm DCS_addr
;
206 * If the DCS already has an open connection, just return
208 if (dcsp
->sd_sock
!= -1) {
215 sd
= socket(PF_ATM
, SOCK_SEQPACKET
, ATM_PROTO_AAL5
);
217 return(ESOCKTNOSUPPORT
);
219 if (sd
> scsp_max_socket
) {
220 scsp_max_socket
= sd
;
224 * Set up connection parameters for SCSP connection
226 UM_ZERO(&DCS_addr
, sizeof(DCS_addr
));
227 #if (defined(BSD) && (BSD >= 199103))
228 DCS_addr
.satm_len
= sizeof(DCS_addr
);
230 DCS_addr
.satm_family
= AF_ATM
;
231 DCS_addr
.satm_addr
.t_atm_sap_addr
.SVE_tag_addr
=
233 DCS_addr
.satm_addr
.t_atm_sap_addr
.SVE_tag_selector
=
235 DCS_addr
.satm_addr
.t_atm_sap_addr
.address_format
=
236 dcsp
->sd_addr
.address_format
;
237 DCS_addr
.satm_addr
.t_atm_sap_addr
.address_length
=
238 dcsp
->sd_addr
.address_length
;
239 UM_COPY(dcsp
->sd_addr
.address
,
240 DCS_addr
.satm_addr
.t_atm_sap_addr
.address
,
241 dcsp
->sd_addr
.address_length
);
243 DCS_addr
.satm_addr
.t_atm_sap_layer2
.SVE_tag
=
245 DCS_addr
.satm_addr
.t_atm_sap_layer2
.ID_type
=
247 DCS_addr
.satm_addr
.t_atm_sap_layer2
.ID
.simple_ID
=
250 DCS_addr
.satm_addr
.t_atm_sap_layer3
.SVE_tag
=
252 DCS_addr
.satm_addr
.t_atm_sap_appl
.SVE_tag
=
256 * Bind the socket to our address
258 if (bind(sd
, (struct sockaddr
*)&DCS_addr
,
265 * Set non-blocking operation
268 rc
= fcntl(sd
, F_SETFL
, FNBIO
+ FNDELAY
);
270 rc
= fcntl(sd
, F_SETFL
, O_NONBLOCK
);
273 scsp_log(LOG_ERR
, "scsp_dcs_connect: fcntl failed");
281 aal5
.forward_max_SDU_size
= dcsp
->sd_server
->ss_mtu
;
282 aal5
.backward_max_SDU_size
= dcsp
->sd_server
->ss_mtu
;
283 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_AAL5
, (caddr_t
)&aal5
,
290 * Set traffic options
292 switch(dcsp
->sd_server
->ss_media
) {
294 traffic
.forward
.PCR_all_traffic
= ATM_PCR_TAXI100
;
295 traffic
.backward
.PCR_all_traffic
= ATM_PCR_TAXI100
;
298 traffic
.forward
.PCR_all_traffic
= ATM_PCR_TAXI140
;
299 traffic
.backward
.PCR_all_traffic
= ATM_PCR_TAXI140
;
303 traffic
.forward
.PCR_all_traffic
= ATM_PCR_OC3C
;
304 traffic
.backward
.PCR_all_traffic
= ATM_PCR_OC3C
;
307 traffic
.forward
.PCR_all_traffic
= ATM_PCR_OC12C
;
308 traffic
.backward
.PCR_all_traffic
= ATM_PCR_OC12C
;
314 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_TRAFFIC
,
315 (caddr_t
)&traffic
, sizeof(traffic
)) < 0) {
321 * Set bearer capability options
323 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_BEARER_CAP
,
324 (caddr_t
)&bearer
, sizeof(bearer
)) < 0) {
332 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_QOS
,
333 (caddr_t
)&qos
, sizeof(qos
)) < 0) {
341 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_LLC
,
342 (caddr_t
)&llc_scsp
, sizeof(llc_scsp
)) < 0) {
348 * Set application name
350 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_APP_NAME
,
351 (caddr_t
)&appname
, sizeof(appname
)) < 0) {
359 if (connect(sd
, (struct sockaddr
*)&DCS_addr
,
360 sizeof(DCS_addr
)) < 0 &&
361 errno
!= EINPROGRESS
) {
374 * Close the socket if something didn't work
385 * Listen for ATM connections from DCSs
391 * sock socket which is listening (also set in
393 * -1 error encountered (reason in errno)
397 scsp_dcs_listen(Scsp_server
*ssp
)
400 struct sockaddr_atm ls_addr
;
405 sd
= socket(PF_ATM
, SOCK_SEQPACKET
, ATM_PROTO_AAL5
);
410 if (sd
> scsp_max_socket
) {
411 scsp_max_socket
= sd
;
417 UM_ZERO(&ls_addr
, sizeof(ls_addr
));
418 #if (defined(BSD) && (BSD >= 199103))
419 ls_addr
.satm_len
= sizeof(ls_addr
);
421 ls_addr
.satm_family
= AF_ATM
;
422 ls_addr
.satm_addr
.t_atm_sap_addr
.SVE_tag_addr
= T_ATM_PRESENT
;
423 ls_addr
.satm_addr
.t_atm_sap_addr
.SVE_tag_selector
=
425 ls_addr
.satm_addr
.t_atm_sap_addr
.address_format
=
426 ssp
->ss_addr
.address_format
;
427 ls_addr
.satm_addr
.t_atm_sap_addr
.address_length
=
428 ssp
->ss_addr
.address_length
;
429 UM_COPY(ssp
->ss_addr
.address
,
430 ls_addr
.satm_addr
.t_atm_sap_addr
.address
,
431 ssp
->ss_addr
.address_length
);
433 ls_addr
.satm_addr
.t_atm_sap_layer2
.SVE_tag
= T_ATM_PRESENT
;
434 ls_addr
.satm_addr
.t_atm_sap_layer2
.ID_type
= T_ATM_SIMPLE_ID
;
435 ls_addr
.satm_addr
.t_atm_sap_layer2
.ID
.simple_ID
=
438 ls_addr
.satm_addr
.t_atm_sap_layer3
.SVE_tag
= T_ATM_ABSENT
;
439 ls_addr
.satm_addr
.t_atm_sap_appl
.SVE_tag
= T_ATM_ABSENT
;
442 * Bind the socket to our address
444 rc
= bind(sd
, (struct sockaddr
*)&ls_addr
, sizeof(ls_addr
));
451 * Set non-blocking I/O
454 rc
= fcntl(sd
, F_SETFL
, FNBIO
+ FNDELAY
);
456 rc
= fcntl(sd
, F_SETFL
, O_NONBLOCK
);
459 scsp_log(LOG_ERR
, "scsp_dcs_listen: fcntl failed");
467 aal5
.forward_max_SDU_size
= ssp
->ss_mtu
;
468 aal5
.backward_max_SDU_size
= ssp
->ss_mtu
;
469 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_AAL5
, (caddr_t
)&aal5
,
476 * Set traffic options
478 switch(ssp
->ss_media
) {
480 traffic
.forward
.PCR_all_traffic
= ATM_PCR_TAXI100
;
481 traffic
.backward
.PCR_all_traffic
= ATM_PCR_TAXI100
;
484 traffic
.forward
.PCR_all_traffic
= ATM_PCR_TAXI140
;
485 traffic
.backward
.PCR_all_traffic
= ATM_PCR_TAXI140
;
489 traffic
.forward
.PCR_all_traffic
= ATM_PCR_OC3C
;
490 traffic
.backward
.PCR_all_traffic
= ATM_PCR_OC3C
;
493 traffic
.forward
.PCR_all_traffic
= ATM_PCR_OC12C
;
494 traffic
.backward
.PCR_all_traffic
= ATM_PCR_OC12C
;
500 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_TRAFFIC
,
501 (caddr_t
)&traffic
, sizeof(traffic
)) < 0) {
507 * Set bearer capability options
509 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_BEARER_CAP
,
510 (caddr_t
)&bearer
, sizeof(bearer
)) < 0) {
518 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_QOS
,
519 (caddr_t
)&qos
, sizeof(qos
)) < 0) {
527 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_LLC
,
528 (caddr_t
)&llc_scsp
, sizeof(llc_scsp
)) < 0) {
534 * Set application name
536 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_APP_NAME
,
537 (caddr_t
)&appname
, sizeof(appname
)) < 0) {
543 * Listen for new connections
545 if (listen(sd
, 5) < 0) {
550 ssp
->ss_dcs_lsock
= sd
;
555 * Close the socket if anything didn't work
562 ssp
->ss_dcs_lsock
= -1;
568 * Accept a connection from a DCS
571 * ssp pointer to server block
574 * address of DCS with new connection
575 * 0 failure (errno has reason)
579 scsp_dcs_accept(Scsp_server
*ssp
)
582 struct sockaddr_atm dcs_sockaddr
;
583 struct t_atm_sap_addr
*dcs_addr
= &dcs_sockaddr
.satm_addr
.t_atm_sap_addr
;
584 Atm_addr dcs_atmaddr
;
588 * Accept the new connection
590 len
= sizeof(dcs_sockaddr
);
591 sd
= accept(ssp
->ss_dcs_lsock
,
592 (struct sockaddr
*)&dcs_sockaddr
, &len
);
596 if (sd
> scsp_max_socket
) {
597 scsp_max_socket
= sd
;
601 * Copy the DCS's address from the sockaddr to an Atm_addr
603 if (dcs_addr
->SVE_tag_addr
!= T_ATM_PRESENT
) {
604 dcs_atmaddr
.address_format
= T_ATM_ABSENT
;
605 dcs_atmaddr
.address_length
= 0;
607 dcs_atmaddr
.address_format
= dcs_addr
->address_format
;
608 dcs_atmaddr
.address_length
= dcs_addr
->address_length
;
609 UM_COPY(dcs_addr
->address
, dcs_atmaddr
.address
,
610 dcs_addr
->address_length
);
614 * Find out which DCS this connection is for
616 for (dcsp
= ssp
->ss_dcs
; dcsp
; dcsp
= dcsp
->sd_next
) {
618 * Compare DCS's address to address
621 if (ATM_ADDR_EQUAL(&dcsp
->sd_addr
,
627 * Make sure we have this DCS configured
631 goto dcs_accept_fail
;
635 * Make sure we are in a state to accept the connection
637 if (ssp
->ss_state
!= SCSP_SS_ACTIVE
) {
639 goto dcs_accept_fail
;
643 * Make sure we don't already have a connection to this DCS
645 if (dcsp
->sd_sock
!= -1) {
647 goto dcs_accept_fail
;
651 * Set application name
653 if (setsockopt(sd
, T_ATM_SIGNALING
, T_ATM_APP_NAME
,
654 (caddr_t
)&appname
, sizeof(appname
)) < 0) {
656 goto dcs_accept_fail
;
660 * Set non-blocking I/O
663 rc
= fcntl(sd
, F_SETFL
, FNBIO
+ FNDELAY
);
665 rc
= fcntl(sd
, F_SETFL
, O_NONBLOCK
);
668 goto dcs_accept_fail
;
672 * Cancel the open retry timer
674 HARP_CANCEL(&dcsp
->sd_open_t
);
677 * Save the socket address and return the
685 * An error has occured--clean up and return
693 * Read an SCSP message from a directly connected server
696 * dcsp pointer to DCS block that has data
700 * else errno indicating reason for failure
704 scsp_dcs_read(Scsp_dcs
*dcsp
)
708 Scsp_server
*ssp
= dcsp
->sd_server
;
712 * Get a buffer to hold the entire message
715 buff
= (char *)UM_ALLOC(len
);
717 scsp_mem_err("scsp_dcs_read: ssp->ss_mtu");
723 len
= read(dcsp
->sd_sock
, buff
, len
);
729 * Parse the input message and pass it to the Hello FSM
731 msg
= scsp_parse_msg(buff
, len
);
734 * Write the message to the trace file if
735 * it's of a type we're tracing
737 if (((scsp_trace_mode
& SCSP_TRACE_HELLO_MSG
) &&
738 msg
->sc_msg_type
== SCSP_HELLO_MSG
) ||
739 ((scsp_trace_mode
& SCSP_TRACE_CA_MSG
) &&
740 msg
->sc_msg_type
!= SCSP_HELLO_MSG
)) {
741 scsp_trace_msg(dcsp
, msg
, 1);
746 * Pass the message to the Hello FSM
748 rc
= scsp_hfsm(dcsp
, SCSP_HFSM_RCVD
, msg
);
752 * Message was invalid. Write it to the trace file
753 * if we're tracing messages.
755 if (scsp_trace_mode
& (SCSP_TRACE_HELLO_MSG
&
756 SCSP_TRACE_CA_MSG
)) {
758 scsp_trace("Invalid message received:\n");
760 for (i
= 0; i
< len
; i
++) {
761 scsp_trace("%02x ", (u_char
)buff
[i
]);
772 * Error on read--check for special conditions
775 if (errno
== ECONNRESET
) {
777 * VCC has been closed--pass the event to
780 rc
= scsp_hfsm(dcsp
, SCSP_HFSM_VC_CLOSED
, NULL
);
782 if (errno
== ECONNREFUSED
) {
784 * VCC open failed--set a timer and try
785 * again when it fires
787 HARP_TIMER(&dcsp
->sd_open_t
,
800 * Listen for Unix connections from SCSP client servers
806 * sock socket which is listening
807 * -1 error (reason in errno)
811 scsp_server_listen(void)
815 static struct sockaddr scsp_addr
= {
816 #if (defined(BSD) && (BSD >= 199103))
817 sizeof(struct sockaddr
), /* sa_len */
819 AF_UNIX
, /* sa_family */
820 SCSPD_SOCK_NAME
/* sa_data */
824 * Unlink any old socket
826 rc
= unlink(SCSPD_SOCK_NAME
);
827 if (rc
< 0 && errno
!= ENOENT
)
833 sd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
837 if (sd
> scsp_max_socket
) {
838 scsp_max_socket
= sd
;
842 * Bind the socket's address
844 rc
= bind(sd
, &scsp_addr
, sizeof(scsp_addr
));
851 * Set non-blocking I/O
854 rc
= fcntl(sd
, F_SETFL
, FNBIO
+ FNDELAY
);
856 rc
= fcntl(sd
, F_SETFL
, O_NONBLOCK
);
864 * Listen for new connections
866 if (listen(sd
, 5) < 0) {
876 * Accept a connection from a server
878 * We accept a connection, but we won't know which server it is
879 * from until we get the configuration data from the server. We
880 * put the connection on a 'pending' queue and will assign it to
881 * a server when the config data arrives.
884 * ls listening socket to accept from
888 * errno reason for failure
892 scsp_server_accept(int ls
)
895 struct sockaddr server_addr
;
899 * Accept the new connection
901 len
= sizeof(server_addr
);
902 sd
= accept(ls
, (struct sockaddr
*)&server_addr
, &len
);
906 if (sd
> scsp_max_socket
) {
907 scsp_max_socket
= sd
;
911 * Set non-blocking operation
914 rc
= fcntl(sd
, F_SETFL
, FNBIO
+ FNDELAY
);
916 rc
= fcntl(sd
, F_SETFL
, O_NONBLOCK
);
924 * Put the new socket on the 'pending' queue
926 psp
= (Scsp_pending
*) UM_ALLOC(sizeof(Scsp_pending
));
928 scsp_mem_err("scsp_server_accept: sizeof(Scsp_pending)");
931 LINK2TAIL(psp
, Scsp_pending
, scsp_pending_head
, sp_next
);
938 * Read a server interface message from a socket
941 * sd socket to read from
944 * msg pointer to message read
945 * 0 failure (errno has reason)
949 scsp_if_sock_read(int sd
)
954 Scsp_if_msg_hdr msg_hdr
;
957 * Read the message header from the socket
959 len
= read(sd
, (char *)&msg_hdr
, sizeof(msg_hdr
));
960 if (len
!= sizeof(msg_hdr
)) {
963 goto socket_read_fail
;
967 * Get a buffer and read the rest of the message into it
969 buff
= (char *)UM_ALLOC(msg_hdr
.sh_len
);
971 scsp_mem_err("scsp_if_sock_read: msg_hdr.sh_len");
973 msg
= (Scsp_if_msg
*)buff
;
974 msg
->si_hdr
= msg_hdr
;
975 len
= read(sd
, &buff
[sizeof(Scsp_if_msg_hdr
)],
976 msg
->si_len
- sizeof(Scsp_if_msg_hdr
));
977 if (len
!= msg
->si_len
- sizeof(Scsp_if_msg_hdr
)) {
981 goto socket_read_fail
;
987 if (scsp_trace_mode
& SCSP_TRACE_IF_MSG
) {
988 scsp_trace("Received server I/F message:\n");
989 print_scsp_if_msg(scsp_trace_file
, msg
);
1003 * Write a server interface message to a socket
1006 * sd socket to write to
1007 * msg pointer to message to write
1011 * errno reason for failure
1015 scsp_if_sock_write(int sd
, Scsp_if_msg
*msg
)
1022 if (scsp_trace_mode
& SCSP_TRACE_IF_MSG
) {
1023 scsp_trace("Writing server I/F message:\n");
1024 print_scsp_if_msg(scsp_trace_file
, msg
);
1029 * Write the message to the indicated socket
1031 len
= write(sd
, (char *)msg
, msg
->si_len
);
1032 if (len
!= msg
->si_len
) {
1046 * Read data from a local server
1049 * ssp pointer to server block that has data
1053 * else errno indicating reason for failure
1057 scsp_server_read(Scsp_server
*ssp
)
1066 msg
= scsp_if_sock_read(ssp
->ss_sock
);
1068 if (errno
== EWOULDBLOCK
) {
1070 * Nothing to read--just return
1075 * Error--shut down the server entry
1077 scsp_server_shutdown(ssp
);
1083 * Process the received message
1085 switch(msg
->si_type
) {
1091 case SCSP_CACHE_RSP
:
1093 * Summarize the server's cache and try to open
1094 * connections to all of its DCSs
1096 scsp_process_cache_rsp(ssp
, msg
);
1097 ssp
->ss_state
= SCSP_SS_ACTIVE
;
1098 for (dcsp
= ssp
->ss_dcs
; dcsp
; dcsp
= dcsp
->sd_next
) {
1099 if (scsp_dcs_connect(dcsp
)) {
1101 * Connect failed -- the DCS may not
1102 * be up yet, so we'll try again later
1104 HARP_TIMER(&dcsp
->sd_open_t
,
1109 ssp
->ss_state
= SCSP_SS_ACTIVE
;
1111 case SCSP_SOLICIT_RSP
:
1113 * The server has answered our request for a particular
1114 * entry from its cache
1116 dcsp
= (Scsp_dcs
*)msg
->si_tok
;
1117 rc
= scsp_cfsm(dcsp
, SCSP_CIFSM_SOL_RSP
, NULL
, msg
);
1119 case SCSP_UPDATE_REQ
:
1121 * Pass the update request to the FSMs for all
1122 * DCSs associated with the server
1124 if (ssp
->ss_state
== SCSP_SS_ACTIVE
) {
1125 for (dcsp
= ssp
->ss_dcs
; dcsp
;
1126 dcsp
= dcsp
->sd_next
) {
1127 rc
= scsp_cfsm(dcsp
, SCSP_CIFSM_UPD_REQ
,
1132 case SCSP_UPDATE_RSP
:
1134 * Pass the update response to the FSM for the
1135 * DCS associated with the request
1137 dcsp
= (Scsp_dcs
*)msg
->si_tok
;
1138 rc
= scsp_cfsm(dcsp
, SCSP_CIFSM_UPD_RSP
, NULL
, msg
);
1141 scsp_log(LOG_ERR
, "invalid message type %d from server",
1152 * Send a Cache Indication to a server
1155 * ssp pointer to server block block
1159 * else errno indicating reason for failure
1163 scsp_send_cache_ind(Scsp_server
*ssp
)
1169 * Get storage for a server interface message
1171 msg
= (Scsp_if_msg
*)UM_ALLOC(sizeof(Scsp_if_msg
));
1173 scsp_mem_err("scsp_send_cache_ind: sizeof(Scsp_if_msg)");
1175 UM_ZERO(msg
, sizeof(Scsp_if_msg
));
1178 * Fill out the message
1180 msg
->si_type
= SCSP_CACHE_IND
;
1182 msg
->si_proto
= ssp
->ss_pid
;
1183 msg
->si_len
= sizeof(Scsp_if_msg_hdr
);
1184 msg
->si_tok
= (u_long
)ssp
;
1189 rc
= scsp_if_sock_write(ssp
->ss_sock
, msg
);
1196 * Read data from a pending server connection
1199 * psp pointer to pending block that has data
1203 * else errno indicating reason for failure
1207 scsp_pending_read(Scsp_pending
*psp
)
1214 * Read the message from the pending socket
1216 msg
= scsp_if_sock_read(psp
->sp_sock
);
1219 goto pending_read_fail
;
1223 * Make sure this is configuration data
1225 if (msg
->si_type
!= SCSP_CFG_REQ
) {
1226 scsp_log(LOG_ERR
, "invalid message type %d from pending server",
1229 goto pending_read_fail
;
1233 * Find the server this message is for
1235 for (ssp
= scsp_server_head
; ssp
; ssp
= ssp
->ss_next
) {
1236 if (strcmp(ssp
->ss_intf
, msg
->si_cfg
.atmarp_netif
) == 0)
1240 scsp_log(LOG_ERR
, "refused connection from server for %s",
1241 msg
->si_cfg
.atmarp_netif
);
1247 * Make sure the server is ready to go
1249 rc
= scsp_get_server_info(ssp
);
1257 ssp
->ss_sock
= psp
->sp_sock
;
1258 ssp
->ss_state
= SCSP_SS_CFG
;
1259 UNLINK(psp
, Scsp_pending
, scsp_pending_head
, sp_next
);
1263 * Listen for connections from the server's DCSs
1265 rc
= scsp_dcs_listen(ssp
);
1272 * Respond to the configuration message
1274 msg
->si_type
= SCSP_CFG_RSP
;
1275 msg
->si_rc
= SCSP_RSP_OK
;
1276 msg
->si_len
= sizeof(Scsp_if_msg_hdr
);
1277 rc
= scsp_if_sock_write(ssp
->ss_sock
, msg
);
1283 * Ask the server to send us its cache
1285 rc
= scsp_send_cache_ind(ssp
);
1295 * Respond to the configuration message
1297 msg
->si_type
= SCSP_CFG_RSP
;
1298 msg
->si_rc
= SCSP_RSP_REJ
;
1299 msg
->si_len
= sizeof(Scsp_if_msg_hdr
);
1300 scsp_if_sock_write(ssp
->ss_sock
, msg
);
1303 if (ssp
->ss_sock
!= -1) {
1304 close(ssp
->ss_sock
);
1307 if (ssp
->ss_dcs_lsock
!= -1) {
1308 close(ssp
->ss_dcs_lsock
);
1311 ssp
->ss_state
= SCSP_SS_NULL
;
1318 * Close the socket and free the pending read block
1320 close(psp
->sp_sock
);
1321 UNLINK(psp
, Scsp_pending
, scsp_pending_head
, sp_next
);