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