1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright (c) 1999 by Sun Microsystems, Inc.
26  * All rights reserved.
27  *
28  */
29 
30 //  SCCS Status:      %W%	%G%
31 //  SDAAdvert.java:   Server Side DAAdvert Message.
32 //  Author:           James Kempf
33 //  Created On:       Tue Feb 10 15:00:39 1998
34 //  Last Modified By: James Kempf
35 //  Last Modified On: Tue Nov 17 12:12:18 1998
36 //  Update Count:     82
37 //
38 
39 package com.sun.slp;
40 
41 import java.util.*;
42 import java.io.*;
43 
44 
45 /**
46  * The SDAAdvert class models the SLP DAAdvert message.
47  *
48  * @version 1.4 97/11/20
49  * @author James Kempf
50  */
51 
52 class SDAAdvert extends SrvLocMsgImpl {
53 
54     SDAAdvert(SrvLocHeader hdr,
55 	      short xid,
56 	      long timestamp,
57 	      ServiceURL url,
58 	      Vector scopes,
59 	      Vector attrs)
60 	throws ServiceLocationException {
61 
62 	// Note that we don't need a server side header here because
63 	//  we will not be parsing anything in.
64 
65 	try {
66 	    this.hdr = (SrvLocHeader)hdr.clone();
67 
68 	} catch (CloneNotSupportedException ex) {
69 
70 	    // We know it's supported.
71 
72 	}
73 
74 	this.hdr.xid = xid;
75 	this.hdr.functionCode = SrvLocHeader.DAAdvert;
76 	this.hdr.mcast = false;
77 	this.hdr.previousResponders = null;  // we don't want this around.
78 	this.hdr.errCode = ServiceLocationException.OK;
79 	this.hdr.overflow = false;
80 	this.hdr.length = 0;
81 	this.hdr.fresh = false;
82 
83 	this.initialize(timestamp, url, scopes, attrs);
84 
85     }
86 
87 
88     // Initialize the message.
89 
90     void
91 	initialize(long timestamp,
92 		   ServiceURL url,
93 		   Vector scopes,
94 		   Vector attrs)
95 	throws ServiceLocationException {
96 
97 	SLPServerHeaderV2 hdr = (SLPServerHeaderV2)this.hdr;
98 	hdr.scopes = (Vector)scopes.clone();
99 
100 	ServiceType serviceType = url.getServiceType();
101 
102 	if (!serviceType.equals(Defaults.DA_SERVICE_TYPE)) {
103 	    throw
104 		new ServiceLocationException(
105 				ServiceLocationException.PARSE_ERROR,
106 				"sdaadv_nondaurl",
107 				new Object[] {serviceType});
108 
109 	}
110 
111 	if (timestamp < 0) {
112 	    throw
113 		new ServiceLocationException(
114 				ServiceLocationException.PARSE_ERROR,
115 				"sdaadv_neg",
116 				new Object[0]);
117 	}
118 
119 	// Validate scope list.
120 
121 	DATable.validateScopes(scopes, hdr.locale);
122 	hdr.scopes = (Vector)scopes;
123 
124 	// Escape scope strings.
125 
126 	hdr.escapeScopeStrings(scopes);
127 
128 	// Parse out the payload.
129 
130 	ByteArrayOutputStream baos = new ByteArrayOutputStream();
131 
132 	String surl = url.toString();
133 
134 	// Parse out the timestamp
135 
136 	putInt32(hdr, timestamp, baos);
137 	byte[] timestampBytes = baos.toByteArray();
138 
139 	// Parse out the URL.
140 
141 	byte[] urlBytes = hdr.putString(surl, baos);
142 
143 	// Parse out the scope list.
144 
145 	byte[] scopeBytes =
146 	    hdr.parseCommaSeparatedListOut(scopes, baos);
147 
148 	// Parse out the attributes.
149 
150 	byte[] attrBytes = hdr.parseAttributeVectorOut(attrs,
151 						       url.getLifetime(),
152 						       false,
153 						       null,
154 						       baos,
155 						       false);
156 
157 	// Parse out SPI list
158 	String spisString = "";
159 	// First get DA SPIs from DA SPIs property
160 	LinkedList spiList = AuthBlock.getSPIList("sun.net.slp.SPIs");
161 	if (spiList != null && !spiList.isEmpty()) {
162 
163 	    StringBuffer spiBuf = new StringBuffer();
164 	    spiBuf.append(spiList.getFirst().toString());
165 
166 	    for (int i = 1; i < spiList.size(); i++) {
167 		spiBuf.append(',');
168 		spiBuf.append(spiList.get(i).toString());
169 	    }
170 	    spisString = spiBuf.toString();
171 	}
172 
173 	byte[] spiBytes = hdr.putString(spisString, baos);
174 
175 	// Parse out auth block, if necessary.
176 
177 	Hashtable auth = null;
178 
179 	if (SLPConfig.getSLPConfig().getHasSecurity()) {
180 	    Object[] message = new Object[9];
181 
182 	    // None of the strings have leading length fields, so add them here
183 	    message[0] = timestampBytes;
184 
185 	    ByteArrayOutputStream abaos = new ByteArrayOutputStream();
186 	    hdr.putInteger(urlBytes.length, abaos);
187 	    message[1] = abaos.toByteArray();
188 	    message[2] = urlBytes;
189 
190 	    abaos = new ByteArrayOutputStream();
191 	    hdr.putInteger(attrBytes.length, abaos);
192 	    message[3] = abaos.toByteArray();
193 	    message[4] = attrBytes;
194 
195 	    abaos = new ByteArrayOutputStream();
196 	    hdr.putInteger(scopeBytes.length, abaos);
197 	    message[5] = abaos.toByteArray();
198 	    message[6] = scopeBytes;
199 
200 	    abaos = new ByteArrayOutputStream();
201 	    hdr.putInteger(spiBytes.length, abaos);
202 	    message[7] = abaos.toByteArray();
203 	    message[8] = spiBytes;
204 
205 	    auth =
206 		hdr.getCheckedAuthBlockList(message,
207 			SLPConfig.getSLPConfig().getAdvertHeartbeatTime());
208 
209 	    // Parse out auth blocks.
210 	    baos.write((byte)(auth.size() & 0xFF));	// auth block count
211 	    hdr.nbytes += 1;
212 	    AuthBlock.externalizeAll(hdr, auth, baos);
213 
214 	} else {
215 
216 	    baos.write((byte)0);
217 
218 	}
219 
220 	// Save bytes.
221 
222 	hdr.payload = baos.toByteArray();
223 
224 	hdr.constructDescription("DAAdvert",
225 				 "        timestamp="+timestamp+"\n"+
226 				 "        URL="+url+"\n"+
227 				 "        attrs="+attrs+"\n"+
228 				 "        SPIs="+spisString+"\n"+
229 				 "        auth block="+AuthBlock.desc(auth) +
230 				 "\n");
231     }
232 
233     // Put out the lower 32 bits of the timestamp.
234 
235     static private void
236 	putInt32(SrvLocHeader hdr, long i,  ByteArrayOutputStream baos) {
237 	baos.write((byte) ((i >> 24) & 0xFF));
238 	baos.write((byte) ((i >> 16) & 0xFF));
239 	baos.write((byte) ((i >> 8)  & 0xFF));
240 	baos.write((byte) (i & 0XFF));
241 
242 	hdr.nbytes += 4;
243     }
244 
245 }
246