Author Topic: How to install CSP - The Beginne  (Read 13794 times)

0 Members and 1 Guest are viewing this topic.

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
How to install CSP - The Beginne
« on: March 08, 2011, 11:05:38 PM »
CONFIGURATION NOTES: (checklist for a basic setup)

- Define ca-profiles, one for each provider/vendor/card-type (yes if two providers happen to use the same ca-system, two
separate profiles are still required). Ca-profiles can be thought of as virtual cardservers, and will seem to the
clients like single cards (with a potentially infinite capacity). If you have an enigma1 services file (dreambox)
you can fetch that and place it where the proxy can read it and point it out in the profile definition. This will
get you friendly readable names for each service rather than just service id. Multiple profiles can read from the
same services file if you specify a provider string as a filter (see proxy-reference.html).

- Define newcamd/radegast listen-ports as needed for each profile (always use newcamd if you have a choice). Usually
only one port is required per profile (or two if you need both newcamd and radegast listeners), but it is now
possible to have an arbitrary number of listen ports for the same profile, complete with their own accept/deny lists
and other protocol-specific settings.

- Define cws-connectors for each cardserver that the proxy should connect to. Use one newcamd-connector or
radegast-connector for each card, and again newcamd is prefered if you have the option (and there would be no point
in connecting to the same card twice with different protocols, don't try it).
Specify which profile each connector belongs to. If the server doesn't always contain the same card then you can omit
the profile, but then you need to be sure that ca-id is correctly specified in each ca-profile. If you have
multiple proxies accessing the same cardserver (or other clients on the side connecting directly to a cardserver)
make sure they all use different accounts in the server.

- Define user accounts that the clients can use to access the proxy profiles. Alternatively, plug in your own user-
manager that makes use of an existing database. Keep in mind that by default users are only allowed 1 connection, so
if you have multiple profiles that users are supposed to have access to simultaneously then you need to increase the
max-connections attribute to be at least equal to the number of profiles. As of 0.8.2, the default is changed from 1
to the number of profiles accessible to the user (e.g if he has profiles="profile1 profile2 profile3" max-connections
becomes 3). This means you only need to change max-connections for users that need more than one client.

- Check all general options in proxy.xml against the proxy-reference.html docs. The defaults in the provided example
configs are not necessarily reasonable, you will actually have to understand what most of the settings mean.
As of 0.8.1 you can start the proxy without proxy.xml, and a skeleton example will be generated for you (in ./config).

- Set the log level to info or fine, switch debug on, along with log-ecm and log-emm. Watch the logs as you start the
proxy and make sure it is able to connect properly to all defined servers, then see what happens when clients connect
to the ca-profiles. Once you get everything working smoothly, you can switch off debug and use info or warning level.

---

Some important caveats for the automatic SERVICE MAPPING:

- If there is only one card in a profile, or multiple identical cards (same subscription/services) it is probably best
to disable service mapping entirely for that profile (although the web gui will be more interesting if it is left on).

- Make sure the newcs user for the proxy doesn't have any rate limit set, since this would be immediately exceeded and
result in cannot decode replies which would screw up the service mapping. Avoid connecting to the same account with
multiple proxies or proxies + other clients, use one account for each connection.

- There is a very limited tolerance for bad ecms. If a card connector fails to decode 2 ecms in a row for service X
(for whatever reason) the proxy will assume service X is no longer available on that card and stop using it for that.
If one client se$$$ bad ecms that result in cannot decode replies when this shouldn't happen, the service
mapper may remove services from card connectors incorrectly (which affects all users).
For users with erratic clients that cause problems like these, try setting map-exclude="true" and the proxy will not
draw any mapping conclusions based on this user's ecms. Likewise if you have any untrusted users, you probably want
them excluded from the mapping to avoid deliberate sabotage.
NOTE: There is no point in setting map-exclude for ALL users, that would amount to disabling service mapping entirely.

- If you're having problems with bad ecms or other artefacts causing the service map to incorrectly remove services
from card connectors, try auto-reset-threshold="1" for the affected profile. This will cause lost services to be
found again more or less immediately, but will generate a lot of unnecessary probing if clients try to watch services
that really can't be decoded on any card. Using the retry-lost-services setting for all profiles with mapping enabled
is recommended. Use block-services to list all services known not to decode anywhere, to reduce unnecessary probing.

- The proxy has no way to determine whether the contents of an ecm is valid or appropriate for the profile. It will
assume that everything received on a given profile port is intended for the provider/vendor of that profile.
It's essential that profiles are set up correctly and all clients know which port to use, since if card connectors or
clients from multiple providers are mixed within one profile the service mapping will become seriously confused or
fail altogether.
If you see services appearing and disappearing at random from the card connectors then this is likely your problem.
As of 0.8.11 there is a transaction flag 'M' that will be set if cache hits indicate that clients are sending ecms
to the wrong profile port. In 0.8.13 such 'M' transactions will be blocked by default, to avoid misleading clients.

- Clients that do not (or cannot) specify correct service id in each request, will only work well in profiles where all
cards are identical (can decode the same services) or where there is only one card. Future versions may improve on
this. If you have hw clients like alex-cs, cardlink.nl or lce that cannot know the sid, you probably want to create a
separate profile for them, and include only cards with (roughly) the same sids available.
As of 0.8.12 there is a broadcast-missing-sid setting for the mapper section in the config, if this is true then every
ecm request without sid will be broadcasted to all connectors in the profile. The client will still only get the reply
from the connector chosen by the load-balancing, but in case that choice was wrong and the client does a retry, then
the CW should be available in the cache.
As of 0.9.0, sending the same ecm (without sid) multiple times to the same connector is avoided by a timed blacklist.

- If you face recurring issues with the automatic service mapping, manually specifying service lists for each connector
is possible. This is achieved by using elements can-decode-sids and cannot-decode-sids per connector config (see proxy-
reference.html).
« Last Edit: May 02, 2011, 12:22:22 PM by bandasdk »

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
CSP Optimization
« Reply #1 on: March 08, 2011, 11:08:54 PM »
CSP Optimization
----------------

Contents:
1. Client behaviour
2. Cardserver behaviour
3. Proxy configuration
4. Interpreting transaction flags
5. Linux/OS-tweaking
6. JVM tweaking


There are a considerable number of timeout values at play for any given ecm -> cw transaction, this readme will attempt
to identify the most common timing pitfalls and suggest a set of best practices.

It should be said that by far the greatest increase to stability comes from adding a second proxy, compared to that
any other optimizations are insignificant. Even if both proxies are connected to the exact same set of cards, the
second chance it offers to clients (regardless of what the issue was) has a _major_ impact on the perceived stability.

NOTE: Most of the tips here are based on ca-systems where the possible delay between the ecm appearing in the TS and
the cw actually changing is fairly large (>5 seco$$$). For ca-systems with tighter margins you may need other methods.
In most proxy examples, it is assumed that the client can safely wait nearly 9 seco$$$ for its cw reply without
experiencing a freeze.


1. Client behaviour (most of the proxy examples are based on mgcamd, or similar clients).
-----------------------------------------------------------------------------------------

- Identify and configure the ecm timeout* value for each client, and set this as high as possible.
I.e. if the situation allows waiting for 9 seco$$$ without causing a picture freeze, then set the value to 9 seco$$$.
Experiment to determine what the actual maximum is (you can use the LoggingPlugin, see 3. Proxy configuration).
If you have multiple proxies or other alternative connections, set the timeout slightly below the maximum to give the
client a chance to get a reply elsewhere in case of failure.

- Client ecm cache and reconnect/retry behaviour etc, are less important and can usually be safely ignored.
If possible the client should be configured so that it tries to connect to a previously unconnected server each time
it sees a new ecm.

- Always keep full client logging enabled when trying to determine the effects of configuration changes.
Usually its a good idea to always have udp logging enabled (with any and all debug options), and send the packages
to whatever desktop machine you're at. Then when troubleshooting is required, all you need to do is start a listener,
for example netcat: nc -l -u -p portnumber
On windows, netcat is available via cygwin (cygwin.com).

* Ecm timeout here refers to the maximum time that the client will wait for a cw response, after sending the ecm request
to the server, before giving up and moving on (typically resulting in a freeze). For example: the "K" value in mg_cfg.


2. Cardserver behaviour (most of the proxy examples assume newcs, but mpcs has also been used).
-----------------------------------------------------------------------------------------------

- Ensure that the server does not have any unnecessary limitations imposed on the account used by the proxy.
Rate limits are of course especially harmful and should be removed completely.

- Avoid configurations where the server attempts to connect back to the client (a newcamd feature). I.e. if the server
allows specifying hostname/port per user account, then make sure you don't. Remove any such elements.

- Ecm cache and emm cache can use reasonable defaults, there is no benefit in modifying them for the sake of the proxy.
Typically the ecm cache would not be used at all, and the emm cache is only there to prevent unecessary time consuming
card communication.

- Priority in the ecm queue is a non-issue when the server only has proxy users, but should be left at default or set
to fifo (or whatever setting causes requests to be processed in the order of arrival).

- Again, keep full logging enabled while troubleshooting. If the server has udp logging, use it to send the log
events to the same target machine used by the client logging (use a different port though) so you can compare both
side by side in real time.

- Keep an eye on cpu use on the server, especially if it is running on a small embedded system. If it is maxed out
it is more likely to experience glitches (returning duplicates, timeouts, card communication failures etc). If so it
may be necessary to insert an artifical delay between asynch requests (see default-min-delay in proxy-reference.html).
« Last Edit: March 08, 2011, 11:11:10 PM by bandasdk »

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
3. Proxy configuration
« Reply #2 on: March 08, 2011, 11:09:44 PM »
3. Proxy configuration
----------------------

To get a definitive overview of what the proxy does with each config value (and where it does it), you can start java
with the following param: -Dcom.bowman.cardserv.util.tracexmlcfg=true
That will track all access to proxy.xml and when you request it (via the admin section of the status web), dump the
trace to file in the proxy etc dir.

It will produce output such as this:

/cardserv-proxy/connection-manager
cannot-decode-wait
type: Time (defSuffix=s)
default: '0'
caller: CwsConnectorManager.configUpdated(CwsConnectorManager.java:63)

Which means that the CwsConnectorManager checks the value of the setting on line 63 in the method
configUpdated() in the file CwsConnectorManager.java. It also shows (as of 0.9.0) that this is a time value and that
the default is 0 (disabled in this case), as well as specified in seco$$$ unless otherwise indicated.


- Asynchronous vs synchronous newcamd

With synchronous newcamd communication (default) the proxy will only send one request at a time to each connector, and
await a reply to that before proceeding. In theory this is inefficient, since the newcamd protocol supports multiple
concurrent requests. In synchronous mode any and all delays that occur due to network latency spikes (or other glitches)
or simply other users on the server side, will delay the entire proxy queue for the connector.

In the asynchronous case, the proxy se$$$ all pending requests for the connector immediately to the server as fast as it
will read them. The replies are then matched to requests by the newcamd sequence id present in each message, as they
come back.
This effectively moves the queue handling from the proxy to the server, and should mean a higher throughput as there is
less room for network interference. Not all servers support async, and even those that do (e.g later newcs versions)
seem to sometimes return unexpected sequence ids. Situations where multiple proxies (or other users) use the same newcs
port seem especially error prone.

As a rule of thumb, if you want to get the maximum capacity from your connectors you should try async mode. Watch the
logs closely for issues related to out of sequence data though (unexpected/unknown replies and subsequent timeouts),
or it could end up doing more harm then good.

If a connector points to another csproxy, it should use synchronous mode (as the proxy will assume each client is a
regular user which will have at most one pending ecm request at any given time).


- The following timing values are significant:

/
Set this to the same as the client ecm timeout (e.g 9 seco$$$) or if in doubt, leave it at the default setting.
Changing it affects what the proxy considers to be one cw validity period, and this in turn affects statistics and
capacity estimates.
Under normal circumstances, you never want to set this value below the ecm timeout of the clients (it should be
equal or larger). In general however, it depe$$$ on which timeout you wish to be reached first, client or proxy.
It may depend on which clients are in use and how they deal with timeouts.

To help figure out the exact cutoff point for clients (the maximum time they can wait before they experience a freeze),
use the LoggingPlugin and the set-test-delay ctrl command (via the status web). This allows you to experiment by adding
a gradually increasing delay for a specific test-client (use the ip filter). Watch the client logs closely and try to
see at which exact ecm round-trip time the freezes start occuring. This is your max-delay for this particular ca-system.
If the time is very short (<3 seco$$$) it might not be possible to set the max-cw-wait for the proxy to the same, but
at least you know where the cutoff point is. Values <4 have not been tested with the proxy, but may still work.
NOTE: To get accurate values with test-delay, use a service that is cached (that other clients are currently watching).
Also, make sure the client ecm timeout is increased to a level where it will not interfere before the test (>9 secs).

/
This allows you to configure the point at which the proxy considers a connector to be congested. The value refers
to the estimated connector queue-length (in seco$$$). By default it is the same as the but its usually
a good idea to set it slightly below, to force service-mapper and metric handling to move to other connectors sooner.
I.e: if max-cw-wait is 5, set congestion limit to 4 (causing any connector with a queue of >8 to be flagged as congested).
Using this mainly makes sense if you have multiple cards with different metric levels and want to fine-tune when the
higher metric cards start getting used.

/ /
You want to keep this at a level that is as high as possible, but still allows room for one retry before the
max-cw-wait is reached. I.e. if max-cw-wait is 9, and the average response time for your profiles is around 2 secs,
set the max-cache-wait to 6 or 7 secs.
This should result in a behaviour where a timeout in the cache means the client can still receive a reply before
reaching its own timeout. Use the transaction flags to determine whether this is actually the case (see below).

Cache timeouts occur when an expected reply never arrives, either because the server that the request was sent to
became disconnected or overloaded, or because a remote cache that indicated it was going to provide the reply failed to
do so (or did but it got lost in transit). It is normal to see more cache timeouts in a proxy setup that uses the
clustered cache.


- These are less important but deserve mention:

/
This only determines how often the proxy will attempt to reconnect to disconnected servers. It can be reduced to
10-15 seco$$$ (but avoid lower values) to minimize downtime due to shaky connections when there are few cards available.
Keep in mind that whenever a connection is lost one immediate retry is performed, so its usually best to leave this
at 30-60 seco$$$.

/
If there are nat-routers or some equivalent between proxy and server, tcp's that are idle for more than a set time
may end up getting disconnected. Setting this value to slightly below that idle timeout will ensure they stay up.
E.g: 59 seco$$$. Note that no keep-alives are sent as long as there is traffic on a server connection, so
there is no danger of flooding it with unnecessary messages.


- Don't touch these unless you're experimenting with some really radical cache-sharing setups:

/
/ /
/ / (experimental, if in doubt remove this from your config)


- For very large shares changing these may be required (see proxy-reference.html):

/
/
/
/ (also available as set per connector)
/ (also available as set per connector)


- For proxy troubleshooting, make sure you have debug="true" for all profiles, and logging configured as follows:


log/cardserv.log
FINE
true
true




In general this is a reasonable troubleshooting default, but of course depending on what you're looking for it may need
changing. Under normal operation you want to use level INFO (or WARNING), and it may make sense to only log transactions
exceeding the client ecm timeout limit as warnings. I.e. use something like:


For each transaction that meets the warning criteria, a more detailed time log will be made available, showing exactly
what the wait time was spent on.
- Cache wait: The time the request was locked in the cache, waiting for another transaction forwarding to a card.
- Send queue: Time spent waiting in line to be sent to a card (usually 0 in async mode as everything is sent immediately).
- Server wait: Time spent waiting for the server to reply. For normal (cache miss) transactions this should be longest.
- Client writeback: Time spent sending the reply back to the client. Typically 0-1 ms, unless there is a network issue.

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
4. Interpreting transaction flags,5. Linux/OS-tweaking,6. JVM tweaking
« Reply #3 on: March 08, 2011, 11:10:33 PM »
4. Interpreting transaction flags
---------------------------------

Normal traffic flags:
F = Normal forward to CWS
C = Cache hit (local)
R = Cache hit (received from remote cache)
I = Instant cache hit (no waiting at all in cache, both request and reply already available)
1 = This was the first transaction performed by a new session
Z = SID changed (compared to previous transaction = user zap, can also indicate multiple tuners or users in one session if it occurs every time)

Service mapper flags:
N = Cannot decode (service mapper says service not on any card, or service blocked)
P = Triggered probing of one or more cards (service mapper didn't know status for this SID)
+ = Caused an addition to the service map (found service, after probing/successful decode)
- = Caused a removal from the service map (lost service, after repeated failed decodes)

Flags indicating possible problems/recovery situations:
B = Blocked by exceeded limits or by filters (plugins)
M = Ca-id mismatch. The ecm reply didn't have the same ca-id as the request, indicates some clients are sending ecms to the wrong ports.
E = Client got an empty reply (cannot-decode received from CWS, or from the proxy itself with situation N
Y = Forward retry performed (first chosen CWS disconnected during the transaction, but alternatives exist)
A = Abort when forwarding (CWS connection was closed before forward, because of other request timeouts or by the network/server)
T = Timeout when forwarding (no response from CWS within time limit, i.e max-cw-wait)
O = Timeout while waiting in cache (waited for max-cache-wait, but no reply was reported to the cache)
Q = Abort while waiting in cache (the forward the cache was waiting for failed, either locally or remotely)
G = Congestion when forwarding (time was > max-cw-wait/2, but forward still performed)
X = Cache hit after failed forward (situation Y, but reply became available in cache so no need for new forward)

Internal/debugging flags:
S = Timeout in send queue (when trying to forward to connector, should normally not occur)
W = Triggered cannot-decode-wait (would have been situation N, but waiting for remote cache paid off)
H = Caused an internal failed rechecking of the cache, represents an attempt to recover from an immediately preceeding problem
U = Interrupt in the no-sid-delay sleep, a request without sid was delayed but disconnected during the delay
D = The user session disconnected before it could receive the reply (likely reached the client ecm timeout)


Transaction flags are listed in the order in which they were set internally by csp (before 0.8.7 it was alphabetical).
I.e. "OFD" reads as: cache timeout occured (O), so attempted forward to card (which succeeded - F), but when the
reply from the forward was returned the client had already disconnected (D).
Note that many flags can occur at virtually the same time, so the order isn't necessarily chronological in all cases.

Examples of common transactions (with the flags ordered as of before 0.8.7):

"FPXZ" - User zapped (Z) to a service that the service mapper lacked knowledge for on one or more cards, so
probes were sent to multiple cards (P). Not knowing where to find the service, the proxy forwarded to the least loaded
card in the profile (F). This card failed to provide a reply, but after the failure a reply was found in the cache (X).
I.e. one of the other probes did get a successful reply.

"+FPZ" - Same as above, except the least loaded first choice was able to provide a reply, and the service mapper used
this information to update the mapped status for this card (+).

"FO" - A cache timeout occured (O, remote cache update may have failed to arrive in time. There was time left before
max-cw-wait, so a forward was performed (and suceeded, F).

"CIZ" - User zapped (Z) to a service already present in cache ©, and immediately received a reply with no waiting (I).
"IRZ" - Same except the cache entry came from a remote cache.

"FOZ" - The first transaction for a new client connection (Z) resulted in a cache timeout (O) followed by a forward (F).
Normal if it occurs mainly in connection with proxy restarts (local or remote), before all cards have been connected.

"ENZ" - User zapped (Z) to a blocked service causing the proxy to immediately reply with an empty cannot-decode (EN).

"+NPZ" - Same as above, except the service wasn't blocked, only marked as non-existant on all cards by the service
mapper. This one request meant the auto-reset-threshold was exceeded, so probes were sent (P) and the first one got
a successful reply, causing the mapper to change the status on that card from cannot decode to can decode (+).

"-EFZ" - User zapped (Z) to a channel believed to exist on a card, but when it was forwarded the server replied with a
cannot decode (EF) and this was the 2nd such failure for this card, so the service mapper removed the channel (-).

"EFT" - A forward (F) timed out waiting for the reply to be returned from the server (T), and there was no time left
for retries so an empty (cannot decode, E) reply was sent back to the client.

This scenario can be fairly common and would show something like this in the standard log, for a situation where the
reply was just a little too late:

WARNING -> NewcamdCws[cwsname:profile] <- Timeout waiting for ecm reply, discarding request and returning empty
(1 failures) - ECM B9328A35 - [16] - Waited: 8241ms
^^ sequence id
INFO -> NewcamdCws[cwsname:profile] <- Message received, cancelling timeout-state

WARNING -> NewcamdCws[cwsname:profile] <- No request found for reply: 16 (DCW, ServiceName profile:sid)
^^ sequence id
I.e. when the reply is finally received, the request is already deleted and the client has been given a failure reply.


5. Linux/OS-tweaking
--------------------

As of 0.8.11 the proxy will use sun java6 features to keep track of used and available unix file descriptors (file
handles). This is a common source of problems, as each tcp socket uses at least one and the default maximum limit per
user is commonly 1024. If exceeded there would be java exception stacktraces in the logs with messages such as
"too many open files".

You can check this by logging in as the user who will be running the proxy and doing:
$ ulimit -n
1024

To increase the limit you typically have to edit /etc/security/limits.conf and add lines like these:
proxyuser soft nofile 8192
proxyuser hard nofile 8192

After a reboot ulimit -n output should show 8192 when logging in as proxyuser. If running sun java6, the currently used
and available filedescriptors will be visible in the status web (as part of the proxy-status xml api command) shown as:
FD: [used/maximum]

If not using sun java6, you can still get some idea how many handles are used by the proxy using lsof for the proxy pid.
For example:
$ /usr/sbin/lsof -p `cat cardservproxy.pid` | wc -l
181

Note that this value will tend to be higher by a fixed number than the one reported by the sun jvm, presumably because
lsof also lists some file handles that don't count against the per-user quota.
I.e. when lsof shows 181, FD would show 141 (the actual number that will cause problems when it reaches the limit).

Depending on OS and JVM, there might also be other limits hit (such as noproc, number of processes/threads).


6. JVM tweaking
---------------

As mentioned elsewhere the proxy only works properly with real sun java (and was only tested under 1.4.2 and 1.6).
To verify that you're using the correct one, check the status web. It should mention HotSpot if it is sun, i.e:
[Java HotSpotâ„¢ Server VM1.6.0_03]
Server or client doesn't matter much, and neither does 64/32 bit (although 64 will tend to use significantly more heap).
If it turns out to be any other jvm implementation you're likely to run into subtle and sporadic problems.
If you've found another that does seem to run the proxy well enough under load, and you can prove it: let me know.
As of 0.9.0, a super user can click on the jvm name in the status web to trigger the status command 'system-properties',
which shows all the jvm information as xml.

The Heap usage displayed on the status web shows the amount of memory currently in use (within this jvm instance, it
says nothing about the rest of the system) and the total allocated by the jvm so far, i.e:
[12503k/57536k] means ~12 megs in use and ~57 allocated. It does not imply that 57 is the maximum available to the jvm,
once it is reached it will probably be able to allocate more.
If it is unable to do so you'll start to get OutOfMemoryError in your logs (hopefully, it may just fail silently).
The maximum heap the jvm is allowed to allocate by default depend on the jvm version and os.
To increase it, add the following parameter to the line that starts java (in cardproxy.sh if you use that script):
-Xmx256m
That would allow the heap to grow up to 256 megs, which should be more than enough for most use cases.
If you know how much your setup usually e$$$ up using, you can give the jvm that much to start with, by also adding:
-Xms100m (for example, this will allocate 100 megs immediately on startup).

The next value 'TC' is for thread count. This will normally be a fixed number around 15, + 2 for every connector, + 1
for every listen port, + 1 for every client session. Use it to spot problems. As long as none of the above changes,
the thread count shouldn't either. If it does then something is going on that you should look into.
As of 0.9.0, clicking on the count will show a list of the actual threads. All threads in the proxy core use very
descriptive names so it should be immediately apparent what each one does.

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
XmlUserManager (com.bowman.cardserv.XmlUserManager)
« Reply #4 on: March 08, 2011, 11:12:56 PM »
XmlUserManager is a small extension of the built in example SimpleUserManager. Instead of reading user definitions
only from proxy.xml it can fetch an external xml file from any url. This can be a simpler alternative to a full
database usermanager, when maintaining the same set of users in a cluster of multiple proxies.

- XmlUserManager uses the exact same xml format as SimpleUserManager (see proxy-reference.html).
- It will accept user definitions included in proxy.xml, just like SimpleUserManager. These are parsed before any
attempts are made to get external definitions, making it possible to have some local users in addition to the main
user db.
- If the same username exists both in proxy.xml and in the fetched user file, the local definition will be overwritten.

------------------------------------------------------

The following are settings are available for XmlUserManager:



- To load the XmlUserManager, use the following user-manager class name: com.bowman.cardserv.XmlUserManager
Changing from one user-manager to another requires a proxy restart.


You are not allowed to view links. Register or Login

- The url of the xml file with user definitions. The file should match the auth-config for SimpleUserManager, but
the top level element is ignored. See config/users.example.xml for an example.
Any url can be used, including https/ftp with user:passwd@hostname type auth info. File urls are also accepted.

NOTE: When using a http/https url, it doesn't have to point to an actual static xml file. A php/jsp/asp page that
renders the xml dynamically from an underlying database is a more flexible solution.

asdf22

- Optionally, the user file can be blowfish encrypted using the included fishenc.jar tool (found in lib). If the
file is not encrypted, omit the user-file-key element entirely.

5

- How often to check for changes in the user file. If no changes have occured, the file will not be fetched/parsed.







------------------------------------------------------

NOTE: Errors in the user file will not prevent the proxy from starting, it will only log warnings if unable to
fetch/parse the file. Local users in proxy.xml will still be available.
Should the user file become temporarily unavailable or broken, the proxy will keep using the last known working one.
To see exactly what XmlUserManager is doing, use log-level FINE.

As of 0.8.8 it is possible to specify multiple source urls, using the following format:




You are not allowed to view links. Register or Login
asdf22


You are not allowed to view links. Register or Login


file:///tmp/users.xml


5

- A third (and perhaps the best) option for configuring multiple targets for cache-updates. The ClusteredCache will
fetch a plain text list of hostnames and portnumbers, and send updates to every entry in the list. The list can be
automatically fetched at regular intervals (or if tracker-update is 0, only when proxy.xml is modified/touched).
This approach allows proxies to be added to a cluster without having to modify the configuration of already existing nodes.
The list must have the following format (# are comments):

# ClusteredCache list file. Syntax: hostname_or_ip:udp_port_nr
proxy1.host.com:54278
proxy2.host.com:54278
192.168.0.3:54275

The list can be stored anywhere, as long as it can be accessed via url (e.g file://, http, https, ftp).
Optionally, the list can also be blowfish encrypted using the included tool fishenc.jar (found in lib, java -jar fishenc.jar).
If encrypted, tracker-key must be correctly set.

54278

- The UDP port where this ClusteredCache instance will listen for incoming updates.

csproxy3.host.com

- The external hostname or IP of this ClusteredCache. This is only needed when using the above tracker setup. The name
should match the one in the tracker list, so the cache instance can identify itself in the list and avoid sending itself
updates.

true

- Set debug to true to enable additional cache information in the status-web. This can impact performance, use with care.

false

- If configured to send to one or more remote caches, this controls whether the names of the connectors are censored in
the outgoing cache updates (will appear as remote: unknown to the target). Only makes sense when dealing with untrusted
proxy peers.

0

- Set this > 0 to enable the strict arbitration procedure. For example if you set it to 200, the ClusteredCache
would use 200 ms for every new (previously unseen ecm) to wait and synchronize with as many other proxies in the cluster
as possible, and determine who is best suited to handle it. Only this proxy would proceed with a forward to a card.
This adds 200 ms to every single transaction, but should ensure that a cluster of proxies will only ask one card in one
proxy, once, for the same ecm. Probably only usable in a cluster where all nodes are fully trusted, and where the
network is reliable with fairly fixed ping times and no congestion.



------------------------------------------------------

NOTE: It is possible to set up the ClusteredCache without any remote targets (receive-only-mode). If no remote-host/port
is set using any of the various methods then the default behaviour will be to not attempt any sending of updates.
This is useful when creating a cache-only proxy node, receiving updates from multiple other proxies but sending to none.
It can also be used to augment local cards with additional services (which will only be available through the cache).

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
CSP Plugins
« Reply #6 on: March 08, 2011, 11:14:13 PM »
CSP Plugins
-----------

As of 0.8.6 the proxy has a plugin framework. This is another one-hour hack so don't read too much into it.

NOTE: With 0.8.10 it is also possible to add connector implementations using these same methods, although connectors
wouldn't be loaded under the plugins section (see README.$$$$$Connector.txt).

Some ideas for plugins:
- CA emulation, have the proxy read/fetch/use the static keys and the clients wont have to.
- Your own simplified CS protocol.
- BISS.
- Log aggregation, have the proxy receive udp/syslog events from servers and clients to aid troubleshooting.
- Fault management, triggering nagios or zabbix alarms on critical errors.

To create a new plugin, first read README.Compiling.txt and ensure you can successfully build the proxy itself.
The source code itself is the ultimate documentation and to find a place to start, you can use the following param when
starting java: -Dcom.bowman.cardserv.util.tracexmlcfg=true
That will keep track of where all proxy.xml accesses are made from in the code, and dump it to file when
you request it via the admin section of the status web.

Then use the following procedure:
1. Copy one of the existing plugin directory trees and rename it (e.g MyTestPlugin).
2. Edit build.xml in the plugin dir and search/replace the old name to match yours.
3. Place any extra dependencies your plugin will need in the lib dir. Remove any jars that are not needed.
4. Start editing the source, renaming the main plugin class and file to match your new name.
5. Run ant in the plugin dir to compile and build the jar (it e$$$ up in dist).

Place the jar in proxy-home/plugins, then add the config elements for the plugin to proxy.xml, e.g:

...


// plugin specific config here


...


The plugin lifecycle is as follows:
1. The main plugin class (that implements ProxyPlugin) is instantiated.
2. configUpdated() is called with the settings specified for this plugin in proxy.xml.
3. Assuming configUpdated() didn't throw any exceptions, start() is called, with a reference to the proxy istself.
4. Next time proxy.xml is touched or changed, stop() will be called allowing the plugin to cleanup before unload.

For most plugins it should be possible to replace the jar file and update/touch proxy.xml to have the new version loaded
without restarting.
NOTE: As of 0.8.11, plugin jars are watched for changes, and automatically reloaded when replaced.

The plugin api is fairly primitive, here's a quick guide for a single class example:

package com.bowman.cardserv;
// You can use any package, but there could be some protected methods only accessible from this one in the main classes.

import com.bowman.cardserv.interfaces.*;
import com.bowman.cardserv.util.*;
import com.bowman.cardserv.rmi.*;
import com.bowman.cardserv.web.*;
// Depending on what you intend to do, different parts of the proxy source needs to be imported.

import java.io.*;
import java.util.*;


public class MyTestPlugin implements ProxyPlugin {
// The main class of the plugin must implement this interface: com.bowman.cardserv.interfaces.ProxyPlugin
// If you want the plugin to have a say in connector selection, also implement: com.bowman.cardserv.interfaces.CwsSelector
// If you want the plugin to filter replies from connectors (dcw's) implement: com.bowman.cardserv.interfaces.ReplyFilter
// Methods outlined below...

public void configUpdated(ProxyXmlConfig xml) throws ConfigException {
// Whenever proxy.xml is changed the plugin will be discarded and reloaded. Settings from proxy.xml available here.
// The plugin should verify that they make sense and throw a ConfigException if they dont.
}

public void start(CardServProxy proxy) {
// Called after configUpdated(). Tells the plugin to initialize everything and start any background jobs etc.
// If it needs access to the proxy it should store the reference passed to this method.
// This reference can be used to get access to most of the functionality, see MessagingPlugin for one example.
// Any control or status comma$$$ should be registered here.
}

public void stop() {
// Called before unload is attempted (every time proxy.xml changes, or when the plugin jar is replaced).
// The plugin should stop all threads and remove any references to itself that it might have registered elsewhere.
// Any control or status comma$$$ should be unregistered here.
}

public String getName() {
return "MyTestPlugin"; // Displayname for the plugin
}

public String getDescription() {
return "A test plugin."; // Description
}

public CamdNetMessage doFilter(ProxySession proxySession, CamdNetMessage msg) {
// Called with every single message sent to the proxy from a client session, or from the proxy back to the sessions.
// The plugin can modify the message, return something else entirely, or block it (by doing msg.setFilteredBy("Reason text")).
// See the LoggingPlugin or EmmAnalyzerPlugin for examples.

return msg; // = do nothing
}

public byte[] getResource(String path, boolean admin) {
// This allows the plugin to export content to the httpd
// The following code ensure that anything placed in /web in the plugin jar file is available via the proxy web.
// Files are accessed using You are not allowed to view links. Register or Login
// The admin flag indicates if the user logged into the web as an admin user.

if(path.startsWith("/")) path = path.substring(1);
try {
DataInputStream dis = new DataInputStream(getClass().getResourceAsStream("/web/" + path));
byte[] buf = new byte[dis.available()];
dis.readFully(buf);
return buf;
} catch (IOException e) {
return null;
}

// Note that user login will be required to access anything this way, with one exception:
// The plugin will be queried for a file called "load.js" whenever anyone accesses the default status web (cs-status).
// This file allows the plugin to hook itself into the javascript in cs-status.war. See GeoipPlugin for an example.
}

public byte[] getResource(String path, byte[] inData, boolean admin) {
// Same as the above method, except for http POST instead of GET.
// Can be used to allow file uploads from the web to a plugin (or any custom data from the client side scripting).

return null;
}


// If your plugin implements the CwsSelector interface, the proxy will call this method for every incoming ecm request.
// The call includes the session where the message originated, and the connectors (set of name Strings) that the proxy
// thinks are valid choices to handle this request. Your plugin can remove names from this list based on the contents
// of the CamdNetMessage data, or based on the properties of the user associated with the session.
/*
public Set doSelection(ProxySession session, CamdNetMessage msg, Set connectors) {
return connectors;
}
*/

// If your plugin implements the ReplyFilter interface, this method will get called for every connector reply (dcw).
// This happens before the proxy does anything with the reply, and allows the plugin to look for and remove bad dcw's.
// To change a suspicious dcw reply into a cannot decode, do msg.setCustomData(new byte[0]).
// To silently block a reply entirely (probably a bad idea) return null instead of the msg.
/*
public CamdNetMessage doReplyFilter(CwsConnector connector, CamdNetMessage msg) {
return msg; // = do nothing

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
Compiling CSP
« Reply #7 on: March 08, 2011, 11:15:04 PM »
Compiling CSP
-------------

The proxy is pure java and can be compiled on any platform that has a java sdk available.

You'll need the following:
- The Java SE sdk and compiler (j2sdk) 1.6 or later: You are not allowed to view links. Register or Login
NOTE: As of 0.8.10 java 1.6 is required to compile everything, but 1.4 is still enough to run the proxy.
Sun only provides downloads for linux/win/solaris, osx users look to apple: You are not allowed to view links. Register or Login
- Apache ant (xml makefile system) 1.6 or later: You are not allowed to view links. Register or Login
- If you're on windows, you should consider using cygwin to get a proper bash shell: You are not allowed to view links. Register or Login
- If you plan to change or fix something, a basic understanding of java concepts will help:
You are not allowed to view links. Register or Login

The proxy comes with project files for Intellij IDEA 7, but you don't need this to compile (its a commercial product):
You are not allowed to view links. Register or Login
NOTE: There is now a open source community version as well, which works perfectly with the csp project files:
You are not allowed to view links. Register or Login

Ant may require you to set the environment variable JAVA_HOME so that it points to your j2sdk install dir.

Once j2sdk + ant is installed (and their respective /bin directories added to PATH) you can build the proxy using the
following procedure:

$ tar xvzf cardservproxy-0.8.13-src.tar.gz
$ cd cardservproxy-src
$ ant

This runs the default build target "tar-app" in the build.xml file. This target compiles all classes, creates
the jar/war files and finally tars the installation directory structure.
Each output file e$$$ up in ./dist

NOTE: tar-app will attempt to build the example plugins (which may have dependencies). If you don't want these then
run ant with: -Dskip-plugins=true

--------------------------------------------------------------------------------------------------------------------

The source distribution is arranged as follows:

build - Temp directory for the installation distribution (dir structure for cardservproxy.tar.gz).
classes - Temp directory for compiled .class files.
config - Example configs and reference.
dist - Temp directory for generated distribution files.
lib - Dependency jars needed to compile (but not to run, you'll need to copy the jars from dist to lib to do that).
NOTE: Source for these dependencies is available on request (go find bowman on efnet or bow on freenode).
etc - Misc resources.
src - Java source files and other resources that will end up in cardservproxy.jar.
trtest - Files needed for the executable fishenc.jar (manifest only, all classes are in cardservproxy.jar).
web - Files for the status web monitoring gui (see README.HttpXmlApi.txt for details). E$$$ up in cs-status.war.
plugins - project dirs for the example plugins (each one laid out roughly like the main dir for the proxy source).

jsw-win32.zip - Template for a java-service-wrapper windows setup (running java and the proxy as windows service).
CardServProxy.ipr CardServProxy.iml - Intellij IDEA project and module files.
build.xml - Apache ant makefile.

NOTE: While the java source may seem somewhat organized at first glance, it's really a mess. It's the result of years
of organic growth (with contributions from many people) with little or no testing or oversight. Don't assume anything
in there is well thought through, if something seems broken - it probably is.

Offline bandasdk

  • Jr. Member
  • **
  • Posts: 82
Csp http/xml api
« Reply #8 on: March 08, 2011, 11:15:51 PM »
Available status comma$$$ (as of 0.9.0):
----------------------------------------
- proxy-status: general usage stats
optional parameters: profile (show info for this profile only)*

- ca-profiles: list of all defined profiles, and their listen ports
optional parameters: name (name of the profile to retrieve, omit for all)*

- cws-connectors: list of all defined connectors and current usage stats for each
optional parameters: name (name of the connector to retrieve, omit for all)*
profile (list only connectors within specified profile)

- proxy-users: list of all active user sessions, and their current status
optional parameters: name (user name to retrieve, omit for all)**
profile (list only sessions within specified profile)

- cache-status: usage stats from the current cache implementation
optional parameters: none

- error-log: the last 40 (by default) events of general interest
optional parameters: profile (list only events related to specified profile)

- user-log: the last 100 transactions results for a specific user (requires debug="true" for the profile)
optional parameters: name (list transactions for named user instead of calling user, admin only)

- user-warning-log: the last 40 transactions with attached warnings (aggregated if the same warning occurs often)**
optional parameters: profile (list only events related to the specified profile)*

- all-services: all services found on all connectors (requires service mapping and a services file)
optional parameters: profile (list only services for specified profile)

- watched-services: currently watched services, based on active user sessions (requires a services file)
optional parameters: profile (list only services for specified profile)

- export-services: dump of the current internal state for the service mappers (which sids can and cannot decode).
optional parameters: name (export map only for the specified connector, omit for all)

- fetch-cfg: returns a copy of the current proxy.xml (NOTE: response is without the cws-status-resp wrapper element!)
optional parameters: none

- ctrl-comma$$$: lists available control comma$$$, and their options
optional parameters: none

- status-comma$$$: list available status comma$$$, and their options
optional parameters: none

- last-seen: lists information about disconnected or removed users (seen before by the session manager)
optional parameters: name (only show seen info for the specified user, omit to show all)**

* By default, only profiles (or connectors within profiles) that the calling user has access to will be shown.

** All comma$$$ are available to any user, however only admin users will be able to retrieve information about
other users. A non-admin user will receive only their own data, regardless of the name parameter.

As of 0.8.6 status-comma$$$ are also dynamic, so any piece of code (plugin or otherwise) may add new ones or override
the function of a command in the above built-in set.


Available control comma$$$:
---------------------------
This list is dynamic (comma$$$ can be added by plugins and extensions).
Run the ctrl-comma$$$ status command as an admin user to obtain the current list, e.g:
You are not allowed to view links. Register or Login$$$

Built in comma$$$:

- reset-connector: clear the service map for one connector (delete all cannot-decode entries causing new probes)
required parameters: name (connector name)

- reset-service: clear the service map entry for one service.
required parameters: id (service id, by default in decimal format, use 0x prefix when specifying hex value)
profile (name of profile that contains this service)

- retry-connector: attempt re-connection for one connector (also temporarily enables disabled connectors)
required parameters: name (connector name)

- kick-user: close all sessions for the specified user
required parameters: name (user name)

- osd-message: send newcamd osd message to all sessions for specified user (or for all users), where clientid is mgcamd or acamd
required parameters: text (message text, avoid special characters)
optional paramaters: name (user name)

- clear-warnings: delete all user transaction warnings

- clear-events: delete all CWS events

- shutdown: stop this proxy node


Remote config updates:
----------------------
It is possible to deploy an updated proxy.xml via HTTP post, using the target-url: /cfgHandler

To fetch the current config xml, use the status command fetch-cfg (admin user required).
When posting an updated config to /cfgHandler, use the same approach as for Method 1 below, with two exception:
- The new config xml is to be posted as is, no cws-status-req or cws-command-req wrapper elements.
- As a consequence, only HTTP basic auth can be used for the login (no way to specify session id in the xml).

The response xml will be a single element:
(proxy -> client)



Command method 1 - HTTP post
--------------------
The default target url for both status and control comma$$$ is: /xmlHandler (e.g http:/proxy-host:8082/xmlHandler).
Xml queries need to be sent with content-type: text/xml (if no charset is specified UTF-8 is always assumed).
No url encoding or base64 encoding should be used.

Login can use standard HTTP basic auth or, in situations where that isn't practical, the following xml-based login
can be used instead:

(login request, client -> proxy)






(successful login reply for an admin user, proxy -> client)




The user identity is any user defined by the current usermanager.
A session id is by default valid until the proxy is restarted (no timeout).
Incorrect user/pass results in:

(failed login reply, proxy -> client)




Once a session id has been obtained, the syntax for status comma$$$ looks like this:
(proxy-status command, client -> proxy)





Multiple status comma$$$ can be sent in one request, like this:
(multiple comma$$$, client -> proxy)








To specify parameters for the status comma$$$, just add attributes:
(cws-connector command with name parameter, client -> proxy)




A control command uses a slightly different syntax, and there can be only one command per request.
(reset-connector control command, client -> proxy)






Command method 2 - HTTP get
-------------------
Uses the same url endpoint as post: /xmlHandler
Login is standard HTTP basic auth only (a session cookie called JSESSIONID will be set if supported).

The same comma$$$ are available, but everything is specified on the query string as follows:
You are not allowed to view links. Register or Login ... herValue...

Examples:
/xmlHandler?command=proxy-users&profile=cable (retrieve all user sessions in profile cable)
/xmlHandler?command=cws-connectors&name=testconn (retrieve connector named testconn)

Control comma$$$ work the same way:
/xmlHandler?comand=osd-message&text=hello&name=userx (send osd text hello to all sessions for userx)


Example status web
------------------
The proxy comes with a simple web site (cs-status.war) made up entirely of client side javascript and xslt. This is
not a conventional web application, but rather a standalone script that will fetch xml from the proxy (ajax-style) and
format it using xslt directly in the browser. It has been tested in firefox 2/3, ie 6/7/8 and safari 3/4 (and probably
won't work in anything else). To get an idea of how the status web works with the xml api, check out the /api-test.html
test page.

To modify the visual appearance (or even structure) of the status web, look at the following files:

/xslt/cws-status-resp.xml - This is the xslt xml that transforms all status command responses into html (or xhtml).
It generates markup that will reference the css styles in: /css/style.css
For more information on xslt: You are not allowed to view links. Register or Login

/js/cs-status.js - The javascript that defines the different sections, and handles pre-processing of the xml (before
the xslt transform) and post-processing of the html. The post-processing involves adding script handlers to
specific id's in the markup created by the xslt transform, making the status web somewhat interactive.
Adding javascript handlers to the browser dom tree (rather than hard coding them into the markup) is sometimes
referred to as 'unobtrusive' javascript.

The cs-status.war file (a zip containing the directory tree served by the built in httpd) can be replaced at runtime
and changes will take effect immediately, no restart required.