Author Archive

szerda, október 12th, 2011 | Author:

Az elmúlt hetekben pályafutásom egyik legérdekesebb feladatával foglalkoztam a munkahelyen. Konkrétumokat nem akarok írni, de egy Amazon-os példával szemléltetem, miről is van szó.

Tegyük fel, hogy az Amazon be akar vezetni egy újféle rendezést: Ha a felhasználó úgy keres, hogy nem specifikálja, mi szerint akar sorbarendezni, akkor egy relevancia szerinti sorbarendezést kap.

Az első feltétele ennek, hogy meghatározzuk, a user milyen szegmens része: Ha korábban főleg technikai kütyükre keresett, akkor vsz. fiatal férfi, míg ha babaruhákat és melltartót vásárolt, akkor jó eséllyel családanya.

A következő lépés annak a meghatározása, hogy melyik szegmens mit szeret és mit nem. Ha például mobiltelefonokat nézünk, akkor a nerd-öt technikailag orientált férfit jobban érdekli a felbontás, mint a készenléti idő, míg a családanya inkább egy ütés, por és víz (nyál) álló telefont értékel, ami túléli a gyerekek támadását.

A fentiek meghatározása után elkészítjük az első komponenst, ami minden szegmenshez meghatároz egy ratinget az adott dologra. Pl. minden egyes telefonra megmondja, hogy az első szegmensnél a felbontásra kap X pontot, az ütésállóságra meg Y pontot, így az össz ratingje X+Y, és ez így tovább a többi szegmensre. Utána már csak annyi dolgunk van, hogy ha valaki rákeres a mobiltelefonokra, akkor – ha kb. tudjuk, ő milyen szegmensben van – akkor a találati listát az adott szegmenshez kapcsolt rating érték alapján csökkenő sorrendbe rendezzük (feltételezve, h a nagyobb rating a jobb).

Eddig nem túl bonyolult a dolog. Itt jön azonban a csavarás: Mi van akkor, ha a user – pl. amiatt, mert a héten minden HTC telefonra 10% leértékelés van – hirtelen csak HTC-ket kezd el látni a találati listában? Ez számunkra nem olyan kívánatos, mert mi azt szeretnénk, ha a felhasználó sokfélét látna ott – ugyanis simán lehet, hogy az adott felhasználó titokban utálja a HTC telefonokat, és tulajdonképpen Samsungot szeretne, de ezt nem tette bele a keresésbe valamilyen okból. Ez az, amit nálunk shuffling-nek hívnak, azaz keverésnek: Fogjuk a találati listát, és átrendezzük úgy, hogy a találatok változatosak legyenek.

Az első megfigyelés az, hogy ezt a keverést mindenképpen a találati listán kell megcsinálnunk, mivel ez keresésenként változik, és látatlanban nem tudjuk előre átrendezni a hasonló találatokat. A felhasználói szokásokat ismerve az is elég valószínű, hogy nem kell az összes találatot átrendeznünk, hiszen a felhasználó ritkán néz meg két oldalnál többet. Az is fontos, hogy ha a keresés pl. egy adott gyártóra történt (mondjuk Samsung) akkor ne erőlködjünk azon, hogy a gyártók szerint is sorbarendezzünk. Hasonlóképpen, ha a listának mondjuk 95%-a ugyanaz a gyártó, akkor szintén értelmetlen a keverés. Továbbá, feltételezhetjük, hogy a vásárló számára értékesebb az, ha minél változatosabb a lista, tehát azt is jó lenne elkerülni, hogy kétféle dolgot váltogassunk (HTC, apple, HTC, apple), ha a listában van mondjuk Samsung és Motorola is.

Van itt azonban egy érdekes kérdés: Ha már 1x berendeztük aszerint, hogy ezek az elemek milyen jók a usernek, akkor most nem vágjuk ezt teljesen felül azzal, hogy megkeverjük? A válasz kettős: Igen, alaposan megbolygatjuk a sorrendet, és nem, nem teljesen vágjuk felül. Lehetőség szerint úgy kell rendeznünk, hogy a találatok az eredeti sorrendhez a lehető legközelebb maradjanak. Ennek az eszköze lehet az algoritmushoz hozzácsapott maximum mélység, ami arról szól, hogy megmondjuk, hogy az átrendezendő elemekre – ami mondjuk a találati lista első 100 eleme – definiálunk egy %-ot, hogy ennél messzebbről ne rángassunk fel elemet semmiképp.

Erre alkottam egy algoritmust, amelyre a következő dolgok igazak: A rekord 1 mezőjére vizsgál, aszerint ha 2 azonos rekordot talál, akkor a találati listából maximum a meghatározott mélységen belül elővesz egy olyat, ami eddig arányosan a legritkábban volt használva. Ugyanolyan ritkaság esetén az eredeti halmazban gyakrabban előforduló elemből vesz. Az algoritmus szekvenciális, a feldolgozott elemeket már nem változtatja, csak a még keveretlen listát.

Hogy néz ki a végeredmény? 15 elemre, 20%-os mélységgel (max 3 elem) az alábbi előfordulásokkal az alábbi eredményeket kapjuk: (bal oldalon az eredeti lista, jobb oldalon a kevert)

Value distribution:
  • HTC     : 60%
  • Apple   : 13%
  • Samsung : 26%
     Index   Make      Index   Make
      ------------------------------
       1, Samsung        1  Samsung
       2,   Apple        2    Apple
       3,     HTC        3      HTC
       4,     HTC        6  Samsung
       5,     HTC        4      HTC
       6, Samsung        5      HTC
       7,     HTC       10  Samsung
       8,     HTC        7      HTC
       9,     HTC       11    Apple
      10, Samsung        8      HTC
      11,   Apple        9      HTC
      12,     HTC       13  Samsung
      13, Samsung       12      HTC
      14,     HTC       14      HTC
      15,     HTC       15      HTC

Hosszabb listákra nyilván sokkal hatékonyabb, de szerintem így is látszik a különbség.

Category: Szakmai  | Leave a Comment
hétfő, július 25th, 2011 | Author:

Basic socket communication

Writing a client/server application communicating over sockets is pretty easy in Java. The server creates an instance of the aptly named ServerSocket class, which waits for incoming connections. The client creates a Socket instance, which then connects to the server (thus creating another Socket on the server side via the accept method of the ServerSocket), and that’s it. Although Sockets are normally blocking read operations, it is easy to emulate a single threaded non-blocking communication with simply checking the available bytes on the socket, and reading only that much.

Blocking secure socket communication, the problem

Switching to a secure socket connection is very easy: First, you need to create some keystores, then some initialization in the code and then you can use some factory classes to create the secure sockets instead of the original constructor calls. Everything else is almost the same.. except..

Getting the number of available bytes are not reliable any more. The reason is simple: As your security and application data arrives in the same stream, the security engine is not able to tell the amount of available application bytes without trying to decrypt everything, but that is a complex operation. Probably more complex and requires more effort than you would like to have in an infinite loop.

Because of this, our workaround for blocking communication is not usable anymore. For a simple application with just one or a handful of clients it is acceptable to have a separate thread for all of the connected clients on the server side, but we need another solution for high user counts.

SocketChannels

Java NIO has a nonblocking socket solution. SocketChannels are designed for this. Because of the fundamentally different usage and the additional classes, such as Selectors, most people never uses them, but they are not overly complex, and with a little practice can be used easily. For beginners, I’d recommend reading this article: Rox Java NIO Tutorial. It’s probably not the easiest to understand, but contains very useful tips and explains typical pitfalls.

Using this, we solve the issue with the blocking channels, but security is still lacking. The bad news is: It is pretty hard to make SocketChannels secure. This is your second chance to turn back, and use the blocking solution, they say a few thousand threads are not really a problem for a good server :D

Securing SocketChannels

Ok, you are desperate. You want ‘em non-blocking channels communicate securely. Here is what you need to add to the code:

  1. You don’t need to do anything with the ServerSocketChannel, and the way it accepts connections.
  2. I prefer doing the reading and writing in a separate class, which “owns” the connection and the SSLEngine. (See Below)
  3. Initialize your security.
  4. On the server side, for every new socketchannel, create a new SSLEngine.
  5. On the client side, do the same for your one channel.
  6. Initiate the handshake.
  7. After the handshake, wrap everything you want to send and unwrap everything that you receive on both sides.

So far it is not too complex, right? Let’s dig deeper.

Initializing security:

private void setupSecurity() {
	SecureRandom secureRandom = new SecureRandom();
	secureRandom.nextInt();

	KeyStore clientKeyStore = KeyStore.getInstance("JKS");
	clientKeyStore.load(new FileInputStream("client.jks"), "KeyStorePassword".toCharArray()); 

	TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
	tmf.init(clientKeyStore);

	KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
	kmf.init(clientKeyStore, "KeyInKeystorePassword".toCharArray());

	sslContext = SSLContext.getInstance("TLS");
	sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), secureRandom);
}

Couldn’t be more straightforward. Creating an SSLEngine is just as easy:

SSLEngine engine = sslContext.createSSLEngine();

And now the handshake.. You can find a lot of explanations here (it’s a bit dry, but very useful). The scaffolding for the code can be found in the same article, but you are better off if you check the code here: [jdk home]\sample\nio\server\ChannelIOSecure.java

It is very complicated, and there is a hidden “flaw”: It’s meant to be used with blocking channels. (See below). Also, some structures are a bit more complex than I’d usually like it, for example the 3 levels deep switch constructs. Anyway, for now you should just try to copy it as closely as you can, and if you can make it work, then you can improve the code as much as you want.

The problems I faced

Obviously, it didn’t work for me the first time I tried. Here are some tips:

  • Don’t give up. It’s complex and ugly, but it can be done.
  • If the handshake doesn’t start, and/or the server complains about plaintext connection, insert the engine.beginHandshake() line before the handshake process. Sometimes the only issue that you see is that the clients sends the messages and the server simply absorbs them without any apparent effect.
  • If you get repeated buffer underflow errors on the server side, and using non-blocking communication, it’s time to add a new check for zero length reads. Trying to unwrap zero length ByteBuffers can cause this issue.
  • In case of unsupported record version problems or sequence violation (during the handshake) try to empty your buffers before you read/unwrap into them and after you have sent them to the other party. Leftover bytes can cause this issue. (Unsupported record version Unknown) (Handshake message sequence violation)
  • If the server/client complains about invalid handshake mac, check your flushing code. You may loose some important bytes. (bad handshake record MAC)
  • Google is your friend: There are a lot of people out there who solved the same issues and wrote an article about it.
  • It’s a good idea to add some logging to the code to see what is happening. It helps you to see the sequence of events on both sides.
  • There are some issues and solutions here I didn’t face. Still, you may see them.

I hope this will help some of you to develop some great, secure applications.

Category: Szakmai  | Tags: , ,  | Leave a Comment
szerda, június 22nd, 2011 | Author:

Bringing up a child is the process of how parents impose order over the fundamentally chaotic nature of their kid.

Category: Nincs kategorizálva  | Tags:  | Leave a Comment
vasárnap, május 08th, 2011 | Author:

A nagysikerű Vagabond v1.0 sokadik érfordulóján szeretném bejelenteni, hogy (főként a 2.0 és a 2.1 kedvező fogadtatása után) még az idén szeretnénk kibocsátani a Vagabond 2.2-es verzióját, ami valószínűleg a Félix kódnevet kapja. (ez még változhat, főleg, ha lány)

hétfő, június 07th, 2010 | Author:

Nemi vacillalas es atszervezes utan megrendeltem a telefonomat (nem a nokiat, hanem a samsungot), ket hettel es ket nappal ezelott az ebayrol. Uj, nem simlockos. A csavo azt irta, h 2 nap normalisan, busy idokben kicsit tobb, uh fizettem es vartam. Az otodik napon rauzentem, h mi a helyzet, nem jott valasz. A kovetkezo heten megint, majd a Paypal-en elinditottam egy dispute-ot, amibol masnap – tovabbi fejlemeny es kommunikacio hijan – claim lett. (az is megerne egy miset, hogy a Paypal miert var 3 napot, hogy elkuldje a tajekoztato levelet ezekrol..) Ma megneztem a csavo recent feedback-jeit, tobben panaszkodtak, h nem jott meg a cucc. A “shop” oldalara kattintva lattam egy kiirast, hogy a faszi beteg, uh most x ideig szunetel az eladas.

Hat ez nem a kommunikacio csucsa. Sajnalom, hogy beteg, de attol meg merges vagyok ra. Vegulis az en penzem (es masoke is) nala all..

Szoval a claim marad, remelhetoleg jovo heten jon is vissza belole a penz. Hirtelen felindulasomban majdnem at is mentem a szemben levo boltba, h vegyek egy kartyafuggetlen peldanyt ott, de azert az a 40 fontos arkulonbseg elbizonytalanitott kicsit. Ugy dontottem, adok meg egy eselyt az internetes rendelesnek, am ezuttal Amazon rendelem meg.

Most varok. 1-2 napon belul meg kene erkeznie.. kivancsi leszek.

ui: Vicces, hogy Lexandro kollega Samsungja is pont a napokban ment tonkre, es o is pont Samsungot vesz helyette. Pedig szerintem egyikunk sem megszallotja a Samsungnak, 1xuen most jok a telefonok, amiket kinalnak.

Category: Hobbi  | Tags: ,  | 2 Comments
kedd, június 01st, 2010 | Author:

Az uj kormany hatalomra kerulesevel komoly modernizacio kezdodott el Magyarorszagon. Ennek az egyik fontos eleme, hogy az allam – koltseget nem kimelve – atallitotta az eddig fizikai szervereken futo iDojaras alkalmazasat cloud alapura.

Azert van ez a sok eso.

Category: Személyes  | Tags:  | 3 Comments
péntek, május 07th, 2010 | Author:

Amikor ma veletlenul megtudtam, hogy melyik dal a “bikicsunaj” eredetije, egybol elkezdett szolni a fejemben.

Ami aztan eszembe is juttatta ezt a kepet:

[A kepet levettek a lenyeg a szoveg: Es most elindul a fejedben a Final Countdown c. dal..]

Category: Személyes  | Tags:  | Leave a Comment
csütörtök, május 06th, 2010 | Author:

A google readerben olvastam ma reggel:

“I can’t see an end. I have no control and I don’t think there’s any escape – I don’t even have a home anymore. It’s time for a new keyboard.”

Category: Személyes  | Tags:  | One Comment
szombat, április 17th, 2010 | Author:

napos_tnBiztos az izlandi hamufelhő miatt, de döbbenetesen jó volt ma az idő. Kisétáltunk a közeli parkba, hogy ejtőzzünk egyet, de kénytelenek voltunk hazajönni, mert túl meleg volt. Én konkrétan pólóban és farmerban voltam, de ez is sok volt. Kéne háromnegyedes nadrág :)

Category: Személyes  | Tags: , ,  | One Comment
csütörtök, április 15th, 2010 | Author:
Relative Chart

Relative Chart

Ha felvesz egy ismeretlen facebookon, a kovetkezo eselyekkel szamolhatsz:

  • 74.4%, hogy scam, phising vagy practical joke
  • 10.3%, hogy farmville-es ismerost keres
  • 9.4%, hogy nevhasonlosag miatt, tevedesbol vett fel (atlagosan)
  • 4.6%, hogy egy reg elfelejtett rokon, peldaul a masodunokatestvered nagyobbik fia/lanya
  • 1.3%, hogy egy idegen, aki csak ismerkedni szeretne/noveli az ismeroslistat
  • 0%, hogy az a szoke csaj a nagy dudakkal, akit tegnap a metron lattal
Category: Személyes  | Tags:  | Leave a Comment